:root{
  /* ── Neutrals ──
     Ink is Marv's own warm near-black from marvlabs.ai, not #000. That one
     swap is most of the reason the page stops reading as a default
     black-on-white template. 15.2:1 on white, 13.5:1 on beige. */
  --white:#ffffff;
  --ink:#2a2520;
  --black:#2a2520;
  /* Raised so all three clear WCAG AA for small text on white AND on beige.
     At the old 0.72/0.58/0.45 the lower two measured 3.8:1 and 2.6:1 on
     beige, which Lighthouse flagged in the footer and which was equally
     wrong everywhere else it was used. */
  --ink-70:rgba(42,37,32,0.80);
  --ink-55:rgba(42,37,32,0.72);
  --ink-40:rgba(42,37,32,0.66);
  --line:rgba(42,37,32,0.12);
  --line-soft:rgba(42,37,32,0.07);
  --line-strong:rgba(42,37,32,0.22);   /* active card, never near-black */

  /* ── Beige ──
     Marv's own paper, #f6f1e8, off the original site. White stays the
     default surface. Beige marks the sections that are context rather than
     product, so it reads as a deliberate pause and not as a wash. */
  --beige:#f6f1e8;
  --beige-2:#efe7d9;
  --placeholder:#f2ede3;   /* only ever visible behind a loading image */

  /* ── Paper on ink ──
     Ink inverted, for type set on the near-black. Currently only the hero
     copy over the footage. Beige rather than white, so it is lit by the
     same paper as the rest of the page instead of going cold. */
  --paper:#f6f1e8;
  --paper-70:rgba(246,241,232,0.78);
  --paper-55:rgba(246,241,232,0.66);

  /* ── Accents, one job each ──
     Teal is the fix: diagnostics, confirmations, data.
     Rust is the cost: the problem side, what a comeback burns.
     Both come from Marv's own swatch set and both clear AA on white and on
     beige (teal 5.1 / 4.5, rust 5.8 / 5.2). --accent is the live brand teal,
     decorative only, never text. */
  --accent:#0FA6B6;
  --accent-ink:#0B7A85;
  --rust:#A8463A;
  --rust-soft:rgba(168,70,58,0.09);

  /* On dark */
  --paper-on-dark:rgba(246,241,232,0.70);
  --line-on-dark:rgba(255,255,255,0.16);

  --sans:'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  --r:16px;
  --r-lg:24px;
  --r-pill:32px;
  --wrap:1496px;
  --gutter:clamp(20px, 3vw, 32px);
  --section:clamp(72px, 8vw, 128px);
  --ease:cubic-bezier(0.16, 1, 0.3, 1);
}

