/* ==========================================================================
   INDIVESTA — the shared design spine
   Ten products, one philosophy: the draft is the machine's, the signature is yours.

   Inherited by all ten. Each product overrides only its SOUL in soul.css:
     --accent, --accent-rgb, --paper, --paper-rgb  (+ optional --card)
   Nothing else should be overridden. If a product needs a new spine token,
   it belongs here, not there.

   FONT TRUTH: the brief specifies Instrument Serif (display) and IBM Plex Sans
   (body). Neither is in this repo's /fonts. JetBrains Mono IS, and is used as
   specified for all data, labels and timestamps — IBM Plex Mono was the
   original mono spec but was never self-hosted; JetBrains Mono replaced it.
   Display falls back to self-hosted Marcellus, body to self-hosted Inter. Both
   stacks name the intended face first, so dropping the real woff2 into /fonts
   and adding two @font-face rules upgrades all ten products at once, no
   markup change.
   ========================================================================== */

/* ---------- Self-hosted faces (absolute paths — served from the repo root) -- */
@font-face{font-family:'Marcellus';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/marcellus-400-latin.woff2') format('woff2');}

/* ---- the two site faces. Same declarations in hub.css; if you change one,
        change all three. Sans and mono are synced across every page. ---- */
@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/space-grotesk-latin.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/jetbrains-mono-latin.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

/* ---------- Spine tokens -------------------------------------------------- */
:root{
  /* Paper temperature — soul.css picks warm cream or cool bone */
  --paper:#F7F5F1;
  --paper-rgb:247,245,241;
  --ink:#14120F;                 /* near-black, never pure #000 */
  --ink-rgb:20,18,15;
  --card:#FFFDFA;                /* one step brighter than paper */

  /* Safety signals — CONSTANT across all ten. Do not theme these. */
  --amber:#B4761A;               /* low confidence — a human must check */
  --amber-rgb:180,118,26;
  --green:#5A7A5E;               /* pass */
  --red:#A33B2E;                 /* flag */

  /* Soul accent — overridden per product */
  --accent:#B4761A;
  --accent-rgb:180,118,26;

  /* Derived neutrals — one mixing rule, so every product's greys agree */
  --muted:color-mix(in oklab, var(--ink) 62%, var(--paper));
  --faint:color-mix(in oklab, var(--ink) 58%, var(--paper));
  --line:color-mix(in oklab, var(--ink) 13%, var(--paper));
  --line-soft:color-mix(in oklab, var(--ink) 7%, var(--paper));
  --surface:color-mix(in oklab, var(--ink) 4%, var(--paper));
  --surface-2:color-mix(in oklab, var(--ink) 8%, var(--paper));

  /* Type */
  --font-display:'Instrument Serif','Marcellus',Georgia,'Times New Roman',serif;
  --font-body:"Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Fluid scale */
  --t-display:clamp(2.6rem,1.4rem + 4.6vw,5.25rem);
  --t-h2:clamp(1.75rem,1.15rem + 2.1vw,2.75rem);
  --t-h3:clamp(1.15rem,1rem + .6vw,1.4rem);
  --t-body:clamp(.975rem,.94rem + .16vw,1.075rem);
  --t-small:.8125rem;
  --t-micro:.6875rem;

  /* Rhythm */
  --gut:clamp(1.25rem,.8rem + 1.8vw,2.5rem);
  --sec:clamp(3.5rem,2rem + 6vw,7rem);
  --maxw:1180px;
  --radius:10px;
  --radius-sm:6px;

  /* Motion — Emil curves. The built-in CSS easings are too weak. */
  --ease-out:cubic-bezier(0.23,1,0.32,1);      /* enter / exit UI */
  --ease-in-out:cubic-bezier(0.77,0,0.175,1);  /* on-screen movement */
  --ease-drawer:cubic-bezier(0.32,0.72,0,1);   /* panels, sheets */
  --dur-fast:120ms;
  --dur:180ms;
  --dur-slow:280ms;
}

/* ---------- Reset / ground ------------------------------------------------ */
*,*::before,*::after{box-sizing:border-box;}
ind-nav,ind-stage{display:block;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--t-body);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img,svg,canvas{max-width:100%;display:block;}
a{color:inherit;}
button{font:inherit;color:inherit;}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px;}
::selection{background:rgba(var(--accent-rgb),.18);}

/* ---------- Type ---------------------------------------------------------- */
.display{
  font-family:var(--font-display);
  font-weight:400;
  font-size:var(--t-display);
  line-height:.98;
  letter-spacing:-.015em;
  margin:0;
}
.h2{
  font-family:var(--font-display);font-weight:400;font-size:var(--t-h2);
  line-height:1.06;letter-spacing:-.01em;margin:0;
}
.h3{font-family:var(--font-body);font-weight:600;font-size:var(--t-h3);line-height:1.28;margin:0;letter-spacing:-.005em;}
.lede{font-size:clamp(1.05rem,.98rem + .5vw,1.3rem);line-height:1.55;color:var(--muted);margin:0;max-width:62ch;}
.prose{max-width:66ch;color:var(--muted);}
.prose strong{color:var(--ink);font-weight:600;}

