/* THE UNSIGNED HOMEPAGE (Maaz's mock, 2026-09-15).
   Source: specs/backstage-pass-homepage.html — layout, graphics, structure and
   copy 1:1. What is OURS is the palette and the two type voices (Maaz: "colors
   + font are ours; everything else is the HTML"): the mock's Manrope/Sora pair
   is replaced by var(--sans)/var(--display) and its ink/panel/gold/cream/live
   by the door mood's own tokens, so the page cannot disagree with the rest of
   the product about what gold is.

   EVERY CLASS IN HERE IS PREFIXED `lp-`, and that is this house's own lesson
   rather than tidiness: the mock's own names collide with five live rules in
   application.css — `.hero` (8), `.live-dot` (12, with the reduced-motion
   machinery hung off it), `.clip-card` (8), `.logo` (3) and `.gold` — and a
   name already taken is how a surface inherits a box by reaching for a
   familiar word (the `.fan-card` / `.flyfig__reach` rounds). The markup's
   structure is the mock's; only the words on the class attributes are namespaced.

   IT IS ALSO ITS OWN SHEET, loaded by the landing alone with
   `data-turbo-track="dynamic"` — Turbo 2.0.23 adds a dynamic stylesheet when
   the new head carries it and REMOVES it when the next one does not (verified
   in turbo.min.js: removeUnusedDynamicStylesheetElements), so ~600 lines of
   marketing CSS never rides a studio screen and never lingers after a visit.

   `test/views/landing_css_declared_test.rb` is the #415 fence: every class the
   view renders has a rule here, and nothing in here is unscoped. */

/* ── the mood's tokens, in the mock's own vocabulary ───────────────────────── */
body.lp {
  /* the five colours the mock names, mapped onto the door mood */
  --lp-ink: var(--bg);           /* #030303 */
  --lp-panel: var(--surface);    /* #202123 */
  --lp-gold: var(--gold);        /* champagne #d4a84b since #730 */
  --lp-cream: var(--text);       /* #f2f0ea */
  --lp-live: var(--live);        /* #e5484d */

  /* the alpha ladders. They are spelled from the resolved channels rather than
     color-mix so a rule reads exactly as the mock's did; if a mood's canvas
     moves, these three lines are the whole edit. */
  --lp-cream-10: rgb(242 240 234 / 0.10);
  --lp-cream-15: rgb(242 240 234 / 0.15);
  --lp-cream-20: rgb(242 240 234 / 0.20);
  --lp-cream-30: rgb(242 240 234 / 0.30);
  --lp-cream-40: rgb(242 240 234 / 0.40);
  --lp-cream-45: rgb(242 240 234 / 0.45);
  --lp-cream-50: rgb(242 240 234 / 0.50);
  --lp-cream-55: rgb(242 240 234 / 0.55);
  --lp-cream-60: rgb(242 240 234 / 0.60);
  --lp-cream-70: rgb(242 240 234 / 0.70);
  --lp-cream-75: rgb(242 240 234 / 0.75);
  --lp-gold-10: rgb(224 182 105 / 0.10);
  --lp-gold-12: rgb(224 182 105 / 0.12);
  --lp-gold-15: rgb(224 182 105 / 0.15);
  --lp-gold-30: rgb(224 182 105 / 0.30);
  --lp-gold-40: rgb(224 182 105 / 0.40);
  --lp-gold-80: rgb(224 182 105 / 0.80);
  --lp-ink-15: rgb(3 3 3 / 0.15);
  --lp-ink-50: rgb(3 3 3 / 0.50);
  --lp-ink-55: rgb(3 3 3 / 0.55);
  --lp-ink-60: rgb(3 3 3 / 0.60);
  --lp-ink-65: rgb(3 3 3 / 0.65);
  --lp-ink-75: rgb(3 3 3 / 0.75);
  --lp-ink-90: rgb(3 3 3 / 0.90);
  --lp-live-15: rgb(229 72 77 / 0.15);
  --lp-live-40: rgb(229 72 77 / 0.40);
}
/* The mock's own `html { scroll-behavior: smooth }`, scoped. It has to reach
   the ROOT element — for viewport scrolling the behaviour is read off `html`
   (browsers propagate it from `body` too, but not reliably) — so `:has()` is
   what keeps the rule on this one page instead of the whole product. The
   `body` rule stays beside it for a browser that reads that instead. */
html:has(body.lp), body.lp { scroll-behavior: smooth; }

/* ── THE MASTHEAD IS THE MOCK'S HEADER (one header, never two) ──────────────
   The mock draws its own 64px bar with the wordmark left and Discover /
   Pricing / Sign in right — which is what `header.topbar` already is on a
   logged-out page, so the landing repositions the house masthead instead of
   stacking a second one under it. Absolute, so it scrolls away over the hero
   exactly as the mock's does, and centred on the page's own 1280 column so the
   wordmark lines up with the hero under it.

   NO `backdrop-filter`. The mock veils the bar with ink at 55% + a 12px blur;
   r9 took that treatment OFF this element on purpose (a compositing layer is
   rasterised on its own origin, so every hairline inside it — here, the gold
   Sign in pill — is snapped against the layer instead of the page). The hero's
   canvas behind the bar is the ink anyway, so transparent reads as the mock's
   veil with none of the cost. */
body.lp header.topbar {
  position: absolute; top: 0; left: 0; right: 0;
  max-width: 1280px; margin: 0 auto;
  background: transparent; border-bottom-color: transparent;
}
body.lp .topbar__link { font-variant-caps: normal; letter-spacing: 0; }
body.lp .topbar__link, body.lp .topbar__pill { font-size: 0.875rem; font-weight: 600; }

