/* ═══════════════════════════════════════════════════════════════════
   RunStaff — Industrial Panel
   Warm workshop ground · embossed plates · safety-signal colour

   CONSOLIDATED. This sheet was rewritten in one pass to end an
   accretion problem: repeated rounds had left duplicate blocks,
   dead rules for removed components, and specificity hacks
   (.wtile.wtile--live) written only to out-rank an earlier rule.
   Order below is now the cascade strategy — tokens, base, layout,
   components, sections, motion, responsive, preferences — so a
   modifier can simply follow its base and win without doubling.
   ═══════════════════════════════════════════════════════════════════ */

/* ── 0. FONTS ───────────────────────────────────────────────────
   Self-hosted, and subset by tools/build-fonts.py to the 106
   characters index.html actually uses.

   Both families came from Google Fonts until 25 Aug 2026. That cost
   two extra origins, two DNS lookups and two TLS handshakes on the
   critical path, behind a render-blocking stylesheet the browser had
   to fetch and parse before it could even DISCOVER the font files.
   Serving them from our own origin collapses that to zero extra
   connections and lets the <head> preload them directly.

   Self-hosting the stock files would NOT have been a byte win —
   Google's five latin-subset files are 132 kB against roughly 108 kB
   served, because Google's "latin" subset carries every accented
   character in the block and this page is UK English. Subsetting is
   what turns it into one: 122 kB -> 54 kB.

   The trade subsetting makes is real, so it is guarded rather than
   trusted: `python tools/build-fonts.py --check` re-derives the
   page's character set and exits non-zero if any face has lost a
   glyph the copy now needs. Run it after any copy change. Without
   that, a character added later renders from the fallback — Arial
   Narrow standing in for Big Shoulders, mid-heading.

   Big Shoulders is a VARIABLE font: one file serves 700, 800 and 900
   through the wght axis, which is why it is a range here and why
   build-fonts.py deliberately passes no axis-pinning option. */
