/* ═══════════════════════════════════════════════════════════════════
   WILDBOSSES · DIAGONAL VIDEO RAIL
   The tilt lives on .rail-tilt, the motion on .rail-track. Keeping them
   on separate elements means the transform origin of a very wide flex
   row never has to be reasoned about.
   ═══════════════════════════════════════════════════════════════════ */

/* The rail is a cinema stage: it stays dark in both themes so film and
   photography carry, and so the dimmed cards recede instead of washing
   out against a pale page.

   The bottom of the stage is a vignette into the stage's OWN darkness,
   not a transition to the page below. The tilted row is clipped by the
   viewport, so cards get sliced mid-countdown; sinking them into black
   reads as depth. Pointing this gradient at the light page instead put
   a milky white band straight across the card content. The seam to the
   page is the gold hairline, the same one under the masthead. */
.wb-rail {
  position: relative;
  background: var(--void);
  isolation: isolate;
}
.wb-rail::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 56px; pointer-events: none; z-index: 3;
  background:
    linear-gradient(90deg, transparent, var(--sun) 22%, var(--citrine) 50%, var(--sun) 78%, transparent)
      bottom / 100% 2px no-repeat,
    linear-gradient(to bottom, transparent, var(--void) 82%);
}

.rail-viewport {
  position: relative;
  overflow: hidden;
  height: clamp(470px, 72vh, 720px);
  cursor: grab;
}
.wb-rail.is-dragging .rail-viewport { cursor: grabbing; }

/* oversized so the rotated row still covers the corners */
.rail-tilt {
  position: absolute;
  top: 50%;
  left: -18%;
  width: 136%;
  /* lifted off centre: .rail-body sits at the bottom of each card, so a
     row centred in the viewport puts every price and countdown right where
     the vignette lands. Riding high leaves the bottom of the stage empty
     for the fade to work in. */
  transform: translateY(calc(-50% - clamp(20px, 3.4vh, 42px))) rotate(var(--tilt, -8deg));
  transform-origin: center;
}

.rail-track {
  display: flex;
  will-change: transform;
}
.rail-run { display: flex; flex: 0 0 auto; }

/* ── card ───────────────────────────────────────────────── */
.rail-card {
  position: relative;
  flex: 0 0 auto;
  /* capped against viewport HEIGHT as well as width: the card is 3/4
     portrait and the row is rotated, so on a short laptop screen a card
     sized only by width is taller than the stage and loses its price. */
  width: min(clamp(266px, 26vw, 400px), 44vh);
  aspect-ratio: 3 / 4.35;
  margin: 0 clamp(12px, 1.6vw, 26px);
  border-radius: var(--r-lg);
  overflow: hidden;
  background:
    var(--grad-canopy);
  box-shadow: 0 8px 30px -8px rgba(0,0,0,.7);
  transform: scale(.9) translateZ(0);
  opacity: .78;
  filter: saturate(.94) brightness(.9);
  transition: transform .7s var(--ease), opacity .7s var(--ease), filter .7s var(--ease);
  -webkit-user-drag: none;
  user-select: none;
}

/* only the card at centre stage is fully present */
.rail-card.is-live {
  transform: scale(1.06) translateZ(0);
  opacity: 1;
  filter: none;
  box-shadow: 0 22px 60px -14px rgba(0,0,0,.8), 0 0 0 1px var(--gold-soft);
}

.rail-media { position: absolute; inset: 0; }
.rail-film,
.rail-still {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  background-size: cover;
  background-position: center;
}
/* The film is visible immediately; its poster attribute covers the gap
   before the first frame. Hiding it until an event fired was one more
   way for a card to end up blank. */
.rail-film { opacity: 1; }
.rail-film.film-failed { display: none; }
/* neither poster nor tour photo: show the canopy gradient rather than a
   black rectangle the reader has to interpret */
.rail-still-bare { background: var(--grad-canopy); }

/* a card with no film yet drifts its poster rather than sitting dead */
.rail-card.is-live .rail-still { animation: railDrift 22s ease-in-out infinite alternate; }
@keyframes railDrift {
  from { transform: scale(1.02) translate3d(-1.2%, 0.8%, 0); }
  to   { transform: scale(1.13) translate3d(1.4%, -1.2%, 0); }
}