/* ── the page ──────────────────────────────────────────────────────────────── */
.lp { display: block; }
.lp-container { width: 100%; max-width: 1280px; margin: 0 auto; padding: 0 20px; }
.lp-section { padding: 96px 0; }
.lp-gold { color: var(--lp-gold); }

@keyframes lp-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes lp-livepulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.lp-rise { animation: lp-rise 650ms ease-out both; }
.lp-delay-100 { animation-delay: 100ms; }
.lp-delay-180 { animation-delay: 180ms; }
.lp-delay-260 { animation-delay: 260ms; }
.lp-pulse { animation: lp-livepulse 1.8s ease-in-out infinite; }

/* ── hero ──────────────────────────────────────────────────────────────────── */
.lp-hero {
  position: relative; min-height: max(640px, 100vh); display: flex; align-items: center;
  padding-top: 80px; border-bottom: 1px solid var(--lp-cream-10);
  overflow: hidden; text-align: center; background: var(--lp-ink);
}
.lp-hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.lp-hero-content { position: relative; z-index: 10; width: 100%; padding: 80px 20px; }
/* THE HEADINGS KEEP THE MOCK'S SENTENCE CASE. `h1, h2` in application.css are
   uppercase marquee caps — the house voice — and the mock's own copy is
   sentence case with a full stop, so the case is the copy's and the FACE is
   ours (the display voice, at the mock's own weight). */
.lp-hero h1 {
  font-family: var(--display); font-weight: 400; text-transform: none;
  font-size: 28px; --lh: 1.3; line-height: round(calc(1em * var(--lh)), 1px);
  max-width: 900px; margin: 0 auto; text-align: center;
}
.lp-hero .lp-gold { display: block; line-height: inherit; }
.lp-h1-line { line-height: inherit; }
/* THE LIVE PILL (Maaz 2026-09-17). It was an OUTLINED box holding red lowercase
   type on a red wash — red on red, so the one word in this headline that names
   the act read as the quietest thing in it. It is the pill every platform draws
   now: live-red FILL, white type, white dot. Four notes.
   · THE CAPS ARE `text-transform`, NEVER THE MARKUP. The H1's own sentence is
     "Go live everywhere." — §5.1 sales copy, asserted as that phrase by
     `public_pages_test` — so the LETTERS stay the copy's and the CASE is ours
     (the `Overlays::CutCard::HEADLINE` separation, applied to a word). It also
     keeps the accessible name a WORD rather than a four-letter run a screen
     reader may spell out.
   · NO BORDER. An outline inside a filled pill is two strokes on one control
     (r8), and it is the "no red-on-red" half of his note.
   · IT STAYS INLINE IN THE H1 at 0.85em of the display face. The reference is a
     chunky sans bar; a bar in a serif headline is another product's chrome.
   · WHITE ON `--live` MEASURES 3.9:1, which is AA for this word at every
     breakpoint: the pill is weight 700 and 23.8px at the phone's own floor, i.e. past
     the 18.66px large-BOLD threshold before the 24px one is even asked.
   `--lp-live-15` / `--lp-live-40` keep their rungs: the alpha ladders at the top
   of this sheet are declared as a SET (`--lp-gold-80` has had no consumer since
   the sheet was written), so pulling two out is the inconsistency, not the tidy. */
