/* ==========================================================================
   www.css — the sketchplay.com marketing LAYER.

   Sits over packages/ui-kit/static/skp/ui-kit.css, which owns: the warm
   ink-on-paper neutrals, Manrope + Kanit, the accent mechanism, the motion
   easing, and the semantic colours. This file NEVER redeclares one of those
   except where the override is a deliberate, recorded decision.

   THE FOUR DELIBERATE DEPARTURES FROM THE KIT (approved 2026-08-11):
     1. RADIUS. Kit is 4/8px, "no pill cards, ever" — a law for a dense data
        console. A landing page is not that. Marketing gets 14/22/28px and
        pills on buttons and chips.
     2. ELEVATION. The kit's shadows are barely-there. Marketing cards float.
     3. TYPE SCALE. Kit display tops out ~44px. Marketing opens at 82.
     4. MOTION DURATION. Kit is console-fast (140/220ms). Reveals here run
        620-900ms — same easing curve, longer arc.

   Design source: skpweb design/fixtures/home-v1.html.
   ========================================================================== */

:root{
  /* -- marketing radius + elevation (departures 1 and 2) -- */
  --r-3:22px; --r-4:28px;
  --r-btn:9999px;
  --shadow-3:0 4px 12px rgba(15,15,20,.06), 0 30px 80px rgba(15,15,20,.14);

  /* -- rhythm -- */
  --section:clamp(88px,10vw,152px);
  --gutter:clamp(20px,4vw,48px);
  --maxw:1200px;
  --s-2:8px; --s-3:12px; --s-4:16px; --s-6:24px; --s-8:32px;
  --s-10:40px; --s-16:64px;

  /* -- departure 4 -- */
  --t-slow:680ms;
}
[data-theme="dark"]{
  --shadow-3:0 4px 12px rgba(0,0,0,.5), 0 30px 80px rgba(0,0,0,.6);
}

/* marketing surfaces are soft; scoped to this app only, never pushed to the kit */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
.wrap-narrow{max-width:860px;margin:0 auto;padding:0 var(--gutter)}

body{
  background:var(--bg); color:var(--text);
  font:400 17px/1.6 var(--font-ui);
  -webkit-font-smoothing:antialiased; overflow-x:hidden; margin:0;
}
img{max-width:100%;display:block}
::selection{background:var(--accent);color:var(--on-accent)}

/* ===== dev banding (matches the other public surfaces) ================== */
.env-stripe{position:fixed;top:0;left:0;right:0;height:3px;z-index:100;
  background:repeating-linear-gradient(-45deg,#F59E0B 0 12px,#0F0F14 12px 24px)}
.env-badge{position:fixed;top:10px;right:10px;z-index:100;background:#F59E0B;
  color:#0F0F14;font:800 10.5px/1 var(--font-ui);letter-spacing:.1em;
  padding:5px 9px;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,.25)}
/* On a phone the header collapses to logo + theme + "Book a demo", and this
   badge sat on top of the demo button — covering the primary CTA on every page
   at every phone width. It moves to the opposite corner rather than shrinking,
   because the left side of the header is a wordmark that can take it. */
@media(max-width:640px){.env-badge{right:auto;left:10px;top:auto;bottom:10px}}

/* ===== type (departure 3) =============================================== */
.eyebrow{
  display:inline-block; font:700 11.5px/1 var(--font-ui);
  letter-spacing:var(--tracking-label); text-transform:uppercase;
  color:var(--accent-ink); margin-bottom:20px;
}
.display{font:800 clamp(40px,6.4vw,82px)/1.02 var(--font-ui);letter-spacing:-.035em;text-wrap:balance;margin:0}
/* ⚠️ Every `<br>` in a .display heading MUST have a space in front of it in the
   markup. `display:none` removes the element and takes its line break with it,
   but it does NOT leave a space behind — so "weekend.<br>Then" renders as
   "weekend.Then" on every phone. Four shipped pages had this before anyone
   looked at a 390px screen. */
@media(max-width:700px){.display br{display:none}}
.h2{font:800 clamp(30px,3.8vw,50px)/1.08 var(--font-ui);letter-spacing:-.03em;text-wrap:balance;margin:0}
.h3{font:700 clamp(19px,1.5vw,22px)/1.3 var(--font-ui);letter-spacing:-.015em;margin:0}
.lede{font:400 clamp(17px,1.45vw,20px)/1.55 var(--font-ui);color:var(--text-2);max-width:54ch;text-wrap:pretty;margin:0}

/* ===== buttons — ink is primary, accent is rare (kit law, KEPT) ========= */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:52px;padding:0 26px;border:1px solid transparent;
  border-radius:var(--r-btn);cursor:pointer;text-decoration:none;
  font:700 15px/1 var(--font-ui);letter-spacing:-.005em;white-space:nowrap;
  transition:transform var(--t-fast) var(--ease),box-shadow var(--t-base) var(--ease),
             background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease);
}
.btn:active{transform:scale(.975)}
.btn-ink{background:var(--text);color:var(--bg);box-shadow:var(--shadow-1)}
.btn-ink:hover{box-shadow:var(--shadow-2);transform:translateY(-2px)}
.btn-ghost{background:transparent;color:var(--text);border-color:var(--border-strong)}
.btn-ghost:hover{background:var(--surface-2);border-color:var(--text-3);transform:translateY(-2px)}
.btn-sm{min-height:42px;padding:0 18px;font-size:14px}
.btn svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

/* ===== nav ============================================================== */
.nav{position:sticky;top:0;z-index:50;border-bottom:1px solid transparent;
  transition:background var(--t-base) var(--ease),border-color var(--t-base) var(--ease)}
.nav.is-stuck{
  background:color-mix(in srgb,var(--bg) 82%,transparent);
  backdrop-filter:blur(14px) saturate(1.4);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
  border-bottom-color:var(--border);
}
.nav-in{display:flex;align-items:center;gap:var(--s-8);height:76px}
.wordmark{font:italic 800 25px/1 var(--font-brand);letter-spacing:-.02em;text-decoration:none;color:var(--text);flex:none}
.nav-links{display:flex;gap:2px;margin-left:var(--s-4)}
.nav-links a{padding:9px 14px;border-radius:var(--r-btn);text-decoration:none;
  font:600 14.5px var(--font-ui);color:var(--text-2);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.nav-links a:hover{background:var(--surface-2);color:var(--text)}
.nav-right{margin-left:auto;display:flex;align-items:center;gap:var(--s-3)}
.icon-btn{width:42px;height:42px;flex:none;border:1px solid var(--border);
  border-radius:var(--r-btn);background:var(--surface);color:var(--text-2);
  display:grid;place-items:center;cursor:pointer;
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.icon-btn:hover{border-color:var(--border-strong);color:var(--text)}
.icon-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
/* 900 was measured by eye and was wrong: wordmark + links + right cluster
   need ~1000px, so 901-1000 pushed the nav off the page. */
@media(max-width:1024px){.nav-links{display:none}}
@media(max-width:560px){
  .nav-in{height:64px;gap:var(--s-4)}
  .wordmark{font-size:21px}
  .nav-right{gap:var(--s-2)}
  .nav-right .btn-ghost{display:none}
  .nav-right .btn-sm{padding:0 14px;font-size:13.5px}
  .icon-btn{width:38px;height:38px}
}

/* ===== hero ============================================================= */
.hero{position:relative;padding:clamp(56px,7vw,96px) 0 0;overflow:hidden}
.hero::before{
  content:"";position:absolute;top:-22%;left:50%;width:min(1100px,120vw);
  aspect-ratio:1;transform:translateX(-50%);pointer-events:none;z-index:1;
  background:radial-gradient(circle at 50% 50%,
    color-mix(in srgb,var(--accent) 16%,transparent) 0%,transparent 62%);
  opacity:.85;
}
.hero-in{position:relative;z-index:2;text-align:center}
.hero .lede{margin:var(--s-6) auto 0;text-align:center}
.hero-cta{display:flex;gap:var(--s-3);justify-content:center;flex-wrap:wrap;margin-top:var(--s-10)}
.hero-note{margin-top:20px;font:500 13.5px var(--font-ui);color:var(--text-3)}

/* hero footage — per-theme blend, because flat opacity on near-white paper is
   grey mush. Light multiplies (keeps darks), dark screens (keeps lights).
   Two intersected masks: the linear fades it out before the product panel,
   the radial punches the CENTRE out so the clip frames the headline instead
   of sitting under it — without that, any busy frame reads as noise. */
.hero-bg{
  position:absolute;inset:0 0 auto;height:min(760px,86%);z-index:0;
  pointer-events:none;overflow:hidden;
  opacity:var(--herovid,.25);
  mix-blend-mode:multiply;
  transition:opacity var(--t-base) var(--ease);
  -webkit-mask-image:
    radial-gradient(ellipse 62% 48% at 50% 33%, transparent 12%, #000 78%),
    linear-gradient(180deg, transparent 0%, #000 14%, #000 44%, transparent 90%);
  mask-image:
    radial-gradient(ellipse 62% 48% at 50% 33%, transparent 12%, #000 78%),
    linear-gradient(180deg, transparent 0%, #000 14%, #000 44%, transparent 90%);
  -webkit-mask-composite:source-in;
  mask-composite:intersect;
}
[data-theme="dark"] .hero-bg{opacity:var(--herovid,.20);mix-blend-mode:screen}
/* BOTH layers absolute: as static blocks at 100% height each they stacked
   vertically and overflow:hidden clipped the video entirely out of view. */
.hero-bg video,.hero-bg img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(.85) contrast(1.05);
}
[data-theme="dark"] .hero-bg video,[data-theme="dark"] .hero-bg img{
  filter:grayscale(.7) contrast(1.1) brightness(1.15);
}
.hero-bg video{opacity:0;transition:opacity 420ms var(--ease)}
.hero-bg video.is-ready{opacity:1}
/* footage is decoration: never spend a phone's data on it */
@media(max-width:760px){.hero-bg{display:none}}

.hero-art{position:relative;z-index:2;margin:clamp(48px,6vw,84px) auto 0;
  max-width:1120px;padding:0 var(--gutter);perspective:2000px}
.hero-art-inner{
  border-radius:var(--r-4);overflow:hidden;background:var(--surface);
  border:1px solid var(--border);box-shadow:var(--shadow-3);
  transform:rotateX(7deg) scale(.985);transform-origin:50% 0;will-change:transform;
}

/* ===== sections ========================================================= */
.sec{padding:var(--section) 0}
.sec-head{max-width:720px;margin-bottom:clamp(40px,4.5vw,64px)}
.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}
.sec-head.center .lede{margin-left:auto;margin-right:auto}
.sec-head .lede{margin-top:20px}

/* ===== logo marquee ===================================================== */
.marquee-sec{padding:var(--section) 0 0}
.marquee-lab{text-align:center;font:700 11.5px var(--font-ui);
  letter-spacing:var(--tracking-label);text-transform:uppercase;
  color:var(--text-3);margin-bottom:var(--s-8)}
.marquee{position:relative;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.marquee-track{display:flex;width:max-content;gap:clamp(40px,5vw,74px);align-items:center}
.js .marquee-track{animation:skp-slide 46s linear infinite}
.marquee:hover .marquee-track{animation-play-state:paused}
@keyframes skp-slide{to{transform:translateX(-50%)}}
.marquee img{height:clamp(30px,3.1vw,42px);width:auto;flex:none;object-fit:contain;
  opacity:.72;filter:grayscale(1) contrast(1.15);border-radius:6px;
  transition:opacity var(--t-base) var(--ease),filter var(--t-base) var(--ease),
             transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.marquee img:hover{opacity:1;filter:none;transform:scale(1.06)}
[data-theme="dark"] .marquee img{filter:grayscale(1) invert(1) brightness(1.9);opacity:.62}
/* client-supplied dark files render as-is — no invert, ever */
[data-theme="dark"] .marquee img.has-dark{filter:grayscale(1) brightness(1.15);opacity:.7}
[data-theme="dark"] .marquee img.has-dark:hover{filter:none;opacity:1}
/* Dark hover stays in the DARK treatment (Lance killed the white-halo —
   logos with opaque white backgrounds read as white boxes). Hover = the same
   inverted logo, full opacity, brighter. No color reveal in dark mode. */
[data-theme="dark"] .marquee img:hover{
  opacity:1;filter:grayscale(1) invert(1) brightness(2.3);transform:scale(1.06)}

/* ===== capability cards ================================================= */
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s-6)}
@media(max-width:980px){.grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.grid{grid-template-columns:1fr}}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-3);
  padding:var(--s-8);box-shadow:var(--shadow-1);text-decoration:none;color:inherit;
  display:block;position:relative;overflow:hidden;
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease),
             border-color var(--t-base) var(--ease)}
.card:hover{transform:translateY(-4px);box-shadow:var(--shadow-2);border-color:var(--border-strong)}
.card-ico{width:46px;height:46px;border-radius:14px;display:grid;place-items:center;
  margin-bottom:20px;background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-ink)}
