/* ═══════════════════════════════════════════════════════════════════════
   ReelSkillz — the Video Village treatment.  PREVIEW THEME.

   Linked AFTER each page's inline <style>, so at equal specificity these
   rules win by order. One file on purpose: the pages carry their own
   inline stylesheets with two different token vocabularies (--mark on the
   product pages, --accent on the legal/install ones), and the only way a
   restyle stays coherent across ten pages is a single sheet that overrides
   both. Iterating inside index-preview produced ten stacked patch layers
   that fought each other; this file replaces all of them.

   The three decisions, measured off videovillage.com rather than guessed:
     ground   #222222  — a flat neutral charcoal, not near-black
     accent   #FF6A1A  — ReelSkillz's OWN orange, restored 2026-08-25 at the
              owner's request. The Video Village blue was only ever the
              preview; the layout, the depth and Outfit are what that
              treatment was actually for, and they all stay. Orange measures
              5.55:1 on this ground, so unlike the blue it is legal as text
              too; #ff8a3a (6.78:1) is the site's own lighter shade and
              carries emphasis.
     second   #FF4F45  — red, used SPARINGLY as Skin's own mark: its pricing
              card and the accents on features-skin.html. Film Pro keeps
              orange, so the two products read apart at a glance instead of
              being two identical cards.
     type     Figtree + JetBrains Mono, headings at 700 — the owner's pick,
              live five-face comparison; closest free face to their
              Brandon Grotesque.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  --ground:#222222; --panel:#2e2e30; --panel-2:#3a3a3d; --rule:#454548;
  --ink:#ffffff; --ink-soft:rgba(255,255,255,.74); --ink-dim:rgba(255,255,255,.56);
  --mark:#ff6a1a; --accent:#ff6a1a;          /* 5.55:1 — fills AND text  */
  --mark-text:#ff8a3a;                       /* 6.78:1 — emphasis        */
  --mark-dim:rgba(255,106,26,.16);
  --mark-2:#ff4f45;                          /* 4.89:1 — Skin, fills     */
  --mark-2-text:#ff6a60;                     /* 5.67:1 — Skin, text/icon */
  --sans:'Figtree',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  /* --mono was never in this sheet — each page declared its own, so the mono
     could only be changed sixteen times. It belongs with --sans. */
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
}
body{background:var(--ground);color:var(--ink);font-family:var(--sans);font-size:17px}

/* ── type: large and light — no heading above weight 300 ─────────────── */
h1,h2{font-weight:700!important;letter-spacing:-.01em!important}
h3{font-weight:500}
p{line-height:1.65}
.lede h1{font:300 clamp(32px,3.6vw,50px)/1.12 var(--sans)!important}
.lede p{font-size:19px;max-width:660px}
/* index.html caps the hero headline at max-width:820px. The whole line is
   875px of ink at the clamped 50px, so that cap was the only reason it broke
   — and text-wrap:balance then split it into two SHORT lines of 416 and 448px
   while the paragraph under it ran 631 and 644. The body copy overhung the
   headline by ~200px, which is the ragged step you can see: the headline was
   the narrowest thing in a 1160px column instead of the widest.

   Uncapped it sets on one 875px line, clear of the paragraph, and the column
   itself is the only limit. balance stays for the narrow viewports where it
   still has to wrap — below about 1000px it does, and balance keeps those two
   lines even instead of leaving "node." alone on the second. */
.lede h1{max-width:none;text-wrap:balance}
.amount{font-weight:300!important;letter-spacing:-.02em!important}
h1,h2,h3{text-wrap:balance}

/* ── the header lists, it does not shout ─────────────────────────────── */
/* position was never set, so the bar scrolled away with the hero. Sticky,
   not fixed: fixed takes it out of flow and the hero jumps up underneath it.
   z-index clears .panel (30), the only other stacked thing on the page.
   index.html:38 sets html{overflow-x:hidden}, which makes html a scroll
   container — sticky still resolves against it, VERIFIED by measuring the
   bar's viewport position after a scroll rather than assumed. */
nav{position:sticky;top:0;z-index:60;
    background:rgba(26,26,28,.85);backdrop-filter:saturate(140%) blur(14px);
    border-bottom:1px solid var(--rule);padding:15px 34px}
/* The file was 512x378 and the CSS forced it into a 1:1 box, squashing the
   mark 26% horizontally — the round centre rendered as an oval, which is the
   "wrong shape" you can see at any size. The 512-wide canvas is opaque black
   with the drawn mark at x 92..419, so a centred 378x378 crop threw away
   nothing but pure black and made the square box honest. Asset replaced in
   place; deploy.py rewrites ?v=1 to a content hash, so all 25 pages pick it
   up and no browser keeps the old one. */
.brand img{width:36px;height:36px;border-radius:9px}
.brand span{letter-spacing:.16em;font-size:10px}
@media (min-width:900px){
  .navburger{display:none!important}
  .navlinks{display:flex!important;gap:30px;position:static!important;
    flex-direction:row!important;background:none!important;border:0!important;
    box-shadow:none!important;padding:0!important;margin:0 0 0 8px!important;
    width:auto!important;height:auto!important;max-height:none!important;
    transform:none!important;opacity:1!important;visibility:visible!important;
    overflow:visible!important}
  .navlinks a{font:400 15px/1 var(--sans)!important;color:var(--ink-soft)}
  .navlinks a:hover{color:#fff}
}

/* ── CTA: flat, small radius, no glow. Dark ink on the blue: 5.16:1. ── */
/* Depth is three things working together and none of them alone: a top-lit
   gradient so the face is not one flat colour, a bright inset hairline along
   the top edge where light would catch, and a shadow under it that is darker
   and tighter than the ambient one. The hover lifts 1px and the shadow grows
   to match — the object moves toward you, it does not just change colour. */
.buy, a.buy{
  background:linear-gradient(180deg,#ff9a5c 0%, var(--mark) 52%, #d9510c 100%)!important;
  /* 10% of the button's own face blended into the ink — the same result as
     90% opacity, but a solid colour, so the arrow glyph and any child
     cannot end up on a different alpha. Worst contrast across the band the
     glyphs actually occupy (32-68% of the button height, where the gradient
     runs #ff7c33 to #f26215) is 4.73:1, still over the 4.5 floor and well
     over the 3.0 one a 17px/700 label qualifies for. */
  color:#3f1c07!important;border:0!important;border-radius:12px!important;
  padding:13px 20px!important;font:600 15px/1 var(--sans)!important;
  letter-spacing:0!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.42),
             inset 0 -1px 0 rgba(0,0,0,.22),
             0 2px 4px rgba(0,0,0,.30),
             0 6px 16px rgba(122,44,6,.42)!important;
  transition:transform .14s ease, box-shadow .14s ease, filter .14s ease}
.buy:hover{transform:translateY(-1px)!important;filter:brightness(1.05);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),
             inset 0 -1px 0 rgba(0,0,0,.22),
             0 4px 8px rgba(0,0,0,.32),
             0 10px 24px rgba(122,44,6,.5)!important}
