/* ============================================================
   Reply Wizard, 2026 rebuild.
   Palette derived from the extension's own icon (#43C08D / #1A8A67),
   deliberately pushed off WhatsApp's #25D366 so the page never reads
   as an official Meta property.
   ============================================================ */
/* ------------------------------------------------------------
   Fonts, served from this origin.

   They used to come from fonts.googleapis.com, which cost a render-blocking stylesheet on
   a third-party origin before either font file could even be discovered. Self-hosted they
   are preloaded from the same connection as the page, and the CSP no longer has to name
   two Google hosts.

   They sit at /fonts, not under /assets, because a font file is the ONE asset here whose
   name changes when its content does, so it is the one that can be cached immutably for a
   year. Cloudflare Pages applies every matching _headers rule and concatenates them, so a
   /fonts/* rule nested inside /assets/* produced a single header reading
   "max-age=31536000, immutable, public, max-age=86400". Separate paths, separate rules.

   Both are the LATIN subset only, and both are variable fonts cut down to the weights this
   site actually uses: Bricolage 500 to 800 (77KB to 69KB), Public Sans 400 to 700 (27KB to
   24KB). Bricolage KEEPS its optical-size axis, which costs 32KB and is worth it: pinning
   opsz widens the letterforms at display sizes, and the hero headline is then wide enough
   to wrap onto a third line, which is the one thing the reserved height cannot absorb.

   font-display is `optional`, not `swap`, and that is the whole reason the page scores no
   layout shift from type. `swap` re-flows every line the moment the webfont arrives, which
   is a real shift for a real visitor. `optional` gives the browser a short block period:
   the font is used if it arrived, and if it did not, this page load stays on the fallback
   and never swaps mid-read. Preloading is what makes the first branch the usual one.
   ------------------------------------------------------------ */
@font-face{
  font-family:"Bricolage Grotesque";
  font-style:normal; font-weight:500 800; font-display:optional;
  src:url(/fonts/bricolage-grotesque-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:"Public Sans";
  font-style:normal; font-weight:400 700; font-display:optional;
  src:url(/fonts/public-sans-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root{
  color-scheme:light;
  --paper:#F5F7F4; --paper-2:#EBEFE9; --card:#FFFFFF; --line:#DCE3DC;
  --text:#111A17; --text-2:#4F615B; --text-3:#5C6E67;
  --brand:#0F6E51; --brand-hover:#0B5741; --brand-ink:#FFFFFF;
  --mint-soft:#DDF0E7; --mint-line:#B6DFCB;
  --amber:#9A5510; --amber-soft:#F7E8D6;
  --danger:#B42318; --danger-soft:#FDECEA; --danger-line:#F1C4BF;
  --tint:#E4EDE7; --tint-line:#CFDED4;
  --tint-warm:#F7EEE0; --tint-warm-line:#EADCC6;
  --ink-block:#0E2A22; --on-ink:#F2F8F4; --on-ink-2:#B7CFC5;
  --ring:#0F6E51;
  --shadow:0 1px 2px rgba(11,21,18,.05), 0 8px 24px -12px rgba(11,21,18,.18);
  --r:14px; --r-sm:9px;
  --measure:66ch; --wrap:1120px;
  --step:clamp(2.6rem, 4.4vw, 4.2rem);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --paper:#0B1512; --paper-2:#101E1A; --card:#12211D; --line:#22352F;
    --text:#EAF2EE; --text-2:#A3B5AE; --text-3:#7E918B;
    --brand:#43C08D; --brand-hover:#5BD1A2; --brand-ink:#062018;
    --mint-soft:#15302A; --mint-line:#27554A;
    --amber:#E5A465; --amber-soft:#2D2117;
    --danger:#FF8A7A; --danger-soft:#3A1714; --danger-line:#6B2A22;
    --tint:#0F1F1A; --tint-line:#1E332C;
    --tint-warm:#1B1710; --tint-warm-line:#33291B;
    --ink-block:#123027; --on-ink:#EAF2EE; --on-ink-2:#A3B5AE;
    --ring:#43C08D;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 10px 30px -14px rgba(0,0,0,.7);
  }
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#0B1512; --paper-2:#101E1A; --card:#12211D; --line:#22352F;
  --text:#EAF2EE; --text-2:#A3B5AE; --text-3:#7E918B;
  --brand:#43C08D; --brand-hover:#5BD1A2; --brand-ink:#062018;
  --mint-soft:#15302A; --mint-line:#27554A;
  --amber:#E5A465; --amber-soft:#2D2117;
  --danger:#FF8A7A; --danger-soft:#3A1714; --danger-line:#6B2A22;
  --tint:#0F1F1A; --tint-line:#1E332C;
  --tint-warm:#1B1710; --tint-warm-line:#33291B;
  --ink-block:#123027; --on-ink:#EAF2EE; --on-ink-2:#A3B5AE;
  --ring:#43C08D;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 10px 30px -14px rgba(0,0,0,.7);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-padding-top:5.2rem}
body{
  margin:0; background:var(--paper); color:var(--text);
  font-family:"Public Sans",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:17px; line-height:1.65; font-synthesis-weight:none;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{
  font-family:"Bricolage Grotesque","Public Sans",ui-sans-serif,system-ui,sans-serif;
  font-weight:700; line-height:1.08; letter-spacing:-.02em;
  text-wrap:balance; margin:0;
}
h1{font-size:clamp(2.4rem,5.6vw,4.1rem); font-weight:800; letter-spacing:-.035em}
h2{font-size:clamp(1.85rem,3.6vw,2.7rem)}
h3{font-size:1.14rem; letter-spacing:-.012em}
p{margin:0}
a{color:inherit}
img,svg{display:block; max-width:100%}
img{height:auto}
ul{margin:0; padding:0; list-style:none}
[hidden]{display:none !important}
b,strong{font-weight:700}
:focus-visible{outline:2.5px solid var(--ring); outline-offset:3px; border-radius:4px}

.wrap{width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:clamp(1.15rem,4vw,2rem)}
.prose{max-width:var(--measure)}
.eyebrow{
  font-size:.775rem; font-weight:700; letter-spacing:.13em; text-transform:uppercase;
  color:var(--brand); margin:0 0 .9rem;
}
.lede{font-size:clamp(1.06rem,1.7vw,1.24rem); color:var(--text-2); line-height:1.6}

.skip{
  position:absolute; left:-9999px; top:0; z-index:99;
  background:var(--brand); color:var(--brand-ink); padding:.7rem 1.1rem; border-radius:0 0 var(--r-sm) 0;
  font-weight:600;
}
.skip:focus{left:0}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.55rem;
  font:inherit; font-weight:600; text-decoration:none; cursor:pointer;
  padding:.78rem 1.35rem; border-radius:var(--r-sm); border:1.5px solid transparent;
  transition:background-color .16s ease, border-color .16s ease, color .16s ease;
  white-space:nowrap;
}
.btn-primary{background:var(--brand); color:var(--brand-ink); border-color:var(--brand)}
.btn-primary:hover{background:var(--brand-hover); border-color:var(--brand-hover)}
.btn-ghost{background:transparent; color:var(--text); border-color:var(--line)}
.btn-ghost:hover{border-color:var(--text-3); background:var(--paper-2)}
.btn-sm{padding:.52rem 1rem; font-size:.93rem}
/* The Chrome mark keeps its own colours in both themes, which is the point of it. */
.chrome-mark{flex:none; width:18px; height:18px}
.btn-sm .chrome-mark{width:16px; height:16px}
.site-footer .chrome-mark{width:14px; height:14px; display:inline-block; vertical-align:-2px; margin-right:.3rem}
.btn-wide{width:100%}

/* ---------- header ---------- */
.site-header{
  position:sticky; top:0; z-index:40;
  background:color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter:saturate(1.5) blur(10px);
  border-bottom:1px solid var(--line);
}
.header-in{display:flex; align-items:center; gap:1.4rem; height:66px}
.brand{display:flex; align-items:center; gap:.6rem; text-decoration:none; font-weight:700; letter-spacing:-.02em; font-size:1.06rem}
.brand svg{flex:none}
/* The product mark. border-radius is on the element as well as in the artwork, so the
   corners stay clean if the file is ever swapped for a square one. */
.brand-mark{flex:none; border-radius:7px}
.site-footer .brand-mark{border-radius:6px}
.site-nav{display:none; gap:1.6rem; margin-left:auto; font-size:.95rem; font-weight:500}
.site-nav a{text-decoration:none; color:var(--text-2)}
.site-nav a:hover{color:var(--text)}
.header-cta{margin-left:auto}
@media (min-width:860px){
  .site-nav{display:flex}
  .header-cta{margin-left:0}
}

/* The menu button (site-header.js), below the width where the links fit inline. The links open
   as a panel under the sticky header, so the page never jumps. */
.nav-toggle{display:inline-flex; align-items:center; justify-content:center; flex:none; width:44px; height:44px;
  margin-right:-6px; border:0; border-radius:10px; background:none; color:var(--text); cursor:pointer}
.nav-toggle:hover{background:var(--paper-2)}
.nav-toggle:focus-visible{outline:2px solid var(--ring); outline-offset:2px}
.nav-toggle path{transition:transform .18s ease, opacity .18s ease; transform-origin:12px 12px}
.site-header.nav-open .nav-toggle .l0{transform:translateY(5px) rotate(45deg)}
.site-header.nav-open .nav-toggle .l1{opacity:0}
.site-header.nav-open .nav-toggle .l2{transform:translateY(-5px) rotate(-45deg)}
@media (max-width:859px){
  .site-header.nav-open .site-nav{display:flex; flex-direction:column; gap:0; position:absolute; left:0; right:0; top:100%;
    margin:0; padding:.5rem clamp(1.15rem,4vw,2rem) 1rem; background:var(--paper); border-bottom:1px solid var(--line);
    box-shadow:0 18px 30px -24px rgba(11,21,18,.45); font-size:1.02rem}
  .site-header.nav-open .site-nav a{min-height:48px; display:flex; align-items:center; border-bottom:1px solid var(--line); color:var(--text)}
  .site-header.nav-open .site-nav a:last-child{border-bottom:0}
}
@media (min-width:860px){ .nav-toggle{display:none} }
/* On a phone the call to action becomes the Chrome mark alone: brand, account, the mark and the
   menu button fit a 360px screen, and the words stay the button's accessible name (font-size 0
   hides them from sight, not from a screen reader). A phone cannot install an extension anyway. */
@media (max-width:520px){
  .site-header .header-cta{font-size:0; gap:0; width:44px; height:44px; min-height:44px; padding:0; border-radius:50%}
  .site-header .header-cta .chrome-mark{width:22px; height:22px}
}
@media (prefers-reduced-motion:reduce){ .nav-toggle path{transition:none} }

/* The My account icon (account-menu.js). It sits between the menu and Add to Chrome; on a
   phone, where the menu is hidden, it takes the auto margin so the CTA keeps its place. */
.acct-link{display:inline-flex; align-items:center; justify-content:center; position:relative;
  width:40px; height:40px; border-radius:50%; border:1px solid var(--line); background:var(--card);
  color:var(--text-2); cursor:pointer; padding:0; text-decoration:none; flex:none}
.acct-link:hover,.acct-link[aria-expanded="true"],.acct-link[aria-current="page"]{color:var(--brand); border-color:var(--mint-line)}
.acct-link:focus-visible{outline:2px solid var(--ring); outline-offset:2px}
.acct-link.is-signed-in::after{content:""; position:absolute; right:1px; bottom:1px; width:10px; height:10px;
  border-radius:50%; background:var(--brand); border:2px solid var(--paper)}
.acct-label{display:none}
/* Signed out on a wide screen: the icon and the words "Sign in", as one pill. */
@media (min-width:860px){
  .acct-link:has(.acct-label){width:auto; gap:.45rem; padding:0 .95rem 0 .7rem; border-radius:999px;
    font-weight:600; font-size:.92rem; line-height:1}
  .acct-link:has(.acct-label) .acct-label{display:inline}
}
.acct-menu{position:relative; flex:none; margin-left:auto}
.site-header .acct-link:not(.acct-menu .acct-link){margin-left:auto}
.acct-menu + .header-cta,.acct-link + .header-cta{margin-left:0}
@media (min-width:860px){
  .acct-menu,.site-header .acct-link:not(.acct-menu .acct-link){margin-left:0}
}
.acct-panel{position:absolute; right:0; top:calc(100% + 10px); z-index:50; width:min(20rem, calc(100vw - 32px));
  background:var(--card); color:var(--text); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow); padding:1rem}
/* A bridge over the 10px gap, so a pointer crossing from the icon never "leaves". */
.acct-panel::before{content:""; position:absolute; left:0; right:0; top:-11px; height:11px}
.acct-pop-title{margin:0 0 .6rem; font-weight:700; font-size:1rem}
/* The sign-in form (signin.js), in the header panel and on /account alike. */
.si{display:grid; gap:.55rem; width:100%}
.si [hidden]{display:none}
.si-label{font-size:.9rem; font-weight:600; color:var(--text-2)}
.si-compact .si-label{font-size:.85rem}
.si input{width:100%; min-height:44px; padding:.5rem .75rem; font:inherit; color:var(--text);
  background:var(--paper); border:1px solid var(--line); border-radius:var(--r-sm)}
.si input:focus-visible{outline:2px solid var(--ring); outline-offset:1px}
.si input[inputmode="numeric"]{letter-spacing:.3em; font-variant-numeric:tabular-nums; font-size:1.1rem}
.si-code{display:grid; gap:.55rem; padding-top:.35rem; border-top:1px dashed var(--line); margin-top:.2rem}
.si-sent,.si-resend-row,.si-note{margin:0; font-size:.85rem; color:var(--text-2)}
.si-note{color:var(--text-3); font-size:.82rem}
.si:not(.si-compact) .si-note{display:none}  /* /account says it in its own lede */
.si-resend{border:0; background:none; padding:0; font:inherit; font-weight:600; color:var(--brand); text-decoration:underline; cursor:pointer}
.si-resend:disabled{color:var(--text-3); text-decoration:none; cursor:default}
.si-timer{font-variant-numeric:tabular-nums; color:var(--text-3)}
.si .acct-status:empty{display:none}
.si:not(.si-compact) .si-send,.si:not(.si-compact) .si-signin{justify-self:start}
.acct-panel .acct-status:empty{display:none}
@media (max-width:600px){
  /* On a phone the panel spans the screen under the header rather than hanging off an icon. */
  .acct-panel{position:fixed; left:16px; right:16px; top:calc(66px + env(safe-area-inset-top, 0px) + 6px); width:auto}
  .acct-panel::before{display:none}
}

/* ============================================================
   THE HERO DEMO
   A WhatsApp Web window drawn in HTML and CSS, playing six scenes.
   No video, no GIF, no raster image: it stays sharp at any size,
   follows the visitor's theme, and the whole thing is under 12KB.
   ============================================================ */

.hero{padding:clamp(2.8rem,6vw,4.5rem) 0 clamp(2.5rem,5vw,4rem)}
.hero-copy{max-width:58ch; margin-bottom:clamp(2.4rem,5vw,3.4rem)}
.hero h1 em{font-style:normal; color:var(--brand)}
/* Both slots are TOP-aligned and both are pinned to the height of the tallest variant.
   Top alignment is what makes the rotating headline cost nothing in layout shift: a line
   added as the text types, or a taller headline replacing a shorter one, appears BELOW
   what is already painted, so no pixel that has been drawn ever moves. Bottom alignment
   reads slightly better on a single frame and pushes every earlier line upward on every
   change, which measured 0.25 of layout shift on its own.

   text-wrap is greedy here, not balanced. Balancing re-flows the whole line every time a
   character arrives, so the same word lands on a different line from one keystroke to the
   next; greedy wrapping means a prefix always breaks exactly where the finished line
   breaks it. */
.h1-slot{display:flex; align-items:flex-start}
.lede-slot{display:flex; align-items:flex-start}
#heroH1{text-wrap:normal}
/* Below 400px the type stops being a fixed 2.4rem and tracks the viewport instead, so the
   ratio of line width to font size stays what it is at 400px. Without this there is a
   10px-wide band around 390px, which is the iPhone 14 and 15, where three of the six
   headlines wrap to three lines and the other three wrap to two: the reserved height is
   then a line taller than most headlines need and half of them sit over a gap. The
   expression is continuous at 400px, so there is no jump at the boundary. */
@media (max-width:400px){
  #heroH1{font-size:calc(10.44vw - 3.34px)}
}
/* The sub-line swaps at once rather than fading behind the headline, so the reader has
   the explanation while the words above are still being typed. No transition: a fade,
   however short, is exactly the delay that was removed. */

/* The caret, while the line is arriving. It is an ::after on the h1 rather than a
   character in the text, so it never ends up in a copied selection, in the accessible
   name, or in the reserved height. */
#heroH1.is-typing::after{
  content:""; display:inline-block; width:.06em; height:.82em;
  vertical-align:-.06em;
  /* Net advance zero. The caret sits in the space the (invisible) trailing dots are
     already holding, so it adds no width of its own. Given real width it pushed the
     dots onto a line of their own for the last few characters of the longer headlines,
     and the line count is what the reserved height is built on. */
  margin-left:.06em; margin-right:-.12em;
  background:var(--brand); animation:caret 1s steps(1) infinite;
}
@keyframes caret{0%,49%{opacity:1} 50%,100%{opacity:0}}

/* The two dots, once it has arrived. They are the signal that this headline is one of
   several and that another is coming, which a caret alone does not say. They hold their
   width at every moment, including while the caret has them hidden mid-type, so nothing
   reflows when they blink. Hidden from the accessible name: they are punctuation for the
   eye, and a screen reader announcing "dot dot" after every headline is noise. */
.head-dots{color:var(--brand); animation:dots 1.15s steps(1) infinite}
#heroH1.is-typing .head-dots{opacity:0; animation:none}
@keyframes dots{0%,55%{opacity:1} 56%,100%{opacity:.14}}

@media (prefers-reduced-motion:reduce){
  #heroH1.is-typing::after{display:none}
  .head-dots{animation:none}
}
.hero .lede{margin-top:1.35rem; max-width:52ch}
.hero-actions{display:flex; flex-wrap:wrap; gap:.7rem; margin-top:2rem}
.hero-note{margin-top:1.1rem; font-size:.9rem; color:var(--text-3); display:flex; align-items:flex-start; gap:.45rem}
.hero-note svg{flex:none; margin-top:.32em}

.stage{margin:0}

/* ---------- the window ---------- */
.wa{
  border:1px solid var(--line); border-radius:var(--r); overflow:hidden;
  background:var(--card); box-shadow:var(--shadow);
  container-type:inline-size;
}
.wa-chrome{
  display:flex; align-items:center; gap:.45rem;
  padding:.55rem .8rem; border-bottom:1px solid var(--line); background:var(--paper-2);
}
.wa-dot{width:9px; height:9px; border-radius:50%; background:var(--line); flex:none}
.wa-url{
  margin-left:.55rem; font-size:.75rem; color:var(--text-3);
  font-weight:600; letter-spacing:.01em;
}
.wa-ext{
  margin-left:auto; display:inline-flex; align-items:center; gap:.35rem;
  font-size:.72rem; font-weight:700; color:var(--brand);
  border:1px solid var(--mint-line); background:var(--mint-soft);
  border-radius:999px; padding:.16rem .55rem .16rem .38rem;
  transition:box-shadow .3s ease;
}
.wa-ext.is-lit{box-shadow:0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent)}