.card-ico svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.card p{font:400 15px/1.55 var(--font-ui);color:var(--text-2);margin:10px 0 0}
.card .go{display:inline-flex;align-items:center;gap:6px;margin-top:20px;
  font:700 14px var(--font-ui);color:var(--accent-ink)}
.card .go svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform var(--t-base) var(--ease)}
.card:hover .go svg{transform:translateX(4px)}

/* ===== accent band ====================================================== */
.band{background:var(--accent);color:var(--on-accent);
  padding:clamp(64px,7vw,104px) 0;position:relative;overflow:hidden}
.band-in{display:flex;align-items:center;gap:clamp(32px,5vw,72px);flex-wrap:wrap}
.band .k{font:800 clamp(52px,7.4vw,104px)/.92 var(--font-ui);letter-spacing:-.04em;flex:none}
.band .t{font:700 clamp(20px,2.3vw,30px)/1.25 var(--font-ui);letter-spacing:-.02em;max-width:38ch}
.band .t strong{display:block;font:800 clamp(34px,4.6vw,62px)/1 var(--font-ui);
  letter-spacing:-.035em;margin-bottom:6px}
.band .t small{display:block;font:500 15.5px/1.5 var(--font-ui);opacity:.72;margin-top:10px}

/* ===== segmented filter — the indicator genuinely slides ================ */
.seg-wrap{display:flex;justify-content:center;margin-bottom:clamp(36px,4vw,56px)}
.seg{position:relative;display:inline-flex;gap:4px;padding:5px;
  background:var(--surface-2);border-radius:var(--r-btn);border:1px solid var(--border)}
.seg-ind{position:absolute;top:5px;bottom:5px;left:0;width:0;border-radius:var(--r-btn);
  background:var(--surface);box-shadow:var(--shadow-1);pointer-events:none;
  transition:transform 480ms var(--ease),width 480ms var(--ease)}
.seg-btn{position:relative;z-index:1;border:0;background:none;cursor:pointer;
  padding:12px 22px;border-radius:var(--r-btn);white-space:nowrap;
  font:700 14.5px var(--font-ui);color:var(--text-3);
  transition:color var(--t-base) var(--ease)}
.seg-btn.is-on{color:var(--text)}
.seg-btn:hover{color:var(--text-2)}
@media(max-width:640px){
  .seg{flex-direction:column;width:100%;border-radius:var(--r-3)}
  .seg-ind{display:none}
  .seg-btn{width:100%}
  .seg-btn.is-on{background:var(--surface);box-shadow:var(--shadow-1)}
}

/* equal columns + stretched rows: two 16:10 images can only match height if
   their columns match, and bodies only line up if the cards stretch */
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-6);align-items:stretch;
  transition:opacity 320ms var(--ease),transform 320ms var(--ease)}
.fgrid.is-swapping{opacity:0;transform:translateY(10px)}
@media(max-width:900px){.fgrid{grid-template-columns:1fr}}
.fblock{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-3);
  overflow:hidden;box-shadow:var(--shadow-1);display:flex;flex-direction:column}
.fblock img{width:100%;aspect-ratio:16/10;object-fit:cover}
.shot-needed{width:100%;aspect-ratio:16/10;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:6px;text-align:center;padding:var(--s-6);
  background:repeating-linear-gradient(-45deg,transparent 0 11px,
    color-mix(in srgb,var(--text-3) 7%,transparent) 11px 22px),var(--surface-2);
  border-bottom:1px solid var(--border);color:var(--text-3)}
.shot-needed svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;opacity:.7}
.shot-needed b{font:700 11.5px var(--font-ui);letter-spacing:var(--tracking-label);text-transform:uppercase}
.shot-needed span{font:500 13px/1.4 var(--font-ui);max-width:26ch}
.fblock .in{padding:var(--s-8);flex:1;display:flex;flex-direction:column}
.fblock h3{font:800 clamp(22px,2.1vw,28px)/1.15 var(--font-ui);letter-spacing:-.025em;margin:0}
.fblock p{font:400 15.5px/1.55 var(--font-ui);color:var(--text-2);margin:12px 0 0}
.fblock ul{list-style:none;margin:20px 0 0;padding:0;display:grid;gap:10px}
.fblock li{display:flex;gap:10px;align-items:flex-start;font:500 15px/1.5 var(--font-ui);color:var(--text-2)}
.fblock li svg{width:18px;height:18px;flex:none;margin-top:2px;color:var(--accent-ink);
  stroke:currentColor;fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
/* auto pushes the stat to the card floor, but auto collapses to 0 with no
   slack and the stat's padding sits BELOW its border — so the floor has to
   come from the element above, or the rule draws through the last list item */
.fblock ul:has(+ .fstat){margin-bottom:var(--s-6)}
.fstat{display:flex;align-items:baseline;gap:10px;margin-top:auto;
  padding-top:20px;border-top:1px solid var(--border)}
.fstat b{font:800 30px/1 var(--font-ui);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.fstat span{font:500 13.5px var(--font-ui);color:var(--text-3)}

/* ===== testimonial ====================================================== */
.quote-sec{background:var(--surface-2);padding:var(--section) 0}
.quote{font:600 clamp(23px,2.8vw,38px)/1.32 var(--font-ui);letter-spacing:-.025em;text-wrap:pretty;margin:0}
.quote-by{display:flex;align-items:center;gap:var(--s-4);margin-top:var(--s-8)}
.quote-av{width:52px;height:52px;flex:none;border-radius:var(--r-btn);display:grid;place-items:center;
  font:800 16px var(--font-ui);background:color-mix(in srgb,var(--accent) 20%,transparent);color:var(--accent-ink)}
.quote-by b{display:block;font:700 16px var(--font-ui)}
.quote-by span{font:500 14px var(--font-ui);color:var(--text-3)}
.quote-by img{height:38px;width:auto;margin-left:auto;opacity:.6;filter:grayscale(1)}
[data-theme="dark"] .quote-by img{filter:grayscale(1) invert(1) brightness(1.7)}

/* ===== closing CTA + footer ============================================ */
.close{padding:var(--section) 0;text-align:center}
.close .lede{margin-left:auto;margin-right:auto;text-align:center;margin-top:20px}
.close .hero-cta{margin-top:var(--s-10)}

.foot{border-top:1px solid var(--border);padding:var(--s-16) 0 var(--s-10)}
.foot-in{display:grid;grid-template-columns:1.6fr repeat(3,1fr);gap:var(--s-10)}
@media(max-width:820px){.foot-in{grid-template-columns:1fr 1fr}}
.foot-blurb{font:400 15px/1.55 var(--font-ui);color:var(--text-2);margin:16px 0 0;max-width:34ch}
.foot h4{font:700 12px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--text-3);margin:0 0 20px}
.foot ul{list-style:none;display:grid;gap:11px;margin:0;padding:0}
.foot ul a{text-decoration:none;font:500 14.5px var(--font-ui);color:var(--text-2)}
.foot ul a:hover{color:var(--text)}
.foot-bottom{display:flex;align-items:center;gap:var(--s-6);flex-wrap:wrap;margin-top:var(--s-16)}
.apps{display:flex;gap:var(--s-3);flex-wrap:wrap}
.appbtn{display:inline-flex;align-items:center;gap:10px;text-decoration:none;
  background:var(--text);color:var(--bg);border-radius:14px;padding:9px 16px 9px 14px;
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.appbtn:hover{transform:translateY(-2px);box-shadow:var(--shadow-2)}
.appbtn svg{width:22px;height:22px;fill:currentColor;stroke:none;flex:none}
.appbtn i{display:block;font:600 9.5px var(--font-ui);opacity:.7;font-style:normal;letter-spacing:.02em}
.appbtn b{display:block;font:800 14px/1.15 var(--font-ui);letter-spacing:-.015em}
.socials{display:flex;gap:var(--s-2);margin-left:auto}
.socials a{width:42px;height:42px;border-radius:var(--r-btn);display:grid;place-items:center;
  border:1px solid var(--border);color:var(--text-2);
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             background var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.socials a:hover{background:var(--accent);color:var(--on-accent);border-color:transparent;transform:translateY(-2px)}
.socials svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
@media(max-width:640px){.socials{margin-left:0}}
.foot-note{margin-top:var(--s-6);padding-top:var(--s-6);border-top:1px solid var(--border);
  font:500 13.5px var(--font-ui);color:var(--text-3)}

/* ===== REVEAL — visible by default; JS opts INTO the animation ========== */
.js .rv{opacity:0;transform:translateY(26px)}
.js .rv.in{opacity:1;transform:none;
  transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease);
  transition-delay:calc(var(--i,0) * 90ms)}
@media(prefers-reduced-motion:reduce){
  .js .rv{opacity:1!important;transform:none!important}
  .js .marquee-track{animation:none}
}

/* ==========================================================================
   HERO PRODUCT PANES — four surfaces, one shown per load (www.js picks).
   Real app vocabulary rendered in HTML, not screenshots: it stays crisp at
   any density, themes correctly, and never goes stale against the product.
   ========================================================================== */
.pane[hidden]{display:none}
.pane-body{padding:var(--s-6);background:var(--surface);min-height:430px;text-align:left}
.pane-h{display:flex;align-items:center;gap:var(--s-3);margin-bottom:20px}
.pane-h b{font:800 19px var(--font-ui);letter-spacing:-.02em}
.pane-h span{font:500 12.5px var(--font-ui);color:var(--text-3)}
.pane-chip{margin-left:auto;flex:none;border-radius:var(--r-btn);padding:5px 12px;
  font:700 11.5px var(--font-ui);
  background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent-ink)}

/* -- MyHQ -- */
.app{display:grid;grid-template-columns:212px 1fr;min-height:430px;text-align:left}
.app-nav{background:var(--surface-2);border-right:1px solid var(--border);
  padding:20px var(--s-3);display:flex;flex-direction:column;gap:2px}
.app-org{display:flex;align-items:center;gap:10px;padding:8px 10px;margin-bottom:var(--s-4)}
.app-mark{width:30px;height:30px;flex:none;border-radius:var(--r-1);display:grid;place-items:center;
  font:800 11px var(--font-ui);background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent-ink)}
.app-org b{font:700 13.5px var(--font-ui);display:block;letter-spacing:-.01em}
.app-org span{font:500 11px var(--font-ui);color:var(--text-3)}
.app-grp{font:700 10px var(--font-ui);letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-3);padding:var(--s-4) 10px 6px}
.app-nv{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r-1);
  font:600 13px var(--font-ui);color:var(--text-2)}
