/* ============================================================================
   SafeStay Vista Pacifico — V1 (EN) — SECTION 00-hero
   ----------------------------------------------------------------------------
   Two parts, kept apart on purpose:

     PART A — Salient CSS that the components in sections/00-hero.html need but
              that is NOT in vendor/. Salient emits per-element CSS into a
              per-page inline <style> block, so the split-heading and
              minimal-arrow rules never reached our vendored file set. Every
              rule in Part A is copied byte-for-byte from this run's own
              capture, with the source file named. Do not edit these; edit them
              in Part B where the override is visible.

     PART B — Mykrobial retargeting. Figma geometry, type and paint, each rule
              citing figma-truth/00-hero.spec.md.

   Loaded after css/site.css, so plain specificity is enough almost everywhere.
   ========================================================================== */


/* ============================================================================
   R7-01 · THE HERO GROUND IS ONE TOKEN — LIVE DEFAULT IS DARK
   ----------------------------------------------------------------------------
   Founder round 7 (Jehnean, FT-20260821): "Try first paint from #0B0F12 (the
   dark ink) instead of white, everything fading in from dark."  Shipped LIVE so
   she can judge it with her eyes.

   >>> THE SWITCH IS THE ONE VALUE BELOW. NOTHING ELSE MOVES. <<<
       --mk-hero-ground: #0b0f12;                 DARK   (round 7, live default)
       --mk-hero-ground: var(--mk-surface-mist);  LIGHT  (round 6, #f4f9fb)
   Every fade in this file is written against the token, never against a colour,
   so flipping that one declaration restores round 6 exactly — including R6-03,
   whose whole point was that the scrim must not paint before the photo does.
   That is why `.row-bg-overlay` keeps its opacity keyframe here even though a
   dark scrim over a dark ground is invisible: drop it and the light variant
   silently regresses.

   WHAT THE OLD GROUND ACTUALLY WAS — MEASURED, because the note in
   sections/00-hero.html §1.2(a) was WRONG about it. It claimed the base was
   `#ffffff` painted on `.inner-wrap`. Probed at animation currentTime 0
   (review/r7/r7-hero/probe-firstpaint-ground.py, 1750x980):

     .row-bg-wrap / .inner-wrap / .row-bg   rgba(0, 0, 0, 0)   <- ALL TRANSPARENT
     #ajax-content-wrap.container-wrap      rgba(0, 0, 0, 0)
     .ocm-effect-wrap-inner                 rgba(0, 0, 0, 0)
     .ocm-effect-wrap                       rgb(244, 249, 251) <- THE GROUND
     body                                   rgb(11, 15, 18)      (fully covered)

   So first paint was #f4f9fb — the page ground from css/mk-bgfade.css:147, not
   white and not the hero's own paint at all. This block gives the hero band its
   OWN opaque ground so the switch is a hero-local decision: css/mk-bgfade.css
   is a shared file this lane must not write, and repointing --mk-page-bg would
   have recoloured all twenty sections to satisfy one.

   WHY THE SECTION AND NOT `.inner-wrap`: `.mk-hero` is the only box guaranteed
   to cover the whole band at every width (the row is min-height max(900px,
   100vh); at 390x844 the band is 900 and taller than the viewport). Painting the
   section also keeps the documented paint-fail fallback honest — a failed <img>
   now degrades to the ground the design actually starts from.
   ========================================================================== */
.mk-hero {
  --mk-hero-ground: #0b0f12;          /* <<< THE SWITCH. See the block above. */
  background-color: var(--mk-hero-ground);
}


/* The `.nectar-split-heading` block that used to sit here is HOISTED to
   css/salient-elements.css — it was duplicated verbatim in 00-hero.css,
   01-who-why.css and 09-recovery-42.css, and one of the three copies had
   dropped a media wrapper. That file loads before every section sheet, so
   the cascade is unchanged. Do not paste it back. */
/* ============================================================================
   PART A.2 — .nectar-next-section-wrap.minimal-arrow
   VERBATIM from salient-truth/portfolio-layered/assets/
   INLINE__03__dynamic-css-inline-css.css (portfolio-layered.lift.md §3.2).
   Only the three @keyframes it drives are already in vendor/
   (style-non-critical.q-40f8116f6d.css) — the variant rules are not.
   ========================================================================== */

.nectar-next-section-wrap.minimal-arrow a{
  width:calc(30px * var(--nectar-next-section-icon-size,1));
  height:calc(70px * var(--nectar-next-section-icon-size,1));
  text-align:center;display:block;line-height:0;position:relative;
}
.centered-text .nectar-next-section-wrap.minimal-arrow a{display:inline-block;}
.nectar-next-section-wrap.minimal-arrow svg{
  animation:ctaMinimaLArrowOuter 2.5s cubic-bezier(.55,0,0.45,1) infinite;
}
.nectar-next-section-wrap.minimal-arrow svg{
  display:block;
  width:calc(40px * var(--nectar-next-section-icon-size,1));
  height:auto;position:absolute;bottom:0;left:0;
}
.nectar-next-section-wrap.minimal-arrow a:hover svg path{
  animation:ctaMinimaLArrowLine 0.6s cubic-bezier(.25,0,0.45,1) forwards;
}
.nectar-next-section-wrap.minimal-arrow a:hover svg polyline{
  stroke-dashoffset:0px;stroke-dasharray:45px;
  animation:ctaMinimaLArrow 0.6s cubic-bezier(.25,0,0.45,1) forwards 0.1s;
}
.nectar-next-section-wrap[data-align="center"]{text-align:center;}
.nectar-next-section-wrap[data-align="right"]{text-align:right;}
.nectar-next-section-wrap[data-align="center"].minimal-arrow a,
.nectar-next-section-wrap[data-align="right"].minimal-arrow a{display:inline-block;}


/* ============================================================================
   PART A.3 — the .top-level full-viewport height
   Salient ships `.wpb_row.vc_row-o-full-height{min-height:99vh}` in
   vendor/…/style.css; the 100vh promotion lives in the per-page inline block:

     @media only screen and (min-width:1000px){
       .wpb_row.vc_row-o-full-height.top-level,
       .wpb_row.vc_row-o-full-height.top-level > .col.span_12{min-height:100vh;}
     }

   Shipped scoped to .mk-hero and floored at the Figma frame — see PART B.1 for
   why the floor is there.
   ========================================================================== */


/* ============================================================================
   PART B — MYKROBIAL RETARGETING
   Every literal below cites figma-truth/00-hero.spec.md.

   A word on the `!important`s. Salient's grid does its column gutters with
   percentages and negative margins — `.vc_row-fluid > .span_12{margin-left:-1%;
   width:102%}` paired with `.vc_row-fluid > .span_12 .wpb_column{padding:0 1%}`
   — and Figma's page has exactly one horizontal inset, the fixed 120. Measured
   live before overriding (CONVENTIONS §8.6): the untouched cascade put the
   content box at x 130.65 / w 1018.7 instead of x 120 / w 1040. Each forced
   property below names the rule that forced it.
   ========================================================================== */

/* --- B.1 the band ------------------------------------------------------- */

/* Salient normally gets position:relative from .full-width-section, which we
   deliberately did not lift (see the note in the markup). The absolutely
   positioned .row-bg-wrap / .mk-hero__cue need a containing block, so state it.
   display:flex is Salient's own intent for a vc_row-flex row — its
   `.vc_row.vc_row-flex.vc_row-o-full-height > .span_12{display:flex}` rule is
   in the demo's per-page CSS, not in our vendored js_composer.css, and without
   it .row_col_wrap_12 sizes to content (measured 600.7px inside a 900px row)
   and vc_row-o-columns-middle has no free space to centre into.
   margin-bottom: Salient's grid puts 30px under every .wpb_row; the hero is a
   900px band, not a stacked row, and the stray 30 made the section 930. */
.mk-hero .wpb_row.top-level {
  position: relative;
  display: flex;
  margin-bottom: 0;
  min-height: 900px;                     /* §1 — the Figma frame, EN 1280x900 */
}

/* Founder note 2 (§7.2): `vc_row-o-full-height` makes the hero 100vh, an
   explicit override of the static 900. Floored at 900 so a short viewport can
   never shrink the band below its Figma frame — that floor is what keeps the
   page-order arithmetic in index.html (heights summing to 20100) intact, and
   it is why a fidelity capture must be taken at 1280x900 for the hero to equal
   its frame exactly. Above 900 the hero grows, by design.

   R7-02 · THE `min-width: 1000px` GATE IS REMOVED, and it was hiding a 212px
   first-scroll LAYOUT SHIFT on tablet. Found while verifying the cue trigger at
   834x1112 (review/r7/r7-hero/probe-834-arrowdrift.py), measured page-space:

     scrollY   #s00-hero h   #fws_mk00hero h   arrow page-y   docH
        0         1112             900             829       27111
       50         1112            1112            1041       27113
      150+        1112            1112            1041       27113

   The SECTION was 1112 from first paint but this ROW was 900, because the gate
   excluded 834 — and then Salient's own `vc_row-o-full-height` script sized the
   row to innerHeight on the first scroll event and the scroll cue dropped 212px
   in one frame. Nothing scrolled it there; it was pure CLS, and it would have
   made R7-02's "the arrow holds still and fades later" false on tablet.

   Ungating it makes the CSS agree with what that script does anyway, so the
   settled layout is unchanged and only the first-paint frame moves. It changes
   nothing at any viewport where 100vh <= 900 — 390x844 stays 900, measured —
   so the only band affected is exactly the one that was broken.
   The floor stays; `max()` is what carries it. */
.mk-hero .wpb_row.top-level { min-height: max(900px, 100vh); }

/* The content column reproduces "Frame 1827" exactly: 900 - 88 - 87.5 = 724.5.
   88 = 48 section padding + the 40px nav row (rendered by the shell's
   #header-outer, not here). 87.5 = the 39.5 arrow row + 48 section padding.
   Salient's own align-content:center then centres the 371px stack at y 264.75 —
   §3's derived figure, arrived at rather than hard-coded. */
.mk-hero .row_col_wrap_12 {
  flex: 1 1 100%;
  margin-left: 0;                     /* vs .vc_row-fluid > .span_12{margin-left:-1%} */
  margin-right: 0;
  width: 100%;                        /* vs the same rule's width:102% */
  min-width: 0;
  position: relative;
  z-index: 10;                        /* over .row-bg-overlay, which is z-index 3 */
  padding-top: 88px;                  /* §1.1 row table — content row starts at y 88 */
  padding-bottom: 87.5px;             /* §1.1 — 39.5 arrow row + 48 pad */
  box-sizing: border-box;
}

/* Salient pads every non-child .wpb_column by 1% of the row and its inner_rows
   carry the matching negative gutter. Figma's only horizontal inset is the
   fixed 120 page margin, applied once, below.
   Forced by: `.vc_row-fluid > .span_12 .wpb_column{padding-left:1%;padding-right:1%}`
   (grid-system.css) and its `body[data-col-gap*=px]` siblings. */
.mk-hero .wpb_column,
.mk-hero .vc_column-inner,
.mk-hero .wpb_wrapper {
  padding-left: 0 !important;
  padding-right: 0 !important;
  margin-left: 0;
  margin-right: 0;
}
.mk-hero .wpb_row.inner_row { margin-left: 0; margin-right: 0; width: 100%; }
.mk-hero .row_col_wrap_12_inner { margin-left: 0; margin-right: 0; width: 100%; }
.mk-hero .mk-hero__col { width: 100%; }

/* The 120 page margin — the same primitive as .mk-container in grid.css,
   restated here because the box it applies to is Salient's inner_row wrapper.
   §1: the hero declares padding 48/120/48/120, and §6/§8 prove 120 is FIXED at
   1280 AND at 1440 rather than proportional. 1280 - 240 = 1040 content. */
.mk-hero .mk-hero__stack > .row_col_wrap_12_inner {
  width: 100%;
  max-width: var(--mk-frame);
  margin-inline: auto;
  padding-inline: var(--mk-page-x) !important;   /* beats the zeroing rule above */
  box-sizing: border-box;
}

