/* =============================================================================
   home.css — Immersive "console / main menu" homepage
   Fixed-viewport experience with two states: splash and dashboard.
   Uses the shared design tokens (tokens.css). This file is loaded ONLY by the
   homepage; subpages keep main.css + the global header/footer shell.
   ========================================================================== */

/* Vendored display face for the first-load intro wordmark only (OFL).
   Self-contained — no Google Fonts CDN at runtime. `block` so the mask never
   renders in a fallback face (the JS also gates the reveal on fonts.load). */
@font-face {
  font-family: 'Plaster';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url('/assets/fonts/plaster.woff2') format('woff2');
}

/* ---- Page shell -----------------------------------------------------------
   The homepage locks the viewport (no document scroll). The dashboard grid
   scrolls internally on mobile instead. */
html.home,
body.home {
  height: 100%;
}

body.home {
  margin: 0;
  min-height: 100svh;
  /* Solid black backdrop — always present behind the shell, so the hero can
     fade up from black during the intro reveal. */
  background: #000;
  color: var(--color-text);
  font-family: var(--font-sans);
  overflow: hidden;            /* locked; dashboard panel scrolls internally */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.home-shell {
  position: relative;
  width: 100%;
  height: 100svh;
  isolation: isolate;          /* own stacking context for the layers below */
}

/* While the intro is pending, the hero content group is hidden so nothing
   flashes through the cut-out letters before JS takes control of the fade. */
body.home[data-intro-pending] .home-shell {
  opacity: 0;
}

/* ===========================================================================
   1. AMBIENT LAYER
   Persistent background behind BOTH states. Architected as a single swappable
   component: today it mounts FloatingLines (WebGL). To switch to a looped
   video later, replace the contents of `.ambient__stage` with the commented
   <video> block in index.html — no other CSS needs to change.
   ========================================================================== */
.ambient {
  position: fixed;
  inset: 0;
  z-index: var(--z-lines);     /* 0 — behind all UI */
  overflow: hidden;
  background:
    radial-gradient(120% 80% at 50% 0%, #141414 0%, var(--color-bg) 60%),
    var(--color-bg);
  pointer-events: none;        /* never eats clicks; UI sits above */
}

.ambient__stage {
  position: absolute;
  inset: 0;
}

.ambient__stage canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

/* Full-bleed looped background video. background:#000 = a BLACK poster so it
   reads as black before it loads / while the intro holds it paused. */
.ambient__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}

/* Dark poster / gradient placeholder shown when the WebGL ambient is absent
   (reduced-motion, low power, or before/while a future <video> loads). */
.ambient__poster {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(140% 100% at 50% -10%, #141414 0%, transparent 55%),
    linear-gradient(180deg, #000000 0%, var(--color-bg) 70%);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}

/* Scrim to keep text legible over the ambient motion. Strength shifts subtly
   between states for depth. */
.ambient__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(120% 90% at 50% 40%, transparent 0%, rgba(0, 0, 0, 0.55) 70%, rgba(0, 0, 0, 0.82) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, transparent 30%, rgba(0, 0, 0, 0.55) 100%);
  transition: opacity var(--dur-slow) var(--ease-out);
}

body.home[data-state="dashboard"] .ambient__scrim {
  opacity: 0.92;
}

/* ===========================================================================
   1b. INTRO REVEAL
   First-load overlay (above everything): a full-bleed solid-orange SVG with the
   wordmark "LISTING" cut OUT as holes (luminance mask). home.js holds, then
   scales the word toward the viewer while the hero fades up from black through
   the growing letterforms and the orange fades out. See home.js for timing.
   ========================================================================== */
.intro {
  position: fixed;
  inset: 0;
  z-index: var(--z-intro);
  pointer-events: auto;        /* intercept the page during the reveal */
}

/* Intro's own black layer (behind the orange SVG). The letter-holes reveal
   THIS until the video trigger, then it cross-dissolves to the playing video. */
.intro__black {
  position: absolute;
  inset: 0;
  background: #000;
}

.intro__overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Orange field. opacity 0 here so pre-JS the screen is black (the intro black
   layer), never a flash of orange; JS fades it in (step 2). */
.intro__orange {
  fill: var(--intro-orange);
  opacity: 0;
}

/* The cut-out wordmark. font-size + opacity + scale are driven by JS (the
   INTRO constants in home.js); this is the static fallback. SVG user units
   (viewBox 0 0 1000 1000). Pivots around its own centre so it grows toward the
   viewer. opacity 0 here so the field is solid orange before JS animates it in. */
.intro__word {
  font-family: 'Plaster', system-ui, sans-serif;
  font-size: 80px;
  letter-spacing: 6px;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}

/* Reduced motion: no reveal at all — the hero shows immediately (JS removes the
   overlay and clears the pending hide). */
@media (prefers-reduced-motion: reduce) {
  .intro { display: none !important; }
}


/* ===========================================================================
   2. PERSISTENT CHROME (HUD)
   Logo (top-left), primary action (top-right), Explore/Close toggle.
   Lives above both states, always visible.
   ========================================================================== */
.hud {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);   /* 200 — above content */
  pointer-events: none;        /* children re-enable as needed */
  display: grid;
  grid-template-rows: auto 1fr auto;
}

.hud > * {
  pointer-events: auto;
}

.hud__top {
  grid-row: 1;            /* pin to the top row */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: clamp(1rem, 3vw, 1.75rem) var(--container-pad);
}

.hud__bottom {
  grid-row: 3;            /* pin to the bottom row (1fr middle pushes it down) */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-md);
  padding: clamp(1rem, 3vw, 1.75rem) var(--container-pad);
}

/* Brand lockup */
.hud-brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55ch;
  text-decoration: none;
  color: var(--color-text);
  font-family: var(--font-display);
  letter-spacing: var(--tracking-tight);
}

