/* =========================================================================
   INTRO-1 LIP-REVEAL — Matey rests as a CENTRED BAND and a CLIP-PATH reveals it to
   full on scroll (pellmell.fr "Our Work since…" model).  INTRO-1 ONLY.  v=25

   WHAT THE BASE DOES (ff2391f, off-limits): Part III is a pure TRANSLATE — the
   card+caption unit #heroProject is FULL SIZE at every scroll position and only
   its y slides from the lip up to a flush-top rest, while .hero-title parallaxes
   up −260 behind it. There is NO scale anywhere in the base.

   WHAT THIS ADDS (overrides only — the base file is byte-identical):
     1. --gap-3  → 123px : the card's RESTING PARK sits below the title block, at
        the base gap ×2.06 (59.62 → 123). Was 300 (the 150px park doubled); CUT BY
        177 to DOUBLE THE REVEAL LIP, 177 → 354 tall (user 2026-07-25). The base JS reads
        --gap-3 to compute projectLipY (var GAP_3 = getComputedStyle(html)['--gap-3']),
        so restating the token here moves the rest park with NO base-JS edit — the
        exact seam css/pellmell-intro-rhythm.css already uses for INTRO-2. This is
        the LIP REST position only (not a flow margin); the pinned rise-translate and
        title-cover are byte-identical to ff2391f. Base untouched.
     2. .hero-card FLUID sizing, CAPPED at pellmell's max — width = min(89.58%·VW, 1492px),
        height via aspect-ratio 1290/600 (auto-caps 694). The corner radius is NOT
        overridden — the base 52.8px stands, matching INTRO-3 (user 2026-07-25). Grows
        with the viewport like pellmell (1290×600 @1440 → 1492×694 @≈1666) then HELD at
        1492×694 (pellmell caps there too). The scan sequence is built to 1277×660 and
        will be mis-fit at this footprint — FLAGGED.
     3. The CLIP-PATH reveal itself lives in js/pellmell-intro-lipscale.js, scrubbing
        --lip-reveal (reveal progress 1 → 0) on .hero-card — a DIFFERENT property +
        element than the base's transform targets (#heroProject y, .hero-title y), so
        the rise-translate and the title-cover stay byte-identical to ff2391f. NO
        scale: the box is its full fixed footprint the whole way; only the clip animates.

   The pin (.hero fixed), #scrollTrack, the rise-guard and the title-cover are all
   the shared base and are NOT touched. Portfolio + INTRO-3 never load this file.
   ========================================================================= */

/* (1) Lip park — restated on :root so it wins the cascade over the base's
   `--gap-3: var(--edge-gap)` (same specificity, later in load order). @property
   registers --gap-3 as <length> in the base, so this literal resolves for the
   base JS's parseFloat. Value: 123px ink-bottom(role) → card top.
   History: ~100 (Figma comp) → 150 → 300 (doubled) → 123 here.

   WHY 123 — THE LIP HEIGHT IS THIS NUMBER, INVERTED. The park is the ONLY control
   over how tall the resting lip reads:

       card-lip-top = role-ink-bottom + --gap-3           (base JS, --card-lip-top)
       visible lip  = viewport height − card-lip-top − (--lip-v × card height)

   role-ink-bottom is fixed by the title block above (it never reads --gap-3), and the
   band's BOTTOM edge sits far below the fold (y ≈ 1301 on a 990-tall window), so the
   fold — not the clip — cuts the lip. Every px off --gap-3 is therefore a px ONTO the
   lip, at every viewport. 300 → 123 buys the 177 that doubles it: 177 → 354.

   DO NOT reach for --lip-v for height. It runs the wrong way (larger = shorter lip)
   and its whole 0–2% range is worth 13.86px on a 692.9-tall card — 8% of the 177
   needed. It is a lip-SHAPE control, not a lip-HEIGHT one.

   COST TO THE BASE SCROLL (ledger in js/pellmell-intro.js, Part III): travel ==
   card-lip-top, so it shortens by the same 177 — 799.2 → 622.2 @1663×990 (−22.15%),
   771.91 → 594.91 @1440×894. This does NOT breach the ledger's "travel only ever
   shrinks" watch: the 300 park had INFLATED travel to 771.91, well past the v=13
   baseline 691; 594.91 is still +11.9% LONGER than the base pose's own 531.53
   (--gap-3 = --edge-gap), which is the shipped, accepted feel. The park change moves
   travel back TOWARD the base, never below it. No base-JS edit: the base reads
   --gap-3 at init, and the reduced-motion path reads --card-lip-top, which derives
   from the same token — both follow, ff2391f stays byte-identical.

   The one number to turn if the lip wants tuning. */