.lp-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0.22em 0.28em; border-radius: 6px;
  background: var(--lp-live); color: #fff;
  text-transform: uppercase; font-size: 0.55em; font-weight: 700;
  letter-spacing: 0.04em; line-height: 1;
  /* 8px down from the last lift — Maaz 2026-09-17. */
  vertical-align: calc(0.62em - 8px);
  /* 20% larger, grown from the bottom so the base does not move. */
  transform: scale(1.2);
  transform-origin: 50% 100%;
  /* Layout gap matches a word-space in the H1; scale(1.2) does not reserve it. */
  margin-inline: 0.28em;
}
.lp-dot { width: 6px; height: 6px; border-radius: 50%; background: #fff; flex: none; }
.lp-tagline { margin-top: 24px; font-size: 18px; color: var(--lp-cream-70); }
.lp-nowrap { white-space: nowrap; }
.lp-icons {
  margin: 28px auto 0; display: flex; align-items: center; justify-content: center; gap: 20px;
  width: fit-content; padding: 12px 18px; border-radius: 999px;
  background: rgb(7 6 5 / 0.72); border: 1px solid var(--lp-cream-15);
}
.lp-icon { color: var(--lp-cream); transition: color 0.2s; display: inline-flex; cursor: pointer; }
.lp-icon:hover { color: var(--lp-gold); }
.lp-icon svg { width: 26px; height: 26px; }

/* ── the claim forms (hero + closing) ──────────────────────────────────────── */
.lp-claim { max-width: 700px; margin: 40px auto 0; }
.lp-claim-row { display: flex; flex-direction: column; gap: 12px; }
.lp-claim-field {
  display: flex; align-items: center; min-height: 60px; flex: 1; padding: 0 24px;
  border-radius: var(--lp-control-radius, 8px); background: var(--lp-panel); border: 1px solid var(--lp-cream-15);
  transition: border-color 0.2s;
}
.lp-claim-field:focus-within { border-color: var(--lp-gold-40); }
.lp-claim-host { color: var(--lp-cream-50); font-size: 16px; white-space: nowrap; }
/* THE FIELD IS THE WRAPPER'S BOX AND THE INPUT PAINTS NOTHING OF ITS OWN.
   Every property here is a house form rule being turned OFF, not a style: this
   selector is (0,1,1) and so is `input[type="text"]` in application.css, so it
   only wins because the sheet loads from `:page_stylesheets` (after the
   house's) — and `border-radius` and `width` have to be named as well as
   `border`, or the house's 6px radius and `width: 100%` survive inside a
   control the mock draws as one seamless box. `border-radius` is invisible
   under `border: none` and is stated anyway, because the claim this page makes
   is that the house rule does not reach in here (measured in
   test/system/unsigned_homepage_test.rb). */
.lp-claim-field input {
  flex: 1; min-width: 0; width: auto; background: transparent;
  border: none; border-radius: 0; outline: none;
  color: var(--lp-cream); font-family: var(--sans); font-size: 16px;
  padding: 16px 0; margin-left: 4px;
}
.lp-claim-field input::placeholder { color: var(--lp-cream-30); }
/* THE BROWSER'S OWN FILL, ON THE ONE FIELD THIS PAGE ASKS FOR (Maaz's QA,
   2026-09-16). Chrome offers a saved username here — the input is called
   `handle` and carries `aria-label="username"` — and picking one painted the
   field a blue-grey block: the UA's autofill background, which is not an
   author `background` and so is unreachable by the rule above it. The
   1000px inset shadow is the only thing that covers it, `-webkit-text-fill-
   color` out-ranks `color` in that state, the caret goes with it, and the
   9999s transition is what keeps the field its own colour on a plane where
   the prefixed shadow is refused. The selection is the same fill's other
   half — inverse video in this page's own two colours, never the OS blue.
   The claim journey's own four fields carry the identical block
   (claim.css); this is the marketing field, and the two are one bug.
   NOT PROVOKABLE FROM A TEST (it needs Chrome's own dropdown and a real
   gesture), so it is asserted at the stylesheet level and nowhere else. */
.lp-claim-field input:-webkit-autofill,
.lp-claim-field input:-webkit-autofill:hover,
.lp-claim-field input:-webkit-autofill:focus,
.lp-claim-field input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--lp-panel) inset;
  -webkit-text-fill-color: var(--lp-cream);
  caret-color: var(--lp-cream);
  transition: background-color 9999s ease-in-out 0s;
}
.lp-claim-field input::selection { background: var(--lp-cream); color: var(--lp-ink); }
.lp-claim-go {
  /* ONE BUTTON GRAMMAR (Maaz 2026-09-19). The landing kept a third: an 8px
     slab where the product's control is a pill.

     IT READS A THEME-ONLY TOKEN, NOT `--radius-control`, AND THAT IS THE
     WHOLE POINT. `--radius-control` is 999px in the BASE sheet (#756 made
     every control a pill) — so reading it here would have made the landing's
     CTA a pill under CLASSIC too, which is a Classic regression wearing a
     fallback. A `var(--token, X)` only preserves Classic when nothing outside
     the theme block sets `--token`; where something does, the base value is
     what Classic computes and the fallback is decoration. The browser caught
     this; the textual fallback check could not. */
  min-height: 60px; padding: 0 32px; border-radius: var(--lp-control-radius, 8px); background: var(--lp-gold);
  color: var(--lp-ink); font-family: var(--sans); font-size: 16px; font-weight: var(--btn-weight, 600);
  border: none; cursor: pointer; transition: background 0.2s;
}
.lp-claim-go:hover { background: var(--lp-cream); }
/* AND NO `.lp-claim-hint` RULE (Maaz 2026-09-21). The format sentence came
   off this field the same day it landed: it is the input's `title` now, so
   Chrome says it when the field refuses a character and nobody else reads
   it. The rule went with the markup rather than being left behind — a class
   named after retired markup is how the next surface inherits a box by
   reaching for a familiar name. */

/* ── section headings ──────────────────────────────────────────────────────── */
.lp-label {
  font-family: var(--display); font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--lp-gold);
}
.lp-title {
  font-family: var(--display); font-weight: var(--headline-weight, 800); text-transform: none;
  font-size: 36px; --lh: 1.15; line-height: round(calc(1em * var(--lh)), 1px); margin-top: 16px;
}
.lp-sub { margin-top: 20px; max-width: 600px; color: var(--lp-cream-55); --lh: 1.7; line-height: round(calc(1em * var(--lh)), 1px); }

/* ── journey ───────────────────────────────────────────────────────────────── */
.lp-journey { margin-top: 64px; display: flex; flex-direction: column; gap: 28px; }
.lp-card { border-radius: var(--radius, 10px); overflow: hidden; border: 1px solid var(--lp-cream-10); background: var(--lp-panel); }
.lp-card--gold { background: var(--lp-gold); color: var(--lp-ink); border-color: var(--lp-gold); }
.lp-card--cream { background: var(--lp-cream); color: var(--lp-ink); border-color: var(--lp-cream); }
.lp-card-grid { display: grid; min-height: 480px; }
.lp-card-text { display: flex; flex-direction: column; justify-content: space-between; padding: 48px; }
.lp-step { font-family: var(--display); font-size: 13px; font-weight: 700; letter-spacing: 0.1em; color: var(--lp-gold); }
.lp-card--gold .lp-step { color: var(--lp-ink-55); }
.lp-card--cream .lp-step { color: var(--lp-ink-50); }
.lp-card-mark { color: var(--lp-gold); margin-bottom: 20px; display: block; }
.lp-card--gold .lp-card-mark, .lp-card--cream .lp-card-mark { color: var(--lp-ink); }
.lp-card-text h3 {
  font-family: var(--display); font-weight: var(--headline-weight, 700); text-transform: none;
  font-size: 30px; --lh: 1.2; line-height: round(calc(1em * var(--lh)), 1px);
}
.lp-card-text p { margin-top: 20px; max-width: 450px; color: var(--lp-cream-55); --lh: 1.7; line-height: round(calc(1em * var(--lh)), 1px); }
.lp-card--gold .lp-card-text p { color: var(--lp-ink-65); }
.lp-card--cream .lp-card-text p { color: var(--lp-ink-60); }
.lp-card-visual {
  position: relative; display: flex; align-items: center; justify-content: center;
  min-height: 320px; padding: 48px; border-top: 1px solid var(--lp-cream-10);
  background: rgb(242 240 234 / 0.025);
}
.lp-card--gold .lp-card-visual,
.lp-card--cream .lp-card-visual { border-top: 1px solid var(--lp-ink-15); background: transparent; }