.rail-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(7,9,8,.94) 0%, rgba(7,9,8,.72) 26%,
    rgba(7,9,8,.16) 58%, rgba(7,9,8,.34) 100%);
}

.rail-body {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: clamp(16px, 1.7vw, 24px);
  display: grid;
  gap: 8px;
  /* its own wash, so the block stays legible no matter how tall it grows
     and never relies on the card scrim reaching far enough up */
  background: linear-gradient(to top, rgba(4,21,15,.96) 62%, rgba(4,21,15,.72) 86%, transparent);
}

.rail-card * { color: var(--pollen); }
.rail-title {
  font-family: var(--display);
  font-size: clamp(22px, 1.9vw, 32px);
  line-height: 1;
  letter-spacing: .01em;
  margin: 0;
  color: var(--pollen);
  text-shadow: 0 2px 22px rgba(0,0,0,.7);
}

.rail-sub {
  margin: 0;
  /* one line only; a two-line subtitle was the other half of the overlap */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: clamp(11.5px, .85vw, 13px);
  color: rgba(243,238,228,.8);
  line-height: 1.45;
}

/* ── countdown ──────────────────────────────────────────── */
/* The label and four units used to sit in one wrapping flex row. At card
   width the seconds could not fit, wrapped to a line of their own, and the
   body — which is anchored to the bottom of the card — grew upwards THROUGH
   the title. That is the overlap on the Nairobi and Diani cards.

   The label now has its own line and the four units are a fixed 4-column
   grid, so the block's height is the same on every card at every width and
   nothing can wrap. */
.rail-count { display: grid; gap: 6px; padding-top: 2px; }
.rail-count-units {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(4px, .5vw, 8px);
}
.rail-count-lab {
  font-size: 9.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--citrine);
}
.rail-count-wait {
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(243,238,228,.72);
}
.rail-unit {
  display: grid; justify-items: center; gap: 2px;
  padding: 7px 2px; border-radius: 9px;
  background: rgba(255,249,227,.09);
  border: 1px solid rgba(180,255,200,.15);
}
.rail-unit b {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(15px, 1.25vw, 21px);
  font-weight: 600;
  line-height: 1;
  color: var(--pollen);
}
.rail-unit i {
  font-style: normal;
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(243,238,228,.66);
}

.rail-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 6px;
  border-top: 1px solid rgba(255,255,255,.16);
  margin-top: 4px;
}
.rail-price {
  font-size: 13px;
  font-weight: 600;
  color: var(--pollen);
}
.rail-spots {
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--citrine);
  padding: 3px 9px;
  border: 1px solid rgba(232,182,80,.5);
  border-radius: 999px;
}

/* ── hint ───────────────────────────────────────────────── */
.rail-hint {
  position: absolute;
  bottom: clamp(16px, 2.4vh, 26px);
  right: clamp(16px, 4vw, 46px);
  z-index: 4;
  pointer-events: none;
}
.rail-hint span {
  font-size: 10px;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: rgba(243,238,228,.44);
}
.wb-rail.is-dragging .rail-hint { opacity: 0; transition: opacity .3s; }

/* ── no motion: a plain readable row, no drift, no autoplay ── */
.wb-rail.rail-static .rail-tilt { transform: translateY(-50%); }
.wb-rail.rail-static .rail-viewport { overflow-x: auto; height: auto; padding: 24px 0; }
.wb-rail.rail-static .rail-card { transform: none; opacity: 1; filter: none; }
.wb-rail.rail-static .rail-hint { display: none; }

@media (prefers-reduced-motion: reduce) {
  .rail-card { transition: none; }
  .rail-card.is-live .rail-still { animation: none; }
}

/* ── the thesis ──────────────────────────────────────────
   The rail used to be the entire top of the homepage: four dark cards
   drifting past, and nowhere on the page a sentence saying what this
   company sells. There was no h1 either, so the document opened on an
   h3 inside a card.

   The band and the stage are one mass — forest at the top sinking into
   the stage's black — so this reads as the hero having a headline rather
   than as a strip bolted above a carousel. */