.hud-brand__mark {
  font-family: 'Plaster', var(--font-display, sans-serif);
  font-weight: 400; /* Plaster is single-weight */
  font-size: calc(var(--fs-400) * 1.2);
  text-transform: uppercase;
}

.hud-brand__sub {
  font-size: calc(var(--fs-100) * 1.35);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-accent);
}

/* Generic HUD button base */
.hud-btn {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.6ch;
  font-family: var(--font-sans);
  font-size: calc(var(--fs-200) * 1.5);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-wide);
  line-height: 1;
  padding: 0.85em 1.4em;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-line-strong);
  background: rgba(0, 0, 0, 0.55);
  color: var(--color-text);
  text-decoration: none;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition:
    background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.hud-btn:hover {
  background: var(--color-bg-hover);
  border-color: var(--color-accent-dim);
}

.hud-btn:active {
  transform: translateY(1px);
}

.hud-btn--accent {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-contrast);
}

.hud-btn--accent:hover {
  background: var(--color-accent-hi);
  border-color: var(--color-accent-hi);
}

.hud-btn--whatsapp {
  display: inline-flex;
  align-items: center;
  gap: 10.5px;
  background-color: #25D366;        /* flat official WhatsApp green */
  color: #FFFFFF;
  font-weight: 700;
  font-size: 16.8px;
  line-height: 1;
  padding: 14.7px 25.2px;
  border: none;
  border-radius: 9999px;            /* full pill */
  box-shadow: 0 4.2px 12.6px rgba(0, 0, 0, 0.15);  /* single soft neutral shadow */
  cursor: pointer;
  transition: background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.hud-btn--whatsapp:hover {
  background-color: #1EBE57;
  transform: translateY(-1px);
  box-shadow: 0 5.6px 15.4px rgba(0, 0, 0, 0.2);
}

.hud-btn--whatsapp:active {
  transform: translateY(0);
}

.hud-btn__icon {
  width: 1.05em;
  height: 1.05em;
  flex: none;
}

/* Plain white WhatsApp glyph directly on the green — no circle, no badge. */
.hud-btn--whatsapp .hud-btn__icon {
  width: 21px;
  height: 21px;
  flex: none;
}

/* Explore / Close toggle — bottom centre. The label swaps via state. */
.hud-toggle {
  position: relative;
}

/* Splash has its own Explore CTA — the HUD toggle is a Close button that
   only appears once the dashboard is open. */
body.home[data-state="splash"] .hud-toggle { display: none; }

.hud-toggle__label--close { display: inline; }

/* Focus visibility everywhere in the HUD + menu */
.hud-btn:focus-visible,
.hud-brand:focus-visible,
.tile:focus-visible,
.social-link:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

/* ===========================================================================
   3. STAGE — holds both states, stacked.
   ========================================================================== */
.stage {
  position: absolute;
  inset: 0;
  z-index: var(--z-hero-ui);   /* 2 — above ambient, below HUD */
}

.state {
  position: absolute;
  inset: 0;
}

/* The inactive state is removed from a11y tree + pointer flow via [inert] in
   the markup; we also visually hide it here. */
.state[hidden] { display: none; }

/* ---- 3a. SPLASH ---------------------------------------------------------- */
.splash {
  display: grid;
  place-items: center;
  padding: calc(var(--header-h) + var(--space-xl)) var(--container-pad) var(--space-4xl);
  text-align: center;
}

.splash__inner {
  max-width: 56rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.9rem, 2.2vw, 1.5rem);
}

