/* /studio — showcase grammar. Loaded on this page only. */

/* Native smooth scrolling fights ScrollTrigger's pin and scrub, and this
   page is one long pinned sequence. Only this page opts out. */
html{scroll-behavior:auto}

/* The header stops being a bar and becomes an overlay: the acts are
   full-bleed and a tinted strip across the top would cut them in half.
   studio.js flips data-nav as light and dark acts pass under it. */
/* Only where the scene actually flips. Without the motion layer there is
   nothing to recolour the header, and a transparent bar would leave the
   white wordmark invisible on the white act. */
html.motion .hdr{position:fixed;inset:0 0 auto;background:transparent;backdrop-filter:none;border-bottom:0}
html.motion .hdr[data-stuck="1"]{background:transparent;border-bottom-color:transparent}
/* A soft scrim in the current act's own colour: the bar stays invisible
   but nav labels never sit directly on top of body copy. */
html.motion .hdr{--scrim:0,0,0}
html.motion .hdr::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(var(--scrim),.9),rgba(var(--scrim),0));
  transition:background 320ms var(--ease);
}
html[data-nav="light"] .hdr{--scrim:255,255,255}
html[data-nav="light"] .hdr{color:#000}
html[data-nav="light"] .nav a{color:#333}
html[data-nav="light"] .nav a:hover{color:#000;background:oklch(0% 0 0 / .06)}
html[data-nav="light"] .burger{border-color:oklch(0% 0 0 / .2)}
.hdr,.nav a,.burger{transition:color 320ms var(--ease),border-color 320ms var(--ease)}

.st-corners{
  position:absolute;inset:0;pointer-events:none;z-index:3;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
}
.st-corners span{position:absolute;padding:clamp(1rem,2.5vw,2rem)}
/* The top pair clears the header rather than sitting under it. */
.st-corners span:nth-child(1){top:60px;left:0}
.st-corners span:nth-child(2){top:60px;right:0}
@media (min-width:60rem){
  html.motion .st-corners span:nth-child(1),
  html.motion .st-corners span:nth-child(2){top:52px}
}
.st-corners span:nth-child(3){bottom:0;left:0}
.st-corners span:nth-child(4){bottom:0;right:0}

/* ---------- act 1: white ---------- */
.st-open{
  position:relative;min-height:100svh;background:#fff;color:#000;
  display:grid;align-content:center;justify-items:start;
  padding:clamp(4rem,10vw,8rem) clamp(1.25rem,5vw,5rem);
}
.st-open__h{
  font-family:var(--body);font-weight:600;letter-spacing:-.045em;line-height:.92;
  font-size:clamp(3.2rem,1rem + 12vw,13rem);text-wrap:nowrap;
}
.st-open__h em{font-style:normal;color:var(--accent)}
.st-open__sub{
  margin-top:clamp(1.5rem,3vw,2.5rem);max-width:34ch;
  font-size:clamp(1rem,.95rem + .4vw,1.25rem);line-height:1.45;color:#555;
}
.st-cue{
  position:absolute;left:50%;bottom:clamp(1rem,2.5vw,2rem);translate:-50% 0;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;color:#999;
}
@media (prefers-reduced-motion:no-preference){
  .st-cue{animation:st-cue 2.4s var(--ease-in-out) infinite}
}
@keyframes st-cue{0%,100%{transform:translateY(0);opacity:.55}50%{transform:translateY(5px);opacity:1}}

/* ---------- act 2: black stage ---------- */
.st-stage{position:relative;background:#000;color:#fff}
.st-stage__gl{position:absolute;inset:0;width:100%;height:100%;z-index:1;display:none}
html.motion .st-stage__gl{display:block}
.st-stage__mark{
  position:absolute;left:50%;top:50%;translate:-50% -50%;z-index:1;
  width:min(46vw,26rem);color:var(--accent);opacity:.5;
}
html.motion .st-stage__mark{display:none}
.st-stage__acts{position:relative;z-index:2}
.st-act{
  font-family:var(--body);font-weight:500;letter-spacing:-.03em;line-height:1.12;
  font-size:clamp(1.85rem,1rem + 3.4vw,4.25rem);
  max-width:24ch;margin-inline:auto;text-align:center;text-wrap:balance;
  padding:clamp(4rem,14vh,10rem) clamp(1.25rem,5vw,5rem);
}
/* Words start dim and fill to white as the act scrolls through. Without
   the motion layer they are simply legible from the start. */
html.motion .st-act .wf{color:#4a4a4a;transition:color 120ms linear}
html.motion .st-act .wf.on{color:#fff}

html.motion .st-stage{height:100svh;overflow:clip}
html.motion .st-stage__acts{position:absolute;inset:0;display:grid;place-items:center}
html.motion .st-act{position:absolute;opacity:0;padding-inline:clamp(1.25rem,5vw,5rem)}
html.motion .st-act[data-act="0"]{opacity:1}

/* ---------- work ---------- */
.st-work{background:#fff;color:#000;padding:clamp(4rem,9vw,9rem) clamp(1.25rem,5vw,5rem)}
.st-work__head{max-width:52ch;margin-bottom:clamp(2.5rem,5vw,4.5rem)}
.st-label{font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.st-work__head h2{
  font-family:var(--body);font-weight:600;letter-spacing:-.04em;line-height:1;
  font-size:clamp(2.1rem,1.2rem + 3.6vw,4.5rem);margin:.75rem 0 1rem;
}
.st-work__head p{color:#555;font-size:clamp(1rem,.95rem + .4vw,1.2rem);max-width:46ch}
.st-work__grid{display:grid;gap:clamp(1.5rem,3vw,3rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr))}
.st-case__img{aspect-ratio:16/10;overflow:hidden;background:#f1f0ec}
.st-case__img img{width:100%;height:100%;object-fit:cover;object-position:top center;transition:transform 800ms var(--ease)}
.st-case:hover .st-case__img img{transform:scale(1.04)}
.st-case__ph{display:grid;place-items:center;height:100%;color:var(--accent)}
.st-case__ph svg{width:28%}
.st-case__m{
  display:flex;justify-content:space-between;gap:1rem;margin-top:.9rem;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;color:#888;
}
.st-case__m span:last-child{color:#000}
.st-case p{margin-top:.35rem;color:#555;font-size:.95rem}

/* ---------- price act ----------
   Black, editorial, and deliberately thin on words: four columns, one
   plain sentence and three plain points each. The full feature lists and
   the jargon live on /pricing; a visitor who does not know what a pixel
   is should still be able to choose here. */
.st-price{background:#000;color:#fff;padding:clamp(4.5rem,10vw,10rem) clamp(1.25rem,5vw,5rem)}
.st-price__head{max-width:40ch;margin-bottom:clamp(3rem,6vw,5.5rem)}
.st-price__head h2{
  font-family:var(--body);font-weight:600;letter-spacing:-.04em;line-height:1;
  font-size:clamp(2.4rem,1.4rem + 4vw,5rem);margin:.9rem 0 1.1rem;
}
.st-price__head p{color:#9a9a9a;font-size:clamp(1.05rem,1rem + .5vw,1.35rem)}

.st-price__grid{
  display:grid;gap:clamp(2rem,4vw,3.5rem);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr));
}
.st-tier{
  /* name, price, sentence, points, button, note — the points row takes
     the slack so the four buttons land on one line. */
  display:grid;gap:1.15rem;grid-template-rows:auto auto auto 1fr auto auto;
  padding-top:1.75rem;border-top:1px solid rgba(255,255,255,.22);
}
.st-tier--pop{border-top-color:var(--accent)}
.st-tier__n{
  display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;color:#fff;
}
.st-tier__n b{color:var(--accent);font-weight:500}
.st-tier__p{
  font-family:var(--body);font-weight:600;letter-spacing:-.045em;line-height:.95;
  font-size:clamp(2.6rem,1.6rem + 2.6vw,3.9rem);
  display:flex;align-items:baseline;gap:.55rem;flex-wrap:wrap;
}
.st-tier__p i{font-style:normal;font-size:.9rem;font-weight:400;letter-spacing:0;color:#8d8d8d}
.st-tier__s{color:#e2e2e2;font-size:1.05rem;line-height:1.45}
.st-tier__f{list-style:none;padding:0;display:grid;gap:.85rem;align-content:start}
.st-tier__f li{
  display:grid;grid-template-columns:1.1em 1fr;gap:.6em;
  font-size:.9375rem;line-height:1.4;color:#a9a9a9;
}
.st-tier__f li::before{content:"";width:.45em;height:.45em;margin-top:.5em;background:var(--accent);border-radius:50%}
.st-tier__cta .btn{width:100%;justify-content:center}
/* One or two lines depending on the package; reserving two keeps the
   four buttons on one line. */
.st-tier__note{font-size:.8125rem;color:#6f6f6f;line-height:1.4;min-height:2.8em}

.st-price__terms{
  margin-top:clamp(3rem,6vw,5rem);padding-top:1.75rem;
  border-top:1px solid rgba(255,255,255,.16);
  display:grid;gap:.75rem;max-width:60ch;
  font-size:.9375rem;line-height:1.5;color:#8d8d8d;
}


/* ---------- close ---------- */
.st-end{
  position:relative;min-height:100svh;background:#000;color:#fff;
  display:grid;align-content:center;justify-items:center;text-align:center;
  padding:clamp(4rem,10vw,8rem) clamp(1.25rem,5vw,5rem);
}
.st-end__h{
  font-family:var(--body);font-weight:600;letter-spacing:-.04em;line-height:1.04;
  font-size:clamp(2.2rem,1.2rem + 4.2vw,5.5rem);max-width:18ch;
}
html.motion .st-end__h .wf{color:#4a4a4a;transition:color 120ms linear}
html.motion .st-end__h .wf.on{color:#fff}
.st-end__btns{display:flex;flex-wrap:wrap;gap:.75rem;justify-content:center;margin-top:clamp(2rem,4vw,3rem)}
.st-end__foot{margin-top:1.5rem;font-family:var(--mono);font-size:.75rem;color:#777;max-width:44ch}

/* The close sits on white so the price act above it keeps the black.
   Same fill effect, inverted. */
.st-end--light{background:#fff;color:#000}
.st-end--light .st-end__foot{color:#666}
.st-end--light .btn--ghost{--fg:#000;border-color:rgba(0,0,0,.22)}
.st-end--light .btn--ghost:hover{--bg:rgba(0,0,0,.05);border-color:rgba(0,0,0,.45)}
html.motion .st-end--light .st-end__h .wf{color:#c8c5be}
html.motion .st-end--light .st-end__h .wf.on{color:#000}

/* ============================================================
   /direct/<niche> in the studio grammar.
   Same acts, same hairlines, same corner labels — only the blocks the
   showcase page never needed are added here.
   ============================================================ */

/* app.css sets `strong, b { color: var(--paper) }` for the dark site, which
   turns every bold word near-white the moment it lands on a white act. Scope
   it back to inherit on every light surface this grammar uses, so the next
   light act does not have to remember. */
.st-open strong, .st-open b,
.st-work strong, .st-work b,
.st-light strong, .st-light b,
.st-end--light strong, .st-end--light b,
.st-rail--light strong, .st-rail--light b{color:inherit}

/* A light act that is not .st-open / .st-work. studio.js watches this class
   too, so the header flips polarity over it. */
.st-light{background:#fff;color:#000}
.st-dark{background:#000;color:#fff}
.st-act-pad{padding:clamp(4rem,9vw,9rem) clamp(1.25rem,5vw,5rem)}
.st-head{max-width:52ch;margin-bottom:clamp(2.5rem,5vw,4.5rem)}
.st-head h2{
  font-family:var(--body);font-weight:600;letter-spacing:-.04em;line-height:1;
  font-size:clamp(2.1rem,1.2rem + 3.6vw,4.5rem);margin:.75rem 0 1rem;
}
.st-head p{font-size:clamp(1rem,.95rem + .4vw,1.2rem);max-width:46ch}
.st-light .st-head p{color:#555}
.st-dark .st-head p{color:#9a9a9a}

/* concept shots — the work grid, but these are our own designs and the
   caption says so, so they do not link anywhere. */
.st-concept__img{aspect-ratio:16/10;overflow:hidden;background:#f1f0ec}
.st-concept__img img{width:100%;height:100%;object-fit:cover;object-position:top center}
.st-concept__m{
  display:flex;justify-content:space-between;gap:1rem;margin-top:.9rem;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;color:#888;
}
.st-concept__m b{color:var(--accent);font-weight:500}
.st-concept h3{font-family:var(--body);font-weight:600;font-size:1.15rem;letter-spacing:-.02em;margin-top:.35rem}
.st-concept p{margin-top:.3rem;color:#555;font-size:.95rem;line-height:1.5}

/* the compliance act — the argument this page actually wins on, so it is
   set as numbered editorial lines rather than a tick list. */
.st-rules{display:grid;counter-reset:sr;border-top:1px solid rgba(255,255,255,.16)}
.st-rules li{
  list-style:none;display:grid;grid-template-columns:4.5rem 1fr;gap:clamp(1rem,3vw,2.5rem);
  padding:clamp(1.1rem,2.2vw,1.8rem) 0;border-bottom:1px solid rgba(255,255,255,.16);
  align-items:baseline;
}
.st-rules li::before{
  counter-increment:sr;content:counter(sr,decimal-leading-zero);
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;color:var(--accent);
}
.st-rules li span{
  font-family:var(--body);font-weight:500;letter-spacing:-.02em;line-height:1.25;
  font-size:clamp(1.05rem,.95rem + .85vw,1.75rem);color:#fff;text-wrap:balance;
}
.st-kicker{
  margin-top:clamp(2rem,4vw,3rem);padding-left:clamp(1rem,2vw,1.5rem);
  border-left:2px solid var(--accent);max-width:56ch;
  font-size:clamp(1rem,.95rem + .4vw,1.2rem);line-height:1.5;color:#9a9a9a;
}

/* proof — four big figures on hairlines, then the live URLs */
.st-figs{display:grid;gap:clamp(1.5rem,3vw,2.5rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,11rem),1fr))}
.st-fig{border-top:1px solid rgba(0,0,0,.18);padding-top:1.1rem}
.st-fig b{
  display:block;font-family:var(--body);font-weight:600;letter-spacing:-.045em;line-height:.95;
  font-size:clamp(2.1rem,1.4rem + 2.4vw,3.4rem);color:var(--accent);
}
.st-fig span{display:block;margin-top:.45rem;font-size:.9375rem;color:#555;line-height:1.4}
.st-links{margin-top:clamp(2rem,4vw,3rem);font-size:.95rem;color:#555;line-height:2}
.st-links a{color:#000;border-bottom:1px solid rgba(0,0,0,.25)}
.st-links a:hover{border-color:var(--accent);color:var(--accent)}

/* FAQ act — hairlines, no boxes */
.st-faq{border-top:1px solid rgba(0,0,0,.18)}
.st-faq details{border-bottom:1px solid rgba(0,0,0,.18)}
.st-faq summary{
  display:flex;justify-content:space-between;gap:1.5rem;align-items:baseline;cursor:pointer;
  list-style:none;padding:clamp(1.1rem,2vw,1.5rem) 0;
  font-family:var(--body);font-weight:600;letter-spacing:-.025em;
  font-size:clamp(1.05rem,.95rem + .7vw,1.5rem);line-height:1.2;
}
.st-faq summary::-webkit-details-marker{display:none}
.st-faq summary::after{content:"+";font-family:var(--mono);font-size:1.5rem;color:var(--accent);line-height:1;flex:none;transition:transform 300ms var(--ease)}
.st-faq details[open] summary::after{transform:rotate(45deg)}
.st-faq summary:hover{color:var(--accent)}
.st-faq__a{padding:0 0 1.6rem;max-width:64ch;color:#555;font-size:1.0625rem;line-height:1.6}

/* ── conversion furniture ──────────────────────────────────
   /studio is a showcase and can afford to make you scroll. A niche page is
   a paid-traffic destination: there has to be a way to act on every screen,
   or the click is bought and thrown away. */

.st-open__btns{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:clamp(1.75rem,3.5vw,2.75rem)}
.st-open .btn--ghost{--fg:#000;border-color:rgba(0,0,0,.22)}
.st-open .btn--ghost:hover{--bg:rgba(0,0,0,.05);border-color:rgba(0,0,0,.45)}
.st-open__note{margin-top:1.1rem;font-family:var(--mono);font-size:.75rem;color:#8a8a8a}

/* one-line CTA rail dropped between acts */
.st-rail{
  display:flex;flex-wrap:wrap;gap:1rem 2rem;align-items:center;justify-content:space-between;
  padding:clamp(1.5rem,3vw,2.25rem) clamp(1.25rem,5vw,5rem);
  background:#000;color:#fff;border-top:1px solid rgba(255,255,255,.14);
}
.st-rail p{font-family:var(--body);font-weight:500;letter-spacing:-.02em;
  font-size:clamp(1.05rem,.95rem + .6vw,1.4rem);max-width:34ch}
.st-rail--light{background:#fff;color:#000;border-top-color:rgba(0,0,0,.14)}

/* ── sample-content preview only ───────────────────────────
   These blocks never render on a live page. See direct-studio.mjs. */
.st-preview{
  position:sticky;top:0;z-index:120;display:flex;flex-wrap:wrap;gap:.5rem 1rem;align-items:baseline;
  padding:.6rem clamp(1.25rem,5vw,5rem);background:#B3261E;color:#fff;
  font-size:.8125rem;line-height:1.4;
}
.st-preview b{font-family:var(--mono);font-size:.6875rem;letter-spacing:.18em;text-transform:uppercase}
.st-preview span{opacity:.92}
/* the sticky bar owns the top of the viewport, so the fixed header sits under it */
html.motion:has(.st-preview) .hdr{top:2.1rem}

.st-band{
  display:grid;gap:clamp(1.5rem,3vw,2.5rem);background:#000;color:#fff;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr));
  padding:clamp(2.5rem,5vw,4rem) clamp(1.25rem,5vw,5rem);
}
.st-band b{display:block;font-family:var(--body);font-weight:600;letter-spacing:-.045em;line-height:.95;
  font-size:clamp(2.1rem,1.4rem + 2.4vw,3.4rem);color:var(--accent)}
.st-band span{display:block;margin-top:.5rem;font-size:.9375rem;color:#9a9a9a;line-height:1.4}

.st-case__lead{max-width:56ch;font-size:clamp(1.05rem,1rem + .5vw,1.35rem);line-height:1.5;
  color:#444;margin-bottom:clamp(1.75rem,3.5vw,2.75rem)}
.st-quote{margin:clamp(2rem,4vw,3rem) 0 0;padding-left:clamp(1rem,2vw,1.5rem);
  border-left:2px solid var(--accent);max-width:52ch}
.st-quote p{font-family:var(--body);font-weight:500;letter-spacing:-.02em;line-height:1.35;
  font-size:clamp(1.2rem,1.05rem + 1vw,1.9rem)}
.st-quote cite{display:block;margin-top:.9rem;font-family:var(--mono);font-size:.6875rem;
  letter-spacing:.16em;text-transform:uppercase;color:#8a8a8a;font-style:normal}

.st-quotes{display:grid;gap:clamp(1.5rem,3vw,2.5rem);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr))}
.st-quotes figure{margin:0;display:grid;gap:1rem;align-content:start;
  padding-top:1.35rem;border-top:1px solid rgba(0,0,0,.18)}
.st-quotes blockquote{margin:0;font-size:1.0625rem;line-height:1.5;color:#333}
.st-quotes figcaption b{display:block;font-weight:600;font-size:.9375rem}
.st-quotes figcaption span{display:block;margin-top:.15rem;font-size:.8125rem;color:#777}

/* ── before / after ────────────────────────────────────────
   Two plates side by side per row, then one line naming the single change
   that matters. The pair carries the argument; the sentence closes it. */
.st-ba{display:grid;gap:clamp(2.5rem,5vw,4.5rem)}
/* Exactly two tracks, never auto-fit: the pair IS the argument, and auto-fit
   opened a third empty column on wide screens that left both plates stranded
   at two thirds width. */
.st-ba__row{display:grid;gap:clamp(1rem,2.5vw,2rem);grid-template-columns:1fr}
@media (min-width:52rem){ .st-ba__row{grid-template-columns:1fr 1fr} }
.st-ba__side{margin:0;display:grid;gap:.7rem;align-content:start}
.st-ba__side figcaption{font-size:.9rem;line-height:1.5;color:#666}
.st-ba__tag{
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:.5rem;
}
.st-ba__tag::before{content:"";width:7px;height:7px;border-radius:50%;flex:none}
.st-ba__tag--b{color:#8a8a8a}
.st-ba__tag--b::before{background:#c9c6bf}
.st-ba__tag--a{color:var(--accent)}
.st-ba__tag--a::before{background:var(--accent)}
/* The "before" plate is deliberately flattened — it is the thing being left
   behind, not a second thing on offer. */
.st-ba__side:first-child .st-concept__img img{filter:saturate(.72) contrast(.94)}
.st-ba__gain{
  grid-column:1 / -1;padding-top:1rem;border-top:1px solid rgba(0,0,0,.16);
  font-size:1.0625rem;line-height:1.5;color:#444;
}
.st-ba__gain b{display:block;font-family:var(--body);font-weight:600;letter-spacing:-.02em;
  font-size:1.15rem;color:#000;margin-bottom:.2rem}

/* ── "what we actually do" — four plain steps ──────────────
   Written for a dentist who has never bought advertising, so the visual
   job is one idea per row and nothing that needs a marketing word. */
.st-plain{display:grid;gap:clamp(1.75rem,3.5vw,3rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr));margin-top:clamp(1rem,2vw,2rem)}
.st-plain__n{font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;color:var(--accent)}
.st-plain__img{aspect-ratio:16/10;overflow:hidden;background:#141414;margin:.9rem 0 1.1rem;border-radius:2px}
.st-plain__img img{width:100%;height:100%;object-fit:cover}
.st-plain h3{font-family:var(--body);font-weight:600;letter-spacing:-.025em;line-height:1.15;
  font-size:clamp(1.2rem,1.05rem + .7vw,1.6rem);margin:.85rem 0 .5rem}
.st-plain p{color:#a9a9a9;font-size:1rem;line-height:1.55}

/* ── the funnel ────────────────────────────────────────────
   A table rendered as bars: ordered stages, one unit (people) on one
   axis, values direct-labelled, and the markup is a real <table> so the
   numbers are readable without seeing the bars at all.
   Ordinal terracotta ramp #F2C0A0 -> #E29268 -> #D2703F, validated against
   this act's #000 surface (monotone L, gaps >= .06, light end 6.13:1). */
/* Not a <table>: app.css puts min-width:34rem on every table, which shoved the
   value column off a 390px screen. A grid reflows instead — label and number on
   one line, the bar taking the full width beneath them on narrow viewports.
   Every value is visible text next to its label, so the numbers read with the
   bars ignored entirely. */
.st-fn{margin-top:clamp(1.5rem,3vw,2.5rem)}
.st-fn__cap{font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;
  text-transform:uppercase;color:#8d8d8d;margin-bottom:1.1rem}
.st-fn__row{
  display:grid;gap:.5rem 1.25rem;align-items:center;padding:.9rem 0;
  grid-template-columns:minmax(0,15rem) 1fr auto;
}
.st-fn__row + .st-fn__row{border-top:1px solid rgba(255,255,255,.12)}
.st-fn__lbl{font-size:1.0625rem;line-height:1.35;color:#fff}
.st-fn__track{min-width:0}
.st-fn__bar{height:14px;border-radius:0 4px 4px 0;display:block}
.st-fn__num{
  font-weight:600;letter-spacing:-.03em;font-size:clamp(1.5rem,1.2rem + 1vw,2.1rem);
  color:#fff;text-align:right;min-width:2.5ch;
}
@media (max-width:44rem){
  .st-fn__row{grid-template-columns:1fr auto}
  .st-fn__track{grid-column:1 / -1;order:2}
}

.st-sum{display:grid;gap:clamp(1rem,2.5vw,2rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,13rem),1fr));
  margin-top:clamp(2rem,4vw,3rem);padding-top:1.75rem;border-top:1px solid rgba(255,255,255,.16)}
.st-sum div b{display:block;font-family:var(--body);font-weight:600;letter-spacing:-.045em;line-height:.95;
  font-size:clamp(2rem,1.4rem + 2.2vw,3.2rem)}
.st-sum div span{display:block;margin-top:.5rem;font-size:.9375rem;color:#8d8d8d;line-height:1.4}
.st-sum .out b{color:var(--accent)}
.st-assume{margin-top:clamp(1.75rem,3vw,2.5rem);padding-left:clamp(1rem,2vw,1.5rem);
  border-left:2px solid rgba(255,255,255,.22);max-width:62ch;font-size:.9375rem;line-height:1.6;color:#8d8d8d}
.st-assume b{color:#fff;font-weight:600}

/* plain-English line on each package, above the feature list.
   The extra row means the slack has to move: .st-tier's default rows put
   the 1fr on the sentence, which would stretch it and unalign the buttons. */
.st-tier--plain{grid-template-rows:auto auto auto auto 1fr auto}
.st-tier__plain{color:#fff;font-size:1.0625rem;line-height:1.45}
.st-tier--plain .st-tier__s{color:#9a9a9a;font-size:.9375rem}

/* the fit list, set against the closing act */
.st-fit{display:grid;gap:.9rem;list-style:none;padding:0;margin-top:clamp(1.5rem,3vw,2.25rem);max-width:44ch;text-align:left}
.st-fit li{display:grid;grid-template-columns:1.1em 1fr;gap:.7em;font-size:1.0625rem;line-height:1.45}
.st-fit li::before{content:"";width:.5em;height:.5em;margin-top:.55em;border-radius:50%;background:var(--wa)}
.st-end--light .st-fit li{color:#444}
.st-alt{margin-top:1.25rem}

@media (max-width:60rem){
  .st-rules li{grid-template-columns:2.6rem 1fr}
}

/* ---------- studio loader ---------- */
.sldr{display:none}
html.intro .sldr{
  display:block;position:fixed;inset:0;z-index:200;background:#fff;
  animation:sldr-out 620ms var(--ease) 760ms forwards;
}
html.intro .sldr__corners span{
  position:absolute;padding:clamp(1rem,2.5vw,2rem);color:#000;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
}
html.intro .sldr__corners span:nth-child(1){top:0;left:0}
html.intro .sldr__corners span:nth-child(2){top:0;right:0}
html.intro .sldr__corners span:nth-child(3){bottom:0;left:0}
html.intro .sldr__corners span:nth-child(4){bottom:0;right:0}
html.intro .sldr__mark{
  position:absolute;left:50%;top:50%;width:min(70vh,70vw);color:var(--accent);
  translate:-50% -50%;rotate:-12deg;
  animation:sldr-sweep 1180ms var(--ease-in-out) forwards;
}
html.intro .sldr__mark path{stroke-dasharray:1;stroke-dashoffset:1;animation:sldr-draw 760ms var(--ease-in-out) forwards}
@keyframes sldr-draw{to{stroke-dashoffset:0}}
@keyframes sldr-sweep{
  0%{transform:translate(-42%,12%) scale(1.15)}
  100%{transform:translate(38%,-10%) scale(1.15)}
}
@keyframes sldr-out{to{transform:translateY(-101%);visibility:hidden}}

/* The page runs its own full-bleed grammar; the shared chrome would
   fight it, so the sticky mobile CTA and the body padding step aside.
   Except on a niche page: /studio is a showcase and can afford to send you
   looking for the button, but /direct/* is where paid clicks land, and most
   South African traffic is a thumb on a phone. There the bar stays. */
body:has(.st-open):not(.direct) .sticky{display:none}
body:has(.st-open){padding-bottom:0}
@media (max-width:60rem){ body.direct:has(.st-open){padding-bottom:5rem} }

/* ============================================================
   Grammar override — the site-wide backdrop replaces the acts.

   This file began as the /studio showcase stylesheet, where the argument was
   made in hard white-to-black cuts. That page is gone and its grammar with it:
   every page now shares one fixed backdrop, so an act painting itself #fff or
   #000 punches a flat rectangle through it.

   The component rules above still earn their place — the before/after plates,
   the funnel, the numbered rules, the plain-language steps are all specific to
   these pages and would be dead weight in the main stylesheet. What follows
   re-dresses their surfaces onto the shared system rather than rewriting them.
   ============================================================ */

.st-open, .st-stage, .st-work, .st-end, .st-end--light,
.st-light, .st-dark, .st-band, .st-rail, .st-rail--light,
.st-price, .st-quotes-act {
  background: transparent;
  color: var(--text);
}

/* Sections stop being full-bleed acts and become measured columns, so the
   backdrop reads down both sides the way it does on every other page. */
.st-act-pad {
  padding: clamp(3rem, 7vw, 6.5rem) var(--gut);
  max-width: var(--max);
  margin-inline: auto;
}
.st-open {
  min-height: 0;
  padding: clamp(4rem, 9vw, 7rem) var(--gut) clamp(3rem, 6vw, 5rem);
  max-width: var(--max);
  margin-inline: auto;
}
.st-open__h {
  font-family: var(--display);
  font-weight: 300;
  letter-spacing: -0.038em;
  line-height: 1.02;
  font-size: clamp(2.6rem, 1rem + 6.4vw, 6rem);
  text-wrap: balance;
  color: var(--paper);
}
.st-open__sub { color: var(--text-dim); max-width: 44ch; }
.st-open__note, .st-cue { color: var(--text-faint); }

.st-head h2 { color: var(--paper); }
.st-light .st-head p, .st-dark .st-head p, .st-head p { color: var(--text-dim); }
.st-label, .st-kicker { color: var(--accent); }

/* Panels take the shared surface: translucent, large radius, the backdrop
   glowing faintly through. */
.st-concept, .st-fig, .st-plain, .st-quote, .st-band, .st-fn,
.st-sum, .st-assume, .st-tier, .st-ba__side, .st-rail {
  background: var(--surface);
  backdrop-filter: blur(14px);
  border: 1px solid oklch(100% 0 0 / 0.055);
  border-radius: var(--rad-panel);
}
.st-tier--pop { border-color: oklch(58% 0.15 42 / 0.45); }

.st-concept__img, .st-plain__img, .st-fig img, .st-ba__side img {
  border-radius: calc(var(--rad-panel) - 8px);
  overflow: hidden;
}

/* The white-act text colours were written against #fff and are unreadable on
   the backdrop. Everything inherits from the tokens instead. */
.st-light, .st-light p, .st-light li, .st-end--light, .st-end--light p { color: var(--text); }
.st-light strong, .st-light b, .st-end--light strong, .st-end--light b { color: inherit; }
.st-end--light .st-end__foot { color: var(--text-faint); }
.st-end--light .btn--ghost { --fg: var(--text); border-color: oklch(100% 0 0 / 0.14); }
.st-end--light .btn--ghost:hover { --bg: oklch(100% 0 0 / 0.05); border-color: oklch(100% 0 0 / 0.3); }
.st-end__h { color: var(--paper); font-weight: 350; letter-spacing: -0.032em; }

/* Corner micro-labels belonged to a full-bleed act. In a measured column they
   collide with the content, so they go. */
.st-corners { display: none; }

/* The preview banner must stay loud — it is the only thing separating sample
   content from a claim. */
.st-preview { background: oklch(48% 0.18 27); color: #fff; }

/* Ghost buttons were coloured for a white act — black text on what is now a
   dark backdrop, i.e. invisible. The hero's secondary call to action was
   unreadable until this. */
.st-open .btn--ghost, .st-light .btn--ghost, .st-rail--light .btn--ghost {
  --fg: var(--text);
  border-color: oklch(100% 0 0 / 0.14);
}
.st-open .btn--ghost:hover, .st-light .btn--ghost:hover, .st-rail--light .btn--ghost:hover {
  --bg: oklch(100% 0 0 / 0.05);
  border-color: oklch(100% 0 0 / 0.3);
}

/* Without the pinned stage these acts are ordinary blocks, and the padding
   that framed a full-screen sentence now leaves a screen of nothing under it. */
.st-stage { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.st-stage__acts { display: grid; gap: 1.25rem; }
.st-act { padding-inline: var(--gut); }