.buy:active{transform:translateY(1px)!important;
  box-shadow:inset 0 2px 5px rgba(0,0,0,.34), 0 1px 2px rgba(0,0,0,.3)!important}

/* ── surfaces: sections are cards, cards-in-cards step up once more ──── */
.wrap.specs,.wrap.paths,.wrap.mods,.wrap.price,.wrap.faq{
  background:var(--panel);border:1px solid var(--rule);border-radius:18px;
  padding:38px 40px;margin:26px auto;max-width:1160px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),
             inset 0 -1px 0 rgba(0,0,0,.26),
             0 2px 4px rgba(0,0,0,.18),
             0 12px 30px rgba(0,0,0,.26)}
.loupes figure,.paths li,.mods li,.faq details,.specs article{
  background:var(--panel-2);border:1px solid rgba(255,255,255,.12);border-radius:12px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08),
             inset 0 -1px 0 rgba(0,0,0,.26),
             0 1px 3px rgba(0,0,0,.22),
             0 8px 20px rgba(0,0,0,.26)}
.specs article{padding:20px 22px}

/* ── before & after: the picture IS the section ───────────────────────────
   Measured on a 390px phone before this block: the card's 40px side padding
   plus its 1px borders left the image 308px wide and 129px tall — the frame
   was taking a quarter of the screen from the one element the section exists
   to show. The heading and the caption keep their padding; only the media
   breaks out of it. */
/* ── before & after: framed like the hero video, not like a card ───────
   .wrap.ba is deliberately NOT in the surface list above any more, so it
   falls back to plain .wrap{padding:0 40px} — a 1160px content width, the
   same number --colw gives the hero video. The two pictures now line up down
   the page instead of one sitting inset inside a panel.

   The negative margins that used to pull the media out of the card's own
   40px padding go with the card: keeping them would make this image 1240px,
   WIDER than the hero, which is the opposite of matching it. */
.wrap.ba{padding-top:38px;padding-bottom:44px;margin:26px auto;max-width:1240px}
/* square corners once it meets the card edge — a 3px radius floating in the
   middle of an 18px one reads as a mistake */
.wrap.ba .cmp{border-radius:10px}
/* .bafoot lives INSIDE .bacar, so the negative margins above drag the caption
   and the dots out to the card edge with the picture. Only the picture should
   break out; put the text back on the same line as the heading above it. */
/* nothing breaks out of the column any more, so the caption needs no
   counter-padding — it already sits on the heading's left edge. */

@media (max-width:820px){
  /* Edge to edge on a phone. The side border and the corner radius go with the
     padding: keeping either would draw a frame around a full-bleed image. Top
     and bottom borders stay, so the section is still separated from the ones
     above and below it. */
  .wrap.ba{padding-left:0;padding-right:0}
  /* full bleed on a phone: the corners meet the screen edge */
  .wrap.ba .cmp{border-radius:0}
  .wrap.ba .bacar{margin-left:0;margin-right:0}
  /* the text either side of the image keeps a thumb-friendly margin */
  .wrap.ba .k,.wrap.ba .bafoot{padding-left:20px;padding-right:20px}
  /* the arrows sat 8px from the old padded edge; against a full-bleed frame
     they need to clear the picture's own corner */
  .wrap.ba .banav.prev{left:10px}
  .wrap.ba .banav.next{right:10px}
}

.loupes figure{padding:10px 10px 16px}
.loupes img{border-radius:9px}
.loupes h3{margin:13px 4px 4px;font-weight:500}
.loupes p{margin:0 4px}

/* ── the pricing cards (index only — classes exist nowhere else) ─────── */
.pgrid.vvcards{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;align-items:stretch}
/* Same idea as the buttons, at a larger scale and much quieter: a hairline of
   light along the top edge, a hairline of shadow along the bottom, and two
   shadows below — a tight one for contact and a wide soft one for the drop.
   A single blurred shadow reads as a sticker; the pair reads as a slab. */
.pgrid.vvcards .card{background:var(--panel-2);border:1px solid rgba(255,255,255,.13);
  border-radius:20px;padding:36px 28px 32px;text-align:center;display:flex;flex-direction:column;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),
             inset 0 -1px 0 rgba(0,0,0,.30),
             0 2px 4px rgba(0,0,0,.24),
             0 14px 32px rgba(0,0,0,.34);
  transition:transform .18s ease, box-shadow .18s ease}
.pgrid.vvcards .card:hover{transform:translateY(-2px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),
             inset 0 -1px 0 rgba(0,0,0,.30),
             0 4px 8px rgba(0,0,0,.26),
             0 22px 46px rgba(0,0,0,.40)}
.pgrid.vvcards .card[data-prod="film-pro"]{
  background:radial-gradient(120% 90% at 50% 0%, rgba(255,106,26,.13), transparent 62%), var(--panel-2);
  border-color:rgba(255,106,26,.38)}
.pgrid.vvcards .card[data-prod="skin"]{
  background:radial-gradient(120% 90% at 50% 0%, rgba(255,79,69,.13), transparent 62%), var(--panel-2);
  border-color:rgba(255,79,69,.36)}
.pgrid.vvcards .card[data-prod="skin"] .plink{color:var(--mark-2-text)}
.pgrid.vvcards .card[data-prod="bundle"]{
  background:radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.09), transparent 62%), var(--panel-2);
  border-color:rgba(255,255,255,.20)}
/* One mark, one frame: every card's icon is a single pre-composed 181x81
   tile (the bundle's two pills live INSIDE its tile), so the name, price
   and button lines share a baseline by construction, not by maintenance. */
.pgrid.vvcards img.picon{width:128px;height:auto;object-fit:contain;display:block;
  margin:6px auto 22px;filter:drop-shadow(0 2px 3px rgba(0,0,0,.4)) drop-shadow(0 10px 22px rgba(0,0,0,.45))}