.app-nv svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.app-nv.on{background:var(--surface);color:var(--text);box-shadow:var(--shadow-1);font-weight:700}
.app-nv.on svg{stroke:var(--accent-ink)}
.app-body{padding:var(--s-6);background:var(--surface);min-width:0}
.app-h{display:flex;align-items:baseline;gap:var(--s-4);margin-bottom:20px}
.app-h b{font:800 19px var(--font-ui);letter-spacing:-.02em}
.app-h span{font:500 12.5px var(--font-ui);color:var(--text-3)}
.app-pill{margin-left:auto;flex:none;border-radius:var(--r-btn);padding:5px 12px;
  font:700 11.5px var(--font-ui);
  background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent-ink)}
.week{display:grid;grid-template-columns:repeat(7,1fr);gap:7px}
.day{border-radius:var(--r-1);padding:9px 7px;min-height:96px;background:var(--surface-2)}
.day.today{background:color-mix(in srgb,var(--accent) 12%,transparent);
  outline:1.5px solid color-mix(in srgb,var(--accent) 40%,transparent)}
.day i{font:700 9.5px var(--font-ui);letter-spacing:.1em;color:var(--text-3);font-style:normal}
.day b{display:block;font:800 17px var(--font-ui);margin:1px 0 7px;letter-spacing:-.02em}
.day.today b{color:var(--accent-ink)}
.ev{border-radius:6px;padding:4px 6px;margin-bottom:4px;font:700 9.5px/1.3 var(--font-ui);
  background:var(--accent);color:var(--on-accent)}
.ev.soft{background:var(--surface);color:var(--text);border:1px solid var(--border)}
.ev em{display:block;font:600 8.5px var(--font-ui);opacity:.72;font-style:normal;margin-top:1px}
.app-rows{display:grid;gap:8px;margin-top:20px}
.app-row{display:flex;align-items:center;gap:var(--s-3);border:1px solid var(--border);
  border-radius:14px;padding:10px var(--s-4)}
.app-art{width:38px;height:38px;flex:none;border-radius:var(--r-1);
  background:linear-gradient(135deg,var(--accent),color-mix(in srgb,var(--accent) 40%,#000))}
.app-art.b{background:linear-gradient(135deg,#2E2E38,#6B6B78)}
.app-row b{font:700 13.5px var(--font-ui);display:block;letter-spacing:-.01em}
.app-row span{font:500 11.5px var(--font-ui);color:var(--text-3)}
.tag{margin-left:auto;flex:none;border-radius:var(--r-btn);padding:5px 11px;
  font:700 11px var(--font-ui);white-space:nowrap}
.tag.ok{background:var(--ok-bg);color:var(--ok)}
.tag.warn{background:var(--warn-bg);color:var(--warn)}
@media(max-width:820px){.app{grid-template-columns:1fr}.app-nav{display:none}}
@media(max-width:620px){.week{grid-template-columns:repeat(4,1fr)}.day:nth-child(n+5){display:none}}

/* -- AI Scheduler -- */
.ask{display:flex;gap:10px;align-items:flex-start;background:var(--surface-2);
  border-radius:14px;padding:12px 14px;margin-bottom:var(--s-4)}
.ask .who{width:26px;height:26px;flex:none;border-radius:var(--r-btn);display:grid;place-items:center;
  font:800 10px var(--font-ui);background:var(--text);color:var(--bg)}
.ask p{font:600 13.5px/1.45 var(--font-ui);color:var(--text);margin:0}
.slots{display:grid;grid-template-columns:64px repeat(3,1fr);gap:6px}
.slots .hd{font:700 9.5px var(--font-ui);letter-spacing:.1em;color:var(--text-3);
  text-transform:uppercase;padding:2px}
.slots .tm{font:700 11px var(--font-ui);color:var(--text-3);display:flex;align-items:center;
  font-variant-numeric:tabular-nums}
.gm{border-radius:7px;padding:7px 8px;font:700 10.5px/1.3 var(--font-ui);
  background:var(--surface-2);border:1px solid var(--border)}
.gm.hot{background:var(--accent);color:var(--on-accent);border-color:transparent}
.gm em{display:block;font:600 9px var(--font-ui);opacity:.7;font-style:normal;margin-top:1px}
.solved{display:flex;align-items:center;gap:8px;margin-top:var(--s-4);padding-top:var(--s-4);
  border-top:1px solid var(--border);font:600 12.5px var(--font-ui);color:var(--text-2)}
.solved svg{width:16px;height:16px;color:var(--ok);stroke:currentColor;fill:none;
  stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;flex:none}

/* -- Ticketing -- */
.tk{display:grid;grid-template-columns:1.25fr 1fr;gap:20px}
@media(max-width:820px){.tk{grid-template-columns:1fr}}
.tkrow{display:flex;align-items:center;gap:var(--s-3);padding:11px 13px;
  border:1px solid var(--border);border-radius:14px;margin-bottom:8px}
.tkrow b{font:700 13px var(--font-ui);display:block}
.tkrow span{font:500 11.5px var(--font-ui);color:var(--text-3)}
.tkrow .amt{margin-left:auto;font:800 14px var(--font-ui);font-variant-numeric:tabular-nums}
.gate{background:var(--text);color:var(--bg);border-radius:14px;padding:20px;
  display:flex;flex-direction:column;justify-content:center}
.gate i{font:700 10px var(--font-ui);letter-spacing:.14em;text-transform:uppercase;
  opacity:.6;font-style:normal}
.gate b{font:800 34px/1 var(--font-ui);letter-spacing:-.03em;margin:8px 0 4px;
  font-variant-numeric:tabular-nums}
.gate span{font:500 12px var(--font-ui);opacity:.7}
.scan{margin-top:var(--s-4);padding-top:var(--s-4);border-top:1px solid rgba(255,255,255,.16);
  display:flex;align-items:center;gap:9px;font:700 11.5px var(--font-ui)}
.scan .dot{width:7px;height:7px;border-radius:99px;background:var(--accent);flex:none}

/* -- Custom website -- */
.chrome{display:flex;align-items:center;gap:7px;padding:9px 13px;
  background:var(--surface-2);border-bottom:1px solid var(--border)}
.chrome i{width:9px;height:9px;border-radius:99px;background:var(--border-strong);flex:none}
.chrome .url{margin-left:8px;flex:1;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-btn);padding:5px 13px;font:600 11px var(--font-ui);color:var(--text-3)}
.site-hero{position:relative;height:150px;border-radius:14px;overflow:hidden;
  margin-bottom:var(--s-4);display:flex;align-items:flex-end;padding:var(--s-4)}
.site-hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.site-hero::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 30%,rgba(0,0,0,.72))}
.site-hero b{position:relative;z-index:1;color:#fff;font:800 20px var(--font-ui);letter-spacing:-.02em}
.site-nav{display:flex;gap:var(--s-4);align-items:center;margin-bottom:var(--s-4)}
.site-nav .mk{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;flex:none;
  font:800 9.5px var(--font-ui);background:var(--accent);color:var(--on-accent)}
.site-nav span{font:600 11.5px var(--font-ui);color:var(--text-2)}
.site-nav .cta{margin-left:auto;background:var(--text);color:var(--bg);border-radius:var(--r-btn);
  padding:5px 12px;font:700 10.5px var(--font-ui)}
.gamerow{display:flex;align-items:center;gap:var(--s-3);padding:9px 0;border-top:1px solid var(--border)}
.gamerow .dt{width:42px;flex:none;text-align:center;border-radius:6px;padding:4px 0;background:var(--surface-2)}
.gamerow .dt i{display:block;font:700 8.5px var(--font-ui);letter-spacing:.08em;color:var(--text-3);font-style:normal}
.gamerow .dt b{display:block;font:800 14px var(--font-ui);letter-spacing:-.02em}
.gamerow .vs b{font:700 12.5px var(--font-ui);display:block}
.gamerow .vs span{font:500 11px var(--font-ui);color:var(--text-3)}
.gamerow .res{margin-left:auto;font:800 12px var(--font-ui);color:var(--accent-ink)}

/* ==========================================================================
   /product/ — the spine, the steps, the FAQ.
   ========================================================================== */
.hero-tight{padding-bottom:clamp(24px,3vw,48px)}
.sec-alt{background:var(--surface-2)}

/* -- THE SPINE — RETAINED, not currently rendered ------------------------
   Removed from /product/ 2026-08-11 (Lance: right idea, wrong page). Kept
   because the pattern is wanted on the individual feature pages. Do not
   delete as "dead CSS".
   -- THE SPINE ------------------------------------------------------------
   Each row draws its OWN connector down from its OWN dot. Drawing one line
   across the container is how the legacy timeline ended up with the line
   floating above the dots when gutter padding pushed them apart. */
.spine{list-style:none;margin:0 auto;padding:0;max-width:600px;display:grid;gap:0}
.spine-row{position:relative;display:flex;align-items:center;gap:var(--s-5,20px);
  padding:20px 0;padding-left:4px}
/* the connector must visibly REACH the next dot, or it reads as five
   unrelated rows instead of one record moving through five stages */
.spine-row:not(:last-child)::before{
  content:"";position:absolute;left:32px;top:calc(50% + 29px);height:calc(100% - 58px + 40px);
  width:2px;border-radius:2px;
  background:color-mix(in srgb,var(--accent) 42%,transparent);
}
.spine-dot{
  width:58px;height:58px;flex:none;border-radius:20px;display:grid;place-items:center;
  background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-1);
  color:var(--accent-ink);position:relative;z-index:1;
}
.spine-dot svg{width:25px;height:25px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.spine-body{min-width:0;flex:1}
.spine-body b{display:block;font:800 clamp(19px,1.9vw,25px)/1.25 var(--font-ui);letter-spacing:-.02em}
.spine-hands{
  display:inline-block;margin-top:8px;border-radius:var(--r-btn);
  padding:5px 13px;font:700 12px var(--font-ui);font-variant-numeric:tabular-nums;
  background:color-mix(in srgb,var(--accent) 15%,transparent);color:var(--accent-ink);
}
.spine-n{flex:none;font:800 12px var(--font-ui);color:var(--text-3);
  font-variant-numeric:tabular-nums;letter-spacing:.06em;opacity:.55}
@media(max-width:560px){
  .spine-row{gap:var(--s-4)}
  .spine-dot{width:46px;height:46px;border-radius:15px}
  .spine-dot svg{width:21px;height:21px}
  .spine-row:not(:last-child)::before{left:26px;top:calc(50% + 23px);height:calc(100% - 46px + 40px)}
  .spine-n{display:none}
}

/* -- GETTING STARTED ------------------------------------------------------ */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s-6)}
@media(max-width:900px){.steps{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.steps{grid-template-columns:1fr}}
.step{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-3);
  padding:var(--s-8);box-shadow:var(--shadow-1)}
.step-n{display:grid;place-items:center;width:34px;height:34px;border-radius:var(--r-btn);
  font:800 14px var(--font-ui);margin-bottom:18px;
  background:var(--accent);color:var(--on-accent)}
.step b{display:block;font:800 17px/1.25 var(--font-ui);letter-spacing:-.015em}
.step p{font:400 14.5px/1.55 var(--font-ui);color:var(--text-2);margin:9px 0 0}

/* -- FAQ ------------------------------------------------------------------
   <details> so it works with JS blocked and is machine-legible (ADR-001's
   agent-legibility principle) — the FAQPage JSON-LD mirrors these exactly. */
.faq{display:grid;gap:10px}
.faq-item{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-3);overflow:hidden}
.faq-item summary{
  display:flex;align-items:center;gap:var(--s-4);cursor:pointer;list-style:none;
  padding:20px var(--s-6);font:700 16.5px/1.4 var(--font-ui);letter-spacing:-.015em;
}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary span{flex:1}
.faq-item summary svg{width:19px;height:19px;flex:none;color:var(--text-3);
  stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
  transition:transform var(--t-base) var(--ease)}
.faq-item[open] summary svg{transform:rotate(180deg)}
.faq-item summary:hover{background:var(--surface-2)}
.faq-item p{margin:0;padding:0 var(--s-6) 22px;font:400 15.5px/1.6 var(--font-ui);
  color:var(--text-2);max-width:66ch}