/* §3 itemSpacing 24, vertical. The four blocks are full-width columns, so they
   stack; only the gap needs stating. */
.mk-hero .mk-hero__stack > .row_col_wrap_12_inner > .wpb_column { float: none; width: 100%; }
.mk-hero .mk-hero__stack > .row_col_wrap_12_inner > .wpb_column + .wpb_column {
  margin-top: var(--mk-space-24);
}

/* Salient's body copy rule puts 30px under every <p> inside a .wpb_wrapper.
   Figma's rhythm is the column gap alone: lockup 30, headline 121, body 108,
   CTA 40, summing with three 24s to the 371 stack §3 measures. The stray 30s
   made the lockup box 60 and the body 138. */
.mk-hero .wpb_wrapper p { padding-bottom: 0; margin-bottom: 0; }

/* Salient promotes the scrim to its own compositor layer with
   `.wpb_row .row-bg-wrap .row-bg-overlay{backface-visibility:hidden}` — a
   legacy GPU hint with no visual effect on a static gradient. Un-promote it:
   on a promoted layer the review browser rasters the gradient late and the
   whole scrim is missing from first-paint captures, which would make every
   fidelity screenshot of this section wrong. Visual output is identical. */
.mk-hero .row-bg-overlay { backface-visibility: visible; -webkit-backface-visibility: visible; }

/* --- B.2 type — §4, the EN/ES table ------------------------------------- */

/* Lockup 3071:2018 — Poppins Regular 20/30, tracking 75% x 20 = 15px, CENTER,
   #ffffff, uppercase. §4.3: CSS adds tracking after the LAST character too, so
   a centred line's ink lands track/2 = 7.5px left of centre; a text-indent of
   one full track puts it back. Figma's 277 hug is ink only — 381.5 + 277/2 = 520. */
.mk-hero__lockup {
  margin: 0;
  padding: 0;
  font-family: var(--mk-font-sans);
  font-weight: var(--mk-w-regular);
  font-size: var(--mk-size-body);            /* 20 */
  line-height: var(--mk-lh-auto);            /* auto 1.5 -> 30px box */
  letter-spacing: var(--mk-track-lockup);    /* 15px */
  text-transform: uppercase;                 /* §4.2 — textCase is not serialised */
  text-indent: var(--mk-track-lockup);       /* §4.3 trailing-track compensation */
  text-align: center;
  color: var(--mk-ink-inverse);
}

/* Headline 854:376 — Merriweather Light 300, 96/121, tracking 2% x 96 =
   1.92px, CENTER, #ffffff. Family and the opsz 18 pin come from tokens.css
   `.mk-page :is(h1,h2,h3,.mk-serif)`; that same rule also pins letter-spacing:0
   (correct for every other Merriweather node on the page) so the hero's 1.92
   has to be put back explicitly. §4.4: the payload's white OUTSIDE stroke on
   this node does NOT render — no -webkit-text-stroke. */
.mk-hero .mk-hero__headline {
  letter-spacing: var(--mk-track-hero);      /* 1.92px */
  text-indent: var(--mk-track-hero);         /* §4.3, same compensation, 1.92px */
  color: var(--mk-ink-inverse);
}
.mk-page .mk-hero .mk-hero__headline h1 {
  margin: 0;
  padding: 0;
  font-weight: var(--mk-w-light);            /* Light 300 */
  letter-spacing: var(--mk-track-hero);      /* vs tokens.css .mk-page :is(h1…){letter-spacing:0} */
  color: inherit;
  /* ------------------------------------------------------------------------
     BASELINE, NOT BOX. A PAINT correction of exactly 1px, and the box is
     deliberately left alone: `position: relative` offsets the painted glyphs
     without moving the layout box, so the 121px line box, §3's 371px stack and
     every downstream offset stay exactly where the spec puts them. Confirmed
     in the A/B: the body band (16.861) and the CTA band (10.667) are
     BYTE-IDENTICAL with and without this rule.

     WHY IT IS NEEDED — the mechanism, measured, not guessed. CSS puts the
     first baseline at `half-leading + ascent` below the line box top, where
     half-leading = (line-height − (ascent + descent)) / 2. Chrome truncates
     that half-leading to whole pixels. So a block whose leading is EVEN lands
     exactly, and a block whose leading is odd or fractional loses the
     remainder and sits high. Every text block in this section, probed live:

       block     line-height   ascent+descent   half-leading   built − truth
       lockup    30            28               1.0  (exact)   dy +0.20  ✓
       body      36            28               4.0  (exact)   dy +0.20  ✓
       headline  121           120              0.5  (LOST)    dy −0.69  ✗
       CTA label 24            22.4             0.8  (LOST)    dy −0.89  ✗

     The two that land exactly are the two with integer leading. That is the
     whole pattern, and it is why this correction is here and not on the body.
     Offsets are sub-pixel lags from cross-correlating the ink-mass row profile
     against figma-truth/sections-en/00-hero.png, not threshold bounds.
     Probed baseline: the h1's is at 94.00px below the line box top, i.e.
     `ascent` with the 0.5 half-leading already truncated away.

     RESIDUAL, STATED: +0.31px, down from −0.69px. Not zero. Measured cost of
     the rule: headline band 12.733 % → 12.262 % differing.

     The offset itself is SCOPED to >= 1025 and lives in B.4, not here: the
     amount is a property of the 96/121 pair, and B.4 replaces the font-size
     with a clamp() below 1025 where 121 no longer holds. Correcting only where
     the correction was measured.
     ---------------------------------------------------------------------- */
  /* ------------------------------------------------------------------------
     OPTICAL SIZE — the local override that used to live here is GONE, because
     tokens.css is now correct. This section's measurement (Figma ink 560.0 vs
     opsz 18's 625.00, +11.61 %, vs auto's 561.00, +0.18 %) was one of eight
     that said the same thing, and it is now the global rule: see
     tokens.css "MERRIWEATHER OPTICAL SIZE" and NOTES.md §F3.
     Nothing to restate here — `.mk-page :is(h1,h2,h3,.mk-serif)` already
     supplies `font-optical-sizing: auto; font-variation-settings: "wdth" 100`.
     ---------------------------------------------------------------------- */
}
/* Salient pins the masked word/letter spans and the h1 itself to line-height
   1.2 (= 115.2px at 96px), but Figma's line box is 121 (auto ~1.26 on
   Merriweather). Left at 1.2 the ink sits ~2.9px low, because the spans are
   vertical-align:bottom inside a 121px strut. The mask still clears the letters
   after the restatement: their start transform is translateY(1.3em) = 124.8px,
   which is still taller than the 121px box.
   Selector has to out-specify Salient's
   `.nectar-split-heading[data-animation-type=…]:not(.markup-generated):not([data-text-effect="none"]) > *`
   (0,4,0), which is why the section class and the attribute are both present. */
.mk-hero .mk-hero__headline[data-animation-type="line-reveal-by-space"] span,
.mk-hero .mk-hero__headline[data-animation-type="line-reveal-by-space"] > *,
.mk-hero .mk-hero__headline[data-animation-type="line-reveal-by-space"] > * > span {
  line-height: var(--mk-lh-hero);            /* 121px */
}

/* Body 854:377 — Poppins Regular 20 / 180% = 36, tracking 0, CENTER, #ffffff.
   Fill-width: 1040 at 1280, 1200 at 1440. Wraps to exactly 3 lines (108). */
.mk-hero__body {
  margin: 0;
  padding: 0;
  font-family: var(--mk-font-sans);
  font-weight: var(--mk-w-regular);
  font-size: var(--mk-size-body);            /* 20 */
  line-height: var(--mk-lh-body);            /* 180% -> 36 */
  letter-spacing: 0;
  text-align: center;
  color: var(--mk-ink-inverse);
}

/* CTA 3085:146 / 3085:147. The button itself is the `myk-btn--primary`
   variant in css/myk-btn.css; nothing about the paint is restated here.
   Salient's demo stylesheet colours every #ajax-content-wrap anchor with an
   id-level selector, which outranks a class — hence the two forced
   properties, and only those two. */
.mk-hero .myk-btn--hero-cta {
  color: var(--mk-ink-inverse) !important;   /* vs #ajax-content-wrap a{color:…} */
  text-decoration: none !important;
}
/* The PILL is already pixel-exact — measured against the Figma export, truth
   and build both put the turquoise box at y596..635 x535..744, and §3's table
   puts the CTA row at 595.75 x 40, which is what the live box reports. Only
   the LABEL inside it sits high, by the same truncated-half-leading mechanism
   documented on the headline above: Poppins 400/16 in a 24px line box has
   ascent+descent 22.4, so half-leading is 0.8 and Chrome keeps 0 of it. The
   live probe puts the label baseline at exactly 17.00px below the span top —
   `ascent`, with the leading gone — and the render lands dy −0.89 against
   Figma.
   1px, on the LABEL only, so the button box never moves. The component's
   `.myk-btn > *{position:relative}` already supplies the positioning context,
   so this adds an offset and nothing else. Measured: CTA band 10.667 % →
   10.368 % differing, every other band byte-identical.
   Scoped to --hero-cta: the nav pills are the shell's, not this section's.

   The trailing track: CSS adds a letter-space AFTER the last character; Figma
   does not. The component puts `letter-spacing: 1px` on the button, so this
   label's advance is 1px wider than the glyph run it actually draws, and
   centring the advance starts the ink half a track early. Now expressed as
   `--myk-btn-track-trim` — the component subtracts it from the label's margin,
   which is exactly what the hand-written rule here used to do. Measured before: dx −0.506 — half of one
   1px track, exactly. Pulling the phantom track back off the end: dx −0.002.
   Same class of fix, and the same technique, as §E2 of sections/04-ecology.css
   (SHARED-REQUESTS REQ-MERRIWEATHER-01, "same class, already handled locally").
   The lockup needs none of this: it carries `text-indent: 15px` = one full
   track, which is the algebraically equivalent form (ink centre = W/2 + (I−T)/2,
   so I = T and margin-right = −T both land on W/2), and it measures dx −0.055.
   The button BOX does not move — verified, truth and build both y596..635
   x535..744 before and after. Measured: CTA band 10.215 % → 8.299 %.

   REGRESSION GUARD: losing this pair costs 00-hero +0.028 pp. It was lost for
   exactly one capture during the myk-btn migration, because this selector
   still said `.mk-pill--hero-cta` after the markup had become `myk-btn` — the
   rule silently stopped matching, the label grew back its phantom 1px
   (209.453 -> 210.453) and lost its 1px lift. Caught by _tools/btn-probe.py,
   which compares computed style across the migration. */
.mk-hero .myk-btn--hero-cta { --myk-btn-track-trim: var(--mk-track-nav, 1px); }
/* LABEL NUDGE: -1px on the DIRECT-CHILD label span — calibrated 2026-08-21 by the
   r5:cta-ink-census SCREENSHOT PIXEL CENSUS (the instrument that settled the
   nav-pill phantom paints): fresh headless Chrome per load via review/sweep31/
   cdp.py, cache disabled, 1280x900, dsf 1, clip scale 4; 3 fresh loads x 2
   promotion states (fresh / post-CDP-keyboard-gesture), all six measurements
   IDENTICAL. The census carries none of the Range instrument's +-1px
   load-to-load noise — that noise, not the sign, is why this line flip-flopped
   through four sweeps.

   MEASURED AT top:0 (CSS px): space above CAP 12.75 · below BASELINE 15.00 ·
   below FULL INK 11.00. The two centering conventions DISAGREE IN SIGN here:
   cap-to-baseline reads the label 1.1px HIGH, full-ink reads it 0.9px LOW. The
   metric decision is EMPIRICAL, not conventional: +1px (the original value)
   renders cap-to-baseline nearly perfect (13.75/14.00) and is exactly the
   render Jehnean flagged ("space on the top is larger than on the bottom") —
   her eye counts the y-descender ink of "your"/"stay" as the label's bottom
   edge. FULL-INK is therefore the governing metric for this label. -1px lands
   above-cap 11.75 / below-ink 12.00 — equal at the census's 0.25px resolution.

   THE SELECTOR IS `> span`, AND THAT IS LOAD-BEARING. The old descendant
   selector (`... span`) matched the label span AND the flip wrapper that
   js/myk-motion.js §4 injects inside it (both position:relative — §2.2's
   `.myk-btn > *` and the flip block's clip box), so every 1px written here
   moved the ink 2px. The census measured the doubling directly: candidate
   +1px shifted the ink +2px. That doubling is what turned the original +1px
   into Jehnean's complaint, and it is the concrete mechanism behind the
   round-4 lesson "a pixel nudge is coupled to the structure it nudges
   within". Direct-child scoping pins the nudge to the one span the markup
   owns; a future inner wrapper cannot re-double it.

   VERIFY with _tools/cta-nudge-verify.py — screenshot ink census, exit 0 iff
   |above-cap minus below-ink| <= 0.5px in BOTH promotion states. Full method +
   audit trail: _tools/cta-ink-census.py. Do NOT re-derive from
   getBoundingClientRect or Range fragments; that instrument flips +-1px
   between identical loads and cannot answer this question. */
