/* ============================================================================
   byd.css — Book Yacht Dubai, "byd-voyage" (worldflight)
   Tokens override engine --sc-* vars (scrollcraft.css). All copy strings live
   in index.html and js/byd.js; nothing here is a component with baked text.
   ========================================================================== */

/* --------------------------------------------------------------- fonts --- */
@font-face {
  font-family: "Archivo Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  src: url("../fonts/archivo-latin-wdth-normal.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Karla";
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url("../fonts/karla-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Karla";
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url("../fonts/karla-latin-500-normal.woff2") format("woff2");
}

/* --------------------------------------------------------------- tokens --- */
:root {
  --sc-canvas:     #07141C;
  --sc-surface:    #0C2B3A;
  --sc-ink:        #F2F5F6;
  --sc-ink-soft:   #C4D6DA;

  --sun:           #F5CF74;
  --sc-accent:     var(--sun);
  --sc-accent-ink: #0C2B3A;

  --wa:            #15803D;
  --wa-hover:      #166534;

  /* Sun-tinted glass (motion-story-06): a color-mix keyed on --sun, so every
     consumer re-tints itself each frame as --sun moves, with no per-frame JS
     writes needed on the glass surfaces themselves. Less tint (90/10, was
     86/14) and a stronger opaque base (84%, was 66%) so the tint can never
     pull pill or plate text (or the gauge chip) under 4.5:1 over bright
     footage (chrome-N1/N2/N3/story-03; value picked by measurement). */
  --glass:         color-mix(in oklab, color-mix(in oklab, #0C2B3A 90%, var(--sun)) 84%, transparent);
  --glass-line:    color-mix(in oklab, #F2F5F6 16%, transparent);
  --scrim:         rgba(7, 20, 28, .6);

  --sc-font-display: "Archivo Variable", system-ui, sans-serif;
  --sc-font-text:    "Karla", system-ui, sans-serif;

  --radius: 12px;
  --gauge-h: 38vh;
  /* Width of the sun gauge's own track/disc/readout strip at the right edge
     (the gauge component itself, below). No right-anchored copy block needs
     to clear it any more: the leg-2 plate moved to the left edge and the
     finale card aligns to the pill's own edge instead, because the gauge is
     always hidden before either is visible (FIX-4 items 1/2). Widened for
     the readout's own glass chip (chrome-N1/chrome-N3). */
  --gauge-lane: 8.5rem;
  /* The pill's own bottom edge, safe-area included: 12px top offset + the
     pill's own height (60px, 56px below 700px width) + the top safe-area
     inset. Every top-anchored copy block clears this on short viewports
     instead of the fixed clamp() alone (story-01). */
  --pill-bottom: calc(12px + env(safe-area-inset-top, 0px) + 60px);
  /* Shared frame edge: the pill's own left/right (82rem centred, i.e.
     --sc-maxw) above ~1488px, the ordinary gutter below it. Every
     lead-anchored block, trail-anchored block and the finale container use
     this instead of --sc-gutter directly so they stay aligned to the pill's
     edges at wide desktop widths (design-desktop-06). */
  --edge: max(var(--sc-gutter), calc((100vw - var(--sc-maxw)) / 2));
}

body {
  margin: 0;
  background: var(--sc-canvas);
  color: var(--sc-ink);
  font-family: var(--sc-font-text);
  font-weight: 450;
  font-size: 1.0625rem;
}

/* --------------------------------------------------------- utility type --- */
.byd-eyebrow,
.rail__leg,
.rail-compact__label,
.gauge__readout,
.chip span,
.field__label,
.field > label,
.field > legend,
.field__help,
.field__error,
.field__note {
  font-family: var(--sc-font-display);
  font-stretch: 100%;
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- display -- */
.sc-finale h2,
[data-sc-copy] h1,
[data-sc-copy] h2 {
  font-family: var(--sc-font-display);
  font-stretch: 125%;
  font-weight: 560;
  letter-spacing: -0.025em;
  line-height: 1.02;
  text-wrap: balance;
  margin: 0;
}
[data-sc-copy] p,
[data-sc-copy] li {
  font-family: var(--sc-font-text);
  font-weight: 450;
  line-height: 1.6;
  text-wrap: pretty;
}

h1.byd-h1 {
  font-size: clamp(2.3rem, 1.2rem + 3.6vw, 4.4rem);
}
h2.byd-leg-h2 {
  font-size: clamp(1.7rem, 1.1rem + 2.2vw, 3rem);
  /* Explicit, not just inherited from [data-sc-copy] h2 above, so the plate
     heading's line breaks stay under the balance algorithm rather than
     ordinary greedy wrap (design-desktop-15). */
  text-wrap: balance;
}
h2.byd-peak {
  font-size: clamp(2.2rem, 1.2rem + 3.8vw, 5rem);
}
/* Peak ink lives on the copy block itself (design-desktop-17): the QA
   harness grades [data-sc-copy]'s own computed color, so setting it on the
   h2 alone (inherited-light-on-dark from the block) made the tool grade a
   colour nobody actually sees. */
#copy-peak {
  color: #0C2B3A;
}

/* -------------------------------------------------------------- glass ---- */
.byd-glass {
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--glass-line);
  box-shadow: var(--sc-edge), var(--sc-e2);
}
@media (prefers-reduced-transparency: reduce) {
  .byd-glass {
    background: var(--sc-surface);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* ------------------------------------------------------------- posters --- */
/* The engine only covers direct <video>/<img>/<canvas> children of a leg; our
   <picture> wrapper around the poster falls outside that selector and sits in
   document flow. Pin it (and the img inside it) to fill the leg like the
   video does, so nothing but the spacer is ever in flow. */
.sc-world__seg > picture {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.sc-world__seg > picture > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Leg 4's horizon otherwise sits noticeably higher than leg 3's at the seam,
   reading as a jump cut (motion-story-05 part 3). Scaling from the top edge
   pushes it down to line up. Uses `scale`, not `transform`, which the engine
   writes inline on the video element for the scrub itself. */
.sc-world__seg:nth-child(4) > video,
.sc-world__seg:nth-child(4) > picture > img {
  transform-origin: 50% 0;
  scale: 1.25;
}

/* ------------------------------------------------------------ skip link -- */
.skip {
  position: fixed;
  z-index: 100;
  top: var(--sc-3);
  left: var(--sc-3);
  padding: var(--sc-3) var(--sc-4);
  background: var(--sc-surface);
  color: var(--sc-ink);
  border-radius: var(--radius);
  transform: translateY(-150%);
  transition: transform 160ms var(--sc-ease-out);
}
.skip:focus-visible {
  transform: translateY(0);
}

/* ------------------------------------------------------------------ pill -- */
.pill {
  position: fixed;
  z-index: 90;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: var(--sc-gutter);
  right: var(--sc-gutter);
  max-width: 82rem;
  margin-inline: auto;
  height: 60px;
  display: flex;
  align-items: center;
  gap: var(--sc-6);
  padding-inline: var(--sc-5);
  border-radius: var(--radius);
}
.pill__mark {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--sc-font-display);
  font-stretch: 125%;
  font-size: 1rem;
  font-weight: 560;
  letter-spacing: -0.025em;
  color: var(--sc-ink);
  text-decoration: none;
  white-space: nowrap;
}

/* -------------------------------------------------------- desktop rail --- */
/* No connector line: a line drawn behind the waypoint labels reads as a
   strike-through. The current waypoint carries its own underline instead. */
.rail {
  display: none;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: var(--sc-6);
  height: 100%;
}
.rail__leg {
  position: relative;
  background: none;
  border: 0;
  padding: var(--sc-2) var(--sc-1);
  color: var(--sc-ink-soft);
  cursor: pointer;
  white-space: nowrap;
  transition: color 160ms var(--sc-ease-out);
}
.rail__leg[aria-current="step"] {
  color: var(--sc-ink);
}
.rail__leg[aria-current="step"]::after {
  content: "";
  position: absolute;
  left: var(--sc-1);
  right: var(--sc-1);
  bottom: -6px;
  height: 2px;
  background: var(--sun);
}
@media (hover: hover) and (pointer: fine) {
  .rail__leg:hover { color: var(--sc-ink); }
}
.rail__leg:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 3px;
  border-radius: var(--sc-r-sm);
}

/* ------------------------------------------------------------ pill wa ---- */
.btn.pill__wa {
  display: none;
  flex: none;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sc-2);
  height: 44px;
  padding-inline: var(--sc-5);
  border-radius: var(--radius);
  font-family: var(--sc-font-text);
  font-weight: 500;
  font-size: var(--sc-t-sm);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 140ms var(--sc-ease-out),
              transform 140ms var(--sc-ease-out),
              box-shadow 140ms var(--sc-ease-out);
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 3px;
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--primary {
  background: var(--sun);
  color: var(--sc-accent-ink);
}
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { background: color-mix(in oklab, var(--sun) 88%, white); }
}

.btn--wa {
  background: var(--wa);
  color: #F2F5F6;
}
@media (hover: hover) and (pointer: fine) {
  .btn--wa:hover { background: var(--wa-hover); }
}
.btn--wa .icon { width: 1.1em; height: 1.1em; flex: none; }

.btn--block { width: 100%; }

.byd-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sc-3);
  margin-top: var(--sc-6);
}

/* --------------------------------------------------------- compact rail -- */
.rail-compact {
  display: none;
  flex: 1;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sc-3);
  min-width: 0;
}
.rail-compact__label {
  color: var(--sc-ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rail-compact__ticks {
  display: flex;
  gap: var(--sc-1);
  flex: none;
}
.rail-compact__tick {
  width: 44px;
  height: 44px;
  border: 0;
  background: none;
  position: relative;
  cursor: pointer;
}
.rail-compact__tick::after {
  content: "";
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  width: 6px;
  height: 6px;
  border-radius: 9999px;
  background: var(--glass-line);
}
.rail-compact__tick[aria-current="step"]::after {
  background: var(--sun);
}
.rail-compact__tick:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 2px;
  border-radius: var(--sc-r-sm);
}

/* ----------------------------------------------------------------- fab --- */
.fab {
  position: fixed;
  z-index: 85;
  right: calc(var(--sc-4) + env(safe-area-inset-right, 0px));
  bottom: calc(var(--sc-4) + env(safe-area-inset-bottom, 0px));
  width: 56px;
  height: 56px;
  border-radius: 9999px;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--wa);
  color: #fff;
  box-shadow: var(--sc-e2);
  transition: background-color 140ms var(--sc-ease-out), transform 140ms var(--sc-ease-out),
              opacity 160ms var(--sc-ease-out), visibility 0s linear 0s;
}
.fab .icon { width: 26px; height: 26px; }
@media (hover: hover) and (pointer: fine) {
  .fab:hover { background: var(--wa-hover); }
}
.fab:active { transform: translateY(1px); }
.fab:focus-visible { outline: 2px solid var(--sun); outline-offset: 3px; }
/* Hidden whenever the hero or the finale block is on screen: each of those
   has its own WhatsApp button, so the FAB would otherwise duplicate or
   overlap it (builder-logic-01/design-mobile-04/design-mobile-08). Opacity +
   delayed visibility, not display:none, so the fade is not truncated. */
