/* ============================================================================
   STAFFIVA — Public landing / marketing stylesheet.
   Self-contained: does NOT depend on site.css or bootstrap. Tokens mirror the
   in-app dark-glass system (staffiva-dashboard-v2.css). Fonts fall back to
   system when Manrope/Inter are absent — the app loads no web-font CDN, so
   neither does this page.
   ============================================================================ */
:root{
  /* purple ramp */
  --purple-900:#25005a; --purple-700:#6d30a7; --purple-600:#7e3af2;
  --purple-500:#8b4ff5; --purple-400:#b97bff; --purple-300:#d2bbff; --purple-200:#e2c3ff;
  /* --primary is accent-as-TEXT (a{color:var(--primary)}, .legal-wrap a). Kept in lockstep with
     staffiva-dashboard-v2.css, whose AA floor is now measured against the brightest ground accent
     text is DRAWN on rather than the bare canvas (ruling R17): 4.53:1 there, 5.41:1 on --surface.
     Was #9a63f5,
     which measured 4.41:1 on this sheet's own --surface-card. */
  --primary:#a16ff6; --primary-hover:var(--purple-500); --primary-accent:var(--purple-300);
  --primary-glow:var(--purple-400); --on-primary:var(--purple-900); --primary-soft:rgba(126,58,242,.15);
  /* surfaces */
  --surface-base:#0f0f14; --surface-lowest:#0e0c1a; --surface:#141121; --surface-low:#1c1929;
  --surface-card:#1c1c25; --surface-container:#221f30; --surface-high:#2a2638;
  --surface-highest:#322e40; --surface-bright:#3a3748; --surface-section:#16161d;
  /* text */
  --text-primary:#f5f5f7; --text-on-surface:#e6dff6; --text-secondary:#b3b3c0;
  /* --text-muted lightened from #84848f in lockstep with staffiva-tokens.css / staffiva-dashboard-v2.css
     — one token name has to mean one colour. See the arithmetic in staffiva-tokens.css: the old value
     only cleared AA against the bare canvas. */
  --text-on-variant:#ccc3d8; --text-muted:#9a9aa6;
  /* borders */
  --border:#2a2a35; --divider:#23232d; --outline-variant:#4a4455;
  --ghost-border:color-mix(in srgb, var(--outline-variant) 15%, transparent);
  --ghost-border-strong:color-mix(in srgb, var(--outline-variant) 30%, transparent);
  /* state */
  --success:#3cddc7; --success-soft:color-mix(in srgb, var(--success) 10%, transparent);
  --warning:#f2c94c; --warning-soft:color-mix(in srgb, var(--warning) 12%, transparent);
  --error:#ff8d8c; --error-strong:#e24b4a; --error-soft:color-mix(in srgb, var(--error) 8%, transparent);
  /* gradients + glows */
  --gradient-primary:linear-gradient(135deg, var(--purple-300), var(--purple-600));
  /* Interactive/label fill: stops kept light enough that --on-primary (dark)
     text clears WCAG AA (>=4.5:1) across the WHOLE gradient — the vivid
     --gradient-primary dark stop (#7e3af2) drops to ~3.1:1 under dark text. */
  --gradient-button:linear-gradient(135deg, var(--purple-300), var(--purple-400));
  --gradient-text:linear-gradient(90deg, rgba(109,48,167,.72), var(--purple-400));
  --page-wash:
    radial-gradient(circle at top left, rgba(126,58,242,.22), transparent 30%),
    linear-gradient(180deg,#13131b 0%, var(--surface-base) 22%, #101017 100%);
  --shadow-ambient:0 24px 48px rgba(14,12,26,.72);
  --shadow-card:0 24px 60px rgba(0,0,0,.28);
  --shadow-card-hover:0 18px 45px rgba(0,0,0,.32), 0 0 28px rgba(126,58,242,.12);
  --shadow-button:0 .85rem 2rem rgba(126,58,242,.26);
  --shadow-button-hover:0 1rem 2.4rem rgba(126,58,242,.34);
  --glow-soft:0 0 28px rgba(185,123,255,.20);
  /* radii */
  --radius-pill:999px; --radius-sm:.875rem; --radius-md:1.125rem; --radius-input:1rem;
  --radius-lg:1.5rem; --radius-xl:1.75rem;
  /* type */
  --font-display:"Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:"Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --tracking-tight:-0.02em; --tracking-label:0.05em;
}

*{box-sizing:border-box;}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%;}
/* The document scrollbar. Staffiva is dark on every layout, but without a declared colour scheme the
   browser paints its LIGHT default scrollbar down the right edge of a near-black page (owner-reported
   2026-09-10). color-scheme: dark asks every engine for its dark native bar (and dark native form
   controls); the scrollbar-* pair thins and tints it where supported (Chromium 121+, Firefox), and the
   -webkit- rules do the same for older WebKit. Same treatment as the side rail (.sd-nav). */
html { color-scheme: dark; scrollbar-width: thin; scrollbar-color: var(--ghost-border-strong) transparent; }
html::-webkit-scrollbar { width: 10px; }
html::-webkit-scrollbar-track { background: transparent; }
html::-webkit-scrollbar-thumb { background: var(--ghost-border-strong); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
html::-webkit-scrollbar-thumb:hover { background: var(--outline-variant); background-clip: padding-box; }
body{
  margin:0; background:var(--surface-base);
  color:var(--text-secondary); font-family:var(--font-body); font-size:16px; line-height:1.6;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; overflow-x:hidden;
}
/* The page wash lives on a fixed underlay, NOT on body with background-attachment:fixed:
   iOS Safari sizes a fixed body background against the full DOCUMENT, so the top-left
   radial ("transparent 30%") ballooned across the whole first screen on iPhone — the
   live site rendered a much lighter purple than desktop. position:fixed paints
   identically in Blink and WebKit. */
body::before{
  content:""; position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:var(--surface-base); background-image:var(--page-wash);
}
h1,h2,h3,h4{font-family:var(--font-display); color:var(--text-primary); letter-spacing:var(--tracking-tight); margin:0;}
p{margin:0;}
a{color:var(--primary); text-decoration:none;}
img{max-width:100%;}
:focus-visible{outline:2px solid var(--primary-glow); outline-offset:2px;}
::selection{background:rgba(126,58,242,.35); color:#fff;}

.wrap{max-width:1160px; margin:0 auto; padding:0 24px;}
/* nowrap: the gradient phrase is a short clause ("you approve") and a mid-phrase
   break reads as two headlines. It still fits on one line at 380px. */
.grad-text{background:var(--gradient-primary); -webkit-background-clip:text; background-clip:text; color:transparent; white-space:nowrap;}
.kicker{font-family:var(--font-body); font-weight:700; font-size:.78rem; letter-spacing:.09em;
  text-transform:uppercase; color:var(--purple-300); margin:0 0 14px;}
.eyebrow{font-size:.75rem; font-weight:600; letter-spacing:var(--tracking-label); text-transform:uppercase; color:var(--text-muted);}
.muted{color:var(--text-muted);}
.lead{font-size:1.14rem; color:var(--text-secondary); line-height:1.6;}

/* shared status dots (used by the product-preview mocks) */
.dot{width:7px; height:7px; border-radius:50%; box-shadow:0 0 8px currentColor; flex:0 0 auto;}
.dot-live{color:var(--success); background:var(--success); animation:pulse 1.8s ease-in-out infinite;}
.dot-accent{color:var(--purple-400); background:var(--purple-400);}
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.35;}}

/* ---- BUTTONS ---- */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:8px; cursor:pointer; border:0;
  font-family:var(--font-display); font-weight:700; letter-spacing:var(--tracking-tight);
  border-radius:var(--radius-lg); padding:14px 26px; font-size:15px; transition:transform .18s ease, box-shadow .18s ease, background .18s ease; white-space:nowrap;}
.btn-primary{background:var(--gradient-button); color:var(--on-primary); box-shadow:var(--shadow-button);}
.btn-primary:hover{transform:translateY(-1px); box-shadow:var(--shadow-button-hover); color:var(--on-primary);}
.btn-ghost{background:color-mix(in srgb, var(--surface-high) 55%, transparent); color:var(--text-on-surface);
  border:1px solid var(--ghost-border-strong);}