.faq-more{text-align:center;margin-top:var(--s-8);font:500 15px var(--font-ui);color:var(--text-3)}
.faq-more a{color:var(--accent-ink);font-weight:700}

/* ==========================================================================
   PRODUCT MODEL grid + the click-to-load feature video.
   ========================================================================== */
/* smooth in-page scroll for "See what is included"; scroll-margin clears the
   sticky nav, or the heading lands underneath it */
html{scroll-behavior:smooth}
[id]{scroll-margin-top:104px}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

.pmgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s-6)}
@media(max-width:980px){.pmgrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.pmgrid{grid-template-columns:1fr}}

.pmcard{
  position:relative;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-3);padding:var(--s-8);box-shadow:var(--shadow-1);
  display:flex;flex-direction:column;overflow:hidden;
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease),
             border-color var(--t-base) var(--ease);
}
.pmcard:hover{transform:translateY(-4px);box-shadow:var(--shadow-2);border-color:var(--border-strong)}
/* the featured tile spans two columns — tournaments are the top of the funnel
   and the grid should say so before a word is read */
.pmcard.is-feature{grid-column:span 2;border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
.pmcard.is-feature::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:radial-gradient(120% 80% at 0% 0%,
    color-mix(in srgb,var(--accent) 10%,transparent),transparent 60%);
}
@media(max-width:980px){.pmcard.is-feature{grid-column:span 2}}
@media(max-width:640px){.pmcard.is-feature{grid-column:span 1}}

.pmh{font:800 20px/1.25 var(--font-ui);letter-spacing:-.02em;margin:0;
  display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pmcard.is-feature .pmh{font-size:clamp(22px,2.1vw,27px)}
.pmbadge{
  font:800 10px/1 var(--font-ui);letter-spacing:.1em;text-transform:uppercase;
  font-style:normal;border-radius:var(--r-btn);padding:5px 9px;
  background:var(--accent);color:var(--on-accent);
}
.pmcard p{font:400 15px/1.55 var(--font-ui);color:var(--text-2);margin:10px 0 0;position:relative;z-index:1}
.pmcard .go{display:inline-flex;align-items:center;gap:6px;margin-top:auto;padding-top:20px;
  font:700 14px var(--font-ui);color:var(--accent-ink);text-decoration:none;position:relative;z-index:1}
.pmcard .go svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform var(--t-base) var(--ease)}
.pmcard:hover .go svg{transform:translateX(4px)}

/* the play affordance — hidden until hover/focus on pointer devices, always
   visible on touch, where there is no hover to reveal it */
.pmplay{
  position:absolute;top:14px;right:14px;z-index:2;display:inline-flex;align-items:center;gap:7px;
  border:1px solid var(--border);background:var(--surface);color:var(--text);
  border-radius:var(--r-btn);padding:7px 13px 7px 9px;cursor:pointer;
  font:700 12px var(--font-ui);
  opacity:0;transform:translateY(-4px);
  transition:opacity var(--t-base) var(--ease),transform var(--t-base) var(--ease),
             background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.pmcard:hover .pmplay,.pmplay:focus-visible{opacity:1;transform:none}
.pmplay:hover{background:var(--accent);color:var(--on-accent);border-color:transparent}
.pmplay svg{width:15px;height:15px;fill:currentColor;stroke:none;flex:none}
@media(hover:none){.pmplay{opacity:1;transform:none}}

/* -- the modal -- */
/* margin:auto is REQUIRED here, not decorative: ui-kit.css carries a
   *{margin:0} reset, which overrides the UA's `dialog:modal{margin:auto}` and
   pins the dialog to the top-left corner. */
.vmodal{
  border:0;padding:0;background:transparent;max-width:min(1040px,92vw);width:100%;
  margin:auto;color:var(--text);overflow:visible;
}
.vmodal::backdrop{background:rgba(10,10,15,.72);backdrop-filter:blur(6px)}
.vmodal-frame{
  position:relative;aspect-ratio:16/9;width:100%;border-radius:var(--r-3);
  overflow:hidden;background:#000;box-shadow:var(--shadow-3);
}
.vmodal-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.vmodal-cap{margin:14px 2px 0;font:700 15px var(--font-ui);color:#F4F4F1}
.vmodal-x{
  position:absolute;top:-46px;right:0;width:36px;height:36px;border-radius:var(--r-btn);
  border:1px solid rgba(255,255,255,.25);background:rgba(255,255,255,.08);color:#fff;
  display:grid;place-items:center;cursor:pointer;
}
.vmodal-x:hover{background:rgba(255,255,255,.18)}
.vmodal-x svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}

/* ==========================================================================
   /demo/ — the one conversion page. Every "Book a demo" on the site lands here.
   ========================================================================== */
.nav.is-minimal .nav-in{height:72px}

.demo-top{padding:clamp(40px,5vw,72px) 0 var(--section)}
.demo-grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(32px,4vw,64px);align-items:start}
@media(max-width:1024px){.demo-grid{grid-template-columns:1fr}}

/* balance + a lower ceiling: the variant headlines vary a lot in length, and
   the longest one hit five lines in this narrow column at 58px */
.demo-h1{font:800 clamp(34px,4.1vw,50px)/1.06 var(--font-ui);letter-spacing:-.032em;
  margin:0;text-wrap:balance}
.demo-copy .lede{margin-top:20px}
/* the copy column sticks while the tall Calendly panel scrolls past it */
@media(min-width:1025px){.demo-copy{position:sticky;top:104px}}

.expect{list-style:none;margin:var(--s-8) 0 0;padding:0;display:grid;gap:18px}
.expect li{display:flex;gap:14px;align-items:flex-start}
.expect-ic{width:38px;height:38px;flex:none;border-radius:12px;display:grid;place-items:center;
  background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-ink)}
.expect-ic svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.expect b{display:block;font:700 15.5px var(--font-ui);letter-spacing:-.01em;margin-bottom:2px}
.expect li>span:last-child{font:400 14.5px/1.5 var(--font-ui);color:var(--text-2)}

.demo-quote{margin:var(--s-8) 0 0;padding:var(--s-6);border-radius:var(--r-3);
  background:var(--surface-2);border:1px solid var(--border)}
.demo-quote blockquote{margin:0;font:500 15px/1.55 var(--font-ui);color:var(--text)}
.demo-quote figcaption{display:flex;align-items:center;gap:12px;margin-top:16px}
.demo-quote figcaption b{display:block;font:700 14px var(--font-ui)}
.demo-quote figcaption span span{font:500 12.5px var(--font-ui);color:var(--text-3)}

.calendly-wrap{border-radius:var(--r-3);overflow:hidden;background:var(--surface);
  border:1px solid var(--border);box-shadow:var(--shadow-2)}
/* The widget does NOT auto-size. Height is the only lever, and too short means
   Calendly renders its own inner scrollbar (Lance: "i hate them"). These three
   values are inherited from the legacy page, where they were tuned by hand. */
/* Height matches what Calendly actually renders for the date-picker step —
   the old 1000-1180px left a card-sized blank band under the widget in both
   themes (Lance). Calendly scrolls internally on its later steps. */
.calendly-inline-widget{min-width:320px;height:760px}
@media(max-width:767px){.calendly-inline-widget{height:820px}}

.demo-alt{margin:20px 2px 0;font:500 14.5px/1.55 var(--font-ui);color:var(--text-3)}
.demo-alt a{color:var(--accent-ink);font-weight:700}

/* landing on the wrong demo variant should cost one click, not a bounce */
.demo-switch{margin-top:var(--s-6);padding-top:var(--s-6);border-top:1px solid var(--border)}
.demo-switch>span{display:block;font:700 12px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--text-3);margin-bottom:12px}
.demo-switch-links{display:flex;gap:8px;flex-wrap:wrap}
.demo-switch-links a{
  border:1px solid var(--border);border-radius:var(--r-btn);padding:8px 15px;
  font:700 13.5px var(--font-ui);color:var(--text-2);text-decoration:none;
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             background var(--t-fast) var(--ease);
}
.demo-switch-links a:hover{background:var(--surface-2);border-color:var(--border-strong);color:var(--text)}

/* conversion pages: the footer is stripped to a wordmark and a line of small
   print. A footer full of links is navigation by another name. */
.foot-slim{padding:var(--s-8) 0}
.foot-slim .foot-note{margin:0;padding:0;border:0;display:flex;align-items:center;
  gap:var(--s-4);flex-wrap:wrap}
.foot-slim .wordmark{font-size:19px}

/* ==========================================================================
   /pricing/ — plans, the one-off, and the flat-vs-per-team table.
   ========================================================================== */
.sec-tight{padding-top:clamp(24px,3vw,40px)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* -- monthly / annual toggle -- */
.bill-toggle{display:inline-flex;gap:4px;padding:5px;margin-top:var(--s-8);
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-btn)}
.bill-btn{border:0;background:none;cursor:pointer;border-radius:var(--r-btn);
  padding:11px 20px;font:700 14.5px var(--font-ui);color:var(--text-3);
  display:inline-flex;align-items:center;gap:8px;
  transition:background var(--t-base) var(--ease),color var(--t-base) var(--ease)}
.bill-btn.is-on{background:var(--surface);color:var(--text);box-shadow:var(--shadow-1)}
.bill-btn em{font-style:normal;font:800 10.5px var(--font-ui);letter-spacing:.06em;
  text-transform:uppercase;border-radius:var(--r-btn);padding:4px 8px;
  background:color-mix(in srgb,var(--accent) 20%,transparent);color:var(--accent-ink)}

/* -- plan cards -- */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s-6);align-items:start}
@media(max-width:980px){.plans{grid-template-columns:1fr;max-width:520px;margin:0 auto}}
.plan{position:relative;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-3);padding:var(--s-8);box-shadow:var(--shadow-1);
  display:flex;flex-direction:column}
/* the popular tier is lifted rather than recoloured — accent is rare (kit law) */
.plan.is-popular{border-color:color-mix(in srgb,var(--accent) 50%,transparent);
  box-shadow:var(--shadow-2)}
.plan-flag{position:absolute;top:-11px;left:var(--s-8);border-radius:var(--r-btn);
  padding:5px 12px;font:800 10.5px var(--font-ui);letter-spacing:.08em;text-transform:uppercase;
  background:var(--accent);color:var(--on-accent)}
.plan-name{font:800 19px var(--font-ui);letter-spacing:-.015em;margin:0}
.plan-price{display:flex;align-items:baseline;gap:9px;margin:12px 0 0}
/* DIRECT children only: the label <em> contains its own spans, and an
   unscoped `.plan-price span` rendered "per month" at price size. */
.plan-price > span{font:800 clamp(38px,4vw,48px)/1 var(--font-ui);letter-spacing:-.035em;
  font-variant-numeric:tabular-nums}
.plan-price em{font-style:normal;font:500 13.5px var(--font-ui);color:var(--text-3)}
.plan-price em span{font:inherit;letter-spacing:normal}
.plan-blurb{font:400 14.5px/1.5 var(--font-ui);color:var(--text-2);margin:14px 0 0;min-height:3em}
.plan-cta{width:100%;margin-top:var(--s-6)}
.plan-feats{list-style:none;margin:var(--s-6) 0 0;padding:0;display:grid;gap:11px}
.plan-feats li{display:flex;gap:10px;align-items:flex-start;
  font:500 14.5px/1.45 var(--font-ui);color:var(--text-2)}
.plan-feats svg,.oneoff-feats svg{width:17px;height:17px;flex:none;margin-top:2px;
  color:var(--accent-ink);stroke:currentColor;fill:none;stroke-width:2.6;
  stroke-linecap:round;stroke-linejoin:round}

/* -- the one-off tournament plan -- */
.oneoff{margin-top:var(--s-6);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-3);box-shadow:var(--shadow-1);padding:var(--s-8);
  display:grid;grid-template-columns:1fr auto;gap:var(--s-8);align-items:center}