.fab.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: background-color 140ms var(--sc-ease-out), transform 140ms var(--sc-ease-out),
              opacity 160ms var(--sc-ease-out), visibility 0s linear 160ms;
}

/* --------------------------------------------------------------- gauge --- */
/* Lives entirely inside the reserved --gauge-lane strip at the right edge
   (right: 0, width: the lane), so nothing it draws can cross into a
   right-anchored plate or card. The track sits flush against the lane's
   right edge; ticks extend to the right of it only, the disc sits centred
   ON it, and the readout sits to its left, so none of the three can ever
   cross another (design-desktop-01/motion-story-07). */
.gauge {
  display: none;
  position: fixed;
  z-index: 40;
  right: 0;
  top: 50%;
  translate: 0 -50%;
  height: var(--gauge-h);
  width: var(--gauge-lane);
  align-items: flex-end;
  flex-direction: column;
  padding-right: 18px;
  transition: opacity 180ms var(--sc-ease-out), visibility 0s linear 0s;
}
/* Hidden while the finale card is open: the gauge overlaps it otherwise.
   Delay visibility so the opacity fade is not truncated. */
.gauge.is-hidden {
  opacity: 0;
  visibility: hidden;
  transition: opacity 180ms var(--sc-ease-out), visibility 0s linear 180ms;
}
.gauge__track {
  position: relative;
  width: 1px;
  height: 100%;
  background: var(--glass-line);
}
.gauge__tick {
  position: absolute;
  left: 0;
  translate: 0 -50%;
  width: 8px;
  height: 1px;
  background: var(--sc-ink-soft);
}
.gauge__tick--30 { top: 5%; }
.gauge__tick--15 { top: 42.5%; }
.gauge__tick--0 { top: 80%; width: 14px; }
.gauge__tick--6 { top: 95%; }
/* Disc and readout each get their own translateY (set identically, every
   frame, by byd.js), using the exact same top:0 + altitude fraction mapping
   the ticks use above, instead of sharing one group transform whose centre
   was the midpoint of both elements rather than the disc alone. */