.btn-ghost:hover{background:var(--surface-high); color:#fff;}
.btn-sm{padding:10px 18px; font-size:14px;}

/* ---- NAV ---- */
/* Skip link: the first focusable thing on the page, parked off the top of the
   sticky bar until it takes focus. It jumps to the audit input — the one thing a
   keyboard visitor came for — rather than to a generic "main". */
.skip-link{position:absolute; left:12px; top:-40px; z-index:100; padding:8px 12px;
  background:var(--surface,#1a1a22); color:var(--text-primary); border-radius:8px;
  border:1px solid var(--ghost-border-strong); font-size:14px; font-weight:600;
  box-shadow:var(--shadow-card);}
.skip-link:focus{top:12px;}
.nav{position:sticky; top:0; z-index:50; transition:background .25s ease, border-color .25s ease, backdrop-filter .25s ease;
  border-bottom:1px solid transparent;}
.nav.scrolled{background:color-mix(in srgb, var(--surface) 78%, transparent); backdrop-filter:blur(18px);
  -webkit-backdrop-filter:blur(18px); border-bottom:1px solid var(--ghost-border);}
/* Content-first pages (legal, account, beta wall) have no hero, so the sticky nav stays
   shaded at all times — otherwise page text scrolls under the transparent bar. Matches
   the .scrolled look. Opt in with ViewData["BodyClass"] on the view. */
body.page-legal .nav,
body.page-auth .nav,
body.page-beta .nav{background:color-mix(in srgb, var(--surface) 82%, transparent); backdrop-filter:blur(18px);
  -webkit-backdrop-filter:blur(18px); border-bottom:1px solid var(--ghost-border);}
.nav-inner{display:flex; align-items:center; justify-content:space-between; gap:20px; padding:14px 0;}
.brand{display:flex; align-items:center; gap:10px; font-family:var(--font-display); font-weight:800;
  font-size:20px; color:var(--text-primary); letter-spacing:-0.02em;}
.brand-mark{width:30px; height:30px; border-radius:9px; background:var(--gradient-primary);
  display:grid; place-items:center; color:var(--on-primary); font-weight:800; font-size:16px; box-shadow:var(--glow-soft);}
.nav-links{display:flex; align-items:center; gap:26px;}
.nav-links a.navlink{color:var(--text-on-variant); font-size:14px; font-weight:500;}
.nav-links a.navlink:hover{color:#fff;}
.nav-cta{display:flex; align-items:center; gap:12px;}
.brand-img{height:28px; width:auto; display:block;}
.foot-brand .brand-img{height:25px;}
.nav-login{color:var(--text-on-variant); font-size:14px; font-weight:600;}
.nav-login:hover{color:#fff;}
/* Mobile menu button — hidden on desktop and until JS un-hides it (see _PublicNav). */
.navlink-mobile{display:none;}
.nav-toggle{display:none; align-items:center; justify-content:center; width:40px; height:40px; padding:0;
  background:color-mix(in srgb, var(--surface-high) 55%, transparent); border:1px solid var(--ghost-border-strong);
  border-radius:var(--radius-sm); color:var(--text-on-surface); cursor:pointer;}
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after{display:block; width:18px; height:2px;
  border-radius:2px; background:currentColor; transition:transform .2s ease, background .2s ease;}
.nav-toggle-bars{position:relative;}
.nav-toggle-bars::before{content:""; position:absolute; top:-6px; left:0;}
.nav-toggle-bars::after{content:""; position:absolute; top:6px; left:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars{background:transparent;}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before{transform:translateY(6px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after{transform:translateY(-6px) rotate(-45deg);}

/* ---- SECTION SHELL ---- */
section{position:relative;}
.sec{padding:88px 0;}
.sec-tint{background:color-mix(in srgb, var(--surface-section) 45%, transparent);
  border-top:1px solid var(--ghost-border); border-bottom:1px solid var(--ghost-border);}
.sec-head{max-width:720px; margin:0 auto 48px; text-align:center;}
.sec-head h2{font-size:clamp(1.75rem,3.4vw,2.6rem); line-height:1.08;}
.sec-head p{margin:16px 0 0; font-size:1.1rem;}
/* The vision section is heading + prose only — nothing follows the head to be
   separated from, so the shared 48px trailer reads as a hole. */
.sec#vision .sec-head{margin-bottom:0;}

/* ---- HERO ---- */
.hero{padding:52px 0 64px;}
.hero-grid{display:grid; grid-template-columns:1.05fr .95fr; gap:56px; align-items:center;}
.hero h1{font-size:clamp(2.3rem,4.6vw,3.5rem); line-height:1.02; margin:0 0 20px;}
.hero .lead{max-width:520px; margin-bottom:26px;}
.hero-badges{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:26px;}
.pill{display:inline-flex; align-items:center; gap:7px; padding:6px 13px; border-radius:var(--radius-pill);
  font-size:12.5px; font-weight:600; background:color-mix(in srgb, var(--surface-high) 50%, transparent);
  border:1px solid var(--ghost-border); color:var(--text-on-variant);}
.pill .dot{background:var(--success); box-shadow:0 0 8px var(--success);}
/* Referral pill above the kicker — same shape language as .pill, accent-toned so it
   reads as "you were invited", not as another feature badge. */
.ref-banner{display:inline-flex; align-items:center; gap:8px; margin:0 0 14px; padding:6px 13px;
  border-radius:var(--radius-pill); font-size:12.5px; font-weight:600; line-height:1.4;
  background:var(--primary-soft); border:1px solid var(--ghost-border-strong); color:var(--purple-200);}

/* audit input form */
/* The frame carries the focus ring for the whole control (see :focus-within below),
   which is why the border is a visible one at every width rather than a hairline. */
.audit-form{display:flex; gap:10px; background:color-mix(in srgb, var(--surface-container) 78%, transparent);
  border:1px solid color-mix(in srgb, var(--outline-variant) 62%, transparent); border-radius:var(--radius-lg); padding:9px; max-width:540px;
  box-shadow:var(--shadow-card); transition:border-color .18s ease, box-shadow .18s ease;}
/* The ring lands on the frame, not the bare input, because the input is a
   transparent slot inside a framed control — a ring drawn on the input alone would
   float inside the box. This is also the ONLY reason the input below may keep
   outline:none: the visible focus indicator moved, it was not removed. */
.audit-form:focus-within{border-color:var(--primary); box-shadow:0 0 0 3px var(--primary-soft), var(--shadow-card);}
.audit-form .prefix{display:flex; align-items:center; padding:0 4px 0 14px; color:var(--text-muted); font-size:14px; font-weight:600;}
/* Address-bar-style site chip: a framed slot that holds a muted globe until the
   typed domain resolves, then crossfades to the site's favicon. The frame keeps
   light-colored favicons from glaring on the dark field. */
.audit-form .site-icon{width:30px; height:30px; flex:none; align-self:center; display:grid; place-items:center; position:relative;
  margin-left:6px; border-radius:9px; background:color-mix(in srgb, var(--surface-card) 85%, white 4%);
  border:1px solid var(--ghost-border);}
.audit-form .site-icon .globe{width:15px; height:15px; color:var(--text-muted); opacity:.75; transition:opacity .2s ease;}
.audit-form .site-icon.has-favicon .globe{opacity:0;}
.audit-form .site-favicon{position:absolute; inset:0; margin:auto; width:16px; height:16px; border-radius:4px;
  opacity:0; transform:scale(.8); transition:opacity .25s ease, transform .25s ease;}
.audit-form .site-favicon.is-visible{opacity:1; transform:scale(1);}
/* outline:none is permitted here ONLY because .audit-form:focus-within paints the
   ring on the frame that surrounds this input. Delete that rule and this one has to
   go with it, or keyboard focus becomes invisible. */
.audit-form input[type=text]{flex:1; min-width:0; background:transparent; border:0; outline:none;
  color:var(--text-primary); font-family:var(--font-body); font-size:16px; padding:12px 6px;}
.audit-form input::placeholder{color:var(--text-muted);}
/* Compact variant for the inline form inside step 1 — same control, less furniture.
   It WRAPS at every width, unlike the hero form which only wraps under 760px: this one lives in a
   ~400px grid column, so on one row the https:// prefix and the button left the field about 60px
   wide and the placeholder was clipped mid-word ("yourbus") on every desktop viewport. The button
   takes its own full-width row and the input keeps a 120px basis, which is the same shape the hero
   form takes on a phone. */
.audit-form-compact{padding:6px; gap:8px; max-width:none; flex-wrap:wrap;}
.audit-form-compact .btn{padding:10px 14px; font-size:14px; flex:1 0 100%;}
.audit-form-compact input[type=text]{font-size:14px; padding:9px 4px; flex:1 1 120px;}
.audit-form-compact .prefix{font-size:13px; padding:0 2px 0 10px;}
/* Each check is one unit: the tick, its bold label and the trailing words wrap
   together or not at all — a break between "No credit" and "card" reads as noise. */
.form-note{margin:14px 0 0; font-size:13px; color:var(--text-muted); display:flex; flex-wrap:wrap; gap:14px; align-items:center;}
.form-note>span{white-space:nowrap;}
.form-note b{color:var(--text-on-variant); font-weight:600;}
.form-note .chk{color:var(--success);}
.see-how{display:inline-flex; align-items:center; gap:8px; margin-top:22px; color:var(--text-on-variant); font-weight:600; font-size:14px;}
.see-how:hover{color:#fff;}
.see-how .play{width:26px; height:26px; border-radius:50%; background:color-mix(in srgb, var(--purple-600) 26%, transparent);
  border:1px solid var(--ghost-border-strong); display:grid; place-items:center; color:var(--purple-200); font-size:10px;}

/* ============================================================================
   GRAFT A — DOM product-preview dashboard collage (browser chrome, greeting,
   stat cards, agent row, draft card + floating sparkline). Ported from the
   continuity direction. Everything is DOM; no screenshots.
   ============================================================================ */
.glass{border-radius:var(--radius-lg);
  background:linear-gradient(180deg, color-mix(in srgb, var(--surface-high) 24%, var(--surface-low)), var(--surface-low));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), inset 0 0 0 1px var(--ghost-border), var(--shadow-ambient);}
/* min-width floor: the collage is the narrower hero track, and between ~1100 and
   1400px the 1.05fr copy column was squeezing it until the mock's own furniture
   (chrome dots, tiles, draft actions) started colliding. The floor is fluid so it
   can never overflow a narrow viewport before the single-column breakpoint.

   The height is no longer the mock's height. The draft card's real headline wraps to two lines,
   which pushed the card's bottom edge down into the floating inbox card; .mock-main is now
   content-sized (bottom:auto below) and this floor is the mock's height PLUS the room the float
   needs to hang off the bottom-right corner without touching the headline. Measured at 1440 and
   the headline needs a SECOND line and the floor has to grow again — see the 1160 rule far below,
   which is where that case is handled. At this floor the float clears the one-line headline by
   25.5px at every width from 1215 up. Shrink it and they touch. */
.collage{position:relative; min-height:470px; min-width:min(100%, 420px); perspective:1600px;}
.preview-tag{position:absolute; top:-10px; right:6px; z-index:6; font-size:.66rem; letter-spacing:.09em;
  text-transform:uppercase; font-weight:700; color:var(--text-muted);
  background:color-mix(in srgb, var(--surface-lowest) 82%, transparent); padding:5px 10px; border-radius:var(--radius-pill);
  box-shadow:inset 0 0 0 1px var(--ghost-border);}
.mock{position:absolute; border-radius:var(--radius-lg); overflow:hidden;
  box-shadow:var(--shadow-card), 0 0 40px rgba(126,58,242,.14);}
/* bottom:auto — the mock hugs its own content instead of stretching to the collage. Stretching it
   would turn the extra height the float needs (see .collage above) into a band of empty dashboard
   under the draft card, which reads as a rendering bug rather than as breathing room. */
.mock-main{inset:16px 0 auto 0; left:5%; right:-2%; transform:rotateY(-9deg) rotateX(3deg) rotate(1deg);
  transform-origin:center; background:linear-gradient(180deg, var(--surface-low), var(--surface));
  box-shadow:var(--shadow-card), 0 0 46px rgba(126,58,242,.16), inset 0 0 0 1px var(--ghost-border);}
.mock-chrome{display:flex; align-items:center; gap:6px; padding:11px 14px; border-bottom:1px solid var(--ghost-border);
  background:color-mix(in srgb, var(--surface) 70%, transparent);}
.mock-chrome i{width:9px; height:9px; border-radius:50%; background:var(--surface-bright); display:block;}
.mock-chrome .tt{margin-left:8px; font-size:.72rem; color:var(--text-muted); font-weight:600;}
.mock-body{padding:16px;}
.mock-greet{font-family:var(--font-display); font-weight:700; font-size:1rem; color:var(--text-on-surface); margin-bottom:3px;}
.mock-greet-sub{font-size:.74rem; color:var(--text-muted); margin-bottom:14px;}
.mock-tiles{display:grid; grid-template-columns:repeat(3,1fr); gap:9px; margin-bottom:14px;}
.mtile{border-radius:var(--radius-md); padding:12px;
  background:linear-gradient(180deg, color-mix(in srgb, var(--surface-high) 55%, transparent), color-mix(in srgb, var(--surface-high) 24%, transparent));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), inset 0 0 0 1px var(--ghost-border);}
.mtile .v{font-family:var(--font-display); font-weight:700; font-size:1.35rem; color:var(--text-on-surface); line-height:1; display:flex; align-items:center; gap:5px;}
.mtile .l{font-size:.66rem; color:var(--text-on-variant); margin-top:7px; font-weight:500;}
.mock-agent{display:flex; gap:11px; align-items:flex-start; border-radius:var(--radius-md); padding:12px;
  background:color-mix(in srgb, var(--surface-high) 30%, transparent); box-shadow:inset 0 0 0 1px var(--ghost-border); margin-bottom:9px;}
.mock-av{position:relative; width:36px; height:36px; border-radius:11px; flex:0 0 auto; display:flex; align-items:center;
  justify-content:center; font-size:17px; background:var(--surface-highest); box-shadow:inset 0 0 0 1px var(--ghost-border);}
.mock-av .wd{position:absolute; bottom:-2px; right:-2px; width:10px; height:10px; border-radius:50%;
  background:var(--success); border:2px solid var(--surface-low); box-shadow:0 0 8px var(--success); animation:pulse 1.8s ease-in-out infinite;}
.mock-agent-main{flex:1; min-width:0;}
.mock-agent-row{display:flex; align-items:center; justify-content:space-between; gap:8px;}
.mock-agent-name{font-family:var(--font-display); font-weight:600; font-size:.86rem; color:var(--text-on-surface);}
.mstate{font-size:.6rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase; border-radius:var(--radius-pill);
  padding:3px 8px; color:var(--success); background:var(--success-soft); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--success) 22%, transparent);}
.mock-agent-micro{display:flex; align-items:center; gap:6px; font-size:.72rem; color:var(--text-on-variant); margin-top:6px;}
.mock-draft{border-radius:var(--radius-md); background:color-mix(in srgb, var(--surface-high) 32%, transparent);
  box-shadow:inset 0 0 0 1px var(--ghost-border); padding:12px 13px;}
.mock-draft-head{display:flex; align-items:center; gap:8px; margin-bottom:7px;}
.mchip{display:inline-flex; align-items:center; gap:5px; border-radius:var(--radius-pill); padding:3px 9px 3px 6px;
  font-size:.66rem; font-weight:700; color:var(--text-on-surface);
  background:color-mix(in srgb, var(--surface-highest) 70%, transparent); box-shadow:inset 0 0 0 1px var(--ghost-border);}
.mock-draft-title{font-family:var(--font-display); font-weight:600; font-size:.8rem; color:var(--text-on-surface); margin-bottom:8px;}
.mock-draft-actions{display:flex; gap:6px;}
.mbtn{font-size:.66rem; font-weight:700; font-family:var(--font-display); border-radius:var(--radius-pill); padding:5px 12px;}
.mbtn-p{background:var(--gradient-button); color:var(--on-primary);}
.mbtn-g{background:transparent; color:var(--primary-accent); box-shadow:inset 0 0 0 1px var(--ghost-border);}
.mline{font-size:.72rem; color:var(--text-muted);}
/* Dropped below the card's bottom edge (and pushed further right) because at
   1280–1680 the floating sparkline sat squarely over the draft card's title.
   The overhang is capped at 26px — under the .wrap gutter — so that between 1100
   (where the float is hidden) and ~1215 (where the page stops being wider than the
   1160 content box) the card cannot be clipped by body's overflow-x:hidden. Above
   that width the cap never engages and the offset is the plain -6%.
   The cap is 22px, not 26px, because the .wrap gutter it has to hide inside is 24px: at a
   1101-1160px viewport the content box ends 24px from the edge, so a 26px overhang put the
   card 2-3px past the viewport and body's overflow-x:hidden shaved it. Measured at 1160:
   26px gave scrollWidth 1163 against a 1160 client width; 22px gives 1160. */
.mock-float{position:absolute; z-index:5; right:max(-6%, -22px); bottom:-14px; width:210px; padding:11px;
  background:linear-gradient(180deg, var(--surface-high), var(--surface-low));
  border-radius:var(--radius-md); box-shadow:var(--shadow-card), 0 0 30px rgba(126,58,242,.2), inset 0 0 0 1px var(--ghost-border);
  transform:rotate(-2deg);}
.mock-float .h{display:flex; align-items:center; gap:7px; font-size:.72rem; font-weight:700; color:var(--text-on-surface); margin-bottom:6px;}
/* The float's body: two figures and a one-hue split bar, sized to hold the same box the
   sparkline held (~86px tall at 210px wide) so the card's -14px overhang still clears the
   draft card above it. Two hues here would read as two series; one hue at two strengths
   reads as "this much of that pile is answered", which is what the numbers say. */
.mock-float .mfig{font-family:var(--font-display); font-weight:700; font-size:.8rem; line-height:1.1;
  color:var(--text-on-surface);}
.mock-float .mfig-sub{font-weight:600; font-size:.68rem; line-height:1.25; color:var(--text-on-variant); margin-top:2px;}
.mock-float .mbar{display:flex; gap:3px; height:6px; margin-top:6px;}
.mock-float .mbar i{background:var(--purple-400); border-radius:3px;}
.mock-float .mbar b{background:color-mix(in srgb, var(--purple-400) 34%, transparent); border-radius:3px;}

/* ---- LOGO STRIP ---- */
.logostrip{border-top:1px solid var(--ghost-border); border-bottom:1px solid var(--ghost-border); padding:26px 0;
  background:color-mix(in srgb, var(--surface-section) 40%, transparent);}
.logostrip .wrap{display:flex; align-items:center; justify-content:center; gap:14px 30px; flex-wrap:wrap;}
.logostrip .lbl{font-size:12.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--text-muted); font-weight:600;}
.logostrip .wrap+.wrap{margin-top:13px;}
.logostrip .more{font-size:12.5px; color:var(--text-muted);}
.netpill{display:inline-flex; align-items:center; gap:8px; padding:8px 15px; border-radius:var(--radius-pill);
  background:color-mix(in srgb, var(--surface-high) 42%, transparent); border:1px solid var(--ghost-border);
  color:var(--text-on-variant); font-weight:600; font-size:14px; font-family:var(--font-display);}
.netpill .g{width:20px; height:20px; border-radius:6px; display:grid; place-items:center; font-size:11px; font-weight:800; color:#fff; font-family:var(--font-display);}
/* Qualifier inside a network pill (e.g. what the connection actually reads). */
.netpill small{color:var(--text-muted); font-size:11.5px; margin-left:4px; font-weight:500;}

/* ---- COMPARE TABLE ---- */
.cmp-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch; border-radius:var(--radius-xl);
  border:1px solid var(--ghost-border-strong); box-shadow:var(--shadow-card);}
table.cmp{width:100%; border-collapse:collapse; min-width:680px; background:color-mix(in srgb, var(--surface-card) 70%, transparent);}
/* The label column's floor, DESKTOP ONLY. It used to be an inline style on the <th>, which meant it
   also applied under the phone breakpoint, where the table becomes table-layout:fixed with a 36%
   first column — 127px at 390px wide. A cell min-width under fixed layout is a known browser
   divergence: an engine that honours it puts the crushed data columns straight back. */
@media (min-width:761px){ table.cmp th:first-child{min-width:190px;} }
table.cmp th, table.cmp td{padding:16px 18px; text-align:left; border-bottom:1px solid var(--divider); font-size:14px; vertical-align:middle;}
/* No position:sticky on the head row. .cmp-scroll is overflow-x:auto with no height cap, which makes
   it the sticky containing block AND gives it no vertical scrollport — so the offset never engaged
   and the header scrolled away with the page exactly as an unsticky one would. The opaque background
   stays: it is what separates the head row from the body, and it was never the sticky rule doing that. */
table.cmp thead th{background:color-mix(in srgb, var(--surface-low) 96%, transparent);
  font-family:var(--font-display); color:var(--text-primary); font-size:14px; border-bottom:1px solid var(--ghost-border-strong);}
table.cmp thead th small{display:block; font-family:var(--font-body); font-weight:500; font-size:11.5px; color:var(--text-muted); margin-top:3px; letter-spacing:0;}
table.cmp tbody th{font-family:var(--font-body); font-weight:600; color:var(--text-on-variant); font-size:13.5px;}
.col-sf{background:color-mix(in srgb, var(--purple-600) 12%, transparent); border-left:1px solid var(--ghost-border-strong); border-right:1px solid var(--ghost-border-strong);}
thead .col-sf{background:color-mix(in srgb, var(--purple-600) 20%, transparent);}
.yes{color:var(--success); font-weight:700;}
.no{color:var(--text-muted);}
.cell-strong{color:var(--text-primary); font-weight:700; font-family:var(--font-display);}
.cmp-foot{text-align:center; margin-top:28px;}
/* Footnote under the table (what the columns are, what the figures are not). */
.cmp-note{max-width:720px; margin:14px auto 0; text-align:center; font-size:13px; line-height:1.55; color:var(--text-muted);}

/* ============================================================================
   GRAFT B — salary / agency cost strip folded into pricing (from the "team"
   direction). Compact framing above the plan cards; cards stay the centerpiece.
   ============================================================================ */
.salary-band{margin:0 auto 40px; max-width:960px; border-radius:var(--radius-xl);
  border:1px solid var(--ghost-border-strong); background:color-mix(in srgb, var(--surface-card) 62%, transparent);
  padding:26px 26px 22px; box-shadow:var(--shadow-card);}
.salary-grid{display:grid; gap:14px; grid-template-columns:repeat(3,1fr) auto; align-items:stretch;}
.salary-item{padding:16px 16px; border-radius:var(--radius-md);
  background:color-mix(in srgb, var(--surface-lowest) 55%, transparent); border:1px solid var(--ghost-border);}
.salary-item .role{font-size:.84rem; color:var(--text-muted);}
.salary-item .cost{font-family:var(--font-display); font-weight:700; font-size:1.45rem; color:var(--text-secondary);
  margin-top:6px; text-decoration:line-through; text-decoration-color:color-mix(in srgb, var(--error) 65%, transparent);}
.salary-item .cost small{font-size:.76rem; color:var(--text-muted); text-decoration:none;}
.salary-vs{display:flex; flex-direction:column; justify-content:center; gap:5px; padding:16px 20px; border-radius:var(--radius-md);
  background:var(--gradient-button); color:var(--on-primary); text-align:left;}
.salary-vs .lbl{font-size:.8rem; opacity:.92; font-weight:600;}
.salary-vs .amt{font-family:var(--font-display); font-weight:800; font-size:1.65rem;}
.salary-vs .amt small{font-size:.86rem; font-weight:700; opacity:.92;}
.salary-foot{margin-top:16px; font-size:.82rem; color:var(--text-muted); line-height:1.55;}

/* ---- PRICING ---- */
.price-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:22px; align-items:stretch;}
.price-card{position:relative; background:color-mix(in srgb, var(--surface-card) 78%, transparent);
  border:1px solid var(--ghost-border-strong); border-radius:var(--radius-xl); padding:30px 26px; display:flex; flex-direction:column;
  box-shadow:var(--shadow-card);}
.price-card.pop{border-color:color-mix(in srgb, var(--purple-400) 55%, transparent); box-shadow:var(--shadow-card), 0 0 34px rgba(126,58,242,.22);}
.price-card .plan{font-family:var(--font-display); font-weight:700; color:var(--text-primary); font-size:16px; display:flex; align-items:center; gap:10px;}
.badge-pop2{font-size:10px; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--on-primary); background:var(--gradient-button); padding:4px 9px; border-radius:99px;}
.price-amt{display:flex; align-items:baseline; gap:6px; margin:16px 0 4px;}
.price-amt .n{font-family:var(--font-display); font-weight:800; font-size:2.6rem; color:var(--text-primary); letter-spacing:-0.03em;}
.price-amt .per{color:var(--text-muted); font-size:14px;}
/* The two lines under the price swapped jobs: what the plan BUYS in plain terms
   (".price-equiv" — "about 30 posts a month") is the line a visitor reads, and the
   credit arithmetic behind it is the footnote. The emphasis follows the meaning, so
   the weights moved with it rather than the classes being renamed everywhere.
   Both carry the same small margin so neither has to be last: the gap before the
   feature list is paid for by .price-card ul's own top margin. */
.price-equiv{font-size:13px; color:var(--text-muted); font-weight:500; margin:0 0 4px;} /* markup: the credits count ('500 credits / month') */
.price-credits{font-size:15px; color:var(--text-primary); font-weight:600; line-height:1.5; margin:0 0 18px;} /* markup: the worked month — the line a visitor reads */
.price-card ul{list-style:none; margin:18px 0 22px; padding:0; display:grid; gap:11px;}
.price-card li{display:flex; gap:10px; font-size:13.5px; color:var(--text-secondary); align-items:flex-start;}
.price-card li .c{color:var(--success); flex:0 0 auto; margin-top:1px;}
.price-card .btn{width:100%; margin-top:auto;}
.credit-key{margin-top:28px; display:flex; flex-wrap:wrap; justify-content:center; gap:9px;}
.credit-key .k{display:inline-flex; align-items:center; gap:7px; padding:7px 13px; border-radius:var(--radius-pill);
  background:color-mix(in srgb, var(--surface-high) 42%, transparent); border:1px solid var(--ghost-border); font-size:12.5px; color:var(--text-on-variant);}
.credit-key .k b{color:var(--text-primary); font-family:var(--font-display);}
.price-foot{text-align:center; margin-top:18px; font-size:13px; color:var(--text-muted);}
/* Beta-only line under the pricing heading (renders only while Beta:Enabled). */
/* Scoped to .sec-head on purpose: this note renders INSIDE the section head, where
   `.sec-head p` (0,1,1) outranks a bare `.beta-note` (0,1,0) and was painting the
   footnote at the 1.1rem lead size. The class alone is not enough here. */
.sec-head .beta-note{max-width:640px; margin:14px auto 0; text-align:center; font-size:13px;
  line-height:1.55; color:var(--text-muted);}
/* Trial terms sit directly under the button they qualify — the card's CTA is
   full-width, so centring keeps the line tied to it rather than to the list above. */
.trial-terms{margin:10px 0 0; text-align:center; font-size:13px; line-height:1.45; color:var(--text-muted);}

/* ---- HOW IT WORKS ----
   THREE FULL-WIDTH ROWS, one per step: copy on one side, the screen recording on the other. As
   three cards in a row the clips rendered ~330px wide, which is smaller than the product screen
   they are showing — the reader could see that something was happening and not what. A row gives
   the clip ~636px at 1440 (0.85fr : 1.35fr of the 1072px inside the card, less the 36px gutter).
   The middle row flips the clip to the LEFT with grid `order` — never `direction` or a DOM swap —
   so the reading order stays step-then-recording for a screen reader while the page stops reading
   as a stripe. */
.steps{display:grid; grid-template-columns:1fr; gap:24px;}
/* min-width:0 lets the track shrink to the container on small phones — grid items default to
   min-width:auto, and a wide clip inside a step was forcing the whole track (and page) past the
   viewport. */
.step{min-width:0;}
/* position:relative is load-bearing, not decoration: the lazy-video script injects .clip-toggle
   and .clip-expand into the video's PARENT (this element) and positions them against it. */
.stagepane{min-width:0; overflow:hidden; position:relative;}
.step{background:color-mix(in srgb, var(--surface-card) 66%, transparent); border:1px solid var(--ghost-border);
  border-radius:var(--radius-lg); padding:24px 20px;
  display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.35fr); gap:36px; align-items:center;}