.pgrid.vvcards .pname{text-transform:none!important;
  font:400 21px/1.25 var(--sans)!important;letter-spacing:0!important;
  color:#fff;margin-bottom:12px}
.pgrid.vvcards .pblurb{font:400 15px/1.55 var(--sans);color:var(--ink-dim);
  margin:0 auto 30px;max-width:30ch;min-height:3.1em;display:flex;
  align-items:center;justify-content:center;text-align:center;text-wrap:balance}
.pgrid.vvcards .amount{font:300 44px/1 var(--sans);color:#fff}
.pgrid.vvcards .amount s{font:300 22px/1 var(--sans);color:rgba(255,255,255,.42);margin-left:10px}
.pgrid.vvcards .pmeta{margin-top:11px;margin-bottom:26px;color:var(--ink-dim);letter-spacing:.13em}
.pgrid.vvcards .buy,.pgrid.vvcards .ghost{margin-top:auto;justify-content:center;width:100%}
.pgrid.vvcards .ghost{
  background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.03));
  border:1px solid rgba(255,255,255,.22);
  /* 12px, not 13: .ghost carries a 1px border top and bottom and .buy carries
     none, so at equal padding the ghost button was 43px against the others'
     41 and sat 2px proud of them in the row. */
  border-radius:12px;padding:12px 18px;font:600 15px/1 var(--sans);
  color:#fff;text-decoration:none;display:inline-flex;align-items:center;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16), 0 2px 6px rgba(0,0,0,.26);
  transition:transform .14s ease, box-shadow .14s ease, background .14s ease}
.pgrid.vvcards .ghost:hover{transform:translateY(-1px);
  background:linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.06));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 6px 16px rgba(0,0,0,.34)}
.pgrid.vvcards .ghost:active{transform:translateY(1px);
  box-shadow:inset 0 2px 5px rgba(0,0,0,.3)}
.pgrid.vvcards .ptrialline{margin-top:16px;font:400 13px/1 var(--sans);color:var(--ink-dim)}
.pgrid.vvcards .plink{display:inline-block;margin-top:14px;
  font:500 14px/1 var(--sans);color:var(--mark-text);text-decoration:none}
.pgrid.vvcards .plink:hover{text-decoration:underline}
/* The bundle card has no About link — there is no page for "both" to point at.
   Removing it pushed that card's button 28px BELOW the other two: .buy carries
   margin-top:auto, so a card with less content under the button is given more
   space above it. Measured, not guessed: the link row is 14px of margin-top
   plus a 14px line. Reserve exactly that. The :has() rule covers any future
   card that loses its link; the explicit one is the fallback where :has() is
   not supported, and an unsupported selector drops its own rule only. */
.pgrid.vvcards .card[data-prod="bundle"] .ptrialline{margin-bottom:28px}
.pgrid.vvcards .card:not(:has(.plink)) .ptrialline{margin-bottom:28px}
.pgrid.vvcards .card ul{display:none}
@media (max-width:900px){
  .pgrid.vvcards{grid-template-columns:1fr}
  .pgrid.vvcards .pblurb{min-height:0}
}

/* ── accent plumbing ─────────────────────────────────────────────────── */
.lede .eyebrow i{background:var(--mark)}
.marktoggle.on{color:var(--mark-text);border-bottom-color:var(--mark-text)}
::selection{background:var(--mark-dim)}
a:focus-visible,button:focus-visible,summary:focus-visible{
  outline:2px solid var(--mark-text);outline-offset:3px}

/* Micro-labels keep their tracking — the one place it earns its keep. */
.k,.eyebrow,.plate-foot,.pmeta{letter-spacing:.16em}

/* Depth stays; the movement goes, for anyone who has asked the OS for less. */
@media (prefers-reduced-motion:reduce){
  .buy,.pgrid.vvcards .ghost,.pgrid.vvcards .card{transition:none!important}
  .buy:hover,.pgrid.vvcards .ghost:hover,.pgrid.vvcards .card:hover{transform:none!important}
}

/* ── the light-orange emphasis colour ────────────────────────────────────
   #ff8a3a is the OLD accent's lighter shade. It is used two ways in the
   pages' own stylesheets and only one of them was caught by the token swap:
   the button gradient (overridden above) and, on features/about/download,
   a plain `color:#ff8a3a` on emphasis text — "Two looks, or *none at all*".
   That one is not behind any token, so it survived and left a single orange
   phrase in the middle of a blue page.

   Scoped to the text roles that use it. NOT applied to `i` — on the features
   page those are the six hue swatches for the density axes (red, yellow,
   green, cyan, blue, magenta) and recolouring them would destroy what they
   are illustrating. */
/* features.html sets this as `.mrow h2 em` (0,1,2). A bare `em` (0,0,1) loses
   to it however late it is loaded — being last only breaks ties at EQUAL
   specificity. Matched here rather than reached for with !important, so the
   page can still override it deliberately if it ever needs to. */
.mrow h2 em, .mpanel h2 em, section h2 em, .lede h1 em,
h1 em, h2 em, h3 em, p em{color:var(--mark-text);font-style:normal}

/* ── Typographic pass, features.html + features-skin.html ────────────────
   Loaded after each page's inline <style>, so equal specificity wins here.

   .shotcap is a TECHNICAL CREDIT — "Temperature 0 -> +40 · rendered by the
   plugin engine". Mono, uppercase, .13em tracked: the right voice for data,
   and features.html's eight image credits keep it. features-skin.html has no
   comparison renders, so its captions are sentences — and that same voice set
   prose as if it were a part number. .pnote is the prose voice.

   SPECIFICITY: these notes are <p> inside .mrow, so a bare .pnote (0,1,0)
   loses every font and colour to features.html's .mrow p (0,1,1) — measured,
   not assumed: the first version of this rule rendered at 15.5px, not 13.5px.
   Each selector below is listed again with an ancestor class so it carries
   (0,2,0) and outranks it without reaching for !important. */
.pnote,.mrow .pnote,.wrap .pnote{margin:14px 0 0;max-width:520px;
  font:400 13.5px/1.62 var(--sans);letter-spacing:normal;text-transform:none;
  color:rgba(255,255,255,.60)}          /* 6.6:1 on --ground */
.pnote b,.mrow .pnote b,.wrap .pnote b{font-weight:500;color:var(--ink-soft)}
.pnote a,.mrow .pnote a,.wrap .pnote a{color:var(--mark-text);
  text-decoration:none;padding-bottom:1px;
  border-bottom:1px solid rgba(255,138,58,.34)}
.pnote a:hover,.mrow .pnote a:hover,.wrap .pnote a:hover{
  border-bottom-color:var(--mark-text)}
.pnote.mid,.wrap .pnote.mid{margin-left:auto;margin-right:auto;text-align:center}

/* This started as an AA fix: the blue eyebrow measured 4.46:1, under the
   4.5:1 floor 10px uppercase text has to clear. Orange does not have that
   problem — --mark is 5.55:1 — but --mark-text (#ff8a3a, 6.78:1) still
   gives small tracked caps more headroom, so the rule stays. */
.mrow .eyebrow{color:var(--mark-text)}

/* Every heading on the page is weight 300 now; a 700 panel title was the one
   weight fighting that. 600 still reads as a title. */
.insp .ihead b{font-weight:600}

/* Body prose ran at --ink-dim (.56 -> 5.94:1) and the lede at 93 characters
   a line. 65-80 is the readable band. */
.mrow p{line-height:1.65;color:rgba(255,255,255,.64)}   /* 7.3:1 */
.fhead p{max-width:620px}
.fhead h1,.mrow h2{text-wrap:balance}