.mk-hero .myk-btn--hero-cta > span { top: -1px; }


/* --- B.3 scroll cue — §5, Frame 1825 / Line 854:381 ---------------------- */

/* Row 3 of the section's vertical auto-layout: 1040 x 39.5 at y 812.5, primary
   MAX (bottom-aligned), counter CENTER. 900 - 812.5 - 39.5 = 48 = the section's
   own bottom padding, so the cue pins to `bottom: 48` and stays correct when
   the band grows past 900 at 100vh. */
.mk-hero .mk-hero__cue {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  /* Frame 1825 is the 1040 content box inside the 120 margin, not full-bleed —
     §5 / §3's table. 1280 - 240 = 1040 at 1280; 1440 - 240 = 1200 at 1440. */
  max-width: calc(var(--mk-frame) - var(--mk-page-x) * 2);
  box-sizing: border-box;
  bottom: var(--mk-section-y);               /* 48 — §1 padding */
  height: 39.5px;                            /* §5 — Frame 1825 */
  margin: 0;
  display: flex;
  justify-content: center;                   /* counterAxisAlignItems CENTER */
  align-items: flex-end;                     /* primaryAxisAlignItems MAX */
  color: var(--mk-ink-inverse);              /* feeds the SVG's currentColor */
}
.mk-hero .mk-hero__cue .row_col_wrap_12_inner,
.mk-hero .mk-hero__cue .wpb_column { width: auto; }
/* Salient's <a> is an inline-block; the page's 20px/36px strut was adding an
   11px descender gap under it and lifting the glyph out of the 39.5 row.
   Salient kills the same strut on its own wrap with line-height:0 on the <a>;
   the wrap needs it too once the wrap is not inside a 0-height demo column. */
.mk-hero .mk-hero__cue .nectar-next-section-wrap { line-height: 0; font-size: 0; }
/* Salient's demo paints every #ajax-content-wrap anchor in its own accent
   (measured: rgb(255,172,102)), and the arrow strokes with currentColor, so
   the colour has to land on the <a> itself, not just on the row. */
.mk-hero .mk-hero__cue .nectar-next-section,
.mk-hero .mk-hero__cue .nectar-next-section:hover,
.mk-hero .mk-hero__cue .next-arrow { color: var(--mk-ink-inverse) !important; }

/* Figma's arrow is 17.42 x 39.5; the demo's is 30 x 70 with a 40px svg.
   Same split as the hamburger in §7.3 — Salient supplies the motion, Figma the
   shape — so the two box rules from PART A.2 are restated at Figma's size and
   nothing else about the component is touched. */
.mk-hero .nectar-next-section-wrap.minimal-arrow a {
  width: 17.42px;                            /* §5 — rotated Line bounding box */
  height: 39.5px;                            /* §5 */
}
.mk-hero .nectar-next-section-wrap.minimal-arrow svg {
  width: 17.42px;                            /* §5; height:auto keeps 39.5 */
  overflow: visible;                         /* 1px round caps sit 0.5 proud */
}

/* The cue's GEOMETRY is verified exact and must not be "corrected" against a
   capture. The live boxes are `.mk-hero__cue` y812.5–852.0 and the SVG
   y812.53–852.00 x631.30–648.70 — §1.1's Frame 1825 row (812.5, 39.5) and §5's
   17.42-wide arrow, to the hundredth. A rest-phase capture puts the ink at
   y812..852, byte-for-byte the rows Figma has.
   `measured/base3/sections/00-hero.png` nevertheless shows it 2.7px LOW with
   thin chevron arms. That is the capture, not the build: PART A.2's
   `ctaMinimaLArrowOuter` is 0% translateY(0) -> 20% translateY(12px) -> 50%
   translateY(0), 2.5s INFINITE, which §7.2 asks for by name, and fullpage.py
   settles entrance motion but never seeks an infinite loop to its rest phase.
   The arrow band therefore drifts run to run (6.102 / 6.129 / 6.263 measured
   across three captures of identical bytes). Filed as INSTRUMENT-1 in
   review/findings/SHARED-REQUESTS.md. Do NOT add a compensating offset here. */

/* --- B.4 responsive — §8, reasoned from the auto-layout modes ------------ */

/* The headline's 1px baseline correction (see B.2) belongs to the 96/121 pair
   and is scoped to the width where that pair holds. Below 1025 the block above
   swaps the font-size for a clamp() and the line-height for a ratio, so the
   truncated half-leading is a different amount and this offset would be a
   guess rather than a measurement. The CTA label's correction is NOT scoped:
   Poppins 400 16/24 is the label at every breakpoint — §8 changes the pill's
   width, never its type. */
@media only screen and (min-width: 1025px) {
  .mk-page .mk-hero .mk-hero__headline h1 { position: relative; top: 1px; }
}

@media only screen and (max-width: 1024px) {
  .mk-hero .mk-hero__headline { font-size: clamp(2.5rem, 7vw, 6rem) !important; }
  .mk-hero .mk-hero__headline[data-animation-type="line-reveal-by-space"] span,
  .mk-hero .mk-hero__headline[data-animation-type="line-reveal-by-space"] > *,
  .mk-hero .mk-hero__headline[data-animation-type="line-reveal-by-space"] > * > span {
    line-height: 1.26;                       /* §4 — Merriweather auto at 96/121 */
  }
}
@media only screen and (max-width: 640px) {
  /* §8: 15px of absolute tracking breaks the lockup line on a 375 viewport;
     the spec's own prescription is 20 -> 16px and 75% -> ~40% (= 6.4px). */
  .mk-hero__lockup {
    font-size: var(--mk-size-base);          /* 20 -> 16 */
    letter-spacing: 6.4px;                   /* §8 — 40% x 16 */
    text-indent: 6.4px;
  }
  .mk-hero__body { font-size: 17px; line-height: 165%; }   /* §8 */
  .mk-hero .myk-btn--hero-cta { display: flex; width: 100%; --myk-btn-justify: center; }  /* §8 align-self:stretch */
}

/* §8 gradient note: the scrim's third stop is fully opaque, so on a tall
   viewport the sealed band grows proportionally and can swallow the CTA.
   Anchor the mid stop higher so the seal stays a band. */
@media only screen and (min-height: 1000px) {
  .mk-hero .row-bg-overlay {
    background: linear-gradient(180deg,
                  var(--mk-hero-scrim-top) 0%,
                  var(--mk-hero-scrim-mid) 65%,
                  var(--mk-hero-scrim-bottom) 100%) !important;
  }
}

/* --- B.5 reduced motion -------------------------------------------------- */

/* §7.2 asks for a plain fade under prefers-reduced-motion. This block is also
   the fail-safe for CONVENTIONS trap 1: the split heading is opacity:0 until
   delay-js rewrites it, and that is the one place on this page where a JS
   failure would leave real content invisible rather than merely unanimated. */
@media (prefers-reduced-motion: reduce) {
  .mk-hero .nectar-split-heading[data-animation-type="line-reveal-by-space"]:not(.markup-generated) { opacity: 1; }
  .mk-hero .nectar-split-heading span .inner { transform: none !important; transition: none !important; }
  .mk-hero .nectar-next-section-wrap.minimal-arrow svg { animation: none !important; }
  .mk-hero .nectar-next-section-wrap.minimal-arrow a:hover svg path,
  .mk-hero .nectar-next-section-wrap.minimal-arrow a:hover svg polyline { animation: none !important; }
  .mk-hero .wpb_column.has-animation { transition: opacity 1ms !important; }
}


/* ============================================================================
   ============================================================================
   PART C — FOUNDER TRACE FIXES D01-D06        lane `fix:hero`, 2026-08-18
   ----------------------------------------------------------------------------
   Source of requirement: founder-trace/FT-20260817-vista-pacifico-review.md.
   Per-defect RCA + predicate + teach-back + MDP contract: founder-trace/helix/.

   OWNERSHIP NOTE, READ BEFORE MOVING ANY OF THIS.
   The nav's stylistic home is css/site.css §1. site.css is a SHARED file and
   this lane ran concurrently with others, so the nav rules for D01-D05 are
   parked HERE, in the one stylesheet this lane owns, and every one of them is
   listed verbatim in founder-trace/SHARED-REQUESTS.md as REQ-HERO-1 for a
   single-owner pass to relocate into site.css §1 unchanged. Nothing in Part C
   depends on living in this file: section sheets are emitted by
   _tools/compose.py AFTER css/site.css and css/myk-btn.css, so the only thing
   the current home buys is cascade position, and site.css §1 would get the
   same result with the same specificity.

   EVERY value below is either (a) copied byte-for-byte from a donor stylesheet
   with the file named, (b) measured off the donor live with
   scratchpad/hero-motion-probe.py, or (c) read off the Figma branding artboard
   with the node id given. Nothing here is a taste call except where a block
   says INFERENCE in capitals.
   ============================================================================
   ========================================================================== */