.step-copy{min-width:0;}
/* The flip is TWO changes, not one. `order` alone moves the clip into the first grid track — which
   is the NARROW one — so the middle row's recording rendered at 398px, smaller than the cards this
   whole change was undoing. The track sizes mirror with it, so the wide track always holds the
   clip whichever side it is on. */
.step:nth-child(even){grid-template-columns:minmax(0,1.35fr) minmax(0,.85fr);}
.step:nth-child(even) .step-copy{order:2;}
.step:nth-child(even) .stagepane{order:1;}
.step-n{width:34px; height:34px; border-radius:10px; background:var(--primary-soft); color:var(--purple-200);
  font-family:var(--font-display); font-weight:800; display:grid; place-items:center; font-size:16px; margin-bottom:16px;
  border:1px solid var(--ghost-border-strong);}
.step h3{font-size:1.3rem; margin-bottom:8px;}
/* No trailing margin: step 1's form supplies its own clear space below the paragraph, and steps
   2 and 3 end on the paragraph. */
.step p{font-size:14.5px; margin:0;}
/* The form must never crowd the clip beside it. 18px above, and the 36px column gutter (or the
   20px row gap once stacked) below/beside it. */
.step .audit-form-compact{margin:18px 0 0;}

/* step clip frame */
.stagepane{border:1px solid var(--ghost-border-strong); border-radius:var(--radius-md);
  background:color-mix(in srgb, var(--surface-lowest) 55%, transparent); padding:14px; min-height:150px;
  display:flex; flex-direction:column; gap:10px; box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--ghost-border) 60%, transparent);}
.stagepane .pane-head{display:flex; align-items:center; justify-content:space-between; gap:8px;}
.stagepane .pane-title{font-family:var(--font-display); font-weight:700; font-size:.8rem; color:var(--text-on-surface);}
.stagepane .pane-tag{font-size:.6rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--purple-200);
  background:var(--primary-soft); border:1px solid var(--ghost-border); padding:3px 8px; border-radius:var(--radius-pill);}
/* mini audit score (step 1) */
.mini-audit{display:flex; align-items:center; gap:16px;}
.mini-ring{position:relative; width:74px; height:74px; flex:0 0 auto;}
.mini-ring svg{transform:rotate(-90deg);}
.mini-ring .rt{stroke:color-mix(in srgb, var(--surface-high) 90%, transparent);}
.mini-ring .rf{stroke:url(#miniRingGrad); stroke-linecap:round;}
.mini-ring .ctr{position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;}
.mini-ring .num{font-family:var(--font-display); font-weight:800; font-size:1.35rem; color:var(--text-primary); line-height:1;}
.mini-ring .lab{font-size:.52rem; color:var(--text-muted); text-transform:uppercase; letter-spacing:.05em; margin-top:2px;}
.mini-bars{flex:1; min-width:0; display:grid; gap:8px;}
.mini-bar-row{display:grid; gap:4px;}
.mini-bar-row .t{display:flex; justify-content:space-between; font-size:.66rem; color:var(--text-on-variant);}
.mini-bar-row .t b{color:var(--text-primary); font-family:var(--font-display); font-weight:700;}
.bar{height:6px; border-radius:99px; background:color-mix(in srgb, var(--surface-high) 80%, transparent); overflow:hidden;}
.bar>span{display:block; height:100%; border-radius:99px;}
/* review-queue rows (step 2) */
.qrow{border-radius:var(--radius-sm); background:color-mix(in srgb, var(--surface-high) 30%, transparent);
  box-shadow:inset 0 0 0 1px var(--ghost-border); padding:10px 11px;}
.qrow .qhead{display:flex; align-items:center; gap:7px; margin-bottom:6px; flex-wrap:wrap;}
.qrow .qch{font-size:.66rem; color:var(--text-on-variant); font-weight:600;}
.qrow .qage{font-size:.62rem; color:var(--text-muted); margin-left:auto;}
.qrow .qtitle{font-family:var(--font-display); font-weight:600; font-size:.76rem; color:var(--text-on-surface);}
/* calendar mock (step 3) */
.cal{display:grid; gap:7px;}
.cal-row{display:flex; align-items:center; gap:9px; padding:7px 10px; border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--surface-high) 26%, transparent); box-shadow:inset 0 0 0 1px var(--ghost-border);}
.cal-row .day{font-size:.6rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--text-muted); width:26px; flex:0 0 auto;}
.cal-row .plat{width:20px; height:20px; border-radius:6px; flex:0 0 auto; display:grid; place-items:center; font-size:10px; font-weight:800; color:#fff; font-family:var(--font-display);}
.cal-row .txt{flex:1; min-width:0; font-size:.72rem; color:var(--text-on-variant); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.cal-row .st{font-size:.56rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase; padding:2px 7px; border-radius:var(--radius-pill); flex:0 0 auto;}
.st-pub{color:var(--success); background:var(--success-soft); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--success) 22%, transparent);}
.st-sch{color:var(--purple-200); background:var(--primary-soft); box-shadow:inset 0 0 0 1px var(--ghost-border);}

/* ---- AGENTS ---- */
.agents{display:grid; grid-template-columns:repeat(3,1fr); gap:22px;}
.agent{background:color-mix(in srgb, var(--surface-card) 74%, transparent); border:1px solid var(--ghost-border-strong);
  border-radius:var(--radius-xl); padding:28px; box-shadow:var(--shadow-card); transition:transform .2s ease, box-shadow .2s ease;}
.agent:hover{transform:translateY(-3px); box-shadow:var(--shadow-card-hover);}
.agent-ico{width:46px; height:46px; border-radius:13px; display:grid; place-items:center; font-size:22px; margin-bottom:16px;
  background:color-mix(in srgb, var(--purple-600) 20%, transparent); border:1px solid var(--ghost-border-strong);}
/* Inline SVG replaces the emoji glyph inside the tile; the tile itself is unchanged,
   and the icon is sized here rather than on each <svg> so one number moves them all. */