.wa-body{display:grid; grid-template-columns:minmax(0,1fr); min-height:24rem}
@container (min-width: 720px){
  .wa-body{grid-template-columns:15.5rem minmax(0,1fr); min-height:28rem}
}
/* Desktop gets a genuinely large window: at 980px and up the whole mock scales up rather
   than just getting wider, so the conversation reads at a comfortable size instead of
   looking like a thumbnail of itself. */
@container (min-width: 980px){
  .wa-body{grid-template-columns:18rem minmax(0,1fr); min-height:36rem}
  .wa-thread{padding:1.4rem 1.3rem; gap:.6rem; min-height:20rem}
  .wa-msg{font-size:.94rem; padding:.6rem .85rem .38rem; border-radius:13px; max-width:min(80%,32rem)}
  .wa-stamp{font-size:.68rem}
  .wa-head{padding:.8rem 1.15rem}
  .wa-headtext b{font-size:.98rem}
  .wa-headtext i{font-size:.78rem}
  .wa-av{width:2.4rem; height:2.4rem; font-size:.78rem}
  .wa-rowtext b{font-size:.9rem}
  .wa-rowtext i{font-size:.82rem}
  .wa-row{padding:.62rem .65rem; gap:.65rem}
  .wa-time{font-size:.72rem}
  .wa-composer{margin:0 1.3rem; padding:.62rem .85rem}
  .wa-input{font-size:.94rem}
  .rw-bar{padding:.8rem 1.3rem 1rem; gap:.5rem}
  .rw-cta{font-size:.85rem; padding:.36rem .95rem}
  .rw-out{font-size:.85rem}
  .rw-ic{width:1.6rem; height:1.6rem}
  .rw-icons{gap:.5rem}
  .rw-pill{padding:.75rem .95rem; max-width:min(88%,36rem)}
  .rw-pill-body{font-size:.92rem}
  .rw-pill-head{font-size:.7rem}
  .rw-pill-tools span{font-size:.74rem; padding:.2rem .5rem}
  .rw-mcp{padding:.8rem .95rem; max-width:min(88%,36rem)}
  .rw-mcp-q,.rw-mcp-a{font-size:.92rem}
  .rw-mcp-tool{font-size:.78rem}
  .wa-chrome{padding:.7rem 1rem}
  .wa-url{font-size:.82rem}
  .wa-ext{font-size:.78rem}
  .wa-voice{padding:.65rem .85rem}
  .wa-play{width:1.9rem; height:1.9rem}
  .wave{height:1.4rem}
  .wa-dur{font-size:.76rem}
}