.gauge__disc {
  position: absolute;
  left: 0;
  top: 0;
  translate: -50% -50%;
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 9999px;
  background: var(--sun);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--sun) 40%, transparent);
  transition: background-color 160ms var(--sc-ease-out);
}
.gauge__readout {
  position: absolute;
  right: calc(100% + 20px);
  top: 0;
  translate: 0 -50%;
  white-space: nowrap;
  text-align: right;
  color: var(--sc-ink);
}
/* Its own small glass chip (chrome-N1/chrome-N3): unreadable straight over
   bright footage otherwise, and the bare text ran into the disc's halo ring. */
.gauge__readout.byd-glass {
  padding: 4px 8px;
  border-radius: var(--radius);
}

/* ---------------------------------------------------------- world copy --- */
.byd-lede {
  max-width: 40ch;
}

/* leg 2: trail, one marine glass plate (the plate is what guarantees
   contrast here, so this block carries no scrim of its own). Left-aligned
   throughout: the trail anchor's own text-align: right is for a single short
   line, not a plate of body copy. */
.byd-leg2 {
  max-width: 30rem;
  border-radius: var(--radius);
  padding: var(--sc-5);
  text-align: left;
}
/* FIX-4 item 1: the plate previously widened to 38rem so a 3-word heading at
   the default clamp() size fit on one line, but that width is what let it
   reach far enough right to sit on the boat/wake (d1440 frame 16, leg-2 local
   ~0.3-0.5) once the block moved to the right side. Narrower at 30rem, with
   the heading pinned to --sc-t-xl instead of the wider clamp(), keeps "How
   booking works" on one line at the smaller width (design-desktop-15). */
@media (min-width: 980px) {
  .byd-leg2 { max-width: 30rem; }
  .byd-leg2 h2.byd-leg-h2 { font-size: var(--sc-t-xl); }
}
@media (max-width: 420px) {
  .byd-leg2 { padding: var(--sc-4); }
  .byd-leg2 h2.byd-leg-h2 { font-size: 1.55rem; }
}
@media (max-width: 340px) {
  .byd-leg2 h2.byd-leg-h2 { font-size: 1.35rem; }
}
.byd-steps {
  margin: var(--sc-4) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--sc-3);
  counter-reset: step;
}
/* One row per step: a numeral column top-aligned with the paragraph's first
   line, and the label + sentence as one inline paragraph (not stacked). */
.byd-steps li {
  counter-increment: step;
  display: flex;
  align-items: flex-start;
  gap: var(--sc-3);
}
.byd-steps li::before {
  content: counter(step);
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: var(--radius);
  background: var(--glass);
  border: 1px solid var(--glass-line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sc-font-display);
  font-stretch: 100%;
  font-weight: 500;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--sc-ink);
}
/* One real child so the flex row above sees exactly two items (numeral,
   text); without this wrapper the <strong> and the trailing text node each
   became their own flex item and split onto separate columns. */
.byd-step-text {
  min-width: 0;
}
.byd-steps strong {
  color: var(--sc-ink);
  font-weight: 500;
}

/* leg 3: single line, lower centre */
.byd-line-xl {
  /* Resets the UA <p> margin, which otherwise sits this block 36px higher
     than the other bottom-anchored copy (design-desktop-16). */
  margin: 0;
  font-size: var(--sc-t-xl);
  color: var(--sc-ink);
  text-align: center;
  max-width: 32ch;
}
/* [data-sc-copy] p's own text-wrap: pretty (byd.css, display type rules)
   otherwise beats a plain .byd-line-xl { text-wrap: balance } on specificity,
   so phones kept a lopsided 5+2-word split (story-07). The id-scoped
   selector here outranks it. */
#copy-leg3 .byd-line-xl {
  text-wrap: balance;
}

/* leg 5: lead, occasions + lineage */
.byd-occasions,
.byd-lineage {
  max-width: 42ch;
}

/* ----------------------------------------------------------- scrims ----- */
/* The whole page regrades with the sun (6.2), scrims included: every scrim
   is retinted from --scrim instead of the engine's static --sc-canvas mix.
   Scrims are plain siblings of their copy block, not [data-sc-copy] blocks
   themselves: the harness hides every [data-sc-copy] element to photograph
   the bare background, so a scrim tagged that way was never being measured
   (and the engine handed it pointer events while visible). byd.js copies
   each copy block's own inline opacity onto its scrim (data-byd-scrim-for)
   every frame instead, so the scrim still fades with its text. */
.sc-world__scrim { pointer-events: none !important; }

.sc-scrim {
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--scrim) 78%, transparent) 0%,
    color-mix(in oklab, var(--scrim) 30%, transparent) 42%,
    transparent 68%);
}
/* color-mix against transparent is capped by --scrim's own alpha (tops out
   around 0.5), so the hero lede and H1 kept failing contrast wherever the
   footage behind them was already bright (new-01/story-02) even though the
   other scrims below were already fixed with a flat alpha wash. Same fix,
   applied here too. */
.sc-scrim--lead {
  background: linear-gradient(to top right,
    rgb(from var(--scrim) r g b / 0.94) 0%,
    rgb(from var(--scrim) r g b / 0.72) 30%,
    rgb(from var(--scrim) r g b / 0.30) 52%,
    transparent 72%);
}
/* leg 3: strengthened to clear 4.5:1 on the worst frame. A flat 0.8-alpha
   wash of the sun-tinted scrim colour, not a color-mix of it (color-mix
   against transparent is capped by --scrim's own alpha, which tops out
   around 0.5 through this leg), fading out by 45% up the frame. */
.sc-scrim--band {
  background: linear-gradient(to top,
    rgb(from var(--scrim) r g b / 0.8) 0%,
    transparent 45%);
}
/* leg 5: lead anchored upper-left (the engine's own .sc-copy--lead is
   bottom-anchored, built for the hero); mirror the corner the other way.
   Strengthened past --scrim's own alpha ceiling for the body lines. */