/* ============================================================================
   C.1 — D01 · HEADER / LOGO / NAV-CTA ENTRANCE
   ----------------------------------------------------------------------------
   "Hero must animate in on load like portfolio-layered/index.html: nav drops
    from top, content animates up+in, paragraph fades, logo animates in,
    top-right button animates in. Only the down arrow was done."

   MEASURED ON THE DONOR (hero-motion-probe.py, headless 1280x900, CDP
   Page.addScriptToEvaluateOnNewDocument + 50ms sampling from document_start):
     #header-outer   opacity 0.01 -> 1   settles 1501 ms
     #top            translateY(-80px) -> 0   settles 1551 ms
     #logo           rides #top, top -50 -> 30
   MEASURED ON OURS, SAME INSTRUMENT, BEFORE THIS BLOCK:
     all three STATIC, animationName "none".

   The nav, the logo and the "Begin recovery" button are all children of #top,
   so ONE transform on #top delivers three of the founders' five bullets. That
   is why the donor only has two keyframes for a five-part description.

   CSS copied from salient-truth/portfolio-layered/assets/
   INLINE__03__dynamic-css-inline-css.css (portfolio-layered.lift.md §2.1):
     #header-outer{opacity:0.01;}
     @media (min-width:691px){
       #header-outer.entrance-animation{animation:header_nav_entrance_animation 1.5s cubic-bezier(0.25,1,0.5,1) forwards;}
       #header-outer.entrance-animation #top{animation:header_nav_entrance_animation_2 1.5s cubic-bezier(0.25,1,0.5,1) forwards;}}
     @keyframes header_nav_entrance_animation{0%{opacity:0.01;}100%{opacity:1;}}
     @keyframes header_nav_entrance_animation_2{0%{transform:translateY(-100%);}100%{transform:translateY(0);}}

   TWO DELIBERATE ALTERATIONS, both stated rather than smuggled:

   (1) NO `.entrance-animation` GATE, AND NO AUTHORED `opacity:0.01`.
       On the donor the class is added by nectar-delay-javascript.js, gated on
       `window.nectarOptions.header_entrance === "true"`. Our build defines no
       `nectarOptions` object at all (verified live: `typeof window.nectarOptions
       === "undefined"`), so that class can never arrive. We could ship the
       options object — but then a JS failure strands a header the CSS has
       already set to `opacity:0.01`, i.e. an invisible nav. `animation-fill-mode:
       both` carries the start state instead, so the only way to get an invisible
       header is for the CSS itself to fail, in which case there is no header to
       animate. Same render, one less single point of failure.

   (2) `translateY(-100%)` BECOMES `calc(-100% - 48px)`.
       The donor's #top is 80px tall at page top, so -100% clears the viewport.
       Ours is 40px tall at y=48 (Figma nav row 1, site.css §1), so a plain
       -100% parks it at y=8 — the nav would visibly slide down out of its own
       shadow instead of dropping in from off-screen. The extra 48px is exactly
       the Figma inset. The donor's SEMANTIC is "starts above the viewport top";
       -100% is only the donor's arithmetic for it.

   ----------------------------------------------------------------------------
   R20-FIX (`r20fix:blur-backdrop-root`) — BOTH HALVES NOW LIVE ON `#top`,
   NEITHER ON `#header-outer` ITSELF. Originally the opacity half ran on
   `#header-outer` and only the transform half ran on `#top` (matching the
   donor's own split, `header_nav_entrance_animation` on the outer element vs.
   `_2` on `#top`). CONFIRMED by r20:verify (fresh Fable verifier, round 20)
   via live bisection — bare blur div works; an identical div inside
   `#header-outer` painted zero pixels; removing the animation made it work
   again — that a permanently-`animation-fill-mode:both`-filling opacity
   animation on `#header-outer` makes IT a CSS "Backdrop Root": every
   descendant `backdrop-filter` (round 20's own scroll-up progressive blur,
   `css/myk-header-blur.css`, injected as a child of `#header-outer` by
   `js/myk-header-scroll.js`) can then only sample `#header-outer`'s own
   transparent subtree instead of the real page content behind it — zero
   visible blur pixels, at every width this `@media` gate applies to.

   `#header-outer` itself paints nothing of its own — `background: transparent
   !important` unconditionally (`css/site.css` §1) — so the opacity fade
   founders actually SEE has only ever been `#top`'s content (wordmark, nav,
   CTA) becoming visible; `#header-outer`'s own opacity was never separately
   perceptible from `#top`'s. Moving BOTH keyframes onto the one element that
   is actually painted is therefore not just bug-for-bug compatible, it is a
   closer match to what founders perceive as "the header fades in" than the
   two-element split ever was. The one thing this trades away: `#search-outer`
   (the OTHER child of `#header-outer`, sibling to `#top`) no longer rides the
   parent's opacity fade — verified inert either way, since it stays hidden at
   rest regardless (no click handler wires it open in this static build; D01's
   own header banner above already establishes nothing here talks to the real
   Salient search JS). REPRODUCED live before this edit (real pixel screenshot,
   `.header-outer__gradient-blur-wrapper.is-active` forced on, crisp section-01
   body copy shifted into the header's own band without moving `window.scrollY`
   — see helix/R20-FIX-blur-backdrop-root.md for the full before/after): text
   under the header band was completely UNBLURRED pre-fix despite the wrapper
   reporting `opacity:1`, and `getComputedStyle(#header-outer).animationName`
   read `mk-header-entrance` (the smoking gun — a real, currently-filling
   animation on the exact element the blur can't see past). Post-fix, the same
   probe shows visible graduated blur and `#header-outer` computes
   `animationName: none`.
   ========================================================================== */

@keyframes mk-header-entrance   { 0% { opacity: 0.01; } 100% { opacity: 1; } }
@keyframes mk-header-entrance-2 {
  0%   { transform: translateY(calc(-100% - var(--mk-nav-inset, 48px))); }
  100% { transform: translateY(0); }
}

/* Donor gate: `@media only screen and (min-width:691px)`. Kept verbatim,
   including its consequence — below 691px there is no header entrance. The
   donor's note applies to us too: it relies on something else to unstick the
   header there, and `both` is that something else for us (the 100% frame is
   the resting state, so a viewport with no matching @media simply never
   animates and never hides anything).

   R20-FIX: both keyframes now animate `#top` (see the banner above this
   block). `#header-outer` itself carries NO animation any more — that is the
   fix. Do not re-split these back across the two elements without re-reading
   that banner; the split is exactly what made `#header-outer` a permanent
   CSS Backdrop Root. */
@media only screen and (min-width: 691px) {
  #header-outer #top {
    animation:
      mk-header-entrance   1.5s cubic-bezier(0.25, 1, 0.5, 1) both,
      mk-header-entrance-2 1.5s cubic-bezier(0.25, 1, 0.5, 1) both;
  }
}


/* ============================================================================
   C.2 — D01 · HERO CONTENT ENTRANCE (lockup, paragraph, CTA, scroll cue)
   ----------------------------------------------------------------------------
   THE ROOT CAUSE IS NOT IN THIS SECTION AND THIS BLOCK IS A LOCAL WORKAROUND.
   State it plainly so nobody "cleans it up" without doing the real fix.

   sections/00-hero.html already declares the donor's exact entrance contract:
   four `.wpb_column.has-animation` with data-animation fade-in / fade-in /
   fade-in-from-bottom / fade-in and data-delay 0 / 300 / 500 / 600, with
   `data-cae="easeOutQuart" data-cad="1500"` on <body>. Salient's
   nectar-delay-javascript.js reads all of it and DOES add `animated-in`.
   The reason nothing moves is upstream of the hero:

     _shell/head-top.html ships `<html lang="en" class="no-js">` and NOTHING
     EVER REMOVES IT. The donor's live <html> class is "js lenis". Vendor
     style.q-98889c766d.css contains

       html:not(.js) .col.has-animation,
       html:not(.js) .wpb_column.has-animation,
       html:not(.js) img.img-with-animation { opacity: 1 }

     at specificity (0,3,1), which BEATS `.wpb_column.has-animation{opacity:0}`
     at (0,2,0). Verified by enumerating every matching rule in the live
     cascade: with `animated-in` removed by hand the column still computes
     `opacity: 1`. The start state of every entrance on the page is defeated,
     so the transition to opacity 1 is a transition from 1 to 1.

     This is a PAGE-WIDE defect — 41 `.wpb_column.has-animation` across 20
     sections, not 4 in the hero — and the one-character fix belongs to whoever
     owns _shell/head-top.html. Filed as REQ-HERO-3 in
     founder-trace/SHARED-REQUESTS.md with the evidence.

   Until that lands, the hero cannot wait: D01 is founder priority 1. These
   rules drive the same four columns with CSS animations, which do not consult
   `opacity` at all and so are immune to the no-js rule. When REQ-HERO-3 lands,
   Salient's own transitions resume underneath and this block becomes redundant
   — harmlessly so, because both end at the identical resting state (opacity 1,
   transform none). DELETE IT THEN, and re-run hero-motion-probe.py to prove
   the columns still move before you do.

   Values, all from the donor rather than invented:
     duration  1500ms  = <body data-cad>, the donor's own column duration knob
     easing    cubic-bezier(0.25,1,0.5,1) = easeOutQuart = <body data-cae>,
               resolved through nectar-delay-javascript.js's own easings table
     delays    0 / 300 / 500 / 600 = the data-delay already on the four columns
     distance  75px = vendor style.q-98889c766d.css
               `.wpb_column.has-animation[data-animation="fade-in-from-bottom"]
                {transform:translateY(75px)}`
   ========================================================================== */

@keyframes mk-hero-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes mk-hero-fade-in-from-bottom {
  from { opacity: 0; transform: translateY(75px); }
  to   { opacity: 1; transform: none; }
}

.mk-hero .wpb_column.has-animation[data-animation] {
  animation-duration: 1500ms;                            /* body data-cad     */
  animation-timing-function: cubic-bezier(0.25, 1, 0.5, 1); /* body data-cae  */
  animation-fill-mode: both;
}
.mk-hero .wpb_column.has-animation[data-animation="fade-in"] {
  animation-name: mk-hero-fade-in;
}
.mk-hero .wpb_column.has-animation[data-animation="fade-in-from-bottom"] {
  animation-name: mk-hero-fade-in-from-bottom;
}
/* The delay is declared on the element as `data-delay`, so read it from there
   rather than re-encoding the stagger in a selector list keyed to node ids —
   change the markup's data-delay and the motion follows, which is the property
   the donor has and a hard-coded list would not. */
.mk-hero .wpb_column.has-animation[data-delay="0"]   { animation-delay:   0ms; }
.mk-hero .wpb_column.has-animation[data-delay="300"] { animation-delay: 300ms; }
.mk-hero .wpb_column.has-animation[data-delay="500"] { animation-delay: 500ms; }
.mk-hero .wpb_column.has-animation[data-delay="600"] { animation-delay: 600ms; }


/* ============================================================================
   C.3 — D02 · NAV ITEM HOVER = the portfolio-layered FLIP
   ----------------------------------------------------------------------------
   Seven rules, copied byte-for-byte from
   salient-truth/portfolio-layered/assets/style.q-e11f637b79.css (offsets
   77924-78277 of that file — they are contiguous there, and this is all of
   them; there is no media wrapper and no second site).

   Scoped to `#header-outer` because our build has no other consumer of the
   primitive and an unscoped `a:hover` rule reaches all 20 sections.

   `position: relative` on the wrapper is ADDED, not copied: the donor gets its
   containing block from Salient's own `#top nav > ul > li > a{position:relative}`,
   which our nav anchors (`.myk-btn`) also have — but the flip must not depend
   on a button primitive that another lane may restack, and `bottom:-120%` is
   meaningless without a known containing block.

   The geometry, so a future reader does not have to re-derive it: both boxes
   are h tall (line-height 1.3). The duplicate is parked at bottom:-120%, i.e.
   its top edge at 1.2h — fully below the overflow:hidden wrapper. On hover the
   parent takes -100% (-h), which the duplicate inherits, putting its top edge
   at 0.2h; its own -20% (-0.2h) then lands it at exactly 0, the pixel the
   original occupied. The original is at -h and clipped. One shape, two labels,
   zero jump.
   ========================================================================== */

#header-outer .nectar-text-reveal-button {
  overflow: hidden;
  display: block;
  line-height: 1.3;
  transform: translateZ(0);
  position: relative;                  /* ADDED — see note above */
}
#header-outer .nectar-text-reveal-button__text {
  transition: transform .55s cubic-bezier(.25, 1, .33, 1) !important;
  display: block;
}
#header-outer .nectar-text-reveal-button__text::after {
  transition: transform .55s cubic-bezier(.25, 1, .33, 1);
  bottom: -120%;
  content: attr(data-text);
  left: 0;
  position: absolute;
  white-space: nowrap;                 /* ADDED — the duplicate is out of flow
                                          and would otherwise wrap "Find help"
                                          and "Begin recovery" to two lines. */
}
#header-outer a:hover .nectar-text-reveal-button__text          { transform: translateY(-100%); }
#header-outer a:hover .nectar-text-reveal-button__text::after   { transform: translateY(-20%); }

/* The wrapper is `display:block` inside a `.myk-btn` whose own line-height
   token sets the pill's 24px leading. Left alone, 1.3 x 16px = 20.8px would
   shorten the label box and lift the text 1.6px inside a 40px pill that Figma
   pins — a fidelity regression bought for nothing, since the flip only needs
   the wrapper to be as tall as one line. Pin it back to the button's own
   leading; the flip arithmetic is in percentages and does not care. */
#header-outer .myk-btn .nectar-text-reveal-button { line-height: var(--myk-btn-leading, 24px); }