/* Mono is for data, labels, source chips, timestamps — never for prose. */
.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
.label{
  font-family:var(--font-mono);font-size:var(--t-micro);font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--faint);
}
.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}

/* ---------- Layout -------------------------------------------------------- */
.wrap{width:min(100% - (var(--gut) * 2),var(--maxw));margin-inline:auto;}
.wrap-wide{width:min(100% - (var(--gut) * 2),1440px);margin-inline:auto;}
.section{padding-block:var(--sec);}
.rule{border:0;border-top:1px solid var(--line);margin:0;}
.stack > * + *{margin-top:1rem;}
.cluster{display:flex;flex-wrap:wrap;gap:.65rem;align-items:center;}

/* ---------- Chrome: nav + footer ------------------------------------------ */
.ind-nav{
  position:sticky;top:0;z-index:60;
  background:rgba(var(--paper-rgb),.86);
  backdrop-filter:blur(14px) saturate(1.4);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
}
/* A scroll edge, not a divider. The 1px rule that used to sit here drew a line
   whether or not anything was under it; this fades the content out as it slides
   beneath the floating chrome, which is what is actually happening. */
.ind-nav::after{
  content:'';position:absolute;left:0;right:0;top:100%;height:16px;
  background:linear-gradient(to bottom,rgba(var(--paper-rgb),.9),rgba(var(--paper-rgb),0));
  pointer-events:none;
}
.ind-nav__in{display:flex;align-items:center;gap:1.25rem;min-height:58px;}
.ind-nav__mark{display:flex;align-items:baseline;gap:.55rem;text-decoration:none;margin-right:auto;}
.ind-nav__no{font-family:var(--font-mono);font-size:var(--t-micro);color:var(--accent);letter-spacing:.1em;}
.ind-nav__name{
  font-family:var(--font-body);font-weight:600;font-size:.95rem;
  letter-spacing:.2em;text-transform:uppercase;
}
.ind-nav__links{display:flex;flex-wrap:wrap;gap:.5rem 1.15rem;align-items:center;}
.ind-nav__links a{
  text-decoration:none;font-size:var(--t-small);color:var(--muted);white-space:nowrap;
  padding:.3rem 0;border-bottom:1px solid transparent;
  transition:color var(--dur) var(--ease-out),border-color var(--dur) var(--ease-out);
}
/* Below ~480px the mark + links no longer fit one row. Let the whole links
   row wrap under the mark rather than letting an individual label's own
   text wrap mid-word. */
@media (max-width:479px){
  .ind-nav__in{flex-wrap:wrap;row-gap:.35rem;}
  .ind-nav__links{width:100%;}
}
.ind-nav__links a[aria-current]{color:var(--ink);border-bottom-color:var(--accent);}
.ind-nav__tour{
  font-family:inherit;font-size:var(--t-small);color:var(--muted);white-space:nowrap;
  padding:.3rem 0;border:0;border-bottom:1px solid transparent;background:none;cursor:pointer;
  transition:color var(--dur) var(--ease-out),border-color var(--dur) var(--ease-out);
}
.ind-nav__tour:hover{color:var(--ink);border-bottom-color:var(--line);}
/* The way out. Indivesta is a guest on ipattern.co, and a guest that traps
   you is not a good one. The wordmark itself comes from /assets/css/logo.css;
   this rule only handles the separator, and it carries the same specificity as
   `.ind-nav__links a` so the nav's own type rules do not win. */
.ind-nav__links a.ind-nav__home{
  font-size:var(--logo-size);
  color:var(--ink);
  padding:0 0 0 1.15rem;
  margin-left:.15rem;
  border-left:1px solid var(--line);
  border-bottom:0;
}

/* ---------- Buttons ------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  padding:.66rem 1.15rem;border-radius:var(--radius-sm);
  border:1px solid var(--ink);background:var(--ink);color:var(--paper);
  font-size:var(--t-small);font-weight:500;letter-spacing:.01em;
  text-decoration:none;cursor:pointer;
  transition:transform var(--dur-fast) var(--ease-out),
             background-color var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out),
             color var(--dur) var(--ease-out);
}
.btn:active{transform:scale(.98);}
.btn--ghost{background:transparent;color:var(--ink);border-color:var(--line);}
.btn--accent{background:var(--accent);border-color:var(--accent);color:#fff;}
.btn--quiet{background:transparent;border-color:transparent;color:var(--muted);padding-inline:.4rem;}
.btn[disabled],.btn[aria-disabled="true"]{
  cursor:not-allowed;background:var(--surface-2);border-color:var(--line);color:var(--faint);
}
.btn[disabled]:active,.btn[aria-disabled="true"]:active{transform:none;}
.ind-nav__links a:active{color:var(--ink);opacity:.55;transition:none;}
@media (hover:hover) and (pointer:fine){
  .btn--ghost:hover{border-color:var(--ink);}
  .btn--quiet:hover{color:var(--ink);}
  .ind-nav__links a:hover{color:var(--ink);}
}

/* ---------- Cards / panels ------------------------------------------------ */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);}
.panel{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;
}
.panel__head{
  display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .75rem;
  padding:.7rem 1rem;border-bottom:1px solid var(--line);
  background:var(--surface);
}
.panel__head .label{color:var(--muted);}
.panel__body{padding:1rem;}
.panel__body--flush{padding:0;}