*{ box-sizing:border-box; }
html{ scroll-behavior:smooth; scroll-padding-top:80px; }
body{
  margin:0;
  background:var(--white);
  color:var(--ink);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.4;
  letter-spacing:-0.01em;
  font-optical-sizing:auto;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{ color:inherit; text-decoration:none; }
/* Form controls do not inherit the page font by default, which is how the
   Continue buttons on the booking page ended up rendering in Arial. */
button,input,select,textarea{ font-family:inherit; font-size:inherit; letter-spacing:inherit; }
img{ max-width:100%; display:block; }
figure,blockquote,ol,ul{ margin:0; padding:0; }
ul{ list-style:none; }
::selection{ background:var(--accent); color:#fff; }

/* ── Layout ─────────────────────────────────────────────────── */
.wrap{ width:100%; max-width:var(--wrap); margin:0 auto; padding:0 var(--gutter); }
.tint{ background:var(--beige); }
.tint .card{ border-color:transparent; }
section{ padding:var(--section) 0; }

/* ── Type ───────────────────────────────────────────────────── */
/* One font, one colour, one weight on any given line. The character comes
   from how the levels differ from each other, not from decorating inside
   one of them.
   The move worth naming: display is set LIGHT and very large at 400 while
   the smaller headings are 500, so size and weight run in opposite
   directions. The default, where everything gets bolder as it gets bigger,
   is most of what makes a type scale read as a template. Tracking and
   leading tighten as size grows, so each level has its own texture rather
   than one setting scaled up and down. */
h1,h2,h3,h4{ margin:0; }
/* The mobile minimum was 40px against 88px on desktop, which read as timid
   on a phone and also made the hero photo the largest element in the first
   screen. At 50px the headline owns the fold, which is both the better
   hero and the faster LCP. */
/* line-height 0.90 put the descender of "every" on line one directly onto
   the crossbar of the T in "SuperTechnician" on line two. Measured, the
   worst vertical gap between the two lines' ink was 0.3px: touching. This
   is the collision that kept getting reported, and it is between LINES,
   not between letters on one line, which is why tightening the pair
   kerning never fixed it. At 1.02 the same measurement is 6.7px.
   If you tighten this again, re-run that check rather than eyeballing it:
   colour each line differently, then take the smallest vertical distance
   between line one's lowest ink and line two's highest, per column. */
h1{ font-size:clamp(50px, 5.6vw, 88px); font-weight:400; line-height:1.02; letter-spacing:-0.058em;
     /* letter-spacing is applied after EVERY character, the word space
        included, so -0.058em pulled 5px out of each gap at 88px and
        "every technician" closed up until the y of every touched the t of
        technician. word-spacing puts back exactly what the tracking took,
        so the letters stay as tight as they were drawn and only the word
        gaps return to the font's own metric. */
     word-spacing:0.058em; }

/* The one pair the display tracking breaks. An r followed by a capital T
   is already tight (the T's crossbar overhangs left, the r's arm reaches
   right), and -0.058em on top of that puts the T's ink 5px INSIDE the r's
   at 88px: measured, they overlap rather than merely touch. Resetting the
   tracking on the r alone, which is what letter-spacing acts on, opens the
   pair to 4.3px against the 3.7 to 4.0 that normal pairs in this line
   measure, so it matches the setting instead of announcing itself.
   Only the h1 needs this. At the lede's -0.005em the same pair is fine. */
.kt{ letter-spacing:normal; }

/* The registered mark. Set at display size it read as a character in the
   sentence rather than as a legal mark, which is also why the full stop
   after it had nowhere to sit. Down to a third of the cap and lifted to
   the cap line, and the sentence ends on the mark. Its own tracking is
   reset: -0.058em on a lone glyph just pulls it into the n before it.
   Display only. In body copy, such as the calculator line, a full-size
   registered mark is already right; at 0.30em of 15px it would be 4.5px. */
.reg{
  font-size:0.30em; letter-spacing:0; word-spacing:0;
  vertical-align:1.30em; line-height:1;
}
/* The TM lockup, for display copy. Half size, then raised back to cap
   height: the glyph is already drawn high, so shrinking alone drops it. */
.tm{
  font-size:0.38em; letter-spacing:0; word-spacing:0;
  vertical-align:1.15em; line-height:1;
}
h2{ font-size:clamp(29px, 3.1vw, 43px); font-weight:500; line-height:1.00; letter-spacing:-0.038em; }
h3{ font-size:clamp(20px, 1.7vw, 25px); font-weight:500; line-height:1.18; letter-spacing:-0.015em; }
h4{ font-size:17px;                     font-weight:500; line-height:1.32; letter-spacing:-0.005em; }
p{ margin:0; }
.lede{ font-size:clamp(16px, 1.25vw, 18px); font-weight:400; line-height:1.6; letter-spacing:-0.005em; color:var(--ink-70); }
.small{ font-size:14px; font-weight:400; line-height:1.55; letter-spacing:0; color:var(--ink-70); }
/* No eyebrow labels anywhere. The few remaining small captions are plain
   sans, sentence case, and read as captions rather than as labels. */
.caption{ font-size:14px; line-height:1.5; color:var(--ink-40); }

/* Centred section intro, the Sana default */
.intro{ max-width:760px; margin:0 auto clamp(40px, 5vw, 72px); text-align:center; }
.intro h2{ margin-bottom:20px; }
.intro .lede{ max-width:60ch; margin:0 auto; }
.intro .btn{ margin-top:28px; }

/* ── Buttons ────────────────────────────────────────────────── */
.btn{
  display:inline-flex; align-items:center; gap:8px;
  padding:11px 18px 11px 20px; border-radius:var(--r-pill);
  font-size:15px; font-weight:450; letter-spacing:-0.01em;
  border:1px solid transparent; cursor:pointer; white-space:nowrap;
  /* A <button> with no fill modifier would otherwise take the UA's grey
     buttonface. Every filled variant sets its own background below. */
  background:transparent; color:inherit;
  transition:background .25s var(--ease), color .25s var(--ease),
             border-color .25s var(--ease), opacity .25s var(--ease);
}
.btn .arrow{ transition:transform .25s var(--ease); }
.btn:hover .arrow{ transform:translateX(3px); }
.btn-black{ background:var(--black); color:var(--white); }
.btn-black:hover{ background:#2a2a2a; }
.btn-white{ background:var(--white); color:var(--black); }
.btn-white:hover{ background:var(--beige); }
.btn-line{ border-color:var(--line); color:var(--ink); }
.btn-line:hover{ border-color:var(--ink-40); background:var(--beige); }
.btn-line-on-dark{ border-color:var(--line-on-dark); color:#fff; }
.btn-line-on-dark:hover{ background:rgba(255,255,255,0.1); }
.btn-sm{ padding:8px 14px; font-size:14px; }
.btn[disabled]{ opacity:.38; cursor:not-allowed; pointer-events:none; }
.btn[disabled]:hover{ transform:none; }
.btn-lg{ padding:14px 24px; font-size:16px; }

/* ── Nav ────────────────────────────────────────────────────── */
.top{
  position:fixed; inset:0 0 auto 0; z-index:80;
  transition:background .3s var(--ease), box-shadow .3s var(--ease);
}
.top.stuck{ background:rgba(255,255,255,0.86); backdrop-filter:blur(16px) saturate(1.4); box-shadow:0 1px 0 var(--line-soft); }
.top-inner{ display:flex; align-items:center; gap:32px; height:64px; }
.brand{ display:flex; align-items:center; gap:13px; font-size:14px; font-weight:450; letter-spacing:0.18em; white-space:nowrap; }
.brand svg{ width:26px; height:26px; flex:none; }
.top nav{ display:flex; gap:26px; }
.top nav a{
  position:relative; font-size:15px; font-weight:450; color:var(--ink);
  padding-bottom:2px;
}
.top nav a::after{
  content:''; position:absolute; left:0; right:100%; bottom:0; height:1px;
  background:var(--ink); transition:right .3s var(--ease);
}
.top nav a:hover::after{ right:0; }
.top-actions{ margin-left:auto; }
@media (max-width:820px){ .top nav{ display:none; } }

/* ── Hero ───────────────────────────────────────────────────────
   The copy is ON the footage. Everything below exists to keep it legible
   over a moving image, which is a harder problem than it looks: the type
   cannot be checked once against a still, because the still it has to
   survive is whichever frame is worst.
   ─────────────────────────────────────────────────────────── */
.hero{ padding:clamp(84px, 9vw, 116px) 0 0; }

.hero-stage{
  position:relative; overflow:hidden;
  border-radius:var(--r-lg);
  /* Dark, not --placeholder. The placeholder beige would flash light
     behind paper-coloured type in the moment before the poster decodes. */
  background:#141210;
  display:grid; place-items:center;
  min-height:clamp(520px, 78vh, 860px);
}
.hero-stage picture{ position:absolute; inset:0; display:block; }
.hero-stage img{ width:100%; height:100%; object-fit:cover; }

/* The scrim. Strength is measured rather than chosen: the footage is a
   dark workshop, but a headlamp shines straight into the lens for much of
   the clip, so the brightest 1% of the area behind the type sits near
   white while the frame's mean luminance is 0.03 to 0.22. Sampled across
   the whole loop, this is what holds the paper type above AA on the worst
   frame. It is a touch heavier at the top, where the lamp lives and where
   the headline sits, and lets the footage breathe at the foot.
   If the footage is ever swapped, re-run the measurement. */
.hero-stage::after{
  content:''; position:absolute; inset:0; z-index:2;
  background:linear-gradient(180deg,
    rgba(18,16,14,0.68) 0%,
    rgba(18,16,14,0.64) 52%,
    rgba(18,16,14,0.52) 100%);
}

.hero-copy{
  position:relative; z-index:3; text-align:center;
  padding:clamp(56px, 7vw, 96px) clamp(20px, 4vw, 64px);
  /* width:100% is not redundant. A grid item under place-items:center is
     sized to its MAX-CONTENT width, so without it the copy grows wider
     than the stage on a phone and the headline is clipped by the stage's
     own overflow:hidden. Measured at 320px: a 331px copy inside a 280px
     stage. width:100% makes it fill the track, and max-width still caps
     and centres it on a wide screen. */
  width:100%; max-width:1180px;
}
.hero-copy h1{ color:var(--paper); margin:0 auto 26px; }
.hero-copy .lede{
  max-width:54ch; margin:0 auto;
  font-size:clamp(16px,1.35vw,19px);
  color:rgba(246,241,232,0.96);
}
.hero-cta{ display:flex; justify-content:center; flex-wrap:wrap; gap:10px; margin-top:34px; }
/* The secondary button is the only ghost button that sits on the footage.
   --line-on-dark is a DIVIDER value: at 16% white it holds up against the
   footer card, and disappears on the frames where the headlamp is in shot.
   Same button, given a border that survives the brightest frame of the loop.
   The label is already #fff over the scrim, which the scrim note covers. */
.hero-cta .btn-line-on-dark{ border-color:rgba(255,255,255,0.42); }
.hero-note{ margin-top:20px; font-size:13px; color:rgba(246,241,232,0.78); }

@media (max-width:640px){
  .hero-stage{ min-height:clamp(460px, 82vh, 720px); }
}
/* "SuperTechnician" is one unbreakable 15-character word, and it is what
   sets the minimum width of this headline. At the 50px floor it measures
   310px, which does not fit a 320px phone at any padding, so below 560px
   the hero headline scales with the viewport instead of holding the floor.
   It stays at 48px on a 390px phone, so this is a rounding-down on the
   narrowest devices rather than a retreat from "the headline owns the
   fold". The rest of the page keeps the global h1 floor. */
@media (max-width:560px){
  .hero-copy{ padding-left:14px; padding-right:14px; }
  .hero-copy h1{ font-size:clamp(34px, 11.5vw, 50px); }
}

/* ── Logo strip ─────────────────────────────────────────────── */
.strip{ padding:clamp(56px, 7vw, 88px) 0 0; margin-top:clamp(40px, 5vw, 72px); }
.strip-label{ text-align:center; margin-bottom:28px; font-size:14px; color:var(--ink-40); }
.logos{ display:grid; grid-template-columns:repeat(5,1fr); gap:clamp(16px,3vw,48px); align-items:center; justify-items:center; }
.logo{ display:grid; place-items:center; width:100%; color:var(--ink-40); transition:color .25s var(--ease); }
.logo:hover{ color:var(--ink); }
.logo svg{ height:clamp(20px,2vw,28px); width:auto; max-width:100%; display:block; overflow:visible; }
@media (max-width:860px){ .logos{ grid-template-columns:repeat(3,1fr); row-gap:32px; } }
@media (max-width:520px){ .logos{ grid-template-columns:repeat(2,1fr); row-gap:28px; } }

/* ── Media cards ────────────────────────────────────────────── */
.media{
  position:relative; border-radius:var(--r-lg); overflow:hidden;
  background:var(--placeholder);
}
.media img{ width:100%; height:100%; object-fit:cover; }
.media-16x7{ aspect-ratio:16/7; }
.media-16x9{ aspect-ratio:16/9; }
.media-4x3{ aspect-ratio:4/3; }
.media-1x1{ aspect-ratio:1/1; }
.media-scrim::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(6,6,6,0.92) 0%, rgba(6,6,6,0.80) 34%, rgba(6,6,6,0.22) 62%, rgba(6,6,6,0) 84%);
}
.media-scrim-b::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(6,6,6,0) 30%, rgba(6,6,6,0.55) 72%, rgba(6,6,6,0.88) 100%);
}
.media-body{
  position:absolute; inset:auto 0 0 0; z-index:2; color:#fff;
  padding:clamp(24px, 3.4vw, 56px);
}
.media-tag{
  position:absolute; top:20px; left:20px; z-index:2;
  background:rgba(255,255,255,0.14); backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,0.2); color:#fff;
  padding:6px 12px; border-radius:var(--r-pill);
  font-size:13px;
}