.agent-ico svg{width:22px; height:22px; display:block;}
.agent h3{font-size:1.3rem; display:flex; align-items:baseline; gap:10px; margin-bottom:6px; flex-wrap:wrap;}
.agent h3 .role{font-family:var(--font-body); font-weight:500; font-size:12.5px; color:var(--purple-200); text-transform:uppercase; letter-spacing:.05em;}
.agent>p{font-size:14px; margin:0 0 16px;}
.agent ul{list-style:none; margin:0; padding:0; display:grid; gap:9px;}
.agent li{display:flex; gap:9px; font-size:13.5px; color:var(--text-secondary);}
.agent li .c{color:var(--purple-300); flex:0 0 auto;}

/* ---- FEATURE CLUSTERS ---- */
/* Three columns, not two: the 'Publishing & SEO' card was merged into 'The content engine',
   which left three cards in a two-column grid and an orphan alone on the second row. Three
   across matches the agents grid directly above it. */
.features{display:grid; grid-template-columns:repeat(3,1fr); gap:22px;}
.fcard{background:color-mix(in srgb, var(--surface-card) 64%, transparent); border:1px solid var(--ghost-border);
  border-radius:var(--radius-lg); padding:26px;}
.fcard h3{font-size:1.15rem; margin-bottom:6px; display:flex; align-items:center; gap:10px;}
.fcard h3 .fic{width:30px; height:30px; border-radius:9px; display:grid; place-items:center; font-size:15px;
  background:var(--primary-soft); border:1px solid var(--ghost-border); flex:0 0 auto; color:var(--purple-200);}
.fic svg{width:18px; height:18px; display:block;}
.fcard>p{font-size:13.5px; margin:0 0 16px; color:var(--text-muted);}
.fcard ul{list-style:none; margin:0; padding:0; display:grid; gap:10px;}
.fcard li{display:flex; gap:9px; font-size:13.5px; color:var(--text-secondary); align-items:flex-start;}
.fcard li .c{color:var(--success); flex:0 0 auto; margin-top:1px;}

/* ---- MONTHLY REPORT BAND ---- */
.report-band{background:
    radial-gradient(60% 120% at 100% 0%, color-mix(in srgb, var(--purple-600) 24%, transparent), transparent 55%),
    color-mix(in srgb, var(--surface-low) 80%, transparent);
  border:1px solid var(--ghost-border-strong); border-radius:var(--radius-xl); padding:44px; overflow:hidden;
  display:grid; grid-template-columns:1.1fr .9fr; gap:40px; align-items:center; box-shadow:var(--shadow-card);}
/* Explicit line-height: these two headings wrap to two or three lines at their
   clamped top size, where the inherited body 1.6 opens a visible gap between them. */
.report-band h2{font-size:clamp(1.6rem,3vw,2.2rem); line-height:1.12; margin-bottom:14px;}
.report-band p{font-size:1.02rem; margin:0 0 20px;}
/* The merged proof band ends in two buttons rather than one link, so they need a
   row that wraps instead of two inline-flex buttons separated by a space. */
.band-actions{display:flex; flex-wrap:wrap; align-items:center; gap:12px;}
/* STACKED variant: the copy reads as the band's header and the two clips sit side by side under
   it. One column of band-width rows, so the clips get half the band each (~502px at 1440) instead
   of two thumbnails queued in a 0.9fr track. */
.report-band-stacked{grid-template-columns:1fr; gap:26px; align-items:start;}
.report-copy{min-width:0;}
/* A header, not a centred masthead: the prose keeps a measure it can be read at while the clips
   below use the full band. */
.report-copy h2, .report-copy>p{max-width:720px;}
.report-kpis{display:grid; grid-template-columns:1fr 1fr; gap:12px;}
.kpi{background:color-mix(in srgb, var(--surface-card) 80%, transparent); border:1px solid var(--ghost-border);
  border-radius:var(--radius-md); padding:16px;}
.kpi .kn{font-family:var(--font-display); font-weight:800; font-size:1.5rem; color:var(--text-primary);}
.kpi .kl{font-size:12px; color:var(--text-muted); margin-top:2px;}
.kpi .badge-tier{display:inline-block; font-size:9.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  padding:2px 7px; border-radius:99px; margin-top:8px;}
.tier-real{background:var(--success-soft); color:var(--success);}
.tier-est{background:var(--warning-soft); color:var(--warning);}

/* ---- EXAMPLE POSTS STRIP ----
   Real, unedited output shown as artefacts: the image at full card width, the
   caption underneath, and a label saying whose brand it was written for.
   The caption is FOLDED, not truncated (see the .cap-clamp block below): a cut example proves
   nothing, so nothing is cut — a line clamp with a button under it that restores every character. */
/* auto-fit + a hard track cap, not repeat(3,1fr): only two cards are real today, and a
   fixed three-column grid left a dead column on the right. Capping the track at 373px
   (the width a third of the content box gives) and centring means two cards sit centred
   at exactly the size three cards would have been, and a third or fourth card fills in
   without any rule changing. */
/* stretch, not start: the three artefact cards are folded to within 24px of each other (see
   .cap-clamp), and stretch closes that last gap so the row reads as one set of equal cards rather
   than three ragged ones. It costs nothing inside a card — .example-card is a flex COLUMN whose
   children all refuse to grow, so the media and the caption stay pinned under the card's top edge
   and any surplus height is dead space at the bottom, never padding injected between them. */
.examples-grid{display:grid; grid-template-columns:repeat(3,1fr);
  justify-content:center; gap:18px; align-items:stretch;}
.example-card{min-width:0; display:flex; flex-direction:column; gap:12px;
  background:color-mix(in srgb, var(--surface-card) 64%, transparent); border:1px solid var(--ghost-border);
  border-radius:var(--radius-lg); padding:16px;}
/* Load-bearing with align-items:stretch above: flex:0 0 auto on every child is what keeps a card
   that was handed extra height from stretching its picture or floating its caption down the box. */
.example-card>*{flex:0 0 auto;}
.example-media{border-radius:10px; overflow:hidden; background:var(--surface-lowest);}
.example-media img{width:100%; height:auto; display:block; border-radius:10px;}
.example-body{display:grid; gap:9px; min-width:0; align-content:start;}

/* ---- THE CAPTION FOLD ----
   MEASURED at 1440 before this existed: the single-image post stood 711px, the carousel 921px and
   the Reel 703px. The 210px gap was the carousel's caption — five paragraphs, 19 lines of a real
   post — and it is not ours to shorten. So it is folded instead: a line clamp, and a button that
   puts every character back. Nothing but caption body text is ever inside the fold.
   .is-collapsed and .has-toggle are both added by the script in _LandingExamples.cshtml and only
   after it has measured a genuine overflow, so a no-JS visitor reads the caption in full and never
   meets a button that does nothing. Same promise as .example-carousel.is-ready above. */
.cap-clamp{min-width:0;}
/* -webkit-box is still the only line clamp with universal support. white-space:pre-line survives
   it, so the paragraph breaks inside the fold are the post's own and not a re-wrap. */
.cap-clamp.is-collapsed .example-cap{display:-webkit-box; -webkit-line-clamp:var(--cap-lines,10);
  -webkit-box-orient:vertical; overflow:hidden;}
/* Two line counts, one row height. The carousel card carries a 62px thumbnail strip and its 10px
   gap that the post beside it does not, so it pays that back out of its own caption. MEASURED at
   1440 collapsed, with the grid's stretch turned off so the cards' own heights show: post 674,
   carousel 651, Reel 663 — a 23px spread, down from 218px.
   A single N cannot do this: both cards would move together and the gap would never close.

   THE NUMBERS ARE NOT FREE TO NUDGE. white-space:pre-line renders each paragraph break as a real
   empty line, and an empty line counts toward the clamp — so a clamp that lands ON one hangs the
   ellipsis alone on a blank line, which reads as if the post itself contained a line of "…".
   MEASURED blank-line positions (1440/1280 · 960 · 430 · 390 · 320):
     post caption      lines 3,8 · 2,6 · 3,7 · 3,8 · 3,9      → 10 is clear at every width (4 and 5 too)
     carousel caption  3,8,12,16 · 3,7,11,14 · 3,7,11,14 · 3,8,13,17 · 4,10,15,19  → 6 is clear (5 and 9 too)
   8 was the first choice for the post and it lands exactly on the blank line at 1440 and at 390.
   Re-measure this list before changing either number, or before either caption is replaced.

   RE-MEASURED 2026-09-10, after the collapsed "Why Staffiva made this" row was added to both post
   cards (1440, stretch off): post 707.3, carousel 708.8, Reel 662.9. The two posts still land
   within 1.5px of each other — which is all these two line counts were ever tuned to do, and they
   were not touched. The Reel's drift is a separate knob; see .reel-frame below. */
.example-carousel .cap-clamp{--cap-lines:6;}
/* The page's small ghost pill: .mbtn-g's transparent fill and inset hairline at .netpill's radius.
   Hidden until .has-toggle, so it cannot be tabbed to before it works. */
.cap-toggle{display:none; margin-top:8px; padding:6px 12px; border:0; cursor:pointer;
  font-family:var(--font-display); font-weight:700; font-size:12.5px; line-height:1;
  color:var(--primary-accent); background:transparent; border-radius:var(--radius-pill);
  box-shadow:inset 0 0 0 1px var(--ghost-border);
  transition:box-shadow .15s ease, color .15s ease;}
.cap-clamp.has-toggle .cap-toggle{display:inline-block;}
.cap-toggle:hover{color:var(--text-primary); box-shadow:inset 0 0 0 1px var(--ghost-border-strong);}
/* Muted by default so the "Real post" label inherits it; the chip repaints itself. */
.example-meta{display:flex; align-items:center; flex-wrap:wrap; gap:8px; font-size:12.5px; color:var(--text-muted);}
/* The platform chip reuses the logo strip's .netpill, which is sized for a 14px row.
   Inside a 12.5px meta line it has to come down or it outweighs the 'Real post' label
   standing next to it. */
.example-meta .netpill{padding:4px 10px; font-size:12px; gap:6px;}
.example-meta .netpill .g{width:16px; height:16px; border-radius:5px; font-size:9px;}
/* A quieter second fact on the meta line — what on the picture is Staffiva's own work rather than
   the image generator's. It sits BEHIND the honesty label in weight: "Real post · carousel" is the
   claim the strip is making, this is a footnote to it.
   OWN ROW, deliberately (flex-basis:100%), and not a "· tag" appended to the label: the chip plus
   the label already fill a card-width meta line at every breakpoint, so an inline tag wrapped
   anyway — and it wrapped with its separator, leaving a lone "·" opening the second line. Given it
   is always going to be a second line, it should look like one. */
.example-meta .meta-tag{flex:0 0 100%; margin-top:-2px; font-size:11.5px; opacity:.72;}
.example-cap{font-size:15px; line-height:1.55; color:var(--text-primary); white-space:pre-line; margin:0;}

/* ---- "WHY STAFFIVA MADE THIS" ----
   The plan each post came out of, on the two cards where we actually have one — the planner's own
   Pillar / audience / angle, verbatim (the contract at the top of _LandingExamples.cshtml says
   which columns, and that they may never be paraphrased). The Reel card has no such row and gets
   no such line.
   <details>, not a scripted panel: it opens with scripting off, and it ships CLOSED so the strip
   still argues with the post itself and the row's collapsed height barely moves — one pill.
   The summary wears .cap-toggle's clothes on purpose: it stands directly under that button, and a
   second control there drawn any other way would read as a different KIND of thing. The chevron is
   all that is added, and only so the pill says which way it goes. */
.example-why{font-size:12.5px; color:var(--text-muted);}
/* Both marker kills are needed, not one: display:inline-flex/list-style:none is what Chromium and
   Firefox honour, ::-webkit-details-marker is what Safari honours. */
.example-why>summary{list-style:none; display:inline-flex; align-items:center; gap:7px;
  padding:6px 12px; cursor:pointer;
  font-family:var(--font-display); font-weight:700; font-size:12.5px; line-height:1;
  color:var(--primary-accent); background:transparent; border-radius:var(--radius-pill);
  box-shadow:inset 0 0 0 1px var(--ghost-border);
  transition:box-shadow .15s ease, color .15s ease;}
.example-why>summary::-webkit-details-marker{display:none;}
.example-why>summary:hover{color:var(--text-primary); box-shadow:inset 0 0 0 1px var(--ghost-border-strong);}
/* summary is natively focusable, so the page's global :focus-visible ring (top of this file) lands
   on it with nothing added here. The offset is widened by 1px only so the ring clears the pill's
   own hairline instead of sitting on it. Never set outline:none on this. */
.example-why>summary:focus-visible{outline-offset:3px;}
/* Chevron as a rotated corner — two borders at 45deg, no glyph and no SVG to load. Right when
   closed, down when open; a reduced-motion visitor simply sees it arrive rotated. */
.example-why>summary::before{content:""; flex:0 0 auto; width:5px; height:5px;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform:rotate(-45deg); transform-origin:60% 60%; transition:transform .15s ease;}
.example-why[open]>summary::before{transform:rotate(45deg);}
.example-why dl{margin:10px 0 0; display:grid; gap:6px;}
/* A grid per ROW, not one six-cell grid over the whole list: the label column is a fixed 56px at
   every width, and a long value wraps under its own label rather than dragging the next label
   down with it. minmax(0,1fr) is what lets it wrap at all inside a 325px card. */
.example-why dl>div{display:grid; grid-template-columns:56px minmax(0,1fr); gap:10px; align-items:baseline;}
.example-why dt{margin:0; font-family:var(--font-display); font-weight:700; font-size:10.5px;
  letter-spacing:var(--tracking-label); text-transform:uppercase; color:var(--text-muted); line-height:1.5;}
.example-why dd{margin:0; font-size:13px; line-height:1.5; color:var(--text-secondary);}
/* Smaller and muted, like .example-note under the lead card: it is a provenance line about the
   three values above it, not a fourth value. */
.example-why-note{margin:9px 0 0; font-size:11.5px; line-height:1.45; color:var(--text-muted);}

.example-foot{margin:18px auto 0; max-width:720px; text-align:center; font-size:13px; line-height:1.55; color:var(--text-muted);}

/* ---- THE CAROUSEL CARD ----
   A carousel is four slides that only mean something in order, so the card has to show that it is
   four and let a reader walk them. The stage keeps the neighbours' .example-media treatment exactly
   — same radius, same fill — and everything added sits OVER it or under it, so the three cards
   still read as one set.
   The furniture (count badge, arrows, the carousel glyph) borrows the product clips' vocabulary
   (.clip-tag / .clip-expand): dark translucent pill, hairline white ring, blur. Nothing new is
   invented for a card that has to look like it belongs. */