/* ---------- left pane ---------- */
.wa-side{
  display:none; border-right:1px solid var(--line); background:var(--paper);
  padding:.7rem .55rem; min-width:0;
}
@container (min-width: 720px){ .wa-side{display:block} }
.wa-search{
  height:1.85rem; border-radius:999px; background:var(--paper-2);
  border:1px solid var(--line); margin-bottom:.55rem; display:flex; align-items:center; padding:0 .7rem;
}
.wa-search span{display:block; height:.4rem; width:52%; border-radius:3px; background:var(--line)}
.wa-list{display:grid; gap:.1rem}
.wa-row{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center;
  gap:.55rem; padding:.5rem .55rem; border-radius:9px; min-width:0;
}
.wa-row.is-active{background:var(--paper-2)}
.wa-av{
  width:2rem; height:2rem; border-radius:50%; flex:none;
  background:var(--av,#5B6B65); color:#fff;
  display:grid; place-items:center; font-size:.68rem; font-weight:700; letter-spacing:.02em;
}
.wa-rowtext{display:grid; gap:.1rem; min-width:0}
.wa-rowtext b{
  font-size:.82rem; font-weight:600; color:var(--text);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.wa-rowtext i{
  font-style:normal; font-size:.75rem; color:var(--text-3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.wa-meta{display:grid; justify-items:end; gap:.2rem; align-self:start}
.wa-time{font-size:.66rem; color:var(--text-3); font-variant-numeric:tabular-nums; white-space:nowrap}
.wa-badge{
  font-size:.62rem; font-weight:700; color:var(--brand-ink);
  background:var(--brand); border-radius:999px; padding:.05rem .35rem;
}

/* Privacy blur. The real extension applies filter: blur(6px) to the chat rows and
   reveals a row on hover; this reproduces both, including the hover. */
.wa-blurable{transition:filter .28s ease}
.wa.blur-left .wa-side .wa-blurable{filter:blur(5px)}
/* Right-pane blur covers the message bodies as well as the header name, because that is
   what `body.gpt-blur-right #main div[role="row"]` does in the extension. Blurring only
   the contact name would demonstrate a feature the product does not have. */
.wa.blur-right .wa-main .wa-blurable,
.wa.blur-right .wa-thread .wa-msg p,
.wa.blur-right .wa-thread .rw-pill-body{filter:blur(5px); transition:filter .28s ease}
.wa.blur-left .wa-side .wa-row:hover .wa-blurable{filter:none}
.wa.blur-right .wa-thread .wa-msg:hover p,
.wa.blur-right .wa-main .wa-head:hover .wa-blurable{filter:none}

/* ---------- right pane ---------- */
.wa-main{display:flex; flex-direction:column; min-width:0; background:var(--paper)}
.wa-head{
  display:flex; align-items:center; gap:.6rem;
  padding:.6rem .85rem; border-bottom:1px solid var(--line); background:var(--card);
}
.wa-headtext{display:grid}
.wa-headtext b{font-size:.86rem; font-weight:600}
.wa-headtext i{font-style:normal; font-size:.7rem; color:var(--text-3)}

.wa-thread{
  flex:1; display:flex; flex-direction:column; justify-content:flex-end; gap:.45rem;
  padding:.9rem .85rem; overflow:hidden; min-height:11rem;
}
.wa-msg{
  max-width:min(88%,26rem); border-radius:11px; padding:.45rem .65rem .3rem;
  font-size:.82rem; line-height:1.5; position:relative;
  border:1px solid var(--line); background:var(--card);
  opacity:0; transform:translateY(6px);
  transition:opacity .32s ease, transform .32s ease;
}
.wa-msg.is-on{opacity:1; transform:none}
.wa-msg p{margin:0; color:var(--text)}
.wa-msg.out{align-self:flex-end; background:var(--mint-soft); border-color:var(--mint-line)}
/* text-2, not text-3. On the outgoing bubble's mint ground in dark mode text-3 measures
   4.24:1, under the 4.5:1 this size needs; text-2 is 6.57:1 there and still reads as a
   timestamp rather than as content. */
.wa-stamp{
  display:block; text-align:right; font-size:.62rem; color:var(--text-2);
  margin-top:.12rem; font-variant-numeric:tabular-nums;
}
.wa-stamp b{color:var(--brand); font-weight:700}

.wa-voice{display:flex; align-items:center; gap:.5rem; padding:.5rem .65rem}
.wa-play{
  width:1.6rem; height:1.6rem; border-radius:50%; flex:none;
  background:var(--brand); color:var(--brand-ink); display:grid; place-items:center;
}
.wave{display:flex; align-items:center; gap:2px; height:1.15rem; flex:1; min-width:5rem}
.wave i{display:block; width:2px; border-radius:2px; background:var(--brand); opacity:.4}
.wa-voice.is-playing .wave i{animation:pulse 1.35s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:.3} 50%{opacity:.9}}
.wa-dur{font-size:.68rem; color:var(--text-2); font-weight:600; font-variant-numeric:tabular-nums; flex:none}
.wa-voice .wa-stamp{position:absolute; right:.65rem; bottom:.05rem}

/* transcript / summary pill */
.rw-pill{
  border:1px solid var(--mint-line); background:var(--mint-soft);
  border-radius:11px; padding:.55rem .7rem; max-width:min(94%,30rem);
  display:none;
}
.rw-pill.is-on{display:block; animation:rise .3s ease both}
@keyframes rise{from{opacity:0; transform:translateY(7px)} to{opacity:1; transform:none}}
.rw-pill-head{
  display:flex; align-items:center; gap:.35rem; margin:0 0 .3rem;
  font-size:.63rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--brand);
}
.rw-pill-body{margin:0; font-size:.8rem; line-height:1.55; color:var(--text); min-height:1.2em}
.rw-pill-body ul{margin:.2rem 0 0; display:grid; gap:.15rem}
.rw-pill-body li{display:flex; gap:.4rem}
.rw-pill-body li::before{content:"✓✓"; color:var(--brand); font-size:.7rem; letter-spacing:-.08em}
.rw-pill-tools{display:flex; flex-wrap:wrap; gap:.3rem; margin:.5rem 0 0}
.rw-pill-tools span{
  font-size:.66rem; font-weight:600; color:var(--text-2);
  border:1px solid var(--mint-line); border-radius:5px; padding:.14rem .4rem; background:var(--card);
}

/* MCP panel */
.rw-mcp{
  border:1px dashed var(--mint-line); border-radius:11px; background:var(--card);
  padding:.6rem .7rem; max-width:min(94%,30rem); display:none;
}
.rw-mcp.is-on{display:block; animation:rise .3s ease both}
.rw-mcp-head{
  display:flex; align-items:center; gap:.4rem; margin:0 0 .4rem;
  font-size:.63rem; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--text-3);
}
.rw-mcp-dot{width:6px; height:6px; border-radius:50%; background:var(--brand); flex:none}
.rw-mcp-q{margin:0; font-size:.8rem; color:var(--text); font-weight:600; min-height:1.2em}
.rw-mcp-tool{
  margin:.4rem 0 0; font-size:.68rem; color:var(--brand); font-weight:700;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; min-height:1em;
}
.rw-mcp-a{margin:.35rem 0 0; font-size:.8rem; line-height:1.5; color:var(--text-2); min-height:1.2em}

/* composer */
.wa-composer{
  display:flex; align-items:center; gap:.55rem; margin:0 .85rem;
  border:1px solid var(--line); border-radius:9px; padding:.45rem .65rem; background:var(--card);
}
.wa-plus{color:var(--text-3); font-size:1.05rem; line-height:1; flex:none}
.wa-input{flex:1; font-size:.84rem; color:var(--text); min-height:1.35em; min-width:0}
.wa-ph{color:var(--text-3)}
.wa-mic{color:var(--text-3); flex:none; display:grid; place-items:center; border-radius:50%; padding:.15rem}
.wa-mic.is-live{color:var(--brand-ink); background:var(--brand); animation:mic 1.1s ease-in-out infinite}
@keyframes mic{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--brand) 45%,transparent)} 60%{box-shadow:0 0 0 6px transparent}}

/* our bar */
.rw-bar{
  display:flex; align-items:center; gap:.4rem; flex-wrap:wrap;
  padding:.6rem .85rem .75rem; margin-top:.55rem;
}
.rw-cta{
  font:inherit; font-size:.74rem; font-weight:700; cursor:default;
  border:1px solid var(--mint-line); background:var(--mint-soft); color:var(--brand);
  border-radius:999px; padding:.28rem .7rem; white-space:nowrap;
  transition:box-shadow .18s ease, transform .18s ease;
}
.rw-cta-2{border-color:var(--line); background:transparent; color:var(--text-3)}
.rw-cta.is-hit{
  transform:translateY(1px);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--brand) 26%, transparent);
}
.rw-out{
  font-size:.74rem; color:var(--text-3); min-width:0; flex:1;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.rw-out.is-work::after{content:"…"; animation:dots 1.1s steps(4) infinite; color:var(--brand)}
@keyframes dots{0%{opacity:.25}50%{opacity:1}100%{opacity:.25}}
.rw-icons{display:flex; align-items:center; gap:.38rem; margin-left:auto; color:var(--text-3)}
.rw-ic{
  position:relative; display:grid; place-items:center; width:1.35rem; height:1.35rem;
  border-radius:5px; transition:color .18s ease, box-shadow .18s ease;
}
.rw-ic svg{width:100%; height:100%}
.rw-ic.is-hit{color:var(--brand); box-shadow:0 0 0 4px color-mix(in srgb, var(--brand) 22%, transparent)}
.rw-ic.is-on{color:var(--brand)}
.rw-badge{
  position:absolute; top:-.3rem; right:-.32rem; font-size:.52rem; font-weight:800;
  background:var(--brand); color:var(--brand-ink); border-radius:999px;
  min-width:.85rem; height:.85rem; display:grid; place-items:center; padding:0 .12rem;
}
.rw-badge:empty{display:none}
/* The user agent's [hidden] rule is HTML-namespaced, so it never matches an svg element: the
   attribute is inert there and setting the .hidden property is inert too, because that IDL
   attribute belongs to HTMLElement. The hero demo hides four svg glyphs that way, so all four
   were drawn at once and the Summary pill wore a microphone. An author rule has no namespace
   restriction. */
.wa [hidden]{display:none}

/* ---------- the rail under the window ---------- */
/* ---------- 3.5.6: a conversation per scene ----------
   The window used to hold ONE conversation, which is right for six features about one thread.
   Translation needs somebody writing in another script and Business Facts needs a customer, so
   a scene now names which conversation is open: the header, the highlighted row and the
   messages all follow, and a message from another conversation is not merely transparent but
   GONE, because a hidden bubble still takes its height in a bottom-anchored thread. */
.wa-thread [data-set].is-away{display:none}
/* Read translation: the control under a foreign bubble, in the shape "Read transcription" has.
   The glyph is ours, not a vendor's, for the reason uiStuff.js gives. */
.rw-tr-read{
  align-self:flex-start; display:none; align-items:center; gap:.3rem;
  font:inherit; font-size:.7rem; font-weight:700; color:var(--brand);
  border:1px solid var(--mint-line); background:var(--mint-soft);
  border-radius:999px; padding:.18rem .6rem .18rem .45rem; margin-top:-.15rem;
  transition:box-shadow .18s ease, transform .18s ease;
}
.rw-tr-read svg{width:.85rem; height:.85rem}
.rw-tr-read.is-on{display:inline-flex; animation:rise .3s ease both}
.rw-tr-read.is-hit{transform:translateY(1px); box-shadow:0 0 0 4px color-mix(in srgb, var(--brand) 26%, transparent)}
/* The translation lands on its own translucent panel, UNDER the original: the original is
   never replaced. Two titled halves, transliteration first, which is the order "both" uses. */
.rw-tr{
  align-self:flex-start; max-width:min(88%,26rem); display:none;
  border:1px solid var(--mint-line); border-radius:11px;
  background:color-mix(in srgb, var(--mint-soft) 78%, transparent);
  padding:.4rem .7rem .45rem;
}
.rw-tr.is-on{display:block; animation:rise .3s ease both}
.rw-tr-title{
  margin:0; font-size:.6rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--brand);
}
.rw-tr-body{margin:0 0 .25rem; font-size:.8rem; line-height:1.4; color:var(--text); min-height:1.2em}
.rw-tr-body:last-child{margin-bottom:0}
.rw-ic.is-away{display:none}
/* Business Facts: the Settings card, drawn over the window for the moment it takes to show
   what the reply will be given. It is a SETTINGS surface and says so in its own header, because
   nothing of it appears in WhatsApp: showing it inside the chat would demonstrate a panel the
   product does not have. */
.wa-main{position:relative}
.rw-sheet{
  position:absolute; left:50%; top:3.6rem; width:min(88%,24rem); translate:-50% 0;
  border:1px solid var(--line); border-radius:12px; background:var(--card);
  box-shadow:0 12px 32px -12px rgba(11,21,18,.35); padding:.7rem .8rem .75rem;
  display:none; z-index:2;
}
.rw-sheet.is-on{display:block; animation:rise .3s ease both}
.rw-sheet-head{
  display:flex; align-items:center; gap:.4rem; margin:0 0 .55rem;
  font-size:.82rem; font-weight:700; color:var(--text);
}
.rw-sheet-head svg{width:1rem; height:1rem; color:var(--brand)}
.rw-sheet-head span{
  margin-left:auto; font-size:.6rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--text-3);
}
.rw-sheet-file{display:flex; align-items:baseline; gap:.5rem; margin:0 0 .35rem}
.rw-sheet-file b{font-size:.76rem; font-weight:700; color:var(--text)}
.rw-sheet-file i{font-style:normal; font-size:.7rem; color:var(--text-3)}
.rw-sheet-rows{display:grid; gap:2px; margin:0 0 .5rem}
.rw-sheet-row{
  display:grid; grid-template-columns:minmax(0,1fr) 3.2rem 4.4rem; gap:.4rem;
  font-size:.72rem; color:var(--text-2); padding:.2rem .4rem; border-radius:5px; background:var(--paper);
  transition:background .3s ease, color .3s ease, box-shadow .3s ease;
}
.rw-sheet-row.is-match{
  background:var(--mint-soft); color:var(--text); font-weight:600;
  box-shadow:inset 0 0 0 1px var(--mint-line);
}
.rw-sheet-note{margin:0; font-size:.72rem; line-height:1.45; color:var(--text-2)}
.rw-sheet-note b{color:var(--text)}
/* Our own mic, recording. The extension's tour lights THIS one, not WhatsApp's composer mic,
   because dictation is ours; the site now does the same. */