/* ── Skin's own mark, scoped to its page (body class="skinpage") ─────────
   Orange is the brand and stays on the nav, the buttons and every shared
   surface. What turns red here is what identifies the PRODUCT: the section
   eyebrows with their icons, the emphasis inside the headings, and the page
   kicker. Delete these five lines and the page is orange like the rest. */
.skinpage .mrow .eyebrow{color:var(--mark-2-text)}
.skinpage .fhead .k{color:var(--mark-2-text)}
.skinpage .mrow h2 em,.skinpage h2 em,.skinpage h1 em{color:var(--mark-2-text)}
.skinpage .pnote a{color:var(--mark-2-text);border-bottom-color:rgba(255,106,96,.34)}
.skinpage a:focus-visible,.skinpage button:focus-visible{outline-color:var(--mark-2-text)}

/* ── one column: the bar, the picture, its credit, the headline ──────────
   .wrap is max-width:1240 / padding:0 40 / border-box, so the text column is
   min(100% - 80px, 1160px). Everything above the fold now measures itself
   against that ONE token, so the picture's edge, the credit strip, the top
   bar's contents and the headline all land on the same x.

   The picture is not cropped to get there. The lede right under it says the
   shot is "shown exactly as it was rendered", and the film's own credit is
   burned into its lower third — object-fit:cover would clip that credit AND
   make the sentence untrue. A 2.386:1 frame only gets shorter by getting
   narrower, so narrowing it to the column is what makes it smaller.

   The bar keeps its full-width background — it has to, it is sticky and has
   to cover what scrolls under it — and only its CONTENTS move in.

   The 820px branch is not a second design: below that breakpoint index.html
   already drops .wrap, nav and .plate-foot to 20px padding, and this token
   reproduces exactly that, so the responsive behaviour is unchanged.

   margin-left is calc((100% - width)/2), never `auto`: when the column is
   wider than the containing block auto margins collapse to 0 and the frame
   shifts right instead of centring. */
:root{--colw:min(100% - 80px, 1160px)}
@media (max-width:820px){ :root{--colw:calc(100% - 40px)} }

/* The picture sat flush against the bar — measured gap was exactly 0. It
   stays tight to its own credit strip below (12px, they are one object) and
   takes its breathing room above instead. clamp so a short laptop screen
   does not spend 24px of its fold on a margin. */
.stage{width:var(--colw);margin-left:calc((100% - var(--colw)) / 2);
       margin-right:0;margin-top:clamp(14px, 2vh, 24px);border-radius:10px}
/* MUST SIT DIRECTLY AFTER THE RULE ABOVE. The phone wants the hero running
   to the screen edge like the before/after does, and this override is the
   same specificity as the desktop rule — so it only wins on source order.
   Written first inside the before/after block a hundred lines earlier, it
   was silently beaten and the video stayed inset at 350px.

   The first version of this used width:100vw with margin-left:calc(50% - 50vw),
   on the assumption that .stage sat inside a padded .wrap. It does not — it is
   a direct child of <body>, and body carries no padding or margin at any width.
   So width:auto already fills the whole usable width, and the vw form was not
   just unnecessary but wrong: 100vw counts the classic scrollbar while the
   containing block does not, so on a desktop browser narrowed below 820px
   (Windows Chrome, or macOS set to always show scrollbars) the hero came out
   15px too wide and the page scrolled sideways. Measured at 768px with a 15px
   scrollbar: left -7, width 768, 7px of horizontal overflow. With width:auto:
   left 0, width 753, none. Overlay scrollbars hid it on every phone, which is
   exactly why it survived the first check. */
@media (max-width:820px){
  .stage{width:auto;margin-left:0;margin-right:0;border-radius:0}
}
.plate-foot{padding-left:calc((100% - var(--colw)) / 2);
            padding-right:calc((100% - var(--colw)) / 2)}
nav{padding-left:calc((100% - var(--colw)) / 2);
    padding-right:calc((100% - var(--colw)) / 2)}

/* ── marks on the spec strip ─────────────────────────────────────────────
   The Apple and Windows paths are the ones ALREADY inline on this page in
   the hero eyebrow, reused so the site draws each mark exactly one way.

   Colours are the ones each owner actually specifies, not invented:
     Apple   — Apple's identity guidelines allow the mark in black or white
               only, never recoloured, so on this ground it is near-white.
     Windows — #00A4EF, the Windows blue. Four panes in four DIFFERENT
               colours would be the MICROSOFT logo, not the Windows one.
     Resolve — the mark, drawn as vectors. I first refused this and shipped
               an abstract three-trackball placeholder instead, which was
               wrong: naming a host application and showing its mark to state
               real compatibility is nominative use, it is what every plugin
               vendor in this market does, and a placeholder nobody
               recognises costs sales for no benefit. Geometry and colours
               were measured off the installed app's icon (face #1c3c55,
               petals #8bedfb/#e9f492/#ff8f7e, rim cyan->red on the
               top-left-to-bottom-right diagonal) and redrawn as paths, so no
               Blackmagic raster is redistributed. Replace with an official
               asset from their brand pack if one is ever obtained.
     One-time— the site accent, so the fourth cell is not the bare one. */