:root {
  --gap-3: 123px;
}

/* WIDTH HALF OF THE 1276x660 RESIZE (user 2026-07-28). TEST — may be reverted.
   The base sets --content-width: 89.58% ("1290 / 1440 — card width") and .hero-card fills it.
   1276 at 1440 is 88.6111, so the WRAPPER is overridden here rather than the token: the token is
   also spent elsewhere in the base and is shared with v2/v3, and this file is INTRO-1 only.
   `left` is untouched, so the card's left edge does not move — only its right edge comes in 14px.
   The height half is the aspect-ratio on .hero-card below.

   *** FIXED px, NOT FLUID — AND THAT IS FORCED, NOT PREFERRED. *** THE EF PANEL IS A FIXED
   1276px BOX (css/pellmell-intro-ef.css). A fluid width can only equal a fixed one at a single
   exact viewport, so "match EF's size" and "stay fluid" are not both satisfiable. Both fluid
   forms were measured at a 1440 viewport and BOTH missed:
       88.6111%   -> 1262.7 x 653.1   (% resolves against .hero, the viewport minus scrollbar: 1425)
       88.6111vw  -> 1262.7 x 653.1   (vw resolved against 1425 here too)
   Fixed 1276 is the only form that actually matches, and it matches at every viewport, exactly
   as EF does. THIS IS THE TRADE THE BRIEF PUT IN SCOPE when it made the cap re-derivable.
   WHAT IT COSTS: the fluid-up-to-1492 pellmell parity this file exists to hold. The card no
   longer grows with the viewport, and `max-width: 1492px` on .hero-card is now INERT (1276 never
   reaches it). If the test is kept, that parity decision needs revisiting deliberately; if it is
   reverted, restore --content-width's 89.58% and aspect-ratio 1290/600 together.
   (Worth noting: 89.58% of 1425 is 1276.5 — almost certainly where the EF footprint's erroneous
   "1276 = the Matey #heroCard size" came from. It was the scrollbar-narrowed width, sampled.) */
.hero-project {
  width: 1203.973px;                   /* == EF's PAINTED width (was 1276, EF's transparent panel) */
  max-width: 100%;                     /* never overflow a narrow viewport */
  /* CENTRED (user 2026-07-28), was `left: var(--content-left)` = 5.21%. That left the card 35.52px
     left of EF's painted box, which is itself centred (panel centred, deck centred within it), so
     the two never lined up except by accident at one width.
     `left` and not a transform: GSAP owns this element's transform (the Part III rise animates its
     y), so a CSS translateX would be overwritten on the first tick.
     SCOPE: the CARD only. `--content-left` is shared with the wordmark and the base title (see
     css/pellmell-intro.css) and those are NOT centred here — pellmell centres both and INTRO-1
     deliberately does not (this file's own note further down). Left/right symmetry of the card
     against a still-left-aligned title is a composition change; flagged, not extended. */
  left: calc((100% - 1203.973px) / 2);
}