.rw-ic.is-live{color:var(--brand-ink); background:var(--brand); border-radius:50%; animation:mic 1.1s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){ .rw-ic.is-live{animation:none} }
.stage-foot{margin-top:1.1rem}
.rail{display:flex; flex-wrap:wrap; gap:.4rem; align-items:center}
.rail-scenes{display:flex; flex-wrap:wrap; gap:.4rem; align-items:center; min-width:0}
.rail button{
  position:relative; overflow:hidden; font:inherit; font-size:.83rem; font-weight:600;
  cursor:pointer; color:var(--text-2); background:var(--card);
  border:1px solid var(--line); border-radius:999px; padding:.34rem .85rem;
  transition:color .18s ease, border-color .18s ease;
}
.rail button:hover{color:var(--text); border-color:var(--text-3)}
.rail button[aria-pressed="true"]{color:var(--brand); border-color:var(--brand)}
.rail-fill{
  position:absolute; inset:0 auto 0 0; width:0; background:var(--mint-soft);
  z-index:-1; pointer-events:none;
}
.rail button[aria-pressed="true"] .rail-fill{background:var(--mint-soft)}
.rail button{isolation:isolate}
.rail-play{margin-left:auto; display:inline-flex; align-items:center; gap:.4rem}
.rail-play svg{width:.8rem; height:.8rem}
.stage-cap{
  margin-top:.9rem; font-size:.92rem; color:var(--text-2); max-width:62ch; min-height:2.9em;
}

@media (prefers-reduced-motion: reduce){
  .wa-msg{opacity:1; transform:none; transition:none}
  .rw-pill,.rw-mcp{animation:none}
  .wave i,.wa-mic.is-live,.rw-out.is-work::after{animation:none}
  .rail-fill{display:none}
}

@media (max-width:640px){
  .wa-thread{min-height:9rem; padding:.7rem .6rem}
  .rw-bar{padding:.5rem .6rem .65rem}
  .rw-out{display:none}
  .stage-cap{min-height:4.2em}
}

/* ---------- section furniture ---------- */
section{padding-block:var(--step)}
/* Alternating bands. The page reads as a sequence of parts rather than one continuous
   slab, and the parts alternate between TWO hues, not one: a cool band that belongs to
   the green the brand is built on, and a warm sand band that sits opposite it. One tint
   on its own was too close to the paper to register as a change at all.

   Both are tokens, so both flip with the theme, and each band carries a hairline of its
   own colour family at the seam so the edge reads as deliberate rather than as a join. */
section.tint{background:var(--tint); border-block:1px solid var(--tint-line)}
section.tint-warm{background:var(--tint-warm); border-block:1px solid var(--tint-warm-line)}
/* Two banded sections in a row would otherwise draw two hairlines on the same seam. */
section.tint + section.tint-warm,
section.tint-warm + section.tint{border-top:0}
.sec-head{margin-bottom:clamp(2rem,4vw,3rem)}
.sec-head p{margin-top:.9rem}

/* ---------- at a glance table ---------- */
.tablewrap{overflow-x:auto; border:1px solid var(--line); border-radius:var(--r); background:var(--card)}
.doc-body .tablewrap{margin:1.4rem 0}
.tablewrap:focus-visible{outline:2.5px solid var(--ring); outline-offset:2px}
table{border-collapse:collapse; width:100%; min-width:460px; font-size:.96rem}
caption{text-align:left; padding:1rem 1.1rem .25rem; color:var(--text-3); font-size:.85rem}
th,td{text-align:left; padding:.78rem 1.1rem; border-bottom:1px solid var(--line); vertical-align:top}
tbody tr:last-child th, tbody tr:last-child td{border-bottom:0}
th{font-weight:600; color:var(--text-2); width:15rem}
td{color:var(--text)}

/* ---------- features ---------- */
.grid{display:grid; gap:1rem}
@media (min-width:960px){.grid-3{grid-template-columns:repeat(3,1fr)}}
.feature{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  padding:1.35rem 1.3rem 1.45rem;
}
.feature h3{margin-bottom:.5rem}
.feature p{color:var(--text-2); font-size:.96rem}
/* The feature marks carry the section visually, so they are sized to be seen: a 60px
   tile at a 26px corner radius, with the glyph at 30px inside it. */
.fmark{
  width:60px; height:60px; border-radius:18px; display:grid; place-items:center;
  background:var(--mint-soft); color:var(--brand); margin-bottom:1.15rem;
  border:1px solid var(--mint-line);
}
.fmark svg{width:30px; height:30px; stroke-width:1.7}
.feature{padding:1.6rem 1.5rem 1.7rem}
/* The seventh card would otherwise sit alone on a row of three. It takes the full row and
   goes horizontal, which suits the claim it carries. */
@media (min-width:960px){
  .feature-wide{
    grid-column:1 / -1; display:grid; grid-template-columns:auto minmax(0,1fr);
    column-gap:1.5rem; align-items:start;
  }
  .feature-wide .fmark{margin-bottom:0; grid-row:1 / span 2}
  .feature-wide h3{align-self:end; margin-bottom:.35rem}
  .feature-wide p{max-width:78ch}
}

/* ---------- shots ---------- */

/* ---------- steps (a real sequence) ---------- */
.steps{counter-reset:s; display:grid; gap:1.6rem; list-style:none; margin:0; padding:0}
@media (min-width:820px){.steps{grid-template-columns:repeat(3,1fr); gap:2rem}}
.step{counter-increment:s; padding-top:1.25rem; border-top:3px solid var(--brand)}
.step::before{
  content:counter(s,decimal-leading-zero);
  font-family:"Bricolage Grotesque",sans-serif; font-weight:800;
  font-size:clamp(3.2rem,6vw,4.6rem); line-height:.85; letter-spacing:-.05em;
  color:var(--brand); display:block; margin-bottom:.75rem;
  font-variant-numeric:tabular-nums;
}
.step h3{margin-bottom:.45rem}
.step p{color:var(--text-2); font-size:.96rem}

/* ---------- pricing ---------- */
.amt-word{font-size:1.5rem}
.foot-blurb{max-width:34ch}
/* The registered address of the company taking the payment. Small, but present on
   every page, which is what a card scheme and a merchant of record both look for. */
.foot-addr{max-width:34ch; margin-top:.85rem; font-size:.86rem; font-style:normal}
.foot-mail{margin-top:.85rem}
.band-lede{margin-top:.8rem}
.foot-brand{margin-bottom:.8rem}
.cycle{
  display:inline-flex; padding:4px; gap:2px; border:1px solid var(--line);
  border-radius:999px; background:var(--card); margin-bottom:.9rem;
}
.cycle button{
  font:inherit; font-size:.92rem; font-weight:600; cursor:pointer;
  border:0; background:transparent; color:var(--text-2);
  padding:.42rem 1.05rem; border-radius:999px; transition:background-color .15s, color .15s;
}
/* `aria-checked`, NOT `aria-pressed`.
   These were two toggle buttons once, and became one radiogroup during the accessibility
   pass: `role="radio"` + `aria-checked` is the correct pairing, and a radio never carries
   `aria-pressed`. The markup and the script were both updated; this selector was not, so
   from that day the selected pill never painted. Both buttons rendered transparent in both
   states, which reads as a toggle that does nothing even though the prices, the checkout
   links and the URL were all changing correctly underneath. Measured live 2026-09-03:
   background-color `rgba(0, 0, 0, 0)` on both, before and after the click.
   `check-site.mjs` now fails on any `[aria-*]` state this stylesheet paints that no page
   can ever be in. */
.cycle button[aria-checked="true"]{background:var(--brand); color:var(--brand-ink)}
.save{
  display:inline-block; margin-left:.7rem; font-size:.82rem; font-weight:700;
  color:var(--amber); background:var(--amber-soft); border-radius:999px; padding:.22rem .65rem;
}
/* Five plans since Studio (2026-09-07), and three columns rather than four or five.
   MEASURED, because the obvious answer is wrong: `--wrap` caps this grid at 1120px however
   wide the window is, so five across is (1088 - 64) / 5 = 204px a card against the 260px the
   four-column layout gave, and a plan card at 204px wraps its own price line. Four columns
   would leave the fifth card alone on a second row, which reads as a mistake rather than a
   layout. 3 + 2 reads as a group and gives each card ~330px, wider than any of them had
   before. */
.plans{display:grid; gap:1rem}
@media (min-width:700px){.plans{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1040px){.plans{grid-template-columns:repeat(3,1fr)}}
.plan{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  padding:1.4rem 1.3rem 1.5rem; display:flex; flex-direction:column;
}
.plan-featured{border-color:var(--brand); border-width:2px; padding:1.35rem 1.25rem 1.45rem}
.plan-tag{
  font-size:.7rem; font-weight:800; letter-spacing:.11em; text-transform:uppercase;
  color:var(--brand); margin-bottom:.55rem; min-height:1.1em;
}
.plan h3{font-size:1.28rem}
.plan-for{color:var(--text-3); font-size:.88rem; margin-top:.25rem; min-height:2.6em}
.price{
  display:flex; align-items:baseline; gap:.3rem; margin:1rem 0 .15rem;
  font-family:"Bricolage Grotesque",sans-serif; font-weight:800; letter-spacing:-.03em;
}
.price .amt{font-size:2.35rem; font-variant-numeric:tabular-nums}
.price .per{font-size:.9rem; font-weight:600; color:var(--text-3); font-family:"Public Sans",sans-serif; letter-spacing:0}
.price-sub{font-size:.82rem; color:var(--text-3); min-height:1.4em}
.plan .btn{margin:1.25rem 0 1.1rem}
.plan-list{display:grid; gap:.55rem; font-size:.93rem; color:var(--text-2); margin-top:auto}
.plan-list li{display:flex; gap:.55rem; align-items:flex-start}
.plan-list svg{flex:none; margin-top:.32em; color:var(--brand)}
.plan-note{font-size:.85rem; color:var(--text-3); margin-top:1.4rem; max-width:var(--measure)}

/* ---------- faq ---------- */
/* Full container width. On desktop the question sits in a left column and its answer
   opens in a right one, which is what actually uses the width: a single narrow column of
   accordions in a 1120px container leaves two thirds of the row empty. */
.faq{border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  cursor:pointer; list-style:none; padding:1.15rem 2.4rem 1.15rem 0; position:relative;
  font-weight:600; font-size:1.06rem;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:""; position:absolute; right:.5rem; top:1.6rem;
  width:10px; height:10px; border-right:2px solid var(--text-3); border-bottom:2px solid var(--text-3);
  transform:rotate(45deg); transition:transform .18s ease;
}
.faq details[open] summary::after{transform:rotate(-135deg)}
.faq .answer{padding:0 0 1.3rem; color:var(--text-2); max-width:72ch}
.faq .answer p + p{margin-top:.7rem}

@media (min-width:900px){
  .faq details{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.35fr); column-gap:3rem; align-items:start}
  .faq summary{grid-column:1; padding-right:1.5rem; font-size:1.1rem}
  .faq summary::after{right:.2rem}
  .faq .answer{grid-column:2; padding-top:1.15rem; max-width:none}
  .faq details:not([open]) .answer{display:none}
}