/* ---------- The traceability grammar: chips + dots ------------------------ */
.chip{
  display:inline-flex;align-items:center;gap:.35rem;
  font-family:var(--font-mono);font-size:var(--t-micro);
  padding:.16rem .44rem;border-radius:4px;
  background:var(--surface-2);color:var(--muted);
  border:1px solid var(--line-soft);white-space:nowrap;
}
.chip--src{
  background:rgba(var(--accent-rgb),.08);
  border-color:rgba(var(--accent-rgb),.22);
  color:color-mix(in oklab,var(--accent) 76%,var(--ink));
}
.chip--none{background:rgba(var(--amber-rgb),.1);border-color:rgba(var(--amber-rgb),.3);color:#7d5210;}
.chip--pulse{animation:chip-pulse 200ms var(--ease-out);}
@keyframes chip-pulse{
  from{background:rgba(var(--accent-rgb),.34);}
  to{background:rgba(var(--accent-rgb),.08);}
}

/* Confidence dot — high / med / low. Low is amber, always, everywhere. */
.dot{display:inline-block;width:7px;height:7px;border-radius:50%;flex:none;}
.dot--hi{background:var(--green);}
.dot--md{background:color-mix(in oklab,var(--amber) 55%,var(--faint));}
.dot--lo{background:var(--amber);}
.dot--none{background:transparent;border:1.5px solid var(--amber);}

.flag{
  display:flex;gap:.55rem;align-items:flex-start;
  font-size:var(--t-small);line-height:1.45;
  padding:.5rem .65rem;border-radius:var(--radius-sm);
  background:rgba(var(--amber-rgb),.09);
  border:1px solid rgba(var(--amber-rgb),.28);
  color:#6f4810;
}
.flag--red{background:rgba(163,59,46,.08);border-color:rgba(163,59,46,.28);color:#7c2c22;}
.flag__mark{
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.1em;
  text-transform:uppercase;padding-top:.14rem;flex:none;
}

/* ---------- Data table ---------------------------------------------------- */
.tbl{width:100%;border-collapse:collapse;font-size:var(--t-small);}
.tbl th{
  text-align:left;font-family:var(--font-mono);font-weight:500;
  font-size:var(--t-micro);letter-spacing:.12em;text-transform:uppercase;
  color:var(--faint);padding:.55rem .7rem;border-bottom:1px solid var(--line);
  background:var(--surface);position:sticky;top:0;z-index:2;
}
.tbl td{padding:.5rem .7rem;border-bottom:1px solid var(--line-soft);vertical-align:top;}
.tbl tbody tr:last-child td{border-bottom:0;}
.tbl .n{font-family:var(--font-mono);font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;}
.tbl__scroll{max-height:var(--tbl-h,420px);overflow:auto;}
.tbl tr.is-low{background:rgba(var(--amber-rgb),.055);}
.tbl tr.is-bad{background:rgba(163,59,46,.06);}
.tbl tr.is-linked{background:rgba(var(--accent-rgb),.16);}

/* ---------- The five-screen contract -------------------------------------- */
.contract{display:flex;flex-wrap:wrap;gap:.35rem;align-items:center;}
.contract__step{
  display:inline-flex;align-items:center;gap:.45rem;
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.1em;
  text-transform:uppercase;color:var(--faint);
  padding:.3rem .55rem;border-radius:4px;border:1px solid transparent;
  background:none;
  transition:color var(--dur) var(--ease-out),background-color var(--dur) var(--ease-out),border-color var(--dur) var(--ease-out);
}
.contract__step[data-done="1"]{color:var(--muted);}
.contract__step[aria-current="step"]{color:var(--ink);background:var(--card);border-color:var(--line);}
.contract__step i{width:5px;height:5px;border-radius:50%;background:var(--line);flex:none;}
.contract__step[data-done="1"] i{background:var(--green);}
.contract__step[aria-current="step"] i{background:var(--accent);}
.contract__arrow{color:var(--line);font-family:var(--font-mono);font-size:var(--t-micro);}

/* ---------- Sign-off primitive ------------------------------------------- */
.signoff{
  display:flex;flex-wrap:wrap;gap:1rem;align-items:center;
  padding:1rem;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);
}
.signoff__check{
  display:flex;gap:.6rem;align-items:flex-start;cursor:pointer;
  font-size:var(--t-small);color:var(--muted);max-width:44ch;
}
.signoff__check input{margin-top:.28rem;accent-color:var(--accent);width:15px;height:15px;flex:none;cursor:pointer;}
.signoff__who{font-family:var(--font-mono);font-size:var(--t-micro);color:var(--faint);margin-left:auto;text-align:right;line-height:1.5;}

/* Audit rows — immutable, append-only, always visible. */
.audit{list-style:none;margin:0;padding:0;font-family:var(--font-mono);font-size:var(--t-micro);}
.audit li{
  display:flex;gap:.75rem;padding:.4rem 0;border-bottom:1px dashed var(--line-soft);
  color:var(--muted);
}
.audit li:last-child{border-bottom:0;}
.audit time{color:var(--faint);flex:none;}
.audit b{font-weight:500;color:var(--ink);}
.audit__empty{color:var(--faint);}

/* ---------- Watermark ----------------------------------------------------- */
.watermark{
  position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;
  font-family:var(--font-mono);font-size:clamp(1.5rem,4.5vw,2.75rem);letter-spacing:.3em;
  color:rgba(var(--ink-rgb),.06);text-transform:uppercase;
  transform:rotate(-16deg);user-select:none;
  transition:opacity 300ms var(--ease-out);
}

/* ---------- Marketing furniture ------------------------------------------ */
.eyebrow{
  display:flex;gap:.6rem;align-items:center;flex-wrap:wrap;
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.16em;
  text-transform:uppercase;color:var(--faint);
}
.eyebrow b{color:var(--accent);font-weight:500;}
.hero{padding-block:clamp(2.5rem,1.5rem + 5vw,5rem) clamp(1.5rem,1rem + 2vw,2.5rem);}
.stage{
  position:relative;border:1px solid var(--line);border-radius:14px;
  background:var(--card);overflow:hidden;
  box-shadow:0 1px 0 rgba(var(--ink-rgb),.03),0 22px 48px -34px rgba(var(--ink-rgb),.35);
}
.stage__bar{
  display:flex;align-items:center;gap:.6rem;padding:.55rem .85rem;
  border-bottom:1px solid var(--line);background:var(--surface);
}
.stage__dots{display:flex;gap:5px;}
.stage__dots i{width:8px;height:8px;border-radius:50%;background:var(--line);display:block;}
.stage__title{font-family:var(--font-mono);font-size:var(--t-micro);color:var(--faint);letter-spacing:.1em;}

.grid-2{display:grid;gap:var(--gut);grid-template-columns:minmax(0,1fr);}
@media (min-width:900px){ .grid-2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);} }
.grid-3{display:grid;gap:var(--gut);grid-template-columns:minmax(0,1fr);}
@media (min-width:760px){ .grid-3{grid-template-columns:repeat(3,minmax(0,1fr));} }