/* 01 broadcast */
.lp-bcast {
  position: relative; display: grid; place-items: center; width: 112px; height: 112px;
  border-radius: 50%; border: 1px solid var(--lp-gold-30); background: var(--lp-gold-10); color: var(--lp-gold);
}
.lp-bcast-ring { position: absolute; border-radius: 50%; border: 1px solid var(--lp-gold-15); }
.lp-bcast-ring--1 { inset: -24px; }
.lp-bcast-ring--2 { inset: -48px; animation-delay: 1.2s; }
.lp-bcast-ring--3 { inset: -72px; animation-delay: 0.6s; }
@keyframes lp-ring { 0%, 100% { opacity: 0.22; } 50% { opacity: 0.9; } }
.lp-bcast-ring { animation: lp-ring 2.4s ease-in-out infinite; }
.lp-bcast-status {
  position: absolute; top: 24px; left: 24px; display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--lp-cream-45);
}
.lp-dests {
  position: absolute; left: 24px; right: 24px; bottom: 28px;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px;
}
.lp-dest { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.lp-dest-mark { display: grid; place-items: center; width: 40px; height: 40px; color: var(--lp-cream-75); }
/* THE MOCK OMITS THIS ONE and cannot render without it: its
   `.destination-icon` SVGs carry no width/height attributes and no CSS rule,
   so a browser gives them the default replaced-element size (300x150) inside a
   40x40 grid cell. 24 is the house's own glyph scale in a 40px box. */
.lp-dest-mark svg { width: 24px; height: 24px; }
.lp-dest-label { font-size: 11px; color: var(--lp-cream-45); }

/* 02 gather — the cut card, as the socials get it */
/* THE MOCK'S OWN LEGIBILITY BUG, STILL FIXED. Its `.gather-label` is
   `position: absolute; top: 0` inside a box whose FIRST in-flow child is the
   dark card, and a positioned element paints above a static one whatever the
   DOM order — so the caption landed on the card it captions. The wrapper's
   `padding-top` is what clears it, and `unsigned_homepage_test` measures that
   rather than arguing it. The block under it was rebuilt on 2026-09-16
   (Todd): the mock drew the cut as a show winding down beside a second room,
   and A14's cut is a feed SPLIT — the legs keep their session and get KB's
   card, so the illustration is that card. */
.lp-cut { position: relative; width: 100%; max-width: 500px; padding-top: 30px; }
.lp-cut-label {
  position: absolute; top: 0; left: 0; font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.15em; color: var(--lp-ink-50);
}
.lp-cut-screen {
  border-radius: 10px; overflow: hidden; color: var(--lp-cream);
  background: var(--lp-ink-90); box-shadow: 0 20px 40px rgb(0 0 0 / 0.25);
}
.lp-cut-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; font-size: 12px; border-bottom: 1px solid var(--lp-cream-10);
}
.lp-cut-live {
  display: flex; align-items: center; gap: 8px;
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--lp-cream-75);
}
.lp-cut-watchers { color: var(--lp-cream-60); white-space: nowrap; }
/* 16:9 IS THE STAGE'S, NOT THE CARD'S — the bar above it is chrome, exactly as
   it is on a platform's own player.
   NO `min-height` GOES NEAR IT, and that is the whole rule rather than a
   tidy-up. A box with an `aspect-ratio` and `min-height: auto` still grows to
   fit its content, so the ratio is what it gets WHEN THERE IS ROOM and the
   content is what it gets otherwise — free, at every width. Writing
   `min-height: min-content` here to "guarantee" that did the opposite: it
   replaced the automatic minimum with one Chrome resolves to nothing in the
   block axis, and at a true 390 (device metrics, never a 390px window) the
   stage clamped to 142px around a 186px card — the note cut off mid-word and
   the whole Join row, the one thing the copy beside it promises, painted
   outside a screen that is `overflow: hidden`. Measured both ways;
   `unsigned_homepage_test` reads the row at the desk AND on a phone. */
.lp-cut-stage {
  position: relative; aspect-ratio: 16 / 9;
  display: grid; place-items: center; padding: 10px;
}
/* A PICTURE OF A HOST, so the card reads as an overlay ON a feed rather than a
   panel on a black rectangle. Two shapes, no asset, announced to nobody. */
.lp-cut-host { position: absolute; inset: 0; overflow: hidden; }
.lp-cut-host::before,
.lp-cut-host::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  background: rgb(242 240 234 / 0.05);
}
.lp-cut-host::before { top: 12%; width: 20%; aspect-ratio: 1; border-radius: 50%; }
.lp-cut-host::after { top: 54%; width: 40%; height: 46%; border-radius: 50% 50% 0 0 / 38% 38% 0 0; }
.lp-cut-card {
  position: relative; width: 100%; border-radius: 8px; padding: 12px;
  border: 1px solid var(--lp-cream-15); background: var(--lp-ink-75);
}
.lp-cut-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.lp-cut-said { min-width: 0; }
.lp-cut-moved {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.16em; color: var(--lp-gold);
}
/* SENTENCE CASE IN THE MARKUP, CAPS HERE. The two lines above are read back
   against `Overlays::CutCard::HEADLINE` — how the frame sets them is
   typography, what they SAY is the claim (that class's own DOOR_ORDER note).

   AND IT SPELLS ITS OWN LEADING. `--lh-snap` is declared once at `:root`, so
   the 1.55 is already baked into the token every other rule in here inherits —
   a bare `--lh: N` beside it is inert (measured: this word rendered a 37px
   line box on a 24px face). One display word inside a card with a fixed height
   is the one place on this page where 13px of dead air under it is visible, so
   it takes the `.prof-name` precedent rather than the sheet's own idiom. */