/* Keyword-forward <h1> headline. */
.splash__title {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: var(--lh-tight);
}

.splash__line { display: block; }

.splash__line--main {
  font-family: "Raleway", var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 5.5vw, 4.25rem);
  letter-spacing: -0.02em;
  line-height: 1.02;
  color: var(--color-text);
  text-wrap: balance;
}

/* Scannable service line — each item reads as a keyword. */
.splash__services {
  margin: 0;
  max-width: 46ch;
  font-family: "Raleway", var(--font-display);
  font-size: clamp(0.95rem, 1.6vw, 1.2rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-text);
  text-wrap: balance;
}

/* SEO hero lead — fades in after the intro lifts and the video starts playing.
   Visible by default so the no-JS / reduced-motion / deep-link paths show it. */
.splash__lead {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  color: var(--color-text-muted);
  text-wrap: balance;
}

.splash__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  justify-content: center;
  margin-top: var(--space-xs);
}

.splash__actions .hud-btn { font-size: var(--fs-300); padding: 1em 1.7em; }

/* ---- 3b. DASHBOARD ------------------------------------------------------- */
.dashboard {
  display: grid;
  place-items: stretch;        /* grid fills the padded viewport */
  /* Top/bottom padding must clear the HUD bars (logo + Close button) on every
     viewport AND leave breathing room. A bar = its own clamp() vertical padding
     ×2 plus the button height (~header-h), so we reserve exactly that and add a
     gap — otherwise the stretched grid slides under the bars and overlaps them. */
  padding:
    calc(var(--header-h) + clamp(1rem, 3vw, 1.75rem) + var(--space-md))
    var(--container-pad);
}

.dashboard__grid {
  /* place-items:stretch on .dashboard already sizes this to the padded area;
     an explicit height:100% mis-resolved and overflowed under the HUD bars. */
  min-height: 0;
  display: grid;
  /* Tight gaps so the tiles read as one dense console. */
  gap: clamp(0.3rem, 0.6vw, 0.5rem);
  grid-template-columns: repeat(6, 1fr);
  /* 6 fine rows: top band = rows 1-4 (= old 2/3), bottom = rows 5-6 (= old 1/3),
     so feat/bosnia/vip/bottom keep their proportions. Only the fleet/airport
     stack is re-split: fleet = 1 track (~half its old height), airport = 3 tracks
     (fills the freed space; the row gaps make it slightly more than half, as asked). */
  grid-template-rows: repeat(6, minmax(0, 1fr));
  /* Bottom-right box split: its top half is absorbed by vip (now rows 3-5),
     its bottom half (row 6, col 6) stays `social` and holds the two square
     social boxes side by side. */
  grid-template-areas:
    "feat feat feat fleet   fleet   bosnia"
    "feat feat feat airport airport bosnia"
    "feat feat feat airport airport vip"
    "feat feat feat airport airport vip"
    "trust trust trust about faqs   vip"
    "trust trust trust about faqs   social";
}

/* ---- Tile base ----------------------------------------------------------- */
.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2xs);
  padding: clamp(1rem, 1.6vw, 1.5rem);
  border: 1px solid var(--color-line);
  border-radius: 0;
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--color-text);
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
  will-change: transform, opacity;
  transition:
    transform var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    background var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    filter var(--dur-base) var(--ease-out);
}

.tile__title {
  font-family: var(--font-display);
  font-size: var(--fs-500);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}

.tile__desc {
  font-size: var(--fs-200);
  color: var(--color-text-muted);
  line-height: var(--lh-snug);
}