@media(max-width:820px){.oneoff{grid-template-columns:1fr}}
.oneoff-copy p{font:400 14.5px/1.5 var(--font-ui);color:var(--text-2);margin:8px 0 0}
.oneoff-feats{list-style:none;margin:var(--s-5) 0 0;padding:0;display:flex;gap:var(--s-6);flex-wrap:wrap}
.oneoff-feats li{display:flex;gap:8px;align-items:center;font:600 13.5px var(--font-ui);color:var(--text-2)}
.oneoff-buy{text-align:right;display:grid;gap:12px;justify-items:end}
@media(max-width:820px){.oneoff-buy{justify-items:start;text-align:left}}

/* -- flat vs per-team -- */
.cmp-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-3);
  background:var(--surface);box-shadow:var(--shadow-1)}
.cmp{width:100%;border-collapse:collapse;min-width:520px}
.cmp th,.cmp td{text-align:left;padding:16px var(--s-6);font:500 14.5px var(--font-ui)}
.cmp thead th{font:800 12px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--text-3);border-bottom:1px solid var(--border)}
.cmp tbody tr+tr th,.cmp tbody tr+tr td{border-top:1px solid var(--border)}
.cmp tbody th{font:700 14.5px var(--font-ui);color:var(--text)}
.cmp-yes{color:var(--accent-ink);font-weight:700}
.cmp-no{color:var(--text-3)}

/* annual view: the yearly figure leads, the monthly equivalent sits under it */
.plan-sub{margin:6px 0 0;font:600 12.5px var(--font-ui);color:var(--text-3);min-height:1.2em}
/* per-feature qualifier — the tournament credit lines carry the fee promise */
.plan-feats li span{display:block}
.feat-sub{display:block;font-style:normal;font:600 12px var(--font-ui);
  color:var(--accent-ink);margin-top:2px}
/* the one-off's fee promise, set as a pill like the billing toggle */
.fee-orb{display:inline-block;margin:var(--s-5) 0 0;border-radius:var(--r-btn);
  padding:9px 16px;font:800 13px var(--font-ui);
  background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent-ink)}
.cmp-yes em{display:block;font-style:normal;font:600 12px var(--font-ui);
  color:var(--text-3);margin-top:2px}

/* ==========================================================================
   /resources/ — the answer library. Every FAQ on the site, one page.
   ========================================================================== */
.ans-search{position:relative;display:flex;align-items:center;gap:12px;
  max-width:600px;margin:var(--s-8) auto 0;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-btn);
  padding:0 18px;box-shadow:var(--shadow-1);
  transition:border-color var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.ans-search:focus-within{border-color:var(--border-strong);box-shadow:var(--shadow-2)}
.ans-search > svg{width:19px;height:19px;flex:none;color:var(--text-3);
  stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}
.ans-search input{flex:1;border:0;background:none;outline:none;min-height:56px;
  font:500 16px var(--font-ui);color:var(--text)}
.ans-search input::placeholder{color:var(--text-3)}
.ans-search input::-webkit-search-cancel-button{display:none}
.ans-search button{border:0;background:none;cursor:pointer;color:var(--text-3);
  display:grid;place-items:center;padding:6px}
.ans-search button:hover{color:var(--text)}
.ans-search button svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}
.ans-count{margin-top:14px;font:600 13.5px var(--font-ui);color:var(--text-3);min-height:1.2em}

.ans-layout{display:grid;grid-template-columns:230px minmax(0,1fr);gap:clamp(28px,4vw,64px);align-items:start}
/* minmax(0,1fr), NOT 1fr: a bare 1fr track's min-size is auto, so the rail
   refuses to shrink below its widest row's max-content (2383px) and the whole
   page scrolls sideways on phones. The desktop track pair already knew this —
   the single-column collapse forgot it. */
@media(max-width:900px){.ans-layout{grid-template-columns:minmax(0,1fr)}.ans-rail{min-width:0}}

/* the rail JUMPS, it does not filter — filtering lives in the search box, and
   two mechanisms that both hide things is one too many */
.ans-rail{position:sticky;top:104px}
@media(max-width:900px){.ans-rail{position:static}}
.ans-rail-h{font:800 11.5px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:var(--text-3);margin:0 0 12px}
.ans-rail ul{list-style:none;margin:0;padding:0;display:grid;gap:2px}
@media(max-width:900px){.ans-rail ul{grid-auto-flow:column;grid-auto-columns:max-content;
  overflow-x:auto;gap:8px;padding-bottom:8px}}
.ans-rail a{display:flex;align-items:center;gap:10px;text-decoration:none;
  padding:8px 12px;border-radius:12px;white-space:nowrap;
  font:600 13.5px var(--font-ui);color:var(--text-2);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.ans-rail a:hover{background:var(--surface-2);color:var(--text)}
.ans-rail a.is-here{background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--text)}
.ans-rail em{margin-left:auto;font-style:normal;font:700 11.5px var(--font-ui);
  color:var(--text-3);font-variant-numeric:tabular-nums}

.ans-group{margin-bottom:var(--s-16)}
.ans-group[hidden]{display:none}
.ans-group-h{margin-bottom:var(--s-5)}
.ans-group-h p{font:400 14.5px/1.5 var(--font-ui);color:var(--text-2);margin:8px 0 0;max-width:60ch}
.ans-src{display:inline-flex;align-items:center;gap:6px;margin-top:12px;
  font:700 13.5px var(--font-ui);color:var(--accent-ink);text-decoration:none}
.ans-src svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform var(--t-base) var(--ease)}
.ans-src:hover svg{transform:translateX(4px)}
.faq-item[hidden]{display:none}
/* the search highlights the matched term rather than only filtering */
.faq-item mark{background:color-mix(in srgb,var(--accent) 30%,transparent);
  color:inherit;border-radius:3px;padding:0 2px}

.ans-empty{text-align:center;padding:var(--s-16) 0;font:500 16px var(--font-ui);color:var(--text-2)}
.ans-empty button{border:0;background:none;cursor:pointer;padding:0;
  font:700 16px var(--font-ui);color:var(--accent-ink);text-decoration:underline}
.ans-empty a{color:var(--accent-ink);font-weight:700}

/* the video-library entry point. Deliberately quieter than the search box —
   it serves existing clients, not the prospect the page is written for. */
.vidlib{display:flex;align-items:center;gap:12px;margin-top:var(--s-6);
  padding:14px;border:1px solid var(--border);border-radius:var(--r-2);
  background:var(--surface);text-decoration:none;box-shadow:var(--shadow-1);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease),
             border-color var(--t-base) var(--ease)}
.vidlib:hover{transform:translateY(-2px);box-shadow:var(--shadow-2);border-color:var(--border-strong)}
.vidlib-ic{width:36px;height:36px;flex:none;border-radius:11px;display:grid;place-items:center;
  background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent-ink)}
.vidlib-ic svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.vidlib-ic svg path{fill:currentColor;stroke:none}
.vidlib-t{min-width:0;flex:1}
.vidlib-t b{display:block;font:700 14px var(--font-ui);color:var(--text);letter-spacing:-.01em}
.vidlib-t em{display:block;font-style:normal;font:500 12px var(--font-ui);color:var(--text-3);margin-top:1px}
.vidlib-lock{flex:none;color:var(--text-3)}
.vidlib-lock svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
@media(max-width:900px){.vidlib{margin-top:var(--s-4)}}

/* ==========================================================================
   /customers/ — featured stories, voices, the roster.
   ========================================================================== */
.story{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-3);
  padding:var(--s-8);box-shadow:var(--shadow-1);display:flex;flex-direction:column;
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease),
             border-color var(--t-base) var(--ease)}
.story:hover{transform:translateY(-4px);box-shadow:var(--shadow-2);border-color:var(--border-strong)}
.story-logo{display:grid;place-items:center;height:56px;width:fit-content;
  padding:0 4px;margin-bottom:20px}
.story-logo img{max-height:46px;width:auto;object-fit:contain}
[data-theme="dark"] .story-logo img{filter:invert(1) brightness(1.8)}
.story p{font:400 15px/1.55 var(--font-ui);color:var(--text-2);margin:10px 0 0;flex:1}
.story-links{display:flex;flex-direction:column;gap:10px;margin-top:var(--s-6);
  padding-top:var(--s-5);border-top:1px solid var(--border)}
.story-primary,.story-secondary{display:inline-flex;align-items:center;gap:7px;
  text-decoration:none;font:700 14px var(--font-ui)}
.story-primary{color:var(--accent-ink)}
.story-secondary{color:var(--text-3)}
.story-secondary:hover{color:var(--text)}
.story-links svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform var(--t-base) var(--ease)}
.story-primary:hover svg{transform:translateX(4px)}
.story-secondary:hover svg{transform:translate(2px,-2px)}

/* -- voices -- */
.voices{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-6)}
@media(max-width:900px){.voices{grid-template-columns:1fr}}
.voice{margin:0;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-3);padding:var(--s-8);box-shadow:var(--shadow-1)}
.voice blockquote{margin:0;font:500 16px/1.55 var(--font-ui);color:var(--text);text-wrap:pretty}
.voice figcaption{display:flex;align-items:center;gap:12px;margin-top:var(--s-6);
  padding-top:var(--s-5);border-top:1px solid var(--border)}
.voice figcaption b{display:block;font:700 14.5px var(--font-ui)}
.voice figcaption span span{font:500 12.5px var(--font-ui);color:var(--text-3)}
.voice figcaption img{height:30px;width:auto;margin-left:auto;opacity:.55;filter:grayscale(1)}
[data-theme="dark"] .voice figcaption img{filter:grayscale(1) invert(1) brightness(1.7)}

/* -- the roster grid -- */
/* 4 across on desktop, not 6 — the logos were too small to read */
.roster{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(4,1fr);gap:var(--s-4)}
@media(max-width:900px){.roster{grid-template-columns:repeat(3,1fr)}}
@media(max-width:600px){.roster{grid-template-columns:repeat(2,1fr)}}
.roster li{display:grid}
.roster a,.roster span{display:grid;place-items:center;height:140px;padding:var(--s-6);
  border:1px solid var(--border);border-radius:var(--r-2);background:var(--surface);
  transition:border-color var(--t-base) var(--ease),transform var(--t-base) var(--ease),
             box-shadow var(--t-base) var(--ease)}
.roster a:hover{border-color:var(--border-strong);transform:translateY(-2px);box-shadow:var(--shadow-1)}
.roster img{max-height:64px;max-width:100%;width:auto;object-fit:contain;
  opacity:.72;filter:grayscale(1);transition:opacity var(--t-base) var(--ease),filter var(--t-base) var(--ease)}
.roster a:hover img{opacity:1;filter:none}
[data-theme="dark"] .roster img{filter:grayscale(1) invert(1) brightness(1.8)}
[data-theme="dark"] .roster a:hover img{filter:none;opacity:1}

/* the roster is its own section again — the testimonial carousel now sits
   between it and the featured stories and does the separating */

/* ==========================================================================
   Full-bleed testimonial carousel.
   Scroll-snap does the work, so with JS blocked this is still a swipeable,
   readable row — JS only adds auto-advance, arrows and dots.
   ========================================================================== */
.voices-sec{overflow:hidden}
/* Break out of .wrap and run edge to edge at ANY viewport width.
   MARGIN, not transform: this element also carries .rv, and the reveal sets
   transform:translateY(26px), which OVERWRITES a translateX(-50%) on the same
   element — the whole track was displaced half a viewport to the right and the
   cards started off-centre. Two rules fighting for one property; the margin
   technique does not compete. */