.sc-scrim--lead-top {
  background: linear-gradient(to bottom right,
    rgb(from var(--scrim) r g b / 0.86) 0%,
    rgb(from var(--scrim) r g b / 0.64) 32%,
    rgb(from var(--scrim) r g b / 0.28) 54%,
    transparent 74%);
}
/* leg 4 (peak): the sky itself is lit, so the fix inverts the type to marine
   ink instead of darkening the footage; this is a soft light wash, not a
   dark scrim. */
.sc-scrim--peak {
  background: radial-gradient(ellipse 60% 45% at 50% 24%,
    rgb(255 244 232 / .42), transparent 70%);
}
@media (max-width: 860px) {
  /* leg 5's mobile copy sits at the TOP of the frame (.sc-copy--lead-top), so
     the dense part of the band has to be a TOP band here, not a bottom one:
     the desktop corner scrim points the same way it does above, this is a
     mobile-only re-point. The stops below hold density further down the
     frame than the first pass did, which still left the lineage paragraph
     under 4.5:1 (design-mobile-06). */
  .sc-scrim--lead-top {
    background: linear-gradient(to bottom,
      rgb(from var(--scrim) r g b / 0.86) 0%,
      rgb(from var(--scrim) r g b / 0.72) 40%,
      rgb(from var(--scrim) r g b / 0.36) 60%,
      transparent 76%);
  }
  /* Mirrors the desktop hero fix above, re-pointed for the hero's own
     bottom-anchored mobile band. */
  .sc-scrim--lead {
    background: linear-gradient(to top,
      rgb(from var(--scrim) r g b / 0.9) 0%,
      rgb(from var(--scrim) r g b / 0.76) 38%,
      rgb(from var(--scrim) r g b / 0.34) 58%,
      transparent 74%);
  }
}

/* ----------------------------------------------------- copy anchors ----- */
/* Every lead-anchored block aligns to the pill's own left edge, not the bare
   gutter, above ~1488px (design-desktop-06). */
.sc-copy--lead {
  left: var(--edge);
}
@media (min-width: 980px) {
  /* FIX-4 item 1: the leg-2 plate (the only trail block today) sat bottom-
     right and covered the boat and its wake (d1440 frame 16). Move it to the
     left, anchored at the pill's own edge like the lead blocks, and vertically
     centre it in the space below the pill (--pill-bottom to 100vh) instead of
     pinning it to the bottom, so the centre-to-lower-centre of the frame
     where the boat travels stays open water. `top` + the standalone `translate`
     property, never `transform`, which the engine writes inline for the
     parallax drift. */
  .sc-copy--trail {
    left: var(--edge);
    right: auto;
    bottom: auto;
    top: calc(50vh + var(--pill-bottom) / 2);
    translate: 0 -50%;
  }
}
/* leg 5: lead, upper left (the built-in .sc-copy--lead sits bottom-left). */
.sc-copy--lead-top {
  bottom: auto;
  top: clamp(3rem, 12vh, 9rem);
}
/* leg 3 and leg 4: centred anchors. left:50% + translate:-50% alone
   shrink-to-fits the box into (containing block - left), i.e. 50vw, so the
   max-width below never actually binds (design-mobile-03, design-desktop-07).
   An explicit width gives the centring something real to centre. */
.sc-copy--lower,
.sc-copy--upper {
  width: min(64rem, calc(100vw - 2 * var(--edge)));
}
/* leg 3: one line, lower centre. */
.sc-copy--lower {
  inset-inline: auto;
  left: 50%;
  bottom: clamp(3rem, 12vh, 9rem);
  translate: -50% 0;
  text-align: center;
}
/* leg 4: peak heading, centred on the upper third. */
.sc-copy--upper {
  inset-inline: auto;
  left: 50%;
  top: clamp(3rem, 14vh, 10rem);
  translate: -50% 0;
  text-align: center;
}
/* Short and landscape viewports: the clamp()s above resolve well above the
   pill (they were sized for portrait phones and desktop, never for a wide,
   short window), so the peak line and the leg-5 heading slid under it
   (story-01, blocker). Floor both at the pill's real bottom edge plus a gap,
   and step the two headings down one size so the shorter block still reads
   as one clear line instead of pushing lower into the frame. */
@media (max-height: 520px) {
  .sc-copy--lead-top,
  .sc-copy--upper {
    top: calc(var(--pill-bottom) + var(--sc-4) + 2vh);
  }
  h2.byd-leg-h2 { font-size: clamp(1.4rem, 1rem + 1.6vw, 2rem); }
  h2.byd-peak { font-size: clamp(1.8rem, 1.1rem + 2.6vw, 3.2rem); }
}

/* --------------------------------------------------------------- finale -- */
/* Transparent fixed container; the card and the info column carry their own
   backgrounds (or none) rather than the section itself. 88px top = the pill's
   bottom edge (12px top + 60px tall) plus a 16px gap. max-width: none beats
   the engine's inherited .sc-copy max-width (design-desktop-02/motion-
   story-11/a11y-02) so the grid can actually claim the space it needs. */