/* The motion-budget note — the through-line of the whole set */
.budget{
  display:grid;gap:.75rem 1.75rem;align-items:start;
  padding:1.15rem 1.25rem;border-radius:var(--radius);
  border:1px solid var(--line);background:var(--surface);
}
@media (min-width:820px){ .budget{grid-template-columns:auto auto minmax(0,1fr);} }
.budget__k{font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--faint);}
.budget__v{font-family:var(--font-mono);font-size:var(--t-small);color:var(--ink);}
.budget__why{font-size:var(--t-small);color:var(--muted);max-width:56ch;}

/* Won't-do list — the honesty block */
.wont{list-style:none;margin:0;padding:0;display:grid;gap:.6rem;grid-template-columns:minmax(0,1fr);}
.wont li{position:relative;padding-left:1.25rem;font-size:var(--t-small);color:var(--muted);}
.wont li::before{content:'\2014';position:absolute;left:0;top:0;font-family:var(--font-mono);color:var(--red);line-height:1.6;}

/* ---------- Enter animation (opt-in per element) -------------------------- */
.enter{opacity:0;transform:scale(.98);}
.enter.is-in{
  opacity:1;transform:none;
  transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out);
}

/* ---------- The workbench (shared by all ten tools) ----------------------
   Every tool is the same room: a contract strip that says where you are, a
   named human in the corner, a narrow ingest rail and a wide work surface. */