/* (2) Full footprint — FLUID 89.58vw, CAPPED at pellmell's max 1492×694 (aspect-ratio-LED).
       width  = min(89.58%·VW, 1492px)   (base wrapper --content-width, held by max-width)
       height = width × 600/1290          (aspect-ratio 1290/600 = 2.15; auto-caps at 694)
       border-radius: 52.8px              (base value, NOT overridden here — see below)

   pellmell.fr's project media is 89.58vw (confirmed in its live `sizes`) on a fluid root
   font-size (font-size: calc(1000/--size·1vw), --size 1440 desktop), so it grows with the
   viewport — but it CAPS at ~1492×694 (its max). We match both: fluid up to the cap, held
   after. (An earlier no-cap pass overshot to 1656×768 on this 1848 display.)
       VW 1440  → 1290×600   (89.58%·1440 = 1290 exactly; aspect → 600)
       VW ≈1666 → 1492×694   (cap engages — pellmell's max)
       VW ≥1666 → 1492×694   (HELD). Below 1666 it scales with the viewport.
   aspect-ratio 1290/600 OVERRIDES the base's 1290/667 (which gives 667-tall, not the 600
   anchor).

   WHY THE CAP EXISTS — PELLMELL PARITY, NOT A MECHANICAL CONSTRAINT (corrected 2026-07-27).
   This block used to justify the cap mechanically: "capping keeps the box 694-tall, so the rest
   clip band's top (14.69%·height down) stays above the fold — an uncapped 768-tall box sank it
   and collapsed the lip." THAT REASONING IS STALE. It was written when --lip-v was symmetric
   with --lip-h at 14.6909%; --lip-v is now 2% (cut precisely because the symmetric inset was
   eating ~100px of the peek), and at 2% the card's HEIGHT barely reaches the band's top.
   Measured at 1920x1000: removing the cap moves the band top 638.9 → 640.9 and the visible lip
   361.1 → 359.1 — a 2px cost, not a collapsed band.
   THE REAL REASON THE CAP STAYS is the one in this file's own header: pellmell.fr's project
   media caps at ~1492x694, and INTRO-1 matches it — fluid up to the cap, held after. That is a
   DESIGN decision (user, 2026-07-27: "keep pellmell parity"), and it is the thing anyone
   proposing to remove the cap would actually be overruling.
   A stale rationale sitting beside a live value is how the value gets removed by the next
   person who checks the arithmetic and finds it does not hold.
   NOTE also that removing the cap alone would NOT match INTRO-3: the aspect-ratio override
   above is a SECOND divergence (uncapped INTRO-1 would be 1706.5x793.7 at 1920 against
   INTRO-3's 1706.5x882.3). Both stay.
   89.58vw + 1492 cap + 1290/600 are THE numbers to turn.
   NOTE: the scan (js/pellmell-intro-scan.js) is authored to 1277×660 and will be
   mis-fit inside this footprint — a separate re-fit pass, flagged in the report. */
/* --lip-reveal = reveal PROGRESS (1 = rest band, 0 = full). Registered as <number>
   so it interpolates cleanly; initial 0 = fully revealed (the no-JS / reduced-motion
   fallback — JS sets it to 1 for the rest band only when it runs). */