/* ---------- cta band ---------- */
.band{
  background:var(--ink-block); color:var(--on-ink); border-block:1px solid var(--ink-block);
}
.band .wrap{display:grid; gap:1.4rem; align-items:center}
@media (min-width:820px){.band .wrap{grid-template-columns:1fr auto}}
.band h2{color:var(--on-ink)}
.band .lede{color:var(--on-ink-2)}
.band .btn-primary{
  background:var(--on-ink); color:var(--ink-block); border-color:var(--on-ink);
}
.band .btn-primary:hover{background:#fff; border-color:#fff; color:var(--ink-block)}

/* ---------- footer ---------- */
.site-footer{padding-block:3rem 2.4rem; font-size:.92rem; color:var(--text-2)}
.foot-grid{display:grid; gap:1.8rem}
@media (min-width:760px){.foot-grid{grid-template-columns:1.4fr 1fr 1fr}}
/* Footer column labels are <h2>, not <h4>: the page outline runs h1 > h2 > h3, and a
   jump to h4 is a real WCAG heading-order failure (axe-core, moderate). They are styled
   down to label size here, which is a visual decision and not a structural one. */
/* Product and Legal are collapsible. On desktop they open by default and the marker is
   hidden, so nothing looks like a control that does not need to be one; below 760px they
   start closed, which is the whole point of an accordion in a footer. */
.foot-group{min-width:0}
.foot-group > summary{
  list-style:none; cursor:pointer; display:flex; align-items:center; justify-content:space-between;
  gap:.75rem; padding:.15rem 0;
}
.foot-group > summary::-webkit-details-marker{display:none}
.foot-group > summary::after{
  content:""; width:8px; height:8px; flex:none;
  border-right:2px solid var(--text-3); border-bottom:2px solid var(--text-3);
  transform:rotate(45deg) translateY(-2px); transition:transform .18s ease;
}
.foot-group[open] > summary::after{transform:rotate(-135deg) translateY(0)}
.foot-group > summary h2{margin-bottom:0}
.foot-group ul{padding-top:.75rem}
@media (min-width:760px){
  .foot-group > summary{cursor:default}
  .foot-group > summary::after{display:none}
}
@media (max-width:759px){
  .foot-group{border-top:1px solid var(--line); padding:.85rem 0}
  .foot-group > summary{padding:.25rem 0}
  .foot-grid{gap:0}
  .foot-grid > div:first-child{margin-bottom:1.4rem}
}

.site-footer h2{
  font-family:"Public Sans",sans-serif; font-size:.76rem; font-weight:700;
  letter-spacing:.11em; text-transform:uppercase; color:var(--text-3); margin-bottom:.75rem;
}
.site-footer ul{display:grid; gap:.5rem}
.site-footer a{text-decoration:none; color:var(--text-2)}
.site-footer a:hover{color:var(--text); text-decoration:underline}
.legal{margin-top:2.2rem; padding-top:1.5rem; border-top:1px solid var(--line); font-size:.85rem; color:var(--text-3);
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; column-gap:1.5rem}
/* The theme switch (theme.js), at the right of the copyright line; below it when there is no room.
   Three real radio buttons, so arrows, Tab and screen readers behave natively; the input covers
   its label invisibly and the label paints the state. */
.legal > p{flex:1 1 30rem; min-width:0}
/* With the switch beside it the affiliation note takes its own line, rather than one line that
   breaks mid-name at desktop widths. */
.legal:has(.theme-switch) .legal-note{display:block; margin-top:.45rem}
.legal:has(.theme-switch) .legal-note::before{content:none}
.theme-switch{display:inline-flex; flex:none; gap:2px; margin:.5rem 0; padding:3px; border:1px solid var(--line); border-radius:999px; background:var(--card); min-width:0}
.theme-switch-legend{position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
.theme-switch-opt{position:relative; display:inline-flex; align-items:center; gap:.35rem; min-height:32px; padding:0 .75rem; border-radius:999px; color:var(--text-2); font-size:.85rem; font-weight:600; cursor:pointer}
.theme-switch-opt input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer}
.theme-switch-opt svg{flex:none}
.theme-switch-opt:hover{color:var(--text)}
.theme-switch-opt:has(input:checked){background:var(--mint-soft); color:var(--brand-hover)}
.theme-switch-opt:has(input:focus-visible){outline:2px solid var(--ring); outline-offset:2px}
/* Copyright and the affiliation note read as one line; the note only drops to its
   own line when the viewport genuinely cannot hold both. */
.legal-note::before{content:"\00a0\00b7\00a0"; color:var(--line)}
@media (max-width:640px){
  .legal-note{display:block; margin-top:.45rem}
  .legal-note::before{content:none}
}


/* ---------- legal documents ---------- */
.doc{padding-block:clamp(2.2rem,4vw,3.4rem) clamp(2.6rem,5vw,4rem)}
.doc-head{border-bottom:1px solid var(--line); padding-bottom:1.6rem; margin-bottom:2.4rem}
.doc-head h1{font-size:clamp(2rem,4.2vw,3rem)}
.doc-meta{margin-top:.9rem; color:var(--text-3); font-size:.92rem}
.doc-body{max-width:none}

/* A legal page at 1120px with a 74ch column wasted a third of the row. The width now
   carries a sticky contents rail, which is also the thing these documents most need:
   they are 27 and 19 sections long and were previously navigable only by scrolling. */
.doc-layout{display:block}
@media (min-width:1000px){
  .doc-layout{display:grid; grid-template-columns:15rem minmax(0,1fr); column-gap:3.5rem; align-items:start}
  .doc-rail{position:sticky; top:5.5rem; max-height:calc(100vh - 8rem); overflow-y:auto; overscroll-behavior:contain}
  .doc-body{max-width:88ch}
}
.doc-rail h2{
  font-family:"Public Sans",sans-serif; font-size:.72rem; font-weight:700;
  letter-spacing:.12em; text-transform:uppercase; color:var(--text-3);
  border:0; padding:0; margin:0 0 .8rem;
}
.doc-rail ol{list-style:none; margin:0; padding:0; display:grid; gap:.1rem; counter-reset:dr}
.doc-rail li{counter-increment:dr}
.doc-rail a{
  display:block; text-decoration:none; color:var(--text-2); font-size:.85rem; line-height:1.35;
  padding:.32rem .55rem .32rem 2rem; border-radius:7px; position:relative;
}
.doc-rail a::before{
  content:counter(dr); position:absolute; left:.55rem; top:.32rem;
  font-size:.72rem; font-variant-numeric:tabular-nums; color:var(--text-3);
}
.doc-rail a:hover{background:var(--tint); color:var(--text)}
.doc-rail a[aria-current="true"]{background:var(--mint-soft); color:var(--brand); font-weight:600}
.doc-rail a[aria-current="true"]::before{color:var(--brand)}
/* The rail is a real <details>: open and non-collapsible on desktop, collapsed on a
   phone, where a nineteen-item list ahead of the text would be its own obstacle. */
.rail-box > summary{list-style:none; cursor:pointer; display:flex; align-items:center; justify-content:space-between; gap:.6rem}
.rail-box > summary::-webkit-details-marker{display:none}
.rail-box > summary::after{
  content:""; width:8px; height:8px; flex:none;
  border-right:2px solid var(--text-3); border-bottom:2px solid var(--text-3);
  transform:rotate(45deg) translateY(-2px); transition:transform .18s ease;
}
.rail-box[open] > summary::after{transform:rotate(-135deg) translateY(0)}
@media (min-width:1000px){
  .rail-box > summary{cursor:default}
  .rail-box > summary::after{display:none}
}
@media (max-width:999px){
  .doc-rail{
    border:1px solid var(--line); border-radius:var(--r); background:var(--card);
    padding:.9rem 1rem; margin-bottom:2rem;
  }
  .rail-box > summary{min-height:44px}
  .doc-rail ol{padding-top:.6rem}
  .doc-rail a{padding-block:.5rem}
}
.doc-body h2{
  font-size:1.32rem; margin:2.6rem 0 .85rem; padding-top:1.6rem;
  border-top:1px solid var(--line); letter-spacing:-.015em;
}
.doc-body > h2:first-child{border-top:0; padding-top:0; margin-top:0}
.doc-body h3{font-size:1.04rem; margin:1.8rem 0 .55rem}
.doc-body p{margin:.85rem 0; color:var(--text-2)}
.doc-body strong{color:var(--text)}
.doc-body ul,.doc-body ol{margin:.85rem 0 .85rem 1.3rem; display:grid; gap:.45rem; color:var(--text-2)}
.doc-body ul{list-style:disc}
.doc-body ol{list-style:decimal}
.doc-body li{padding-left:.2rem}
.doc-body a{color:var(--brand); text-decoration:underline; text-underline-offset:2px; overflow-wrap:anywhere}
.doc-body{overflow-wrap:break-word}
.doc-body table{margin:1.2rem 0}
.callout{
  border:1px solid var(--mint-line); background:var(--mint-soft);
  border-radius:var(--r); padding:1.1rem 1.2rem; margin:1.6rem 0;
}
.callout p{color:var(--text); margin:.5rem 0}
.callout p:first-child{margin-top:0}
.callout p:last-child{margin-bottom:0}


/* ============================================================
   MOBILE
   Measured on a 390x844 touch viewport: every real control below is brought to a 44px
   tap height, and no piece of real copy is left under 12px. Inline links inside a
   sentence are deliberately left alone: WCAG 2.5.8 exempts them, and padding them out
   would break the line they sit in.
   ============================================================ */

/* "Most popular" was rendering at 11.2px. 12px is the floor for real copy. */
.plan-tag{font-size:.75rem}

@media (hover:none), (max-width:760px){
  /* Scene rail and the play control */
  .rail button{min-height:44px; padding-block:.55rem}
  /* Billing period switch */
  .cycle button{min-height:44px; padding-block:.6rem}
  /* Header wordmark */
  .brand{min-height:44px}
  /* The one control that was still 41px tall on a phone. */
  .header-cta{min-height:44px}
  /* Footer: the accordion headers ARE the control on mobile, and every link in them
     needs a real target rather than a 17px line of text. */
  .foot-group > summary{min-height:44px}
  .site-footer ul{gap:0}
  .site-footer ul li a{display:inline-flex; align-items:center; min-height:44px}
  .site-nav a{min-height:44px; display:inline-flex; align-items:center}
}

@media (max-width:760px){
  /* The mock is a picture of an interface, so its type can run small, but not this small
     on a phone. */
  .wa-stamp{font-size:.66rem}
  .wa-dur{font-size:.72rem}
  .rw-cta{font-size:.78rem}
  /* The hero demo does not need to be as tall as the copy above it on a phone. */
  .wa-body{min-height:20rem}
  .wa-thread{min-height:9.5rem}
  /* Section rhythm tightens up so the page is not 11,000px of scrolling. */
  :root{--step:3rem}
  .hero{padding-top:2.2rem}
  .hero-copy{margin-bottom:2rem}
  .sec-head{margin-bottom:1.6rem}
  .stage-foot{margin-top:.9rem}
  .rail{gap:.35rem}
  .plan{padding:1.2rem 1.15rem 1.3rem}
  .feature{padding:1.35rem 1.25rem 1.4rem}
  .fmark{width:52px; height:52px; border-radius:15px; margin-bottom:.95rem}
  .fmark svg{width:26px; height:26px}
  .tablewrap table{min-width:0}
  th{width:auto; min-width:9rem}
  .band .wrap{gap:1.1rem}
  .site-footer{padding-block:2.2rem 2rem}
}

@media (max-width:400px){
  body{font-size:16px}
  .wrap{padding-inline:1rem}
  .rail button{font-size:.8rem; padding-inline:.7rem}
}


/* ============================================================
   MOBILE BUTTONS
   Everything that is a control gets one of three shapes on a phone, so the page never
   shows two buttons of different heights doing the same job:
     full-width block  the primary actions (hero, plans, the closing call)
     equal halves      a two-state switch (monthly / yearly)
     one scrolling row the scene rail, which has six items and cannot stack
   ============================================================ */
@media (max-width:640px){
  /* Primary actions go full width and identical height, stacked. Two buttons of
     different natural widths sitting side by side was the untidiest thing on the page. */
  .hero-actions{display:grid; grid-template-columns:1fr; gap:.6rem}
  .hero-actions .btn{width:100%; min-height:50px; font-size:1rem}
  .band .wrap .btn{width:100%; min-height:50px; font-size:1rem}
  .plan .btn{min-height:48px}

  /* The billing switch: two exactly equal halves, edge to edge. */
  .cycle{display:grid; grid-template-columns:1fr 1fr; width:100%; border-radius:12px}
  .cycle button{border-radius:9px; min-height:44px}
  .save{margin-left:0; margin-top:.6rem; display:inline-block}

  /* The scene rail becomes one row that scrolls, with the chips at their natural width
     and a snap point on each. Six chips wrapped into ragged rows of two and three was
     the other untidy thing; a single row reads as deliberate. */
  .rail{display:grid; gap:.7rem; align-items:stretch}
  .rail-scenes{
    flex-wrap:nowrap; overflow-x:auto; scroll-snap-type:x mandatory;
    scrollbar-width:none; -ms-overflow-style:none;
    padding-block:.15rem;
  }
  .rail-scenes::-webkit-scrollbar{display:none}
  .rail-scenes button{flex:none; scroll-snap-align:start; white-space:nowrap}
  .rail-play{margin-left:0; justify-self:start; min-height:44px}

  /* Header: the wordmark and the call to action balance instead of the CTA crowding it. */
  .header-in{gap:.75rem}
  .header-cta{padding-inline:.85rem}
  .header-cta .chrome-mark{width:15px; height:15px}
}

@media (max-width:400px){
  /* At the narrowest the header CTA drops to the mark plus one word. */
  .header-cta{font-size:.86rem; padding-inline:.7rem}
}


/* ---------- 404 ----------
   Cloudflare Pages serves its own page when this file is missing, which is an unbranded
   grey screen on the domain a payment reviewer is checking. */
.notfound{padding:clamp(3.5rem,9vw,7rem) 0 clamp(4rem,10vw,8rem)}
.nf-list{margin-top:2rem; display:grid; gap:.1rem; max-width:34ch}
.nf-list a{
  display:block; padding:.7rem 0; min-height:44px; color:var(--text);
  border-bottom:1px solid var(--line); text-decoration:none; font-weight:600;
}
.nf-list a:hover{color:var(--brand)}
.nf-help{margin-top:2rem; color:var(--text-2)}

/* ---------- print ----------
   The legal documents get printed and filed. Give them the page, not the furniture. */
@media print{
  .site-header,.site-footer,.doc-rail,.skip,.stage,.band,.cycle{display:none !important}
  body{background:#fff; color:#000; font-size:11pt}
  .doc-layout{display:block}
  .doc-body{max-width:none}
  a{color:#000; text-decoration:underline}
  /* A printed page loses every href, so put the important ones back in the margin. */
  .doc-body a[href^="http"]::after{content:" (" attr(href) ")"; font-size:9pt; word-break:break-all}
  .doc-body a[href^="mailto"]::after{content:none}
  h1,h2,h3{break-after:avoid-page}
  table,figure,li{break-inside:avoid}
  details{display:block}
  details > summary{list-style:none}
  details:not([open]) > *:not(summary){display:revert}
}

/* ============================================================
   /support
   The same form as the one inside the extension's options page, posting to the same
   Worker. Everything here is layout: the behaviour lives in assets/support.js.
   ============================================================ */
.sup{padding:clamp(2.6rem,5vw,4rem) 0 clamp(3.5rem,7vw,5.5rem)}
.sup h1{font-size:clamp(2.1rem,4.4vw,3.2rem)}
.sup .lede{max-width:56ch}
.sup-grid{display:grid; gap:clamp(1.6rem,3vw,2.6rem); margin-top:clamp(2rem,4vw,3rem)}
@media (min-width:900px){
  .sup-grid{grid-template-columns:minmax(0,1.35fr) minmax(0,.85fr); align-items:start}
}

.sup-form{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  padding:clamp(1.2rem,3vw,2rem); display:grid; gap:1.15rem; box-shadow:var(--shadow);
}
.sup-row{display:grid; gap:1.15rem}
@media (min-width:560px){.sup-row{grid-template-columns:1fr 1fr}}

.field{display:grid; gap:.4rem; min-width:0}
.field label{font-weight:600; font-size:.94rem}
.opt{font-weight:400; color:var(--text-3); font-size:.85rem}
.hint{font-size:.84rem; color:var(--text-3); margin:0}

.field input,.field textarea{
  font:inherit; font-size:.97rem; color:var(--text); background:var(--paper);
  border:1.5px solid var(--line); border-radius:var(--r-sm); padding:.66rem .8rem;
  width:100%; min-width:0; min-height:44px;
  transition:border-color .16s ease, background-color .16s ease;
}
.field textarea{resize:vertical; line-height:1.55}
.field input:hover,.field textarea:hover{border-color:var(--text-3)}
.field input:focus,.field textarea:focus{border-color:var(--brand); background:var(--card); outline:none}
.field input:focus-visible,.field textarea:focus-visible{outline:2.5px solid var(--ring); outline-offset:1px}
.field input::placeholder,.field textarea::placeholder{color:var(--text-3)}
/* The file input's own button is drawn by the browser and cannot be styled through the
   element, only through this pseudo-element. Left unset it is the one control on the page
   in the platform's colours rather than ours. */
.field input[type="file"]{padding:.45rem .5rem}
.field input[type="file"]::file-selector-button{
  font:inherit; font-weight:600; font-size:.9rem; cursor:pointer;
  color:var(--text); background:var(--paper-2); border:1.5px solid var(--line);
  border-radius:var(--r-sm); padding:.4rem .8rem; margin-right:.7rem;
}
.field input[type="file"]::file-selector-button:hover{border-color:var(--text-3)}

/* Off-screen, not display:none. A bot that only fills rendered fields is not the bot this
   catches; one that fills every field in the DOM is. */
.sup-hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden}

.sup-actions{display:flex; flex-wrap:wrap; align-items:center; gap:.9rem 1.1rem}
.sup-status{margin:0; font-size:.92rem; color:var(--text-2)}
.sup-status.is-ok{color:var(--brand); font-weight:600}
.sup-status.is-error{color:var(--amber); font-weight:600}

.sup-aside{display:grid; gap:1rem; align-content:start}
.sup-card{
  background:var(--tint); border:1px solid var(--tint-line);
  border-radius:var(--r); padding:1.1rem 1.2rem;
}
.sup-card h2{font-size:.78rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--text-3); font-weight:700; margin-bottom:.55rem}
.sup-card p{font-size:.94rem; color:var(--text-2)}
.sup-card a{color:var(--brand)}
.sup-links{display:grid; gap:.15rem}
.sup-links a{
  display:block; padding:.42rem 0; font-size:.94rem; color:var(--text-2);
  text-decoration:none; border-bottom:1px solid var(--tint-line); min-height:34px;
}
.sup-links li:last-child a{border-bottom:0}
.sup-links a:hover{color:var(--brand)}
.sup-addr{font-size:.88rem; line-height:1.5}

/* ---------- /welcome and /checkout: the two transaction pages ----------
   One narrow column, because every state here is a short instruction and a wide measure
   makes a numbered list harder to follow, not easier. The states share a grid slot rather
   than stacking, so swapping them cannot move the page under a reader's cursor.

   /checkout shares this block rather than copying it. Both pages are the same object: a
   handful of mutually exclusive states, one of which is visible, none of which is longer
   than a paragraph and a pair of buttons. A second set of rules that had to be kept in step
   with these would drift the first time one of them was touched. */
.wel .wrap, .co .wrap{max-width:60rem}
.wel-state, .co-state{display:grid; gap:1.4rem; justify-items:start}
.wel-state .sec-head, .co-state .sec-head{margin:0}
.wel-steps{
  display:grid; gap:.7rem; margin:0; padding-left:1.35rem;
  max-width:58ch; color:var(--text-2); font-size:1rem; line-height:1.6;
}
.wel-steps b{color:var(--text)}
.wel-actions, .co-actions{display:flex; flex-wrap:wrap; gap:.75rem}

/* The key itself. Monospace, wrapping at any character, because it is 51 characters with no
   spaces and a 360px screen has to show all of it or the copy button is the only way out. */
/* THE KEY CARD (2026-09-22). The key is the only thing this state exists to hand over, and
   it used to look like a disabled input: a thin strip with a GHOST copy button beside fully
   legible text, sitting below a headline, a tinted warning and a four-step list. It reads as
   "here is a value", not "here is the thing to take with you", and the owner read past it
   twice. Now it is a titled card, the key inside it is MASKED, and Copy is the primary
   action -- so the only way to get the key out is the one way that cannot go wrong. */
.wel-keycard{
  /* FULL WIDTH, matching the two bands above it. At 42rem it ended 224px short of their
     right edge, and three stacked blocks on two different measures read as a hierarchy
     nobody intended: the narrow one looks subordinate, which is the opposite of true here. */
  width:100%; max-width:none;
  background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  padding:1.15rem 1.25rem 1.05rem; box-shadow:var(--shadow);
  display:grid; gap:.4rem;
}
.wel-keycard-title{margin:0; font-size:1.05rem; line-height:1.3}
.wel-keycard-sub{margin:0 0 .55rem; font-size:.9rem; line-height:1.5; color:var(--text-2)}
.wel-key{
  display:flex; flex-wrap:wrap; align-items:center; gap:.5rem .6rem;
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-sm);
  padding:.5rem .5rem .5rem .85rem; max-width:100%;
}
.wel-key code{
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:.95rem; color:var(--text); word-break:break-all; min-width:0; flex:1 1 15rem;
  /* Only useful once the key is REVEALED, and only in a font that carries the feature, which
     is why it is a nicety rather than the fix: mistaking `O` for `0` is what cost somebody
     twenty minutes on 2026-09-22, and masking is what actually prevents it. */
  font-variant-numeric:slashed-zero;
}
/* The reveal. A quiet square beside the value rather than a labelled button, because the
   labelled button on this row is Copy and two of those would compete. */