/* ============================================================================
   C.4 — D03 · LOGO HOVER
   ----------------------------------------------------------------------------
   *** INFERENCE. NOT DRAWN ANYWHERE. FOUNDER CONFIRMATION REQUESTED. ***
   The founders wrote "Logo needs its hover animation", and there is no such
   animation to copy: portfolio-layered's logo is a plain text <a> with a colour
   hover only, and searching the whole branding artboard 3017:633 for "hover"
   returns four nodes (3269:5600 Primary Button Hover State, 3269:5623 Hover,
   3091:1270 [Mouse hover], 3097:1707 Optional hover name) — none of them a logo.

   The reasoning, so the founders can overrule it in one sentence: G4 says a
   hover state must be consistent across every instance of its class, D02 sets
   the header's hover primitive to the flip, and the logo is in the header. So
   the logo gets the flip. If the answer is "no, the logo should do X", X
   replaces this block and nothing else changes — the markup contract is the
   same three levels.

   THE ONE ALTERATION vs C.3, and why it is forced: the duplicate in C.3 is
   `content: attr(data-text)`, which can only be a flat string, and this
   wordmark is not flat — MYKR[O]BIAL carries the turquoise brand O in its own
   span. So the duplicate is real markup (see _shell/head-tail.html, D03 fence)
   and therefore a SIBLING rather than a child. A sibling does not inherit the
   parent's -100%, so its hover transform is the full -120% instead of C.3's
   -20%. Same landing pixel, different arithmetic, for a structural reason.
   ========================================================================== */

#header-outer #logo .mk-wordmark__flip {
  overflow: hidden;
  display: block;
  position: relative;
  line-height: inherit;
  transform: translateZ(0);
}
#header-outer #logo .mk-wordmark__face {
  display: block;
  transition: transform .55s cubic-bezier(.25, 1, .33, 1);
}
#header-outer #logo .mk-wordmark__face--ghost {
  position: absolute;
  left: 0;
  bottom: -120%;
  white-space: nowrap;
}
#header-outer #logo:hover .mk-wordmark__face          { transform: translateY(-100%); }
#header-outer #logo:hover .mk-wordmark__face--ghost   { transform: translateY(-120%); }


/* ============================================================================
   C.5 — D04 · MENU BUTTON HOVER = the resort/rooms TWO-STACK SWAP
   ----------------------------------------------------------------------------
   "Menu button hover is WRONG — top and bottom bars slide off right
    independently. Must match resort/rooms/index.html."

   Both halves of that sentence have the same cause. Salient's hover is not a
   slide-away, it is a SWAP: a cloned icon is parked one clip-width + 8px to the
   LEFT and both stacks travel the same distance right, so the resting icon
   leaves the clip box exactly as the clone arrives (resort-rooms.lift.md §1.4,
   measured there as matrix(1,0,0,1,30,0) on all six pseudo-bars). We never had
   the clone — init.js only clones for a toggle inside `header#top ul` and ours
   is a bare div — so all the founders could see was the leaving half. And with
   the clip box forced to `overflow: visible` (site.css §1 note 1) the bars did
   not even leave, they slid across the page.

   THE MYK-BTN METHOD APPLIES HERE ALMOST COMPLETELY. Every distance in
   Salient's rules is `calc(var(--nectar-ocm-icon-width, 22px) + 8px)`. Figma's
   dehaze glyph is 18 wide, so setting that ONE variable retargets the parked
   offset, the hover travel and the open-state travel at once, out of the
   vendored stylesheet, with no rule rewritten. That is the whole of the first
   declaration below.

   WHAT STILL HAS TO BE WRITTEN, and why — this is the honest part.
   Salient paints three bars as `.lines::after` (top), `.lines-button::after`
   (middle) and `.lines::before` (bottom), with `.lines` itself transparent.
   site.css §1 note 3 deleted `.lines-button::after` (it renders 22px wide and
   near-black from salient-dynamic-styles and Figma has no fourth bar) and
   promoted `.lines` itself to be the middle bar. That was the right call for
   the RESTING geometry and it is measured. It has two consequences here:
     - `.lines` appears in none of Salient's hover or open-state selector
       lists, so our middle bar is the one that never moves;
     - our bars sit in the opposite pseudo-elements from the donor's:
       ours ::before is the TOP bar (top:-6) and ::after is the BOTTOM (top:+6);
       the donor's are the other way round (::after -7 top, ::before +7 bottom).
   So the delay table has to be re-keyed to OUR bar identities or the wipe runs
   bottom-to-top. Donor timing, measured off its live computed styles
   (resort-rooms.lift.md §1.4), stated by VISUAL POSITION:

       bar      delay entering (hover)    delay leaving
       top               0 ms                 80 ms
       middle           40 ms                 40 ms
       bottom           80 ms                  0 ms

   duration 0.65s, easing cubic-bezier(.3,1,.3,1) — Salient's own
   --nectar-header-hover-timing / --nectar-cubic-bezier-out defaults.
   ========================================================================== */

/* ONE VARIABLE RETARGETS THREE VENDORED RULES: the clone's parked offset
   (skin-material `.lines-button.hover-effect{left:calc((var+8px)*-1)}` = -26),
   the hover travel (`translateX(calc(var+8px))` = +26) and the open-state
   travel (`translateX(calc((var+8px)*2))` = +52). Figma dehaze is 18 wide. */
#header-outer .slide-out-widget-area-toggle { --nectar-ocm-icon-width: 18px; }

/* THE CLIP BOX. site.css §1 forces `overflow: visible !important` on this span
   for two reasons that no longer hold: the third bar was being cut off by
   Salient's 21px window (the window is now 14px and sized to the glyph, and
   all three bars measure inside 0..14), and the open-state X needed rotation
   room (the X has moved out of this span entirely — see C.6). Without a clip
   there is no swap, and on open the bars travel 52px into the page instead of
   out of view: that is literally the founders' "ghost 2-bar menu". */
body #header-outer .slide-out-widget-area-toggle a > span:not(.close-wrap) {
  overflow: hidden !important;
  position: relative;
}

/* THE CLONE. Salient parks it in flow with `margin-top:-2px`, which works
   because its `.lines-button` is a ~2px-tall box; ours is an explicit 18x14
   box (site.css §1), so in flow it would stack 14px below and be clipped away.
   Taken out of flow instead — same rendered result, and it cannot perturb the
   resting centring of the real icon, which is a measured Figma position. */
#header-outer .slide-out-widget-area-toggle a > span .lines-button.hover-effect {
  position: absolute;
  top: 0;
  left: calc((var(--nectar-ocm-icon-width, 18px) + 8px) * -1);
  margin-top: 0;
}

/* ---------------------------------------------------------------------------
   THE MIDDLE BAR GOES BACK ONTO `.lines-button::after`, WHERE SALIENT PUTS IT.
   This is a CORRECTION of this lane's own first attempt and the reason is worth
   more than the fix, because every computed style read CORRECT while the render
   was wrong — the kind of failure that survives a diff review.

   site.css §1 note 3 deleted `.lines-button::after` (Salient's middle bar, which
   salient-dynamic-styles paints 22px and near-black) and promoted `.lines`
   itself — until then only a positioning parent — to BE the middle bar. Correct
   for the resting geometry, and measured. But `.lines::before` and
   `.lines::after` are CHILDREN of `.lines`, so a transform on `.lines`
   COMPOSES with theirs. Adding `.lines` to the travel list moved the top and
   bottom bars 26 + 26 = 52px while the middle moved 26. Every probe agreed the
   transform was `matrix(1,0,0,1,26,0)` on all six bars, because each element's
   OWN transform was 26; the doubling only exists in the composed rendering
   tree. Caught by looking at the pixels: the settled hover showed one bar, not
   three, because the two doubled bars had left the clip box.

   There is no static CSS that staggers a parent and its own pseudo-children
   independently — the child's effective offset is always parent + own, so a
   40ms-delayed parent curve cannot coexist with a 0ms child curve. The middle
   bar therefore has to be a SIBLING, which is exactly why Salient hangs it off
   `.lines-button` and leaves `.lines` transparent. Restored here, in this
   lane's own file, without touching site.css's measured geometry:
   the bar identities, widths (18/18/13) and y positions are unchanged, only
   which element paints the middle one.
   --------------------------------------------------------------------------- */

/* Middle bar: Salient's element, Figma's geometry. `content` is re-enabled
   against site.css §1 note 3's `content: none`; width comes free from
   --nectar-ocm-icon-width; top:6 centres it in the 14px glyph box (Salient
   ships top:0, sized for its own 21px box). */
body #header-outer .slide-out-widget-area-toggle .lines-button::after,
body #header-outer.transparent .slide-out-widget-area-toggle .lines-button::after {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  width: var(--nectar-ocm-icon-width, 18px) !important;
  height: 2px !important;
  /* R19-06 (`css/site.css` §1B.2, read that section for the full mechanism):
     reads the header tone token instead of the literal, fallback preserves
     today's default. This replaces what was a THIRD file's copy of the same
     `.dark-text`/`.dark-text.transparent` specificity-superset pair
     site.css's top/bottom bars and the wordmark each also carried — three
     independent rounds (r18fix2, r18fix3, this file's own prior note) each
     had to re-derive that exact tie by hand, once per file, which is the DRY
     violation site.css §1B.2 now closes. One unconditional declaration below
     covers both `.light-text` and `.dark-text`; there is no higher-
     specificity rule left anywhere for a `.dark-text.transparent` state to
     tie against. */
  background-color: var(--myk-header-ink, var(--mk-ink-inverse)) !important;
  border-radius: 0;
  opacity: 1;
}
/* `.lines` is a positioning parent again, never a painted bar and never
   transformed. Transforming it is what doubled its children. */
body #header-outer .slide-out-widget-area-toggle .lines,
body #header-outer.transparent .slide-out-widget-area-toggle .lines {
  background-color: transparent !important;
  transform: none !important;
}

/* THE TRAVEL. Salient's own three selectors, verbatim in structure — no
   `.lines` in the list. */
body #header-outer .slide-out-widget-area-toggle a:hover .lines-button::after,
body #header-outer .slide-out-widget-area-toggle a:hover .lines::before,
body #header-outer .slide-out-widget-area-toggle a:hover .lines::after,
body #header-outer .slide-out-widget-area-toggle a:focus-visible .lines-button::after,
body #header-outer .slide-out-widget-area-toggle a:focus-visible .lines::before,
body #header-outer .slide-out-widget-area-toggle a:focus-visible .lines::after {
  transform: translateX(calc(var(--nectar-ocm-icon-width, 18px) + 8px));
}

/* THE STAGGER. TWO COMPETITORS HAD TO BE BEATEN AND BOTH WERE MEASURED, NOT
   GUESSED — the first pass of this block lost to both and the probe caught it:
   `transitionDelay` read 0.08s on the TOP bar entering when it should read 0s.

   (a) skin-material.q-2c163bc272.css declares these transitions with
       `!important`, keyed to the DONOR's bar identities:
         body .lines:before{... 0s ...!important}                 (donor BOTTOM)
         body .lines:after {... 80ms ...!important}               (donor TOP)
         body …a:hover .lines:before{... 80ms ...!important}
         body …a:hover .lines:after {... 0s  ...!important}
       Ours are the other way round (site.css §1 note 3 promoted `.lines` to be
       the middle bar and left ::before as top / ::after as bottom), so the
       vendored delays run the wipe bottom-to-top. Beating an `!important`
       needs an `!important`.
   (b) css/site.css §1 sets `transition: var(--mk-motion-dur-icon)` on a
       selector list that includes `body #header-outer.transparent … .lines`
       at specificity (1,3,2) — HIGHER than a plain
       `body #header-outer … .lines` at (1,2,2). #header-outer carries
       `.transparent` over the hero, so the plain form silently lost and the
       middle bar kept a 0.3s ease with no delay. Matched here.

   Verified after the fix by reading transitionDelay in all three states. */