.sc-finale {
  position: fixed;
  max-width: none;
  top: 88px;
  left: var(--edge);
  right: var(--edge);
  bottom: 24px;
}
@media (min-width: 980px) {
  .sc-finale {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 30rem;
    /* A definite row (not the default auto-sized track) so the card's
       max-height: 100% fallback below has something real to resolve
       against, instead of collapsing to its own min-content. */
    grid-template-rows: minmax(0, 1fr);
    column-gap: var(--sc-7);
    align-items: end;
    /* The engine drifts every [data-sc-copy] block by up to -2vh across its
       window (translate3d), which ate the 16px gap this inset was designed
       around (design-desktop-03/motion-story-03). Compensating the top by
       the same 2vh keeps the card clear of the pill at settle without
       fighting the inline transform. */
    top: calc(88px + 2vh + env(safe-area-inset-top, 0px));
    /* FIX-4 item 2: previously reserved the gauge's lane too, leaving the
       card's right edge ~110px short of the pill's own right edge even
       though the gauge is always hidden by the time the finale is visible
       (byd.js is-hidden threshold, below). Align to the pill's edge directly. */
    right: var(--edge);
  }
}
.finale__card {
  border-radius: var(--radius);
  /* FIX-4 item 5: the finale sits over leg 5's brightest frame (the lit EMAAR
     sign), which showed through the shared --glass token's 84% base. A
     card-only, higher-opacity variant of the same tint formula (92%, still
     retinted by --sun every frame) fixes the show-through without changing
     --glass for the pill/plate/FAQ/gauge chip. Overridden to no background at
     all below 980px, where the outer sheet carries the glass instead. */
  background: color-mix(in oklab, color-mix(in oklab, #0C2B3A 90%, var(--sun)) 92%, transparent);
  /* The finale is the "card width" @container context the builder row
     below queries (design-mobile-02/design-desktop-10) at every width, not
     only the >= 980px desktop layout, so the mobile bottom sheet (often
     wider than the 480px desktop card) can still go two-column once it has
     the room. */
  container-type: inline-size;
}
@media (min-width: 980px) {
  .finale__card {
    grid-column: 2;
    /* Without an explicit row, auto-placement gives this item and
       .finale__info separate implicit rows (each column claims its own
       track), and the 1fr row above only gets the leftover space. Both
       belong in the grid's one real row. */
    grid-row: 1;
    align-self: start;
    max-height: 100%;
    overflow-y: auto; /* fallback only: the card is compressed to fit without it */
    padding: var(--sc-6) var(--sc-5);
  }
}
.finale__info {
  display: flex;
  flex-direction: column;
  gap: var(--sc-7);
}
@media (min-width: 980px) {
  .finale__info {
    grid-column: 1;
    grid-row: 1;
    max-width: 36rem;
    /* An opened FAQ answer must not push the questions above it off-screen
       (design-desktop-04/a11y-02): the column scrolls internally instead. */
    max-height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}
.sc-finale__title {
  font-size: var(--sc-t-xl);
}

/* ---------------------------------------------------------------- form -- */
.builder {
  margin-top: var(--sc-6);
  display: flex;
  flex-direction: column;
  gap: var(--sc-4);
  /* The date input's dark background needs the native picker (icon + popup
     chrome) to follow, or the calendar icon paints black-on-navy
     (design-mobile-12). */
  color-scheme: dark;
}
/* Date and Guests stack by default and only sit side by side once the card
   itself (not the viewport) has room for both min-content widths
   (design-mobile-02/design-desktop-10); min-width: 0 on the grid children
   is what lets the row actually shrink instead of forcing a horizontal
   scroll on the narrowest phones. */
.builder__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sc-4);
}
.builder__row > .field {
  min-width: 0;
}
@container (min-width: 420px) {
  .builder__row {
    grid-template-columns: 1fr 1fr;
  }
}
.field {
  display: flex;
  flex-direction: column;
  gap: var(--sc-2);
  border: 0;
  padding: 0;
  margin: 0;
}
.field > label,
.field > legend {
  color: var(--sc-ink);
  padding: 0;
}
.field input[type="date"],
.field input[type="text"] {
  width: 100%;
  min-width: 0;
  height: 44px;
  padding-inline: var(--sc-4);
  border-radius: var(--radius);
  border: 1px solid var(--glass-line);
  background: color-mix(in oklab, var(--sc-surface) 60%, transparent);
  color: var(--sc-ink);
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-base);
}
.field input:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 2px;
}
/* A native <input type="date">'s internal segments (month/day/year/the
   calendar-icon toggle) move focus into the control's own UA shadow root, so
   :focus-visible on the host stops matching partway through and the ring
   disappears (new-02). :focus-within on the wrapping .field stays true
   across every segment, so key the ring off that instead. */
.field:has(input:focus-within) input:not(:focus-visible) {
  outline: 2px solid var(--sun);
  outline-offset: 2px;
}
.field input[aria-invalid="true"] {
  border-color: color-mix(in oklab, var(--sun) 60%, transparent);
}
.field__error {
  color: var(--sun);
}
.field__error[hidden] { display: none; }
.field__note[hidden] { display: none; }
/* Lives inside the Time-of-day <legend> now (small, one line) rather than
   below the chips, so the auto-preselection reads as an annotation on the
   label it explains instead of a separate block (design-desktop-05). On
   phones the legend is too narrow for label plus note and it wraps; letting
   the legend itself wrap (instead of the note alone) keeps the wrapped note
   left-aligned with the label above it, not indented under it (story-05). */
.field--chips > legend:has(#lingered-note:not([hidden])) {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--sc-2);
  row-gap: 2px;
}
#lingered-note {
  color: var(--sc-ink-soft);
  font-weight: 500;
  margin-left: 0;
  white-space: nowrap;
}
#lingered-note[hidden] { display: none; }

/* chips */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sc-2);
}
.chip {
  position: relative;
}
.chip input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.chip span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--sc-4);
  border-radius: var(--radius);
  border: 1px solid var(--glass-line);
  background: color-mix(in oklab, var(--sc-surface) 55%, transparent);
  color: var(--sc-ink-soft);
  cursor: pointer;
  transition: background-color 140ms var(--sc-ease-out),
              color 140ms var(--sc-ease-out),
              border-color 140ms var(--sc-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .chip:hover span { border-color: var(--sun); }
}
.chip input:checked + span {
  background: var(--sun);
  color: var(--sc-accent-ink);
  border-color: var(--sun);
}
.chip input:focus-visible + span {
  outline: 2px solid var(--sun);
  outline-offset: 2px;
}
.chip input:active + span {
  transform: translateY(1px);
}
/* FIX-4 item 6: flex-wrap left an orphan chip alone on its own row once the
   card narrowed past a phone width (e.g. "6+ hours" or "Night" alone at
   390px). Below 480px of card width, lay each chip row out on a grid sized to
   its own option count instead, so every row fills evenly: Occasion 3
   columns (6 options, two full rows), Duration 4 columns (4 options, one
   row), Time of day 2 columns (4 options, two full rows). The three chip
   groups share the same .chips container class, so :has() on the radio name
   picks out which column count applies to which row. */
/* Phones only: the desktop card is also under 480px wide (30rem minus
   padding), where the wrapped chip rows already fit; applying the grid there
   made the card overflow at 1366x768 and 1280x720 (FIX-4 regression). */