.wb-rail-top {
  /* the surface rule in wb-tokens.css sets background:var(--bg); this wins
     because it is declared after it in the cascade and is more specific */
  background: linear-gradient(to bottom, var(--forest) 0%, var(--forest-deep) 62%, var(--void) 100%);
  padding: clamp(38px, 6vw, 74px) 0 clamp(26px, 3.4vw, 40px);
  position: relative; overflow: hidden;
}
.wb-rail-top::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 66% 70% at 50% -24%, rgba(255,214,64,.20), transparent 70%),
    radial-gradient(ellipse 40% 70% at 100% 40%, rgba(111,217,67,.10), transparent 72%);
}
/* `max-width:21ch` on this block resolved `ch` against the body font at
   16px, so the column was ~280px wide while the headline set at 92px —
   one word per line. Measure the headline against its OWN font instead,
   and let the block itself be as wide as the grid allows. */
/* Two columns from 1000px. The copy alone left ~800px of empty green on a
   laptop, which reads as an unfinished page rather than as restraint. The
   right column is the soonest departure with its countdown running — the
   headline claims every trip already has a date, so the proof of it should
   be standing next to the claim rather than three scrolls further down. */
.wb-rail-grid {
  position: relative; z-index: 1;
  display: grid; gap: clamp(28px, 4vw, 56px);
  align-items: center;
}
@media (min-width: 1000px) {
  .wb-rail-grid { grid-template-columns: minmax(0, 1.05fr) minmax(340px, .95fr); }
}
.wb-rail-copy { position: relative; z-index: 1; max-width: 62rem; min-width: 0; }

/* ── next departure panel ───────────────────────────────── */
.wb-next {
  display: none; position: relative;
  border-radius: var(--r-lg); overflow: hidden;
  background: rgba(4,21,15,.52);
  border: 1px solid rgba(180,255,200,.20);
  box-shadow: 0 24px 60px -24px rgba(0,18,10,.9);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.wb-next.is-on { display: block; }
.wb-next-media { position: absolute; inset: 0; }
.wb-next-media img { width: 100%; height: 100%; object-fit: cover; opacity: .34; }
.wb-next-in { position: relative; padding: clamp(22px, 2vw, 30px); display: grid; gap: 14px; }
.wb-next-lab {
  font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--citrine); margin: 0;
}
.wb-next-name {
  margin: 0; font-family: var(--display); font-size: clamp(26px, 2.3vw, 36px);
  line-height: 1; letter-spacing: .01em; color: var(--pollen);
}
.wb-next-sub { margin: -6px 0 0; font-size: 13.5px; color: rgba(243,238,228,.78); line-height: 1.5; }
.wb-next-count { display: flex; gap: 10px; }
.wb-next-count div {
  flex: 1; text-align: center; padding: 9px 4px;
  border-radius: 10px; background: rgba(255,249,227,.07);
  border: 1px solid rgba(180,255,200,.14);
}
.wb-next-count b {
  display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 21px; font-weight: 600; line-height: 1; color: var(--pollen);
}
.wb-next-count i {
  font-style: normal; font-size: 9px; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(243,238,228,.62);
}
.wb-next-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-top: 13px; border-top: 1px solid rgba(180,255,200,.16);
}
.wb-next-price { font-size: 14px; font-weight: 600; color: var(--pollen); }
.wb-next-price small { display: block; font-size: 10px; font-weight: 400; letter-spacing: .1em; text-transform: uppercase; color: rgba(243,238,228,.6); }
.wb-rail-copy h1 {
  margin: 0 0 18px;
  font-family: var(--display);
  /* 8.4vw overshot badly on a laptop; 76px is already a very loud line
     in a condensed face */
  font-size: clamp(34px, 5.6vw, 76px);
  line-height: .95; letter-spacing: .01em;
  color: var(--leaf-white);
  max-width: 15ch;          /* 15 characters of Anton, not of Geist */
  text-wrap: balance;
}
/* the promise the product actually keeps, in the accent, on its own line */
.wb-rail-copy h1 em {
  font-style: normal; display: block; color: var(--citrine);
}
.wb-rail-lede {
  margin: 0; max-width: 46ch;
  color: #A9CBB2; font-size: clamp(15px, 1.5vw, 17.5px); line-height: 1.6;
}
.wb-rail-acts { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 26px; }
/* ways to pay — set as chips rather than a tick list, because these are
   options to choose between, not claims being made */