.tile__arrow {
  position: absolute;
  top: clamp(1rem, 1.6vw, 1.5rem);
  right: clamp(1rem, 1.6vw, 1.5rem);
  width: 1.4rem;
  height: 1.4rem;
  color: var(--color-text-faint);
  transition: color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

/* Hover/focus: elevate + brighten the focused tile. The "recede others" feel
   is added by JS toggling [data-dimmed] on siblings. */
.tile:hover,
.tile:focus-visible {
  transform: translateY(-3px);
  border-color: var(--color-accent);
  background: rgba(255, 255, 255, 0.09);
  box-shadow: var(--shadow-lg);
}

.tile:hover .tile__arrow,
.tile:focus-visible .tile__arrow {
  color: var(--color-accent);
  transform: translate(2px, -2px);
}

/* Recede non-focused tiles (set by JS on the grid). */
.dashboard__grid[data-focus] .tile:not([data-active]) {
  filter: brightness(0.62) saturate(0.85);
  opacity: 0.82;
}

/* ---- Tile placements ----------------------------------------------------- */
.tile--feat    { grid-area: feat; justify-content: space-between; }
.tile--fleet   { grid-area: fleet; }
.tile--bosnia  { grid-area: bosnia; }
.tile--airport { grid-area: airport; }
.tile--vip     { grid-area: vip; }
.tile--trust   { grid-area: trust; }
.tile--about   { grid-area: about; }
.tile--faqs    { grid-area: faqs; }

/* ---- Featured vehicle spotlight (static placeholder, no 2nd WebGL ctx) --- */
.tile--feat {
  border-color: var(--color-line-strong);
  /* Plain gray glass — no orange tint (matches the other grid tiles). */
  background: rgba(255, 255, 255, 0.05);
  /* Reserve a bottom strip for the absolutely-positioned .feat__seo label
     (label line-height + its bottom inset) so head/media/name/specs always sit
     above it and never overlap, on any viewport height. */
  padding-bottom: calc(var(--fs-500) * 1.6 + clamp(1rem, 1.6vw, 1.5rem));
}

.tile--feat:hover,
.tile--feat:focus-visible {
  background: rgba(255, 255, 255, 0.09);
}

.feat__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.feat__label {
  font-size: var(--fs-100);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-accent);
  font-weight: var(--fw-semibold);
}

.feat__media {
  position: relative;
  flex: 1;
  min-height: 4rem;   /* shrinks the car under vertical pressure instead of
                         pushing name/specs into the reserved label strip */
  margin: var(--space-sm) 0;
  border-radius: 0;
  /* No backdrop — the cars (reflection baked into the artwork) sit on the tile
     itself. A horizontal edge mask FEATHERS the car as it slides in/out so it
     dissolves softly at the sides instead of hard-clipping mid-box. */
  overflow: hidden;
  background: none;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
}

/* Two layers stack inside .feat__media; home.js toggles .is-active / .is-leaving
   to cross-slide them. CSS transitions (not GSAP) so a car is never left stuck
   invisible if the tab backgrounds — the active resting state is always opacity 1.
   Base state = staged off to the right, blurred + hidden. Each layer carries the
   car, a faded mirror reflection, and a ground-shadow pool so the transparent
   cut-out reads as resting on the tile. Motion uses an easeOutExpo curve. */
.feat__layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;   /* definite height so the car/reflection %-heights resolve */
  opacity: 0;
  transform: translateX(60%) scale(1.04);
  filter: blur(14px);
  pointer-events: none;
  will-change: transform, opacity, filter;
  transition:
    opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Current car: driven home, sharp and centred (smooth deceleration). */
.feat__layer.is-active {
  opacity: 1;
  transform: translateX(0) scale(1);
  filter: blur(0);
}
/* Outgoing car: accelerates out to the left with a motion-blur (easeInExpo). */
.feat__layer.is-leaving {
  opacity: 0;
  transform: translateX(-55%) scale(0.97);
  filter: blur(14px);
  transition-timing-function: cubic-bezier(0.7, 0, 0.84, 0);
}

/* Plain transparent car cut-out, contained in the layer — no effects. */
.feat__car {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}

/* Name + specs cross-fade together on each change. */
.feat__info {
  transition:
    opacity 0.3s var(--ease-out),
    transform 0.42s var(--ease-out);
}
.feat__info.is-swapping {
  opacity: 0;
  transform: translateY(8px);
}

@media (prefers-reduced-motion: reduce) {
  .feat__layer,
  .feat__info { transition: none; }
}

.feat__name {
  font-family: var(--font-display);
  font-size: var(--fs-600);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--lh-tight);
}