@media (max-width: 979px) {
  @container (max-width: 479px) {
    .chips {
      display: grid;
      gap: var(--sc-2);
    }
    .chips:has(input[name="occasion"]) { grid-template-columns: repeat(3, 1fr); }
    .chips:has(input[name="duration"]) { grid-template-columns: repeat(4, 1fr); }
    .chips:has(input[name="timeOfDay"]) { grid-template-columns: repeat(2, 1fr); }
    .chips .chip { min-width: 0; }
    .chips .chip span {
      width: 100%;
      min-width: 0;
      justify-content: center;
      text-align: center;
      padding-inline: var(--sc-2);
      font-size: 0.75rem;
    }
  }
}

/* guest stepper: the input is flex:1 (not a fixed width) so it absorbs
   whatever space the minus/plus buttons don't use, which is what actually
   centres the number and lets the group span the field's full width
   (design-desktop-10) instead of stopping short of it. */
.stepper {
  display: flex;
  align-items: center;
  gap: var(--sc-2);
}
.stepper__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--radius);
  border: 1px solid var(--glass-line);
  background: color-mix(in oklab, var(--sc-surface) 55%, transparent);
  color: var(--sc-ink);
  cursor: pointer;
  transition: background-color 140ms var(--sc-ease-out), transform 140ms var(--sc-ease-out);
}
.stepper__btn .icon { width: 16px; height: 16px; }
@media (hover: hover) and (pointer: fine) {
  .stepper__btn:hover { background: color-mix(in oklab, var(--sc-surface) 80%, transparent); }
}
.stepper__btn:active { transform: translateY(1px); }
.stepper__btn:focus-visible { outline: 2px solid var(--sun); outline-offset: 2px; }
.stepper__btn:disabled { opacity: 0.4; cursor: not-allowed; }
.stepper input {
  flex: 1;
  min-width: 0;
  height: 44px;
  text-align: center;
  border-radius: var(--radius);
  border: 1px solid var(--glass-line);
  background: color-mix(in oklab, var(--sc-surface) 60%, transparent);
  color: var(--sc-ink);
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-base);
  font-variant-numeric: tabular-nums;
  appearance: textfield;
  -moz-appearance: textfield;
}
.stepper input::-webkit-inner-spin-button,
.stepper input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* .builder's own flex gap only separates .builder__submit from its
   siblings, not the button from its own helper text inside it, which left
   them touching (qa2r2-help-gap-zero). */
.builder__submit {
  display: flex;
  flex-direction: column;
  gap: var(--sc-3);
}
/* Last-resort fallback: if the card ever still needs its own scroll (a long
   lingered-note state, an unusually short viewport), the submit stays
   reachable without scrolling to the very end (design-desktop-05). The
   padding-top alone (no compensating negative margin) keeps the field above
   it at the builder's own gap or more, never less (design-desktop-11: the
   negative margin previously cut that gap from 16px to 4px). */
@media (min-width: 980px) {
  .builder__submit {
    position: sticky;
    bottom: 0;
    background: var(--glass);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    padding-top: var(--sc-3);
  }
}

.field__help--submit {
  margin: 0;
  text-align: center;
  color: var(--sc-ink-soft);
}

/* faq (spaced from the card by .finale__info's own gap, not its own margin,
   now that it lives in a separate column/block at desktop) */
/* Motion-story-06: the FAQ is one of the four glass surfaces the sun regrade
   tints, so it gets the same treatment leg-2's plate and the finale card
   already carry, and stops reading as bare text over the finale's exclusive
   FAQ accordion. */
.faq.byd-glass {
  border-radius: var(--radius);
  padding: var(--sc-5);
}
.faq {
  display: flex;
  flex-direction: column;
  gap: var(--sc-2);
}
.faq__item {
  border-top: 1px solid var(--glass-line);
}
/* FIX-4 item 3: the panel's own border (.faq.byd-glass) already frames the
   first question; this item's own border-top on top of that read as a
   redundant hairline sitting just inside the panel edge, and made the gap
   above the first question look tighter than the gap below the last one. */
.faq__item:first-child {
  border-top: none;
}
.faq__item summary {
  cursor: pointer;
  list-style: none;
  color: var(--sc-ink);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sc-3);
  min-height: 44px;
  padding-block: var(--sc-3);
}
.faq__item summary::-webkit-details-marker { display: none; }
/* Disclosure chevron: the native marker is suppressed above and nothing
   replaced it, so the questions read as static text (design-desktop-13). */
.faq__item summary::after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  rotate: 45deg;
  transition: rotate 160ms var(--sc-ease-out);
}
.faq__item[open] summary::after {
  rotate: -135deg;
}
.faq__item summary h3 {
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-base);
  font-weight: 500;
  margin: 0;
}
@media (hover: hover) and (pointer: fine) {
  .faq__item summary:hover h3 { color: var(--sun); }
}
.faq__item summary:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 2px;
  border-radius: var(--sc-r-sm);
}
.faq__item[open] summary h3 { color: var(--sun); }
.faq__item p {
  margin: var(--sc-2) 0 var(--sc-3);
  color: var(--sc-ink-soft);
}

/* colophon (spaced from the FAQ by .finale__info's own gap; the border stays
   as its own visual divider) */
.colophon {
  padding-top: var(--sc-4);
  border-top: 1px solid var(--glass-line);
  display: flex;
  flex-direction: column;
  gap: var(--sc-1);
  color: var(--sc-ink-soft);
  font-size: var(--sc-t-xs);
}
/* Keeps the phone number from splitting across two lines inside the narrow
   info column (design-desktop-12). */
.nowrap { white-space: nowrap; }

/* --------------------------------------------------------------- no-js --- */
.no-js .gauge,
.no-js .fab,
.no-js .rail-compact,
.no-js .rail { display: none !important; }
.no-js .sc-world { position: static; height: auto; }
.no-js .sc-world__seg { display: none; }
.no-js .sc-world__seg:first-child {
  display: block;
  position: static;
  height: 60svh;
  opacity: 1 !important;
  visibility: visible !important;
}
.no-js .sc-world__seg:first-child video { display: none; }
.no-js .sc-world__seg .sc-world__poster {
  position: static;
  width: 100%;
  height: 100%;
  transform: none !important;
}
.no-js .sc-world__copy {
  position: static;
  background: var(--sc-surface);
  pointer-events: auto;
}
.no-js .sc-world__scrim { display: none; }
.no-js [data-sc-copy] {
  position: static;
  opacity: 1 !important;
  pointer-events: auto !important;
  transform: none !important;
  max-width: none;
  inset-inline: 0;
  width: auto;
  padding: var(--sc-7) var(--sc-gutter);
  translate: none;
}
.no-js .sc-finale {
  max-height: none;
  overflow-y: visible;
  width: auto;
}
.no-js [data-sc-spacer] { display: none; }
.no-js .pill { position: static; margin-bottom: var(--sc-4); }