.wb-rail-pay {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 24px 0 0; padding: 0; list-style: none;
}
.wb-rail-pay::before {
  content: 'Pay with';
  font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
  color: #7FA98B; margin-right: 2px;
}
.wb-rail-pay li {
  font-size: 12px; font-weight: 600; letter-spacing: .05em;
  color: var(--leaf-white);
  padding: 7px 14px; border-radius: 999px;
  background: rgba(255,249,227,.08);
  border: 1px solid rgba(180,255,200,.22);
}

@media (max-width: 640px) {
  .wb-rail-copy { max-width: none; }
  .wb-rail-copy h1 { max-width: none; }
  .wb-rail-acts .wb-btn { flex: 1 1 auto; justify-content: center; }
  .wb-rail-pay { gap: 7px; }
  .wb-rail-pay li { font-size: 11.5px; padding: 6px 12px; }
}

@media (max-width: 640px) {
  /* ── the diagonal is a wide-screen gesture ───────────────
     Rotated -8deg, the leading card is sliced by the viewport edge: on a
     phone the first thing anyone saw was half a title and a price cut
     down the middle. Below 640px the tilt is dropped entirely and the row
     becomes an upright snap scroller — the same cards, the same order,
     legible, and swipeable in the direction a thumb already expects. */
  .rail-viewport {
    height: auto; overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 4px 0 26px;
    cursor: default;
  }
  .rail-viewport::-webkit-scrollbar { display: none; }
  .rail-tilt {
    position: static; width: auto; left: auto; top: auto;
    transform: none;
  }
  .rail-track { transform: none !important; padding-inline: clamp(16px, 4vw, 46px); }
  /* the duplicate run is what makes the mobile auto-advance wrap without a
     visible rewind: at the end of a set, scrollLeft steps back by exactly
     one run onto an identical card */
  .rail-run { display: flex; }
  .rail-card {
    width: min(78vw, 320px);
    aspect-ratio: 3 / 4.1;
    margin: 0 10px 0 0;
    scroll-snap-align: center;
    transform: none; opacity: 1; filter: none;
  }
  .rail-card:last-child { margin-right: clamp(16px, 4vw, 46px); }
  .rail-card.is-live { transform: none; box-shadow: 0 18px 44px -16px rgba(0,0,0,.8), 0 0 0 1px var(--gold-soft); }
  .rail-hint { display: none; }
  .wb-rail::after { height: 0; background: linear-gradient(90deg, transparent, var(--sun) 22%, var(--citrine) 50%, var(--sun) 78%, transparent) bottom / 100% 2px no-repeat; }
}

/* shown only when a film genuinely will not run, so a card is never an
   unexplained black rectangle */
.rail-play {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%,-50%);
  z-index: 4; cursor: pointer;
  background: rgba(10,10,9,.72);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.28);
  color: var(--pollen); font-size: 11px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 11px 20px; border-radius: 999px;
  display: none; max-width: 82%; text-align: center; line-height: 1.4;
}
.rail-card.film-stuck .rail-play { display: block; }


/* ── the panel on a phone ────────────────────────────────────────────
   Shown at every width now, not just above 1000px. Everything the desktop
   card carries is here — label, name, subtitle, live countdown, price and
   the link through — just stacked under the copy instead of beside it. */
@media (max-width: 999px) {
  .wb-next { margin-top: 4px; }
  .wb-next-in { padding: 20px; gap: 12px; }
  .wb-next-name { font-size: 26px; }
  .wb-next-count { gap: 7px; }
  .wb-next-count div { padding: 8px 2px; }
  .wb-next-count b { font-size: 19px; }
  .wb-next-foot { padding-top: 12px; }
  .wb-next-foot .wb-btn { flex: 1 1 auto; justify-content: center; }
}
@media (max-width: 380px) {
  .wb-next-count b { font-size: 17px; }
  .wb-next-count i { font-size: 8px; letter-spacing: .1em; }
}