.vwall{position:relative;width:100vw;margin-inline:calc(50% - 50vw)}
.vwall-track{
  /* the SCROLL container only — layout lives on .vwall-inner */
  overflow-x:auto;scroll-snap-type:x proximity;
  scroll-padding-inline-start:var(--gutter);
  scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
/* width:max-content + auto inline margins is the reliable "centre when it
   fits, left-align when it overflows" pattern. justify-content:center centres
   the overflow too and makes the first cards unreachable; `safe center` did
   not behave consistently here. Auto margins simply compute to 0 when the
   content is wider than the box. */
.vwall-inner{
  display:flex;gap:var(--s-6);width:max-content;margin-inline:auto;
  padding:4px var(--gutter) var(--s-6);
}
.vwall-track::-webkit-scrollbar{display:none}

.vcard{
  /* bigger than the first pass: at 330px four cards nearly fit a 1440 track and
     the carousel had almost nothing to do. Portrait video wants presence. */
  position:relative;flex:0 0 clamp(280px,30vw,400px);scroll-snap-align:start;
  /* PORTRAIT, per Lance — a talking-head video is a portrait shape */
  /* Until a real still exists the quote is CENTRED — bottom-aligned left a
     card-height void under the play button. With a poster it bottom-aligns,
     because then the void is the photograph. */
  aspect-ratio:3/4;display:flex;flex-direction:column;justify-content:center;
  border-radius:var(--r-3);padding:var(--s-6);overflow:hidden;
  background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-1);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease);
}
.vcard:hover{transform:translateY(-4px);box-shadow:var(--shadow-2)}
/* when a real still exists it becomes the card, with a scrim for legibility */
.vcard[style*="--poster"]{background:var(--poster) center/cover no-repeat;border-color:transparent}
.vcard[style*="--poster"]::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,.15) 30%,rgba(0,0,0,.82));z-index:0}
.vcard[style*="--poster"]{justify-content:flex-end}
.vcard[style*="--poster"] blockquote,
.vcard[style*="--poster"] footer{position:relative;z-index:1;color:#fff}
.vcard[style*="--poster"] footer span span{color:rgba(255,255,255,.72)}

.vcard blockquote{margin:0;font:600 15px/1.45 var(--font-ui);letter-spacing:-.012em;
  color:var(--text);text-wrap:pretty;
  /* long quotes must not push the attribution out of a fixed-ratio card */
  display:-webkit-box;-webkit-line-clamp:8;-webkit-box-orient:vertical;overflow:hidden}
.vcard footer{display:flex;align-items:center;gap:10px;margin-top:var(--s-5);
  padding-top:var(--s-4);border-top:1px solid var(--border)}
.vcard[style*="--poster"] footer{border-top-color:rgba(255,255,255,.22)}
.vcard footer b{display:block;font:700 13.5px var(--font-ui)}
.vcard footer span span{font:500 12px var(--font-ui);color:var(--text-3)}
.vcard footer img{height:26px;width:auto;margin-left:auto;opacity:.5;filter:grayscale(1)}
[data-theme="dark"] .vcard footer img{filter:grayscale(1) invert(1) brightness(1.7)}

.vcard-play{position:absolute;top:14px;right:14px;z-index:2;
  width:44px;height:44px;border-radius:var(--r-btn);cursor:pointer;
  border:1px solid var(--border);background:var(--surface);color:var(--text);
  display:grid;place-items:center;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             transform var(--t-fast) var(--ease)}
.vcard-play:hover{background:var(--accent);color:var(--on-accent);border-color:transparent;transform:scale(1.06)}
.vcard-play svg{width:17px;height:17px;fill:currentColor;stroke:none}

.vwall-ctl{display:flex;align-items:center;justify-content:center;gap:var(--s-4);margin-top:var(--s-4)}
.vwall-ctl button{width:40px;height:40px;border-radius:var(--r-btn);cursor:pointer;
  border:1px solid var(--border);background:var(--surface);color:var(--text-2);
  display:grid;place-items:center;
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.vwall-ctl button:hover{border-color:var(--border-strong);color:var(--text)}
.vwall-ctl svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.vwall-dots{display:flex;gap:7px}
.vwall-dots button{width:8px;height:8px;min-width:0;padding:0;border-radius:99px;border:0;
  background:var(--border-strong);cursor:pointer;transition:width var(--t-base) var(--ease),
  background var(--t-base) var(--ease)}
.vwall-dots button[aria-selected="true"]{width:24px;background:var(--accent-ink)}

/* SAMPLE badge — fabricated placeholder testimonials must be unmistakable on
   sight, so a screenshot can never be mistaken for a real customer. */
.vcard-sample{position:absolute;top:14px;left:14px;z-index:2;
  border-radius:var(--r-btn);padding:5px 11px;
  font:800 10px var(--font-ui);letter-spacing:.1em;text-transform:uppercase;
  background:#F59E0B;color:#17130A}

/* ==========================================================================
   /about/ — the origin story, the timeline, the values.
   ========================================================================== */
.origin{max-width:62ch;margin:0 auto}
.origin p{font:400 17px/1.7 var(--font-ui);color:var(--text-2);margin:0 0 var(--s-5)}
.origin p:last-child{margin-bottom:0}
/* `.origin p` (0,1,1) outranks a bare `.origin-lead` (0,1,0) and silently
   flattened this back to body copy. Match the element too, and keep it AFTER
   the paragraph rule. */
.origin p.origin-lead{font:800 clamp(24px,2.6vw,34px)/1.2 var(--font-ui);
  letter-spacing:-.028em;color:var(--text);margin:0 0 var(--s-6)}
.origin strong{color:var(--text);font-weight:700}

/* the timeline reuses the spine, with the YEAR in the dot instead of an icon */
.spine-year{font:800 13px var(--font-ui);letter-spacing:-.01em;color:var(--text-2);
  font-variant-numeric:tabular-nums;text-align:center;line-height:1.1}
.spine-row.is-now .spine-dot{background:var(--accent);border-color:transparent;
  box-shadow:0 6px 20px color-mix(in srgb,var(--accent) 35%,transparent)}
.spine-row.is-now .spine-year{color:var(--on-accent)}
.spine-note{display:block;margin-top:6px;font:400 15px/1.55 var(--font-ui);
  color:var(--text-2);max-width:52ch}

/* the values grid is three-up and never two — three principles read as a set */
.grid-3{grid-template-columns:repeat(3,1fr)}
@media(max-width:900px){.grid-3{grid-template-columns:1fr;max-width:560px;margin:0 auto}}

/* ==========================================================================
   /contact/ — the form, and the three routes that are not the form.
   The inputs themselves are the kit's (.formgrid/.field/.input/.selectwrap);
   this only does layout, the honeypot, and the send/failure states.
   ========================================================================== */
.contact-grid{display:grid;grid-template-columns:1.45fr 1fr;gap:var(--s-8);
  align-items:start}
.contact-form-col{min-width:0}
/* the kit caps .formgrid at 560px for a console sidebar; this is a page */
.contact-form{max-width:none}
.contact-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-5)}

/* Off-canvas, NOT display:none — some bots skip fields they can tell are not
   rendered, and the whole point of a honeypot is that they fill it in. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* The hint exists in the markup from the start so the live region has
   somewhere to land, but "Required." under every empty field is nagging before
   anyone has done anything wrong. Show it only once the field IS wrong. */
.contact-form .field [data-hint]{display:none}
.contact-form .field.invalid [data-hint]{display:block}

.contact-send{display:flex;align-items:center;gap:var(--s-5);flex-wrap:wrap}
.form-status{font:600 14px/1.4 var(--font-ui);color:var(--text-2);margin:0}
.form-status.is-bad{color:var(--danger)}

.contact-done{text-align:center;padding:var(--s-7) 0}
.contact-done p{color:var(--text-2);margin:var(--s-3) 0 0;font:400 16px/1.6 var(--font-ui)}
.contact-tick{display:grid;place-items:center;width:52px;height:52px;margin:0 auto var(--s-5);
  border-radius:50%;background:var(--accent)}
.contact-tick svg{width:26px;height:26px;fill:none;stroke:var(--on-accent);
  stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}

.contact-aside{display:grid;gap:var(--s-5)}
.contact-card .btn{margin-top:var(--s-5)}
.contact-nofrom .btn{margin-top:var(--s-5)}

@media(max-width:1024px){
  .contact-grid{grid-template-columns:1fr;gap:var(--s-7)}
  /* three side-by-side cards under a full-width form reads as a footer strip,
     which is not what they are */
  .contact-aside{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:760px){
  .contact-row{grid-template-columns:1fr}
  .contact-aside{grid-template-columns:1fr}
}

/* ==========================================================================
   /product/ai-scheduler/ — the moat page.
   The solver panel is the display moment; everything else here is support.
   ========================================================================== */

/* the "live" dot next to the hero eyebrow */
.pulse{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--accent);margin-right:8px;vertical-align:1px;
  box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 60%,transparent);
  animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 55%,transparent)}
  70%{box-shadow:0 0 0 9px transparent}
  100%{box-shadow:0 0 0 0 transparent}
}
@media(prefers-reduced-motion:reduce){.pulse{animation:none}}

/* One always-dark section. It is not the dark THEME — it is a dark surface in
   both themes, so the solver panel reads as a console no matter what the
   visitor has chosen. The tokens below are therefore fixed values rather than
   theme tokens, which is the one place on this site that is allowed. */