/* -------------------------------------------------------- reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  .gauge, .gauge__disc { transition: none; }
  .btn, .chip span, .stepper__btn, .fab, .skip, .faq__item summary::after { transition: none; }
}

/* --------------------------------------------------------------- mobile -- */
@media (min-width: 980px) {
  .rail { display: flex; }
  .btn.pill__wa { display: inline-flex; }
  .gauge { display: flex; }
  /* The rail centres in the leftover space between the wordmark and the
     WhatsApp button, not on the page's own centred axis, which is visibly
     off from the centred copy blocks that appear under it
     (design-desktop-14). A grid gives the rail its own centred track. */
  .pill {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    column-gap: var(--sc-6);
  }
  .rail {
    flex: none;
    justify-self: center;
  }
  .btn.pill__wa {
    justify-self: end;
  }
}
/* 980-1099px: the rail labels' min-content is wider than the leftover 1fr
   share the pill grid gives them, so two of the five wrap to a second line
   and the whole rail drifts off the page axis (chrome-N4). Force one line
   and tighten the gaps that were the actual cause of the squeeze. */
@media (min-width: 980px) and (max-width: 1099px) {
  .pill { column-gap: var(--sc-4); }
  .rail { gap: var(--sc-4); }
}
/* Card must show the submit button without an internal scroll at 1440x900,
   1366x768 and 1280x720 (design-desktop-05): compress the rhythm only when
   the viewport is short enough to need it. */
@media (min-width: 980px) and (max-height: 860px) {
  .finale__card {
    padding: var(--sc-5);
  }
  .sc-finale__title { font-size: var(--sc-t-lg); }
  .builder {
    margin-top: 12px;
    gap: 12px;
  }
  .builder__row {
    gap: 12px;
  }
  .field {
    gap: 6px;
  }
  .finale__card .chip span {
    min-height: 36px;
    padding: 6px 12px;
    font-size: .875rem;
  }
}
@media (max-width: 979px) {
  .rail-compact { display: flex; }
  .fab { display: flex; }
  /* The section is the bottom sheet here, so it carries the glass background
     itself; the card drops its own so the two panels don't nest. bottom:
     -2vh compensates the engine's own -2vh end-of-window drift, which
     otherwise floats the sheet's square bottom corners above the screen
     edge (design-mobile-05); the extra bottom padding both restores that
     2vh of clearance for the last field and keeps it clear of the home
     indicator on notched phones. */
  .sc-finale {
    top: auto;
    right: 0;
    bottom: -2vh;
    left: 0;
    max-height: calc(100svh - 5.5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: var(--radius) var(--radius) 0 0;
    background: var(--glass);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    display: flex;
    flex-direction: column;
    gap: var(--sc-6);
    padding-top: var(--sc-6);
    padding-bottom: calc(2vh + var(--sc-4) + env(safe-area-inset-bottom, 0px));
  }
  .finale__card,
  .finale__info {
    padding-inline: var(--sc-5);
  }
  .finale__card {
    background: none;
    border: none;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
@media (max-width: 979px) and (prefers-reduced-transparency: reduce) {
  .sc-finale {
    background: var(--sc-surface);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
/* The leg-2 plate's bottom clamp otherwise leaves zero clearance from the FAB
   zone on short phones (chrome-N7): floor it at the FAB's own footprint
   (56px) plus a gap plus the bottom safe-area. Gated to min-height: 521px
   (matched to the portrait phones the defect was measured on, all >= 667px
   tall): below that the plate is already tall enough relative to the
   viewport that adding more bottom clearance pushes it under the pill
   instead (a worse, blocker-class defect this fix must not cause). */
@media (max-width: 979px) and (min-height: 521px) {
  .sc-copy--trail {
    bottom: max(clamp(3rem, 12vh, 9rem), calc(56px + 2 * var(--sc-4) + 2vh + env(safe-area-inset-bottom, 0px)));
  }
}

@media (max-width: 860px) {
  /* Landscape phones/tablets can carry side safe-area insets (a notch or a
     rounded corner); the bare gutter alone let the wordmark and the last
     compact tick sit under them (chrome-N8). */
  .pill {
    left: calc(var(--sc-3) + env(safe-area-inset-left, 0px));
    right: calc(var(--sc-3) + env(safe-area-inset-right, 0px));
  }
}

@media (max-width: 700px) {
  h1.byd-h1 { font-size: 2.05rem; }
  .byd-cta-row { flex-direction: column; align-items: stretch; }
  /* One row, wordmark left, compact rail right: at the pill's normal padding
     and gap, plus 44px-wide ticks, the five-tick row (236px) cannot fit
     beside the wordmark without overlapping it (design-mobile-01/motion-
     story-02). Tighten the pill's own padding/gap and the wordmark's own
     stretch axis (Expanded reads noticeably wider) to free up room, then
     narrow the ticks themselves; height stays 44px so the tap target itself
     stays full height. */
  .pill { height: 56px; padding-inline: var(--sc-4); gap: var(--sc-2); }
  /* The pill is 56px here, not the 60px default; keep --pill-bottom (story-01)
     matching whichever height is actually on screen. */
  :root { --pill-bottom: calc(12px + env(safe-area-inset-top, 0px) + 56px); }
  .pill__mark {
    font-stretch: 100%;
    /* font-stretch: 100% (Expanded reads too wide at this width) collapses
       the word space between "Book" and "Yacht Dubai" (chrome-N10). */
    word-spacing: 0.08em;
  }
  .rail-compact__label { display: none; }
  .gauge { display: none; }
  .rail-compact__ticks { gap: 0; }
  /* Fixed 34px ticks still overlap the wordmark at 340px and below
     (chrome-N5): shrink with the viewport instead of a single hard cutoff. */
  .rail-compact__tick { width: clamp(24px, calc((100vw - 200px) / 5), 34px); }
}
@media (max-width: 309px) {
  /* Below this the five ticks have no room at all even at their floor width;
     hiding them keeps the wordmark clear (chrome-N5). */
  .rail-compact__ticks { display: none; }
}

/* ------------------------------------------------ portrait hero (FIX-5) ---- */
/* Owner report 2026-09-29: the first fold on a phone showed neither a yacht
   nor water. The whole hero sat in one bottom-anchored group, right on top of
   the yacht (roughly 62-75% of the viewport height in leg 1), under the
   strongest part of the bottom scrim, with a flat wall of towers above it.
   Split it instead: the H1 stays at the top (over the towers), the lede and
   the CTAs sit together at the bottom (over the darker water, in thumb reach),
   and the yacht stays clear between them. Portrait phones and tablets only;
   landscape and desktop keep the lead anchor. `top`/`bottom` and the flex
   column only, never `transform`, which the engine writes on every copy
   block. */
@media (max-width: 979px) and (orientation: portrait) {
  #copy-hero {
    top: calc(var(--pill-bottom) + var(--sc-5));
    bottom: calc(var(--sc-5) + env(safe-area-inset-bottom, 0px));
    left: var(--edge);
    right: var(--edge);
    display: flex;
    flex-direction: column;
  }
  /* The lede and the CTAs are one group pinned to the bottom: no UA paragraph
     margin under the lede and a tighter row gap than the desktop hero, so the
     group stays low enough to clear the yacht's hull. */
  #copy-hero .byd-lede { margin-top: auto; margin-bottom: 0; }
  /* Stacked by default (below 340px); two across from 340px up, below. */
  #copy-hero .byd-cta-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sc-3);
    margin-top: var(--sc-4);
  }
  #copy-hero .byd-cta-row .btn {
    padding-inline: 12px;
    font-size: 0.875rem;
  }
  /* A soft shadow lets the scrim stay light so the footage still reads. */
  #copy-hero h1,
  #copy-hero .byd-lede {
    text-shadow: 0 1px 2px rgb(4 12 18 / .45), 0 2px 16px rgb(4 12 18 / .4);
  }
  /* One gradient, two dark ends and a clear middle, shaped to where the text
     actually sits: dark behind the H1 (fading out by ~30% of the height) and
     dark behind the lede and CTAs (starting ~72%), transparent between so the
     yacht and the water read. Overrides the bottom band the 860px rule above
     gives the hero. */
  .sc-scrim--lead {
    background: linear-gradient(to bottom,
      rgb(from var(--scrim) r g b / 0.84) 0%,
      rgb(from var(--scrim) r g b / 0.72) 14%,
      rgb(from var(--scrim) r g b / 0.5) 24%,
      rgb(from var(--scrim) r g b / 0.2) 29%,
      transparent 32%,
      transparent 72%,
      rgb(from var(--scrim) r g b / 0.5) 80%,
      rgb(from var(--scrim) r g b / 0.78) 90%,
      rgb(from var(--scrim) r g b / 0.88) 100%);
  }
}
@media (max-width: 979px) and (orientation: portrait) and (min-width: 340px) {
  #copy-hero .byd-cta-row { grid-template-columns: 1fr 1fr; }
}
/* Short portrait screens: the yacht's hull reaches ~81% of the viewport height
   late in the hero window, and the fixed 44px buttons leave the lede little
   room under it. Step the lede one size down (--sc-t-sm) and tighten the
   bottom group so no text box covers the hull (FIX-5 item 4c). Only the
   bottom group changes; the H1 stays where it is. */
@media (max-width: 979px) and (orientation: portrait) and (max-height: 899px) {
  #copy-hero .byd-lede { font-size: var(--sc-t-sm); line-height: 1.45; }
  #copy-hero .byd-cta-row { margin-top: var(--sc-3); }
}

/* ------------------------------------------------------------- 404 page -- */
/* site/404.html has no engine (seo-perf-01): it links only this file, so the
   shared body rule above supplies its background/ink/font reset. */
.error-404 {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sc-4);
  padding: var(--sc-6) var(--sc-gutter);
  text-align: center;
}
.error-404 h1 {
  margin: 0;
  font-family: var(--sc-font-display);
  font-stretch: 125%;
  font-weight: 560;
  letter-spacing: -0.025em;
  line-height: 1.1;
  font-size: clamp(1.6rem, 1rem + 2.4vw, 2.6rem);
}
.error-404 a {
  color: var(--sun);
  font-family: var(--sc-font-text);
  font-weight: 500;
}