.wel-key-eye{
  /* Square, and the SAME HEIGHT as the Copy button beside it (measured at 55px with this
     font). A 34px control next to a 55px one reads as an afterthought that drifted into the
     row rather than a second control belonging to the same object. */
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  width:55px; height:55px; padding:0; cursor:pointer; color:var(--text-2);
  background:transparent; border:1.5px solid var(--line); border-radius:var(--r-sm);
  transition:color .16s ease, border-color .16s ease, background-color .16s ease;
}
.wel-key-eye:hover{color:var(--text); border-color:var(--text-3)}
.wel-key-eye[aria-pressed="true"]{color:var(--brand); border-color:var(--brand)}
/* NARROW: the key takes the whole first line and the two controls share the second, next to
   each other. Left to wrap on its own the row put the key and the eye together with Copy
   underneath on the far side -- two controls belonging to one object, separated by the thing
   they act on. Copy grows into the space because it is the primary action and a thumb target. */
@media (max-width:560px){
  .wel-key{padding:.6rem}
  .wel-key code{flex:1 1 100%; padding:.15rem .25rem .35rem}
  .wel-key-eye{order:2}
  .wel-key .btn{order:3; flex:1 1 auto}
}

.wel-key-status{
  /* The height is RESERVED rather than grown into, so confirming a copy does not shove the
     four numbered steps underneath it down the page at the moment somebody is reading them. */
  margin:.5rem 0 0; min-height:1.25em; font-size:.85rem; font-weight:600; color:var(--brand);
}
.wel-key-status[data-tone="warn"]{color:var(--amber)}

.wel-note{
  background:var(--tint-warm); border:1px solid var(--tint-warm-line);
  border-radius:var(--r); padding:1rem 1.15rem; display:grid; gap:.5rem; max-width:52ch;
}
.wel-note h2{font-size:1rem; margin:0}
.wel-note p{margin:0; font-size:.94rem; color:var(--text-2)}

/* THE DUPLICATE-SUBSCRIPTION WARNING, AND WHY IT IS THE LOUDEST THING ON THE PAGE.
   It shares `.wel-note` with the "install the extension" hint, which is a footnote and should
   stay one, so the emphasis is a modifier rather than a change to the base. This block is not
   a footnote: it tells somebody they are being charged twice, and it is the only sentence on
   the page that costs money to miss. It sat at 52ch in the left third of a very wide page
   above a headline four times its size, which is the visual weight of an aside.
   `max-width:none` rather than a larger ch value, because the state blocks below it are
   `justify-items:start` and this one wants the whole column. */
/* (d) The install band: the reason and the action on ONE row, replacing a stacked card
   whose button sat on its own third line -- height spent saying nothing.

   IT MUST STAY BELOW `.wel-note`. Both are single-class selectors, so order is the only
   thing deciding them, and written above the base every line here lost in silence: measured
   in a browser, the band came out `display:grid`, 52ch wide, button on its own row. The
   stylesheet said one thing and the page did another, and nothing failed. */
.wel-note--inline{
  display:flex; align-items:center; justify-content:space-between; gap:1rem 1.25rem;
  flex-wrap:wrap; max-width:none; width:100%;
}
.wel-note--inline .wel-note-body{display:grid; gap:.3rem; min-width:16rem; flex:1 1 22rem}
.wel-note--inline h2{font-size:1.02rem}
.wel-note--inline p{font-size:.92rem}
.wel-note--inline .btn{flex:none}