@property --lip-reveal {
  syntax: "<number>";        /* reveal PROGRESS: 1 = rest band, 0 = full. (was <percentage>) */
  /* INHERITS (was false, 2026-07-27). css/pellmell-intro-content-scale.css drives the
     inner-card content (project title + title rail) off this SAME progress, and its rules
     sit on DESCENDANTS of .hero-card — which cannot read a non-inheriting property. The
     alternative (a second property tweened in a second file) would have to re-declare
     REVEAL_LOCK and the ease, and TODO 07-24 already schedules a REVEAL_LOCK nudge
     0.5 → ~0.45; the two would then desync SILENTLY. One source, no desync.
     THE REVEAL MODEL IS UNCHANGED: clip-path, --lip-h, --lip-v, REVEAL_LOCK, the ease and
     the timeline are all byte-identical. Only this flag moved. Cost is an ambient readable
     var on ~20 descendants + animated-property recalc across that subtree — bounded, cheap.
     COUPLING: REVEAL_LOCK now times BOTH the clip reveal and the content spread. Tuning the
     reveal tunes the content. Intended — see the content-scale css/js headers and TODO. */
  inherits: true;
  initial-value: 0;          /* 0 = fully revealed (no-JS / reduced-motion fallback) */
}
.hero-card {
  /* FLUID 89.58vw, CAPPED at pellmell's max (1492×694). Width = min(89.58%·VW, 1492px)
     — comes from #heroProject (--content-width) but held by max-width; height via
     aspect-ratio 1290/600 (= 2.15), which caps at 694 the instant width caps at 1492.
       VW 1440  → 1290×600   (89.58%·1440 = 1290 exactly; aspect → 600)
       VW ≈1666 → 1492×694   (cap engages — pellmell's max)
       VW ≥1666 → 1492×694   (HELD — matches pellmell, which also caps here)
     Fluid up to the cap, then held: grows with the viewport like pellmell but stops at
     pellmell's size instead of overshooting. The cap also keeps the box 694-tall, so the
     rest clip band's top (14.69%·height down) doesn't sink below the fold (lip stays read-
     able) — an uncapped 768-tall box pushed the band down and collapsed the lip. */
  /* ── SIZED TO EF'S **PAINTED** BOX, 1203.973 x 660 (user 2026-07-28). ──────────────────
     CORRECTED TARGET. The first pass matched 1276x660 — .visual-panel.ef-visual's LAYOUT box.
     That element is `background: transparent` and paints NOTHING; the visible EF container is
     the card deck inside it, which is 72.03px narrower. Measured painted extents:
         EF    x 109.75 -> 1313.72 = 1203.97      (the four .ef-screen cards)
         Matey x  74.23 -> 1350.23 = 1276.00      (this card, which does paint)
     Both numbers DERIVE from EF's own card geometry, so neither is transcribed:
         width  = .ef-screen 799 x .ef-stack scale 1.50685 = 1203.973
         height = .ef-screen 438 x 1.50685              =  660.000
         aspect = 799 / 438                             =    1.824201
     *** MANUAL-SYNC HAZARD: if .ef-screen's 799 or .ef-stack's 1.50685 ever change, these two
     values must change with them. There is no live link. ***
     Width comes from the .hero-project override above; this is the height half.

     THIS RETURNS THE CARD TO ~THE BASE'S OWN PELLMELL PROPORTION. css/pellmell-intro.css
     authors .hero-card at `aspect-ratio: 1290 / 667` and calls it "Pellmell proportion
     (≈1.934)". 1276/660 = 1.93333 against that 1.93403 — **0.036% apart**. The 1290/600
     override this replaces was 2.150, i.e. the override was the divergence, and dropping it
     lands back on the base ratio rather than inventing a third one.

     IT ALSO CLOSES A DOCUMENTED MIS-FIT. This file's own header says: "the scan
     (js/pellmell-intro-scan.js) is authored to 1277x660 and will be mis-fit inside this
     footprint — a separate re-fit pass, flagged in the report." 1276x660 IS that footprint,
     to within a pixel of width. The re-fit pass is no longer needed.

     THE CAP IS NOW INERT, which is the re-derivation the brief asked for. `max-width: 1492px`
     is kept as a declaration but the box is a fixed 1276, so it never binds. Its live reason was
     pellmell parity — "pellmell.fr's project media caps at ~1492x694, and INTRO-1 matches it" —
     and a fixed box gives up that parity outright, which is the trade recorded on .hero-project
     above. The old MECHANICAL argument for the 694 half ("an uncapped 768-tall box sank the band
     and collapsed the lip") does not apply either way: this file already records that reasoning
     as STALE, measured at 1920x1000 as a **2px** cost, not a collapsed band, since --lip-v went
     to 2%. The clip band itself is untouched — --lip-h / --lip-v are FRACTIONS of the box, so
     they re-derive on the new height with no edit.

     NOTHING ELSE HARDCODES THE OLD SIZE. Grepped: this was the only literal 600/694 in the
     INTRO-1 sheets and js. Every other consumer is a FRACTION of the measured box — scan.js's
     thumb (cw x 0.2693), lensSize, cardStart, stackStartY, aptR, --bp-glow-blur; content-scale's
     LIP_H, CENTRE_HALF, --cs-*; scan.css's percentage insets — so they all re-derive on their
     own. The dress assets (apt / blueprint / measurement lines) are authored on ONE 1290x602
     frame and share ONE fit rule (object-fit: cover; the lines svg carries the matching
     preserveAspectRatio="xMidYMid slice"), so they stay registered WITH EACH OTHER and simply
     crop 69.1px per side at the new ratio — accepted (user: background, no significant content).
     Inner content POSITIONS, the reveal and the cadence are untouched. */
  aspect-ratio: 799 / 438;
  max-width: 1492px;
  /* BORDER-RADIUS IS NOW OVERRIDDEN, 52.8 -> 10 (user, 2026-08-24). The Matey project
     container joins the project screens on the FOOTER's 10px corner.
     OVERRIDDEN HERE, NOT EDITED AT THE BASE. `css/pellmell-intro.css` .hero-card is
     SHARED — pellmell-intro-v3.html and -rhythm.html both load it — so changing 52.8
     there would silently reshape INTRO-3's card too. This sheet is INTRO-1-only (v3
     loads feed.css instead), so the override is scoped correctly and INTRO-3 keeps 52.8.
     This supersedes the old "NO border-radius override" note that stood here: INTRO-1's
     foreground corners deliberately NO LONGER match INTRO-3's.
     The card is unscaled, so 10 authored paints 10.
     The clip-path `round` below spends the SAME 10 so the clip corner and the box corner
     are one shape — the two must always move together. */
  border-radius: 10px;
  /* CLIP-PATH LIP REVEAL. --lip-reveal is the PROGRESS (1 = rest band, 0 = full),
     scaling two rest insets INDEPENDENTLY:
       --lip-h (horizontal) = the width band  (matches pellmell's ~1074 rest width);
       --lip-v (vertical)   = SMALL, so the clip never eats the peek's TOP. A symmetric
                              14.69% cut ~100px off it; 2% costs 13.86px on a 692.9-tall
                              card and no more.
                              NOT THE HEIGHT CONTROL — the lip is FOLD-limited, not clip-
                              limited (the band's bottom edge is ~300px below the fold),
                              so --lip-v's whole 0–2% range is worth 13.86px and it runs
                              BACKWARDS (larger = shorter). Lip height is --gap-3, the
                              park — see (1) above. This one only shapes the band's top.
     Runs on clip-path (not transform) on .hero-card — a different property + element
     than the base's transforms (#heroProject y, .hero-title y), so the rise-translate
     + title-cover stay byte-identical. */
  --lip-h: 14.6909%;
  --lip-v: 2%;
  clip-path: inset(calc(var(--lip-reveal) * var(--lip-v)) calc(var(--lip-reveal) * var(--lip-h)) round 10px);
  will-change: clip-path;
}