/* pre-mount: leg 1 visible before the engine writes inline opacity (the
   stage classes are in the markup so first paint is already laid out: CLS). */
.js .sc-world__seg:first-child { opacity: 1; }

/* Short desktop screens (1280x720 class): 8px builder rhythm so the card fits
   with the submit visible and no internal scroll (measured 614 > 592 at 12px). */
@media (min-width: 980px) and (max-height: 760px) {
  .finale__card .builder { gap: 8px; margin-top: 8px; }
}

/* Very short landscape phones (568x320 class): the hero is taller than the
   space under the pill, so step it down until it clears the pill. */
@media (max-height: 360px) and (orientation: landscape) {
  h1.byd-h1 { font-size: 1.5rem; line-height: 1.05; }
  #copy-hero .byd-lede { font-size: 0.875rem; line-height: 1.45; margin-block: var(--sc-2) var(--sc-3); }
  #copy-hero .btn { height: 40px; }
}
@media (max-height: 360px) and (orientation: landscape) {
  .sc-copy--trail.byd-leg2 {
    top: calc(var(--pill-bottom) + var(--sc-2));
    bottom: auto;
    translate: none;
    max-width: calc(100vw - 2 * var(--edge) - 76px);
    padding: var(--sc-3) var(--sc-4);
  }
  .byd-leg2 .byd-leg-h2 { font-size: 1.125rem; }
  .byd-leg2 li { font-size: 0.8125rem; line-height: 1.4; }
  .byd-leg2 ol { gap: var(--sc-1); margin-top: var(--sc-2); }
}
@media (max-height: 360px) and (orientation: landscape) {
  .sc-copy--lower { width: calc(100vw - 2 * (56px + var(--sc-5))); }
}

/* Portrait phones: the hero is present from the first pixel, so it does not
   need the engine's +/-2vh copy drift, which at scroll 0 pushed the CTA row to
   within ~7px of the screen bottom. Stylesheet !important beats the engine's
   inline transform for this one block only. */
@media (max-width: 979px) and (orientation: portrait) {
  #copy-hero { transform: none !important; }
}
@media (max-width: 979px) and (orientation: portrait) and (min-height: 700px) and (max-height: 899px) {
  #copy-hero .byd-lede { font-size: 0.9375rem; }
}