body #header-outer .slide-out-widget-area-toggle .lines::before,
body #header-outer.transparent .slide-out-widget-area-toggle .lines::before {  /* top */
  transition: transform .65s cubic-bezier(.3, 1, .3, 1) 80ms,
              background-color .2s ease, opacity .2s ease !important;
}
body #header-outer .slide-out-widget-area-toggle .lines-button::after,
body #header-outer.transparent .slide-out-widget-area-toggle .lines-button::after { /* middle */
  transition: transform .65s cubic-bezier(.3, 1, .3, 1) 40ms,
              background-color .2s ease, opacity .2s ease !important;
}
body #header-outer .slide-out-widget-area-toggle .lines::after,
body #header-outer.transparent .slide-out-widget-area-toggle .lines::after {   /* bottom */
  transition: transform .65s cubic-bezier(.3, 1, .3, 1) 0s,
              background-color .2s ease, opacity .2s ease !important;
}
/* Entering delays — the order reverses, exactly as the donor does it. */
body #header-outer .slide-out-widget-area-toggle a:hover .lines::before,
body #header-outer.transparent .slide-out-widget-area-toggle a:hover .lines::before,
body #header-outer .slide-out-widget-area-toggle a:focus-visible .lines::before,
body #header-outer.transparent .slide-out-widget-area-toggle a:focus-visible .lines::before {
  transition: transform .65s cubic-bezier(.3, 1, .3, 1) 0s,
              background-color .2s ease, opacity .2s ease !important;
}
body #header-outer .slide-out-widget-area-toggle a:hover .lines::after,
body #header-outer.transparent .slide-out-widget-area-toggle a:hover .lines::after,
body #header-outer .slide-out-widget-area-toggle a:focus-visible .lines::after,
body #header-outer.transparent .slide-out-widget-area-toggle a:focus-visible .lines::after {
  transition: transform .65s cubic-bezier(.3, 1, .3, 1) 80ms,
              background-color .2s ease, opacity .2s ease !important;
}

/* site.css §1's `.lines-button.x2.close .lines{background-color:transparent}`
   belonged to the old rotate-the-bars-into-an-X morph and is now a no-op:
   `.lines` is transparent in every state. Left alone deliberately — deleting it
   from site.css is the single-owner pass's call, not this lane's. */


/* ============================================================================
   C.6 — D05 · ON OPEN, THE MENU ICON IS REPLACED BY THE X
   ----------------------------------------------------------------------------
   Figma note 3271:5966, verbatim and complete (review/branding/media-misc.md
   §4.1): "[Open menu][Nav in hero][Open, fullscreen nav menu for the branding
   site. Align menu button and close button with animation]".
   Read against boards 3271:5828 (closed: search + dehaze) and 3271:6114 (open:
   search + close): SAME TWO SLOTS, SAME ORDER. There is no third control and
   no ghost bars anywhere in the design.

   MEASURED IN THE OPEN STATE BEFORE THIS BLOCK, which is the founders' report:
     .lines            box [1121, 67, 18, 2]   — did not move (not in Salient's
                       menu-push-out selector list, which names .lines-button:after,
                       .lines:after and .lines:before)
     .lines::before/::after   translated +60px to x 1181-1199 and still visible,
                       because the clip box was overflow:visible
     .close-wrap       ABSENT from the header toggle entirely — 0 nodes
     #header-outer #top > .container   opacity 0 and left there
   i.e. a displaced pair of bars and no X. "A ghost 2-bar menu sits right of
   the close" is an exact description of that measurement.

   C.5 already fixes the leaving half (clip box restored, `.lines` added to the
   travel). This block supplies the arriving half. Almost all of it is already
   vendored — skin-material.q-2c163bc272.css carries .close-wrap, .close-line,
   the four crossLeft/crossRight keyframes and the menu-push-out travel — so
   what follows is only the three things the vendored CSS cannot know:
   our bar identity, our icon size, and our ink.
   ========================================================================== */

/* Open-state travel needs NO rule of ours. skin-material already ships
     body[data-slide-out-widget-area-style*=fullscreen] #top .menu-push-out
       .lines-button:after, … .lines:after, … .lines:before
       {transform:translateX(calc((var(--nectar-ocm-icon-width,22px) + 8px) * 2))!important}
   and with the middle bar back on `.lines-button::after` and the variable set
   to 18, that rule names all three of our bars and computes our 52px. The
   earlier version of this block added `.lines` to the list and re-introduced
   the doubling described above — do not add it back. */

/* THE X, SIZED TO THE MENU GLYPH — 18, not Salient's 22 and not Figma's 24.
   Founder note on D05: "Close icon may be too bulky." media-misc.md §4.2 reads
   the artboard as a 24x24 close glyph beside an 18x14 dehaze glyph and infers
   ~18px for optical parity; that inference is logged there as ambiguity A4 and
   is NOT drawn. Sized here to 18 so the two controls match, and carried as a
   variable so a founder answer is a one-line change. */
#header-outer .slide-out-widget-area-toggle { --mk-close-size: 18px; }

#header-outer .slide-out-widget-area-toggle a { position: relative; }
/* `:not(.small)` IS LOAD-BEARING, not decoration. skin-material pins
   `#top .slide-out-widget-area-toggle:not(.small) a .close-wrap{width:22px!important}`
   inside `@media (min-width:1000px)`; without the same `:not(.small)` this rule
   is a specificity step below it and the X renders 22 wide in an 18 tall box —
   measured that way on the first pass. */
#header-outer .slide-out-widget-area-toggle:not(.small) a .close-wrap,
#header-outer .slide-out-widget-area-toggle a .close-wrap {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%) translateZ(0);
  width:  var(--mk-close-size) !important;
  height: var(--mk-close-size) !important;
  display: block;
  /* !important IS THE FIX FOR A03, and the bang is not defensive — it is the
     minimum that beats a live `!important` on the same property.
     site.css §1 pins `body #header-outer .slide-out-widget-area-toggle a > span
     {overflow:visible!important}` to let the hamburger's third bar escape
     Salient's 21px window. C.6 then moved the X to be a SIBLING of that span —
     i.e. it is ALSO `a > span`, so site.css's bang landed on the X's clip box
     too and this declaration, unbanged, lost. MEASURED before the fix:
     `getComputedStyle(.close-wrap).overflow === "visible"`.
     WHAT THAT COSTS, measured, not reasoned: skin-material parks the strokes
     for the OPEN state at `translateY(-30px) translateX(±30px)` and only flies
     them in after an animation-delay (.15s line2, .29s line1), while this
     element's own opacity is already ramping 0->1 over .3s. With no clip, that
     delay window is not empty — it paints two full-length diagonal strokes
     30px ABOVE the button, fading up, before the X exists. review/menu-x/
     film-before.json: 1117 bright px outside the 18x18 glyph box at anim 169ms,
     ink present from 88ms to 519ms. That is founder item A03 verbatim: "an
     artifact of almost like those lines that are going to come in for the X
     showing up too early".
     A03 is therefore NOT the triple-clone defect it was filed against — see
     the `a > * .close-wrap` rule below for that, which is real but separate.
     The seam belongs in site.css (its `a > span` should read
     `a > span:not(.close-wrap)`, as 00-hero.css §C.5 line 814 already does);
     REQ-MENUX-1 in founder-trace/SHARED-REQUESTS.md asks for that. Until it
     lands this bang holds the contract locally. */
  overflow: hidden !important;
  opacity: 0;
  transition: opacity .3s ease;
  pointer-events: none;
}

/* ONE X, NOT THREE.  init.js:164285 appends a fresh `.close-wrap` into EVERY
   `header#top .slide-out-widget-area-toggle a > span`. Our <a> has two direct
   span children — the hamburger's 18x14 clip box and the authored X — so the
   selector matches BOTH and the page ends up with three co-located Xs:
     a > span > .close-wrap                (clone, and CROPPED: an 18x18 X
                                            inside an 18x14 overflow:hidden box)
     a > .close-wrap                       (authored — the one we style)
     a > .close-wrap > .close-wrap         (clone, nested inside the authored)
   Measured: 1 wrap / 2 lines at rest, 3 wraps / 6 lines after the first click.
   The inherited note filed this as happening AT PAGE LOAD; it does not —
   init.js is a `type="salientlazyscript"` tag, so the injection happens when
   the lazy chain is promoted on first interaction. review/menu-x/before.json
   carries both censuses.

   `:has(> .close-wrap)` IS LOAD-BEARING. The naive form of this rule hides
   every non-direct-child `.close-wrap` unconditionally, and would leave the
   header with NO close control at all if a later lane ever deleted the
   authored node from _shell/head-tail.html. Gated on the authored node
   existing, the failure mode degrades to Salient's own stock behaviour (a
   cropped X) instead of to nothing. */
#header-outer .slide-out-widget-area-toggle a:has(> .close-wrap) > * .close-wrap {
  display: none !important;
}

/* Same `:not(.small)` step as the base rule above. Adding it there without
   adding it here is exactly how the first pass shipped an X that stayed at
   opacity 0 in the open state — the base rule outranked the open rule by one
   pseudo-class. Caught by the probe, not by reading. */
#header-outer .slide-out-widget-area-toggle:not(.small) .animating .close-wrap,
#header-outer .slide-out-widget-area-toggle:not(.small) .open .close-wrap,
#header-outer .slide-out-widget-area-toggle .animating .close-wrap,
#header-outer .slide-out-widget-area-toggle .open .close-wrap { opacity: 1; }

/* Vendored `.close-line` is 2px wide at `left:9px` — centred for Salient's
   20/22px box. Ours is 18, so the centre is 8. White, not the vendored #000:
   this header sits on a dark hero and on #0B0F12 when open. */
#header-outer .slide-out-widget-area-toggle a .close-line {
  width: 2px;
  left: calc((var(--mk-close-size) - 2px) / 2);
  background-color: var(--mk-ink-inverse) !important;
  border-radius: 0;                    /* Figma's icon strokes are square-ended,
                                          like the dehaze bars — media-misc §4.2 */
}
/* Vendored parked-state keyframes translate by a hard-coded 22px, which for an
   18px box leaves the strokes 4px inside the clip and shows two stubs at rest.
   Re-declared at our size; everything else about the animation (0.4s,
   cubic-bezier(.52,.01,.16,1), forwards, the .06s/.1s lead of line2 over
   line1) is Salient's and stays vendored. */
@keyframes mk-crossLeftClose  { 100% { transform: translateY(var(--mk-close-size)) translateX(var(--mk-close-size)) rotate(-45deg); } }
@keyframes mk-crossRightClose { 100% { transform: translateY(var(--mk-close-size)) translateX(calc(var(--mk-close-size) * -1)) rotate(45deg); } }
#header-outer .slide-out-widget-area-toggle a:not(.open) .close-line1 { animation-name: mk-crossLeftClose; }
#header-outer .slide-out-widget-area-toggle a:not(.open) .close-line2 { animation-name: mk-crossRightClose; }

/* ONE SLOT, NEVER TWO. The off-canvas panel ships its own `.slide_out_area_close`
   (_shell/bottom.html). It computes to display:none in this OCM style today, so
   this rule is a GUARD, not a change: if a later lane restyles the panel, the
   design still says one control. Kept in the DOM and focusable-adjacent rather
   than removed, so the panel keeps a programmatic close for assistive tech that
   never reaches the header. */
#slide-out-widget-area.fullscreen-inline-images > .inner-wrap > .inner > .slide_out_area_close {
  opacity: 0;
  pointer-events: none;
}

/* The header content is faded to 0 on open by init.js and only faded back by an
   anime() call inside a nested setTimeout; measured live, it stays at 0, so the
   X would arrive invisible. The founders' requirement is that the control is
   VISIBLE and morphs in place, so the open state pins it. */
#header-outer.side-widget-open #top > .container { opacity: 1 !important; }