/* Canary-yellow SEO/branding label pinned to the bottom-left of the featured
   (Range Rover) spotlight. Absolute so it can't be clipped by the tile's
   overflow:hidden; feat__info gets bottom room below (see .feat__info) so the
   vehicle name/specs never overlap it. Sized/styled to match .tile__title. */
.feat__seo {
  position: absolute;
  left: clamp(1rem, 1.6vw, 1.5rem);
  bottom: clamp(1rem, 1.6vw, 1.5rem);
  z-index: 3;
  font-family: var(--font-display);
  font-size: var(--fs-500);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--color-accent);
  pointer-events: none;
}

.feat__specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-xs);
  padding: 0;
  list-style: none;
}

.feat__specs li {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.feat__spec-k {
  font-size: var(--fs-100);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.feat__spec-v {
  font-size: var(--fs-300);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

/* ---- Trust / guest-review carousel --------------------------------------- */
/* Container styling stays inherited from .tile (border, glass bg, padding,
   radius, shadow) — only the internals change to host the rotating reviews. */
.tile--trust { justify-content: center; }

/* Animatable edge-feather amount (registered so it can transition smoothly —
   a raw custom property would jump discretely). 0% = no feather (resting). */
@property --feather {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

/* Viewport: stacks every review slide on top of each other and clips.
   Feathered top/bottom edges so moving text dissolves before it hits the box
   edge instead of hard-clipping. The feather EASES IN as a shuffle starts and
   EASES BACK OUT after it ends (driven by --feather) — never a hard cut-off. */
.reviews {
  position: relative;
  flex: 1;
  min-height: 0;
  width: 100%;
  --feather: 0%;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--feather), #000 calc(100% - var(--feather)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--feather), #000 calc(100% - var(--feather)), transparent 100%);
  transition: --feather 0.55s cubic-bezier(0.25, 1, 0.5, 1);
}

.reviews.is-shuffling { --feather: 14%; }

/* One review. All slides overlap; only [data-active] is visible. Vertical
   "shuffle": the incoming review rises from below while the outgoing one
   slides up out of the way, both cross-fading on an Apple-fluid easeOutQuart
   curve. Rest position = parked below; .is-leaving = exiting upward. */
.review {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  /* Group stars + name + review at the TOP so the text sits right under the name
     (and never grows down into the date). The date is pinned to the bottom. */
  justify-content: flex-start;
  gap: var(--space-2xs);
  width: 100%;
  opacity: 0;
  transform: translateY(110%);
  pointer-events: none;
  transition:
    opacity 0.85s cubic-bezier(0.25, 1, 0.5, 1),
    transform 0.85s cubic-bezier(0.25, 1, 0.5, 1);
}

.review[data-active] {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.review.is-leaving {
  opacity: 0;
  transform: translateY(-110%);
}

.trust__stars {
  color: var(--color-accent);
  font-size: var(--fs-400);
  letter-spacing: 0.1em;
  line-height: 1;
}

/* Name leads the block (above the review) and sits a step larger. */
.trust__name {
  font-family: var(--font-display);
  font-size: var(--fs-500);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--lh-snug);
  color: var(--color-text);
}

.trust__quote {
  font-size: var(--fs-300);
  color: var(--color-text-muted);
  line-height: var(--lh-snug);
  width: 100%;
  margin: 0;
  /* Clamp to the lines that fit the short box and let the box ellipsis (…) do
     the truncation — so long reviews never hard-clip at the box edge. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  text-overflow: ellipsis;
}

.trust__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.75rem;
  /* Sits directly under the review text (no longer pinned to the box bottom) so
     the date tracks the content, not the box height. */
  padding-top: var(--space-2xs);
  font-size: var(--fs-200);
  color: var(--color-text-faint);
  /* Leave room so the meta never tucks under the Google glyph. */
  padding-right: 2.25rem;
}

.trust__badge { color: var(--color-text-muted); }

/* Google "G" shortcut — subtle, anchored to the bottom-right corner. */
.reviews__google {
  position: absolute;
  right: clamp(0.85rem, 1.4vw, 1.25rem);
  bottom: clamp(0.85rem, 1.4vw, 1.25rem);
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.06);
  opacity: 0.7;
  transition:
    opacity var(--dur-base) var(--ease-out),
    background var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.reviews__google:hover,
.reviews__google:focus-visible {
  opacity: 1;
  background: rgba(255, 255, 255, 0.12);
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .review,
  .review[data-active],
  .review.is-leaving {
    transition: opacity 0.3s linear;
    transform: none;
  }
}

/* ---- Social tile --------------------------------------------------------- */
/* The bottom-right box was split: this cell now just hosts the two social
   boxes side by side, so the outer tile frame is dropped — the two
   `.social-link`s ARE the visible boxes (matching the reference). */
.tile--social {
  --social-gap: clamp(0.3rem, 0.6vw, 0.5rem);
  grid-area: social;
  /* The two boxes split the cell into equal halves and each FILLS its half —
     full cell height, half the width — so they sit flush with the rest of the
     grid at every viewport (no floating squares, no leftover gutters). The
     outer tile frame is dropped; the two `.social-link`s ARE the visible boxes. */
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--social-gap);
  border: none;
  background: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  padding: 0;
  /* `.tile` defaults to overflow:hidden, which clipped the lifted top border and
     the hover shadow off the social boxes — making them look unlike the grid. */
  overflow: visible;
}

.social-link {
  min-width: 0;
  display: grid;
  place-items: center;
  border-radius: 0;
  border: 1px solid var(--color-line);
  color: var(--color-text-muted);
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  /* Match the standard tile hover (lift + accent border + shadow) for cohesion. */
  transition:
    transform var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    background var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.social-link:hover,
.social-link:focus-visible {
  transform: translateY(-3px);
  color: var(--color-accent);
  border-color: var(--color-accent);
  background: rgba(255, 255, 255, 0.09);
  box-shadow: var(--shadow-lg);
}

.social-link svg { width: 38%; height: auto; }

/* ===========================================================================
   4. STATE TRANSITIONS (JS-driven via GSAP; CSS holds the resting visuals).
   Initial hidden offsets for splash/panel reveal are applied by JS to allow
   precise stagger. We expose data-state for non-GSAP styling hooks above.
   ========================================================================== */

/* ===========================================================================
   5. MOBILE — single-column scrollable stack of tiles.
   ========================================================================== */
@media (max-width: 860px) {
  body.home { overflow: hidden; }

  .dashboard {
    align-items: stretch;
    padding-top: calc(var(--header-h) + clamp(1rem, 3vw, 1.75rem) + var(--space-md));
    padding-bottom: calc(var(--header-h) + clamp(1rem, 3vw, 1.75rem) + var(--space-md));
  }

  .dashboard__grid {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    grid-template-areas:
      "feat"
      "fleet"
      "bosnia"
      "airport"
      "vip"
      "trust"
      "about"
      "faqs"
      "social";
    max-height: none;
    height: 100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-right: 2px;        /* room for scrollbar */
  }

  .tile { min-height: 6.5rem; }
  .tile--feat { min-height: 16rem; }

  .splash__title { font-size: var(--fs-800); }
}

@media (max-width: 520px) {
  .splash__actions { flex-direction: column; width: 100%; }
  .splash__actions .hud-btn { justify-content: center; width: 100%; }
}

/* ---- Mobile HUD --------------------------------------------------------
   The live menu (the injected Forza garage column) scrolls UNDER the fixed
   HUD on mobile, so:
     • the top row keeps only the brand, over a legibility scrim, and stops
       swallowing touches (only its children take pointer events);
     • the WhatsApp CTA leaves the top bar and becomes a fixed bottom-right
       pill in the thumb zone (safe-area aware), with a shortened label.
   The Forza column reserves top/bottom padding for both (forza-menu.css). */
@media (max-width: 860px) {
  .hud__top {
    pointer-events: none;          /* full-width strip must not block taps */
    background: linear-gradient(180deg,
      rgba(0, 0, 0, 0.78) 0%,
      rgba(0, 0, 0, 0.35) 62%,
      transparent 100%);
  }
  .hud__top > * { pointer-events: auto; }

  .hud-btn--whatsapp {
    position: fixed;
    right: max(1rem, env(safe-area-inset-right));
    bottom: calc(1rem + env(safe-area-inset-bottom));
    padding: 0.95rem 1.3rem;       /* ~48px tall — thumb-sized */
    font-size: 0.95rem;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  }
  .hud-btn--whatsapp .hud-btn__txt-chat { display: none; }  /* "WhatsApp" only */
}

/* ===========================================================================
   6. REDUCED MOTION — no scrub, no stagger, no WebGL motion. Content is
   immediately usable. JS also skips GSAP timelines and mounts the poster.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .ambient__poster { opacity: 1; }

  .tile,
  .tile__arrow,
  .social-link {
    transition: none !important;
  }
}