.lp-cut-word {
  margin-top: 3px; font-family: var(--display); font-weight: var(--headline-weight, 800); font-size: 24px;
  text-transform: uppercase; color: var(--lp-gold);
  --lh: 1.05; line-height: round(calc(1em * var(--lh)), 1px);
}
.lp-cut-note { margin-top: 5px; font-size: 12px; color: var(--lp-cream-60); }
.lp-cut-qr {
  flex: none; display: grid; place-items: center; width: 58px; height: 58px;
  border-radius: 6px; background: var(--lp-cream); color: var(--lp-ink);
}
.lp-cut-qr svg { width: 46px; height: 46px; }
.lp-cut-join {
  margin-top: 10px; display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 6px; font-size: 12px;
  border: 1px solid var(--lp-gold-30); background: var(--lp-ink-50);
}
.lp-cut-join-word { color: var(--lp-gold); flex: none; }
.lp-cut-join-url {
  color: var(--lp-cream-75); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lp-cut-join svg { margin-left: auto; flex: none; color: var(--lp-gold); }
.lp-cut-joining {
  position: relative; margin-top: -14px; margin-left: auto; width: 100%;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; border-radius: 8px; padding: 14px 16px;
  background: var(--lp-cream); color: var(--lp-ink); box-shadow: 0 20px 40px rgb(0 0 0 / 0.15);
}
.lp-cut-joining-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--lp-ink-50);
}
.lp-cut-joining-title {
  margin-top: 5px; font-family: var(--display); font-weight: var(--headline-weight, 700); text-transform: none;
  font-size: 18px; --lh: 1.2; line-height: round(calc(1em * var(--lh)), 1px);
}
.lp-faces { display: flex; }
.lp-face {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%;
  border: 2px solid var(--lp-cream); background: var(--lp-ink); color: var(--lp-gold);
  font-size: 11px; margin-left: -8px;
}
.lp-face:first-child { margin-left: 0; }
.lp-face--more { background: var(--lp-gold); color: var(--lp-ink); font-weight: 600; }

/* 03 retain */
.lp-retain { width: 100%; max-width: 420px; }
.lp-retain-head { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 24px; }
.lp-retain-label { font-size: 12px; text-transform: uppercase; color: var(--lp-cream-40); }
.lp-retain-count {
  font-family: var(--display); font-weight: var(--figure-weight, 800); font-size: 36px; margin-top: 8px;
  --lh: 1; line-height: round(calc(1em * var(--lh)), 1px); font-variant-numeric: tabular-nums lining-nums;
}
.lp-retain-growth { font-size: 14px; color: var(--lp-gold); }
.lp-channel {
  display: flex; align-items: center; gap: 16px; padding: 16px; border-radius: 6px;
  border: 1px solid var(--lp-cream-10); background: rgb(3 3 3 / 0.70); margin-bottom: 12px;
}
.lp-channel-mark {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  background: var(--lp-gold-15); color: var(--lp-gold); flex: none;
}
.lp-channel-info { flex: 1; min-width: 0; }
.lp-channel-name { font-size: 14px; font-weight: 600; }
.lp-channel-desc { font-size: 12px; color: var(--lp-cream-40); }
.lp-channel-count { font-size: 12px; color: var(--lp-gold); }

/* 04 replay */
.lp-replay { width: 100%; max-width: 520px; }
.lp-replay-card {
  border-radius: 8px; background: var(--lp-ink); color: var(--lp-cream);
  padding: 20px; box-shadow: 0 20px 40px rgb(0 0 0 / 0.25);
}
.lp-replay-head { display: flex; align-items: center; justify-content: space-between; }
.lp-replay-badge {
  padding: 2px 8px; border-radius: 3px; background: var(--lp-gold); color: var(--lp-ink);
  font-size: 11px; font-weight: 600;
}
.lp-replay-dur { font-size: 12px; color: var(--lp-cream-40); }
.lp-wave { display: flex; align-items: flex-end; gap: 4px; height: 96px; margin-top: 48px; }
.lp-wave span {
  flex: 1; border-radius: 1px; background: var(--lp-cream-20);
  transform-origin: bottom center; animation: lp-bar 1.15s ease-in-out infinite alternate;
}
.lp-wave span:nth-child(2n) { animation-duration: 1.35s; }
.lp-wave span:nth-child(3n) { animation-delay: 0.18s; }
@keyframes lp-bar { from { transform: scaleY(0.42); } to { transform: scaleY(1); } }
.lp-wave span.lp-wave--on { background: var(--lp-gold); }
.lp-replay-labels {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 20px;
  text-align: center; font-size: 12px; color: var(--lp-cream-50);
}
.lp-replay-labels span { animation: lp-label 3.6s ease-in-out infinite; }
.lp-replay-labels span:nth-child(2) { animation-delay: 1.2s; }
.lp-replay-labels span:nth-child(3) { animation-delay: 2.4s; }
@keyframes lp-label { 0%, 100% { opacity: 0.4; } 30% { opacity: 1; } }