@font-face{
  font-family:'Big Shoulders Display';
  src:url('assets/fonts/bigshoulders-var.b2b6586d.woff2') format('woff2-variations'),
      url('assets/fonts/bigshoulders-var.b2b6586d.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Barlow'; src:url('assets/fonts/barlow-400.88167f07.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Barlow'; src:url('assets/fonts/barlow-500.714bd2ed.woff2') format('woff2');
  font-weight:500; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Barlow'; src:url('assets/fonts/barlow-600.2560082a.woff2') format('woff2');
  font-weight:600; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Barlow'; src:url('assets/fonts/barlow-700.7c70c144.woff2') format('woff2');
  font-weight:700; font-style:normal; font-display:swap;
}


/* ── 1. TOKENS ─────────────────────────────────────────────────── */

:root{
  /* ground + material: warm canvas, deliberately not cream, which
     is the AI-default palette the previous site landed on */
  --steel:      #c9d9c2;   /* page ground        */
  --steel-tint: #b7caaf;   /* alternating band   */
  --panel:      #dbe8d5;   /* raised plate face  */
  --panel-hi:   #e8f1e4;
  --ink-deep:   #243026;   /* dark section ground*/
  --sd:         #9db096;   /* shadow, dark side  */
  --sl:         #f7fdf4;   /* shadow, light side */

  /* ink */
  --ink:        #18211a;
  /* Both muted tones are set by MEASUREMENT, not by eye: each must clear
     4.5:1 against the worst ground it actually lands on (--steel-tint's
     dark stop #92ab8b for light sections, --plate-face-d's #425442 for
     dark). The previous pair passed on steel, was never re-checked after
     two ground changes, and shipped failing. tools/contrast-audit.js
     now enforces this on the rendered page every build. */
  --muted:      #313a31;   /* 4.73 on #92ab8b, 6.13 on #adc0ab */
  --muted-dark: #b6caaf;   /* 4.68 on #425442, 5.46 on #3b493d */

  /* brand signal */
  --orange:      #d9600f;  /* lamps, rules, marks       */
  --orange-btn:  #a8490a;  /* button ground (AA on #fff)*/
  --orange-ink:  #8c3d07;  /* small text on a plate     */
  /* Accent text that lands on the raw ground rather than on a plate:
     --orange-ink measures 3.91 there and fails. Set the same way --muted
     is, against the worst light ground the page actually has. */
  --orange-deep: #5f2704;  /* 4.73 on #92ab8b, 6.13 on #adc0ab */
  --green:       #3f5834;
  /* The green twin of --orange-deep, and set the same way: --green
     measures 3.17 on --steel-tint's dark stop and 4.10 on the light
     ground, so it fails anywhere it lands off a plate. Opening an
     accordion tile does exactly that to its gain line. */
  --green-deep:  #2c3d23;  /* 4.68 on #92ab8b, 6.06 on #adc0ab */
  --green-led:   #5f8248;

  /* On-dark and on-orange variants. These existed as 26 loose hex
     literals scattered through the stylesheet until 25 Aug 2026 — the
     one real gap in a system that otherwise runs 68 properties and 400+
     var() uses. It is the worst place to have a gap: they are precisely
     the values a palette change will NOT carry, because nothing links
     them to the tokens they are variants of. The measured notes are the
     reason each one is the value it is, not a rounder neighbour. */
  --orange-on-dark:    #f0a35c;  /* accent text/icons on --sec-dark    */
  --orange-on-dark-lo: #f5b070;  /* hover + diagram strokes on dark    */
  --peach-on-orange:   #ffdcb8;  /* accent text on the --orange-btn band */
  --peach-on-orange-hi:#ffe7cd;  /* NOT the peach above: on the saving
                                    pill's deeper ground that measured
                                    short, this is the one that passes  */
  --cream-on-orange:   #ffeeda;  /* #ffdcb8 measured 4.47 on
                                    --orange-btn — under AA by 0.03    */
  --ink-on-orange:     #2a1c0c;  /* dark text ON an orange ground      */

  /* Signal colours: workplace-signage logic, not variety. Each
     says what KIND of thing an item is, so hue carries meaning
     and stays consistent across every section. */
  --sig-live: #c2540c;     /* needs you now            */
  --sig-ok:   #1d6d38;     /* confirmed, signed off    */
  --sig-info: #1e5f80;     /* visibility, reporting    */
  --sig-time: #8a6516;     /* scheduling, clock        */
  --sig-live-bg: rgba(194,84,12,.13);
  --sig-ok-bg:   rgba(29,109,56,.15);
  --sig-info-bg: rgba(30,95,128,.15);
  --sig-time-bg: rgba(138,101,22,.14);
  /* lifted for legibility on dark grounds */
  --sig-live-d: #f0904a;
  --sig-ok-d:   #6cd08d;
  --sig-info-d: #6eb7d8;
  --sig-time-d: #d9ab52;

  /* system */
  --r:     14px;
  --r-sm:  9px;
  --wrap:  1200px;
  --ease:  cubic-bezier(.2,.7,.3,1);

  /* A machined plate reads by three things at once: it sits lighter
     than its ground, it catches light on the top edge, and it drops
     a contact shadow underneath. Shadow alone was not enough once
     the ground gained texture — measured 1.12 ground-to-panel, below
     the ~1.15 where an edge is visible at all. */
  --ground:      linear-gradient(168deg,#cfdec8,#b8cbb0);
  --ground-tint: linear-gradient(168deg,#c2d3ba,#aabfa1);
  --ground-dark: linear-gradient(168deg,#2c3b2e,#223026);
  --ground-warm: rgba(247,253,244,.9);
  --rule:        rgba(45,85,45,.10);
  --nav-bg:      rgba(34,48,38,.96);      /* dark control strip   */
  --nav-border:  rgba(255,255,255,.14);
  --nav-ink:     #e6f0e4;                 /* nav text             */
  --nav-muted:   #9db396;
  --plate-face: linear-gradient(160deg,#eef7ea,#d8e6d1);
  --edge-lit:   inset 0 1px 0 rgba(255,255,255,.95);
  --edge-dark:  inset 0 -1px 0 rgba(80,110,80,.34);

  --raise:    var(--edge-lit), var(--edge-dark),
              8px 8px 17px var(--sd), -7px -7px 15px var(--sl);
  --raise-lo: var(--edge-lit), var(--edge-dark),
              4px 4px 10px var(--sd), -4px -4px 9px var(--sl);
  --raise-hi: var(--edge-lit), var(--edge-dark),
              13px 13px 30px var(--sd), -11px -11px 26px var(--sl);

  /* On a near-black ground neumorphism cannot work — a dark shadow
     on dark is invisible. Dark plates use a rim light plus a real
     drop shadow instead, which is how a panel actually reads in a
     dim room. */
  --plate-face-d: linear-gradient(160deg,#425442,#374839);
  --raise-d:  inset 0 1px 0 rgba(255,247,230,.13),
              inset 0 -1px 0 rgba(0,0,0,.45),
              0 12px 26px rgba(0,0,0,.55);
  --raise-d-lo: inset 0 1px 0 rgba(255,247,230,.11),
              inset 0 -1px 0 rgba(0,0,0,.4),
              0 7px 16px rgba(0,0,0,.45);
  --sink:     inset 0 1px 0 rgba(140,128,106,.35), inset 5px 5px 11px var(--sd), inset -4px -4px 9px var(--sl);
  --sink-lo:  inset 2px 2px 5px var(--sd), inset -2px -2px 5px var(--sl);

  /* Material backgrounds. Deliberately NOT product screenshots:
     app screens behind copy about those same screens read as
     noise, and it spends the real screenshots twice. Texture and
     drawing-grid instead — the world's own materials. */
  --grain: url("assets/media/texture/grain-soft.png");
  --perf:  url("assets/media/texture/perf.png");
}


/* ── 2. BASE ───────────────────────────────────────────────────── */

*,*::before,*::after{ box-sizing:border-box; }

html{ scroll-behavior:smooth; scroll-padding-top:84px; }

body{
  margin:0;
  color:var(--ink);
  font:400 16px/1.6 'Barlow', ui-sans-serif, system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  background:
    var(--grain),
    /* drafting grid, faint — technical paper, not graph paper */
    repeating-linear-gradient(0deg,  var(--rule) 0 1px, transparent 1px 46px),
    repeating-linear-gradient(90deg, var(--rule) 0 1px, transparent 1px 46px),
    radial-gradient(130% 90% at 50% 0%, var(--ground-warm), transparent 64%),
    var(--ground);
  background-attachment:fixed, fixed, fixed, fixed, fixed;
}

img,video{ max-width:100%; display:block; }
/* <picture> is a wrapper for format negotiation and must never become a box.
   Three rules here size the img against its PARENT — .run__shot img is
   height:100% inside the absolutely-inset figure, .fthumb img likewise — and
   an inline <picture> in between would resolve those percentages against the
   wrapper instead, collapsing the phone frames to nothing. display:contents
   removes it from the box tree entirely, so every existing selector and every
   percentage keeps resolving exactly as it did before the AVIF sources were
   added. It carries no semantics of its own, so nothing is lost to a11y. */
picture{ display:contents; }

h1,h2,h3{
  font-family:'Big Shoulders Display', 'Barlow', sans-serif;
  text-transform:uppercase;
  font-weight:800;
  line-height:1;
  letter-spacing:.006em;
  margin:0;
  text-wrap:balance;
}

p{ margin:0; }
ul,ol{ margin:0; padding:0; list-style:none; }
a{ color:inherit; }

:focus-visible{
  outline:3px solid var(--orange-btn);
  outline-offset:3px;
  border-radius:4px;
}

.sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Hidden by clipping, not by left:-9999px. The old technique works, but
   it was the one element that showed up in an overflow scan, and in an
   RTL context it places content off the wrong edge. clip-path leaves the
   element at its natural position and simply paints nothing. */
.skip{
  position:absolute; left:12px; top:12px; z-index:100;
  clip-path:inset(50%); 
  background:var(--ink); color:var(--panel);
  padding:12px 20px; font-weight:700; text-decoration:none;
}
.skip:focus{ clip-path:none; }


/* ── 3. LAYOUT ─────────────────────────────────────────────────── */

.wrap{
  max-width:var(--wrap); margin-inline:auto; width:100%;
  padding-inline:clamp(20px,4vw,48px);
}
.wrap--narrow{ max-width:760px; }
.wrap--mid{ max-width:900px; }

.sec{ padding:clamp(64px,8vw,112px) 0; position:relative; }
/* no section may widen the page; clip (not hidden) so position:sticky
   inside a section would still work */
.sec, .punch, .cta, .hero{ overflow-x:clip; }

.sec--tint{
  background:
    var(--grain),
    repeating-linear-gradient(90deg, var(--rule) 0 1px, transparent 1px 46px),
    var(--ground-tint);
  box-shadow:inset 0 1px 0 rgba(255,253,247,.6),
             inset 0 -1px 0 rgba(150,138,116,.35);
}

.sec--dark{
  background:
    var(--perf),
    linear-gradient(115deg, rgba(255,255,255,.045) 0%, transparent 38%, rgba(255,255,255,.03) 72%, transparent 100%),
    var(--ground-dark);
  color:var(--panel);
}

/* kept as a hook so a section can still carry an accent field;
   no longer loads product screenshots */
.sec--bg{ position:relative; overflow:hidden; isolation:isolate; }


/* ── 4. SHARED TYPE ────────────────────────────────────────────── */

/* Section kicker — a stamped label, not a caption. It was 12px
   --orange-ink sitting directly on the ground, which measured 3.02–3.92:1
   and read as a footnote above a 46px heading. As a filled pill it is the
   same object in every section, carries its own contrast (#fff on
   --orange-btn = 5.8:1) and stops depending on whatever ground it lands on. */
.kicker{
  font:700 13px/1 'Barlow',sans-serif;
  text-transform:uppercase; letter-spacing:.13em;
  color:#fff; background:var(--orange-btn);
  display:inline-flex; align-items:center; gap:8px;
  padding:6px 12px 6px 10px; border-radius:999px;
  margin:0 0 18px;
}
.kicker::before{
  content:""; width:7px; height:7px; border-radius:50%;
  background:var(--peach-on-orange); flex:none;
}
/* dark sections get the same pill — it no longer needs a ground-specific tone */
.kicker--dark{ color:#fff; }
.kicker--dark::before{ background:var(--peach-on-orange); }

.h2{ font-size:clamp(30px,3.6vw,46px); }
.h2--big{ font-size:clamp(34px,5vw,66px); line-height:.98; }

.accent{ color:var(--orange-ink); }
.sec--dark .accent{ color:var(--orange-on-dark); }
.cta .accent{ color:var(--peach-on-orange); }

.sec__head{ max-width:760px; margin-bottom:clamp(36px,4.5vw,56px); }
.sec__head--center{ margin-inline:auto; text-align:center; }
.sec__head--center .kicker{ justify-content:center; }
.sec__head--dark{ max-width:820px; }
.sec__lede{ font-size:clamp(16px,1.5vw,18.5px); color:var(--muted); margin-top:18px; line-height:1.6; }
.sec__lede--center{ margin-inline:auto; }
.sec--dark .sec__lede{ color:var(--muted-dark); }

/* bullets — the page's main reading unit */
.bul li{
  position:relative; padding-left:20px; font-size:16px;
  color:var(--muted); margin-bottom:7px; line-height:1.45;
}
.bul li::before{
  content:""; position:absolute; left:0; top:8px;
  width:7px; height:7px; background:var(--orange);
  clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%);
}
.bul li b{ color:var(--ink); font-weight:600; }
.sec--dark .bul li{ color:var(--muted-dark); }
.sec--dark .bul li b{ color:var(--panel); }

.ticks li{
  position:relative; padding-left:26px; font-size:14px;
  color:var(--muted); margin-bottom:10px; line-height:1.5;
}
.ticks li::before{
  content:""; position:absolute; left:0; top:7px;
  width:12px; height:7px;
  border-left:2.5px solid var(--green-led);
  border-bottom:2.5px solid var(--green-led);
  transform:rotate(-45deg);
}


/* ── 5. CONTROLS ───────────────────────────────────────────────── */

.btn{
  display:inline-flex; align-items:center; justify-content:center;
  font:700 13.5px/1 'Barlow',sans-serif;
  text-transform:uppercase; letter-spacing:.05em;
  padding:16px 26px; border:0; border-radius:var(--r-sm);
  text-decoration:none; cursor:pointer;
  transition:transform .18s var(--ease), box-shadow .18s var(--ease);
}
.btn--primary{
  background:var(--orange-btn); color:#fff;
  box-shadow:5px 5px 13px rgba(140,60,8,.34), -4px -4px 11px rgba(255,255,255,.55);
}
.btn--primary:hover{ transform:translateY(-2px); box-shadow:7px 8px 18px rgba(140,60,8,.4), -4px -4px 11px rgba(255,255,255,.6); }
.btn--primary:active{ transform:translateY(1px); box-shadow:inset 3px 3px 7px rgba(90,38,4,.45); }

.btn--inset{ background:var(--panel); color:var(--ink); box-shadow:var(--sink-lo); }
.btn--inset:hover{ box-shadow:var(--raise-lo); }

.btn--ghost{
  background:var(--orange-btn); color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 4px 12px rgba(0,0,0,.35);
  padding:12px 20px; font-size:12.5px;
}
.btn--ghost:hover{ transform:translateY(-1px); }

.btn--onorange{
  background:var(--panel-hi); color:var(--orange-ink);
  box-shadow:0 8px 20px rgba(80,32,4,.28);
  font-size:14.5px; padding:18px 32px;
}
.btn--onorange:hover{ transform:translateY(-2px); }

.actions{ display:flex; flex-wrap:wrap; gap:14px; }

/* Contact us is a text link, not a filled button, everywhere it appears.
   Two buttons side by side would put the quick question and the booked
   demo at equal weight; the hierarchy is the whole point of having two. */
.linkbtn{
  background:none; border:0; padding:2px 0; margin:0; cursor:pointer;
  font:600 15px/1.4 'Barlow',sans-serif; color:var(--orange-deep);
  text-decoration:underline; text-underline-offset:3px;
  text-decoration-thickness:1.5px;
}
.linkbtn:hover{ color:var(--ink); }
.aside{
  margin-top:14px; font-size:15px; color:var(--muted);
  display:flex; align-items:center; gap:7px; flex-wrap:wrap;
  min-height:26px;
}

/* One weight below the filled button and one above a text link: the
   question path is a real choice, so it gets a real control — outlined,
   so it still yields to the demo button standing next to it. The border
   is currentColor, so each ground only has to name a text colour. */
.btn--line{
  background:transparent; color:var(--ink);
  box-shadow:inset 0 0 0 1.6px currentColor;
}
.btn--line:hover{ transform:translateY(-2px); }
.btn--line:active{ transform:translateY(1px); }
.btn--line-dark{ color:var(--nav-ink); }
.btn--line-dark:hover{ color:#fff; }
.btn--line-onorange{ color:#fff; }
.btn--line-onorange:hover{ color:var(--peach-on-orange); }

/* indicator lamps */
.led{
  width:10px; height:10px; border-radius:50%; flex:none;
  background:#cdc4b2; box-shadow:inset 1px 1px 2px var(--sd);
  display:inline-block;
}
.led--live{ background:var(--orange); box-shadow:0 0 9px rgba(217,96,15,.85); }
.led--off{ background:#cdc4b2; box-shadow:inset 1px 1px 2px var(--sd); }

/* stamped plate marks holding an icon.
   Modifiers follow the base, so no doubled selector is needed. */
.ico{
  width:22px; height:22px; flex:none; display:block;
  stroke:currentColor; stroke-width:2; fill:none;
  stroke-linecap:square; stroke-linejoin:miter;
}
.ico--lg{ width:28px; height:28px; }

.plate{
  width:46px; height:46px; border-radius:11px; flex:none;
  display:grid; place-items:center; color:var(--orange-ink);
  background:var(--panel); box-shadow:var(--sink-lo);
}
.plate--sm{ width:36px; height:36px; border-radius:9px; }
.plate--live{ color:var(--sig-live); background:var(--sig-live-bg); }
.plate--ok  { color:var(--sig-ok);   background:var(--sig-ok-bg); }
.plate--info{ color:var(--sig-info); background:var(--sig-info-bg); }
.plate--time{ color:var(--sig-time); background:var(--sig-time-bg); }

.sec--dark .plate{
  background:#3b352b; color:var(--orange-on-dark-lo);
  box-shadow:inset 2px 2px 5px #2a251d, inset -2px -2px 5px #4b4437;
}
.sec--dark .plate--live{ color:var(--sig-live-d); background:rgba(240,144,74,.15); }
.sec--dark .plate--ok  { color:var(--sig-ok-d);   background:rgba(143,189,118,.15); }
.sec--dark .plate--info{ color:var(--sig-info-d); background:rgba(121,170,193,.15); }
.sec--dark .plate--time{ color:var(--sig-time-d); background:rgba(217,171,82,.15); }


/* ── 6. NAV ────────────────────────────────────────────────────── */

.nav{
  position:sticky; top:0; z-index:50;
  background:var(--nav-bg);
  backdrop-filter:saturate(1.4) blur(10px);
  border-bottom:1px solid var(--nav-border);
}
.nav__in{
  max-width:var(--wrap); margin-inline:auto;
  padding:14px clamp(20px,4vw,48px);
  display:flex; align-items:center; gap:22px;
}
/* RunStaff, not RUNSTAFF. PRODUCT.md pins the name as capitalised in
   copy — the internal S is a brand signal, and text-transform was
   throwing it away on the one element that carries the name. Bigger
   too: at 23px it sat level with the nav links it should outrank. */
.brand{
  display:flex; align-items:center; gap:11px; color:var(--nav-ink);
  font-family:'Big Shoulders Display',sans-serif;
  font-weight:800; font-size:29px; text-transform:none;
  letter-spacing:.004em; text-decoration:none; flex:none;
}
.brand__mark{ width:25px; height:25px; flex:none; }
.brand--foot{ color:var(--panel); font-size:25px; }

/* The bar is 1104px wide at every desktop width — --wrap caps it — so its
   space is fixed and any new item has to be paid for by an old one. The two
   CTAs were paid for by the sign-in item, which the product does not have
   anyway: a personal link is everyone's login. */
.nav__links{ display:flex; gap:18px; margin-left:auto; position:relative; }
.nav__links a{ white-space:nowrap; }
.nav__links a{
  font:600 12.5px/1 'Barlow',sans-serif;
  text-transform:uppercase; letter-spacing:.05em;
  color:var(--nav-muted); text-decoration:none;
  display:inline-flex; align-items:center; justify-content:center;
  min-height:26px; min-width:26px; padding:6px 0;
  border-bottom:2px solid transparent;
  transition:color .16s, border-color .16s;
}
.nav__links a:hover{ color:var(--nav-ink); border-bottom-color:var(--orange); }
.nav__links a[aria-current="true"]{ color:var(--nav-ink); }
.nav__cta{ flex:none; }
.nav__ask{ flex:none; margin-left:auto; padding:12px 14px; font-size:12.5px; }

/* Driven by transform, not left/width: animating layout properties forces a
   reflow on every frame of the scroll-spy slide. Base width is 1px and JS
   scales it, so translateX + scaleX stay on the compositor. */
.nav__ind{
  position:absolute; bottom:-1px; left:0; width:1px; height:2px;
  background:var(--orange); border-radius:2px; opacity:0;
  transform:scaleX(0); transform-origin:left center;
  transition:transform .34s var(--ease), opacity .22s;
  pointer-events:none;
}

/* mobile menu — native <details>, works with JS off */
.mnav{ display:none; position:relative; flex:none; }
.mnav summary{
  list-style:none; cursor:pointer;
  width:42px; height:42px; border-radius:var(--r-sm);
  background:rgba(255,247,230,.10); box-shadow:inset 0 0 0 1px rgba(255,247,230,.18);
  display:grid; place-items:center;
}
.mnav summary::-webkit-details-marker{ display:none; }
.mnav__bars,
.mnav__bars::before,
.mnav__bars::after{
  content:""; display:block; width:17px; height:2px;
  background:var(--nav-ink); border-radius:2px;
}
.mnav__bars{ position:relative; }
.mnav__bars::before{ position:absolute; top:-6px; }
.mnav__bars::after{ position:absolute; top:6px; }
.mnav[open] summary{ box-shadow:var(--sink-lo); }
.mnav__panel{
  position:absolute; right:0; top:calc(100% + 10px);
  background:var(--panel); border-radius:var(--r);
  box-shadow:var(--raise-hi); padding:8px; min-width:216px;
  display:flex; flex-direction:column;
}
.mnav__panel a{
  font:600 13px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.05em; color:var(--muted); text-decoration:none;
  padding:13px 14px; border-radius:7px; min-height:26px;
  display:flex; align-items:center;
}
.mnav__panel a:hover{ background:var(--steel); color:var(--ink); }
.mnav__ask{
  font:700 13px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.05em; color:var(--orange-deep); text-align:left;
  background:none; border:0; cursor:pointer;
  padding:13px 14px; border-radius:7px; min-height:26px;
  margin-top:4px; border-top:1px solid var(--rule);
}
.mnav__ask:hover{ background:var(--steel); }


/* ── 7. HERO ───────────────────────────────────────────────────── */

/* Badge on its own full-width row, then a two-column split, then four
   tiles across the full width beneath it. No product screen lives up
   here any more: the cover story the hero used to carry on its right
   now has its own section directly below, where it can be read as one
   story instead of competing with the question. */
.hero{ padding:clamp(56px,7vw,104px) 0 clamp(64px,7.6vw,100px); position:relative; overflow:hidden; }

/* a drafting-board field, not a screenshot: the hero reads as material
   without competing with what sits on top of it. The warm lamp moved
   left and up with the strapline it now sits behind. */
.hero::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background:
    repeating-linear-gradient(0deg,  rgba(120,108,88,.10) 0 1px, transparent 1px 92px),
    repeating-linear-gradient(90deg, rgba(120,108,88,.10) 0 1px, transparent 1px 92px),
    radial-gradient(64% 46% at 72% 24%, rgba(217,96,15,.11), transparent 64%),
    radial-gradient(60% 60% at 12% 8%, rgba(255,253,247,.75), transparent 70%);
}
.hero > *{ position:relative; z-index:2; }

.hero__in{
  max-width:var(--wrap); margin-inline:auto; width:100%;
  padding-inline:clamp(20px,4vw,48px);
}
/* Top of the left column, level with the strapline's first line, so the
   hero opens on one line across. On its own full-width row above the
   split it answered "what is this" first, which was the point — but it
   left a pill floating alone over a band of nothing, and the strapline
   still reads first because it is three times the size. */
/* No dot. On a section kicker it reads as a status lamp; on a line that
   is one plain sentence about what the product is, it reads as a stray
   bullet in front of it. The other kickers keep theirs. */
.hero__badge{ margin:0 0 clamp(18px,2.2vw,26px); padding-left:12px; }
.hero__badge::before{ display:none; }

.hero__split{
  display:grid; position:relative;
  grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr);
  column-gap:0; row-gap:0; align-items:start;
}

/* The demo gets a line to itself; the two quieter paths share the next
   one, so "see how it works" and "got a question" read as the pair of
   alternatives they are instead of one button and an orphan. */
.actions--sub{ margin-top:14px; align-items:center; gap:18px; }
.actions--sub .aside{ margin-top:0; }

/* The provocation and the promise on one line, in the colour this page
   uses for "sorted" — the badge above says what this is, the strapline
   opposite asks the question, and only this answers it. Rule above,
   because it is a conclusion drawn from the paragraph it follows. */
.hero__worth{
  margin:clamp(20px,2.4vw,28px) 0 0; padding-top:clamp(16px,1.9vw,22px);
  border-top:1px solid rgba(72,102,72,.3);
  box-shadow:inset 0 1px 0 rgba(255,253,244,.85);
  font-family:'Big Shoulders Display','Barlow',sans-serif;
  font-weight:800; font-size:clamp(19px,1.95vw,25px);
  line-height:1.12; letter-spacing:.012em; color:var(--green);
  max-width:34ch;
}
/* The hours are the claim; the rest is the setup. Colouring the second
   sentence lets the eye take the number without reading the sentence. */
.hero__worth b{ font-weight:inherit; color:var(--orange-deep); }
/* The hook is first in the DOM and second on screen: explicit grid
   placement, not `order`, so the reading order a screen reader gets and
   the order a phone shows are the same one. */
.hero__hook{ grid-column:2; grid-row:1; position:relative; padding-left:clamp(26px,3.4vw,52px); }
.hero__ctx { grid-column:1; grid-row:1; padding-right:clamp(26px,3.4vw,52px); }

/* The seam. A machined channel cut on the column boundary — one dark
   line, one lit line beside it, fading out at both ends so it reads as
   a join rather than a border. Two related blocks of one thought, which
   is the whole reason the row is split at all.

   It hangs off the ROW, not off the hook: top-aligned columns are two
   different heights, and a seam that stopped where the shorter one did
   looked like it had been cut off. 42% is the boundary the .84/1.16
   track pair actually falls on. */
.hero__split::after{
  content:""; position:absolute; z-index:1;
  left:44%; top:0; bottom:0; width:1px;
  background:linear-gradient(180deg,transparent,rgba(72,102,72,.42) 8%,rgba(72,102,72,.42) 92%,transparent);
  box-shadow:1px 0 0 rgba(255,253,244,.9);
}
.hero__hook::before{ display:none; }

/* The hook, and the largest thing on the page by a clear margin. If it
   ever starts competing with the label opposite, the fix is more size
   and weight here — not more space between them. */
/* Three lines, at full size. It was briefly set to two — the 12ch cap
   was doing the wrapping rather than the type size, so dropping it and
   the size to 58px put "Where do your hours go" on one line. Read back,
   the taller stack won: three short lines at 75px are easier to take in
   than two long ones, and the extra height balances the left column. */
.hero__strap{
  font-size:clamp(41px,5.7vw,75px); font-weight:900;
  line-height:.93; letter-spacing:-.004em;
  margin:0 0 clamp(30px,3.4vw,42px); max-width:12ch;
}

/* A category label now, not a headline: a third the size of the hook
   and set in the muted ink, so it can be read second without ever
   being mistaken for the thing being asked. */
.hero__label{
  font-family:'Big Shoulders Display','Barlow',sans-serif;
  font-weight:700; text-transform:uppercase; letter-spacing:.05em;
  font-size:clamp(18px,1.85vw,24px); line-height:1.25;
  color:var(--muted); margin:0 0 14px;
}
/* Same face, same case, smaller and in the accent. Set in lowercase
   Barlow it read as a different voice interrupting the list; matching
   the label and stepping down in size and colour keeps it part of the
   same line while still reading as the aside it is.

   --orange-deep, not --orange-ink: this lands on the raw hero ground,
   not on a plate, where --orange-ink measures 3.92. That is the exact
   distinction the two tokens exist for. */
.hero__more{
  font-size:.72em; letter-spacing:.05em;
  color:var(--orange-deep); white-space:nowrap;
}
.lede{
  font-size:clamp(16.5px,1.6vw,19px); color:var(--muted);
  max-width:46ch; margin:0; line-height:1.58;
}

.hero__tiles{ margin-top:clamp(50px,6.2vw,84px); }


/* ── 7b. WHAT JUST HAPPENED ────────────────────────────────────────
   Was the hero's right-hand column, and it did not survive the lift
   unchanged: the two-column shell around it existed to balance a
   headline, a lede, two buttons and a text link, and with those gone
   the left half was 500px of nothing. It is a section now, so it uses
   the grammar every other section on this page uses — heading, lede,
   then the evidence.

   The evidence is the flow, below. It replaced a vertical cascade of
   three big cards plus a four-tile strip that restated them in words;
   the old outer stage wrapper went with them, since the flow carries
   its own wrap and gutters. */

/* Labels the cards as REAL product screens — the most load-bearing
   sentence in this section, previously set at 11px. */
.stage__cap{
  display:flex; align-items:center; gap:9px;
  font:700 15px/1.25 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.09em; color:var(--ink); margin-bottom:18px;
}

/* ── the cover flow ─────────────────────────────────────────
   Replaces a vertical cascade of three large cards PLUS a separate
   four-tile strip that restated the same three beats in words: the
   same story told twice, in ~1400px of page, directly under a hero
   tile that now tells it a third time in 14 frames.

   One row instead. Each step carries its own proof, its own number
   and its own line, so the picture and the sentence about it are the
   same object. The sequence is the information here — that is what
   earns the 01-04 numerals and the connectors between them. */
.flow{
  max-width:var(--wrap); margin-inline:auto; width:100%;
  padding-inline:clamp(20px,4vw,48px);
}
/* Narrower than the wrap on purpose. These tiles are read, not looked
   at: the screenshot under each one is corroboration for a claim the
   hero has already made at full size, so the measure of the sentence
   is what sets the width, not the width of a phone capture. */
.flow__steps{
  --flow-gap:clamp(16px,2.2vw,30px);
  /* was 960px: four cards that wide gave each screenshot more room than
     it needed and pushed the turn markers far apart, so the sequence read
     as four separate things rather than one story. */
  max-width:780px; margin-inline:auto;
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--flow-gap); list-style:none; margin-block:0; padding:0;
}
/* 01 02      Left column is Adam: he raises it, and it comes back to
   04 03      him. Right column is the cover itself: matched, then
              accepted. So the sequence turns at the end of row one and
              runs back, closing the loop on the person who started it
              rather than trailing off at the far edge. */
.flow__step:nth-child(3){ grid-column:2; grid-row:2; }
.flow__step:nth-child(4){ grid-column:1; grid-row:2; }
.flow__step{
  position:relative; display:flex; flex-direction:column;
  background:var(--plate-face); border-radius:var(--r);
  padding:18px 14px 14px; box-shadow:var(--raise);
}
/* margin-top:auto bottom-aligns the strips across a row whose
   sentences run to different lengths */
.flow__shot{ margin:16px 0 0; border-radius:9px; overflow:hidden; margin-top:auto; padding-top:16px; }
.flow__shot img{ width:100%; height:auto; display:block; border-radius:9px; }
.flow__meta{ display:flex; align-items:center; gap:8px; margin:0 0 5px; padding-inline:6px; }
.flow__no{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:15px; letter-spacing:.08em;
}
.flow__h{ font-size:24px; margin:0 0 9px; padding-inline:6px; }
.flow__p{ font-size:16.5px; line-height:1.55; color:var(--muted); margin:0; padding-inline:6px; }

/* state in the same orange-to-green language the hero run uses, so a
   reader who has opened Auto-Cover already knows what the colour means */
.flow__step[data-state="live"] .flow__no{ color:var(--orange-ink); }
.flow__step[data-state="live"] .led{ background:var(--orange); box-shadow:0 0 9px rgba(217,96,15,.85); }
/* --green, not --green-led: the LED green is a lamp colour and measures
   3.39 on the plate. The old .tile__no got away with it only because it
   was large text (3:1); this numeral is 15px, so it needs 4.5. */
.flow__step[data-state="done"] .flow__no{ color:var(--green); }
.flow__step[data-state="done"] .led{ background:var(--green-led); box-shadow:0 0 8px rgba(61,138,95,.7); }

/* Drawn, not a glyph, and sized to be seen: these carry the reading
   order now that it turns a corner. One per hand-off — right across
   row one, down the right-hand side, then back left along row two. */
.flow__step::before{
  content:""; position:absolute; z-index:2;
  width:22px; height:22px;
  border-top:4px solid var(--orange); border-right:4px solid var(--orange);
  opacity:.85;
}
.flow__step:nth-child(1)::before{ content:none; }
/* 01 → 02, across the row-one gutter */
.flow__step:nth-child(2)::before{
  left:calc((var(--flow-gap) / 2 + 8px) * -1); top:50%;
  transform:translateY(-50%) rotate(45deg);
}
/* 02 ↓ 03, down the right-hand side */
.flow__step:nth-child(3)::before{
  top:calc((var(--flow-gap) / 2 + 8px) * -1); left:50%;
  transform:translateX(-50%) rotate(135deg);
}
/* 03 → 04, back across the row-two gutter, pointing left */
.flow__step:nth-child(4)::before{
  right:calc((var(--flow-gap) / 2 + 8px) * -1); top:50%;
  transform:translateY(-50%) rotate(225deg);
}
.flow__more{ margin:clamp(22px,2.8vw,34px) 0 0; font-size:15.5px; }
.flow__more a{ font-weight:700; color:var(--orange-deep); text-decoration:none; }
.flow__more a:hover{ text-decoration:underline; }

/* One column: the turn disappears, so every hand-off points down and
   the snake placement has to be undone or 03 and 04 swap over. */
@media (max-width:639px){
  .flow__steps{ grid-template-columns:minmax(0,1fr); }
  .flow__step:nth-child(3),
  .flow__step:nth-child(4){ grid-column:1; grid-row:auto; }
  .flow__step:nth-child(n+2)::before{
    left:50%; right:auto; top:calc((var(--flow-gap) / 2 + 7px) * -1);
    transform:translateX(-50%) rotate(135deg);
  }
}

/* ── 8. PANELS & CARDS ─────────────────────────────────────────── */

.panel{
  background:var(--plate-face);
  border-radius:var(--r); box-shadow:var(--raise);
}
.panel--tall{ padding:clamp(26px,3vw,36px); }
.panel--tall h3{ font-size:23px; }
.panel--tall p{ font-size:14.5px; color:var(--muted); }
.panel__row{ display:flex; align-items:center; gap:13px; margin-bottom:12px; }
.who{ display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:clamp(16px,2vw,24px); }
.sec--dark .panel{
  background:var(--plate-face-d);
  color:var(--panel); box-shadow:var(--raise-d);
}
.sec--dark .panel--tall p{ color:var(--muted-dark); }

/* ── who it's for: shape diagrams, not screenshots ──────────
   These panels answer "is this me?", which is a question about shape —
   how many sites, how many teams, and where the reader personally
   stands. A product screenshot cannot show any of that, and the three
   that were here all reappear further down the page anyway.

   Drawn with currentColor so one rule sets the whole figure, with the
   focal element — the part that IS the reader — lifted in amber. */
.whofig{ margin:16px 0 0; }
.whodiag{
  display:block; width:100%; height:auto;
  color:var(--muted-dark);
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
  background:rgba(0,0,0,.16); border-radius:9px; padding:10px 8px;
}
.whodiag__tie{ stroke-dasharray:3 4; opacity:.65; }
.whodiag__team{ opacity:.8; }
.whodiag .is-you{ stroke:var(--orange-on-dark-lo); }
.whodiag__ring{ stroke:rgba(245,176,112,.4); stroke-dasharray:4 5; }
.whodiag__arrow{ stroke:var(--muted-dark); opacity:.8; }
.whodiag__lbl--you{ fill:var(--orange-on-dark-lo); }
.whodiag__lbl{
  stroke:none; fill:var(--muted-dark);
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase; letter-spacing:.1em;
}
.whofig figcaption{
  margin-top:10px; font-size:13px; color:var(--muted-dark);
  font-weight:600; line-height:1.4;
}


/* feature thumbnails: a real cropped product screen on the card
   it describes; a marked placeholder where none exists yet */
.fthumb{
  margin:14px 0 0; border-radius:9px; overflow:hidden;
  background:var(--steel-tint); box-shadow:var(--sink-lo);
  aspect-ratio:16/10;
}
.fthumb img{ width:100%; height:100%; object-fit:cover; object-position:top center; display:block; }
.fthumb--ph{
  display:flex; flex-direction:column; justify-content:center; gap:5px;
  padding:14px 16px; text-align:left; box-shadow:none;
  background:
    repeating-linear-gradient(135deg, rgba(168,73,10,.09) 0 9px, transparent 9px 18px),
    var(--steel-tint);
  border:1.5px dashed rgba(168,73,10,.5);
}
/* sits on the dashed placeholder fill (#b4b493), darker than the plate —
   --orange-ink only reaches 3.55 there, so this one steps down again */
.fthumb__tag{
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.12em; color:#6b2f05;
}
.fthumb__what{
  font-family:'Big Shoulders Display',sans-serif; font-weight:700;
  font-size:15px; text-transform:uppercase; color:var(--ink); line-height:1.05;
}
.fthumb__why{ font-size:12.5px; color:var(--muted); line-height:1.35; }
.sec--dark .fthumb{ background:#1b1712; box-shadow:inset 2px 2px 6px #14110c; }
.sec--dark .fthumb--ph{
  background:repeating-linear-gradient(135deg, rgba(240,163,92,.10) 0 9px, transparent 9px 18px), #1b1712;
  border-color:rgba(240,163,92,.45);
}
.sec--dark .fthumb__tag{ color:var(--orange-on-dark); }
.sec--dark .fthumb__what{ color:var(--panel); }
.sec--dark .fthumb__why{ color:var(--muted-dark); }


/* ── 9. THE FOUR — pain tiles ──────────────────────────────────
   The hero asks one question and this row is the four answers, so it
   lives in the hero now. It replaced both the old standalone Core Four
   section and the three-item accordion that section had become: the
   page was carrying two near-identical "pick the one that's yours"
   mechanisms a scroll apart, and only one of them was needed.

   Collapsed, a tile shows the pain and what it costs you every week —
   no feature name, no screen. Opening one closes the other three.

   Four headers across row 1; every panel in the SAME cell of row 2,
   spanning all four columns. Only one panel is ever taller than 0px,
   so the row is exactly the height of whichever is open and the drawer
   always appears directly beneath the tile that was clicked — in
   place, no scroll, no jump to a section below.

   The 4-across placement applies only under .is-live, which main.js
   adds once it has taken control. Without JS the grid stays a single
   column with every panel open, which is the right linear fallback. */

.pain{ display:grid; gap:clamp(12px,1.4vw,18px); }
.pain.is-live{ grid-template-columns:repeat(4,minmax(0,1fr)); }
/* a grouping for the JS and the a11y tree, not a box */
.pain__item{ display:contents; }

.pain.is-live > .pain__item > .pain__hd{ grid-row:1; }
.pain.is-live > .pain__item:nth-child(1) > .pain__hd{ grid-column:1; }
.pain.is-live > .pain__item:nth-child(2) > .pain__hd{ grid-column:2; }
.pain.is-live > .pain__item:nth-child(3) > .pain__hd{ grid-column:3; }
.pain.is-live > .pain__item:nth-child(4) > .pain__hd{ grid-column:4; }
.pain.is-live > .pain__item > .pain__panel{ grid-row:2; grid-column:1 / -1; }
.pain.is-live > .pain__item:nth-child(1) > .pain__panel{ --n:1; }
.pain.is-live > .pain__item:nth-child(2) > .pain__panel{ --n:2; }
.pain.is-live > .pain__item:nth-child(3) > .pain__panel{ --n:3; }
.pain.is-live > .pain__item:nth-child(4) > .pain__panel{ --n:4; }

.pain__hd{ margin:0; font:inherit; display:flex; min-width:0; }

.pain__btn{
  flex:1 1 auto; min-width:0;
  display:flex; flex-direction:column; align-items:flex-start;
  gap:clamp(10px,1.1vw,14px);
  padding:clamp(16px,1.6vw,21px) clamp(16px,1.6vw,22px) clamp(15px,1.5vw,20px);
  background:var(--plate-face); border:0; border-radius:var(--r);
  box-shadow:var(--raise-lo); cursor:pointer; text-align:left; color:var(--ink);
  transition:box-shadow .3s var(--ease), transform .3s var(--ease), background .3s var(--ease);
}
.pain__btn:hover{ transform:translateY(-2px); box-shadow:var(--raise); }
.pain__btn:focus-visible{ outline:3px solid var(--orange-btn); outline-offset:3px; }

/* open = pressed in. A switch that is currently down is the plainest
   thing this material can say about "you're looking at this one".
   --panel, not --ground-tint: the tint's dark stop drops the green gain
   line to 4.01:1, and the sink shadow is what reads as pressed anyway —
   it is the same engraved recess .ba and .run__cap are cut from. */
.pain__item.is-open .pain__btn,
.pain__item.is-open .pain__btn:hover{
  background:var(--panel); box-shadow:var(--sink); transform:none;
}

.pain__top{
  display:flex; width:100%; align-items:center;
  justify-content:space-between; gap:12px;
}

/* the pain's category, stamped into the plate */
/* Filled orange pill in every state, not only when open. Four engraved
   grey chips read as inert labelling; four lit ones read as four things
   you can press, which is what they are. The open tile does not need
   the pill to say so — the pressed plate, the flipped chevron and the
   drawer underneath already do. */
.pain__cat{
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.13em; color:#fff;
  padding:6px 11px; border-radius:999px;
  background:var(--orange-btn);
  box-shadow:0 3px 8px rgba(120,52,8,.24), inset 0 1px 0 rgba(255,255,255,.2);
}

.pain__label{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:clamp(20px,2.05vw,27px); line-height:1.03;
  transition:color .2s var(--ease);
}
.pain__btn:hover .pain__label{ color:var(--orange-ink); }
.pain__item.is-open .pain__label{ color:var(--ink); }

/* The answer, on the line under the pain, in the colour this page uses
   for "sorted". A collapsed tile stated the problem and its price and
   left the reader to guess what RunStaff did about it; this is that, in
   four words, before anything is opened. */
.pain__gain{
  font-family:'Big Shoulders Display',sans-serif; font-weight:700;
  font-size:clamp(15.5px,1.5vw,19px); line-height:1.12;
  text-transform:none; letter-spacing:.01em;
  color:var(--green); margin:9px 0 auto;
}

/* the sting: what this one costs you every week, in the operator's own
   units. Visibility carries no figure and one is not invented for it —
   the tile simply ends after its gain line. */
.pain__cost{
  font:600 14.5px/1.3 'Barlow',sans-serif;
  text-transform:none; letter-spacing:0;
  color:var(--orange-ink); margin-top:12px;
}

/* Opening the tile presses the plate away and puts this line on the raw
   page ground, where --orange-ink measures 3.92 — the same trap
   .pain__more is already out of on the next rule down. */
.pain__item.is-open .pain__cost{ color:var(--orange-deep); }
.pain__item.is-open .pain__gain{ color:var(--green-deep); }

/* A named control, not an arrow. A chevron says only that something
   happens; on a tile whose whole point is "pick the one that's yours",
   the invitation is worth spelling out. The text lives in CSS so it
   never joins the button's accessible name — aria-expanded already
   tells a screen reader which way this thing is pointing. */
.pain__more{
  flex:none;
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.11em; color:var(--orange-ink);
  padding:5px 0 4px; border-bottom:1.5px solid currentColor;
  transition:color .2s var(--ease);
}
.pain__more::after{ content:"Show me"; }
.pain__btn:hover .pain__more{ color:var(--orange-deep); }
.pain__item.is-open .pain__more{ color:var(--orange-deep); }
.pain__item.is-open .pain__more::after{ content:"Hide"; }

/* Height, not grid-template-rows. The 0fr→1fr trick needs overflow:hidden
   on the grid item to clip, but that same overflow zeroes the track's
   automatic minimum here, so the row measured 0px open and closed alike;
   without it, 0fr refuses to collapse. An explicit height is measured by
   main.js and released back to auto once the transition ends, so the panel
   still reflows with the content and the viewport. No JS = height:auto =
   fully open, which is the correct no-script fallback. */
/* The plate is on the base rule, not on .is-live. Scoped to .is-live it
   left the no-JS fallback rendering the panel straight onto the hero
   ground, where the orange tagline measures 3.92:1 — contrast-audit
   caught it with the class removed. Only the shadow is JS-conditional,
   because only the shadow depends on the panel being collapsible. */
.pain__panel{
  overflow:hidden; position:relative;
  background:var(--plate-face); border-radius:var(--r);
  transition:height .42s var(--ease), box-shadow .3s var(--ease);
}
.pain.is-live .pain__panel{ box-shadow:var(--raise); }
/* a closed panel is 0px tall — its shadow would still paint a sliver */
.pain.is-live .pain__item.is-closed .pain__panel{ box-shadow:none; }
/* set for one frame while an outgoing panel closes, so the scroll
   compensation in main.js can measure a settled layout */
.pain__item.is-instant .pain__panel{ transition:none; }

/* A full-width drawer has to point back at the quarter-width tile that
   opened it: a short lit bar on its top edge, centred under that tile.
   --n is the tile's column, so the arithmetic is the grid's own. */
.pain.is-live .pain__panel::before{
  content:""; position:absolute; top:0; z-index:3;
  --gp:clamp(12px,1.4vw,18px);
  --cw:calc((100% - 3 * var(--gp)) / 4);
  --bw:clamp(44px,5vw,76px);
  width:var(--bw); height:3px; border-radius:0 0 3px 3px;
  background:var(--orange);
  left:calc((var(--n) - 1) * (var(--cw) + var(--gp)) + var(--cw) / 2 - var(--bw) / 2);
}
.pain.is-live .pain__item.is-closed .pain__panel::before{ display:none; }

.pain__body{ padding:clamp(22px,2.6vw,32px) clamp(18px,2.4vw,30px) clamp(24px,2.9vw,34px); }

.pain__feat{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:clamp(21px,2.2vw,27px); line-height:1.1; margin:0 0 5px;
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
}
.pain__sub{
  font-family:'Barlow',sans-serif; font-weight:600; font-size:13px;
  text-transform:uppercase; letter-spacing:.09em; color:var(--muted);
}
.pain__tag{
  font-size:clamp(16px,1.5vw,18.5px); color:var(--orange-ink);
  font-weight:600; margin:0 0 clamp(20px,2.3vw,28px); line-height:1.4;
}

/* An open panel used to be four paragraphs of one weight stacked over
   four screens of equal size, and it read as a wall. It now has three
   jobs in falling order of loudness: the saving, the change, the
   detail. Copy on the left, the run of real screens on the right. */
.pain__grid{
  display:grid;
  grid-template-columns:minmax(0,1fr) clamp(340px,38vw,470px);
  gap:clamp(26px,3.6vw,54px); align-items:start;
}
/* Stacked, not side by side, and capped to a real measure. Side by side
   these two are ~50ch each and the copy column comes out 316px tall next
   to a 583px screen — the hole at the bottom of the panel was the layout,
   not the spacing. Stacked at 56ch the column earns its height and the
   lines stay inside a readable measure. */
.pain__cols{
  display:grid; grid-template-columns:1fr;
  gap:clamp(20px,2.6vw,32px); max-width:56ch;
}

/* The payoff, and the loudest object in the panel. This is the only
   number on the page a manager is actually shopping for, and as plain
   green text under a green-ish before/after it was indistinguishable
   from the copy around it. A filled safety-orange pill is the same
   object as .kicker, so it costs the design system nothing.
   Visibility has no figure and therefore no pill — that pain has no
   honest hour count and one is not invented to fill the slot. */
.saving{
  display:inline-flex; align-items:baseline; gap:11px;
  margin:0 0 clamp(20px,2.4vw,28px);
  padding:8px 16px 9px 13px; border-radius:999px;
  background:var(--orange-btn); color:#fff;
  box-shadow:0 7px 16px rgba(120,52,8,.3), inset 0 1px 0 rgba(255,255,255,.22);
}
/* var(--peach-on-orange-hi), not the --kicker peach var(--peach-on-orange) this started as: on
   --orange-btn that one measures 4.47 — close enough to look fine and
   still a fail at 11px. contrast-audit caught it; this clears 4.89. */
.saving__k{
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.13em; color:var(--peach-on-orange-hi); flex:none;
}
.saving__v{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:clamp(18px,1.8vw,22px); line-height:1; letter-spacing:.01em;
}

/* Before and after are two STATES of the same week, not two sentences
   about it, so they are set as one engraved instrument with a rule
   between them: the keys carry the signal colours the rest of the page
   already uses for "needs you" and "sorted", and the after line steps
   up to full ink while the before line stays muted. */
.ba{
  background:var(--panel); border-radius:var(--r-sm);
  box-shadow:var(--sink-lo); padding:2px 14px;
}
.ba__row{
  display:flex; gap:11px; align-items:baseline;
  margin:0; padding:16px 0;
  font-size:15.5px; line-height:1.55; color:var(--muted);
}
.ba__row + .ba__row{ box-shadow:inset 0 1px 0 rgba(72,102,72,.24); }
.ba__k{
  flex:none; width:47px;
  font:700 10.5px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.11em; color:var(--orange-ink);
  background:none; box-shadow:none; padding:0; margin:0; text-align:left;
}
.ba__t{ min-width:0; }
.ba__row--after{ color:var(--ink); }
.ba__row--after .ba__k{ color:var(--green); }

/* ── the run: real stills, cross-faded ───────────────────────────
   No video. None of these moments is an interaction worth filming —
   nothing is typed, dragged or tapped in them; they are states. So the
   story runs left to right as stills that cross-fade and loop while
   the tile is open, which costs no clip to produce, host, or keep in
   sync with the product.

   Base CSS stacks every shot in normal flow, visible: that is the
   no-JS reading, and it is a complete one. main.js adds .is-live and
   only then do the shots pile into one stage and start cycling. */
/* Caption, steps and Pause sit BESIDE the screen, not under it. Stacked
   they cost ~160px of height each and forced the stage to be cropped to
   pay for it; alongside, that height comes back and the screen can be
   shown whole. The stage is second in the DOM and first on screen so a
   phone gets the screen, then its caption — the same order it read in
   before the columns existed. */
.run{
  min-width:0; display:grid; position:relative;
  grid-template-columns:minmax(0,1fr) clamp(200px,20vw,265px);
  column-gap:clamp(12px,1.4vw,20px); row-gap:0; align-items:stretch;
}
/* The same machined channel the hero uses, cut between the argument and
   the evidence. Without it the panel is one undifferentiated field and
   the running demo reads as more copy rather than as a thing to watch.
   It sits in the middle of .pain__grid's gap, and .run is the taller
   column, so its height is the row's. */
.run::before{
  content:""; position:absolute; z-index:1; top:0; bottom:0; width:1px;
  left:calc(-1 * clamp(26px,3.6vw,54px) / 2);
  background:linear-gradient(180deg,transparent,rgba(72,102,72,.34) 7%,rgba(72,102,72,.34) 93%,transparent);
  box-shadow:1px 0 0 rgba(255,253,244,.85);
}
.run__lead{ grid-column:1 / -1; grid-row:1; }
.run__stage{ grid-column:2; grid-row:2; }
/* centred against the screen, not pinned to its top: a 180px block of
   controls hanging from the top of a 575px column reads as an orphan
   third column rather than as the screen's own readout */
.run__side {
  grid-column:1; grid-row:2; min-width:0;
  display:flex; flex-direction:column; justify-content:center;
}

.run__lead{
  margin:0 0 12px; font-size:14px; line-height:1.45;
  color:var(--muted); font-style:italic;
}
.run__stage{
  display:flex; flex-direction:column; gap:12px;
  background:var(--panel); border-radius:var(--r);
  box-shadow:var(--sink-lo); padding:8px;
}
/* The source aspect, whole. It was cropped to 390/620 to buy back the
   height the caption and controls were spending underneath it; with
   those moved alongside, the screen gets to be a screen again. */
.run.is-live .run__stage{
  display:block; position:relative;
  aspect-ratio:390/846; overflow:hidden;
}
.run__shot{ margin:0; border-radius:9px; overflow:hidden; position:relative; }
.run.is-live .run__shot{
  position:absolute; inset:8px; opacity:0; pointer-events:none;
  transform:scale(1.015); transform-origin:50% 30%;
  transition:opacity .62s var(--ease), transform .62s var(--ease);
}
/* opacity only, never display or visibility: every shot stays in the
   accessibility tree, so a screen reader still gets all four alts and
   their figcaptions in order instead of whichever frame happened to be
   showing when it arrived */
.run.is-live .run__shot.is-on{ opacity:1; transform:none; }
.run__shot img{
  width:100%; height:100%; object-fit:cover; object-position:top;
  border-radius:9px; display:block;
}

/* ── the focus mark ─────────────────────────────────────────
   These are whole phone captures shown ~250px wide inside the
   stage. At that size a reader cannot find the one card that
   changed, and the frame has moved on before they have. The mark
   rings the region the caption is talking about and dims the rest,
   so the eye lands in the right place immediately.

   The layer is sized to the IMAGE, not to the figure, and the two
   are not the same box. The figure's inset is a fixed 8px on a
   fluid stage, which always leaves it a taller ratio than the
   source — so object-fit:cover is always HEIGHT-constrained here:
   it fills the height exactly and crops ~2% off each side. Sizing
   this layer to the figure instead would put every mark up to 16px
   above the thing it points at.

   height:100% + the source aspect reproduces the rendered image
   box exactly at every size; the centring matches cover's default
   horizontal placement, which object-position:top does not change. */
.run__focus{
  position:absolute; top:0; left:50%; transform:translateX(-50%);
  height:100%; aspect-ratio:780/1688; pointer-events:none;
}
.run__focus > span{
  position:absolute; display:block;
  left:calc(var(--fx) * 1%);  top:calc(var(--fy) * 1%);
  width:calc(var(--fw) * 1%); height:calc(var(--fh) * 1%);
  border:2px solid var(--orange); border-radius:7px;
  /* One element does both jobs: the ring, and — via a spread far
     larger than the frame — the scrim over everything outside it.
     .run__shot is overflow:hidden, so the spread stops at the
     screenshot's own rounded edge. */
  box-shadow:0 0 0 100vmax rgba(8,12,22,.46), 0 0 12px rgba(217,96,15,.55);
  opacity:0; transition:opacity .45s var(--ease) .3s;
}
/* the ring carries the same state the caption's LED does */
.run__shot[data-state="done"] .run__focus > span{
  border-color:var(--green-led);
  box-shadow:0 0 0 100vmax rgba(8,12,22,.46), 0 0 12px rgba(95,130,72,.6);
}
/* it arrives just after the frame has settled, which is what makes
   it read as a pointer rather than as part of the screenshot */
.run.is-live .run__shot.is-on .run__focus > span{ opacity:1; }
/* the fallback has no is-on — every frame is simply present */
.run:not(.is-live) .run__focus > span{ opacity:1; transition:none; }

/* ── whose phone this is ────────────────────────────────────
   The cover run crosses three people — the person off sick, you,
   and the person who picks it up — and a reader who cannot tell
   whose screen they are on reads the whole sequence as one
   confused app. The caption says it, but only if you read it; this
   says it at a glance.

   Deliberately NOT colour-coded per person. Hue on this page is
   already committed to what KIND of thing something is
   (--sig-live / --sig-ok / --sig-info / --sig-time), and a second
   hue language mapping colour to PEOPLE would collide with it —
   green especially, which already means resolved on the ring two
   rules up. The word does the work; one neutral plate carries it. */
.run__who{
  position:absolute; top:10px; left:10px; z-index:2;
  padding:3px 7px; border-radius:5px;
  background:#f4f2ec; color:#1c2419;
  font:700 9.5px/1 'Barlow',sans-serif;
  text-transform:uppercase; letter-spacing:.07em; white-space:nowrap;
  box-shadow:0 1px 3px rgba(8,12,22,.45);
  opacity:0; transition:opacity .3s var(--ease) .16s;
}
.run.is-live .run__shot.is-on .run__who{ opacity:1; }
.run:not(.is-live) .run__who{ opacity:1; transition:none; }
@media (prefers-reduced-motion:reduce){
  .run__focus > span{ transition-delay:0s; }
}

/* The caption is the line that tells you what you are looking at, and
   at 11px muted above a screenshot it was the smallest thing in the
   panel. It is now its own engraved bar under the stage, in full ink,
   with the LED carrying the state of the beat it describes. */
.run__cap{
  display:flex; align-items:flex-start; gap:8px;
  margin:0; padding:10px 12px;
  background:var(--panel); border-radius:var(--r-sm);
  box-shadow:var(--sink-lo);
  font:700 12.5px/1.35 'Barlow',sans-serif;
  text-transform:uppercase; letter-spacing:.055em; color:var(--ink);
  /* three lines reserved, not two: in a ~165px column "RunStaff builds
     it, then checks it" runs to three, and a caption that changes every
     2.6s must not resize the panel it lives in */
  min-height:calc(3 * 1.35em + 20px);
}
.run__cap .led{ flex:none; margin-top:4px; background:var(--muted); box-shadow:none; }
.run__cap[data-state="live"] .led{ background:var(--orange); box-shadow:0 0 9px rgba(217,96,15,.85); }
.run__cap[data-state="done"] .led{ background:var(--green-led); box-shadow:0 0 8px rgba(61,138,95,.7); }

.run__ctrls{
  display:flex; flex-direction:column; align-items:flex-start;
  gap:10px; margin-top:11px;
}
/* Segmented progress, the way a story does it: one engraved channel per
   step, filling in real time so you can see both where you are and how
   long is left. Stamped numerals said the first but never the second,
   and on an autoplaying run the second is the anxious question.

   Each segment is still a real button — the cycle is never the only way
   to reach a step — and the fill is driven from the same per-frame
   timer that advances the screens, so the bar cannot drift from it. */
.run__pips{ display:flex; gap:6px; margin:0; padding:0; align-self:stretch; flex:1 1 auto; min-width:0; }
/* the li is the flex item here, not the button inside it — sizing the
   button alone left every segment at zero width */
.run__pips li{ flex:1 1 0; min-width:0; display:flex; }
.run__pip{
  position:relative; flex:1 1 auto; width:100%; min-width:0;
  padding:11px 0; border:0; background:none; cursor:pointer;
  -webkit-appearance:none; appearance:none;
}
.run__pip::before{
  content:""; display:block; height:5px; border-radius:3px;
  background:var(--panel); box-shadow:var(--sink-lo);
}
/* centred, not offset from the top: the tap target grows on small
   screens and the bar should stay in the middle of it */
.run__pip-fill{
  position:absolute; left:0; top:50%; transform:translateY(-50%); height:5px; width:0;
  border-radius:3px; background:var(--orange);
  box-shadow:0 0 7px rgba(217,96,15,.5);
}
.run__pip:hover::before{ background:var(--steel-tint); }
.run__pip:focus-visible{ outline:3px solid var(--orange-btn); outline-offset:2px; border-radius:4px; }
/* Auto-advancing content needs a way to stop, and a named control beats
   an icon nobody has to guess at. Hovering or focusing the run pauses
   it too, so reading a screen never becomes a race. */
.run__hold{
  padding:8px 11px; border:0; border-radius:6px;
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.1em; color:var(--orange-ink);
  background:var(--panel); box-shadow:var(--sink-lo); cursor:pointer;
  transition:color .2s var(--ease);
}
.run__hold:hover{ color:var(--ink); }
.run:not(.is-live) .run__ctrls{ display:none; }

/* A marked slot, never a stand-in. The Visibility tile's two screens do
   not exist yet and nothing plausible is put in their place. 5/7, not
   the 390/846 the real capture will use: a phone screen's true aspect
   turns the slot into a column of hatching that reads as broken rather
   than pending. Inside the fixed stage it fills the frame either way. */
.run__shot--ph .ph{
  display:flex; flex-direction:column; justify-content:center; gap:5px;
  height:100%; min-height:0; aspect-ratio:5/7; padding:16px 15px; border-radius:9px;
  background:
    repeating-linear-gradient(135deg, rgba(168,73,10,.09) 0 9px, transparent 9px 18px),
    var(--steel-tint);
  border:1.5px dashed rgba(168,73,10,.5);
}
.run.is-live .run__shot--ph .ph{ aspect-ratio:auto; }
/* on the dashed placeholder fill, --orange-ink only reaches 3.55 — this
   one steps down again, the same way .fthumb__tag does */
.ph__tag{
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.12em; color:#6b2f05;
}
.ph__what{
  font-family:'Big Shoulders Display',sans-serif; font-weight:700;
  font-size:15px; text-transform:uppercase; color:var(--ink); line-height:1.05;
}
.ph__why{ font-size:12.5px; color:var(--muted); line-height:1.35; }

.device{
  background:var(--plate-face);
  border-radius:var(--r); padding:12px; box-shadow:var(--raise); margin:0;
}
.device__bar{
  display:flex; align-items:center; gap:8px;
  font:700 10px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.08em; color:var(--muted); padding:3px 4px 11px;
}
.device video, .device img{
  width:100%; border-radius:var(--r-sm); background:#0d0f12;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.14);
}


/* ── 10. THE WEEK ──────────────────────────────────────────────── */

/* The gap between cadences used to live on a .cadences wrapper. The
   persona rebuild replaced that wrapper with .wk__view and the rule was
   left matching nothing, so Hourly / Daily / Weekly rendered flush — a
   0px gap between two DIFFERENT cadences while two rows of the SAME grid
   sat 15px apart, which inverted the whole structure. It belongs on the
   bands themselves, where no wrapper can be renamed out from under it. */
.cadence-band + .cadence-band{
  margin-top:clamp(30px,4vw,52px);
  padding-top:clamp(26px,3.4vw,44px);
  border-top:1px solid rgba(240,163,92,.22);
}
/* Cadence header sits ABOVE its tiles, full width, rather than in a 215px
   left column. That buys the grid the whole measure, which is what lets the
   tiles run four across; the old side rail capped them at three and left
   Hourly and Daily each ending on a row of one. */
.cadence-band{ display:block; }

.cadence-band__rail{
  position:relative; padding:0 0 0 18px;
  /* 2px, as the original rail was — I widened this to 3px when moving the
     header above the tiles and it tripped the side-tab rule. The extra pixel
     was not a design decision. */
  border-left:2px solid rgba(217,96,15,.45);
  margin-bottom:clamp(16px,2vw,24px);
  display:flex; align-items:baseline; flex-wrap:wrap; gap:0 16px;
}
.cadence-band__rail .plate{ align-self:center; }
.cadence-band__rail h3{ font-size:clamp(26px,3vw,36px); color:var(--panel); margin:0; flex:none; }
.cadence-band__rail p{ font-size:15px; color:var(--muted-dark); line-height:1.45; margin:0; }
/* The count is no longer a separate pill floating at the end of the rail.
   A bare "5" beside a mood line referred to nothing, and as the last flex
   item its x position was set by the length of the text next to it — three
   bands, three positions, a 56px ragged edge. Count, cadence and noun are
   one phrase now ("4 hourly moments"), which is the only arrangement where
   all three read as belonging to each other. */
.cadence-band__c{ color:var(--orange-on-dark); font-variant-numeric:tabular-nums; }

/* ── the persona filter ─────────────────────────────────────
   Persona is the PRIMARY axis and cadence the secondary one, so the
   pills sit above the bands, not beside them. Both views ship visible
   and every card ships open, so a reader without JS gets all nineteen
   moments and all nineteen screens; main.js hides the inactive view
   and collapses the cards on init, which is also what makes
   aria-selected and aria-expanded honest. */
.wk__pills{
  display:flex; gap:8px; justify-content:center; flex-wrap:wrap;
  background:rgba(0,0,0,.24); border-radius:var(--r-sm);
  padding:7px; width:fit-content;
  box-shadow:inset 0 2px 5px rgba(0,0,0,.5), inset 0 -1px 0 rgba(255,247,230,.07);
  margin:0 auto clamp(28px,3.4vw,44px);
}
.wk__pill{
  background:transparent; border:0; border-radius:7px; cursor:pointer;
  padding:12px 22px; color:var(--muted-dark);
  font:700 13px/1.2 'Barlow',sans-serif; text-transform:uppercase; letter-spacing:.05em;
  display:inline-flex; align-items:center; gap:9px;
  transition:box-shadow .18s var(--ease), color .18s, background .18s;
}
.wk__pill:hover{ color:var(--panel); }
/* The chosen pill is FILLED, not tinted. Lifted orange text on the dark
   plate measured 4.39:1 and its count 3.92:1 — the same trap .kicker was
   pulled out of in section 4. A filled pill carries its own ground and
   stops depending on whatever it is sitting on. */
.wk__pill[aria-selected="true"]{
  background:var(--orange-on-dark); color:var(--ink-on-orange);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 4px 12px rgba(0,0,0,.45);
}
.wk__pill:focus-visible{ outline:3px solid var(--orange-on-dark); outline-offset:2px; }
/* the count is a fact about the view, not decoration — it tells you
   how much is behind the pill before you press it */
.wk__n{
  font:700 11px/1 'Barlow',sans-serif; letter-spacing:.06em; color:var(--muted-dark);
  border:1.5px solid rgba(240,163,92,.38); border-radius:999px; padding:3px 7px;
}
.wk__pill[aria-selected="true"] .wk__n{ color:var(--ink-on-orange); border-color:rgba(42,28,12,.45); }
.wk__note{
  text-align:center; color:var(--muted-dark); font-size:15px;
  margin:-.6em auto clamp(26px,3.2vw,40px); max-width:52ch;
}
.wk__view[hidden]{ display:none; }
.wk__view:focus{ outline:none; }

/* Same contract as .run above: the resting state is VISIBLE, and only
   a running script hides the cards to deal them back in. A keyframe
   with fill-mode both would strand a whole persona view at opacity 0
   whenever the animation clock is throttled. */
.wtile{ transition:opacity .38s var(--ease), transform .38s var(--ease), box-shadow .3s var(--ease); }
.wk__view.is-armed .wtile{ opacity:0; transform:translateY(13px); }
.wk__view.is-armed .wtile.is-in{ opacity:1; transform:none; }

/* Three across, not four. Band counts are 5/2/6 and 3/3/1; at four
   columns the five-card band ends on a single orphan. */
/* stretch, not start: with align-items:start a row of cards measured
   119 / 99 / 99px and left a hole under the two short ones. Safe only
   because the open lead card below takes a row to itself — otherwise
   stretch would drag its two collapsed neighbours to its full height. */
.wgrid{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(10px,1.4vw,15px); align-items:stretch;
}
/* The lead card of each band ships open, so it spans the row and lays its
   detail out beside its screen rather than above it — stacked, one open
   card cost ~280px and pushed the rest of the cadence off the fold. */
.wtile[data-wk-lead]{ grid-column:1 / -1; }
/* The split used to be 1fr | 320px — text took the room and the screen
   got the scrap, which on a three-column-wide card left a band of empty
   plate beside two lines of prose. Inverted: the detail is short and
   reads fine at 360px, and the screens are the reason the card is open
   at all, so they get the rest. */
.wtile[data-wk-lead] .wtile__inner{
  display:grid; grid-template-columns:minmax(0,360px) minmax(0,1fr);
  gap:clamp(14px,2.2vw,28px); align-items:start;
}
.wtile[data-wk-lead] .wtile__inner .fthumb{ margin-top:0; }
@media (max-width:640px){
  .wtile[data-wk-lead] .wtile__inner{ grid-template-columns:minmax(0,1fr); }
  .wtile[data-wk-lead] .wtile__inner .fthumb{ margin-top:12px; }
}
@media (max-width:1080px){ .wgrid{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:640px){  .wgrid{ grid-template-columns:1fr; } }

/* A moment card is one line of relief with its detail and its screen
   folded behind it — the same contract as a Core Four tile, one size
   down. Collapsed it costs three lines; open it costs a screenshot. */
.wtile{
  background:var(--plate-face-d); border-radius:var(--r-sm);
  box-shadow:var(--raise-d-lo);
  border-top:2px solid rgba(217,96,15,.55);
  overflow:hidden;
}
.wtile.is-open{ box-shadow:var(--raise-d); }

.wtile{ display:flex; flex-direction:column; }
.wtile__hd{ margin:0; font:inherit; }
.wtile__btn{
  width:100%; display:flex; align-items:center; gap:10px;
  padding:15px 16px 0; background:none; border:0; cursor:pointer;
  text-align:left; color:var(--panel);
}
.wtile__btn:focus-visible{ outline:3px solid var(--orange-on-dark); outline-offset:-3px; }
.wtile__btn .ico{ width:19px; height:19px; color:var(--orange-on-dark); flex:none; }
.wtile__name{
  flex:1 1 auto; min-width:0;
  font-family:'Big Shoulders Display',sans-serif; font-weight:700;
  font-size:17px; text-transform:uppercase; line-height:1.05;
  transition:color .2s var(--ease);
}
.wtile__btn:hover .wtile__name{ color:var(--orange-on-dark-lo); }
/* Who the moment is for. Was 9.5px #8d836f on #425442 — 2.18:1, below
   even the large-text floor, on the one label that tells you whether a
   moment is yours or your staff's. It carries its own ground now. */
.wtile__who{
  font:700 10.5px/1 'Barlow',sans-serif; font-style:normal;
  text-transform:uppercase; letter-spacing:.08em;
  color:#e8f1e4; background:rgba(255,255,255,.13);
  padding:3px 8px; border-radius:999px; white-space:nowrap; flex:none;
}
/* Owner moments sit in the shared Manager & Owner view, so they need a
   marker that survives being scanned past — a filled pill and a lit top
   edge, not a second shade of grey. */
.wtile__who--own{ color:var(--ink-on-orange); background:var(--orange-on-dark); }
.wtile--own{ border-top-color:var(--orange-on-dark); }

.wtile__chev{
  flex:none; width:9px; height:9px; margin-right:2px;
  border-right:2.5px solid var(--orange-on-dark); border-bottom:2.5px solid var(--orange-on-dark);
  transform:rotate(45deg) translate(-1px,-1px);
  transition:transform .3s var(--ease);
}
.wtile.is-open .wtile__chev{ transform:rotate(225deg) translate(-1px,-1px); }

.wtile__line{
  font-size:13.5px; color:var(--muted-dark); line-height:1.45;
  margin:9px 0 0; padding:0 16px 15px; flex:1 1 auto;
}
/* Height, not grid-template-rows — same reasoning as .pain__panel in
   section 9: an explicit height is measured by main.js and released
   back to auto once the transition ends. No JS = height:auto = open. */
.wtile__panel{ overflow:hidden; transition:height .36s var(--ease); }
.wtile.is-instant .wtile__panel{ transition:none; }
.wtile__inner{
  padding:14px 16px 16px;
  border-top:1px solid rgba(255,247,230,.09);
}
.wtile__det{ font-size:13.5px; color:var(--muted-dark); line-height:1.5; margin:0; }
.wtile__inner .fthumb{ margin-top:12px; aspect-ratio:16/9; }

.wtile--live{ border-top-color:rgba(240,144,74,.75); }
.wtile--live .ico{ color:var(--sig-live-d); }
.wtile--ok  { border-top-color:rgba(143,189,118,.7); }
.wtile--ok .ico{ color:var(--sig-ok-d); }
.wtile--info{ border-top-color:rgba(121,170,193,.7); }
.wtile--info .ico{ color:var(--sig-info-d); }
.wtile--time{ border-top-color:rgba(217,171,82,.7); }
.wtile--time .ico{ color:var(--sig-time-d); }
/* the owner marker outranks the signal hue on the top edge */
.wtile--own{ border-top-color:var(--orange-on-dark); }


/* ── 11. ORANGE PUNCTUATION BAND ───────────────────────────────── */

.punch{
  background:var(--orange-btn); color:#fff;
  padding:clamp(44px,5vw,68px) 0; position:relative; overflow:hidden;
}
/* No stripe overlay. .punch and .cta are both --orange-btn, but the 7%
   black hatch made this band render visibly darker than the closing CTA —
   two different oranges for the same signal. The band reads on its own. */
.punch__pair{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
  gap:clamp(24px,3.4vw,52px); position:relative;
}
.punch__col{ display:flex; gap:18px; align-items:flex-start; }
.punch__mark{
  width:52px; height:52px; border-radius:14px; flex:none;
  display:grid; place-items:center; color:#fff; background:rgba(0,0,0,.16);
  box-shadow:inset 3px 3px 7px rgba(0,0,0,.28), inset -3px -3px 7px rgba(255,255,255,.14);
}
.punch__mark .ico{ width:25px; height:25px; }
.punch__body{ flex:1 1 auto; min-width:0; }
.punch h2{ font-size:clamp(22px,2.4vw,30px); margin-bottom:10px; }
/* The band is --orange-btn, and .accent globally resolves to --orange-ink:
   orange text on orange ground at 1.30:1, effectively invisible. .cta got
   this override when it was built; .punch never did. */
.punch .accent{ color:var(--peach-on-orange); }
.punch .bul--onorange li{ color:#fff; font-size:14px; }
.punch .bul--onorange li::before{ background:var(--peach-on-orange); }
.punch .bul--onorange li b{ color:#fff; font-weight:700; }


/* the delivery mechanism, directly under the claim it supports.
   Sits on the orange band, so every colour here is chosen against
   --orange-btn (#a8490a), not against the page ground. */
.alerts{
  margin-top:clamp(30px,3.6vw,46px);
  padding-top:clamp(26px,3vw,38px);
  border-top:1px solid rgba(255,255,255,.28);
}
/* Its own heading, because this is a THIRD claim — delivery — not a
   footnote to the two above it. The band was starting to blur "work
   happens with nobody watching" (the server) into "it comes to you"
   (the notification); they are different promises and both stand. */
.alerts__h{
  font-size:clamp(24px,2.7vw,34px); color:#fff; margin:0 0 12px;
}
.alerts__h .accent{ color:var(--peach-on-orange); }
.alerts__lede{
  font-size:clamp(16px,1.55vw,19px); line-height:1.5; color:var(--cream-on-orange);
  max-width:62ch; margin:0 0 clamp(22px,2.6vw,32px); font-weight:500;
}
/* var(--peach-on-orange) measured 4.47 on --orange-btn — under by 0.03 */
.alerts__lede em{ color:var(--cream-on-orange); font-style:normal; font-weight:700; }
.alerts__set{
  list-style:none; margin:0; padding:0; display:grid;
  grid-template-columns:repeat(auto-fit,minmax(228px,1fr));
  gap:clamp(12px,1.5vw,18px);
}
/* DARKEN the card, do not lighten it. A white veil over --orange-btn
   lifts the ground to ~#b15b22, which dropped the body copy to 3.98:1 and
   the placeholder labels to 3.16. Going the other way deepens the ground
   and every light tone on it clears AA with room to spare. */
.alerts__item{
  background:rgba(0,0,0,.22); border-radius:var(--r-sm);
  padding:clamp(16px,1.8vw,20px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14);
}
.alerts__item h3{
  font-size:19px; color:#fff; margin:0 0 7px;
}
.alerts__item p{ font-size:14.5px; line-height:1.5; color:#ffe6cd; margin:0; }
/* the placeholder frame is tuned for the page ground and the dark band;
   on orange it needs its own pair to stay legible */
.alerts__item .fthumb{ margin-top:13px; aspect-ratio:16/10; background:rgba(0,0,0,.40); box-shadow:none; }
.alerts__item .fthumb--ph{
  background:repeating-linear-gradient(135deg, rgba(255,255,255,.07) 0 9px, transparent 9px 18px), rgba(0,0,0,.40);
  border-color:rgba(255,255,255,.42);
}
.alerts__item .fthumb__tag{ color:var(--peach-on-orange); }
.alerts__item .fthumb__what{ color:#fff; }
/* .fthumb__why inherits --muted, which is tuned for the light page ground
   and measured 1.31:1 here. The first three placeholders in this band had
   no why line, so the gap only surfaced when one gained a reason. */
.alerts__item .fthumb__why{ color:#e8c9a8; }


/* the delivery claim wears the same mark as the two claims above it, so
   the three read as one family rather than two statements and a footnote */
.alerts__hd{ display:flex; gap:clamp(14px,1.9vw,20px); align-items:flex-start; }
.alerts__hd .punch__mark{ flex:none; }
.alerts__hd > div{ min-width:0; }


/* ── 12. WHY US / DOUBLE-LOCK ──────────────────────────────────── */

.lockwrap{
  display:grid; grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:clamp(30px,4.5vw,68px); align-items:start;
}
.lockwrap__head .h2{ font-size:clamp(30px,3.5vw,50px); }
.lockwrap__head .sec__lede{ max-width:42ch; }
.lockrows{ display:flex; flex-direction:column; gap:clamp(12px,1.6vw,18px); }
.lockrow{
  display:flex; gap:20px; align-items:center;
  background:var(--plate-face); color:var(--ink);
  border-radius:var(--r); padding:20px 24px; box-shadow:var(--raise);
}
/* Was three identical dials — needles at -52 / +4 / +54 degrees, no
   ticks, no scale, no unit, and not even a systematic sweep. A gauge
   promises a measurement, and there is no quantity here to measure;
   in the one section arguing RunStaff does not ship decorative modules,
   that was decoration wearing an instrument's clothes.

   What is actually true is that these are three GATES in sequence, each
   of which must pass before the next. So the ring carries three segments
   and lights one more at every stage, and the glyph in the middle names
   what that stage does. The state colour is the row's own signal, so the
   mark says the same thing the copy does. */
.gate{
  width:62px; height:62px; flex:none; position:relative;
  display:grid; place-items:center;
  border-radius:50%; background:var(--panel); box-shadow:var(--sink);
  color:var(--muted);
}
.gate__ring{ position:absolute; inset:0; width:100%; height:100%; }
/* r=18 -> circumference 113.1. Three arcs of 33.7 with a 4-unit gap tile
   the ring exactly; each segment is offset by one pitch (37.7). */
.gate__seg{
  fill:none; stroke:rgba(150,138,116,.42); stroke-width:3.4; stroke-linecap:butt;
  stroke-dasharray:33.7 79.4;
  transform:rotate(-90deg); transform-origin:50% 50%;
  transition:stroke .3s var(--ease);
}
.gate__seg:nth-child(2){ stroke-dashoffset:-37.7; }
.gate__seg:nth-child(3){ stroke-dashoffset:-75.4; }
.gate--1 .gate__seg:nth-child(1),
.gate--2 .gate__seg:nth-child(-n+2),
.gate--3 .gate__seg{ stroke:currentColor; }
.gate__ico{ width:22px; height:22px; color:currentColor; position:relative; }
/* the row's signal colour drives both ring and glyph */
.lockrow--live .gate{ color:var(--sig-live); }
.lockrow--done .gate{ color:var(--sig-ok); }
.lockrow__no{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:12px; letter-spacing:.14em; color:var(--muted); display:block;
}
.lockrow h3{ font-size:22px; margin:3px 0 6px; color:var(--ink); }
.lockrow p{ font-size:14px; color:var(--muted); line-height:1.5; }
.lockrow--live{ box-shadow:var(--raise-hi); }
.lockrow--live h3{ color:var(--orange-ink); }
.lockrow--done h3{ color:var(--green); }



/* ── 13. USE CASES ─────────────────────────────────────────────
   Replaced a 9x6 availability matrix. Fifty-four cells that almost all
   said "included" re-argued the section's own first sentence; the only
   column carrying information was which feature a sector reaches for
   first, and that is now the whole list. */

/* Six full-width rows spent 1,094px on ~40 words and left a measured
   mean of 461px — 41.8% of every row — empty on the right, which read as
   thin rather than as spacious. Three up, two rows.
   The sector name is a <b> inside the sentence, not a separate <h3>: as
   a heading it left the sentence a lowercase fragment ("reaches first
   for…") that a screen-reader user hit as a broken heading. */
.reach{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(auto-fit,minmax(288px,1fr));
  gap:clamp(12px,1.6vw,18px);
}
.reach__row{
  display:grid; grid-template-columns:auto minmax(0,1fr);
  align-items:start; gap:13px;
  background:var(--plate-face); border-radius:var(--r-sm);
  padding:clamp(17px,2vw,22px) clamp(17px,2vw,22px);
  box-shadow:var(--raise-lo);
  transition:transform .18s var(--ease), box-shadow .18s var(--ease);
}
.reach__row:hover{ transform:translateY(-3px); box-shadow:var(--raise); }
.reach__what{ font-size:15.5px; color:var(--muted); line-height:1.5; margin:0; }
/* Inline, not display:block. Folding the <h3> into the sentence fixed it
   semantically, but a block-level name put the break straight back and it
   still read as a heading followed by a lowercase fragment. It is one
   sentence, so it is set as one. */
.reach__who{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:1.28em; text-transform:uppercase;
  color:var(--ink); line-height:1;
}
.reach__hi{ color:var(--orange-deep); font-weight:600; }

/* engraved, not raised: reference set into the ground rather than a
   thing you act on — the same material rule the comparison list and
   the security list follow */
.notebar{
  display:flex; gap:15px; align-items:flex-start;
  margin-top:clamp(22px,2.8vw,32px);
  background:var(--steel); border-radius:var(--r);
  padding:clamp(20px,2.4vw,26px); box-shadow:var(--sink);
}
.notebar p{ font-size:14.5px; color:var(--muted); line-height:1.55; }
.notebar b{ color:var(--ink); }


/* ── 14. FEATURE CHIPS ─────────────────────────────────────────── */

.grid12{ display:grid; grid-template-columns:repeat(auto-fill,minmax(258px,1fr)); gap:clamp(12px,1.6vw,18px); }
/* Icon beside the heading, not stacked above it — same change as .wtile.
   A 36px plate on its own line cost a full line of height on all twelve. */
.chip{
  display:grid; grid-template-columns:auto 1fr; column-gap:12px;
  align-items:start;
  background:var(--plate-face);
  border-radius:var(--r-sm); padding:20px 20px 18px; box-shadow:var(--raise-lo);
  transition:transform .18s var(--ease), box-shadow .18s var(--ease);
}
/* start, not center: the body spans heading + copy + thumbnail, so a
   centred plate drifts to the middle of the card instead of the heading */
.chip .plate{ grid-column:1; grid-row:1; align-self:start; }
.chip__body{ grid-column:2; grid-row:1; }
.chip:hover{ transform:translateY(-3px); box-shadow:var(--raise); }
.chip .plate{ margin-bottom:0; }
.chip h3{ font-size:19px; margin-bottom:7px; }
.chip p{ font-size:15px; color:var(--muted); line-height:1.5; }
.chip .fthumb{ margin-top:13px; }

/* Each chip's screen is now its own disclosure, same contract as a week
   card (panelCtl in main.js): heading and the one line of copy always
   show, the screen is a click away. A group used to hide every screen
   in it behind one big toggle; now the group is always visible (see
   .undrgrp__hd) and this is the thing that actually expands. */
.chip__hd{ margin:0; font:inherit; }
.chip__btn{
  width:100%; display:flex; align-items:center; gap:8px;
  padding:0; background:none; border:0; cursor:pointer;
  text-align:left; font:inherit; color:inherit;
}
.chip__btn:focus-visible{ outline:3px solid var(--orange-btn); outline-offset:2px; }
.chip__t{ transition:color .2s var(--ease); }
.chip__btn:hover .chip__t{ color:var(--orange-ink); }
.chip__chev{
  flex:none; width:8px; height:8px; margin-left:auto;
  border-right:2px solid var(--orange-ink); border-bottom:2px solid var(--orange-ink);
  transform:rotate(45deg) translate(-1px,-1px);
  transition:transform .3s var(--ease);
}
.chip.is-open .chip__chev{ transform:rotate(225deg) translate(-1px,-1px); }
.chip__panel{ overflow:hidden; transition:height .36s var(--ease); }
.chip.is-instant .chip__panel{ transition:none; }


/* ── everything underneath: two groups, always open ──────────────
   Structure now mirrors the Week's cadence bands exactly: the group
   itself is a label, not a toggle -- what used to hide every screen in
   it behind one button now always shows heading + one line per screen,
   same as a closed week card. Each screen expands on its own
   (.chip__btn), and one control per group opens or closes all of them
   at once (.bandall, injected by main.js, same as the week's per-band
   control). */
.undr{ display:flex; flex-direction:column; gap:clamp(16px,2vw,24px); }
.undrgrp{
  background:var(--plate-face); border-radius:var(--r);
  box-shadow:var(--raise-lo); overflow:hidden;
}
/* This group used to be the thing you clicked to reveal its screens at
   all -- one button, everything behind it. Now it matches the week's
   bands: always showing what it holds, with each screen its own
   disclosure below (see .chip__btn) and one all-in-one control per
   group (see .bandall, injected by main.js) instead of a single big
   toggle over the whole batch. */
.undrgrp__hd{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto auto;
  align-items:center; gap:clamp(12px,1.6vw,18px);
  padding:clamp(16px,1.9vw,22px) clamp(17px,2.1vw,26px);
  margin:0; font:inherit; color:var(--ink);
}
/* .bandall's colors assume the dark #week ground it was built for --
   this is its first appearance on a light section, so it needs the
   inverse pair, same as .fthumb and .plate already carry per ground. */
.undrgrp__hd .bandall{ border-color:rgba(24,33,26,.2); color:var(--muted); }
.undrgrp__hd .bandall:hover{ border-color:var(--orange-btn); color:var(--ink); }
.undrgrp__t{
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:clamp(20px,2.2vw,26px); text-transform:uppercase; line-height:1.05;
}
.undrgrp__sub{
  grid-column:2; grid-row:2; font-size:14.5px; color:var(--muted);
  line-height:1.45; margin-top:4px;
}
.undrgrp__n{
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase; letter-spacing:.08em;
  color:var(--orange-ink); background:var(--panel); box-shadow:var(--sink-lo);
  padding:7px 11px; border-radius:999px; white-space:nowrap;
}
.undrgrp__inner{ padding:2px clamp(17px,2.1vw,26px) clamp(20px,2.4vw,28px); }
/* Found the actual cause of the icon/heading misalignment: h1-h3 get
   margin:0 in the base reset, h4 was never included, so the browser's
   default ~25px top margin on h4 (1.33em at 19px) was pushing every chip
   heading down from the icon beside it -- not a grid/align-items issue,
   which is why tweaking those never fixed it. */
.undrgrp .chip h4{ font-size:19px; margin:0 0 7px; }
@media (max-width:640px){
  .undrgrp__n{ grid-column:2; grid-row:3; justify-self:start; margin-top:9px; }
  .undrgrp__hd{ grid-template-columns:auto minmax(0,1fr) auto; }
  .undrgrp__hd .bandall{ grid-column:2; grid-row:3; justify-self:end; margin-top:9px; }
}

/* ── 15. PRICING ───────────────────────────────────────────────── */

.terms{
  display:flex; gap:8px; justify-content:center;
  background:var(--steel); border-radius:var(--r-sm);
  padding:7px; box-shadow:var(--sink); width:fit-content;
  margin:0 auto 14px;
}
.term{
  background:transparent; border:0; border-radius:7px; cursor:pointer;
  padding:12px 24px; color:var(--muted);
  font:700 13px/1.2 'Barlow',sans-serif; text-transform:uppercase; letter-spacing:.05em;
  transition:box-shadow .18s var(--ease), color .18s;
}
.term small{ display:block; font-size:10.5px; font-weight:600; letter-spacing:.04em; text-transform:none; margin-top:3px; }
.term.is-on{ background:var(--panel); color:var(--orange-ink); box-shadow:var(--raise-lo); }

/* Cards were top-aligned and ragged-bottom (398 / 507 / 375px), so the
   three CTAs landed 131px apart with the FLAGSHIP one lowest — the exact
   inverse of the intended emphasis. Equal height, CTA pinned to the
   bottom, one baseline to scan across. */
.plans{ display:grid; grid-template-columns:repeat(auto-fit,minmax(276px,1fr)); gap:clamp(16px,2vw,24px); align-items:stretch; }
.plan{ display:flex; flex-direction:column; }
.plan__cta{ margin-top:auto; }
.plan{ padding:clamp(26px,3vw,34px); position:relative; }
.plan--lead{ box-shadow:var(--raise-hi); }
.plan__flag{
  position:absolute; top:-11px; left:clamp(26px,3vw,34px);
  background:var(--orange-btn); color:#fff;
  /* 11px, not the 10px this was. The flag used to read "Most venues" —
     decorative emphasis, where size barely mattered. It now carries the
     plan's actual venue range, so it is information a buyer reads, and
     10px uppercase at .1em tracking is below where that is comfortable. */
  font:700 11px/1 'Barlow',sans-serif; text-transform:uppercase; letter-spacing:.1em;
  padding:7px 12px; border-radius:5px;
}
.plan h3{ font-size:29px; }
.plan__for{ font-size:13px; color:var(--muted); margin:5px 0 18px; }
.plan__price{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.plan__price strong{
  font-family:'Big Shoulders Display',sans-serif; font-weight:900;
  font-size:50px; line-height:1; color:var(--ink);
}
/* The unit is the difference between "£7" and "£7 per EXTRA venue". At 13px
   beside a 46px numeral it was decoration; it now reads as part of the price. */
.plan__unit{ font-size:16px; font-weight:600; color:var(--ink); }
.plan__unit b{ font-weight:700; }
.plan__alt{ font-size:13px; color:var(--muted); margin:5px 0 12px; }
.plan__total{
  font-size:14.5px; line-height:1.45; color:var(--ink);
  background:var(--ground-tint); border-radius:8px;
  padding:9px 12px; margin:0 0 18px;
}
.plan .bul{ margin-bottom:24px; }
.plan__cta{ width:100%; }

/* Price ladder and comparison, side by side. Apart, the examples were a
   thin row of five and the table a full-width band of 13px text with a lot
   of empty middle; together they fill the same measure and read as one
   answer to "what does this cost, and against what". */
/* .stepper rules removed with the Core Four cards they served — the pain
   accordion's .run cross-fades the same beats in a single stage. */

.paypair{
  margin-top:clamp(30px,3.6vw,44px);
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(20px,3vw,36px); align-items:start;
}
@media (max-width:900px){ .paypair{ grid-template-columns:1fr; } }

.examples__h{ font-size:20px; margin-top:0; }
.examples{ margin-top:16px; display:grid; grid-template-columns:1fr; gap:10px; }
/* one row per venue count — a ladder, so 1 -> 2 -> 3 -> 5 is readable down
   the column instead of across five narrow cards */
.example{
  background:var(--plate-face);
  border-radius:var(--r-sm); padding:13px 16px; box-shadow:var(--raise-lo);
  display:grid; grid-template-columns:1fr auto; align-items:baseline; column-gap:14px;
}
.example__n{ grid-column:1; grid-row:1; font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:var(--muted); }
.example__p{
  grid-column:2; grid-row:1; text-align:right;
  font-family:'Big Shoulders Display',sans-serif; font-weight:800;
  font-size:27px; color:var(--ink); line-height:1;
}
.example__p small{ font-size:13px; font-family:'Barlow',sans-serif; font-weight:600; color:var(--muted); }
.example__m{ grid-column:2; grid-row:2; text-align:right; font-size:13px; color:var(--muted); margin-top:2px; }

/* heading sits OUTSIDE the plate, level with "What you'd actually pay" on
   the left — it was inside, so the two columns started at different heights */
.compare{
  margin-top:16px; background:var(--steel);
  border-radius:var(--r); padding:clamp(22px,2.6vw,30px); box-shadow:var(--sink);
}
/* bottom margin carries the gap the .terms rule used to own, so the raised
   lead card and its -11px flag clear this line instead of sitting over it */
.terms__note{
  text-align:center; font-size:13.5px; color:var(--muted);
  margin:0 auto clamp(34px,4vw,50px); line-height:1.5; max-width:52ch;
}
/* The two columns had no names, so which side was the competitor had
   to be inferred from a strikethrough. Named, with the same three-track
   grid as the rows so the labels sit over their own columns. */
.compare__key{
  display:grid; grid-template-columns:1fr 22px 1fr; gap:0 10px;
  padding:0 0 10px; margin:0 0 4px; border-bottom:1.5px solid rgba(150,138,116,.45);
  font:700 10.5px/1 'Barlow',sans-serif; text-transform:uppercase; letter-spacing:.1em;
}
.compare__key span{ grid-area:1/1; color:var(--muted); }
.compare__key b{ grid-area:1/3; color:var(--orange-ink); font-weight:700; }
@media (max-width:760px){
  .compare__key{ grid-template-columns:1fr; gap:3px; }
  .compare__key span{ grid-area:1/1; }
  .compare__key b{ grid-area:2/1; }
}
.compare li{
  display:grid; grid-template-columns:1fr 22px 1fr; gap:10px;
  align-items:center; padding:11px 0; font-size:15px;
  border-bottom:1px solid rgba(150,138,116,.32);
}
.compare li:last-child{ border-bottom:0; }
.compare li span{ grid-area:1/1; color:var(--muted); text-decoration:line-through; text-decoration-color:rgba(150,138,116,.6); }
.compare li::before{ content:"→"; grid-area:1/2; color:var(--orange); font-weight:700; font-size:13px; text-align:center; }
.compare li b{ grid-area:1/3; color:var(--ink); font-weight:600; }

.fineprint{ margin-top:22px; font-size:13.5px; color:var(--muted); line-height:1.6; }


/* ── 16. FAQ ───────────────────────────────────────────────────── */

.faq{ display:flex; flex-direction:column; gap:10px; }
.qa{
  background:var(--plate-face);
  border-radius:var(--r-sm); box-shadow:var(--raise-lo); overflow:hidden;
}
/* The answer starts in the dead space beside the question, so a reader gets
   the gist of all six without clicking anything; expanding adds the detail
   rather than revealing the answer for the first time. */
.qa summary{
  list-style:none; cursor:pointer; padding:18px 52px 18px 22px;
  font-family:'Big Shoulders Display',sans-serif; font-weight:700;
  font-size:21px; text-transform:uppercase; color:var(--ink);
  position:relative; min-height:26px;
  display:grid; grid-template-columns:minmax(0,auto) minmax(0,1fr);
  align-items:baseline; gap:6px 18px;
}
.qa__peek{
  font-family:'Barlow',sans-serif; font-weight:400; font-size:15px;
  text-transform:none; color:var(--muted); line-height:1.45;
}
.qa[open] .qa__peek{ display:none; }
@media (max-width:720px){
  .qa summary{ grid-template-columns:1fr; }
}
.qa summary::-webkit-details-marker{ display:none; }
.qa summary::after{
  content:""; position:absolute; right:22px; top:50%;
  width:11px; height:11px; margin-top:-6px;
  border-right:2.5px solid var(--orange); border-bottom:2.5px solid var(--orange);
  transform:rotate(45deg); transition:transform .22s var(--ease);
}
.qa[open] summary{ color:var(--orange-ink); }
.qa[open] summary::after{ transform:rotate(-135deg); }
.qa p{ padding:0 22px 20px; font-size:14.5px; color:var(--muted); line-height:1.6; }


/* ── 17. TRUST / ABOUT / CTA / FOOTER ──────────────────────────── */

.about{ font-size:clamp(16px,1.7vw,19px); color:var(--muted); line-height:1.66; margin-top:20px; }
.about2{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.85fr); gap:clamp(28px,4vw,56px); align-items:start; }
.trust__h{ font-size:22px; margin-bottom:10px; }
.trust__copy p{ font-size:14.5px; color:var(--muted); margin-bottom:18px; }
.trust__list{
  background:var(--steel); border-radius:var(--r);
  padding:clamp(20px,2.4vw,28px); box-shadow:var(--sink);
}
.trust__list li{
  display:flex; align-items:center; gap:13px;
  padding:13px 4px; font-size:14.5px; font-weight:600; color:var(--ink);
  border-bottom:1px solid rgba(150,138,116,.32);
}
.trust__list li:last-child{ border-bottom:0; }
.trust__list em{
  margin-left:auto; font-style:normal; font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:.09em; color:var(--muted);
}

.cta{ background:var(--orange-btn); color:#fff; padding:clamp(60px,7vw,96px) 0; }
.cta__in{ text-align:center; display:flex; flex-direction:column; align-items:center; gap:18px; }
.cta h2{ font-size:clamp(34px,5vw,62px); }
.cta p{ font-size:clamp(16px,1.7vw,19px); max-width:46ch; color:rgba(255,255,255,.92); }
.cta__actions{ display:flex; gap:14px; flex-wrap:wrap; justify-content:center; margin-top:8px; }

.foot{ background:var(--ink-deep); color:var(--muted-dark); padding:40px 0; }
.foot__in{ display:flex; flex-wrap:wrap; align-items:center; gap:22px; }
.foot__links{ display:flex; gap:20px; flex-wrap:wrap; margin-left:auto; }
.foot__links a{
  font:600 12px/1 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.05em; text-decoration:none; color:var(--muted-dark);
  /* side padding so a short label ("About") still clears 44px wide */
  display:inline-flex; align-items:center; min-height:26px; padding:2px 8px;
}
.foot__links a:hover{ color:var(--panel); }
.foot__cta{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.foot__ask{ padding:12px 18px; font-size:12.5px; }
.foot__legal{ font-size:12px; width:100%; padding-top:18px; border-top:1px solid #433d33; }


/* ── 18. CONTACT DIALOG ─────────────────────────────────────────
   Same material language as the page: a raised plate on a darkened
   ground, engraved fields. The Cal.com booking modal is Cal's own
   surface and is themed through its embed config in main.js — this
   one is ours, and the two are kept visually close so the site does
   not read as two different products. */

.cdlg{
  border:0; padding:0; background:none; color:var(--ink);
  width:min(560px, calc(100vw - 28px));
  max-height:min(88vh, 900px);
  border-radius:var(--r); overflow:visible;
}
.cdlg::backdrop{
  background:rgba(20,30,22,.62);
  backdrop-filter:blur(3px) saturate(.9);
}
.cdlg__plate{
  position:relative;
  background:var(--plate-face);
  border-radius:var(--r);
  box-shadow:var(--raise-hi);
  padding:clamp(22px,3.4vw,34px);
  max-height:inherit; overflow-y:auto;
}
.cdlg__plate:focus{ outline:none; }
.cdlg__x{
  position:absolute; top:10px; right:10px;
  width:38px; height:38px; border:0; border-radius:var(--r-sm);
  background:var(--panel); box-shadow:var(--sink-lo);
  color:var(--muted); font:400 22px/1 'Barlow',sans-serif; cursor:pointer;
}
.cdlg__x:hover{ box-shadow:var(--raise-lo); color:var(--ink); }
.cdlg__h{ font-size:clamp(28px,4vw,38px); }
.cdlg__lede{ margin-top:10px; color:var(--muted); font-size:15.5px; max-width:44ch; }

.cdlg__done{ text-align:center; padding:26px 8px 12px; display:grid; justify-items:center; gap:14px; }
.cdlg__done[hidden], .cdlg__body[hidden]{ display:none; }
.cdlg__done .cdlg__lede{ margin-top:0; }
.cdlg__done:focus-visible{ outline:none; }

/* fields — engraved, matching the recessed controls used elsewhere */
.cform{ margin-top:22px; }
.cform__grid{ display:grid; grid-template-columns:1fr 1fr; gap:16px 18px; }
.cfield{ display:grid; gap:7px; margin:0; min-width:0; border:0; padding:0; }
.cfield--wide{ grid-column:1 / -1; }
.cfield__lab{
  font:700 12px/1.2 'Barlow',sans-serif; text-transform:uppercase;
  letter-spacing:.06em; color:var(--muted); padding:0;
}
.cfield__opt{ font-weight:500; text-transform:none; letter-spacing:0; opacity:.8; }
.cfield__in{
  font:400 15.5px/1.4 'Barlow',sans-serif; color:var(--ink);
  background:var(--panel); border:0; border-radius:var(--r-sm);
  box-shadow:var(--sink-lo); padding:13px 14px; width:100%;
  min-height:48px;
}
.cfield__in--area{ resize:vertical; min-height:104px; }
.cfield__in::placeholder{ color:#5d6a5d; }
.cfield__in[aria-invalid="true"]{ box-shadow:var(--sink-lo), inset 0 0 0 2px var(--orange-btn); }
.cfield__err{ font:600 13px/1.35 'Barlow',sans-serif; color:var(--orange-ink); }

.cradios{ display:flex; gap:10px; flex-wrap:wrap; }
.cradio{
  display:inline-flex; align-items:center; gap:9px; cursor:pointer;
  background:var(--panel); box-shadow:var(--sink-lo);
  border-radius:var(--r-sm); padding:12px 16px; min-height:46px;
  font:600 14.5px/1 'Barlow',sans-serif; color:var(--ink);
}
.cradio input{ accent-color:var(--orange-btn); width:17px; height:17px; margin:0; }
.cradio:has(input:checked){ box-shadow:var(--raise-lo); color:var(--orange-ink); }

.cform__foot{ margin-top:22px; display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.cform__send[disabled]{ opacity:.65; cursor:progress; }
.cform__status{ font:600 14px/1.4 'Barlow',sans-serif; color:var(--muted); }
.cform__status[data-state="bad"]{ color:var(--orange-ink); }

@media (max-width:560px){
  .cform__grid{ grid-template-columns:1fr; }
}


/* ── 19. MOTION ────────────────────────────────────────────────────
   Safety rule: the RESTING state is always the visible one and
   motion only adds an entrance (fill-mode backwards). If animation
   never runs — reduced motion, a frozen background tab, an embedded
   viewer — the page is simply complete and static. A settle guard
   retires each entrance once it should have finished, so a stalled
   timeline can never strand content behind an opening keyframe.
   All of it is gated on [data-anim="on"], set by an inline script
   in <head> that opts out entirely for prefers-reduced-motion.
   ──────────────────────────────────────────────────────────────── */

.reveal{ opacity:0; transform:translateY(18px); transition:opacity .6s var(--ease), transform .6s var(--ease); }
.reveal.is-in{ opacity:1; transform:none; }

@keyframes pulse{
  0%,100%{ box-shadow:0 0 9px rgba(217,96,15,.85); }
  50%    { box-shadow:0 0 15px rgba(217,96,15,1), 0 0 3px rgba(217,96,15,.9); }
}

[data-anim="on"] .stage__cap .led--live{ animation:pulse 2.6s ease-in-out infinite; }

/* needles land on their own resting angle (no "to" keyframe).
   Eased-out, not bounced: the previous curve overshot past the resting
   angle. That would be right for a needle reading a real value, but these
   angles are fixed decoration, so the overshoot was just bounce. */
/* The gates light in order, so the ring reads as a sequence rather than
   three marks arriving at once. No fill-mode: the resting state is the
   LIT state, so a throttled animation clock leaves the marks correct
   rather than blank. */
@keyframes gateIn{ from{ stroke-dashoffset:0; opacity:0; } }
[data-anim="on"] .lockrows.is-swept .gate__seg{ animation:gateIn .6s var(--ease); }
[data-anim="on"] .lockrows.is-swept .lockrow:nth-child(2) .gate__seg{ animation-delay:.18s; }
[data-anim="on"] .lockrows.is-swept .lockrow:nth-child(3) .gate__seg{ animation-delay:.36s; }

/* settle guard — see note above */
[data-anim="on"] .anim-settled .gate__seg{ animation:none !important; }


/* ── 20. RESPONSIVE ────────────────────────────────────────────── */

/* Eight links and two CTAs fit the capped 1104px bar with room to spare, but
   below ~1125px the bar's own 4vw side padding eats the margin and the demo
   button ran off the edge. The strip goes tighter here rather than dropping
   an item or wrapping to two lines — it is a control strip, so it is allowed
   to sit closer to the edge than the page content does. */
@media (max-width:1160px){
  .nav__in{ padding-inline:24px; gap:16px; }
  .nav__links{ gap:14px; }
}

@media (max-width:1080px){
  .nav__links{ display:none; }
  .mnav{ display:block; }
  .nav__in{ gap:12px; }
  .nav__ask{ display:none; }
  .nav__cta{ margin-left:auto; }
}

@media (max-width:1080px){
  .lockwrap{ grid-template-columns:1fr; }
  .about2{ grid-template-columns:1fr; }
}

/* Four tiles across stop being four tiles across here: below this the
   row stacks full width, in the same order, and each drawer opens
   directly under its own tile. Same pattern, one column. */
@media (max-width:1024px){
  .pain.is-live{ grid-template-columns:1fr; }
  /* :nth-child(n) is not decoration — it matches the specificity of the
     per-column rules above, which otherwise win and leave every tile
     placed in an implicit column it no longer has. */
  .pain.is-live > .pain__item:nth-child(n) > .pain__hd,
  .pain.is-live > .pain__item:nth-child(n) > .pain__panel{ grid-row:auto; grid-column:auto; }
  .pain.is-live .pain__panel::before{ left:clamp(18px,4vw,30px); }
}

@media (max-width:900px){
  /* Copy first, then the run beneath it, capped so a portrait phone
     screen does not become the whole viewport. The cross-fade is the
     same one — there is no reason to switch pattern on a phone. */
  .pain__grid{ grid-template-columns:1fr; gap:clamp(22px,4vw,32px); }
  .pain__cols{ gap:clamp(16px,3vw,24px); }
  /* one column, screen first then its caption — the side column only
     earns its keep where there is width to put it in */
  .run{ grid-template-columns:1fr; max-width:300px; margin-inline:auto; }
  .run__lead,
  .run__stage,
  .run__side{ grid-column:1; grid-row:auto; }
  .run__side{ margin-top:11px; }
  .run__cap{ min-height:calc(2 * 1.35em + 20px); }
  .run__ctrls{ flex-direction:row; align-items:center; }
  .run__hold{ margin-left:auto; flex:none; }
  /* 45px of tap target around a 5px bar */
  .run__pip{ padding:20px 0; }

  /* Stacked, the strapline leads: there is no room on a phone for a
     quiet first glance before the real question. The seam turns with
     the layout, from a channel between columns to one across them. */
  .hero__split{ grid-template-columns:1fr; }
  .hero__split::after{ display:none; }
  .hero__hook{ grid-column:1; grid-row:1; padding-left:0; padding-bottom:clamp(24px,4.5vw,32px); }
  .hero__ctx { grid-column:1; grid-row:2; padding-right:0; padding-top:clamp(24px,4.5vw,32px); }
  /* stacked, the seam turns with the layout: the same channel, cut
     across the two blocks instead of between them */
  .hero__hook::before{
    display:block; content:""; position:absolute;
    left:0; right:0; top:auto; bottom:0; width:auto; height:1px;
    background:linear-gradient(90deg,transparent,rgba(72,102,72,.42) 8%,rgba(72,102,72,.42) 92%,transparent);
    box-shadow:0 1px 0 rgba(255,253,244,.9);
  }
  .hero__strap{ max-width:none; }
}

@media (max-width:760px){
  .compare li{ grid-template-columns:1fr; gap:1px; }
  .compare li span{ grid-area:1/1; }
  .compare li::before{ grid-area:2/1; text-align:left; }
  .compare li b{ grid-area:3/1; }
}

@media (max-width:480px){
  .pain__btn{ gap:12px; }
}


/* ── 20b. TAP TARGETS ───────────────────────────────────────────
   Measured at 375px, 35 controls rendered below the 44x44 minimum —
   including all thirteen week cards at 34px and the nine section-rail
   links at 28px. PRODUCT.md asks for large touch targets specifically
   because staff use this one-handed on a busy floor; the marketing site
   is evaluated the same way. Height only: none of these need to grow
   horizontally, and min-height leaves every existing layout intact. */
@media (max-width:1080px){
  .wtile__btn{ min-height:44px; }
  .wk__pill{ min-height:44px; }
  .chip__btn{ min-height:44px; }
  .pain__btn{ min-height:52px; }

  .srail a{ min-height:44px; }
  .srail{ padding-block:7px; }
  .mnav summary{ min-width:44px; min-height:44px; }
  .mnav__panel a{ min-height:44px; display:flex; align-items:center; }
  .mnav__ask{ min-height:44px; }

  .brand, .brand--foot{ min-height:44px; display:inline-flex; align-items:center; }
  .btn{ min-height:44px; }
  .linkbtn{ min-height:44px; display:inline-flex; align-items:center; }
  .foot__links a{ min-height:44px; display:inline-flex; align-items:center; }
  .qa summary{ min-height:44px; }
}


/* ── 21. MOTION PREFERENCES ────────────────────────────────────── */

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{ opacity:1; transform:none; }
  .nav__ind{ transition:none; }
  /* Nothing advances on its own here, so a Pause control would be a
     button that pauses nothing. The pips still step through the run. */
  .run__hold{ display:none; }

  /* ── and then give the feedback back ──────────────────────────
     The blanket kill above is right about MOTION — nothing should
     travel, scale or auto-advance. It is wrong about STATE. Applied
     to * it also flattens the accordion opening, the tab changing
     and every hover and focus, so a visitor who asked for less
     motion loses the one signal that tells them their click landed.
     Reduced motion means fewer large movements, not no change.

     So: colour and opacity come back at 120ms, which reads as a
     response rather than as movement. Geometry stays off — the
     height transitions on the three accordions are exactly the kind
     of large travel this query exists to stop, and they are left at
     .001ms so panels still snap open instantly. */
  a,button,summary,input,select,textarea,
  .pain__tag,.pain__cost,.pain__gain,.wk__pill,.run__pip,.btn{
    transition-property:color,background-color,border-color,box-shadow,opacity !important;
    transition-duration:120ms !important;
  }
}


/* ── microtype floors on small screens ──────────────────────────
   An audit on 25 Aug 2026 measured four labels below 12px on a 375px
   phone: .run__who at 9.5, .ba__k at 10.5, .pain__cat and .saving__k
   at 11. Contrast was never the problem — .run__who measures 14.26:1 —
   size was. PRODUCT.md describes this audience as one-handed, phone in
   an apron, on a busy floor, and .run__who is load-bearing: it is what
   tells you whose phone you are looking at across a 14-frame run. The
   brief's own reason for adding it was that the caption says it "only
   if read", which is exactly the argument against setting it at 9.5px.

   Desktop keeps the tighter sizes — these are stamped plate labels and
   the compression is the point there. Only the phone gets the floor,
   where the type is furthest from the eye and the plates have room. */
@media (max-width:700px){
  .run__who{ font-size:11px; padding:4px 8px; }
  .ba__k{ font-size:11.5px; width:52px; }
  .pain__cat,.saving__k{ font-size:11.5px; }
}

/* ── 22. MOBILE SECTION RAIL ────────────────────────────────────
   Desktop has a persistent nav; small screens had only a hamburger,
   which hides both position and options behind a tap. On a page this
   long that is the wrong trade. The rail is always visible, scrolls
   horizontally, and marks the section in view. Desktop hides it —
   the nav already does this job there. */
.srailwrap{ display:none; position:relative; }
.srail__btn{ display:none; }

@media (max-width:1080px){
  .srailwrap{
    display:block; position:sticky; top:60px; z-index:40;
    background:var(--nav-bg);
    backdrop-filter:saturate(1.4) blur(10px);
    border-bottom:1px solid var(--nav-border);
  }
  .srail{
    display:flex; gap:6px;
    padding:8px 40px;
    overflow-x:auto; -webkit-overflow-scrolling:touch;
    scrollbar-width:none; scroll-behavior:smooth;
  }
  .srail::-webkit-scrollbar{ display:none; }
  .srail a{
    flex:none; text-decoration:none;
    font:700 10.5px/1 'Barlow',sans-serif;
    text-transform:uppercase; letter-spacing:.05em;
    color:#2b2721; background:#f4f1ea;
    /* 28px was well under the 44px touch minimum on the one control a
       thumb reaches for most on this page. Section 20b sets the same
       floor, but this rule is later in the cascade and was winning. */
    padding:7px 14px; border-radius:6px; min-height:44px;
    display:inline-flex; align-items:center;
    box-shadow:0 1px 2px rgba(0,0,0,.35);
  }
  .srail a[aria-current="true"]{
    color:#fff; background:var(--orange-btn);
    box-shadow:0 0 0 2px rgba(255,255,255,.25);
  }
  /* the rail scrolls, so say so: arrows plus a fade at each end */
  .srail__btn{
    position:absolute; top:0; bottom:0; width:44px; z-index:2;
    border:0; cursor:pointer; color:var(--nav-ink);
    display:grid; place-items:center; padding:0;
    font:700 15px/1 'Barlow',sans-serif;
  }
  .srail__btn--prev{ left:0;  background:linear-gradient(90deg,var(--nav-bg) 55%,transparent); }
  .srail__btn--next{ right:0; background:linear-gradient(270deg,var(--nav-bg) 55%,transparent); }
  .srail__btn[hidden]{ display:none; }

  /* The week's screens used to be forced on every reader — 20 tiles
     x ~140px was roughly 2,800px of phone scroll for pictures the copy
     already covered, so they were hidden here. They now sit behind the
     card expand, which the reader opens deliberately, so hiding them
     would delete content someone asked to see. The rule is gone. */
}

@media (max-width:640px){
  /* feature chips keep their image — there the picture is the point */
  .chip .fthumb{ aspect-ratio:16/9; }
}

/* ── screens at their own shape ───────────────────────────────────────
   The .fthumb box forced a landscape crop, which was right while every
   capture was a hand-picked horizontal slice. The batches from 25-26 Aug
   are portrait, framed around a whole piece of UI, so the tiles stopped
   coercing aspect: --nat is one screen, --strip is two to four.

   These live at the end of the file on purpose. .sec--dark .fthumb,
   .wtile__inner .fthumb, .alerts__item .fthumb and .chip .fthumb are all
   (0,2,0) and all set aspect-ratio or background. A single-class opt-out
   loses to every one of them silently. */
.fthumb.fthumb--nat,
.fthumb.fthumb--strip{
  aspect-ratio:auto; background:none; box-shadow:none;
  border-radius:0; overflow:visible;
}

/* ONE rule sizes every screen, single or in a strip.
   They diverged before -- a strip got a fixed height while a single got a
   max-height that a narrow card never reached -- so a two-screen alerts
   card rendered 310px tall next to a one-screen neighbour at 191px, and
   nothing on the page looked related to anything else.

   Height is the constant and width follows the screen's own aspect, so
   nothing is squashed and cover only ever bites when a very wide crop
   would overflow its card. */
.fthumb.fthumb--nat img,
.fthumb.fthumb--strip img{
  height:var(--shot-h); width:auto; max-width:100%;
  object-fit:cover; object-position:top center;
  border-radius:9px; background:var(--steel-tint); box-shadow:var(--sink-lo);
}

/* Height scales with the card the screen sits in: a 175px screen that
   reads fine in a quarter-width alerts card is lost in a full-width one. */
.fthumb.fthumb--nat,
.fthumb.fthumb--strip                        { --shot-h:225px; }
.alerts__item .fthumb.fthumb--nat,
.alerts__item .fthumb.fthumb--strip          { --shot-h:170px; }
.chip .fthumb.fthumb--nat,
.chip .fthumb.fthumb--strip                  { --shot-h:185px; }
.wtile[data-wk-lead] .fthumb.fthumb--nat,
.wtile[data-wk-lead] .fthumb.fthumb--strip   { --shot-h:270px; }

.fthumb.fthumb--nat{ display:flex; justify-content:center; }

/* Measured: .chip columns render ~251px wide, but --shot-h:185px needs
   ~296px to hold these screens (1.5-1.6:1) uncropped — narrower than the
   column has, so cover was cropping every one here, not just the rare
   wide case the rule above expects. Width is the one dimension every
   column actually has in common, so fix that instead and let height
   follow each screen's own shape, uncropped. */
.chip .fthumb.fthumb--nat img,
.chip .fthumb.fthumb--strip img{
  height:auto; width:100%; object-fit:contain;
}

/* Measured 2026-08-27: role-under-min-03.png is 560x200 (2.8:1) sharing a
   strip with two portrait siblings at 811 and 646 tall. A shared
   --shot-h:225px forces it to 630px wide in a 326px card -- cover then
   crops both edges off, cutting the one screen that most needed to stay
   legible. The same fixed height also makes a merely-tall portrait
   (holiday-01, 560x909) render at 139px wide -- readable to no one.
   Width-for-width with the chip fix above: every #week screen sizes to
   the card's own width, never the other way around, so nothing this
   shape-mismatched again gets cropped, and nothing gets shrunk past
   reading just to keep a uniform height across images that were never
   the same shape to begin with. */
.wtile__inner .fthumb.fthumb--nat img,
.wtile__inner .fthumb.fthumb--strip img{
  height:auto; width:100%; object-fit:contain;
}

/* The lead tile spans two grid columns specifically to hold its screens
   (see grid-column:1/-1 above), so at 684px it has room to show both
   live-attendance screens side by side. Paging them as full-width pages
   -- correct for a single narrow column -- instead forced one portrait
   screen to fill the whole 684px, rendering it far larger than the text
   beside it and hiding the second screen behind a page nobody needed.
   Only this tile is wide enough for this; everywhere else still pages. */
.wtile[data-wk-lead] .fthumb.fthumb--strip{
  overflow-x:visible; scroll-snap-type:none;
}
.wtile[data-wk-lead] .fthumb.fthumb--strip picture{
  flex:1 1 0; width:auto; gap:14px;
}
.wtile[data-wk-lead] .fthumb.fthumb--strip{ gap:14px; }

/* Same fault, same fix, found by auditing every image on the page rather
   than one section at a time: the alerts row's five screens run
   1.05-1.44:1, and --shot-h:170px renders three of them under 200px wide
   (alert-lock 178px, alert-wrist/alert-7am 198px, alert-openclose-02
   143px) while cropping the widest (alert-openclose-01) 7% off both
   edges. Width-for-width here too. */
.alerts__item .fthumb.fthumb--nat img,
.alerts__item .fthumb.fthumb--strip img{
  height:auto; width:100%; object-fit:contain;
}

/* The strip scrolls when its screens outrun the card. There is no
   scrollbar: main.js plays it through once when the tile opens and gives
   it dots, so a second screen announces itself rather than waiting behind
   a control nobody looks for. */
.fthumb.fthumb--strip{
  display:flex; align-items:flex-start;
  overflow-x:auto; scroll-snap-type:x mandatory;
  scrollbar-width:none; -ms-overflow-style:none;
}
.fthumb.fthumb--strip::-webkit-scrollbar{ display:none; }
/* Measured 2026-08-27: most of these screens are portrait phone captures,
   narrower than the card once scaled to --shot-h. With picture as
   display:contents and the <img> itself as the only flex/scroll-snap
   item, a narrow image left the card's spare width open for the NEXT
   image to bleed into — paging never showed exactly one screen, only
   ever a variable blend of two. picture is the page now: full card
   width, image centred inside it, so a page is always exactly one
   screen regardless of that screen's own width. */
.fthumb.fthumb--strip picture{
  display:flex; flex:0 0 100%; width:100%; justify-content:center;
  scroll-snap-align:start;
}
.fthumb.fthumb--strip img{ cursor:pointer; }

/* Dots: the way back to a screen the play-once already went past. */
.fdots{
  display:flex; gap:7px; justify-content:center;
  margin:9px 0 0; padding:0; list-style:none;
}
.fdots__b{
  width:8px; height:8px; padding:0; border:0; border-radius:50%;
  background:rgba(255,255,255,.30); cursor:pointer;
  transition:background .2s var(--ease), transform .2s var(--ease);
}
.fdots__b:hover{ background:rgba(255,255,255,.55); }
.fdots__b[aria-current="true"]{ background:var(--orange); transform:scale(1.25); }
.sec--tint .fdots__b{ background:rgba(20,30,20,.22); }
.sec--tint .fdots__b:hover{ background:rgba(20,30,20,.42); }
.fdots__b:focus-visible{ outline:2px solid var(--orange); outline-offset:3px; }

/* One control per band, added by JS beside the band's own label. */
.cadence-band__rail{ position:relative; }
.bandall{
  margin-left:auto; align-self:center; flex:none;
  padding:7px 13px; border-radius:999px;
  border:1px solid rgba(255,255,255,.22); background:transparent;
  color:var(--muted-dark); cursor:pointer;
  font:700 11.5px/1 'Barlow',sans-serif;
  letter-spacing:.09em; text-transform:uppercase; white-space:nowrap;
  transition:border-color .2s var(--ease), color .2s var(--ease);
}
.bandall:hover{ border-color:var(--orange-on-dark); color:var(--panel); }
.bandall:focus-visible{ outline:2px solid var(--orange); outline-offset:3px; }
@media (max-width:520px){ .bandall{ margin:10px 0 0; align-self:flex-start; } }