.wb{padding-block:1.1rem 0;}
.wb__bar{
  display:flex;gap:1rem 1.5rem;align-items:center;flex-wrap:wrap;
  padding:.4rem 0 1rem;border-bottom:1px solid var(--line);
}
.wb__who{
  margin-left:auto;font-family:var(--font-mono);font-size:var(--t-micro);
  color:var(--faint);text-align:right;line-height:1.55;
}
.wb__who b{color:var(--ink);font-weight:500;}
.wb__grid{display:grid;gap:var(--gut);margin-top:1.5rem;align-items:start;}
@media (min-width:1040px){ .wb__grid{grid-template-columns:20rem minmax(0,1fr);} }
@media (min-width:1040px){ .wb__grid--wide{grid-template-columns:17rem minmax(0,1fr);} }
.wb__col{display:grid;gap:1rem;align-content:start;}
.wb__state{
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.1em;
  text-transform:uppercase;color:var(--faint);
}
.wb__stat{display:flex;gap:1.25rem;flex-wrap:wrap;font-family:var(--font-mono);font-size:var(--t-micro);color:var(--faint);}
.wb__stat b{color:var(--ink);font-weight:500;font-size:var(--t-small);}
.wb__note{font-size:var(--t-small);color:var(--faint);max-width:64ch;}
.is-hidden{display:none !important;}
.toggle{
  display:inline-flex;align-items:center;gap:.55rem;cursor:pointer;
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);
}
.toggle input{position:absolute;opacity:0;width:0;height:0;}
.toggle__track{
  width:34px;height:19px;border-radius:19px;background:var(--surface-2);
  border:1px solid var(--line);position:relative;flex:none;
  transition:background-color var(--dur) var(--ease-out),border-color var(--dur) var(--ease-out);
}
.toggle__track::after{
  content:'';position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;
  background:var(--faint);
  transition:left 180ms var(--ease-out),background-color 180ms var(--ease-out);
}
.toggle input:checked + .toggle__track{background:rgba(var(--accent-rgb),.16);border-color:rgba(var(--accent-rgb),.4);}
.toggle input:checked + .toggle__track::after{left:16px;background:var(--accent);}
.toggle input:focus-visible + .toggle__track{outline:2px solid var(--accent);outline-offset:2px;}


/* ---------- Reduced motion ------------------------------------------------
   Keep opacity and colour. Drop movement. Never remove the information. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:1ms !important;animation-iteration-count:1 !important;
    transition-duration:1ms !important;scroll-behavior:auto !important;
  }
  .enter{opacity:1;transform:none;}
  .btn:active{transform:none;}
}

/* ---------- Reduced transparency ------------------------------------------
   The product nav is a translucent layer over scrolling content. Asked for
   less transparency, it becomes solid — and the scroll edge goes with it,
   because a fade over an opaque bar is just a smudge. */
@media (prefers-reduced-transparency:reduce){
  .ind-nav{
    background:var(--paper);
    backdrop-filter:none;-webkit-backdrop-filter:none;
    border-bottom:1px solid var(--line);
  }
  .ind-nav::after{display:none;}
}

/* ---------- More contrast --------------------------------------------------
   Solid chrome, defined borders, and the derived greys promoted towards ink.
   The safety colours are NOT touched: amber, green and red mean the same thing
   at every contrast setting, and re-tinting them would break that promise. */
@media (prefers-contrast:more){
  .ind-nav{
    background:var(--paper);
    backdrop-filter:none;-webkit-backdrop-filter:none;
    border-bottom:1px solid var(--ink);
  }
  .ind-nav::after{display:none;}
  :root{
    --muted:color-mix(in oklab, var(--ink) 86%, var(--paper));
    --faint:color-mix(in oklab, var(--ink) 70%, var(--paper));
    --line:color-mix(in oklab, var(--ink) 40%, var(--paper));
    --line-soft:color-mix(in oklab, var(--ink) 24%, var(--paper));
  }
  .card,.panel,.chip,.btn--ghost{border-color:var(--line);}
  .tbl th{border-bottom-color:var(--ink);}
}

.skip-link{
  position:absolute;left:-9999px;top:0;z-index:100;
  padding:.7rem 1rem;background:var(--ink);color:var(--paper);
  font-family:var(--font-mono);font-size:.75rem;letter-spacing:.08em;
  text-transform:uppercase;text-decoration:none;
}
.skip-link:focus{left:0;}
[tabindex="-1"]:focus{outline:none;}

/* ---------- Landing-page walkthrough: Manual/Auto Play + ghost cursor -----
   Shared by every spine-based product's index.html — the four "Trace family"
   pages fork the whole stylesheet already, so they carry their own copy of
   this instead. Reference implementation: CommentSmart's index.html (a pill
   toggle, a narrative caption, and a pointer that moves to + pulses on the
   real control being demonstrated in Auto Play, or bobs as a hint over the
   next sensible click in Manual). The host that positions .wt-pointer needs
   position:relative — set per product, since the right host varies. */
.wt-bar{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem 1.25rem;margin-bottom:1.25rem;}
.wt-toggle{display:inline-flex;border:1px solid var(--line);border-radius:999px;padding:3px;gap:2px;background:var(--surface);flex:none;}
.wt-toggle-btn{
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.06em;text-transform:uppercase;
  padding:.4rem .8rem;border:0;background:none;border-radius:999px;color:var(--faint);cursor:pointer;
  transition:background-color var(--dur) var(--ease-out),color var(--dur) var(--ease-out);
}
.wt-toggle-btn.is-on{background:var(--ink);color:var(--paper);}
.wt-narrative{flex:1 1 320px;min-width:0;margin:0;font-size:var(--t-small);line-height:1.55;color:var(--muted);}
.wt-narrative b{color:var(--ink);}