/* 05 republish */
.lp-republish { position: relative; display: flex; align-items: flex-end; gap: 16px; min-height: 320px; }
.lp-clip {
  aspect-ratio: 9/14; width: 100px; border-radius: 6px; padding: 12px;
  background: var(--lp-ink); border: 1px solid var(--lp-cream-15); text-align: center;
}
.lp-clip:nth-child(1) { transform: rotate(-6deg); }
.lp-clip:nth-child(2) {
  width: 116px; background: var(--lp-gold); color: var(--lp-ink);
  box-shadow: 0 20px 50px rgb(0 0 0 / 0.4); z-index: 2;
}
.lp-clip:nth-child(3) { transform: rotate(6deg); }
.lp-clip-time { font-size: 10px; color: var(--lp-gold); }
.lp-clip:nth-child(2) .lp-clip-time { color: var(--lp-ink-75); }
.lp-clip-body { margin-top: 48px; }
/* `display: block` is added to the mock's rule: `margin: 0 auto` on an INLINE
   svg centres nothing, and the mock plainly means the glyph to sit in the
   middle of its 9:14 card. */
.lp-clip-body svg { margin: 0 auto; display: block; color: var(--lp-gold); }
.lp-clip .lucide-scissors { transform-origin: 28% 50%; animation: lp-cut 1.7s ease-in-out infinite; }
@keyframes lp-cut { 0%, 100% { transform: rotate(0deg); } 35% { transform: rotate(-22deg); } 55% { transform: rotate(14deg); } }
.lp-clip:nth-child(2) .lp-clip-body svg { color: var(--lp-ink); }
.lp-clip-title { margin-top: 12px; font-size: 12px; }
.lp-clip:nth-child(2) .lp-clip-title { font-weight: 600; }
/* THE ROW IS ABSOLUTE, SO IT CONTRIBUTES NO HEIGHT — and that is what had it
   sitting ON the reels rather than under them. Its band runs from
   `visualH - 60` (20px up, 40px tall) while the visual's own content box ends at
   `visualH - 48`, so the overlap was a structural 12px at every width where the
   visual's height is its CONTENT's: MEASURED −12px at 390, 640, 660 and 768
   before this round, and clear only at ≥1024 where the grid row is what makes
   the card 480px tall. Growing `.lp-republish`'s min-height cannot fix it (the
   row is anchored to the same bottom, so both move together) — the fix is to
   reserve the band in the visual's own padding, which `:has()` scopes to the one
   card that draws it. 88 = the band's 60 + 28 of air. The desk gains 20px of
   that air and lands nearer the mock's own gap. */
.lp-card-visual:has(.lp-republish) { padding-bottom: 88px; }
.lp-monetize-shot { width: min(100%, 520px); height: auto; border-radius: 16px; box-shadow: 0 18px 40px rgb(0 0 0 / 0.16); }
.lp-republish-dests {
  position: absolute; left: 20px; right: 20px; bottom: 20px;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px;
}

/* ── pricing ───────────────────────────────────────────────────────────────── */
.lp-pricing { border-top: 1px solid var(--lp-cream-10); }
.lp-plans { margin-top: 64px; display: grid; gap: 28px; }
.lp-plan {
  position: relative; display: flex; flex-direction: column; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--lp-cream-10); background: var(--lp-panel); padding: 40px;
}
.lp-plan--featured { background: var(--lp-gold); color: var(--lp-ink); border-color: var(--lp-gold); }
.lp-plan-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.lp-plan-name {
  font-family: var(--display); font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--lp-gold);
}
.lp-plan--featured .lp-plan-name { color: var(--lp-ink-55); }
.lp-plan-badge {
  padding: 4px 12px; border-radius: 999px; background: var(--lp-ink); color: var(--lp-gold);
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em;
  white-space: nowrap;
}
.lp-plan-price {
  margin-top: 32px; font-family: var(--display); font-weight: var(--figure-weight, 800); font-size: 48px;
  --lh: 1; line-height: round(calc(1em * var(--lh)), 1px); font-variant-numeric: tabular-nums lining-nums;
}
.lp-plan-per { font-family: var(--sans); font-size: 16px; font-weight: 400; color: var(--lp-cream-45); }
.lp-plan--featured .lp-plan-per { color: var(--lp-ink-50); }
/* The trial line under the price (FHL launch): a quiet fact in the sans, on
   both fills. */
.lp-plan-trial { margin-top: 10px; font-family: var(--sans); font-size: 14px; color: var(--lp-cream-60); }
.lp-plan--featured .lp-plan-trial { color: var(--lp-ink-60); }
.lp-plan-features { margin: 40px 0 32px; padding: 0; list-style: none; }
.lp-plan-feature { display: flex; gap: 12px; margin-bottom: 16px; font-size: 14px; color: var(--lp-cream-70); }
.lp-plan--featured .lp-plan-feature { color: var(--lp-ink-75); }
.lp-plan-feature > svg { flex-shrink: 0; margin-top: 3px; width: 16px; height: 16px; color: var(--lp-gold); }
.lp-plan--featured .lp-plan-feature > svg { color: var(--lp-ink); }
.lp-plan-dests { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; color: var(--lp-cream-60); }
.lp-plan--featured .lp-plan-dests { color: var(--lp-ink-60); }
.lp-plan-dests svg { width: 18px; height: 18px; }
.lp-plan-dests span { font-family: var(--sans); font-size: 14px; font-weight: 500; }
.lp-plan-cta {
  display: inline-flex; justify-content: center; width: 100%; margin-top: auto;
  padding: 14px 24px; border-radius: 8px; background: var(--lp-gold); color: var(--lp-ink);
  font-size: 14px; font-weight: 600; transition: background 0.2s;
}
.lp-plan-cta:hover { background: var(--lp-cream); }
.lp-plan--featured .lp-plan-cta { background: var(--lp-ink); color: var(--lp-gold); }
.lp-plan--featured .lp-plan-cta:hover { background: var(--lp-panel); }