.wel-note--loud{
  max-width:none; width:100%; padding:1.25rem 1.4rem; gap:.7rem;
  border-width:2px; box-shadow:var(--shadow);
}
.wel-note--loud h2{font-size:1.45rem; font-weight:700; line-height:1.25; color:var(--text)}
.wel-note--loud p{font-size:1.02rem; color:var(--text)}
.wel-note--loud p b{color:var(--text)}
@media (max-width:600px){
  .wel-note--loud{padding:1rem 1.1rem}
  .wel-note--loud h2{font-size:1.2rem}
}

/* The single-row footer, on /404 and /checkout.
   `.site-footer` is on the selector for a reason: `.site-footer ul{display:grid}` above is
   one class and one type, and `.foot-mini` alone is one class, so the grid won and this
   footer has been rendering as a stacked column since it was written. Nothing failed, which
   is why nobody saw it -- the links all worked, they were just one per line. */
.site-footer .foot-mini{
  display:flex; flex-wrap:wrap; gap:.4rem 1.4rem;
  font-size:.93rem; color:var(--text-2); padding-bottom:.4rem;
}
.foot-mini a{text-decoration:none; color:var(--text-2)}
.foot-mini a:hover{color:var(--brand)}

/* ---------- /guide: the long-form page ----------
   One column at a reading measure, and every section opens with a .gd-answer: a
   self-contained paragraph that answers the heading before any elaboration. That shape
   is for two readers at once. A person scanning gets the answer without reading on, and
   a retrieval system that pulls one paragraph out of the page pulls one that still makes
   sense with the page removed, because it names the product rather than saying "it". */
.gd{padding:clamp(2.6rem,5vw,4.2rem) 0}
.gd-top{padding-bottom:clamp(1.8rem,3vw,2.6rem)}
.gd h1{font-size:clamp(2.1rem,4.4vw,3.2rem)}
.gd h2{font-size:clamp(1.6rem,3vw,2.15rem); margin-bottom:1.1rem}
.gd .prose > * + *{margin-top:1.05rem}
.gd .lede{max-width:60ch}
.gd-meta{font-size:.86rem; color:var(--text-3); margin-top:1.1rem}

.gd-answer{
  font-size:1.06rem; line-height:1.62; color:var(--text);
  border-left:3px solid var(--brand); padding-left:1.05rem;
}
.gd-list{display:grid; gap:.75rem; max-width:var(--measure)}
.gd-list li{padding-left:1.15rem; position:relative; color:var(--text-2)}
.gd-list li::before{content:"—"; position:absolute; left:0; color:var(--brand)}
.gd-nots li::before{content:"×"; font-weight:700}
.gd-cite{font-size:.88rem; color:var(--text-3)}
.gd-cite a, .gd .prose p a{color:var(--brand)}
.gd-steps{margin-top:1.6rem}
.gd code{
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:.9em; background:var(--paper-2); border-radius:5px; padding:.08em .34em;
}
.gd table code{background:transparent; padding:0}
/* A block of code, as opposed to a word of it. The .gd code rule above paints a chip
   background and padding that make sense inside a sentence and nonsense around eight lines
   of JSON, so the block wins and the inline chip is switched off inside it. Blocks live in
   a .tablewrap, which is what gives them their own horizontal scroll: wide content must
   never make the page body scroll sideways. */
.gd pre{
  margin:1.05rem 0 0; padding:.95rem 1.1rem; background:var(--paper-2);
  border:1px solid var(--line); border-radius:10px; overflow-x:auto;
  font-size:.86rem; line-height:1.55;
}
.gd pre code{background:transparent; padding:0; font-size:inherit}
/* Inside a .tablewrap the WRAPPER scrolls and takes focus; a pre that also scrolled was a second,
   unfocusable scroll region (axe scrollable-region-focusable, found 2026-09-30 on /mcp at phone width). */
.gd .tablewrap pre{overflow-x:visible; width:max-content; min-width:100%}
.gd h3{font-size:1.15rem; margin:1.9rem 0 .6rem}

/* A reference page, laid out to its container rather than to a reading measure.
   The rest of the site holds running text at --measure (66ch), which is the width prose is
   comfortable to read at. A reference page is not read that way: it is scanned, and its
   content is three-column tables and blocks of JSON that a 66ch column turns into stacks of
   two-word lines.
   So this class lifts the measure cap and keeps the site's own --wrap (1120px). An earlier
   version widened the container to 1500px too, and that was too far in the other direction:
   the page stopped looking like the rest of the site, and a paragraph running the width of a
   large monitor is genuinely harder to scan than one that does not. The container is the
   right constraint; the 66ch column inside it was the wrong one.
   A body class rather than a global change, because the marketing pages are read top to
   bottom and the measure is right for them. */
body.doc-wide .prose{max-width:none}
/* The sections on this page carry BOTH classes on one element (`<div class="wrap prose">`),
   so the rule above also removed the container's own cap and the page ran the full width of
   the monitor. Re-assert it, after, at equal specificity. What is being lifted is the
   reading MEASURE, never the container. */
body.doc-wide .wrap{max-width:var(--wrap)}
body.doc-wide .gd .lede{max-width:72ch}
body.doc-wide .gd-list, body.doc-wide .gd-dl{max-width:none}
body.doc-wide .gd-toc{max-width:none}
body.doc-wide .gd table{width:100%}
/* Running paragraphs still get a measure, just a roomier one than 66ch: the tables are what
   needed the width, and a 100-character line of prose is not an improvement on a 66. */
body.doc-wide .gd .prose > p{max-width:82ch}

.gd-dl{max-width:var(--measure)}
.gd-dl dt{font-weight:700; margin-top:1.35rem}
.gd-dl dd{margin:.3rem 0 0; color:var(--text-2)}

/* The table of contents is a real <nav>, not decoration: it is the page's own outline,
   and an answer engine reads it as one. */
.gd-toc{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  padding:1.15rem 1.35rem; margin-top:2rem; max-width:44rem; box-shadow:var(--shadow);
}
.gd-toc h2{
  font-size:.78rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--text-3); margin:0 0 .7rem; font-family:inherit; font-weight:700;
}
.gd-toc ol{margin:0; padding-left:1.3rem; display:grid; gap:.3rem; color:var(--text-2)}
.gd-toc a{color:var(--text-2); text-decoration:none}
.gd-toc a:hover{color:var(--brand)}

/* A ghost button on the ink band. It had never been used there until the guide page's
   closing CTA, and it was still painting var(--text) on var(--ink-block): dark on dark
   in light mode, at a contrast ratio axe measures as a failure. */
.band .btn-ghost{color:var(--on-ink); border-color:color-mix(in srgb, var(--on-ink) 42%, transparent)}
.band .btn-ghost:hover{
  color:var(--on-ink); border-color:var(--on-ink);
  background:color-mix(in srgb, var(--on-ink) 12%, transparent);
}

@media (max-width:640px){
  .sup-actions{flex-direction:column; align-items:stretch}
  .sup-actions .btn{width:100%; min-height:50px}
  .sup-status{text-align:center}
  .sup-links a{min-height:44px; display:flex; align-items:center}
}

/* The 27-second tour on the home page (2026-09-30). youtube-nocookie and loading="lazy", so
   nothing is fetched from YouTube until the section is near the viewport. */
.video{margin:2rem auto 0; max-width:760px; aspect-ratio:16/9; border-radius:var(--r); overflow:hidden;
  border:1px solid var(--line); background:var(--card)}
.video iframe{display:block; width:100%; height:100%; border:0}

/* ---------- My account (row 90, 2026-09-30) ---------- */
.acct-form{display:grid; gap:1rem; width:100%; max-width:30rem}
.acct-status{margin:0; min-height:1.25em; font-size:.9rem; font-weight:600; color:var(--brand)}
.acct-status[data-tone="warn"]{color:var(--amber)}
.acct-card{width:100%; max-width:40rem; background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  padding:1.1rem 1.25rem; display:grid; gap:.75rem}
.acct-card h2{font-size:1.05rem; margin:0}
.acct-status-line{margin:0; font-weight:600}
.acct-meter{display:grid; gap:.4rem}
.acct-meter-bar{height:.6rem; border-radius:999px; background:var(--paper-2); overflow:hidden; border:1px solid var(--line)}
.acct-meter-bar span{display:block; height:100%; width:0; background:var(--brand)}
.acct-row{display:flex; flex-wrap:wrap; gap:1rem}
.acct-row .field{flex:1 1 10rem}
.field select{font:inherit; color:var(--text); background:var(--paper); border:1px solid var(--line);
  border-radius:var(--r-sm); padding:.6rem .7rem}
.field select:focus-visible{outline:2.5px solid var(--ring); outline-offset:1px}
.acct-devices{margin:0; padding-left:1.1rem; display:grid; gap:.3rem; color:var(--text-2)}

/* ============================================================
   My account, signed in (the redesign approved 2026-09-30)
   ============================================================ */
.acct.is-home .wrap{max-width:var(--wrap)}
.acx{display:grid; grid-template-columns:minmax(0,1fr); gap:1.5rem; justify-items:stretch}
.acx-main{display:grid; gap:1.5rem; min-width:0}
.acx-muted{color:var(--text-2)}
.acx-label{font-size:.75rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-3)}
.acx-card{background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:clamp(1.15rem,2.4vw,1.75rem); min-width:0}
.acx-card h2{margin:0; font-family:inherit; font-size:1.15rem; font-weight:700; letter-spacing:0}
.acx-card-head{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:.5rem 1rem; margin-bottom:1rem}
.acx-card-head .acx-muted{font-size:.88rem}
.acx-link{border:0; background:none; padding:.4rem .2rem; min-height:44px; font:inherit; font-weight:600; color:var(--brand); cursor:pointer; text-decoration:none}
.acx-link:hover{text-decoration:underline}
.acx-link-danger{color:var(--danger); display:inline-flex; align-items:center}
.acx-note{margin:1rem 0 0; padding-top:1rem; border-top:1px solid var(--line); font-size:.84rem; line-height:1.5; color:var(--text-3)}
.acx-banner{margin:0; padding:.85rem 1rem; border-radius:var(--r-sm); background:var(--amber-soft); color:var(--text); font-size:.92rem}

/* The section menu: a sticky rail on a desktop, a row of chips under the header on a phone. */
.acx-nav{position:sticky; top:66px; z-index:5; display:flex; gap:.5rem; overflow-x:auto; scrollbar-width:none;
  margin-inline:calc(-1 * clamp(1.15rem,4vw,2rem)); padding:.7rem clamp(1.15rem,4vw,2rem);
  background:var(--paper); border-bottom:1px solid var(--line)}
.acx-nav::-webkit-scrollbar{display:none}
.acx-nav-label{display:none}
.acx-nav a,.acx-nav-out{flex:none; display:inline-flex; align-items:center; gap:.6rem; min-height:40px; padding:0 .95rem;
  border-radius:999px; border:1px solid var(--line); background:var(--card); color:var(--text-2); font:inherit; font-size:.92rem;
  font-weight:600; text-decoration:none; cursor:pointer; white-space:nowrap}