.wt-pointer{
  position:absolute;top:0;left:0;width:22px;height:22px;z-index:40;pointer-events:none;
  transform:translate(-9999px,-9999px);opacity:0;
  transition:transform .55s var(--ease-in-out),opacity .25s var(--ease-out);
  filter:drop-shadow(0 2px 5px rgba(var(--ink-rgb),.35));
}
.wt-pointer.visible{opacity:1;}
.wt-pointer-bob{display:block;position:relative;}
.wt-pointer.hint .wt-pointer-bob{animation:wtBob 1.1s ease-in-out infinite;}
@keyframes wtBob{0%,100%{transform:translate(0,0);}50%{transform:translate(-3px,4px);}}
.wt-pointer-ring{
  position:absolute;left:-7px;top:-7px;width:20px;height:20px;border-radius:50%;
  border:2px solid var(--accent);opacity:0;
}
.wt-pointer.pulse .wt-pointer-ring{animation:wtPulse .6s ease-out;}
@keyframes wtPulse{0%{transform:scale(.3);opacity:.9;}100%{transform:scale(1.9);opacity:0;}}
@media (prefers-reduced-motion:reduce){
  .wt-pointer{transition:none;}
  .wt-pointer.hint .wt-pointer-bob,.wt-pointer.pulse .wt-pointer-ring{animation:none;}
}

/* ---------- Walkthrough console: one screen, and the reader is never dragged --
   Added when the walkthroughs were rebuilt to run the real tool in the page.
   Three problems these rules solve, all reported from the live pages:
     1. the console was taller than the window, so following the ghost cursor
        meant scrolling the page up and down;
     2. the narration sat beside the mode buttons as grey text, and read as a
        caption rather than as an instruction;
     3. nothing said what the cursor was about to click.
   The host element carries .wt-console and position:relative. */
.wt-console{position:relative;}
@media (min-width:900px){
  .wt-console--fit{
    display:flex;flex-direction:column;
    /* the cap has to leave room for the pinned menu as well as a margin, or the
       console's own header parks underneath it */
    max-height:calc(100vh - var(--wt-headroom, 40px));
    max-height:calc(100dvh - var(--wt-headroom, 40px));
    overflow:hidden;              /* the cap has to clip, or the overflow paints
                                     over whatever section sits above or below */
  }
  /* align-items:start is common on these grids and would let each column keep its
     natural height and spill out of the capped box instead of scrolling inside it */
  .wt-console--fit .wt-panes{flex:1 1 auto;min-height:0;align-items:stretch !important;}
  .wt-console--fit .wt-panes > *{min-height:0;overflow-y:auto;overscroll-behavior:contain;padding-bottom:1.5rem;}
  /* the ghost pointer belongs to the console, but if a product puts it inside the
     pane row anyway it must not be given a scroller — its caption hangs well
     outside its 22px box and would be clipped away. */
  .wt-console--fit .wt-panes > .wt-pointer{overflow:visible;padding:0;min-height:0;}
  .wt-console--fit .wt-panes > *::-webkit-scrollbar{width:9px;}
  .wt-console--fit .wt-panes > *::-webkit-scrollbar-track{background:transparent;}
  .wt-console--fit .wt-panes > *::-webkit-scrollbar-thumb{
    background:rgba(var(--ink-rgb),.16);border-radius:9px;border:2px solid transparent;background-clip:padding-box;
  }
  .wt-console--fit .wt-panes > *:hover::-webkit-scrollbar-thumb{background:rgba(var(--ink-rgb),.3);background-clip:padding-box;}
}

/* controls: Manual | Auto Play, then Play/Pause and Reset */
.wt-play-btn{
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.05em;font-weight:600;
  padding:.4rem .8rem;border-radius:8px;border:1px solid var(--line);background:var(--surface);
  color:var(--ink);cursor:pointer;white-space:nowrap;flex:none;
  transition:border-color var(--dur) var(--ease-out),color var(--dur) var(--ease-out);
}
.wt-play-btn:hover{border-color:var(--muted);}
.wt-play-btn.paused{color:var(--accent);border-color:var(--accent);}
.wt-reset-btn{color:var(--faint);}
.wt-reset-btn:hover{color:var(--ink);}
.wt-bar-hint{flex:1 1 240px;min-width:0;margin:0;font-size:var(--t-micro);line-height:1.5;color:var(--faint);}

/* always one click from the full-size tool */
.wt-tool-link{
  flex:none;margin-left:auto;white-space:nowrap;text-decoration:none;
  font-family:var(--font-mono);font-size:var(--t-micro);font-weight:600;letter-spacing:.03em;
  padding:7px 14px;border-radius:8px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink);transition:border-color .2s ease,background-color .2s ease;
}
.wt-tool-link:hover{border-color:var(--ink);}
@media (max-width:560px){ .wt-tool-link{margin-left:0;} }
@media (max-width:560px){
  .wt-bar{gap:.5rem;}
  .wt-bar .wt-controls{flex:1 1 100%;min-width:0;flex-wrap:wrap;gap:.5rem;}
}
.wt-controls{display:flex;align-items:center;gap:.6rem;flex:none;flex-wrap:wrap;}