/* ============================================================================
   C.7 — D06 · HERO CTA HOVER = the Figma primary-button hover state
   ----------------------------------------------------------------------------
   "Hero CTA hover is not the Figma hover state. Must match the primary-button
    hover in the branding artboard."  Ours was `opacity: .87`, invented.

   FIGMA, artboard 3269:5586 "Section buttons" -> Frame 1849 3269:5594:
     3269:5598 "Primary Button Enabled State"  fill #1EB2BC · pad 8/18 · h40
     3269:5600 "Primary Button Hover State"    fill LINEAR GRADIENT
               #2BD8D8 -> #137983 · pad 10/20 · h44
               + DROP_SHADOW #00000026 offset(0,4) radius 4
               + BACKGROUND_BLUR 4 (both states)

   BOTH nodes ALSO declare `strokes:["#ffffff"]` 1px CENTER, and on this file
   that is not evidence — media-misc.md §2.1 documents paints that do not
   render in both directions. Bleed-tested before use, per that warning:
     3269:5598 -> PNG 107x40 for a 107x40 node. Zero inflation. NO RING.
     3269:5600 -> PNG  99x52 for a  91x44 node. The inflation is 4px each side
                  and 8px at the bottom, which is the drop shadow (offset y4 +
                  radius 4), not a stroke; probing the body edge at y=26 reads
                  (42,202,202,153) -> (43,215,215,255) with no white pixel
                  between. NO RING ON HOVER EITHER.
   Gradient axis read off the render rather than decoded from
   gradientTransform: sampling the 91px body left to right gives
   f=0.00 (43,215,215) · 0.50 (31,169,173) · 1.00 (20,123,132) — a horizontal
   left-to-right ramp matching #2BD8D8 -> #137983. Hence 90deg.

   TWO IMPLEMENTATION NOTES:
   (1) CROSS-FADE, NOT A BACKGROUND SWAP. `background` does not interpolate
       between a solid colour and a gradient — it would cut. css/myk-btn.css
       §2.2 already solved this for the outline variant with a `::before`
       overlay whose opacity animates; the same primitive is reused here rather
       than a second mechanism invented for the same job.
   (2) THE 4px GROWTH IS ABSORBED BY A -2px MARGIN. Figma grows the pill by
       2px on every side (padding 8/18 -> 10/20). Applied as padding alone it
       would push the hero's vertically-centred stack 2px on every hover. The
       negative margin keeps the LAYOUT box at 40px while the PAINTED box is
       Figma's 44px — the design's growth, none of the jitter.

   >>> PROMOTED AND DELETED — 2026-08-18, lane `foldback:buttons-sweep`. <<<

   REQ-HERO-2 asked for this block to move to `.myk-btn--primary` in
   css/myk-btn.css and said "delete it from the section sheet — do not leave
   both." Both halves are done. THE RULES BELOW THIS COMMENT ARE GONE; the
   evidence above is kept because it is the receipt for the values now in the
   primitive (§2.3 `.myk-btn--primary`), and a reader arriving here from D06
   should find the measurement, not a dead end.

   WHERE IT WENT, and what changed on the way:
     · `--myk-btn-hover-bg` (the gradient) and `--myk-btn-hover-shadow` are now
       `.myk-btn--primary` defaults, so the nav CTA, the closing-CTA pill and
       the footer Join get the identical hover. That is G4/D41/D47, and it is
       why leaving a section-scoped copy here would have been actively wrong:
       a second definition is how the page ends up with two primary hovers.
     · The GROWTH mechanism changed from `padding + height + margin: -2px` on
       the ELEMENT to `inset: -2px` on the LAYER. Same painted result — the
       pill still measures 213.45 x 44 against a 209.45 x 40 rest — and the
       label still does not move. The reason is generality, not taste: the
       element-growth form cannot be shared. The nav CTA has a pinned
       `width: 169px` (myk-btn.css §5) so it would grow only vertically; the
       two 18-cta-expand pills are flex items whose row would re-lay-out; the
       footer Join sits inside a `<form>` row. A layer at `position: absolute`
       is invisible to all three layouts. §4.2's measured note from
       portfolio-layered says the same thing about the donor: "nothing about
       the text box changes … the grow happens on a pseudo behind the label."
     · The layer moved from `z-index: -1` to `z-index: 0` to match the one the
       outline variant already used. Both paint above the element's own
       background inside its `isolation: isolate` context (CSS 2.1 Appendix E
       steps 3 and 6 are both after step 2) and below the §2.2 label at
       z-index 1, so this is a notation change, not a paint one.
   ========================================================================== */


/* ============================================================================
   C.8 — reduced motion for everything Part C adds
   ----------------------------------------------------------------------------
   css/reduced-motion.css is emitted LAST by compose.py and already neutralises
   `.wpb_column.has-animation`, but it neutralises `opacity` and `transform`
   properties — it does not stop an `animation-name`, and C.1/C.2 are
   animations. Explicit, and local to the rules that need it.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  #header-outer,
  #header-outer #top,
  .mk-hero .wpb_column.has-animation[data-animation] { animation: none !important; }

  #header-outer .nectar-text-reveal-button__text,
  #header-outer .nectar-text-reveal-button__text::after,
  #header-outer #logo .mk-wordmark__face,
  #header-outer .slide-out-widget-area-toggle .lines,
  #header-outer .slide-out-widget-area-toggle .lines::before,
  #header-outer .slide-out-widget-area-toggle .lines::after,
  .mk-hero .myk-btn--hero-cta,
  .mk-hero .myk-btn--hero-cta::before { transition: none !important; }

  /* The X still has to arrive — it is the only close affordance. Instant. */
  #header-outer .slide-out-widget-area-toggle a .close-line { animation: none !important; }
  #header-outer .slide-out-widget-area-toggle a:not(.open) .close-line1,
  #header-outer .slide-out-widget-area-toggle a:not(.open) .close-line2 { opacity: 0; }
}


/* ============================================================================
   PART D — BRANDING FOLD-BACK VERIFICATION.  Lane `foldback:hero-nav`, 2026-08-18.
   ----------------------------------------------------------------------------
   PART C was written before the three branding specs closed. This lane re-drove
   every interactive state in the header and the hero CTA against
   `review/branding/buttons.md`, `cursors.md` and `media-misc.md`, with a real
   pointer on the built page (`Input.dispatchMouseEvent`, not
   `CSS.forcePseudoState`, because D02/D04/D05 are JS- and transition-driven).

   **THIS PART DECLARES NO RULES.** Everything it checked either measured clean
   or belongs to `css/myk-btn.css` (promoted by `foldback:buttons-sweep` on the
   same day). Three candidate fixes were written here, measured, and then
   DELETED as wrong — that is the content of this block, because each one is a
   trap the next lane would otherwise re-lay. Data:
     review/hero-nav/measured-{before,after}.json   header + CTA, rest & hover
     review/hero-nav/toggle-{before,after}.json     hamburger/close, 4 states
     review/hero-nav/flip-parity.json               logo vs nav flip, 6 samples
     review/hero-nav/blend-reach.json               mix-blend-mode isolation
     review/hero-nav/chip-alpha.json                backdrop-root double-paint

   ----------------------------------------------------------------------------
   D.1 — THE NAV LADDER IS NOT THIS SURFACE'S. Settles OPEN-BTN-3.
   ----------------------------------------------------------------------------
   `buttons.md` §3.4 BUILD RULE N1 says the nav item rests at `#ffffffbf` (75 %)
   and hovers to 100 %, and calls it "the single most-missed row in the system".
   `figma-truth/00-hero.spec.md` §4 says `nav.link` rests at `#ffffff`.
   `myk-btn.css` §2.3 recorded the disagreement as OPEN-BTN-3 and escalated
   rather than averaging — correctly. **It is now settled, against the ladder,
   by going back to the artboard.**

   Read from Figma this run, SafeStay hero `854:363` — not the branding board:
     `3017:589` "Resources"  fills ["#ffffff"], no opacity  -> 100 %
     `3016:403` "Safe stays" fills ["#ffffff"], no opacity  -> 100 %
   and confirmed in the render (`review/hero-nav/figma-hero-854-363.png`, 2x):
   glyph strokes reach (255,255,255). At 75 % over this backdrop they would
   peak near (219,216,215).

   The 75 % values are real but they belong elsewhere: `3269:5620` is the
   BRANDING-SITE nav-item component, and `media-misc.md` §4.3's 75 % is the
   OPEN-MENU link (`3271:6085`). Both are the branding site; the SafeStay hero
   nav is its own instance and it is drawn at 100 %. D45/D48 (footer links and
   social icons) are the ladder's real build sites and they belong to the
   footer lane. **Do not apply the ladder to `.mk-nav__list`.**

   ----------------------------------------------------------------------------
   D.2 — THE NAV CHIP FILLS ARE PHANTOMS, INCLUDING ON THE SAFESTAY ARTBOARD.
   ----------------------------------------------------------------------------
   `css/tokens.css` lines 156-157 mark both fills "declared … not rendered", and
   `myk-btn.css` §2.3 kept `--ghost`/`--active` transparent on that basis. This
   lane tried to overturn it — `buttons.md` §3.4 render-proves a step under the
   branding board's selected chip — and the attempt FAILED against the artboard
   that governs this section. Declared on `854:363`:
     `3017:588`  nav item, default   fill #000000 @ 15 %, blend NORMAL
     `3016:402`  nav item, selected  fill #000000 @ 10 %, blend LUMINOSITY
   Render-tested at 2x on the hero export, both directions:
     horizontal, css y=52 across the whole nav row (x 280→1120): the ONLY steps
       are the outline CTA's 1 px white ring at x≈860 and x≈1014. No pill edge.
     vertical, through the SELECTED pill's centre (css x=658, y 40→95): the
       photograph runs 101→116 monotonically across BOTH pill boundaries
       (y=48, y=88). The only steps are the white glyph strokes at y=66-73.
   A 15 % NORMAL black would step ~17 RGB. Nothing steps. **Both fills are
   phantoms, exactly like PRIMARY's white stroke** — and note the 15 % one is a
   NORMAL blend, so "the blend could not composite" does not explain it. The
   payload is simply not what renders; `get_node_full` does not report a paint's
   own `visible` flag any more than `get_nodes_info` reports a node's.

   Two mechanisms were measured on the way and are worth keeping, because both
   would have made a "correct" declaration render wrong:
     (a) `mix-blend-mode: luminosity` CANNOT reach the photograph from anywhere
         in this header. Rendering the chip `luminosity` vs `normal` differs by
         **0 pixels** (blend-reach.json) while chip-vs-no-chip differs by a mean
         of 13.6. Three blending-isolation groups sit in between: the `<li>`
         (`z-index:10`, Salient's own), `header#top` (`z-index:9998`) and
         `#header-outer.transparent` (`z-index:9998`). Any stacking context is
         an isolation group. A declaration that provably does nothing is worse
         than none, because the next reader copies it.
     (b) A semi-transparent layer painted BEHIND a `backdrop-filter` element is
         composited twice. The nav item carries `blur(4px)` (Figma
         BACKGROUND_BLUR 4), and a 10 % fill measured **0.1716** effective alpha
         on a pseudo behind it versus **0.1033** on the element's own
         background (chip-alpha.json, 8 sample points). A 72 % overshoot from a
         construction choice that reads as a free implementation detail. If a
         founder ever restores these fills, they go on the element, not behind
         it — Figma has fill and blur on ONE node and so must we.

   ----------------------------------------------------------------------------
   D.3 — §4.1's "100 % vs 20 %" IS THE DECLARED TRANSFORM, NOT THE MOTION.
         The logo flip (C.4) is CORRECT. Do not "fix" it.
   ----------------------------------------------------------------------------
   `buttons.md` §4.1 says of the donor flip: "The two halves travel different
   distances — 100 % vs 20 % — over the same 0.55s. That asymmetry is the whole
   feel … Build it as a conveyor with both halves travelling 100 % and it will
   read as sluggish and wrong."

   Read literally that condemns C.4, whose ghost is a SIBLING (it has to be —
   the wordmark carries the turquoise brand O, so it cannot be
   `content: attr(data-text)`) and therefore declares `translateY(-120%)`
   instead of the donor's `-20%`. Measured before believing it, both flips
   sampled on the same clock (flip-parity.json):

       t (ms)     nav ::after composed      logo ghost composed
          60           -12.776                  -12.765
         120           -20.599                  -20.603
         180           -24.948                  -24.949
         275           -27.864                  -27.873
         400           -28.711                  -28.711
         700           -28.800                  -28.800

   **Identical to three decimals.** The donor's incoming half also travels
   −120 % ON SCREEN: its own −20 % composes with the parent's −100 %, and
   §4.1 says so itself two sentences earlier ("the duplicate, which rides along
   with its moving parent"). Same curve on both terms, so the composition is
   the same curve scaled. There is no rendered asymmetry to reproduce.
   A lane that "corrects" a flip so the incoming half moves only −20 % of a line
   box on screen will land the second word 80 % short and break it.

   ----------------------------------------------------------------------------
   D.4 — WHAT MEASURED CLEAN, so it is not re-opened.
   ----------------------------------------------------------------------------
   D02 flip: `__text` −24.000 (−100 % of the 24 px box), `::after` −4.800
     (−20 %), `.55s cubic-bezier(.25,1,.33,1)`, mask `overflow:hidden`, and the
     box does NOT grow (127 px at rest and on hover) — `buttons.md` §4.1 and the
     "no size change" half of N1, both exact.
   D04 dehaze: 18×2 / 18×2 / **13**×2 at local y 0-2, 6-8, 12-14, all left-
     aligned, square ends, `#ffffff` — `media-misc.md` §4.2 to the pixel,
     including the deliberately short bottom bar. Verified by pixel census of
     the render, not by computed style, because the middle bar is painted by
     `.lines-button::after` while `.lines` itself computes transparent.
   D04 swap: clone parked at `left: -26px` = one clip width (18) + 8, both
     stacks travel +26 on hover, stagger 0/40/80 ms on `.65s cubic-bezier(.3,1,
     .3,1)`. The resting icon leaves the 18 px clip exactly as the clone lands.
   D05: on open the bars travel +52 (`(18+8)*2`) and are clipped away, and the
     `.close-wrap` fades in at the SAME centre — dehaze box (1281,61,18,14)
     centre (1290,68); X wrapper (1281,59,18,18) centre (1290,68). One slot,
     aligned, no ghost bars in any of the four states probed. Figma note
     `3271:5966` satisfied. Close size stays on `--mk-close-size: 18px` pending
     founder answer A4.
   D06: after `foldback:buttons-sweep` promoted the hover to `.myk-btn--primary`
     this section holds no CTA hover rules of its own, which is what REQ-HERO-2
     asked for. Verified against the primitive, not re-implemented here.
   ========================================================================== */