.acx-nav a svg,.acx-nav-out svg{display:none}
.acx-nav a.is-current{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.acx-nav a:focus-visible,.acx-nav-out:focus-visible,.acx-link:focus-visible{outline:2px solid var(--ring); outline-offset:2px}
.acx-nav-out{order:9}
@media (min-width:980px){
  .acx{grid-template-columns:220px minmax(0,1fr); gap:3rem; align-items:start}
  .acx-nav{flex-direction:column; gap:.2rem; overflow:visible; margin:0; padding:0; border:0; background:none; top:90px; align-self:start}
  .acx-nav-label{display:block; margin:.4rem .75rem .6rem}
  .acx-nav a,.acx-nav-out{border:0; background:none; border-radius:10px; padding:0 .75rem; min-height:44px; font-size:.95rem}
  .acx-nav a svg,.acx-nav-out svg{display:block; flex:none}
  .acx-nav a:hover,.acx-nav-out:hover{background:var(--paper-2); color:var(--text)}
  .acx-nav a.is-current{background:var(--mint-soft); color:var(--brand-hover)}
  .acx-nav-out{order:0; margin-top:.8rem; border-top:1px solid var(--line); border-radius:0; padding-top:.8rem; min-height:52px}
}
@media (min-width:980px) and (prefers-color-scheme:dark){ :root:not([data-theme="light"]) .acx-nav a.is-current{color:var(--brand)} }
@media (min-width:980px){ :root[data-theme="dark"] .acx-nav a.is-current{color:var(--brand)} }

.acx-head{display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between; gap:1rem; scroll-margin-top:140px}
.acx-head h1{margin:0; font-size:clamp(2rem,4vw,2.8rem)}
.acx-sub{margin:.4rem 0 0; color:var(--text-2)}
.acx-sub b{color:var(--text); overflow-wrap:anywhere}
#acx-billing,#acx-invoices,#acx-devices,#acx-help{scroll-margin-top:140px}

/* The plan card. */
.acx-plan{display:grid; gap:1.75rem}
@media (min-width:1100px){ .acx-plan{grid-template-columns:minmax(0,1fr) 17rem} }
/* No meter to show (an ended plan, or no reading yet): the plan takes the whole card rather than
   leaving the meter's column empty beside text wrapped to make room for it (owner, 2026-09-30). */
@media (min-width:1100px){ .acx-plan:has(> .acx-meter[hidden]){grid-template-columns:minmax(0,1fr)} }
.acx-plan-main{display:grid; gap:1.1rem; align-content:start; min-width:0}
.acx-plan-top{display:flex; flex-wrap:wrap; align-items:center; gap:.75rem; font-size:.9rem}
.acx-plan-title{display:flex; flex-wrap:wrap; align-items:baseline; gap:.4rem 1rem}
.acx-plan-title h2{margin:0; font-family:"Bricolage Grotesque","Public Sans",sans-serif; font-size:clamp(1.9rem,3.4vw,2.4rem); font-weight:800}
.acx-price{font-size:1.15rem; font-weight:600}
.acx-line{margin:0; color:var(--text-2); max-width:75ch}
.acx-pill{display:inline-flex; align-items:center; gap:.4rem; padding:.28rem .7rem; border-radius:999px; font-size:.82rem; font-weight:700; white-space:nowrap}
.acx-pill.is-ok{background:var(--mint-soft); color:var(--brand-hover)}
.acx-pill.is-ok::before{content:""; width:7px; height:7px; border-radius:50%; background:var(--brand)}
.acx-pill.is-trial,.acx-pill.is-free{background:var(--tint); color:var(--text-2)}
.acx-pill.is-warn{background:var(--amber-soft); color:var(--amber)}
.acx-pill.is-bad{background:var(--danger-soft); color:var(--danger)}
.acx-pill.is-ended{background:var(--paper-2); color:var(--text-2)}
.acx-facts{margin:0; display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); border:1px solid var(--line); border-radius:12px}
.acx-fact{padding:.9rem 1rem; display:grid; gap:.25rem; align-content:start}
.acx-fact + .acx-fact{border-left:1px solid var(--line)}
.acx-fact dd{margin:0}
.acx-fact-v{font-weight:600; font-size:1rem}
.acx-fact-s{font-size:.82rem}
.acx-actions{display:flex; flex-wrap:wrap; gap:.75rem}
.acx-actions .btn svg{flex:none}
.acx-meter{display:grid; gap:.8rem; align-content:start; padding:1.25rem; background:var(--paper); border:1px solid var(--line); border-radius:12px}
.acx-meter-num{margin:0; color:var(--text-2)}
.acx-meter-num span{font-family:"Bricolage Grotesque","Public Sans",sans-serif; font-size:2.6rem; font-weight:800; color:var(--text); margin-right:.3rem}
.acx-bar{height:10px; border-radius:999px; background:var(--line); overflow:hidden}
.acx-bar span{display:block; height:100%; width:0; background:var(--brand); border-radius:999px}
.acx-meter .acx-muted{margin:0; font-size:.88rem; line-height:1.5}
.acx-change{display:grid; gap:.9rem; padding:1rem; border:1px dashed var(--line); border-radius:12px}
.acx-change[hidden]{display:none}
.acx-change p{margin:0; font-size:.9rem}
.acx-change-row{display:flex; flex-wrap:wrap; gap:1rem}
.acx-change-row .field{display:grid; gap:.35rem; min-width:10rem}

/* Payment method and billing details. */
.acx-grid2{display:grid; gap:1.5rem}
@media (min-width:760px){ .acx-grid2{grid-template-columns:repeat(2,minmax(0,1fr))} }
.acx-pm{display:flex; align-items:center; gap:1rem}
.acx-pm p{margin:0}
.acx-pm-text{display:grid; gap:.2rem}
.acx-pm-text b{font-size:1.05rem}
.acx-pm-text span{font-size:.9rem}
.acx-cardchip{width:58px; height:40px; border-radius:8px; flex:none; background:var(--ink-block); position:relative}
.acx-cardchip.is-mastercard::before,.acx-cardchip.is-mastercard::after{content:""; position:absolute; top:11px; width:18px; height:18px; border-radius:50%}
.acx-cardchip.is-mastercard::before{left:14px; background:#EB5B25}
.acx-cardchip.is-mastercard::after{left:26px; background:#F5A623; opacity:.9}
.acx-cardchip.is-visa::after{content:"VISA"; position:absolute; inset:0; display:grid; place-items:center; color:#fff; font:italic 800 .8rem/1 "Public Sans",sans-serif; letter-spacing:.05em}
.acx-dl{margin:0; display:grid; grid-template-columns:minmax(7rem,auto) minmax(0,1fr); gap:.7rem 1rem; font-size:.95rem; align-items:center}
.acx-dl dd{margin:0; font-weight:600; overflow-wrap:anywhere}
.acx-dl dd .acx-link{padding:0; min-height:0}

/* Invoices: a table on a desktop, a stack of rows on a phone. */
.acx-table-wrap{overflow-x:auto}
.acx-inv{width:100%; border-collapse:collapse; font-size:.95rem}
.acx-inv[hidden]{display:none}
.acx-inv th{text-align:left; font-size:.75rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-3); padding:.6rem .75rem; border-bottom:1px solid var(--line)}
.acx-inv td{padding:.95rem .75rem; border-bottom:1px solid var(--paper-2); vertical-align:middle}
.acx-inv tr:last-child td{border-bottom:0}
.acx-inv .num{text-align:right; font-variant-numeric:tabular-nums}
.acx-inv .acx-strong{font-weight:600}
.acx-inv .acx-link{padding:0; min-height:0; white-space:nowrap}
.acx-inv .acx-inv-period{display:block; margin-top:.15rem; font-size:.84rem; color:var(--text-3)}
.acx-inv td[data-label="Paid with"],.acx-inv td[data-label="Date"],.acx-inv td[data-label="Amount"]{white-space:nowrap}
.acx-inv td[data-label="What for"]{min-width:10rem}
/* The card is on the Payment method card already; the column goes before "What for" gets cramped. */
#acx-invoices{container-type:inline-size}
@container (max-width:860px){ .acx-inv th:nth-child(3),.acx-inv td[data-label="Paid with"]{display:none} }
#acx-inv-empty{margin:0}
@media (max-width:759px){
  .acx-inv thead{display:none}
  .acx-inv,.acx-inv tbody,.acx-inv tr{display:block}
  .acx-inv{min-width:0; max-width:100%}
  .acx-inv tr{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:.25rem 1rem; padding:.9rem 0; border-bottom:1px solid var(--paper-2)}
  .acx-inv td{display:block; padding:0; border:0; text-align:left}
  .acx-inv td[data-label="Date"]{grid-column:1; font-weight:700}
  .acx-inv td[data-label="Amount"]{grid-column:2; grid-row:1; text-align:right}
  .acx-inv td[data-label="What for"]{grid-column:1 / -1; color:var(--text-2); font-size:.9rem}
  .acx-inv td[data-label="Paid with"]{display:none}
  .acx-inv td[data-label="Status"]{grid-column:1}
  .acx-inv td[data-label="Invoice"]{grid-column:2; text-align:right}
}

/* Browsers and sign-in. */
.acx-devices{list-style:none; margin:0; padding:0}
.acx-devices li{display:flex; align-items:center; gap:.9rem; padding:.8rem 0; border-bottom:1px solid var(--paper-2)}
.acx-devices li:last-child{border-bottom:0}
.acx-dev-icon{width:40px; height:40px; flex:none; border-radius:10px; background:var(--paper-2);
  -webkit-mask:none; position:relative}
.acx-dev-icon::after{content:""; position:absolute; inset:10px 9px 13px; border:2px solid var(--text-3); border-radius:3px}
.acx-dev-icon::before{content:""; position:absolute; left:15px; right:15px; bottom:9px; height:2px; background:var(--text-3)}
.acx-dev-icon.is-current{background:var(--mint-soft)}
.acx-dev-icon.is-current::after{border-color:var(--brand)}
.acx-dev-icon.is-current::before{background:var(--brand)}
.acx-dev-text{display:grid; gap:.15rem; min-width:0}
.acx-dev-text span.acx-muted{font-size:.88rem}
.acx-dev-this{margin-left:.5rem; font-size:.72rem}
.acx-dev-this::before{display:none}

/* Help tiles and managing the subscription. */
.acx-help{display:grid; gap:1rem; padding-block:0}
@media (min-width:760px){ .acx-help{grid-template-columns:repeat(3,minmax(0,1fr)); gap:1.5rem} }
.acx-tile{display:grid; gap:.45rem; align-content:start; text-decoration:none; color:var(--text)}
.acx-tile svg{color:var(--brand)}
.acx-tile span{color:var(--text-2); font-size:.9rem; line-height:1.5}
.acx-tile:hover{border-color:var(--mint-line)}
.acx-manage{display:grid; gap:.25rem}
.acx-manage h2{margin-bottom:.5rem}
.acx-manage-row{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:.75rem 1.5rem; padding:.9rem 0; border-top:1px solid var(--paper-2)}
.acx-manage-row[hidden]{display:none}
.acx-manage-row > div{display:grid; gap:.2rem; flex:1 1 20rem}
.acx-manage-row .acx-muted{font-size:.9rem}
.btn.acx-danger{background:var(--card); color:var(--danger); border-color:var(--danger-line)}
.btn.acx-danger:hover{background:var(--danger-soft)}
@media (max-width:759px){ .acx-manage-row .btn,.acx-actions .btn{width:100%} }

/* The cancel dialog. */
.acx-dialog{width:min(32rem, calc(100vw - 32px)); border:1px solid var(--line); border-radius:var(--r); padding:1.6rem;
  background:var(--card); color:var(--text); box-shadow:var(--shadow)}
.acx-dialog::backdrop{background:rgba(11,21,18,.45)}
.acx-dialog h2{margin:0 0 1rem; font-size:1.6rem}
.acx-dialog label{display:block; margin:1.1rem 0 .4rem; font-size:.9rem; font-weight:600; color:var(--text-2)}
.acx-dialog select{width:100%; min-height:44px; padding:0 .7rem; font:inherit; color:var(--text); background:var(--paper); border:1px solid var(--line); border-radius:var(--r-sm)}
.acx-dialog .acct-status{margin-top:.6rem}
.acx-dialog .acct-status:empty{display:none}
.acx-ticks{list-style:none; margin:0; padding:0; display:grid; gap:.55rem}
.acx-ticks li{position:relative; padding-left:1.6rem}
.acx-ticks li::before{content:""; position:absolute; left:.15rem; top:.35em; width:.55rem; height:.3rem; border-left:2.4px solid var(--brand); border-bottom:2.4px solid var(--brand); transform:rotate(-45deg)}
.acx-dialog-actions{display:flex; flex-wrap:wrap; gap:.75rem; justify-content:flex-end; margin-top:1.4rem}
@media (max-width:480px){ .acx-dialog-actions .btn{width:100%} }

/* /connect, the relay's consent page (2026-10-02). The return host is shown large, as the MCP
   authorization spec asks; the "will not" list carries a cross rather than a tick. */
.cn-card{display:grid; gap:1rem; max-width:40rem}
.cn-card h2{font-size:1.05rem; margin:.4rem 0 0}
.cn-host{font-size:1.25rem; font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.cn-claim{font-weight:400; font-size:.85rem}
.cn-nots li::before{width:.7rem; height:0; top:.65em; border-left:0; border-bottom:2.4px solid var(--danger, #c0392b); transform:rotate(45deg)}
.cn-nots li::after{content:""; position:absolute; left:.07rem; top:.65em; width:.7rem; border-bottom:2.4px solid var(--danger, #c0392b); transform:rotate(-45deg)}