/* the narration band: what is happening right now, in its own space */
.wt-say{
  display:flex;align-items:flex-start;gap:1rem;
  padding:.85rem 1.1rem .85rem .9rem;margin-bottom:1.1rem;
  border:1px solid var(--line);border-left:4px solid var(--accent);border-radius:10px;
  background:rgba(var(--accent-rgb),.07);
}
.wt-say.flash{animation:wtSayFlash 1.1s var(--ease-out);}
@keyframes wtSayFlash{
  0%,18%{background:rgba(var(--accent-rgb),.2);}
  100%{background:rgba(var(--accent-rgb),.07);}
}
.wt-say__meta{display:flex;flex-direction:column;align-items:center;gap:.3rem;flex:none;width:6.5rem;padding-top:.1rem;}
.wt-say__count{
  font-family:var(--font-mono);font-size:var(--t-micro);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--paper);background:var(--accent);padding:.15rem .55rem;border-radius:999px;white-space:nowrap;
}
.wt-say__stage{
  font-family:var(--font-mono);font-size:var(--t-micro);font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--accent);text-align:center;line-height:1.35;
}
.wt-say__text{margin:0;flex:1;min-width:0;font-size:var(--t-body,1rem);line-height:1.6;color:var(--ink);text-wrap:pretty;}
.wt-say__text b{font-weight:700;}
@media (max-width:640px){
  .wt-say{flex-direction:column;gap:.55rem;}
  .wt-say__meta{flex-direction:row;align-items:center;gap:.55rem;width:auto;}
  .wt-say__stage{text-align:left;}
}

/* the pointer says what it is about to do, so the instruction is where the eye is */
.wt-pointer-say{
  position:absolute;left:19px;top:15px;white-space:nowrap;pointer-events:none;
  font-family:var(--font-mono);font-size:var(--t-micro);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  background:var(--ink);color:var(--paper);padding:.25rem .55rem;border-radius:6px;
  box-shadow:0 4px 12px rgba(var(--ink-rgb),.3);opacity:0;transition:opacity var(--dur) var(--ease-out);
}
.wt-pointer.visible .wt-pointer-say{opacity:1;}
.wt-pointer-say:empty{display:none;}
.wt-pointer.flip-x .wt-pointer-say{left:auto;right:16px;}
.wt-pointer.flip-y .wt-pointer-say{top:auto;bottom:14px;}

/* while auto play drives, the reader watches rather than clicks */
.wt-console.is-auto .wt-panes button:not(.wt-toggle-btn):not(.wt-play-btn),
.wt-console.is-auto .wt-panes input,
.wt-console.is-auto .wt-panes textarea,
.wt-console.is-auto .wt-panes label{pointer-events:none;}

/* ---------- Guided tour ----------------------------------------------------
   Five fixed elements: a top progress/mode bar, a full-screen click-catcher,
   a spotlight ring (its own box-shadow doubles as the dim backdrop — nothing
   else needs painting), a ghost cursor that rests on whatever this step's
   click target is, and the tooltip card. See IND.tour() in
   indivesta-spine.js. Stacking: catch 998 < ring 999 < cursor 1000 <
   card 1001 < bar 1002 — the bar always reads on top. */
.ind-tour__bar{
  position:fixed;inset:0 0 auto 0;z-index:1002;display:flex;align-items:center;gap:1rem;
  padding:.65rem 1rem;background:var(--card);border-bottom:1px solid var(--line);
}
.ind-tour__segs{display:flex;gap:.35rem;flex:1;max-width:480px;}
.ind-tour__seg{
  flex:1;height:4px;padding:0;border:0;border-radius:2px;background:var(--line-soft);
  position:relative;overflow:hidden;cursor:pointer;
}
.ind-tour__seg-fill{position:absolute;inset:0;width:0;background:var(--accent);border-radius:inherit;}
.ind-tour__seg[data-state="done"] .ind-tour__seg-fill{width:100%;opacity:.4;}
.ind-tour__seg[data-state="active"] .ind-tour__seg-fill{width:100%;}
.ind-tour__modes{
  margin-left:auto;display:flex;gap:2px;padding:2px;border:1px solid var(--line);
  border-radius:999px;background:var(--surface);flex:none;
}
.ind-tour__mode-btn{
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.06em;text-transform:uppercase;
  color:var(--faint);background:none;border:0;border-radius:999px;padding:.3rem .7rem;cursor:pointer;
  transition:background-color var(--dur) var(--ease-out),color var(--dur) var(--ease-out);
}
.ind-tour__mode-btn[aria-pressed="true"]{background:var(--ink);color:var(--paper);}
.ind-tour__close{
  flex:none;font-size:1.2rem;line-height:1;color:var(--faint);background:none;border:0;
  cursor:pointer;padding:0 .2rem;
}
.ind-tour__close:hover{color:var(--ink);}