/* ── Generic cards ──────────────────────────────────────────── */
.cards-2{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:clamp(12px,1.4vw,20px); }

/* Three equal tiles, no lead card. The problem grid pairs one to one with
   the stat grid below it, and a lead card in either one would break the
   correspondence the ordinals are there to make. */
.cards-3{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(12px,1.4vw,20px); }
.card{
  background:var(--white); border-radius:var(--r);
  padding:clamp(24px, 2.6vw, 36px);
  border:1px solid var(--line-soft);
}
.card h3{ margin-bottom:10px; font-size:clamp(19px,1.6vw,22px); }
.card p{ color:var(--ink-70); font-size:15px; line-height:1.5; }
.card-ic{ color:var(--accent-ink); margin-bottom:16px; display:block; }
.card-ic svg{ width:20px; height:20px; }
.card h4{ margin-bottom:8px; }
@media (max-width:860px){ .cards-2,.cards-3{ grid-template-columns:1fr; } }

/* ── Feature rows (product modules) ─────────────────────────── */
.feature{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(20px, 3vw, 56px); align-items:center;
  margin-top:clamp(20px,2.4vw,28px);
}
.feature.flip .feature-copy{ order:2; }
.feature-copy{ padding:clamp(0px, 2vw, 32px) 0; }
.feature-copy h3{ margin-bottom:14px; max-width:18ch; }
.feature-copy p{ color:var(--ink-70); max-width:46ch; }
.feature-copy .small{ margin-top:14px; color:var(--ink-55); }
@media (max-width:860px){
  .feature{ grid-template-columns:1fr; }
  .feature.flip .feature-copy{ order:0; }
}

/* ── Product screen ─────────────────────────────────────────────
   A browser frame on a soft backdrop, the way Stripe show checkout.
   The one place shadows are allowed: this is standing in for a
   screenshot, and a screenshot has an edge.
   ─────────────────────────────────────────────────────────── */