/* ==========================================================================
   HERO ENTRANCE — Omai grammar, founder round 5 (Jehnean, 2026-08-20).

   "I don't like that the titles come up from behind the line... they fade in
   AND animate in. It can still come up, but I want the same fade and the same
   pacing... and the whole background image should also load in."

   The masked `line-reveal-by-space` split-heading is REMOVED from the hero
   markup (this section only — other sections keep their Salient reveals until
   she reviews them). One system drives the hero: pure CSS keyframes, no JS,
   no delay-js gating, because the hero is above the fold and must move at
   first paint.

   Every number below is MEASURED FROM OMAI, not invented — review/omai/
   PACING.md, confirmed live via CDP: text 700ms / cubic-bezier(.4,0,.2,1) /
   opacity 0->1 / translateY 40px->0, base delay 100ms; images opacity-ONLY
   1000ms. The 120ms stagger step is our composition choice inside their
   grammar. The headline colour settle mirrors their "welcome home" title,
   which starts one colour and arrives at another.
   ========================================================================== */

@keyframes mykHeroRise {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes mykHeroImg {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes mykHeroInk {
  from { color: #b9c7cf; }   /* muted cool grey, settles to white like Omai's title */
  to   { color: #ffffff; }
}

.mk-hero [data-myk-hero-in] {
  opacity: 0;                                  /* rest state before the keyframe */
  animation: mykHeroRise 700ms cubic-bezier(.4, 0, .2, 1) both;
}
.mk-hero [data-myk-hero-in="1"] { animation-delay: 100ms; }
.mk-hero [data-myk-hero-in="2"] { animation-delay: 220ms; }
.mk-hero [data-myk-hero-in="3"] { animation-delay: 340ms; }
.mk-hero [data-myk-hero-in="4"] { animation-delay: 460ms; }

.mk-hero [data-myk-hero-in="2"] h1 {
  animation: mykHeroInk 1400ms cubic-bezier(.4, 0, .2, 1) 220ms both;
}

.mk-hero picture[data-myk-hero-img] {
  animation: mykHeroImg 1000ms cubic-bezier(.4, 0, .2, 1) 100ms both;
}

/* R6-03 (FT-20260820 round 6): "I can still see the GRADIENT before the fade
   completes. Start from plain white — no gradient visible — then everything
   fades in together."

   Round 5 put the PHOTO on the 1000ms Omai image fade but left the scrim —
   the inline 180deg #0b0f1280->#0b0f12 gradient on `.row-bg-overlay`
   (00-hero.html §1.2(c)) — painting at full strength from t=0, so first paint
   was white + a dark gradient with no photo under it. Same keyframe, same
   1000ms, same 100ms delay, same curve as the <picture>: the two layers now
   rise as one paint. The min-height:1000px block in B.4 only re-declares
   `background` (with !important), not opacity, so this animation reaches that
   variant too. First paint is the white base on .inner-wrap and nothing else.

   AUDITED: these are the only two layers painting over the hero photo band at
   first paint — the video stack is an inert <template>, `.row-bg` carries no
   paint of its own, and the header/cue run their own entrance clocks and do
   not cover the photo.

   R7-01 (2026-08-21): this keyframe is now what makes the ground token a TRUE
   one-value switch. Under the dark default the scrim is a dark gradient over a
   dark ground, so its fade is imperceptible and deleting it would look like a
   simplification — do not. Flip --mk-hero-ground back to var(--mk-surface-mist)
   and this rule is again the whole of R6-03. The two layers rise as one paint
   in BOTH variants; only the colour they rise out of changes. */
.mk-hero .row-bg-overlay {
  animation: mykHeroImg 1000ms cubic-bezier(.4, 0, .2, 1) 100ms both;
}

/* The old split-heading pinning rules a few blocks up key on
   [data-animation-type="line-reveal-by-space"], which no longer exists in this
   section's markup — they are inert by construction, left in place as the
   rollback path. */

@media (prefers-reduced-motion: reduce) {
  .mk-hero [data-myk-hero-in],
  .mk-hero [data-myk-hero-in="2"] h1,
  .mk-hero picture[data-myk-hero-img],
  .mk-hero .row-bg-overlay {          /* R6-03: scrim lands instantly too */
    animation: none;
    opacity: 1;
    transform: none;
    color: #ffffff;
  }
}

/* ==========================================================================
   R6-02 / R6-04 REGRESSION FIX — the headline's size pipeline, restored.

   Round 5 removed `nectar-split-heading` from the headline wrapper to kill the
   masked reveal. What nobody saw: Salient's size chain rode on that class —
   salient-elements.css:49 `@media (min-width:1000px) .nectar-split-heading
   [data-custom-font-size="true"] h1 { font-size: inherit }` is how the h1
   inherited the wrapper's inline `font-size: var(--mk-size-hero)` (96px).
   Class gone -> rule dead -> h1 fell to the generic heading scale (~60px), and
   below 1000px the band rules produced the inverted responsive behaviour
   Jehnean described. The "font change" she saw is Merriweather's opsz axis:
   at 60px vs 96px with font-optical-sizing:auto the letterforms genuinely
   differ. Family never changed; the size did, and the face followed.

   This is the donor's rule re-scoped to our class, byte-equivalent behaviour
   at every width. The animation (mykHeroRise/mykHeroInk) is untouched. */
@media only screen and (min-width: 1000px) {
  .mk-hero .mk-hero__headline[data-custom-font-size="true"] h1 {
    font-size: inherit;
    line-height: inherit;
  }
}

/* ==========================================================================
   R6-05 — the scroll cue fades out on scroll, Omai's clock exactly.

   Trigger + toggle: the inline script at the end of sections/00-hero.html
   writes `mk-scrolled` on <html>, both directions — Omai's own controller
   shape (their cd() @main-CZCy3EJJ.js:360278 toggles body.scrolled at 200;
   measured live, probe-omai-indicator.py).

   R7-02 (2026-08-21): the THRESHOLD moved, this rule did NOT. Round 6's 200
   was measured to be at exact parity with Omai (205/206/207/206/240 sampled
   on theirs; 200 on ours at every width) — so Omai's proportion could not fix
   the "disappears prematurely" defect, because we were already shipping it.
   The script now derives the threshold from our own geometry (450/450/490/
   556/478 at the five review widths). EVERYTHING BELOW IS UNCHANGED: same
   600ms, same curve, same symmetry, same row-wrapper placement, so the idle
   dip and the Salient entrance keep their own clocks. Full reasoning and the
   rollback knob are in the comment above that script.
   Fade: opacity only, 600ms, cubic-bezier(.25,.5,0,1) — read off their live
   [data-scroll-indicator] verbatim, same curve both directions (their
   `bottom .4s` term is a cookie-banner offset we do not have).

   The transition sits on the ROW WRAPPER so the arrow's idle-dip loop
   (ctaMinimaLArrowOuter, on the svg) and its Salient delay-js entrance (on
   the column) keep their own clocks untouched — the founder's praise list
   names the arrow. pointer-events off while hidden: ours is a real <a>
   (skip-hash); an invisible click target is a keyboard/pointer trap Omai
   does not have (theirs is an inert div). */
.mk-hero .mk-hero__cue {
  transition: opacity .6s cubic-bezier(.25, .5, 0, 1);
}
html.mk-scrolled .mk-hero .mk-hero__cue {
  opacity: 0;
  pointer-events: none;
}
/* Reduced motion: state lands instantly, same both directions. */
@media (prefers-reduced-motion: reduce) {
  .mk-hero .mk-hero__cue { transition: none; }
}

/* ==========================================================================
   MOBILE ROUND (FT founder feedback, 2026-08-31) — CTA presence + copy bump.
   Desktop >=1000px is untouched: every rule below sits inside a max-width
   gate, and no value outside a gate is restated.

   CTA: the pill is `height: var(--myk-btn-height)` (myk-btn.css §2.1, 40px),
   so padding-block cannot grow the box — the height token is the one lever.
   54px keeps the label's 24px leading centred by the component's own
   align-items:center; radius/paint are untouched (the token feeds only the
   box). Label 16 -> 17 via the size token for the same reason.               */
@media only screen and (max-width: 999px) {
  .mk-hero .myk-btn--hero-cta {
    --myk-btn-height: 54px;                  /* 40 -> 54, founder: "not hug"  */
    --myk-btn-size: 17px;                    /* 16 -> 17                      */
  }
}

/* Copy bump at the phone edge. The h1 is DISCONNECTED from the wrapper's
   clamp below 691: the vendored phone tier ships `body h1{font-size:39px;
   line-height:39px}` (salient-dynamic-styles…css, max-width:690 block) at
   (0,0,2), which beats inheritance — the same defect _band-xs.css §1 proved
   and repaired for 691-999. Reconnect with `inherit` (0,3,1 wins plainly),
   then raise the clamp MINIMUM only — 2.5rem -> 2.5625rem (40 -> 41) — so
   the ramp's 7vw arm and 6rem cap are byte-identical and >=1000px never sees
   this rule. Net at 412px: 39 -> 41. line-height cannot be `inherit` here
   (the wrapper's inline var(--mk-lh-hero) is the fixed 121px box); 1.26 is
   §4's Merriweather auto ratio, the same value the old span rules used.     */
@media only screen and (max-width: 690px) {
  .mk-hero .mk-hero__headline { font-size: clamp(2.5625rem, 7vw, 6rem) !important; }
  .mk-page .mk-hero .mk-hero__headline h1 {
    font-size: inherit;                      /* vs vendored `body h1{39px}`   */
    line-height: 1.26;                       /* §4 — never the wrapper's 121  */
  }
}
/* Subhead: the whole phone tier renders 17px today — B.4 authors it at <=640
   and the vendored max-width:690 tier's own body scale lands the same 17 for
   641-690 (probed live at 660: fontSize 17px). One gate covers both, a pure
   bump everywhere it fires. Equal specificity, later in file — wins at <=640
   over B.4; B.4's 165% line-height is kept. */
@media only screen and (max-width: 690px) {
  .mk-hero__body { font-size: 18px; }        /* 17 -> 18, line-height 165% kept */
}