.specs b{display:flex;align-items:center;gap:9px}
.slogo{width:18px;height:18px;flex:none;display:block}
.slogo.apple{color:#f5f5f7;margin-top:-1px}
.slogo.win{color:#00a4ef}
.slogo.once{color:var(--mark-text)}
@media(max-width:520px){ .slogo{width:16px;height:16px} }

/* ── full screen on the hero ─────────────────────────────────────────────
   The stream is ALREADY pinned to its top rung — 4096x1716 hevc at 116 Mbps
   peak, chosen by bitrate on MANIFEST_PARSED — so full screen needs no
   quality switch. It is the only thing that was missing to see it at size.

   .stage is what goes full screen, not the <video>: the video is
   aria-hidden and tabindex=-1 decoration, and fullscreening the container
   keeps the button reachable inside it.

   :fullscreen and :-webkit-full-screen are SEPARATE rules on purpose. In one
   selector list a pseudo-class the browser does not know invalidates the
   whole list, and the styling would silently do nothing in the other. */
.fsbtn{position:absolute;right:12px;bottom:12px;z-index:5;
  width:38px;height:38px;border-radius:10px;padding:0;cursor:pointer;
  display:grid;place-items:center;color:#fff;opacity:.72;
  background:rgba(10,10,12,.5);border:1px solid rgba(255,255,255,.2);
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
  transition:opacity .16s ease,background .16s ease}
.fsbtn:hover{opacity:1;background:rgba(10,10,12,.8)}
.fsbtn:focus-visible{opacity:1;outline:2px solid var(--mark-text);outline-offset:3px}
.fsi{width:19px;height:19px;display:block;grid-area:1/1}
.fsbtn .fsi.in{display:none}
.fsbtn.is-on .fsi.out{display:none}
.fsbtn.is-on .fsi.in{display:block}

.stage:fullscreen{width:100vw;max-width:none;height:100vh;
  margin:0;border-radius:0;background:#000;display:grid;place-items:center}
.stage:-webkit-full-screen{width:100vw;max-width:none;height:100vh;
  margin:0;border-radius:0;background:#000;display:grid;place-items:center}
.stage:fullscreen video{width:100%;height:100%;aspect-ratio:auto;object-fit:contain}
.stage:-webkit-full-screen video{width:100%;height:100%;aspect-ratio:auto;object-fit:contain}
.stage:fullscreen .fsbtn{right:22px;bottom:22px}
.stage:-webkit-full-screen .fsbtn{right:22px;bottom:22px}

@media(prefers-reduced-motion:reduce){ .fsbtn{transition:none} }
@media(max-width:560px){ .fsbtn{width:34px;height:34px;right:9px;bottom:9px}
  .fsi{width:17px;height:17px} }

/* ── the type scale the owner chose in the font lab ──────────────────────
   Figtree / JetBrains Mono · Sentence 700 -.01em · head 85% body 100% label 115%

   The heading clamps are the page's own, multiplied by .85 — not new numbers,
   so they still scale with the viewport exactly as before. The label sizes are
   the page's own mono sizes at 1.15. Kept here, last in the last sheet, so the
   whole scale is one block to read or revert rather than edits in sixteen
   inline stylesheets.

   Specificity: .lede h1 sets its size through a `font:` SHORTHAND with
   !important, so a bare `h1{font-size}` would lose. Each selector below
   matches the one it has to beat and comes later. */
.lede h1,.fhead h1,.mrow h2{font-weight:700!important;letter-spacing:-.01em!important}
.lede h1{font-size:clamp(27.2px,3.06vw,42.5px)!important}
.fhead h1{font-size:clamp(27.2px,3.4vw,45.9px)!important}
.mrow h2{font-size:clamp(22.1px,2.55vw,34px)!important}

.mrow .eyebrow{font-size:11.5px}
.lede .eyebrow{font-size:12.65px}
.irow .vl{font-size:13.23px}
.shotcap{font-size:12.65px}
.specs span{font-size:11.5px}
.k{font-size:11.5px}
.ptag{font-size:11.5px}
.plate-foot{font-size:11.5px}
.sz,.plat .meta{font-size:12.08px}

/* ── the rest of the mono labels, at the chosen 115% ─────────────────────
   These carry the same job as the ones above — they were simply declared in
   other rules, and leaving them at 10px made the label scale inconsistent. */
.klabel{font-size:11.5px}
.cmp .tag{font-size:11.5px}
.ba figcaption,.bafoot figcaption{font-size:11.5px}
.save{font-size:11.5px}
.nlab{font-size:11.5px}
.pgrid.vvcards .pmeta{font-size:11.5px}
.badots + *,.bacar figcaption{font-size:11.5px}

/* ── phone: hit areas ────────────────────────────────────────────────────
   Measured on a 375px viewport. The hero CTA was a 17px-tall tap target and
   it is the main conversion link on a phone; the carousel dots were 8px. The
   fix is hit AREA, not visible size — nothing here changes how anything
   looks, so the desktop layout that was tuned earlier is untouched.

   44px is the figure Apple and WCAG 2.5.5 both land on. */
@media (max-width:820px){
  .lede .actions .go,.lede .trial a,.plink,.pgrid.vvcards .plink,
  .pnote a,.swapbtn,.dlfoot a,
  /* the sign-in page's own switchers: forgot password, magic link, create
     account — 13px tall, and on the phone they are the whole recovery path */
  .swap button{display:inline-flex;align-items:center;min-height:44px}
  .banav,.fsbtn{width:44px;height:44px}
  .brand{min-height:44px}
  /* Footer columns are a stack of links; 28px rows are legal under WCAG 2.5.8
     but fiddly for a thumb, and they cost nothing to open up.

     display:FLEX, not inline-flex. `footer a{display:block}` is what puts
     these on separate lines, and inline-flex overrode it — the six Navigate
     links collapsed onto one line reading "HomeFeaturesAbout PricingDownload
     Account", because the markup has no separator between them and never
     needed one while they were block. Block-level flex keeps the stack AND
     gives the 40px box. */
  /* ── the footer, three columns instead of one long fall ───────────────
     Stacking every link one per line made the footer the longest thing on
     the page. The three link groups go side by side and the brand keeps the
     full width above them; the type comes down with the columns so the
     labels still fit. Tap targets stay 40px tall — the rows are shorter, not
     the boxes. */
  .fgrid{grid-template-columns:repeat(3,1fr);gap:22px 14px}
  .fbrand{grid-column:1 / -1}
  .fgrid a{display:flex;align-items:center;min-height:40px;font-size:13px}
  .fgrid h4{margin-bottom:6px}
  /* studio@reelskillz.com wants 117px and the column is 107px, so it has to
     wrap. Left to break-word it split as "studio@reelskillz.co / m", which
     reads as a typo. The markup carries a <wbr> after the @, and
     overflow-wrap:break-word (unlike word-break) takes a real break
     opportunity when there is one, so it lands as "studio@ / reelskillz.com"
     and only falls back to mid-word if the column ever gets narrower than
     "reelskillz.com" (78px). */
  .fgrid a[href^="mailto:"]{font-size:12px;overflow-wrap:break-word;line-height:1.35}
  footer span{font-size:10px;letter-spacing:.06em}
  .fbase a{display:inline-flex;align-items:center;min-height:40px}
  /* "Film Pro v1.4.3 · DaVinci Resolve 18+ · macOS & Windows" is 424px of
     tracked mono against 350px of column, so it always takes two lines here.
     Left to itself it broke after "macOS &" and left WINDOWS alone on the
     second. Balanced it splits at a middot into 193 and 223px. Shrinking it
     to fit one line instead would need 9.5px, which is too small to read. */
  .fbase span{text-wrap:balance}
  /* the account dashboard's own controls. Standalone, every one of them —
     the prose links in .accfoot and inside the card copy are left alone on
     purpose: WCAG 2.5.8 exempts a target sitting in a sentence, and growing
     one there breaks the line it lives in. */
  .ncard .nbtn,.ncard .nmore,.who .out{display:inline-flex;align-items:center;
    justify-content:center;min-height:44px}
  /* width:100% already, so flex — inline-flex would shrink-to-fit the label */
  .prod button{display:flex;align-items:center;justify-content:center;min-height:44px}
  /* The dot stays 8px; only what your thumb can hit grows.
     36 WIDE, NOT 44. The dots sit 8px apart on 8px dots — 16px centre to
     centre — so a 44px halo overhangs its neighbour by 28px, and since the
     later sibling paints on top it swallowed the previous dot's own centre.
     Measured with elementFromPoint at each dot's middle: every tap landed on
     the NEXT slide, and only the sixth dot worked at all. A hit area may not
     be wider than the spacing that separates it from the next one, so the
     gap goes to 28px (36px centre to centre) and the halo matches it. Height
     is free — nothing sits above or below — so it keeps the full 44. */
  /* 28px of gap and a 36px halo was the safe answer to the overlap bug but
     it read as six dots scattered across the strip. Pulled in to 24px centre
     to centre — WCAG 2.5.8 AA's 24px minimum exactly, and still no overlap
     because the halo is never wider than that spacing. Height stays 40:
     nothing sits above or below, so the vertical costs nothing. */
  .badots{gap:17px}
  .badot{width:7px;height:7px}
  .badot.is-on{transform:scale(1.35)}
  .badot{position:relative}
  .badot::after{content:"";position:absolute;left:50%;top:50%;
    width:24px;height:40px;transform:translate(-50%,-50%)}

  /* ── the hero eyebrow, on a phone ──────────────────────────────────────
     Two things broke this line. The label scale below sets
     `.lede .eyebrow{font-size:12.65px}` with no media query, at the same
     specificity as the page's own mobile rule and loaded after it, so 11px
     never applied and the eyebrow ran 15% wide at every width. Then ACES was
     added to it, worth another ~66px. At 375px the flex row gave up and broke
     into three pieces: the node glyph orphaned on its own line, the text
     under it, the platform marks under that.

     `display:block` is the fix that survives a narrower phone. As a flex row
     the parts can only break BETWEEN items, which is what stranded the icon;
     as inline flow the whole thing wraps like a sentence and the glyphs stay
     with the words. 10.5px/.08em is then the largest that still holds one
     line at 375px — measured, not guessed — and it is the same trade the
     original mobile rule made when it dropped to 11px/.14em before ACES
     existed. Below 375px it wraps, tidily, instead of falling apart. */
  .lede .eyebrow{display:block;line-height:1.75;
    font-size:10.5px;letter-spacing:.08em}
  .lede .eyebrow .ic.ofx{display:inline-block;vertical-align:-3px;margin-right:8px}
  .lede .eyebrow .lbl{display:inline}
  .lede .eyebrow .osmarks{display:inline-flex;vertical-align:-3px;margin-left:9px}
}

/* Visually hidden, still announced. clip-path over the old clip:rect() and
   NOT display:none / visibility:hidden — both of those remove the node from
   the accessibility tree, which is the opposite of what this is for. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

/* ── phone: let the picture carry the page ─────────────────────────────────
   Measured on a 390px screen before this block: body copy 19px, a card price
   at 44px, product names at 21px — against a before/after image only 163px
   tall. The type was out-shouting the one thing the page is selling, and the
   mono labels wrapped ("apple silicon & intel" over two lines, the carousel
   caption over two) because of TRACKING, not size: .16em on 11.5px is nearly
   2px a character.

   MUST STAY LAST IN THIS FILE. Three of these have to beat rules that already
   carry !important or a heavier selector — `.lede h1` (!important, line ~458),
   `.pgrid.vvcards .pname` (0,3,0 + !important) and `.pgrid.vvcards .amount`
   (0,3,0). They are matched at equal specificity and win on source order, so
   moving this block up the file silently undoes half of it. */
@media (max-width:820px){
  /* 40px of side padding is a fifth of a 390px screen */
  .wrap.specs,.wrap.paths,.wrap.mods,.wrap.price,.wrap.faq{padding:26px 20px}
  .wrap.ba{padding-top:26px;padding-bottom:26px}

  .lede p{font-size:16px;line-height:1.6}
  .lede h1{font-size:25px!important}
  .price h2,.faq h2,.mods h2,.paths h2{font-size:20px}
  .faq dt{font-size:14px}
  .faq dd{font-size:13.5px}
  .trial{font-size:13px}
  .lede .actions .go{font-size:15.5px}
  .specs b{font-size:13.5px}

  .pgrid.vvcards .pname{font-size:17px!important;margin-bottom:9px}
  .pgrid.vvcards .pblurb{font-size:13.5px;margin-bottom:20px;min-height:0}
  .pgrid.vvcards .amount{font-size:32px}
  .pgrid.vvcards .amount s{font-size:15px;margin-left:8px}
  .pgrid.vvcards .pmeta{font-size:10.5px;letter-spacing:.10em;margin-bottom:18px}
  .pgrid.vvcards img.picon{width:96px;margin:2px auto 14px}

  /* the mono labels — tracking is what made these wrap, so it comes down with
     the size rather than instead of it */
  .k .klabel,.specs span,.ba figcaption,.plate-foot,.save,.ptrialline{
    font-size:10.5px;letter-spacing:.10em}
  /* Tracked uppercase mono is the widest possible way to set a sentence —
     10.5px at .08em ran the caption onto two lines. Sans, sentence case, no
     tracking is about 40% narrower at the same nominal size, so it reads
     smaller and fits on one line without dropping to an unreadable px. */
  .ba figcaption{font:400 11px/1.45 var(--sans);letter-spacing:0;
    text-transform:none}

  /* ── the pricing cards on a phone: THE LEDGER ─────────────────────────
     Chosen by the owner on 2026-08-27 from three rendered options.

     The three products stop being separate cards and become one slab —
     hairline dividers, a coloured rail down the left of each row. The eye
     runs one column and compares three numbers instead of re-reading three
     boxes. Measured at 390px: 171 / 172 / 172px, 515px for the list against
     872px before — 41% less scroll, and the only option where all three
     prices fit on one phone screen.

     MUST STAY LAST IN THIS FILE, for the same reason as the block it
     replaces: several of these rules beat .pgrid.vvcards .pname (0,3,0 with
     !important) and .amount (0,3,0) at equal specificity, and equal
     specificity is settled by source order. */


  /* ── the plate ─────────────────────────────────────────────────────────
     The depth that used to live on three separate cards moves to the list
     itself: one lit top edge, one shadow under the whole object. Capped at
     560 and centred so the tablet range keeps a readable line length
     instead of stretching a 46px pill across 700px. */
  .pgrid.vvcards{
    display:block;gap:0;
    max-width:560px;margin-left:auto;margin-right:auto;
    background:var(--panel-2);
    border:1px solid rgba(255,255,255,.13);
    border-radius:16px;overflow:hidden;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.10),
               inset 0 -1px 0 rgba(0,0,0,.30),
               0 2px 4px rgba(0,0,0,.24),
               0 16px 34px rgba(0,0,0,.34)}

  /* ── the row ───────────────────────────────────────────────────────────
     Fixed markup order, rearranged by area: tile column, text column,
     price column — the shape of a store row, not of a card. The tile spans
     the name and the blurb so the text block hangs off it as one object;
     the price hangs at the right of the same two rows, the way a price
     hangs at the right of a menu line. Measured at 390: all three blurbs
     set to exactly two lines in this column, so the rows come out 171, 172
     and 172px — one rhythm, where the three cards were 278, 299 and 260.
     At 360 Skin's blurb takes a third line and that row goes to 190. */
  .pgrid.vvcards .card{
    position:relative;
    display:grid;
    grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-areas:
      "icon  name   price"
      "icon  blurb  price"
      "note  note   note"
      "act   act    act";
    column-gap:12px;row-gap:0;align-content:start;
    text-align:left;
    padding:14px 16px 15px 21px;
    background:transparent;border:0;border-radius:0;box-shadow:none;
    height:auto;transform:none}
  .pgrid.vvcards .card + .card{border-top:1px solid rgba(255,255,255,.085)}
  /* hover sticks after a tap on a phone; the lift belongs to the mouse */
  .pgrid.vvcards .card:hover{transform:none;
    box-shadow:none;background-color:transparent}

  /* the rail — a pseudo-element, so no markup changes. Full bleed top to
     bottom, clipped by the plate's radius at the two ends; 3px here, 4px
     and lit on the lead row below. */
  .pgrid.vvcards .card::before{
    content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
    border-radius:0 2px 2px 0;background:rgba(255,255,255,.26)}

  /* ── which row is which ───────────────────────────────────────────────
     (0,4,0) each, to beat the desktop radial-gradient rules at the same
     specificity on source order.

     The light comes off the RAIL, and it is spent before the text starts.
     That second half is not styling, it is arithmetic: the row sits on
     --panel-2 #3a3a3d, where --mark-text measures 4.83:1 — legal, with
     0.33 to spare. A flat rgba(255,106,26,.15) wash over it lightens the
     ground to rgb(88,65,56) and drops that same orange to 4.02:1, so the
     first, prettier version of this rule made SAVE $77 and About Film Pro
     illegal at 10 and 12.5px. The stops are therefore in PIXELS, not
     percentages: full strength across the 21px the rail and its bloom
     occupy, and down to .04 by the time the first glyph starts —
     padding-left is 21px, and the orange measures 4.60:1 there. The
     non-lead rows are DARKENED rather than lightened, which pushes the lead
     forward and raises every contrast on the two below it (Skin's meta
     5.18, the bundle's 4.98). */
  .pgrid.vvcards .card[data-prod="film-pro"]{
    background:linear-gradient(90deg,rgba(255,106,26,.13) 0px,rgba(255,106,26,.04) 21px,
                                     rgba(255,106,26,.012) 45%,transparent 72%)}
  .pgrid.vvcards .card[data-prod="film-pro"]::before{
    width:4px;background:linear-gradient(180deg,#ffa168,var(--mark) 55%,#d9510c);
    box-shadow:0 0 10px rgba(255,106,26,.42)}
  .pgrid.vvcards .card[data-prod="skin"]{
    background:linear-gradient(90deg,rgba(255,79,69,.12) 0px,rgba(255,79,69,.038) 21px,
                                     rgba(255,79,69,.010) 45%,transparent 72%),
               rgba(0,0,0,.10)}
  .pgrid.vvcards .card[data-prod="skin"]::before{
    background:linear-gradient(180deg,#ff8b83,var(--mark-2) 55%,#cf332a);
    box-shadow:0 0 10px rgba(255,79,69,.34)}
  .pgrid.vvcards .card[data-prod="bundle"]{
    background:linear-gradient(90deg,rgba(255,255,255,.06) 0px,rgba(255,255,255,.018) 21px,
                                     transparent 62%),
               rgba(0,0,0,.10)}
  .pgrid.vvcards .card[data-prod="bundle"]::before{
    background:linear-gradient(180deg,rgba(255,255,255,.62),rgba(255,255,255,.24))}

  /* ── the tile ─────────────────────────────────────────────────────────
     181x81 natural. Width is set, height is auto and aspect-ratio backs it
     up, so it can never be squared off. clamp() is what carries this from
     320 to 820 without a second breakpoint. */
  .pgrid.vvcards img.picon{
    grid-area:icon;align-self:start;justify-self:start;margin-top:2px;
    width:clamp(56px,16.5vw,72px);height:auto;aspect-ratio:181/81;
    object-fit:contain;
    filter:drop-shadow(0 1px 2px rgba(0,0,0,.45))
           drop-shadow(0 6px 14px rgba(0,0,0,.42))}

  /* ── name ─────────────────────────────────────────────────────────────
     600, not 400: at 15.5px on a row this is the label you scan, and the
     light weight the desktop card uses at 21px goes soft down here. */
  .pgrid.vvcards .pname{
    grid-area:name;align-self:start;justify-self:start;margin:0;
    font:600 15.5px/1.2 var(--sans)!important;
    letter-spacing:-.005em!important;text-transform:none!important;
    color:#fff;text-wrap:balance}

  /* ── blurb ────────────────────────────────────────────────────────────
     --ink-soft, not --ink-dim: .56 white at 12.5px is 4.4:1 on this panel
     and this is the line that does the selling. .74 measures 7.1:1. */
  .pgrid.vvcards .pblurb{
    grid-area:blurb;margin:4px 0 0;max-width:none;min-height:0;
    display:block;text-align:left;text-wrap:pretty;
    font:400 12.5px/1.42 var(--sans);color:var(--ink-soft)}

  /* ── price — the loudest thing on the row ─────────────────────────────
     .amount becomes a right-aligned column so the old price sits UNDER the
     new one rather than beside it: it reads as a price tag, and it hands
     ~34px of width back to the name and the blurb. The whitespace text
     node between <b> and <s> makes no anonymous item — flex drops
     white-space-only runs — so the stack is exactly two lines.
     font-weight and letter-spacing carry !important because
     `.amount{font-weight:300!important}` (0,1,0) would otherwise win on
     importance no matter how specific this selector is; <b> needs its own
     rule because the UA sheet's b{font-weight:bolder} applies to the
     element itself and beats an inherited 300. */
  .pgrid.vvcards .amount{
    grid-area:price;align-self:start;justify-self:end;
    display:flex;flex-direction:column;align-items:flex-end;
    margin:-2px 0 0;padding:0;text-align:right;color:#fff;
    font:300 32px/.92 var(--sans);
    font-weight:300!important;letter-spacing:-.032em!important}
  .pgrid.vvcards .amount b{
    font:inherit;font-weight:300;letter-spacing:inherit;color:#fff;display:block}
  .pgrid.vvcards .amount s{
    display:block;margin:7px 0 0;font:400 13px/1 var(--sans);
    letter-spacing:0;color:rgba(255,255,255,.60);
    text-decoration-color:rgba(255,255,255,.46);text-decoration-thickness:1px}
  /* the lead's number is physically bigger — the one piece of hierarchy a
     list this flat still has room for */
  .pgrid.vvcards .card[data-prod="film-pro"] .amount{font-size:36px}

  /* ── the spec line ────────────────────────────────────────────────────
     Two micro-labels sharing one grid cell, one pinned left and one right:
     terms on the left, the risk-reducer on the right. Both mono, both
     uppercase, both 10px — measured, the pair leaves 96px of clear space
     between them at 390, 42px at 360 and 11px at 320, and neither is
     nowrap, so the worst case on a narrower screen is a wrap, never an
     overflow. Orange marks the two rows that carry a saving. */
  .pgrid.vvcards .pmeta{
    grid-area:note;justify-self:start;align-self:center;
    margin:11px 0 0;max-width:56%;
    font:500 10px/1.4 var(--mono);letter-spacing:.075em;
    text-transform:uppercase;color:rgba(255,255,255,.58)}
  .pgrid.vvcards .card[data-prod="film-pro"] .pmeta,
  .pgrid.vvcards .card[data-prod="bundle"] .pmeta{color:var(--mark-text)}
  .pgrid.vvcards .ptrialline{
    grid-area:note;justify-self:end;align-self:center;
    margin:11px 0 0;max-width:42%;text-align:right;
    font:400 10px/1.4 var(--mono);letter-spacing:.05em;
    text-transform:uppercase;color:rgba(255,255,255,.62)}
  /* the two (0,4,0) rules that reserve a missing About link's space on the
     desktop card — they outrank the rule above, so they are answered here */
  .pgrid.vvcards .card[data-prod="bundle"] .ptrialline,
  .pgrid.vvcards .card:not(:has(.plink)) .ptrialline{margin:11px 0 0}

  /* ── the action line ──────────────────────────────────────────────────
     Pill left, About right, in ONE cell — so the three CTAs line up down
     the list and the row costs 59px instead of two stacked bands. The two
     hit areas are separated HORIZONTALLY — 72px of clear space at 390,
     42px at 360, 7px at 320 — which is what keeps a 46px and a 44px target
     from touching; verified with elementFromPoint on a 6x4 grid of points
     inside every control, not with getBoundingClientRect. The max-widths
     are the floor that stops the two ever meeting on a narrower screen.
     padding/font/radius carry !important because the `.buy,a.buy` block
     sets all three that way. */
  .pgrid.vvcards .buy,
  .pgrid.vvcards .ghost{
    grid-area:act;justify-self:start;align-self:center;
    margin:13px 0 0;width:auto;min-width:130px;max-width:55%;
    display:inline-flex;align-items:center;justify-content:center;
    white-space:nowrap;
    min-height:46px;padding:0 15px!important;
    font:600 14px/1 var(--sans)!important;letter-spacing:0!important;
    border-radius:12px!important}
  /* the markup is `Get Film Pro<span class="arw">&rarr;</span>` — no space
     between them, so the gap has to come from CSS */
  .pgrid.vvcards .buy .arw{display:inline-block;margin-left:7px}
  /* Skin's button wears Skin's colour — the outline is tinted, the fill
     stays dark, so it still reads as the quieter of the three */
  .pgrid.vvcards .card[data-prod="skin"] .ghost{
    background:linear-gradient(180deg,rgba(255,79,69,.17),rgba(255,79,69,.05));
    border-color:rgba(255,79,69,.46)}

  .pgrid.vvcards .plink{
    grid-area:act;justify-self:end;align-self:center;
    margin:13px 0 0;max-width:42%;padding-left:10px;
    display:inline-flex;align-items:center;justify-content:flex-end;
    min-height:44px;
    font:500 12.5px/1.25 var(--sans);letter-spacing:0;
    color:var(--mark-text);text-decoration:none}

  /* ── and the spacing, which was the louder half of the problem ──────────
     Sizes came down first and the page still read as airy, because what was
     actually wrong was the rhythm: 48px above the headline, a 1.75 eyebrow,
     body at 1.6, then 20 / 18 / 28 / 20 of margin stacked underneath it. On a
     390px screen that pushed the carousel a whole screen down. Measured: the
     hero block was 458px tall and is now 390px — 15% back, and the picture
     reaches the first screen. */
  .lede{padding-top:26px}
  .lede .eyebrow{line-height:1.45;margin-bottom:12px}
  .lede h1{margin-bottom:10px}
  .lede p{line-height:1.5;margin-bottom:18px}
  .lede .actions{gap:12px}
  .lede .trial{margin-top:14px}
  .plate-foot{padding-top:10px;line-height:1.35;gap:2px 0}
  .wrap.ba .k{margin-bottom:12px}
  .bafoot{margin-top:8px;gap:8px}
  .faq dd{line-height:1.5}
  .faq div{padding-top:12px;margin-bottom:10px}
  .wrap.specs,.wrap.paths,.wrap.mods,.wrap.price,.wrap.faq,.wrap.ba{
    margin-top:20px;margin-bottom:20px}
}


/* ── the ACES chip, inside the node graph ─────────────────────────────────
   It used to sit under the paragraph as a separate pill. Moved into .ngraph so
   the mark and the node it describes are one object.

   Two things were wrong with the first attempt at that, and both are fixed
   here. The chip wore a bordered capsule — a box inside the card's own box —
   and it was positioned absolutely over a row that reserved space for it with
   padding-left. Absolute plus a fixed reservation cannot hold: .ngraph centres
   its row, so padding-left only buys half of what it costs, and the shortfall
   grows as the card narrows. Measured at 1280px the capsule's right edge was
   2.9px past the node's first wire dot; at 940px, where the two-column grid is
   at its tightest, it was 21.4px in.

   So the chip is now an ordinary flex item at the head of the row (order:-1,
   it is last in the DOM). Overlap is then impossible by construction, and the
   card's min-content width becomes 395px against the three-node card's 392 —
   the grid already grows its columns to min-content, so the two cards stay the
   same size and nothing new overflows. */
.ngraph .aceschip{order:-1;flex:0 0 auto;align-self:center;
  margin:0 36px 0 0;padding:0;gap:8px}
.ngraph .acesmark{width:64px}
.ngraph .aceschip span{font-size:9.5px;letter-spacing:.08em}

@media (max-width:820px){
  /* on a phone the column is ~350px and the row would have to scroll, so the
     chip goes under the node instead — the one case where taking it out of
     flow is right. 40px, not the 52px the capsule needed: without its 7px of
     vertical padding and its border the chip is 23px tall, not 39px. */
  .ngraph:has(.aceschip){position:relative;padding-bottom:40px}
  .ngraph .aceschip{position:absolute;left:50%;bottom:8px;
    transform:translateX(-50%);margin:0}
}