/* ── creators ──────────────────────────────────────────────────────────────── */
/* THE DECK SITS UNDER THE HEADING (Maaz 2026-09-17). `space-between` put the
   sentence in the RIGHT half of the row, baseline-level with the display
   heading (measured at 1400: the h2 at x=80 and the deck at x=720, both bottoms
   on 5254) — two columns of unrelated blocks rather than a heading and its own
   deck. Every other section on this page stacks label / title / sub as three
   siblings and pricing's is the reference, so one column is what makes the
   page's own rhythm true here too. Below 1024 `flex-wrap` was already stacking
   them, which is why this only ever read wrong at the desk.
   NO `gap`: `.lp-sub` already carries the 20px, and two numbers holding one
   distance is how the next edit moves one and not the other. */
.lp-creators-head { display: flex; flex-direction: column; align-items: flex-start; }
.lp-creators {
  margin-top: 48px; display: grid;
  border-left: 1px solid var(--lp-cream-10); border-top: 1px solid var(--lp-cream-10);
}
.lp-creator {
  min-height: 224px; padding: 28px;
  border-right: 1px solid var(--lp-cream-10); border-bottom: 1px solid var(--lp-cream-10);
  transition: background 0.2s;
}
.lp-creator:hover { background: var(--lp-panel); }
.lp-creator-mark { color: var(--lp-gold); display: block; }
.lp-creator h3 { margin-top: 40px; font-family: var(--sans); font-size: 20px; font-weight: 600; text-transform: none; }
.lp-creator p { margin-top: 8px; max-width: 280px; font-size: 14px; color: var(--lp-cream-50); --lh: 1.6; line-height: round(calc(1em * var(--lh)), 1px); }

/* ── the closing claim ─────────────────────────────────────────────────────── */
.lp-claim-section { border-top: 1px solid var(--lp-cream-10); text-align: center; }
.lp-claim-section .lp-title { font-size: 48px; }

/* ── footer ────────────────────────────────────────────────────────────────── */
.lp-foot { border-top: 1px solid var(--lp-cream-10); padding: 40px 0 calc(48px + env(safe-area-inset-bottom)); }
.lp-foot-inner {
  display: flex; flex-direction: column; align-items: center; justify-content: space-between;
  gap: 16px; font-size: 14px; color: var(--lp-cream-50);
}
.lp-foot-brand {
  font-family: var(--display); font-size: 12px; font-weight: 700;
  text-transform: uppercase; color: var(--lp-gold); letter-spacing: 0.05em;
}
.lp-foot-top { color: var(--lp-cream-50); transition: color 0.2s; }
.lp-foot-top:hover { color: var(--lp-gold); }

/* ── responsive (the mock's own two breakpoints) ───────────────────────────── */

/* THE PHONE HERO SPANS THE CLAIM ROW (Maaz 2026-09-21, item 1 of the mobile
   claim batch — his corrected phone shot). The two headline lines were drawn
   at the base 28px whatever the phone's width, so under a full-bleed Claim it
   pill they read as a narrow caption over a wide control: MEASURED at 390,
   "Go LIVE everywhere." 264.5px and "Bring them Backstage." 274.8px against a
   350px row — 76% and 78% of it.

   THE SIZE IS A SHARE OF THE ROW'S OWN BOX, WHICH IS WHY IT IS A CONTAINER
   QUERY AND NOT `vw`. `.lp-hero-content` is `padding: 80px 20px`, so its
   CONTENT box is exactly what `.lp-claim-row` fills — 1cqi is 1% of the thing
   the headline is being matched to, and the coefficient survives a padding
   change where a `calc(Nvw - Mpx)` would quietly stop agreeing with the row.

   THE COEFFICIENT IS MEASURED, AND IT IS THE WIDER LINE'S. Line 2 is
   9.8143 em-widths of this face and line 1 is 9.0179 em plus 12 fixed pixels
   (the badge's own 6px dot and 6px gap, which do not scale), so ONE size
   cannot put both lines on the same width — two different strings. The wider
   one is set to 97% of the row (9.88cqi ≈ 0.97 × 100 / 9.8143) and the other
   lands where its own letters land: MEASURED at 390, 339.4px and 323.8px of
   350 — 97% and 93%. The 3% is the wrap margin: this headline is a `<br>` and
   two spans with nothing stopping either line from breaking, and a fallback
   face during a font swap measures wider than Playfair.

   BOTH ENDS ARE PINNED AND BOTH ARE CONTINUOUS. The floor is today's 28px,
   which binds below ~323px of viewport — where the line already fills 98% of
   the row, so the smallest phones are unchanged. The ceiling is 48px, which is
   what `min-width: 640px` sets one rule down, so the boundary has no jump in
   it. Desktop is untouched by construction: every rule here is inside a
   `max-width` query. */
@media (max-width: 639px) {
  .lp-hero { align-items: center; }
  body.lp header.topbar { background: rgb(0 0 0 / 0.35); }
  .lp-hero-content { container-type: inline-size; padding: 0 20px 80px; }
  .lp-tagline-sep { display: none; }
  .lp-icons { gap: 14px; padding: 10px 14px; }
  .lp-claim-go { align-self: center; width: 50%; min-height: 52px; }
  .lp-section { padding: 56px 0; }
  .lp-card-grid { min-height: 0; }
  .lp-card-grid > * { min-width: 0; }
  .lp-card-text { padding: 28px 22px; }
  .lp-card-text { position: relative; }
  .lp-card-mark { position: absolute; top: 24px; right: 22px; margin: 0; }
  .lp-card-text h3 { margin-top: 16px; }
  .lp-card-visual { min-height: 0; padding: 28px 22px; }
  .lp-card-visual:has(.lp-bcast) { min-height: 380px; align-items: flex-start; padding-top: 110px; }
  .lp-dest-label { display: none; }
  .lp-card-visual:has(.lp-republish) { padding-bottom: 80px; }
  .lp-republish { min-height: 0; gap: 12px; }
  .lp-clip { width: 84px; }
  .lp-clip:nth-child(2) { width: 96px; }
  .lp-plans { margin-top: 32px; gap: 16px; }
  .lp-plan { padding: 28px 22px; }
  .lp-plan-features { margin: 24px 0 20px; }
  .lp-plan-feature { margin-bottom: 10px; }
  .lp-hero h1 { font-size: clamp(40px, 14.5cqi, 56px); font-weight: 500; --lh: 1.1; }
  .lp-hero h1 br { display: none; }
  .lp-h1-line { display: block; }
  .lp-hero .lp-gold { margin-top: 0.3em; }
}