.shot{
  border-radius:var(--r-lg);
  padding:clamp(16px, 4vw, 64px) clamp(12px, 3.5vw, 56px) 0;
  background:
    radial-gradient(120% 90% at 10% 0%, #fffdf9 0%, rgba(255,253,249,0) 58%),
    radial-gradient(100% 80% at 94% 10%, #ece2d0 0%, rgba(236,226,208,0) 64%),
    var(--beige);
  overflow:hidden;
}
.frame{
  border-radius:12px 12px 0 0; overflow:hidden;
  background:#fff; border:1px solid rgba(42,37,32,0.14); border-bottom:0;
  box-shadow:0 1px 2px rgba(42,37,32,.05), 0 20px 44px -18px rgba(42,37,32,.24);
  max-width:1080px; margin:0 auto;
}

/* Browser chrome */
.chrome{
  display:flex; align-items:center; gap:8px;
  padding:11px 14px; background:#faf7f1; border-bottom:1px solid rgba(42,37,32,0.09);
}
.chrome .tl{ width:10px; height:10px; border-radius:99px; background:rgba(42,37,32,0.16); flex:none; }
.chrome .url{
  margin:0 auto; display:flex; align-items:center; gap:7px;
  background:#fff; border:1px solid rgba(42,37,32,0.10); border-radius:99px;
  padding:5px 16px; font-size:12px; color:var(--ink-55);
  max-width:340px; width:100%; justify-content:center;
}
.chrome .url svg{ width:11px; height:11px; color:var(--ink-40); flex:none; }

/* The screen itself. Not a chat: a repair order worksheet, which is the
   artifact a shop actually passes around. Type and whitespace carry it,
   so there are no nested cards, no pills, no confidence bars and no
   composer, which is what made the first pass read as a template. */
.app{ min-height:420px; }
.app-nav{
  display:flex; align-items:center; gap:26px;
  padding:14px clamp(20px,3vw,44px); border-bottom:1px solid rgba(42,37,32,0.08);
  font-size:13px; color:var(--ink-40);
}
.app-brand{ display:flex; align-items:center; gap:8px; color:var(--ink); font-weight:500; }
.app-brand svg{ width:14px; height:14px; }
.app-nav nav{ display:flex; gap:22px; }
.app-nav nav .on{ color:var(--ink); box-shadow:inset 0 -1px 0 var(--ink); padding-bottom:3px; }
.app-bay{ margin-left:auto; }

.doc{ padding:clamp(26px,3.4vw,48px) clamp(20px,3vw,44px) clamp(30px,4vw,56px); }
.doc-head{ position:relative; padding-bottom:clamp(22px,2.6vw,34px); }
.doc-ro{ font-size:13px; color:var(--ink-40); margin-bottom:10px; }
.doc-veh{ font-size:clamp(19px,1.9vw,25px); font-weight:500; letter-spacing:-0.02em; margin-bottom:8px; }
.doc-meta{ font-size:13px; color:var(--ink-40); }
.doc-code{
  position:absolute; top:0; right:0;
  font-size:14px; letter-spacing:0.02em; color:var(--rust);
}

.doc-row{
  display:grid; grid-template-columns:132px minmax(0,1fr);
  gap:clamp(16px,2.4vw,36px);
  padding:clamp(22px,2.6vw,32px) 0;
  border-top:1px solid rgba(42,37,32,0.08);
}
.doc-lbl{ font-size:13px; color:var(--ink-40); }
.doc-body p{ font-size:14.5px; line-height:1.6; color:var(--ink); max-width:62ch; }
.doc-note{ color:var(--ink-55) !important; }

/* Hanging numerals, not badges. */
.dx{ list-style:none; counter-reset:dx; margin-top:20px; display:grid; gap:20px; }
.dx li{ counter-increment:dx; padding-left:38px; position:relative; }
.dx li::before{
  content:counter(dx,decimal-leading-zero);
  position:absolute; left:0; top:1px;
  font-size:13px; color:var(--ink-40); font-variant-numeric:tabular-nums;
}
.dx .dx-t{ font-size:14.5px; font-weight:500; letter-spacing:-0.01em; margin:0 0 5px; }
.dx li p{ font-size:14px; line-height:1.55; color:var(--ink-55); max-width:58ch; }

@media (max-width:720px){
  .app-nav nav{ display:none; }
  .doc-row{ grid-template-columns:1fr; gap:10px; padding:22px 0; }
  .doc-code{ position:static; margin-top:12px; }
}
@media (max-width:860px){
  .how{ grid-template-columns:1fr; }
  .how-lead{ grid-template-columns:1fr; }
  .how-lead .how-copy{ order:0; }
}

/* ── Dark panel (the brain) ─────────────────────────────────── */
.dark{
  background:#1c1815; color:var(--beige); border-radius:var(--r-lg);
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(20px,3vw,48px); align-items:center;
  padding:clamp(28px,3.4vw,56px);
}
.dark h3{ margin-bottom:14px; max-width:16ch; }
.dark p{ color:var(--paper-on-dark); max-width:44ch; }
.dark-figure{ position:relative; aspect-ratio:16/11; min-height:240px; }
.dark-figure canvas{ position:absolute; inset:0; width:100%; height:100%; }
@media (max-width:860px){
  .dark{ grid-template-columns:1fr; }
  .dark-figure{ order:-1; aspect-ratio:6/5; min-height:0; max-height:280px; }
}

/* ── Ordinals ───────────────────────────────────────────────────
   The problem cards and the stat cards carry the same 01/02/03, because
   the two grids are one argument: the number answers the card above it.
   Quiet on purpose. It only has to be findable, not read first.
   ─────────────────────────────────────────────────────────── */
.ord{
  font-size:12.5px; font-weight:500; letter-spacing:0.08em;
  color:var(--ink-40); margin-bottom:14px;
  font-variant-numeric:tabular-nums;
}

/* ── The answers ────────────────────────────────────────────────
   Three rows, stacked, one open at a time. Each names the problem it
   answers rather than relying on the reader to carry 01/02/03 down from
   the grid above.

   Hover opens a row, and so do focus and click: hover is nothing on a
   touch screen and nothing on a keyboard, so the head is a real <button>
   with aria-expanded rather than a div with a mouse listener. The row is
   still readable with no JS at all, because .ans-body is only collapsed by
   a rule that main.js turns on.

   The body animates on grid-template-rows rather than max-height. A guessed
   max-height either clips a long answer or leaves the easing wrong for a
   short one; 0fr to 1fr is the real height, whatever it is.
   ─────────────────────────────────────────────────────────── */
.ans{
  display:grid; gap:clamp(8px,1vw,12px);
  /* One set of measurements for the head and the body, so the answer text
     lines up with the label above it. */
  --ans-pad:clamp(22px, 2.6vw, 36px);
  --ans-gap:clamp(14px, 2.4vw, 32px);
}
.ans-row{
  background:var(--white); border:1px solid var(--line-soft);
  border-radius:var(--r); overflow:hidden;
  transition:border-color .3s var(--ease), background .3s var(--ease);
}
.ans-row.is-open{ border-color:var(--line); }
.ans-head{
  width:100%; background:none; border:0; cursor:pointer; text-align:left;
  display:grid; grid-template-columns:1fr auto; align-items:center;
  gap:var(--ans-gap);
  padding:clamp(20px,2.4vw,30px) var(--ans-pad);
  color:var(--ink);
}
.ans-q{ font-size:clamp(17px,1.5vw,21px); font-weight:500; letter-spacing:-0.015em; }
.ans-head .v{
  font-size:clamp(30px,3.4vw,48px); font-weight:400; line-height:1;
  letter-spacing:-0.04em; font-variant-numeric:tabular-nums;
  justify-self:end; white-space:nowrap;
}
/* Collapsed only once main.js says so, so no-JS leaves every answer open
   and readable rather than hiding two thirds of the section. */
.js-ans .ans-body{
  display:grid; grid-template-rows:0fr;
  transition:grid-template-rows .42s var(--ease);
}
.js-ans .ans-row.is-open .ans-body{ grid-template-rows:1fr; }
/* THE GRID ITEM MUST CARRY NO PADDING AND min-height:0. Both, or the row
   will not close. A grid item defaults to min-height:auto, which floors the
   0fr track at its own min-content height, and padding on the item counts
   toward that floor even under overflow:hidden. Measured with the padding
   on the <p>: the track resolved to 30px, exactly its bottom padding, and
   every closed answer kept a visible sliver. Hence .ans-inner, whose only
   job is to be a bare clipping box with the padded text inside it. */
.ans-body > .ans-inner{ overflow:hidden; min-height:0; }
.ans-body p{
  color:var(--ink-70); font-size:15px; line-height:1.55;
  max-width:62ch;
  padding:0 var(--ans-pad) clamp(22px,2.6vw,30px);
}
@media (max-width:520px){
  .ans-head{ grid-template-columns:1fr; row-gap:8px; }
  .ans-head .v{ justify-self:start; }
}

/* ── Calculator ─────────────────────────────────────────────────
   Two halves: the question and the slider on the left, the money on
   the right. The figure is the largest numeral on the page on purpose,
   because the whole section exists to make one number land.
   ─────────────────────────────────────────────────────────── */
.calc{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(20px,3vw,44px); align-items:stretch;
}
.calc-in,.calc-out{
  background:var(--beige); border-radius:var(--r-lg);
  padding:clamp(28px,3.4vw,48px);
  display:flex; flex-direction:column;
}
.calc-out{ background:var(--ink); color:var(--white); justify-content:center; }
/* The slider moved into the beige problem section, where a beige input panel
   would vanish into the ground. On beige it goes white; the figure panel is
   ink either way. */
.tint .calc-in{ background:var(--white); }

/* Hands off from the slider to the three cards below it. */
.calc-lead-in{
  margin:clamp(48px,6vw,80px) 0 clamp(24px,3vw,36px);
  text-align:center;
  font-size:clamp(17px,1.5vw,21px); font-weight:500; letter-spacing:-0.015em;
}
.calc-q{
  display:block; font-size:clamp(17px,1.6vw,21px); font-weight:500;
  line-height:1.3; letter-spacing:-0.02em; max-width:26ch;
}
.calc-ros{
  display:block; margin:auto 0 6px;
  padding-top:clamp(24px,3vw,40px);
  font-size:clamp(40px,5vw,64px); font-weight:400; line-height:1;
  letter-spacing:-0.05em; font-variant-numeric:tabular-nums;
}
.calc-ends{
  display:flex; justify-content:space-between;
  margin-top:12px; font-size:12.5px; color:var(--ink-40);
  font-variant-numeric:tabular-nums;
}

/* One track, one thumb, written twice because the two engines expose
   different pseudo-elements and neither accepts a shared selector list:
   an unknown pseudo invalidates the whole rule. */
.calc-range{
  -webkit-appearance:none; appearance:none;
  width:100%; margin:16px 0 0; background:transparent; cursor:pointer;
}
.calc-range:focus{ outline:none; }
.calc-range:focus-visible{ outline:2px solid var(--accent-ink); outline-offset:6px; border-radius:99px; }
.calc-range::-webkit-slider-runnable-track{
  height:4px; border-radius:99px;
  /* main.js writes --fill as a percentage. The hard stop paints the
     travelled part of the track in ink and leaves the rest as a hairline. */
  background:linear-gradient(90deg, var(--ink) 0 var(--fill,50%), var(--line-strong) var(--fill,50%) 100%);
}
.calc-range::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:22px; height:22px; margin-top:-9px; border-radius:99px;
  background:var(--ink); border:3px solid var(--beige);
  box-shadow:0 1px 3px rgba(42,37,32,.28);
  transition:transform .2s var(--ease);
}
.calc-range:active::-webkit-slider-thumb{ transform:scale(1.12); }
.calc-range::-moz-range-track{
  height:4px; border-radius:99px;
  background:linear-gradient(90deg, var(--ink) 0 var(--fill,50%), var(--line-strong) var(--fill,50%) 100%);
}
.calc-range::-moz-range-thumb{
  width:16px; height:16px; border-radius:99px;
  background:var(--ink); border:3px solid var(--beige);
  box-shadow:0 1px 3px rgba(42,37,32,.28);
}

.calc-fig{
  font-size:clamp(48px,6.6vw,96px); font-weight:400; line-height:0.92;
  letter-spacing:-0.062em; font-variant-numeric:tabular-nums;
}
.calc-unit{
  font-size:clamp(20px,2.2vw,30px); font-weight:400;
  letter-spacing:-0.03em; color:var(--paper-on-dark); margin-top:6px;
}
.calc-say{
  margin-top:clamp(20px,2.4vw,30px); max-width:32ch;
  font-size:clamp(15px,1.2vw,17px); line-height:1.5;
  color:var(--paper-on-dark);
}
.calc-cta{ display:flex; flex-wrap:wrap; gap:10px; margin-top:clamp(22px,2.6vw,32px); }
/* In flow rather than absolutely placed, so it can never land on the
   buttons when the CTA row wraps on a narrow card. */
.calc-how{ align-self:flex-end; margin-top:clamp(16px,2vw,22px); font-size:12.5px; color:var(--paper-on-dark); }
.calc-how:hover{ color:var(--white); }
.calc-out .btn{ align-self:flex-start; }
@media (max-width:860px){
  .calc{ grid-template-columns:1fr; }
  .calc-ros{ padding-top:20px; }
}

/* ── DMS wordmarks ──────────────────────────────────────────────
   Set type, not the vendors' official logotypes. See the REPLACE note
   in index.html before publishing.
   ─────────────────────────────────────────────────────────── */
.dms{
  display:grid; grid-template-columns:repeat(5,1fr);
  gap:clamp(16px,3vw,44px); align-items:center; justify-items:center;
  padding:clamp(8px,1.5vw,16px) 0 clamp(40px,5vw,64px);
}
.dms .logo svg{ height:clamp(19px,1.9vw,26px); }
.trust-checks{
  grid-template-columns:repeat(2,minmax(0,1fr)); display:grid;
  gap:clamp(14px,2vw,24px) clamp(24px,4vw,56px);
  max-width:1000px; margin:0 auto; padding-top:clamp(28px,3.4vw,44px);
  border-top:1px solid var(--line);
}
@media (max-width:860px){ .dms{ grid-template-columns:repeat(3,1fr); row-gap:30px; } .trust-checks{ grid-template-columns:1fr; } }
@media (max-width:520px){ .dms{ grid-template-columns:repeat(2,1fr); } }

/* ── Checks ─────────────────────────────────────────────────── */
.checks{ display:grid; gap:14px; }
.checks li{ display:flex; gap:12px; font-size:15px; color:var(--ink-70); align-items:flex-start; line-height:1.5; }
.checks svg{ width:15px; height:15px; color:var(--accent-ink); flex:none; margin-top:4px; }
.chips{ display:flex; flex-wrap:wrap; gap:8px; }
.chip{ border:1px solid var(--line); border-radius:var(--r-pill); padding:8px 15px; font-size:14px; color:var(--ink-70); }

/* ── FAQ ────────────────────────────────────────────────────── */
.faq{ max-width:860px; margin:0 auto; border-top:1px solid var(--line); }
.faq details{ border-bottom:1px solid var(--line); }
.faq summary{
  list-style:none; cursor:pointer; padding:26px 0; display:flex; gap:20px;
  font-size:18px; font-weight:450; line-height:1.35;
  outline:none;
}
.faq summary::-webkit-details-marker{ display:none; }
.faq summary:focus-visible{
  outline:2px solid var(--accent-ink); outline-offset:-4px; border-radius:8px;
}
.faq summary .pm{ margin-left:auto; color:var(--ink-40); flex:none; font-size:22px; line-height:1; transition:transform .38s var(--ease); }
.faq details[open] summary .pm{ transform:rotate(45deg); }
/* main.js animates this wrapper's height, so the answer needs somewhere to
   be measured and something to clip it while it moves. */
.faq .ans-wrap{ overflow:hidden; }
.faq .ans{ padding:0 0 26px; max-width:70ch; color:var(--ink-70); font-size:15px; line-height:1.55; }
@media (prefers-reduced-motion:reduce){
  .faq summary .pm{ transition:none; }
}

/* ── Final CTA ──────────────────────────────────────────────── */
.cta-card{
  position:relative; border-radius:var(--r-lg); overflow:hidden;
  min-height:clamp(340px, 34vw, 440px); display:grid; place-items:center; text-align:center;
}
.cta-card img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.cta-card::after{ content:''; position:absolute; inset:0; background:rgba(6,6,6,0.68); }
.cta-card .inner{ position:relative; z-index:2; color:#fff; padding:clamp(28px,4vw,64px); max-width:880px; }
/* This was 64px against 43px for every other h2, on the longest heading on
   the site, so it set three lines and read as a different scale rather than
   as emphasis. Now a notch above the h2 ramp instead of an outlier. */
.cta-card h2{ margin-bottom:18px; font-weight:400; font-size:clamp(30px,3.4vw,48px); line-height:0.98; letter-spacing:-0.042em; max-width:22ch; margin-left:auto; margin-right:auto; }
.cta-card p{ color:rgba(255,255,255,0.76); font-size:clamp(15px,1.2vw,18px); line-height:1.5; max-width:52ch; margin:0 auto; }
.cta-card .acts{ display:flex; justify-content:center; flex-wrap:wrap; gap:10px; margin-top:30px; }

/* ── Footer ─────────────────────────────────────────────────────
   One big beige card, brand top left, links top right, legal on the
   floor.
   ─────────────────────────────────────────────────────────── */
footer{ padding:0 0 clamp(20px,3vw,32px); }
.foot-card{
  position:relative; overflow:hidden;
  background:var(--beige); border-radius:var(--r-lg);
  padding:clamp(32px,4vw,56px) clamp(24px,3.5vw,56px) clamp(8px,1vw,16px);
  display:flex; flex-direction:column;
}
.foot-top{ display:flex; gap:clamp(24px,4vw,64px); flex-wrap:wrap; position:relative; z-index:2; }
.foot-brand{ display:flex; align-items:center; gap:14px; font-size:clamp(17px,1.6vw,21px); font-weight:450; letter-spacing:0.18em; white-space:nowrap; }
.foot-brand svg{ width:clamp(28px,2.6vw,34px); height:clamp(28px,2.6vw,34px); flex:none; }
.foot-cols{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(20px,3vw,56px); margin-left:auto; }
.foot-cols .foot-h{ font-size:14px; font-weight:450; color:var(--ink-40); margin:0 0 16px; }
.foot-cols ul{ display:grid; gap:11px; }
.foot-cols a{ font-size:15px; color:var(--ink-70); transition:color .2s var(--ease); }
.foot-cols a:hover{ color:var(--ink); }

.foot-cta{
  position:relative; z-index:2; margin-top:clamp(36px,5vw,72px);
  display:flex; align-items:flex-end; gap:clamp(20px,4vw,48px); flex-wrap:wrap;
}
.foot-mission{
  font-size:clamp(24px,3vw,40px); line-height:1.02;
  letter-spacing:-0.04em; font-weight:400; max-width:14ch;
}
.foot-cta .btn{ margin-bottom:4px; }

.foot-legal{
  position:relative; z-index:2; margin-top:auto;
  padding:clamp(28px,4vw,56px) 0 clamp(18px,2vw,24px);
  display:flex; flex-wrap:wrap; gap:14px; justify-content:space-between;
  font-size:13px; color:var(--ink-40);
}

@media (max-width:820px){
  .foot-cols{ grid-template-columns:repeat(2,minmax(0,1fr)); margin-left:0; width:100%; row-gap:32px; }
}
@media (max-width:460px){
  .foot-cols{ grid-template-columns:1fr 1fr; }
}

/* "powered by" plus the Marv-L lockup, under the booking page title. The
   lockup is the model's mark rather than the company's, which is exactly
   what it is naming here. Served as an <img> rather than inlined: it is one
   use on one page, and the file is 2KB with its wordmark already outlined,
   so it does not need the sprite or a webfont. */
.powered{
  display:flex; align-items:center; gap:10px;
  margin:18px 0 26px;
  font-size:13px; color:var(--ink-40);
}
.powered img{ height:26px; width:auto; display:block; }

/* ── Booking page ──────────────────────────────────────────────
   Beige page, one white card holding the questions, the copy and
   the progress rail parked on the left. The steps inside the card
   are rows divided by hairlines rather than cards of their own,
   because cards inside a card is the thing that reads as clutter.
   ─────────────────────────────────────────────────────────── */
/* Flex column so the minimal footer sits on the viewport floor while the
   card is still short, rather than floating in the middle of the beige. */
.book-page{ background:var(--beige); min-height:100vh; display:flex; flex-direction:column; }
.book-page .book-layout{ flex:1 1 auto; align-content:start; }
.book-page .top.stuck{ background:rgba(246,241,232,0.88); box-shadow:0 1px 0 var(--line-soft); }

.book-layout{
  display:grid; grid-template-columns:minmax(0,0.86fr) minmax(0,1.14fr);
  gap:clamp(48px,7vw,112px); align-items:start;
  max-width:1240px;
  padding:clamp(104px,12vw,150px) var(--gutter) clamp(64px,7vw,96px);
}
.book-side{ position:sticky; top:104px; }
.book-side h1{ max-width:11ch; margin-bottom:22px; }
.book-side .lede{ max-width:44ch; }
.book-side-note{
  margin-top:22px; font-size:15px; line-height:1.55;
  color:var(--ink-55); max-width:42ch;
}
@media (max-width:980px){
  .book-layout{ grid-template-columns:1fr; row-gap:clamp(40px,6vw,64px); }
  .book-side{ position:static; }
}
.rail li.on{ color:var(--ink); font-weight:450; }
.rail li.on .rdot{ border-color:var(--ink); background:var(--ink); }
.rail li.done .rdot{ border-color:var(--accent-ink); background:var(--accent-ink); }
.rail li.done{ color:var(--ink-55); }
@media (max-width:980px){ .rail{ display:none; } }

/* No card and no inner box. This used to be a white panel (.book-panel)
   wrapping a beige one (.cal-wrap) wrapping the embed, which was three
   grounds deep for one calendar and only added edges.

   The booker still has a white ground, but it is Cal's own, set through
   cal-bg in book.js rather than by a wrapper here. Do not put the white
   back on this element: two white surfaces with different radii, one
   inside the other, is what it looked like before. */
.book-panel{ background:none; padding:0; }
.qstep.done .qn{ background:var(--accent-ink); color:#fff; }
.opt-lbl{ color:var(--ink-40); font-size:12px; }
.field input.invalid{ border-color:var(--rust); }

.cal-wrap{ background:none; padding:0; }
.cal-inline{ min-height:560px; width:100%; }
.cal-fallback{ border:1px solid var(--line); border-radius:var(--r); padding:clamp(22px,2.4vw,32px); }
.cal-fallback h3{ font-size:20px; margin-bottom:10px; }
.cal-fallback p{ color:var(--ink-70); font-size:15px; line-height:1.5; max-width:52ch; margin-bottom:22px; }

/* ── Minimal footer, booking page only ── */
.foot-min{ border-top:1px solid var(--line); padding:0; }
.foot-min-inner{
  display:flex; align-items:center; gap:clamp(16px,3vw,32px);
  height:64px; font-size:13px; color:var(--ink-40);
}
.foot-min .brand{ font-size:13px; }
.foot-min .brand svg{ width:18px; height:18px; }
.foot-min-c{ margin-left:clamp(8px,2vw,24px); }
.foot-min-links{ margin-left:auto; display:flex; gap:clamp(14px,2vw,24px); }
.foot-min-links a{ color:var(--ink-40); }
.foot-min-links a:hover{ color:var(--ink); }
@media (max-width:620px){
  .foot-min-inner{ height:auto; padding:18px 0; flex-wrap:wrap; row-gap:10px; }
  .foot-min-c{ margin-left:0; }
  .foot-min-links{ margin-left:0; width:100%; }
}

/* ── Legal pages ───────────────────────────────────────────── */
.legal-hero{ padding:clamp(104px,12vw,148px) 0 clamp(40px,5vw,64px); }
.legal-hero .wrap{ max-width:1024px; }
.legal{ padding-top:clamp(44px,6vw,72px); }
.legal .wrap{ max-width:1024px; }
.legal-row{
  display:grid; grid-template-columns:minmax(0,0.72fr) minmax(0,1.28fr);
  gap:clamp(20px,4vw,56px);
  padding:clamp(26px,3.4vw,40px) 0; border-top:1px solid var(--line);
}
.legal-row h2{ font-size:clamp(19px,1.8vw,23px); font-weight:500; letter-spacing:-0.015em; line-height:1.2; max-width:16ch; }
.legal-row p{ font-size:15px; line-height:1.6; color:var(--ink-70); max-width:70ch; }
.legal-row p + p{ margin-top:14px; }
.legal-row a{
  color:var(--ink);
  text-decoration:underline; text-decoration-color:var(--line-strong);
  text-decoration-thickness:1px; text-underline-offset:3px;
}
.legal-row a:hover{ text-decoration-color:var(--ink); }
.legal-list{ display:grid; gap:11px; }
.legal-list li{ font-size:15px; line-height:1.6; color:var(--ink-70); padding-left:16px; position:relative; }
.legal-list li::before{ content:''; position:absolute; left:0; top:10px; width:5px; height:5px; border-radius:99px; background:var(--ink-40); }
@media (max-width:760px){ .legal-row{ grid-template-columns:1fr; gap:12px; } }

/* ── Reveal ─────────────────────────────────────────────────── */
.rv{ opacity:0; transform:translateY(16px); transition:opacity .8s var(--ease), transform .8s var(--ease); }
.rv.in{ opacity:1; transform:none; }
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  .rv{ opacity:1; transform:none; transition:none; }
}

/* ══════════════════════════════════════════════════════════════
   Carried back from the vision-layer build: the marquee, the hero
   video band, and the source-line styles the cited figures need.
   Nothing else came with them, so the layout is unchanged.
   ══════════════════════════════════════════════════════════════ */

/* ── Hero footage band ──────────────────────────────────────────
   The poster is the LCP element and the only thing that loads until
   main.js is told there is a video. The <video> is inserted on top of
   it, so the band never collapses and never flashes black.
   ─────────────────────────────────────────────────────────── */
/* The <video> main.js injects. z-index 1 puts it over the poster and under
   the scrim (2) and the copy (3), so the type is never sitting on raw
   footage even for the frame between the video appearing and the scrim
   painting. */
.hero-stage video{
  position:absolute; inset:0; z-index:1;
  width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .6s var(--ease);
}
.hero-stage video.on{ opacity:1; }


/* ── Brand marquee ──────────────────────────────────────────────
   Two rows travelling in opposite directions, deliberately slow: at the
   original 46s the counter-motion was hard to look at. The track holds the
   list twice and animates to translateX(-50%), which is the only offset that
   loops without a jump: at the end of the cycle the second copy sits
   exactly where the first one began.
   ─────────────────────────────────────────────────────────── */
.mq{
  display:grid; gap:clamp(18px,2.4vw,30px);
  /* Full-bleed on purpose. The rows have to run off both edges or the
     scroll reads as a carousel with a start and an end. */
  width:100%; overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}
.mq-row{ overflow:hidden; }
.mq-track{
  display:flex; align-items:center; width:max-content;
  animation:mq 110s linear infinite;
  will-change:transform;
}
/* The spacing is a per-item margin, NOT a flex `gap`, and that is the whole
   trick. With `gap` the track is 20 items plus 19 gaps, so half of it is
   10 items plus 9.5 gaps while the distance from item 0 to item 10 is
   10 items plus 10 gaps. translateX(-50%) then lands half a gap short and
   the row visibly jumps once a cycle. Measured at 36px on a 72px gap.
   As a margin the track is exactly 20 x (item + margin), so half of it is
   exactly the loop distance. */
.mq .logo{ margin-right:clamp(40px,5vw,80px); }
.mq-r .mq-track{ animation-direction:reverse; }
@keyframes mq{ to{ transform:translateX(-50%); } }
/* Hovering anywhere in the block pauses both rows, not just the one
   under the cursor, so they do not drift out of step with each other. */
.mq:hover .mq-track{ animation-play-state:paused; }
.mq .logo{ width:auto; flex:none; }
.mq .logo svg{ height:clamp(32px,3vw,44px); width:clamp(32px,3vw,44px); }

@media (prefers-reduced-motion:reduce){
  /* Stopped dead would hide half the brands off the right edge, so the
     row becomes a strip you can scroll by hand instead. */
  .mq{ -webkit-mask-image:none; mask-image:none; }
  .mq-row{ overflow-x:auto; scrollbar-width:thin; }
  .mq-track{ animation:none; }
}


/* ── Source lines ───────────────────────────────────────────────
   Every claim on this page is attributed. The attribution is
   deliberately quiet: it has to be readable and checkable, not
   compete with the number it supports.
   ─────────────────────────────────────────────────────────── */
.src{
  max-width:74ch; margin:clamp(28px,3.4vw,44px) auto 0;
  text-align:center;
  font-size:13px; line-height:1.6; color:var(--ink-40);
}
.cite{ display:block; margin-top:6px; color:var(--ink-40); font-size:12.5px; }

/* A citation sitting ON a scrim rather than under a section. Used where the
   ground below the block travels to near-black and ink would disappear.

   The width cap is not cosmetic. .media-scrim fades left to right:
   rgba(6,6,6,.92) at 0%, .80 at 34%, .22 at 62%, nothing by 84%. Text that
   runs past roughly 40% of the figure comes out the far side of its own
   scrim and sits on the bare photograph. Left at the inherited 74ch this
   line measured 592px, ending at 71.5% of the figure, and dropped to
   3.86:1. The quote above it is capped at 26ch for the same reason. */
.src-on-dark{
  max-width:32ch; margin:clamp(16px,1.8vw,22px) auto 0 0;
  text-align:left; color:rgba(255,255,255,0.72);
}


/* ── Demo film dialog ───────────────────────────────────────────
   Opened from the hero's "Watch the video". The dialog is the backdrop
   hit area, so the video sits inside with no padding of its own. */
.film{
  width:min(1200px, 92vw); max-width:none; padding:0; border:0;
  background:#000; border-radius:12px; overflow:visible;
}
.film::backdrop{ background:rgba(20,17,14,0.86); }
.film video{ display:block; width:100%; height:auto; max-height:86vh; border-radius:12px; background:#000; }
.film-close{
  position:absolute; top:-44px; right:0; width:36px; height:36px;
  border:0; border-radius:50%; background:rgba(255,255,255,0.14); color:#fff;
  font-size:24px; line-height:1; cursor:pointer;
}
.film-close:hover{ background:rgba(255,255,255,0.26); }