.example-carousel{gap:10px;}
/* Load-bearing: the badge, the glyph and the two arrows are positioned against this box, not
   against .example-media, so the ring on the image is never cut by an overlay. */
.carousel-stage{position:relative;}
.carousel-count{position:absolute; right:9px; top:9px; z-index:2; pointer-events:none;
  font-family:var(--font-display); font-size:11px; font-weight:700; letter-spacing:.03em; line-height:1;
  color:#fff; padding:5px 9px; border-radius:var(--radius-pill); background:rgba(10,10,16,.62);
  border:1px solid color-mix(in srgb, #fff 22%, transparent);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);}
.carousel-glyph{position:absolute; left:9px; top:9px; z-index:2; pointer-events:none;
  width:26px; height:26px; display:grid; place-items:center; border-radius:8px; color:#fff;
  background:rgba(10,10,16,.52); border:1px solid color-mix(in srgb, #fff 18%, transparent);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);}
.carousel-glyph svg{width:15px; height:15px; display:block;}
/* The arrows are the one control that cannot work without scripting, so they do not exist until
   the script has wired them (it adds .is-ready). The thumbnails below stay visible either way. */
.carousel-btn{display:none;}
.example-carousel.is-ready .carousel-btn{position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:30px; height:30px; border-radius:50%; padding:0; display:grid; place-items:center; cursor:pointer;
  color:#fff; background:rgba(10,10,16,.62); border:1px solid color-mix(in srgb, #fff 22%, transparent);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); opacity:.72; transition:opacity .15s ease;}
.carousel-btn:hover, .carousel-btn:focus-visible{opacity:1;}
.carousel-btn svg{width:14px; height:14px; display:block;}
.carousel-prev{left:9px;}
.carousel-next{right:9px;}
/* No margin-top: the card is a flex column with a 10px gap, which already supplies the spacing.
   Setting both stacked them to 20px and the thumbs floated away from the slide they belong to. */
.carousel-thumbs{display:flex; gap:8px;}
/* Capped at 62px, not a quarter of the row. Four thumbs filling the 325px stage would be ~74px
   each and buy no legibility — at this size a thumbnail is recognised by its picture, not read.
   MEASURED at 1440: the card is 921px against 711 for the single-image post beside it. 72 of that
   210 is this row; the other ~140 is the caption, which is five paragraphs of a real post and is
   not ours to shorten. Trimming the row further only buys back single-digit pixels, so 62 is
   where it stops.
   flex:1 with a max-width, not a fixed width: on a 320px phone four fixed 62px thumbs plus their
   gaps are wider than the card's content box and would have pushed out of it. aspect-ratio keeps
   every thumb square as it shrinks, so a slide is never cropped to fit our furniture. */
.carousel-thumb{flex:1 1 0; min-width:0; max-width:62px; aspect-ratio:1 / 1;
  padding:0; border:0; background:none;
  line-height:0; border-radius:8px; cursor:pointer; opacity:.66;
  box-shadow:inset 0 0 0 1px var(--ghost-border);
  transition:opacity .15s ease, box-shadow .15s ease;}
.carousel-thumb:hover{opacity:1;}
.carousel-thumb img{width:100%; height:100%; object-fit:cover; border-radius:8px; display:block;}
/* The selected thumb is the only place --primary appears on this card: it marks which slide the
   stage is showing, and nothing else. */
.carousel-thumb[aria-pressed="true"]{opacity:1; box-shadow:0 0 0 2px var(--primary);}

/* ---- THE REEL CARD ----
   The third artefact is a vertical video, so it is shown in the shape it was made in: a 9:16 frame
   at the card's own width, wearing .example-media's radius so the three cards still read as one set.
   position:relative here is load-bearing exactly as it is on .report-video-frame — the lazy-video
   script injects .clip-toggle (bottom-right) and .clip-expand (top-right) into the video's PARENT
   and pins them to its corners, so the FRAME has to be that parent or the pause button lands on the
   note underneath. Both corners are clear of the burned-in captions, which sit across the middle of
   the frame, and the REEL pill takes the one corner the script never uses. */
.example-reel{gap:12px;}
/* The cap now bites at desktop too, and that is its job. Uncapped, the frame takes the track's full
   325px and is 577px tall — a 703px card the two folded posts beside it (674 and 651) cannot reach
   without unfolding more caption than their clamps can honestly give (see the blank-line note on
   .cap-clamp: the line counts are not free to nudge). 302px is the width whose 9:16 height (537px)
   lands the Reel card at 663, between them; the frame stays portrait because aspect-ratio,
   not a height, is what shapes it, and margin-inline:auto centres the narrower frame in the track
   rather than letting it sit off to one side.
   The 960 block re-opens this to 360px: there the track is ~420px wide, the Reel shares a row with
   the lead card instead of the two posts, and 290 would shrink it for no reason.

   STALE AS OF 2026-09-10, and knowingly left alone. The why-line added 33.5px to each post card, so
   302px no longer lands the Reel "between them": at 1440 with stretch off the row is now
   707.3 / 708.8 / 662.9, a 45.8px spread against 12.3px before. MEASURED alternatives, same run:
   cap 310px → 677.1 (spread 31.6), 318px → 691.4 (17.4), uncapped/325px → 703.2 (5.6). Raising the
   cap is the one-line fix and it restores exactly the property this comment claims — but it also
   makes the Reel visibly bigger, which is a design call for the owner, not a side effect of adding
   a why-line. Until that call is made the row is level anyway: .examples-grid is align-items:stretch,
   so all three cards RENDER at 708.8 and the surplus is dead space under the Reel's note, as it
   already was at 12.3px. Do not read 663 above as current. */
.reel-frame{position:relative; aspect-ratio:9 / 16; width:100%; max-width:none; margin-inline:auto;
  border-radius:10px; overflow:hidden; background:#000;} /* 2026-09-10: cap lifted — with the why-row on the post cards (707px) the uncapped 9:16 frame lands the Reel card within ~6px of them */
/* Absolute + object-fit, not width:100%/height:auto: the frame owns the box (so the card's height
   is known before a single video byte arrives and nothing reflows when it does) and the clip fills
   it. The clip is 540×960, exactly the frame's ratio, so cover crops nothing. */
.reel-frame video{position:absolute; inset:0; width:100%; height:100%; display:block; object-fit:cover;}
/* Same invitation the product clips give: click to enlarge. */
.reel-frame video:not([controls]){cursor:zoom-in;}
.reel-tag{position:absolute; left:9px; top:9px; z-index:2; pointer-events:none;
  font-family:var(--font-display); font-size:11px; font-weight:700; letter-spacing:.05em; line-height:1;
  color:#fff; padding:5px 9px; border-radius:var(--radius-pill); background:rgba(10,10,16,.62);
  border:1px solid color-mix(in srgb, #fff 22%, transparent);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);}
/* This slot holds the artefact's OWN caption on the two cards beside it. On the Reel card it holds
   our sentence about the Reel, because we do not have that Reel's caption — so it is muted and a
   notch down from .example-cap's 15px. A note that looks exactly like a real caption would be the
   one dishonest pixel on the strip. */
.reel-note{font-size:13.5px; color:var(--text-muted);}

/* ---- THE LEAD CARD, AS AN INBOX CARD ----
   The two posts on this strip are artefacts you can recognise on sight — a picture and a caption.
   The lead was neither: it was a stack of four grey meta rows and three identical paragraphs, and
   a reader had to parse the labels to work out which paragraph was the stranger and which was
   Staffiva. Drawn the way the product draws it — avatar, who, fit score, the quote as a bubble,
   Scout's draft in its own accented panel — the roles are legible before a word is read.
   Type is a notch under .example-cap (14px, not 15px) so the card does not shout over the three
   artefact cards above it. .examples-grid stretches its cards, but this one opts out with
   align-self:start: at desktop it is alone on its row so nothing changes, and at the two-column
   breakpoint it shares a row with the much taller Reel — stretching would give it 280px of empty
   card below the permission line.

   It takes a row of its own, full width, under the three artefacts — a lead is a different KIND of
   thing from a post and stacking it as a fourth 1/3-width card said otherwise. Inside, two columns:
   the stranger's words on the left, Staffiva's drafted reply on the right. That is the honesty
   label made structural — whose words are whose is legible before either label is read.
   1.1fr/1fr, not 1fr/1fr: the left column carries the head furniture (avatar, source, tag, score)
   above its quote and needs the extra ~30px to keep that row off a second line. */
.example-lead{grid-column:1 / -1; display:grid; grid-template-columns:1.1fr 1fr; gap:22px;
  align-items:start; align-self:start;}
.lead-main, .lead-side{min-width:0; display:grid; gap:10px; align-content:start;}
.lead-side{gap:8px;}
/* The grid gap already spaces the note off the reply panel; the element's own top margin would
   stack on top of it. */
.lead-side .example-note{margin:0;}
.lead-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap;}
.lead-av{width:32px; height:32px; flex:0 0 auto; border-radius:50%; display:grid; place-items:center;
  font-family:var(--font-display); font-weight:800; font-size:15px; line-height:1; color:#fff;
  background:var(--surface-highest); box-shadow:inset 0 0 0 1px var(--ghost-border);}
/* The source's own mark, applied only when the configured source really is Reddit (see the view). */
.lead-av-reddit{background:#ff4500; box-shadow:none;}
.lead-who{flex:1 1 120px; min-width:0; display:grid; gap:1px;}
.lead-src{font-family:var(--font-display); font-weight:700; font-size:13.5px; color:var(--text-primary);}
.lead-sub{font-size:11.5px; line-height:1.35; color:var(--text-muted);}
.lead-tag{flex:0 0 auto; font-size:9.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase;
  padding:3px 8px; border-radius:var(--radius-pill); color:var(--purple-200);
  background:var(--primary-soft); border:1px solid var(--ghost-border-strong);}
.lead-score{flex:0 0 auto; margin-left:auto; text-align:right;}
.lead-score-n{display:flex; align-items:center; justify-content:flex-end; gap:5px; line-height:1;
  font-family:var(--font-display); font-weight:800; font-size:20px; color:var(--text-primary);}
.lead-dot{width:7px; height:7px; border-radius:50%; flex:0 0 auto;
  background:var(--success); box-shadow:0 0 8px var(--success);}
.lead-score-l{display:block; margin-top:3px; font-size:9.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--text-muted);}
/* The bubble IS the quotation — no typed quote marks, so the verbatim excerpt keeps exactly the
   characters the author wrote (it opens on an ellipsis because the capture began mid-sentence). */
.lead-quote{margin:0; padding:10px 12px; border-radius:0 10px 10px 0;
  border-left:3px solid var(--outline-variant);
  background:color-mix(in srgb, var(--surface-lowest) 72%, transparent);
  font-size:14px; line-height:1.5; color:var(--text-secondary);}
.lead-why{margin:0; font-size:12.5px; line-height:1.5; color:var(--text-muted);}
/* Purple accent = ours. The stranger's words are the neutral bubble above; this panel is the only
   thing on the card Staffiva wrote, and the colour says so before the label does. */
.lead-reply{padding:10px 12px; border-radius:0 10px 10px 0; border-left:3px solid var(--purple-500);
  background:var(--primary-soft);}
.lead-reply-h{display:flex; align-items:center; gap:6px; margin-bottom:6px; flex-wrap:wrap;}
.lead-spark{flex:0 0 auto; color:var(--purple-300);}
.lead-spark svg{width:14px; height:14px; display:block;}
.lead-reply-t{font-family:var(--font-display); font-weight:700; font-size:12.5px; color:var(--text-primary);}
.lead-reply-by{font-size:11px; color:var(--text-muted);}
.lead-reply-body{margin:0; font-size:14px; line-height:1.5; color:var(--text-secondary);}

/* ---- ASK STAFFIVA BAND ----
   Same two-column band shape as the monthly report, with a chat transcript in the
   right column instead of KPI tiles. */
.ask-band{background:
    radial-gradient(60% 120% at 100% 0%, color-mix(in srgb, var(--purple-600) 24%, transparent), transparent 55%),
    color-mix(in srgb, var(--surface-low) 80%, transparent);
  border:1px solid var(--ghost-border-strong); border-radius:var(--radius-xl); padding:44px; overflow:hidden;
  display:grid; grid-template-columns:.85fr 1.15fr; gap:40px; align-items:center; box-shadow:var(--shadow-card);}
.ask-band h2{font-size:clamp(1.6rem,3vw,2.2rem); line-height:1.12; margin-bottom:14px;}
.ask-copy{min-width:0;}
.ask-copy>p{font-size:1.02rem; margin:0 0 20px;}
.ask-copy ul{list-style:none; margin:0; padding:0; display:grid; gap:9px;}
.ask-copy li{display:flex; gap:9px; font-size:13.5px; color:var(--text-secondary);}
.ask-copy li .c{color:var(--purple-300); flex:0 0 auto;}
.ask-chat{min-width:0;}
/* The transcript is two real exchanges plus an evidence card, and it sets the band's height on its
   own — so the vertical rhythm here is deliberately tight: 8px between turns, 12px of card padding,
   and a 13.5px body that matches the feature lists elsewhere on the page rather than the 14px it
   used. Nothing was dropped to buy the space; the trimming was done by whole sentence in the view. */
.chat{display:grid; gap:8px; padding:12px; border-radius:var(--radius-lg);
  background:color-mix(in srgb, var(--surface-lowest) 78%, transparent); border:1px solid var(--ghost-border);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);}
.chat-q{justify-self:end; max-width:88%; padding:9px 12px; border-radius:14px 14px 4px 14px;
  background:var(--primary-soft); border:1px solid var(--ghost-border-strong);
  color:var(--text-primary); font-size:13.5px; line-height:1.5;}
.chat-a{justify-self:start; max-width:94%; padding:10px 12px; border-radius:14px 14px 14px 4px;
  background:color-mix(in srgb, var(--surface-high) 42%, transparent); border:1px solid var(--ghost-border);
  color:var(--text-secondary); font-size:13.5px; line-height:1.5;}
.chat-a b{color:var(--text-primary); font-weight:600;}
.chat-note{margin:6px 0 0; font-size:12px; color:var(--text-muted);}
/* Footnote, not body copy: without this it inherits .ask-copy>p and shouts the price. */
/* Same trap as .beta-note: `.ask-copy>p` (0,1,1) beats a bare `.ask-note`, so the credit
   footnote was shouting at 1.02rem next to the copy it annotates. */
.ask-copy>p.ask-note{font-size:12.5px; line-height:1.55; color:var(--text-muted); margin:14px 0 0;}

/* ---- FOUNDER ---- */
.founder{display:flex; align-items:center; gap:22px; max-width:760px; margin:0 auto; padding:26px;
  background:color-mix(in srgb, var(--surface-card) 64%, transparent); border:1px solid var(--ghost-border);
  border-radius:var(--radius-lg);}
.founder-photo{flex:0 0 auto; width:96px; height:96px; border-radius:50%; overflow:hidden;
  background:var(--surface-high); box-shadow:inset 0 0 0 1px var(--ghost-border);}
.founder-photo img{width:96px; height:96px; display:block; border-radius:50%; object-fit:cover;}
.founder-body{min-width:0;}
.founder-body h3{font-size:1.15rem; margin-bottom:8px;}
.founder-body p{font-size:14px; line-height:1.62; color:var(--text-secondary); margin:0 0 12px;}
.founder-link{font-size:14px; font-weight:600;}

/* ---- FAQ ---- */
.faq{max-width:820px; margin:0 auto; display:grid; gap:12px;}
.qa{background:color-mix(in srgb, var(--surface-card) 64%, transparent); border:1px solid var(--ghost-border);
  border-radius:var(--radius-md); overflow:hidden;}
.qa summary{cursor:pointer; list-style:none; padding:20px 24px; font-family:var(--font-display); font-weight:600;
  color:var(--text-primary); font-size:15.5px; display:flex; justify-content:space-between; align-items:center; gap:16px;}
.qa summary::-webkit-details-marker{display:none;}
.qa summary .ic{flex:0 0 auto; width:22px; height:22px; border-radius:6px; display:grid; place-items:center;
  background:var(--primary-soft); color:var(--purple-200); font-size:15px; transition:transform .2s ease;}
.qa[open] summary .ic{transform:rotate(45deg);}
.qa .a{padding:0 24px 22px; font-size:14.5px; color:var(--text-secondary); line-height:1.62;}

/* ---- FINAL CTA ---- */
.finalcta{text-align:center; background:
    radial-gradient(50% 130% at 50% 0%, color-mix(in srgb, var(--purple-600) 26%, transparent), transparent 60%);
  border:1px solid var(--ghost-border-strong); border-radius:var(--radius-xl); padding:56px 32px; box-shadow:var(--shadow-card);}
.finalcta h2{font-size:clamp(1.9rem,3.6vw,2.8rem); line-height:1.12; margin-bottom:14px;}
.finalcta p{max-width:560px; margin:0 auto 30px; font-size:1.08rem;}
.finalcta .audit-form{margin:0 auto;}
/* font-size restated: `.finalcta p` (0,1,1) outranks `.form-note` (0,1,0), which had the
   bottom reassurance row rendering at 17.28px against the hero row's 13px. */
.finalcta .form-note{justify-content:center; font-size:13px;}
.finalcta .alt{margin-top:22px; font-size:14px; color:var(--text-muted);}
.finalcta .alt a{font-weight:600;}

/* ---- FOOTER ---- */
footer{border-top:1px solid var(--ghost-border); padding:52px 0 40px; margin-top:20px;}
.foot-grid{display:grid; grid-template-columns:1.6fr 1fr 1fr 1fr; gap:32px; margin-bottom:36px;}
.foot-brand .brand{margin-bottom:14px;}
.foot-brand p{font-size:13.5px; color:var(--text-muted); max-width:300px; margin:0;}
/* Who and where — the legal entity line under the tagline. */
.foot-brand .foot-company{margin-top:12px; font-size:12.5px; line-height:1.55;}
.foot-col .foot-title{font-family:var(--font-display); font-size:12px; text-transform:uppercase; letter-spacing:.07em; color:var(--text-muted); margin-bottom:14px; font-weight:700;}
.foot-col a{display:block; color:var(--text-on-variant); font-size:13.5px; margin-bottom:10px; font-weight:500;}
.foot-col a:hover{color:#fff;}
.foot-bottom{border-top:1px solid var(--ghost-border); padding-top:24px; display:flex; justify-content:space-between; flex-wrap:wrap; gap:12px; font-size:12.5px; color:var(--text-muted);}
.foot-bottom .honest{max-width:640px; line-height:1.5;}

/* ---- FORCED COLORS ----
   background-clip:text with a transparent fill is invisible in a forced-colours
   theme: the gradient is dropped, so the words disappear rather than change colour.
   The headline's accent clause is the one place we do that on this page. */
@media (forced-colors:active){
  .grad-text{background:none; -webkit-text-fill-color:CanvasText; color:CanvasText;}
}

/* ---- MOTION SAFETY ---- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  .dot-live, .mock-av .wd{animation:none;}
  .btn, .agent, .price-card{transition:none;}
}

/* ---- RESPONSIVE ---- */
/* The bar is a .wrap, but .nav-inner's own `padding:14px 0` wins by source order and
   zeroes the horizontal half — invisible while the viewport is wider than the 1160
   content box, and edge-to-edge the moment it is not. Restored here (the 480 rule
   below still narrows it), NOT by changing the base rule, which would also re-inset
   the bar on wide screens where it currently spans the full 1160. */
@media (max-width:1160px){
  .nav-inner{padding:14px 24px;}
  /* Somewhere around 1110 the collage track gets narrow enough that the draft card's real headline
     takes a second line, which pushes the card's bottom edge ~26px further down and straight into
     the floating inbox card. The floor grows to match, which lowers the float rather than moving
     anything the reader is reading. Measured at 1101: 12.0px of daylight between them. The band is
     only 60px wide (below 1101 the float is hidden outright), so the extra height costs nothing
     anywhere else. */
  .collage{min-height:494px;}
}
/* The hero stacks EARLIER than the rest of the page. Its two columns are copy and a
   perspective-transformed mock, and the mock stops being legible long before a plain
   two-column grid would: at 1100 the copy column is already squeezing it. Only the
   hero cluster lives here; everything else still turns at 960. */
@media (max-width:1100px){
  /* Halved gaps: stacked, the hero reads as one column of copy, and the desktop
     40px gutter plus the pills' own trailing margin left a visible hole above the
     mock. */
  .hero-grid{grid-template-columns:1fr; gap:20px;}
  .hero .lead{max-width:none;}
  .hero-badges{margin-bottom:13px;}
  .collage{min-height:0; min-width:0; margin-top:4px;}
  .mock-main{position:relative; inset:auto; left:0; right:0; transform:none;}
  .mock-float{display:none;}
  .preview-tag{position:static; display:inline-block; margin-bottom:10px;}
}
@media (max-width:960px){
  .price-grid{grid-template-columns:1fr; max-width:440px; margin:0 auto;}
  .salary-grid{grid-template-columns:1fr 1fr;}
  /* Steps stack: copy, then its clip beneath. The even-row flip is cancelled here — with one
     column an `order` swap would put the recording ABOVE the step it belongs to. */
  .step, .step:nth-child(even){grid-template-columns:1fr; gap:20px; padding:24px;}
  .step:nth-child(even) .step-copy, .step:nth-child(even) .stagepane{order:0;}
  .agents{grid-template-columns:1fr;}
  .features{grid-template-columns:1fr;}
  .report-band{grid-template-columns:1fr; padding:32px;}
  .ask-band{grid-template-columns:1fr; padding:32px;}
  .examples-grid{grid-template-columns:1fr 1fr;}
  /* Re-opened from the desktop 302px. That cap exists to level the Reel with the two folded posts
     it shares a row with at three columns; here it shares a row with the lead card instead, so the
     only job left is the original one — stop an uncapped 9:16 frame in a ~420px track from becoming
     750px tall. */
  .reel-frame{max-width:360px;}
  /* Two columns puts the Reel alone on row 2 with a dead cell beside it. The lead card gives up its
     full-width span here and fills that cell instead — which also means it is now half a row wide,
     so its own two columns stack. */
  .example-lead{grid-column:auto; grid-template-columns:1fr;}
  .foot-grid{grid-template-columns:1fr 1fr;}
}
/* Tablets: three plan cards do not fit, one card in a 440px column wastes the width.
   The max-width has to be re-opened here — it is set in the 960 block above and this
   block only wins the columns. */
@media (min-width:761px) and (max-width:960px){
  .price-grid{grid-template-columns:1fr 1fr; max-width:760px;}
}
@media (max-width:760px){
  .nav-inner{position:relative; flex-wrap:wrap; row-gap:0;}
  .nav-login{display:none;}
  .nav-toggle:not([hidden]){display:inline-flex;}
  .nav-links .navlink-mobile{display:block;}
  /* No-JS fallback: hamburger stays hidden, so the links sit under the bar as a
     wrapped full-width row — primary nav is never lost without scripting. */
  .nav-links{order:3; width:100%; flex-wrap:wrap; gap:6px 18px; padding:10px 0 2px;}
  /* JS present: the list becomes a disclosure panel the hamburger toggles. */
  .nav-links.nav-collapsed{display:none; position:absolute; top:100%; left:0; right:0; order:0; width:auto;
    flex-direction:column; align-items:stretch; gap:2px; padding:12px 24px 16px; flex-wrap:nowrap;
    background:color-mix(in srgb, var(--surface) 94%, transparent); backdrop-filter:blur(18px);
    -webkit-backdrop-filter:blur(18px); border-bottom:1px solid var(--ghost-border); box-shadow:var(--shadow-card);}
  .nav-links.nav-collapsed.is-open{display:flex;}
  .nav-links.nav-collapsed .navlink{padding:9px 2px; font-size:15px;}
  .sec{padding:64px 0;}
  .hero{padding:32px 0 40px;}
  /* WRAP, not a column: stacking put "https://" on a line of its own above an empty
     field, which reads as a broken control. Wrapping keeps the prefix and the input
     on one row and drops only the button to the next. */
  .audit-form{flex-wrap:wrap; padding:8px;}
  .audit-form .site-icon{display:none;}
  .audit-form .btn{flex-basis:100%; width:100%;}
  .audit-form input[type=text]{flex:1 1 140px;}
  .audit-form .prefix{padding-left:8px;}
  .report-kpis{grid-template-columns:1fr 1fr;}
  .examples-grid{grid-template-columns:1fr;}
  /* One column: the lead's two halves stack in DOM order — their words, then ours. */
  .example-lead{grid-template-columns:1fr;}
  /* The comparison table stops scrolling sideways and becomes a phone-width table.
     The fourth column ("Do it yourself") is the one a phone can afford to lose: it
     is the weakest of the three alternatives and its cells are the longest. It is
     still there for everyone at 761px and up. */
  .cmp th:nth-child(4), .cmp td:nth-child(4){display:none;}
  /* table-layout:fixed with explicit shares. Under auto layout the label column claimed the
     width it wanted and left the two comparison columns ~85px each, and because
     overflow-wrap:anywhere also shrinks a cell's min-content width, the table happily
     obliged by snapping words mid-character ("Staffiv/a", "agen/cy", "publis/hed").
     Fixed shares stop the label column bullying the others, and break-word only splits a
     word that genuinely cannot fit on its own line. */
  table.cmp{min-width:0; width:100%; table-layout:fixed;}
  table.cmp th:first-child, table.cmp td:first-child{width:36%;}
  table.cmp th:nth-child(2), table.cmp td:nth-child(2),
  table.cmp th:nth-child(3), table.cmp td:nth-child(3){width:32%;}
  table.cmp th, table.cmp td{padding:10px 8px; font-size:13px; white-space:normal; overflow-wrap:break-word;}
}
@media (max-width:600px){
  .founder{flex-direction:column; align-items:center; text-align:center; gap:16px; padding:22px;}
  .founder-photo{margin:0 auto;}
}
@media (max-width:480px){
  .wrap{padding:0 18px;}
  /* Keep brand / hamburger / CTA on one uncrowded row on small phones. The
     padding is restated because the .wrap mobile rule (above) would otherwise
     win by source order and zero out the bar's vertical padding. */
  .nav-inner{gap:10px; padding:10px 18px;}
  .nav-cta{gap:8px;}
  .nav .btn-sm{padding:9px 12px; font-size:13px;}
  .brand-img{height:24px;}
  .salary-grid{grid-template-columns:1fr;}
  .foot-grid{grid-template-columns:1fr;}
  .foot-bottom{flex-direction:column;}
  .mini-audit{flex-direction:column; align-items:stretch;}
  .mini-ring{margin:0 auto;}
}
@media (max-width:380px){
  .wrap{padding:0 14px;}
  .hero h1{font-size:1.95rem;}
  .price-amt .n{font-size:2.2rem;}
  .netpill{font-size:13px; padding:7px 12px;}
}


/* ---- real product footage (media pass) ---- */
.stagepane-video{padding:0; overflow:hidden; background:#0b0b10; position:relative;}
.stagepane-video video{display:block; width:100%; height:auto; border-radius:inherit;}
/* <figure>: the frame holds the clip (and the honesty tag), the caption sits outside it. The
   script injects .clip-toggle / .clip-expand into the video's PARENT and pins them to its corners,
   so the frame — not the figure — has to be the positioned box, or the pause button lands on the
   caption. margin:0 kills the UA's default figure margin. */
.report-video{margin:0; min-width:0;}
.report-video-frame{position:relative; border-radius:16px; overflow:hidden; border:1px solid var(--ghost-border);
  background:#0b0b10; box-shadow:var(--shadow-card, 0 18px 50px rgba(0,0,0,.45));}
.report-video video{display:block; width:100%; height:auto;}
.report-video figcaption{margin-top:10px; font-size:12.5px; line-height:1.45; color:var(--text-muted);}
/* The two clips as a pair, not a stack: each is half the band wide and captioned with the screen
   it shows. min-width:0 so a wide video cannot push a track past its share. */
.report-videos{min-width:0; display:grid; grid-template-columns:1fr 1fr; gap:20px; align-items:start;}
@media (max-width:760px){ .report-videos{grid-template-columns:1fr;} }
/* Honesty label for footage that shows numbers. The screens are real recordings; the figures in
   them come from our demonstration workspace, so they are labelled where they appear (the page's
   own rule) and not only in the footer. pointer-events:none keeps the click-to-enlarge behaviour of
   the clip underneath. TOP-left: it is clear of .clip-toggle (bottom-right) and .clip-expand
   (top-right), and the bottom-left corner of the monthly-report clip is exactly where its headline
   numbers sit — a label that covers the figure it is labelling is worse than no label. */
.clip-tag{position:absolute; left:10px; top:10px; z-index:3; font-size:.62rem; letter-spacing:.09em;
  text-transform:uppercase; font-weight:700; color:var(--text-muted); pointer-events:none;
  background:color-mix(in srgb, var(--surface-lowest) 86%, transparent); padding:4px 9px;
  border-radius:var(--radius-pill); box-shadow:inset 0 0 0 1px var(--ghost-border);}
.report-note{margin:0; font-size:12.5px; line-height:1.5; color:var(--text-muted);}
.demo-dialog{border:0; padding:0; background:transparent; max-width:min(1100px, 92vw); width:100%;
  /* overflow:visible kills the UA scrollbars AND lets the close button sit outside the corner */
  overflow:visible;}
.demo-dialog::backdrop{background:rgba(5,5,10,.82); backdrop-filter:blur(6px);}
.demo-dialog video{display:block; width:100%; height:auto; border-radius:14px;
  border:1px solid var(--ghost-border); background:#0b0b10;}
.demo-close{position:absolute; top:-14px; right:-14px; z-index:2; width:38px; height:38px; border-radius:50%;
  border:1px solid var(--ghost-border); background:var(--surface-high, #22222c); color:#fff; font-size:20px;
  cursor:pointer; line-height:1;}
.demo-close:hover{background:#2e2e3a;}}
/* click-to-enlarge modal reuses .demo-dialog but goes wider for a closer look at
   the inline product clips (steps render only ~330px, so detail is easy to miss). */
.demo-dialog.clip-dialog{max-width:min(1440px, 92vw);}
/* PORTRAIT IN A LANDSCAPE DIALOG. Every clip this modal was built for is 1440×824, so
   .demo-dialog video's width:100% is right for them and catastrophic for the 9:16 Reel: at 92vw
   wide it would be well over two viewports tall, with only its middle on screen.
   Scoped by the dialog's aria-label, which openClip() in Index.cshtml copies from the clicked
   clip's own aria-label before showModal() — the one thing in the DOM that says WHICH clip is
   enlarged. Keying on it leaves every landscape clip's dialog byte-for-byte as it was, rather than
   handing them a max-height they never asked for. THE PREFIX MUST TRACK THE REEL'S aria-label IN
   _LandingExamples.cshtml (there is a note there pointing back here).
   88vh, not 100: the close button hangs 14px outside the top-right corner and needs somewhere to
   hang.
   The dialog BOX has to be narrowed to match, and neither auto nor fit-content does it: the UA
   sheet gives a modal <dialog> left:0/right:0, so width:auto fills the viewport (measured: a
   1325px box around a 446px clip, with the close button stranded 440px off the corner), and
   fit-content resolves against the clip's 540px intrinsic width rather than the height-clamped
   width it will actually paint at. So the box is told the same two limits the video gets, in the
   same order — whichever binds, both agree, and the close button lands on the video's own corner. */
.clip-dialog[aria-label^="Real Reel"]{width:min(calc(88vh * 9 / 16), 92vw); background:transparent;} /* no overflow clip: the close button hangs outside the corner on purpose */
/* ONE constraint, not two. The earlier max-height + max-width pair let the box resolve to a shape
   that was not 9:16 (a short window capped the height while width:auto kept the intrinsic 540px),
   and object-fit:contain then painted bars in whatever the dialog's background was — the owner saw
   white bars top and bottom (2026-09-09). Now the video is exactly as wide as the box and its
   height follows from aspect-ratio, so it is 9:16 at every viewport and fills the box edge to edge;
   the box width already respects both viewport limits. object-fit:cover absorbs sub-pixel rounding. */
.clip-dialog[aria-label^="Real Reel"] video{width:100%; height:auto; aspect-ratio:9 / 16; max-height:none; max-width:none;
  margin-inline:auto; object-fit:cover; background:#0b0b10; border-radius:14px;}

.clip-toggle{position:absolute; right:10px; bottom:10px; z-index:2; width:34px; height:34px; border-radius:50%;
  border:1px solid color-mix(in srgb, #fff 22%, transparent); background:rgba(10,10,16,.62); color:#fff;
  font-size:13px; line-height:1; cursor:pointer; display:grid; place-items:center;
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); opacity:.75; transition:opacity .15s ease;}
.clip-toggle:hover, .clip-toggle:focus-visible{opacity:1;}

/* Enlarge affordance — mirrors .clip-toggle (same always-visible treatment) but
   pinned top-right, so it never collides with the bottom-right pause toggle. */
.clip-expand{position:absolute; right:10px; top:10px; z-index:2; width:34px; height:34px; border-radius:50%;
  border:1px solid color-mix(in srgb, #fff 22%, transparent); background:rgba(10,10,16,.62); color:#fff;
  line-height:1; cursor:pointer; display:grid; place-items:center; padding:0;
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); opacity:.75; transition:opacity .15s ease;}
.clip-expand:hover, .clip-expand:focus-visible{opacity:1;}
.clip-expand svg{width:15px; height:15px; display:block;}
/* Autoplay-mode clips invite a click to enlarge. Clips showing native controls
   (reduced-motion / rejected autoplay) keep the default cursor for their controls. */
.stagepane-video video:not([controls]), .report-video video:not([controls]){cursor:zoom-in;}


/* ---- legal pages (Privacy / Terms) on the public shell ---- */
.legal{padding:120px 0 80px;}
.legal-wrap{max-width:760px;}
.legal-wrap h1{font-family:var(--font-display); font-size:clamp(30px,4.5vw,42px); font-weight:800; margin:10px 0 6px;}
.legal-updated{color:var(--text-muted); font-size:14px; margin-bottom:36px;}
.legal-wrap h2{font-family:var(--font-display); font-size:20px; font-weight:700; margin:34px 0 10px;}
.legal-wrap h3{font-family:var(--font-display); font-size:16px; font-weight:700; margin:24px 0 8px; color:var(--text);}
.legal-wrap p, .legal-wrap li{color:var(--text-on-variant); line-height:1.75; font-size:15.5px;}
.legal-wrap ul, .legal-wrap ol{padding-left:22px; margin:10px 0 18px; display:grid; gap:6px;}
.legal-wrap strong{color:var(--text);}
.legal-wrap a{color:var(--primary);}


/* ---- account pages (login / register / password / email confirm) on the public shell ----
   Same shell as /beta: one glass card on the shared dark wash, under the shared _PublicNav.
   The bar is shaded at rest here (body.page-auth, above), so the top padding only has to
   look right — it never has to hide content scrolling under a transparent bar. */
.auth-wall{padding:72px 0 96px;}
.auth-card{max-width:560px; margin:0 auto; padding:40px clamp(22px, 5vw, 44px);}
.auth-card h1{font-size:clamp(1.6rem, 4vw, 2.15rem); margin-bottom:14px;}
.auth-lead{margin-bottom:28px;}
.auth-form{margin:0; display:block;}
.auth-field{margin:0 0 18px;}
.auth-label{display:block; font-size:.82rem; font-weight:600; letter-spacing:var(--tracking-label);
  text-transform:uppercase; color:var(--text-on-variant); margin:0 0 10px;}
.auth-input{display:block; width:100%; background:var(--surface-lowest);
  border:1px solid var(--ghost-border-strong); border-radius:var(--radius-input);
  color:var(--text-primary); font:inherit; font-size:15px; padding:13px 16px; outline:none;
  transition:border-color .18s ease, box-shadow .18s ease;}
.auth-input::placeholder{color:var(--text-muted);}
.auth-input:focus{border-color:var(--primary); box-shadow:0 0 0 3px var(--primary-soft);}
.auth-hint{display:block; margin:8px 0 0; font-size:13px; color:var(--text-muted);}
/* "optional" tag beside a label — lower-case on purpose so it reads as an aside, not a heading. */
.auth-optional{margin-left:6px; text-transform:none; letter-spacing:0; font-weight:500;
  font-size:.78rem; color:var(--text-muted);}
/* jquery-validate marks the offending control; keep the cue visible without the app sheet. */
.auth-input.input-validation-error{border-color:var(--error-strong);}
.auth-error{display:block; margin:8px 0 0; font-size:13px; font-weight:600; color:var(--error);}
.auth-error:empty{display:none;}
/* asp-validation-summary emits an empty <ul> shell on a clean render — hide it. */
.auth-summary{margin:0 0 18px;}
.auth-summary.validation-summary-valid{display:none;}
.auth-summary ul{margin:0; padding-left:18px; display:grid; gap:4px;}
.auth-row{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 16px; margin:0 0 22px;}
.auth-check-label{display:inline-flex; align-items:center; gap:9px; font-size:14px; color:var(--text-secondary); cursor:pointer;}
.auth-check{width:17px; height:17px; flex:0 0 auto; accent-color:var(--primary); cursor:pointer;}
.auth-link{font-size:14px; font-weight:600;}
.auth-consent{margin:0 0 22px;}
.auth-consent-row{display:flex; align-items:flex-start; gap:10px; cursor:pointer;}
.auth-consent-row .auth-check{margin-top:3px;}
.auth-consent-text{font-size:13.5px; line-height:1.6; color:var(--text-secondary);}
.auth-consent-text a{font-weight:600;}
.auth-actions{display:flex; flex-wrap:wrap; gap:12px; align-items:center;}
.auth-switch{margin:24px 0 0; font-size:14px; color:var(--text-secondary);}
.auth-switch a{font-weight:600;}
/* Register's carried-over brand chip (favicon + business name preview). */
.auth-brand{display:flex; align-items:center; gap:12px; margin:0 0 22px; padding:12px 14px;
  border-radius:var(--radius-md); background:color-mix(in srgb, var(--surface-high) 40%, transparent);
  border:1px solid var(--ghost-border);}
.auth-brand-shell{width:38px; height:38px; flex:0 0 auto; display:grid; place-items:center; position:relative;
  border-radius:11px; background:var(--surface-lowest); border:1px solid var(--ghost-border);
  color:var(--text-on-surface); font-family:var(--font-display); font-weight:800; font-size:16px;}
.auth-brand-img{width:20px; height:20px; border-radius:5px;}
.auth-brand-name{font-family:var(--font-display); font-weight:700; font-size:15px; color:var(--text-primary);}
.auth-brand-helper{margin:2px 0 0; font-size:12.5px; color:var(--text-muted);}
@media (max-width:480px){
  .auth-wall{padding:52px 0 72px;}
  .auth-card{padding:30px 20px;}
  .auth-actions .btn{width:100%;}
}

/* ── Ask band: real-transcript furniture (checks, evidence card, cost line, question chips) ── */
.chat-a p{margin:0 0 6px;} .chat-a p:last-child{margin-bottom:0;}
.chat-checks{display:flex; flex-wrap:wrap; gap:6px; margin:0 0 6px;}
.chat-checks span{font-size:11.5px; font-weight:600; color:var(--text-secondary); padding:3px 9px; border-radius:var(--radius-pill); background:var(--primary-soft); border:1px solid var(--ghost-border);}
.chat-cost{font-size:11.5px; color:var(--text-muted); margin-top:6px;}
.chat-card{margin:8px 0 2px; padding:10px; border-radius:12px; background:rgba(0,0,0,.28); border:1px solid var(--ghost-border);}
.chat-card-h{font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); margin-bottom:6px;}
/* auto-fit, not repeat(4,1fr): four fixed tiles are what forced the evidence card wider than the
   chat bubble, which is what put a horizontal scrollbar on the card. They now wrap to 2×2 the
   moment four will not fit, and the card never has anything to scroll. */
.chat-kpis{display:grid; grid-template-columns:repeat(auto-fit,minmax(88px,1fr)); gap:6px; margin-bottom:7px;}
.chat-kpi{display:flex; flex-direction:column; gap:1px; padding:6px 8px; border-radius:9px; background:rgba(255,255,255,.03); border:1px solid var(--ghost-border);}
/* 9.5px / .04em, not 10px / .06em: "Impressions/views" is the longest label and at the wider
   tracking it wrapped in every tile, costing the card a row of height.
   overflow-wrap:normal undoes the break-word these tiles INHERIT from .chat-a (which exists so a
   long word cannot widen the bubble on a phone). Inherited into a 110px tile it snapped the label
   mid-word — "IMPRESSIONS/VIE / WS" — so the only break opportunity is the <wbr> in the view. */
.chat-kpi .l{font-size:9.5px; letter-spacing:.04em; text-transform:uppercase; color:var(--text-muted);
  overflow-wrap:normal; word-break:normal;}
.chat-kpi .v{font-family:var(--font-display); font-weight:700; font-size:16px; color:var(--text-primary);}
/* table-layout:fixed with a named first column: under auto layout the platform names and the
   four headings set a min-content width the card could not honour, and the card scrolled. */
.chat-table{width:100%; border-collapse:collapse; font-size:12px; table-layout:fixed;}
.chat-table th,.chat-table td{padding:5px 6px; text-align:right; border-top:1px solid var(--ghost-border); color:var(--text-secondary);}
.chat-table th:first-child,.chat-table td:first-child{text-align:left; width:32%;}
.chat-table thead th{border-top:0; font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted);}
.chat-table tbody th{font-weight:600; color:var(--text-primary);}
.chat-card-f{margin-top:6px; font-size:11px; color:var(--text-muted);}
.chat-card-f .fresh{color:#3ddc97; font-weight:700; letter-spacing:.06em; font-size:10px; text-transform:uppercase;}
.chat-chips{list-style:none; padding:0; margin:14px 0 0; display:flex; flex-wrap:wrap; gap:8px;}
.chat-chips li{font-size:12.5px; color:var(--text-secondary); padding:6px 11px; border-radius:var(--radius-pill); border:1px solid var(--ghost-border); background:rgba(255,255,255,.03);}
@media (max-width:480px){ .chat-kpis{grid-template-columns:repeat(2,1fr);} }
.example-note{margin:10px 0 0; font-size:11.5px; color:var(--text-muted);}

/* ── Ask band: the evidence card must never widen the chat past its bubble ──
   overflow:hidden, NOT overflow-x:auto. A scrollbar inside a marketing transcript is furniture the
   reader has to operate to see a number we are quoting at them; the fixed table and the wrapping
   KPI tiles above mean there is nothing left to scroll to. */
.chat > *{min-width:0;} .chat-q,.chat-a{overflow-wrap:break-word;}
.chat-card{overflow:hidden;}
/* A NARROW CARD DROPS THE "POSTS" COLUMN, the way the comparison table drops "Do it yourself".
   Under ~405px of card the four fixed columns leave the data columns narrower than the word
   "Impressions" at any legible size, and the headings snapped mid-word ("IMPRES / SIONS"). Three
   columns give them a clean single line. Posts is the column that can go: the total is in the
   sentence above ("across 33 posts") and in the Posts KPI tile, so no figure shown here changes —
   one breakdown is simply not shown when there is no room for it.

   A CONTAINER query, not a viewport one, because the card's width is not a function of the
   viewport: the Ask band is two columns above 960px and one below it, so the card is NARROWER at
   1000px (384) than it is at 700px (498). Every viewport breakpoint I could write would be wrong on
   one side of that flip. Container queries are older than the color-mix() this sheet already
   depends on everywhere, so they need no fallback here. */
.chat-card{container-type:inline-size;}
@container (max-width:405px){
  .chat-table th:nth-child(2), .chat-table td:nth-child(2){display:none;}
  .chat-table th:first-child,.chat-table td:first-child{width:30%;}
  .chat-table thead th{font-size:9.5px; letter-spacing:.04em;}
}
@media (max-width:480px){
  .ask-band{padding:22px 16px;}
  .chat{padding:12px;} .chat-q{max-width:94%;} .chat-a{max-width:100%;}
  .chat-table{font-size:11px;} .chat-table th,.chat-table td{padding:5px 5px;}
  .chat-kpi{padding:7px 8px;} .chat-kpi .v{font-size:16px;}
}

/* ── Case study band ──
   The first-30-days customer band (_LandingCaseStudy.cshtml, behind Landing:CaseStudy:Enabled).
   Same card as .report-band and .ask-band — the surface declarations below are copied from
   .report-band verbatim, not re-derived, so the three bands stay one object under one theme edit.
   Radius is --radius-xl for the same reason: it is what both neighbouring bands use, and a band
   that rounds differently reads as a different component rather than a third of the same one. */
.case-band{background:
    radial-gradient(60% 120% at 100% 0%, color-mix(in srgb, var(--purple-600) 24%, transparent), transparent 55%),
    color-mix(in srgb, var(--surface-low) 80%, transparent);
  border:1px solid var(--ghost-border-strong); border-radius:var(--radius-xl); padding:44px; overflow:hidden;
  display:grid; grid-template-columns:1.25fr 1fr; column-gap:36px; row-gap:14px; align-items:start;
  box-shadow:var(--shadow-card);}
/* Four explicit rows rather than columns, and the reason is the fold. Row 1 is the copy beside the
   four tiles, row 2 is the three charts as one full-width strip, row 3 is the per-platform line,
   row 4 is the footnote.
   The charts took the full width when they went from two to three: three plots inside the old
   right-hand column would render ~160px wide each, which is not a chart, it is a sparkline. Once
   they are full width the tiles have nowhere to go but up beside the copy, and 2x2 there is what
   keeps the band inside one screen — tiles as their own full-width row underneath measured ~145px
   taller at 1440 and pushed the footnote off the fold.
   DOM order is copy -> tiles -> charts -> platform strip -> footnote (headline numbers before
   drawings, which is also the phone order), so nothing reorders between breakpoints; these five
   rules are the only thing that puts the tiles up beside the copy, and deleting them degrades to
   source order rather than to a broken layout.
   The band's internal spacing (row-gap here, the lead and bullet-list bottom margins, the tile's
   vertical padding) is tuned a few px tighter than the page default for the same reason: measured
   at 1440 the section lands just under 1000px, and the numbers that carry the claim have to be in
   the same screen as the sentence that makes it. If the copy grows, re-measure before adding
   anything. */
.case-copy{grid-column:1; grid-row:1;}
.case-stats{grid-column:2; grid-row:1;}
.case-charts{grid-column:1 / -1; grid-row:2;}
.case-platforms{grid-column:1 / -1; grid-row:3;}
.case-foot{grid-column:1 / -1; grid-row:4;}
/* Explicit line-height for the same reason as .report-band h2: this heading wraps at its clamped
   top size, where the inherited body 1.6 opens a visible gap between the two lines. */
.case-band h2{font-size:clamp(1.6rem,3vw,2.2rem); line-height:1.12; margin-bottom:10px;}
.case-copy{min-width:0;}
.case-lead{font-size:17px; line-height:1.6; color:var(--text-secondary); margin:0 0 10px;}
/* The three qualifiers, in the .fcard list vocabulary (check marker, secondary text). They are the
   band's caveats as much as its highlights — the third one is what keeps "+37% Google impressions"
   from reading as a reach claim, and what says out loud how small the audience behind the social
   numbers is — so they sit in the copy column at body weight, never as a footnote. */
.case-points{list-style:none; margin:0 0 12px; padding:0; display:grid; gap:8px;}
.case-points li{display:flex; gap:9px; font-size:13.5px; line-height:1.5; color:var(--text-secondary); align-items:flex-start;}
.case-points li .c{color:var(--success); flex:0 0 auto; margin-top:1px;}
/* Four tiles, .chat-kpi's shape at band scale, 2x2 in the band's right-hand column. They are read
   as pairs — two social tiles then two search tiles — so a single column would turn them into a
   list four screens tall on a phone; 2x2 is the shape at every width, which is why there is no
   four-across variant any more. */
.case-stats{display:grid; grid-template-columns:1fr 1fr; gap:12px;}
.case-stat{padding:14px 18px; border-radius:12px; background:rgba(255,255,255,.03); border:1px solid var(--ghost-border);}
.case-stat .v{font-family:var(--font-display); font-weight:700; font-size:34px; color:var(--text-primary); line-height:1.1;}
.case-stat .l{font-size:11px; letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted); margin-top:4px;}
.case-sub{font-size:12.5px; line-height:1.45; color:var(--text-secondary); margin:6px 0 0;}
/* ── The three charts ──
   ONE hue for the row, and it is --primary for every mark in all three. Nothing else on any chart
   is coloured: the baseline is a border token, every label is a text token, and the only tint is
   the line's own fill at 14%. That is the whole rule — a second hue here would have to mean a
   second series, and there is exactly one series per chart.
   All three SVGs carry the same viewBox and the same plot box, so the bar tops and the line ride
   the same optical grid whether the row is three across, two, or stacked. The viewBox is 360 wide
   because that is close to the width they actually render at (~328px at 1160, ~322px on a 390px
   phone): text inside a viewBox scales with the box, so keeping the two within ~20% of each other
   is what lets an 11px label BE an 11px label at every breakpoint instead of needing a font-size
   ladder at each one. .case-chart's max-width is what holds the top end of that ratio. */
.case-charts{display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:20px; align-items:start; min-width:0;}
/* The cap is the other half of the viewBox-to-render ratio above: without it a stacked chart on a
   700px band draws its 12px axis labels at 20px. */
/* position:relative is load-bearing, not habit: the sr-only .case-sr table below is absolutely
   positioned, and a TABLE treats width:1px as a minimum rather than a size, so it lays out at its
   full ~440px and pushes the DOCUMENT's scroll width past the viewport at any width where the
   third chart sits far enough right. Giving the figure a containing block puts that table back
   inside .case-band's overflow:hidden, where it is clipped and stops widening the page. */
.case-chart{margin:0; min-width:0; max-width:420px; position:relative;}
.case-chart-h{font-size:12.5px; font-weight:700; letter-spacing:.02em; color:var(--text-secondary); margin:0 0 4px;}
.case-chart svg{display:block; width:100%; height:auto;}
/* The caption is not a credit line. Chart B's names the one post that is a quarter of the month, so
   the tallest bar cannot be read as a typical week; Chart C's says who the impressions belong to,
   and without it the line is a Staffiva claim about a site that already ranked. Each ships with its
   chart or neither does. */
.case-chart-note{font-size:12px; line-height:1.45; color:var(--text-muted); margin:4px 0 0;}
.cchart text{font-family:var(--font-body);}
.cc-base{stroke:var(--ghost-border-strong); stroke-width:1;}
.cc-bar{fill:var(--primary);}
/* The part week is drawn at 45% for the same reason it is named in the note under the chart: three
   days of a week next to five full ones is not a fall in output, and a solid bar says it is. */
.cc-bar.is-part{fill:color-mix(in srgb, var(--primary) 45%, transparent);}
.cc-line{fill:none; stroke:var(--primary); stroke-width:2; stroke-linejoin:round; stroke-linecap:round;}
.cc-area{fill:var(--primary); opacity:.14;}
/* 9px endpoint dot with a 2px ring in the band's own surface, so the marker reads as a mark on the
   line rather than a thickening of it. */
.cc-dot{fill:var(--primary); stroke:var(--surface-low); stroke-width:2;}
.cc-val{font-size:13px; font-weight:700; fill:var(--text-secondary);}
.cc-end{font-size:13px; font-weight:700; fill:var(--text-primary);}
.cc-ax{font-size:12px; fill:var(--text-muted);}
/* Invisible hover targets, drawn last and a full band wide, so the tooltip is findable — including
   over the zero week, which has no bar to point at. */
.cc-hit{fill:transparent; pointer-events:all;}
/* ── Per-platform line ──
   Deliberately not a fourth chart: no axis, no baseline, no scale. Three counts per platform in
   words, and one thin bar behind each set as a second reading of the impressions figure printed
   beside it (scaled to the busiest platform, aria-hidden, --primary like everything else). The
   numbers are the content, which is why this one carries no sr-only table. */
.case-platforms{display:flex; flex-wrap:wrap; align-items:center; gap:8px 20px;
  padding:8px 14px; border:1px solid var(--ghost-border); border-radius:12px;
  background:rgba(255,255,255,.03);}
.case-plat-h{flex:0 0 auto; width:96px; margin:0; font-size:11px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--text-muted); line-height:1.35;}
.case-plat-list{flex:1 1 420px; list-style:none; margin:0; padding:0; display:grid;
  grid-template-columns:repeat(3, minmax(0,1fr)); gap:8px 20px;}
.case-plat{min-width:0;}
.case-plat-n{display:block; font-size:12.5px; font-weight:700; color:var(--text-primary); line-height:1.35;}
.case-plat-bar{display:block; height:4px; margin:3px 0; border-radius:2px;
  background:color-mix(in srgb, var(--primary) 14%, transparent);}
.case-plat-bar i{display:block; height:100%; border-radius:2px; background:var(--primary);}
.case-plat-v{display:block; font-size:12px; line-height:1.35; color:var(--text-secondary);}
/* The same numbers as the drawing, for anything that cannot see it. Standard clip-and-hide; not
   display:none, which would take it out of the accessibility tree along with the pixels. */
.case-sr{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0;}
/* Provenance for the WHOLE band, not just the tiles — the three bullets above come from the same
   pull — so it spans every column rather than sitting in one track. */
.case-foot{font-size:12.5px; line-height:1.5; color:var(--text-muted); margin:0;}
/* The one width where three charts is a squeeze: between the two-column collapse and the point
   where .wrap stops growing, the row is ~277px per plot, which divides a 12-unit axis label down
   to 9px. The labels step up (they are in user units, so the browser divides the step back down)
   and every other week start drops out, because bigger labels in the same band would touch. Every
   bar still prints its own value and the sr-only table still carries all seven weeks.
   The min-height is the third heading: "Google Search impressions, 28-day windows" is the only
   one that wraps here, and without a floor it alone pushes its plot a line lower than the two
   beside it. */
@media (min-width:961px) and (max-width:1150px){
  .cc-ax{font-size:14px;} .cc-val{font-size:14.5px;} .cc-end{font-size:14.5px;}
  .cc-ax-alt{display:none;}
  .case-chart-h{min-height:40px;}
}
@media (max-width:960px){
  /* Band collapses to one column: the explicit row/column placements above have to go with it, or
     the copy, the tiles and the charts fight over row 1 in a single-column grid. */
  .case-band{grid-template-columns:1fr; padding:28px; row-gap:26px;}
  .case-copy, .case-stats, .case-charts, .case-platforms, .case-foot{grid-column:auto; grid-row:auto;}
  /* Full width now, so two charts sit side by side and the third takes the left half of a second
     row. Three across at this width would be ~270px each, which is where the axis labels start to
     touch. */
  .case-charts{grid-template-columns:1fr 1fr;}
}
@media (max-width:700px){
  .case-charts{grid-template-columns:1fr;}
  /* The label stops being a gutter and becomes a heading over its own list. */
  .case-plat-h{flex:1 1 100%; width:auto;}
  .case-plat-list{grid-template-columns:1fr;}
}
@media (max-width:480px){
  .case-band{padding:22px 16px;}
  .case-stat{padding:14px 14px;}
  .case-stat .v{font-size:28px;}
}
/* The one place the viewBox-to-render ratio breaks down. Below ~340px the band is narrow enough
   that a 360-unit viewBox draws its 12px axis label at 8.6px, so the labels step up (they are in
   user units, so the step is what the browser divides back down) and every other week start drops
   out — seven week labels in a 260px chart is a wall, and every value is still printed above its
   own bar. */
@media (max-width:340px){
  .cc-ax{font-size:15px;} .cc-val{font-size:16px;} .cc-end{font-size:16px;}
  .cc-ax-alt{display:none;}
}

/* PHONES (kept at the END of the sheet on purpose: same specificity as the portrait rule above, so
   source order is what makes the 80vh width win on phones): iOS Safari draws its native video controls INSIDE the frame's top corners (fullscreen /
   picture-in-picture top-left, volume top-right), so a close button that hangs on the top-right
   corner sits exactly on the mute toggle — the owner hit this on staffiva.com 2026-09-10 and could
   not unmute the Reel without closing it. Below 760px the close button moves into its own band
   ABOVE the video, right-aligned, 44px for touch; the portrait dialog gives up 8vh of height so the
   band always has room (10vh clears 52px on a 520px-tall viewport). Landscape clips are short on a
   phone, so the band already has room there. */
@media (max-width:760px){
  .demo-close{top:-52px; right:0; width:44px; height:44px; font-size:22px;}
  .clip-dialog[aria-label^="Real Reel"]{width:min(calc(80vh * 9 / 16), 92vw);}