@media (min-width: 700px) and (max-width: 1023px) {
  .lp-plans--two, .lp-creators { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 640px) {
  .lp-hero h1 { font-size: 48px; }
  .lp-icons { margin-top: 44px; }
  .lp-tagline { font-size: 20px; }
  .lp-title { font-size: 48px; }
  .lp-card-text h3 { font-size: 36px; }
  .lp-claim-row { flex-direction: row; }
  .lp-claim-host, .lp-claim-field input { font-size: 18px; }
  .lp-claim-go { font-size: 18px; }
  .lp-icon svg { width: 28px; height: 28px; }
  .lp-plan-price { font-size: 56px; }

  /* 02's cut card, at the width it was drawn for. The base above is the phone:
     the card sits inside a 16:9 stage, so its own type and the code have to
     come down with it or there is nothing left of the headline. */
  .lp-cut-stage { padding: 14px; }
  .lp-cut-card { padding: 14px; }
  .lp-cut-word { font-size: 30px; }
  .lp-cut-qr { width: 72px; height: 72px; }
  .lp-cut-qr svg { width: 56px; height: 56px; }
  .lp-cut-joining { width: 74%; flex-wrap: nowrap; }
  .lp-cut-joining-title { font-size: 20px; }

  /* 05's REELS, AT THE WIDTH THEY WERE DRAWN FOR (Maaz 2026-09-17). They were
     100/116px — a third of the gold panel's own height — so the card read as
     empty space with three stamps in it. 1.5x is 150/174, and the row is then
     150 + 16 + 174 + 16 + 150 = 506px of content, which this breakpoint is the
     first to have room for. At EXACTLY 640 it is 2px over (the card's content
     box is 504), and those 2px are absorbed by the visual's own 48px of
     padding rather than clipped off a card: measured at 640, every clip's box
     is 32px INSIDE the card and the row's own width is a full 506.
     THE BASE ABOVE IS THE PHONE AND IS DELIBERATELY UNTOUCHED — the `.lp-cut-*`
     reasoning one block up. Down there the row does NOT shrink to the card:
     Chrome takes a flex item's specified width as its min-content contribution,
     so the grid track is floored at 348 + 96 = 444 inside a 350px card and
     clip 3 is already half clipped by `.lp-card`'s own `overflow: hidden`
     (measured: 55.9px outside the card at 390). 1.5x there would put clip 3
     off the card altogether, so the phone keeps the reels it has.
     The inner type moves WITH the card or the bigger box is emptier than the
     small one: the glyphs keep their existing 28/32 proportion to the two card
     widths (1.5x → 42/48) and the two stamps take 1.2x. Padding stays 12px on
     purpose — holding it while the card grows is what gives the title the room
     to stop wrapping. */
  .lp-clip { width: 150px; border-radius: 10px; }
  .lp-clip:nth-child(2) { width: 174px; }
  .lp-clip-time { font-size: 12px; }
  .lp-clip-body { margin-top: 72px; }
  .lp-clip-body svg { width: 42px; height: 42px; }
  .lp-clip:nth-child(2) .lp-clip-body svg { width: 48px; height: 48px; }
  .lp-clip-title { margin-top: 18px; font-size: 15px; }
}

@media (min-width: 1024px) {
  .lp-hero h1 { font-size: 72px; --lh: 1.1; }
  .lp-hero-content { padding-bottom: 160px; }
  .lp-icons { margin-top: 20px; padding: 0; background: none; border: 0; gap: 24px; }
  .lp-hero-bg { transform: scale(1.15); transform-origin: 50% 60%; }
  .lp-hero .lp-gold { white-space: nowrap; }
  .lp-card-grid { grid-template-columns: 0.8fr 1.2fr; }
  .lp-card-grid--reverse { grid-template-columns: 1.2fr 0.8fr; }
  .lp-card-visual { border-top: none; border-left: 1px solid var(--lp-cream-10); }
  .lp-card--gold .lp-card-visual,
  .lp-card--cream .lp-card-visual { border-top: none; border-left: 1px solid var(--lp-ink-15); }
  .lp-plans { grid-template-columns: repeat(3, 1fr); }
  /* TWO CARDS SINCE THE FHL LAUNCH (Free is hidden): two even tracks, centred
     inside the container rather than sprawled across three columns' width. */
  .lp-plans--two { grid-template-columns: repeat(2, 1fr); max-width: 860px; margin-left: auto; margin-right: auto; }
  .lp-creators { grid-template-columns: repeat(3, 1fr); }
  .lp-creators-head .lp-sub { max-width: none; }
  .lp-foot-inner { flex-direction: row; }
}

/* The mock's own reduced-motion block. The house kill for `.live-dot` lives
   next to its own declaration in application.css (the r9 lesson: an override
   above the rule it overrides is inert), so this one sits next to these. */
@media (prefers-reduced-motion: reduce) {
  .lp-rise { animation: none; opacity: 1; }
  .lp-pulse { animation: none; }
  .lp-bcast-ring, .lp-wave span, .lp-replay-labels span, .lp-clip .lucide-scissors { animation: none; }
  body.lp { scroll-behavior: auto; }
}