.sec-dark{background:var(--ink,#0F0F14);color:#F4F4F5;
  padding:var(--section) 0}
.sec-dark .h2{color:#fff}
.sec-dark .lede{color:#A9A9B4}
.sec-dark .eyebrow{color:var(--accent)}

.solver{border:1px solid rgba(255,255,255,.10);border-radius:var(--r-3);
  background:#141419;box-shadow:var(--shadow-3);overflow:hidden}
.solver-top{display:flex;align-items:center;justify-content:space-between;
  gap:var(--s-4);padding:16px var(--s-6);border-bottom:1px solid rgba(255,255,255,.08)}
.solver-ev b{display:block;font:800 15px var(--font-ui);color:#fff}
.solver-ev small{font:500 12.5px var(--font-ui);color:#8A8A96}
.solver-tag{flex:none;border-radius:var(--r-btn);padding:6px 12px;
  font:800 11px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;background:rgba(255,255,255,.09);color:#C9C9D2}

.solver-body{display:grid;grid-template-columns:1.25fr 1fr}
.solver-chat{padding:var(--s-6);border-right:1px solid rgba(255,255,255,.08)}
.solver-trace{padding:var(--s-6)}
/* The greys in this panel are literals, not tokens, because the panel is dark
   in BOTH themes. That means nothing recomputes them — they were checked by
   hand against #141419 and #0F0F14, and #6E6E7A (the obvious first pick) came
   out at 3.65:1 and had to go. If you change one, re-run the contrast. */
.solver-lab{display:block;font:800 11px var(--font-ui);
  letter-spacing:var(--tracking-label);text-transform:uppercase;color:#82828E;
  margin-bottom:var(--s-5)}

.chat{display:grid;gap:var(--s-4);list-style:none}
.msg{display:grid;gap:5px;justify-items:start;max-width:88%}
.msg-b{border-radius:var(--r-2);padding:11px 14px;
  font:500 14.5px/1.5 var(--font-ui)}
.msg time{font:600 11.5px var(--font-ui);color:#82828E}
/* the operator is the human — their side is the plain one */
.msg-op{justify-self:end;justify-items:end;text-align:right}
.msg-op .msg-b{background:rgba(255,255,255,.09);color:#EDEDF0}
.msg-ai .msg-b{background:#1E1E26;color:#D5D5DD;
  border:1px solid rgba(255,255,255,.07)}
/* the one message that reports a completed fix wears the accent */
.msg-result .msg-b{background:color-mix(in srgb,var(--accent) 16%,#1E1E26);
  border-color:color-mix(in srgb,var(--accent) 34%,transparent);color:#fff}

.trace{display:grid;gap:var(--s-4);list-style:none}
.trace-row{display:grid;grid-template-columns:auto 1fr;gap:var(--s-4);
  align-items:start}
.trace-tick{width:20px;height:20px;flex:none;margin-top:2px;border-radius:50%;
  display:grid;place-items:center;background:var(--accent)}
.trace-tick svg{width:11px;height:11px;fill:none;stroke:var(--on-accent);
  stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}
.trace-b b{display:block;font:700 14px var(--font-ui);color:#EDEDF0}
.trace-b small{display:block;margin-top:2px;font:500 12.5px/1.45 var(--font-ui);
  color:#8A8A96;font-variant-numeric:tabular-nums}

.solver-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s-4);
  margin-top:var(--s-7);padding-top:var(--s-6);
  border-top:1px solid rgba(255,255,255,.08)}
.solver-stats dt{font:800 clamp(22px,2.4vw,30px)/1 var(--font-ui);color:#fff;
  letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.solver-stats dd{margin-top:5px;font:600 12px var(--font-ui);color:#8A8A96}

.solver-note{margin:var(--s-6) 0 0;text-align:center;
  font:500 13.5px var(--font-ui);color:#8A8A96}

/* --- the replay ---------------------------------------------------------
   Only the .is-playing state hides anything, and only JS ever sets it. With
   no JS the transcript is simply there, which is the readable fallback. */
.solver.is-playing .msg,
.solver.is-playing .trace-row,
.solver.is-playing .solver-stats > div{opacity:0;transform:translateY(10px)}
.solver .msg,.solver .trace-row,.solver .solver-stats > div{
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.solver.is-playing .is-on{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .solver.is-playing .msg,
  .solver.is-playing .trace-row,
  .solver.is-playing .solver-stats > div{opacity:1;transform:none}
}

/* four across, and never two-by-two: these are four separate promises, not
   a 2×2 matrix of anything */
.grid-4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1024px){.grid-4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.grid-4{grid-template-columns:1fr}}

/* three-column comparison — the extra column the pricing table does not have */
.cmp-us{color:var(--accent-ink)!important}
.cmp-tick,.cmp-cross{display:inline-grid;place-items:center;width:20px;height:20px;
  border-radius:50%}
.cmp-tick{background:var(--accent)}
.cmp-tick svg{width:11px;height:11px;fill:none;stroke:var(--on-accent);
  stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}
.cmp-cross{background:color-mix(in srgb,var(--text-3) 20%,transparent)}
.cmp-cross svg{width:10px;height:10px;fill:none;stroke:var(--text-3);
  stroke-width:2.6;stroke-linecap:round}

@media(max-width:1024px){
  /* stacked, and the trace loses its divider rather than keeping a rule that
     now runs along the wrong axis */
  .solver-body{grid-template-columns:1fr}
  .solver-chat{border-right:0;border-bottom:1px solid rgba(255,255,255,.08)}
}
@media(max-width:640px){
  .msg{max-width:100%}
  .solver-stats{grid-template-columns:1fr;gap:var(--s-5)}
}

/* `.steps` is hardcoded to four tracks because /product/ has four steps; this
   page has three and was rendering a hole in the row. The modifier and its
   stops must come AFTER the base media queries or the base 2-up/1-up rules
   would still win at narrow widths. */
.steps-3{grid-template-columns:repeat(3,1fr)}
@media(max-width:1024px){.steps-3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.steps-3{grid-template-columns:1fr}}

/* -- the wedge: the argument on the left, the footage on the right -------- */
.wedge{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-8);align-items:center}
.wedge .origin{margin:0;max-width:none}

/* A facade, not a player. It carries .pmplay so www.js's existing video-modal
   binding picks it up — no second player, and nothing third-party loads until
   someone clicks. */
.wedge-vid{position:relative;display:block;width:100%;aspect-ratio:16/10;
  border:1px solid var(--border);border-radius:var(--r-3);cursor:pointer;
  background:
    radial-gradient(ellipse 70% 60% at 50% 42%, color-mix(in srgb,var(--accent) 22%,transparent), transparent 70%),
    var(--surface-2);
  box-shadow:var(--shadow-1);overflow:hidden;
  transition:box-shadow var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
.wedge-vid:hover{box-shadow:var(--shadow-2);transform:translateY(-2px)}
.wedge-vid:focus-visible{outline:none;box-shadow:var(--focus-ring),var(--shadow-2)}
.wedge-vid-in{position:absolute;inset:0;display:grid;place-content:center;
  justify-items:center;gap:14px}
.wedge-vid-in svg{width:22px;height:22px;fill:var(--on-accent);stroke:none}
.wedge-vid-in > svg{grid-area:1/1;width:64px;height:64px;padding:21px;
  box-sizing:content-box;border-radius:50%;background:var(--accent);
  box-shadow:0 10px 34px color-mix(in srgb,var(--accent) 40%,transparent)}
.wedge-vid-in > span{font:700 15px var(--font-ui);color:var(--text)}
/* the stand-in has to be labelled where it is, not in a commit message */
.wedge-vid-note{position:absolute;top:12px;right:12px;border-radius:var(--r-btn);
  padding:5px 11px;font:800 10.5px var(--font-ui);
  letter-spacing:var(--tracking-label);text-transform:uppercase;
  background:var(--surface);color:var(--text-3);border:1px solid var(--border)}

@media(max-width:1024px){
  .wedge{grid-template-columns:1fr;gap:var(--s-7)}
  .wedge .origin{max-width:62ch;margin:0 auto}
}

/* -- the panel's rows mode -------------------------------------------------
   The AI Scheduler panel's left column is a conversation; every other feature
   page's is a form filling in. Same component, same deal-out — .frow carries
   .msg so the replay picks it up without knowing which mode it is in. */
.frows{display:grid;gap:var(--s-4)}
.frow{display:grid;grid-template-columns:auto 1fr;gap:var(--s-5);align-items:baseline;
  max-width:100%;justify-items:stretch;
  border:1px solid rgba(255,255,255,.07);border-radius:var(--r-2);
  background:#1E1E26;padding:12px 14px}
.frow dt{font:700 12px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:#82828E;white-space:nowrap}
.frow dd{font:500 14.5px/1.5 var(--font-ui);color:#EDEDF0;text-align:right}
/* the last row is the one that completed — it wears the accent, same as the
   chat's result bubble */
.frow-done{background:color-mix(in srgb,var(--accent) 16%,#1E1E26);
  border-color:color-mix(in srgb,var(--accent) 34%,transparent)}
.frow-done dd{color:#fff;font-weight:700}
@media(max-width:640px){
  .frow{grid-template-columns:1fr;gap:4px}
  .frow dd{text-align:left}
}

/* ==========================================================================
   THE HEADER — dropdown + the mobile menu
   ========================================================================== */
.navitem{position:relative}
.navtop{display:inline-flex;align-items:center;gap:5px;border:0;background:none;
  cursor:pointer;padding:9px 14px;border-radius:var(--r-btn);
  font:600 14.5px var(--font-ui);color:var(--text-2);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.navtop svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;
  transition:transform var(--t-fast) var(--ease)}
.navtop:hover,.navitem.is-open .navtop{background:var(--surface-2);color:var(--text)}
.navitem.is-open .navtop svg{transform:rotate(180deg)}
.navtop:focus-visible{outline:none;box-shadow:var(--focus-ring)}

/* `hidden` does the hiding, so the panel is genuinely out of the tab order and
   out of the accessibility tree when it is shut. The animation is an opt-in on
   top of that, not the mechanism. */
.navmenu[hidden]{display:none}
.navmenu{position:absolute;top:calc(100% + 8px);left:0;z-index:60;width:max-content;
  max-width:min(560px,calc(100vw - 2 * var(--gutter)));
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-3);box-shadow:var(--shadow-3);overflow:hidden}
.navitem.is-open .navmenu{animation:navdrop .22s var(--ease) both}
@keyframes navdrop{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.navitem.is-open .navmenu{animation:none}}

.navmenu-in{display:grid;grid-template-columns:1fr 1fr;gap:2px;padding:8px}
.navmenu-in a{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start;
  padding:12px;border-radius:var(--r-2);text-decoration:none;
  transition:background var(--t-fast) var(--ease)}
.navmenu-in a:hover{background:var(--surface-2)}
.navmenu-in a:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.navmenu-in b{display:block;font:700 14.5px var(--font-ui);color:var(--text)}
.navmenu-in small{display:block;margin-top:3px;font:500 12.5px/1.45 var(--font-ui);
  color:var(--text-3)}
.navmenu-in a[aria-current="page"]{background:var(--surface-2)}
.navmenu-in a[aria-current="page"] b{color:var(--accent-ink)}
.navmenu-ico{display:grid;place-items:center;width:34px;height:34px;flex:none;
  border-radius:var(--r-2);background:color-mix(in srgb,var(--accent) 16%,transparent)}
.navmenu-ico svg{width:17px;height:17px;fill:none;stroke:var(--accent-ink);
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* the section's own landing page — a full-width row, not a hover-only link */
.navmenu-more{display:flex;align-items:center;gap:7px;padding:13px 20px;
  border-top:1px solid var(--border);background:var(--surface-2);
  font:700 13.5px var(--font-ui);color:var(--text);text-decoration:none}
.navmenu-more:hover{color:var(--accent-ink)}
.navmenu-more svg{width:15px;height:15px;fill:none;stroke:currentColor;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

.nav-links a[aria-current="page"]{color:var(--text);background:var(--surface-2)}

/* -- the burger + the sheet ------------------------------------------------
   Hidden above 1024 where .nav-links does the work; it IS the work below. */
.burger{display:none;width:40px;height:40px;flex:none;border:1px solid var(--border);
  background:var(--surface);border-radius:var(--r-btn);cursor:pointer;
  place-content:center;gap:5px;padding:0}
.burger span{display:block;width:17px;height:2px;border-radius:2px;
  background:var(--text);transition:transform var(--t-fast) var(--ease),
  opacity var(--t-fast) var(--ease)}
.burger[aria-expanded="true"] span:first-child{transform:translateY(3.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:translateY(-3.5px) rotate(-45deg)}
.burger:focus-visible{outline:none;box-shadow:var(--focus-ring)}

.mnav[hidden]{display:none}
.mnav{position:fixed;inset:0;top:64px;z-index:45;background:var(--bg);
  overflow-y:auto;-webkit-overflow-scrolling:touch;
  animation:mnavin .2s var(--ease) both}
@keyframes mnavin{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.mnav{animation:none}}
.mnav-in{padding:var(--s-6) var(--gutter) var(--s-8);display:grid;gap:2px}
.mnav-top{display:block;padding:14px 4px;text-decoration:none;
  font:800 21px var(--font-ui);letter-spacing:-.02em;color:var(--text);
  border-bottom:1px solid var(--border)}
.mnav-top[aria-current="page"]{color:var(--accent-ink)}
.mnav-sub{display:grid;gap:2px;padding:var(--s-4) 0}
.mnav-sub a{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:center;
  padding:11px 4px;text-decoration:none}
.mnav-sub b{display:block;font:700 15px var(--font-ui);color:var(--text)}
.mnav-sub small{display:block;margin-top:2px;font:500 13px/1.4 var(--font-ui);
  color:var(--text-3)}
.mnav-sub a[aria-current="page"] b{color:var(--accent-ink)}
.mnav-cta{display:grid;gap:var(--s-3);margin-top:var(--s-6)}
.mnav-cta .btn{width:100%}

@media(max-width:1024px){
  .burger{display:grid}
  /* the ghost "Sign in" is hidden at this width already; the sheet carries it */
}
@media(min-width:1025px){
  .mnav{display:none}
}
@media(max-width:640px){
  .navmenu-in{grid-template-columns:1fr}
}

/* ⚠️ The header needs ~1065px of viewport at its full spacing, but the desktop
   nav switches on at 1025 — so 1025–1064 pushed "Book a demo" off the page.
   Same failure as the 901–1000 band before it: the breakpoint was chosen for
   where the links LOOK cramped, not for where they stop fitting. Measure it.
   This tightens the header between the two sanctioned stops rather than
   handing a burger to everyone under 1280. */
@media(min-width:1025px) and (max-width:1279px){
  .nav-in{gap:var(--s-5)}
  .nav-links{margin-left:0}
  .nav-links a,.navtop{padding-left:10px;padding-right:10px}
  .nav-right{gap:var(--s-2)}
}
/* a nav section with no index page — a heading, not a dead link */
.mnav-top.is-label{color:var(--text-3)}
/* flipped by www.js when the panel would run off the right edge */
.navmenu.is-right{left:auto;right:0}

/* ==========================================================================
   /compare/ — the head-to-head pages.
   The design job is not "look convincing", it is "be checkable": the source
   sits inside the row with the claim, and the verification date is where a
   sceptic looks first.
   ========================================================================== */
/* icon + ONE text node, so the sentence wraps as a sentence. Three flex items
   put the bolded date on its own column when it wrapped on a phone. */
.cmp-stamp{display:inline-flex;align-items:center;gap:9px;margin-top:var(--s-6);
  border-radius:var(--r-btn);padding:9px 16px;
  background:color-mix(in srgb,var(--accent) 15%,transparent);
  font:600 13.5px var(--font-ui);color:var(--accent-ink)}
.cmp-stamp b{font-weight:800}
.cmp-stamp svg{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

.cmp-context{border-left:3px solid var(--accent);padding:2px 0 2px var(--s-6);
  max-width:62ch;margin:0 auto}
.cmp-context p{font:500 16px/1.65 var(--font-ui);color:var(--text-2);margin:0}
.cmp-context a{display:inline-flex;align-items:center;gap:6px;margin-top:10px;
  font:700 13px var(--font-ui);color:var(--accent-ink)}
.cmp-context a svg,.vs-src svg{width:13px;height:13px;flex:none;fill:none;
  stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* -- compare v2: the table is the page; receipts are footnotes ----------- */
/* extensions over the pricing .cmp table */
.cmpx thead th.cmpx-brand{color:var(--text)}
.cmpx tbody td{vertical-align:middle}
.cmpx-lead{font:800 15.5px/1.4 var(--font-ui);color:var(--text)}
.cmpx-rest{font:500 14.5px/1.4 var(--font-ui);color:var(--text-3);
  font-variant-numeric:tabular-nums}
.cmpx-tick{display:inline-block;width:17px;height:17px;margin-right:8px;
  vertical-align:-3px;border-radius:50%;
  background:var(--accent) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%2317130A" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"><path d="M4 13l5 5L20 7"/></svg>') center/9px no-repeat}
.cmpx-fn{text-decoration:none;color:var(--text-3);margin-left:3px}
.cmpx-fn:hover{color:var(--accent-ink)}
.cmpx-fn sup{font:700 11px var(--font-ui)}
.cmpx-legend{margin:12px 2px 0;font:500 13px var(--font-ui);color:var(--text-3)}

.cmp-context{border-left:3px solid var(--accent);padding:2px 0 2px var(--s-6);
  max-width:62ch;margin:0 0 var(--s-7)}
.cmp-context p{font:500 15.5px/1.6 var(--font-ui);color:var(--text-2);margin:0}
.cmp-context a{display:inline-flex;align-items:center;gap:6px;margin-top:8px;
  font:700 12.5px var(--font-ui);color:var(--accent-ink)}
.cmp-context a svg,.vs-src svg{width:13px;height:13px;flex:none;fill:none;
  stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* the receipts: a numbered source list, deliberately quiet */
.receipts{list-style:none;margin:0;padding:0;counter-reset:src;display:grid;gap:var(--s-5)}
.receipt{counter-increment:src;position:relative;padding-left:34px;
  font:400 14.5px/1.6 var(--font-ui);color:var(--text-2)}
.receipt::before{content:counter(src);position:absolute;left:0;top:1px;
  width:22px;height:22px;display:grid;place-items:center;border-radius:50%;
  border:1px solid var(--border-strong);font:700 11.5px var(--font-ui);
  color:var(--text-3)}
.receipt b{color:var(--text)}
.receipt:target::before{background:var(--accent);color:var(--on-accent);border-color:transparent}
.receipt .vs-src{display:inline-flex;align-items:center;gap:6px;margin-left:8px;
  font:700 12.5px var(--font-ui);color:var(--text-3);text-decoration:none}
.receipt .vs-src:hover{color:var(--accent-ink)}
}
}

/* -- the client-sites carousel (/product/websites-and-apps/) ---------------
   Reuses the testimonial carousel's machinery — .vwall / .vwall-track /
   .vwall-inner and the [data-carousel] script — with a 16:9 card instead of a
   3:4 one, because that is the shape of a website. */
.sitewall{margin-top:var(--s-8)}
.sitewall-lab{margin:0 0 var(--s-6);text-align:center;
  font:800 11.5px var(--font-ui);letter-spacing:var(--tracking-label);
  text-transform:uppercase;color:#82828E}

.scard{position:relative;display:block;flex:0 0 clamp(300px,46vw,620px);
  scroll-snap-align:start;aspect-ratio:16/9;border-radius:var(--r-3);
  overflow:hidden;text-decoration:none;
  border:1px solid rgba(255,255,255,.12);background:#141419;
  box-shadow:var(--shadow-2);
  transition:transform var(--t-base) var(--ease),border-color var(--t-base) var(--ease)}
.scard:hover{transform:translateY(-4px);border-color:color-mix(in srgb,var(--accent) 55%,transparent)}
.scard:focus-visible{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
.scard img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
/* the scrim only exists under the caption, so the screenshot stays readable */
.scard-meta{position:absolute;left:0;right:0;bottom:0;padding:var(--s-6);
  display:grid;gap:2px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.86) 62%)}
.scard-meta b{font:800 16px var(--font-ui);color:#fff;letter-spacing:-.01em}
.scard-meta small{font:500 13px var(--font-ui);color:rgba(255,255,255,.72)}
.scard-go{position:absolute;top:12px;right:12px;width:30px;height:30px;
  display:grid;place-items:center;border-radius:50%;
  background:rgba(0,0,0,.5);backdrop-filter:blur(4px);opacity:0;
  transition:opacity var(--t-base) var(--ease)}
.scard:hover .scard-go,.scard:focus-visible .scard-go{opacity:1}
.scard-go svg{width:13px;height:13px;fill:none;stroke:#fff;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}

/* legal links live in both footers; the pages themselves stay on the legacy
   box (runbook 3.6) — these are plain links, not routes in this app */
.foot-legal{margin-left:auto}
.foot-legal a{color:var(--text-3);text-decoration:none;font:500 13.5px var(--font-ui)}
.foot-legal a:hover{color:var(--text)}
@media(max-width:640px){.foot-legal{margin-left:0}}

/* ==========================================================================
   Feedback round 1 (2026-08-14): dark default, swapper, always-dark footer,
   quote fade, bigger marquee.
   ========================================================================== */
/* the accent swatch button — a filled circle in the CURRENT accent */
.accent-dot{display:block;width:16px;height:16px;border-radius:50%;
  background:var(--accent);border:2px solid var(--surface);
  box-shadow:0 0 0 1px var(--border-strong)}

/* the footer is ALWAYS dark, both themes — fixed values on purpose.
   ⚠️ specificity: .foot ul a (0,1,2) beats .foot a (0,1,1), which is exactly
   how light mode ended up with near-black links on the black footer. Match
   the real selectors, don't rely on order. */
.foot{background:#0A0A0F;color:#B4B4BD}
.foot .wordmark{color:#fff}
.foot a,.foot ul a{color:#B4B4BD}
.foot a:hover,.foot ul a:hover{color:#fff}
.foot h4{color:#6E6E7A}
.foot-note{border-top-color:rgba(255,255,255,.1);color:#6E6E7A}
.foot-legal a{color:#6E6E7A}
.foot-legal a:hover{color:#fff}
.socials a{border-color:rgba(255,255,255,.14);color:#B4B4BD}

/* official store badges (Lance: colorful, not our monochrome buttons).
   Google's official PNG carries baked-in padding; the negative margin trims
   it so both badges sit at the same optical height. */
.apps img{height:46px;width:auto;display:block;border-radius:8px;
  transition:transform var(--t-base) var(--ease)}
.apps a:hover img{transform:translateY(-2px)}
.apps img.gp{height:68px;margin:-11px 0}

/* marquee heading (was an eyebrow) + logos sized up ~30% */
.marquee-h{font:800 clamp(20px,2.2vw,28px)/1.25 var(--font-ui);
  letter-spacing:-.02em;text-align:center;color:var(--text);
  margin:0 0 var(--s-10)}
.marquee img{height:56px}
@media(max-width:640px){.marquee img{height:42px}}

/* quote rotation fade — the stage animates HEIGHT so a longer/shorter quote
   eases instead of snapping the page (Lance) */
.quote-stage{position:relative;transition:height .55s var(--ease);overflow:hidden}
.quote-item{transition:opacity .6s var(--ease)}
.quote-item.is-fading{opacity:0}

/* the parallaxed hero footage needs headroom so translated pixels stay covered */
.hero-bg img,.hero-bg video{height:130%}

/* GSAP-ScrollSmoother-style smoothing: scroll input stays 100% NATIVE (no
   wheel hijack — rounds 2 and 3 proved that path feels like dragging weight);
   the content layer chases the real scroll position. Activated by JS only
   when: fine pointer, no reduced-motion, ≥768px, and no [data-native-scroll]
   on the page (resources + demo keep native for their sticky rails). */
.has-smooth #smooth{position:fixed;inset:0;overflow:hidden}
.has-smooth #smoothContent{will-change:transform}

/* hero eyebrow: the full phrase is desktop-only; phones get the short cut */
.eyebrow .eb-short{display:none}
@media(max-width:640px){
  .eyebrow .eb-long{display:none}
  .eyebrow .eb-short{display:inline}
}

/* nav panel: the whole-platform link leads, prominent (Lance) */
.navmenu-more.is-top{display:flex;align-items:center;justify-content:space-between;
  gap:10px;margin:0 0 12px;border-radius:12px;padding:12px 16px;
  background:color-mix(in srgb,var(--accent) 14%,transparent);
  font:800 14.5px var(--font-ui);color:var(--accent-ink);text-decoration:none}
.navmenu-more.is-top:hover{background:color-mix(in srgb,var(--accent) 22%,transparent)}
.navmenu-more.is-top svg{width:15px;height:15px;fill:none;stroke:currentColor;
  stroke-width:2.2;stroke-linecap:round}

/* required-field marks on the contact form (Lance) */
.contact-form .req{color:#E5484D;font-style:normal;font-weight:800;margin-left:1px}

/* real video posters — the wedge facade and the product tiles show the
   YouTube thumbnail of whichever clip they will play (Lance: make sure the
   thumbnail shows). Scrim keeps the play button legible on any poster. */
.wedge-vid.has-poster{background:var(--poster) center/cover no-repeat}
.wedge-vid.has-poster::before{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,.18),rgba(0,0,0,.55));z-index:0}
.wedge-vid.has-poster .wedge-vid-in{z-index:1}
.wedge-vid.has-poster .wedge-vid-in > span{color:#fff}
.wedge-vid.has-poster .wedge-vid-note{z-index:1;background:rgba(0,0,0,.55);
  color:#fff;border-color:transparent;backdrop-filter:blur(4px)}
/* product tiles: a poster strip above the card body, always visible, with the
   play pill on it (the pill no longer hides until hover — a thumbnail without
   a visible play control reads as a photo) */
/* the card keeps its own padding for the body; the poster is a full-bleed
   strip pulled out to the edges with negative margins so it meets the border */
.pmcard.has-poster{padding-top:0;overflow:hidden}
.pmcard.has-poster::before{content:"";display:block;aspect-ratio:16/9;
  background:var(--poster) center/cover no-repeat;
  margin:0 calc(-1 * var(--s-8)) var(--s-5)}
.pmcard.has-poster .pmplay{opacity:1;transform:none;top:auto;right:auto;
  position:absolute;left:14px;top:14px;background:rgba(0,0,0,.6);color:#fff;
  border-color:transparent;backdrop-filter:blur(4px)}
.pmcard.has-poster .pmplay:hover{background:var(--accent);color:var(--on-accent)}