/* (4) CENTRED COMPOSITION (pellmell "Our Work since…"). The base left-aligns the title
   + card at --content-left; pellmell CENTRES both, from rest through the whole scroll.
   Horizontal only — the vertical gap system, the lip park, the pin, #scrollTrack and the
   title-cover are all untouched.

       card:    min(89.58vw, 1492) → 1492 @≥1666 (capped); rest = centred clip band (no width scale)
       title:   "Shoon" centred (fit-content + margin:auto) → ~381 padding @1920
       tagline: BROWNE + UX PRODUCT DESIGN, flush-left with each other, indented 57px
                right of "Shoon"'s left edge (relative to the centred title)
   Both the card and the title are centred by margin:auto (no transform), so the base's
   own transforms (card rise-y, title parallax-y) stay byte-identical and simply move the
   already-centred boxes UP on scroll — they never shift horizontally. */

/* Card: fills the --content-width wrapper (89.58%·VW), which the base positions
   symmetrically (left 5.21vw / width 89.58vw) → the card is centred at every width, no
   cap. margin:auto is a no-op now (card == wrapper width). The clip inset is symmetric,
   so the revealed band stays concentric with this box. */
.hero-card { margin-inline: auto; }

/* Title: CENTRED (pellmell is centred from rest through scroll — it only moves UP, never
   left→centre). fit-content shrinks .hero-title to its widest line ("Shoon"); left:0
   right:0 + margin-inline:auto then centres that block in the viewport → "Shoon" sits
   centred (its own padding, ~381 each side @1920; the 214/257 pellmell quoted are for the
   wider word "pellmell"). NO transform is used here, so the base's title-y parallax (and
   nothing else) owns the transform — the title rises straight up, staying centred. */
.hero-title {
  left: 0;
  right: 0;
  width: fit-content;
  margin-inline: auto;
  /* fit-content is INTRINSIC sizing — the browser recomputes .hero-title's width from
     its content, which de-optimises compositing of the animated descendants inside it
     (the Part-II tagline reveal went "mechanical"). Promote .hero-title to its own layer
     so that recalc is contained and its children composite against a stable surface.
     (The base already transforms this element on scroll, so a layer is warranted anyway.) */
  will-change: transform;
}

/* Restore the buttery Part-II reveal on the tagline lines. They animate transform+opacity
   (base tier-2: y + opacity, staggered) but — unlike the "Shoon" .ht-char letters, which
   carry their own will-change — had none, so under the fit-content title above they fell
   off the GPU fast-path. Give them the SAME promotion .ht-char already has. */
.ht-browne, .ht-role { will-change: transform, opacity; }

/* Tagline block (BROWNE + UX PRODUCT DESIGN): the whole .ht-sub wrapper is indented ~57px
   right of "Shoon"'s LEFT EDGE — the pellmell tagline indent, relative to the (now centred)
   title, not the viewport. Both lines sit in .ht-sub, so indenting the WRAPPER keeps them
   FLUSH-LEFT with each other (not staggered). It is a flex item in .hero-title (fit-content
   = "Shoon"'s box), so this margin measures from Shoon's left edge and does not touch the
   vertical gap chain. */
.ht-sub { margin-left: 57px; }