.ind-tour__catch{position:fixed;inset:0;z-index:998;background:transparent;}
.ind-tour__ring{
  position:fixed;z-index:999;pointer-events:none;border-radius:var(--radius);
  border:2px solid var(--accent);
  box-shadow:0 0 0 9999px rgba(var(--ink-rgb),.55);
  transition:left var(--dur-slow) var(--ease-in-out),top var(--dur-slow) var(--ease-in-out),
             width var(--dur-slow) var(--ease-in-out),height var(--dur-slow) var(--ease-in-out);
}
.ind-tour__cursor{
  position:fixed;left:0;top:0;z-index:1000;pointer-events:none;
  filter:drop-shadow(0 2px 5px rgba(var(--ink-rgb),.4));
  transition:transform var(--dur-slow) var(--ease-in-out);
}
.ind-tour__cursor::after{
  content:'';position:absolute;left:2px;top:1px;width:14px;height:14px;border-radius:50%;
  border:2px solid var(--accent);animation:ind-tour-ping 1.6s var(--ease-out) infinite;
}
@keyframes ind-tour-ping{
  0%{transform:scale(.4);opacity:.9;}
  70%,100%{transform:scale(1.8);opacity:0;}
}
.ind-tour__card{
  position:fixed;z-index:1001;background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);padding:1rem;box-shadow:0 24px 60px -24px rgba(var(--ink-rgb),.4);
  transition:left var(--dur-slow) var(--ease-in-out),top var(--dur-slow) var(--ease-in-out);
}
.ind-tour__title{margin:0 0 .4rem;font-weight:600;color:var(--ink);font-size:var(--t-small);}
.ind-tour__body{margin:0;font-size:var(--t-small);line-height:1.55;color:var(--muted);}
.ind-tour__row{display:flex;justify-content:space-between;align-items:center;gap:1rem;margin-top:.9rem;}
.ind-tour__row .btn{padding:.4rem .85rem;font-size:var(--t-small);}
@media (prefers-reduced-motion:reduce){
  .ind-tour__ring,.ind-tour__card,.ind-tour__cursor{transition:none;}
  .ind-tour__cursor::after{animation:none;display:none;}
}
@media (max-width:560px){
  .ind-tour__bar{flex-wrap:wrap;}
  .ind-tour__segs{order:1;flex-basis:100%;max-width:none;}
}

/* ---------- Nav anchors ----------------------------------------------------
   The nav is sticky and about 58px tall, so a fragment jump would otherwise
   land the target's first line underneath it. `:where()` keeps this at zero
   specificity: any page that wants a different offset just sets its own. */
:where(#overview,#how-to-use,#before-after,.ind-anchor){scroll-margin-top:5rem;}
/* A zero-height marker for a section that already owns its id (a console the
   product's own script looks up by id). It adds an anchor without taking one
   away. */
.ind-anchor{display:block;height:0;}

/* ---------- Hero industry line ---------------------------------------------
   The number and product name live top-left in <ind-nav>, so the hero opens
   on the <h1>. The transformation + industry sits after the .lede instead,
   reusing .eyebrow so it inherits each page's own palette and type. Appended
   last on purpose: this sheet's cascade is order-sensitive. Bottom margin is
   zeroed so the following .cluster keeps sole control of the gap to the CTAs. */
.hero-industry{margin:1.1rem 0 0;}

/* The spine's menu is sticky, so it sits over the top of whatever is beneath it.
   The one-screen console is capped against the room left under it, not the whole
   window. 58px of menu plus the 40px breathing margin. */
:root{ --wt-headroom:98px; }

/* ---- tool.html's own strip -------------------------------------------------
   "How it works" and "Reset the demo" used to sit inside the menu, between Demo
   and Showcases, where two buttons read as two more destinations and made the
   tool page's menu differ from every other page's. They live here instead,
   under the menu, with the one line of orientation the tool page never had:
   the landing pages narrate themselves through the walkthrough band, but anyone
   who opens the tool directly arrived with no idea what they were looking at. */
.ind-toolbar{
  border-bottom:1px solid var(--line);
  background:rgba(var(--paper-rgb),.7);
}
.ind-toolbar__in{
  display:flex;align-items:center;gap:1rem 1.5rem;flex-wrap:wrap;
  padding-block:.7rem;
}
.ind-toolbar__hint{
  margin:0;flex:1 1 24ch;min-width:0;
  font-size:var(--t-small);line-height:1.5;color:var(--muted);
}
.ind-toolbar__hint b{color:var(--ink);font-weight:600;}
.ind-toolbar__acts{display:flex;gap:.5rem;flex:none;}
.ind-toolbar__btn{
  font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.04em;
  white-space:nowrap;padding:.45rem .85rem;border-radius:999px;cursor:pointer;
  border:1px solid var(--line);background:transparent;color:var(--ink);
  transition:border-color var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.ind-toolbar__btn:hover{border-color:var(--ink);background:rgba(var(--ink-rgb),.04);}
@media (max-width:640px){
  .ind-toolbar__in{padding-block:.6rem;}
  .ind-toolbar__acts{width:100%;}
  .ind-toolbar__btn{flex:1 1 auto;text-align:center;}
}
