/* ══════════════════════════════════════════════════════════════════════════
   ZipQuarry — writing section
   ─────────────────────────────────────────────────────────────────────────
   The one stylesheet shared by /writing/. index.html at the root is still a
   single self-contained file; this exists so several article pages do not
   carry several drifting copies of the same tokens.

   Still no build step: this is a plain <link>, nothing compiles it.
   The token block below is a VERBATIM copy of the :root in ../index.html.
   If you change a token there, change it here. See BRAND.md section 1.

   GitHub Pages serves this with cache-control: max-age=600, so a returning
   visitor can get a stale copy of this file alongside fresh HTML. Every page
   in /writing/ therefore links it as ?v=N. **Bump that N in all four HTML
   files whenever you change this file.** Currently v=2.
   ══════════════════════════════════════════════════════════════════════════ */

:root{
  --navy:#0A1B33;
  --navy-soft:#33465F;
  --ink-faint:#68788F;
  --blue:#0B5FFF;
  --blue-deep:#0043C4;
  --blue-tint:#EAF1FF;
  --blue-line:#C9DAFF;
  --green:#0E9F6E;
  --green-tint:#E4F6EE;
  --cream:#FFF8EC;
  --cream-line:#F4E2BE;
  --violet:#6846D8;
  --violet-tint:#F1EDFF;
  --paper:#FFFFFF;
  --paper-warm:#F7F9FC;
  --border:#E3E9F2;
  --blue-lift:#7AA8FF;
  --mint:#7DF7C6;
  --amber:#B26A00;
  --amber-tint:#FFF4E0;
  --slate-tint:#EEF1F6;
  --map-base:#F2F6FD;
  --radius-lg:18px;
  --radius-md:12px;
  --radius-sm:10px;
  --shadow-card:0 1px 2px rgba(10,27,51,.05),0 10px 30px -12px rgba(10,27,51,.14);
  --shadow-pop:0 2px 4px rgba(10,27,51,.06),0 24px 50px -18px rgba(11,95,255,.28);
  --shadow-btn:0 1px 2px rgba(10,27,51,.10),0 10px 24px -10px rgba(11,95,255,.60);
  --shadow-btn-hover:0 2px 4px rgba(10,27,51,.12),0 18px 34px -10px rgba(11,95,255,.55);
  --nav-h:64px;
  --font-display:"Bricolage Grotesque",sans-serif;
  --font-body:"Instrument Sans",sans-serif;
  --font-mono:"Spline Sans Mono",ui-monospace,"SF Mono",monospace;
  /* writing-only */
  --measure:68ch;
}

*{margin:0;padding:0;box-sizing:border-box}
/* The `hidden` attribute is only a UA rule, so any author `display` beats it.
   `.btn{display:inline-flex}` and `.check-progress{display:grid}` both did,
   which left the angle tool's copy button live and clickable while the tool
   was telling the reader to skip the lead. Nothing here should ever have to
   remember to re-hide itself. */
[hidden]{display:none!important}
html{scroll-behavior:smooth}
body{
  font-family:var(--font-body);color:var(--navy);background:var(--paper);
  line-height:1.6;font-size:16px;-webkit-font-smoothing:antialiased;overflow-x:hidden;
}
::selection{background:var(--blue);color:#fff}
img{max-width:100%;height:auto}
.wrap{width:min(1120px,100% - 40px);margin-inline:auto}

h1,h2,h3,h4{font-family:var(--font-display);line-height:1.14;letter-spacing:-.02em;font-weight:800}
h1,h2{text-wrap:balance}
p{text-wrap:pretty}

.hl{
  color:var(--blue-deep);
  background:linear-gradient(180deg,transparent 60%,rgba(11,95,255,.16) 60%,rgba(11,95,255,.16) 93%,transparent 93%);
  -webkit-box-decoration-break:clone;box-decoration-break:clone;padding:0 .07em;border-radius:.05em;
}

:focus-visible{outline:2.5px solid var(--blue);outline-offset:3px;border-radius:4px}
.btn:focus-visible{border-radius:999px}
.cta-band :focus-visible{outline-color:var(--mint)}
:target,[id]{scroll-margin-top:calc(var(--nav-h) + 20px)}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.skip-link{
  position:absolute;left:12px;top:-60px;z-index:100;
  background:var(--blue);color:#fff;padding:.7em 1.2em;border-radius:0 0 var(--radius-sm) var(--radius-sm);
  text-decoration:none;font-weight:600;font-size:.9rem;transition:top .18s ease;
}
.skip-link:focus{top:0}

.kicker{
  font-family:var(--font-mono);font-size:.72rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--blue);display:inline-flex;align-items:center;gap:.55em;margin-bottom:1rem;
}
.kicker::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--blue);box-shadow:0 0 0 4px var(--blue-tint)}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  font-family:var(--font-body);font-weight:600;font-size:1rem;
  padding:.95em 1.7em;border-radius:999px;cursor:pointer;text-decoration:none;border:none;
  max-width:100%;text-align:center;min-height:44px;overflow-wrap:anywhere;
  transition:transform .18s ease,box-shadow .18s ease,background .18s ease;
}
.btn:active{transform:scale(.97)}
.btn-primary{background:linear-gradient(180deg,#2C74FF,var(--blue));color:#fff;box-shadow:var(--shadow-btn)}
.btn-primary:hover{background:linear-gradient(180deg,var(--blue),var(--blue-deep));transform:translateY(-2px);box-shadow:var(--shadow-btn-hover)}
.btn-ghost{background:transparent;color:var(--navy);border:1.5px solid var(--border)}
.btn-ghost:hover{border-color:var(--blue);color:var(--blue);transform:translateY(-2px);background:var(--blue-tint)}
.btn-invert{background:#fff;color:var(--blue-deep);box-shadow:0 10px 26px -10px rgba(0,32,96,.5)}
.btn-invert:hover{transform:translateY(-2px);box-shadow:0 16px 36px -10px rgba(0,20,60,.55)}
.btn-outline-light{background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.45);font-family:var(--font-mono);font-size:.85rem}
.btn-outline-light:hover{border-color:#fff;background:rgba(255,255,255,.1);transform:translateY(-2px)}

/* ---------- reveal ---------- */
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}
.reveal.in{opacity:1;transform:none}
.d1{transition-delay:.08s}.d2{transition-delay:.16s}.d3{transition-delay:.24s}.d4{transition-delay:.32s}

/* ---------- nav ---------- */
.nav{
  position:sticky;top:0;z-index:50;background:rgba(255,255,255,.86);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--border);
}
.nav-inner{display:flex;align-items:center;justify-content:space-between;height:64px;gap:1rem}
.logo{
  display:flex;align-items:center;gap:.6rem;text-decoration:none;color:var(--navy);
  font-family:var(--font-display);font-weight:800;font-size:1.15rem;letter-spacing:-.02em;
}
.logo-mark{width:30px;height:30px;flex:none}
.nav-right{display:flex;align-items:center;gap:1.25rem}
.nav-link{
  font-size:.9rem;font-weight:600;color:var(--navy-soft);text-decoration:none;
  transition:color .18s ease;white-space:nowrap;
}
.nav-link:hover{color:var(--blue)}
.nav-link[aria-current="page"]{color:var(--blue)}
.nav .btn{padding:.6em 1.2em;font-size:.9rem}
@media(max-width:559px){ .nav-link.hide-xs{display:none} }

/* ---------- reading progress ---------- */
/* Decorative: it duplicates what the scrollbar already says, so it is
   aria-hidden. Transform only, written from a rAF, so scrolling never
   triggers layout. 3px tall — a progress bar that needs to be noticed is
   competing with the writing. */
.progress{
  position:fixed;left:0;top:0;height:3px;width:100%;z-index:60;
  background:linear-gradient(90deg,var(--blue),var(--green));
  transform:scaleX(0);transform-origin:0 50%;will-change:transform;
}

/* ---------- article header ---------- */
.art-head{padding:clamp(2.5rem,6vw,4.5rem) 0 clamp(1.5rem,3vw,2.5rem);position:relative}
.art-head::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(rgba(10,27,51,.09) 1px,transparent 1px);
  background-size:26px 26px;
  mask-image:radial-gradient(60% 70% at 60% 10%,#000 20%,transparent 72%);
  -webkit-mask-image:radial-gradient(60% 70% at 60% 10%,#000 20%,transparent 72%);
}
.art-head .wrap{position:relative;z-index:1}
.art-head h1{font-size:clamp(2rem,5.4vw,3.25rem);letter-spacing:-.03em;max-width:20ch}
.dek{
  color:var(--navy-soft);font-size:clamp(1.05rem,2.2vw,1.3rem);
  max-width:58ch;margin-top:1.25rem;line-height:1.5;
}
.art-meta{
  display:flex;flex-wrap:wrap;gap:.5rem 1.25rem;align-items:center;margin-top:1.75rem;
  font-family:var(--font-mono);font-size:.72rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-faint);
}

/* ---------- article body ---------- */
/* minmax(0,1fr) and min-width:0, not `display:grid` alone. A grid item
   defaults to min-width:auto, so the 460px min-width on .prose table pushed
   the single-column track to 462px and scrolled the whole page sideways on a
   375px screen. The table is meant to scroll inside .table-scroll; these two
   declarations are what keep it there. */
.art-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:3rem;padding-bottom:clamp(3rem,7vw,5rem)}
.art-layout > *{min-width:0}
.prose{max-width:var(--measure);font-size:1.06rem;line-height:1.72}
.prose > * + *{margin-top:1.35rem}
.prose h2{
  font-size:clamp(1.45rem,3.4vw,1.95rem);margin-top:3.25rem;letter-spacing:-.02em;
  scroll-margin-top:calc(var(--nav-h) + 20px);
}
.prose h3{font-size:1.15rem;font-weight:600;margin-top:2.25rem;letter-spacing:-.01em}
.prose p{color:var(--navy-soft)}
.prose strong{color:var(--navy);font-weight:600}
.prose a{color:var(--blue-deep);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1.5px}
.prose a:hover{color:var(--blue)}
.prose ul,.prose ol{padding-left:1.35rem;color:var(--navy-soft)}
.prose li + li{margin-top:.55rem}
.prose li::marker{color:var(--blue)}
.prose hr{border:none;border-top:1px solid var(--border);margin:2.75rem 0}

/* Lede paragraph: the first paragraph carries a little more weight, which is
   what tells a scanner where the article actually starts. */
.prose > p.lede-p{font-size:1.16rem;color:var(--navy);line-height:1.62}

/* Pull quote. One per article at most — it is an emphasis device, and a page
   with three of them has none. */
.pull{
  border-left:3px solid var(--blue);padding:.35rem 0 .35rem 1.5rem;
  font-family:var(--font-display);font-weight:600;font-size:clamp(1.2rem,2.8vw,1.5rem);
  line-height:1.34;letter-spacing:-.02em;color:var(--navy);margin-block:2.5rem;
}

/* Callout. .note is neutral, .warn is the one that costs money to ignore. */
.callout{
  border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--paper-warm);
  padding:1.35rem 1.5rem;margin-block:2rem;
}
.callout > * + *{margin-top:.7rem}
.callout .callout-label{
  font-family:var(--font-mono);font-size:.66rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--blue-deep);display:flex;align-items:center;gap:.5em;
}
.callout p{color:var(--navy-soft);font-size:.97rem}
.callout.warn{background:var(--amber-tint);border-color:#F0DCB4}
.callout.warn .callout-label{color:var(--amber)}
.callout.good{background:var(--green-tint);border-color:#BFE7D6}
.callout.good .callout-label{color:var(--green)}

/* Example blocks: a real email draft, a real search setup. Bordered and
   scrollable on their own, so a long subject line never scrolls the page. */
.example{
  border:1px solid var(--border);border-radius:var(--radius-lg);background:#fff;
  box-shadow:var(--shadow-card);overflow:hidden;margin-block:2rem;
}
.example-head{
  display:flex;align-items:center;gap:.6rem;padding:.7rem 1rem;border-bottom:1px solid var(--border);
  background:var(--paper-warm);font-family:var(--font-mono);font-size:.68rem;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--navy-soft);
}
.example-head .dot{width:8px;height:8px;border-radius:50%;flex:none}
.dot.b{background:var(--blue)}.dot.g{background:var(--green)}.dot.a{background:var(--amber)}
.example-body{padding:1.1rem;font-size:.9rem;line-height:1.62;color:var(--navy-soft);overflow-x:auto}
.example-body .to{
  font-family:var(--font-mono);font-size:.7rem;color:var(--ink-faint);
  border-bottom:1px dashed var(--border);padding-bottom:.6rem;margin-bottom:.75rem;
}
.example-body p + p{margin-top:.7rem}
.example-body mark{
  background:var(--blue-tint);color:var(--blue-deep);padding:.05em .16em;border-radius:4px;font-weight:500;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}
.example.bad{border-color:#F0DCB4}
.example.bad .example-head{background:var(--amber-tint);color:var(--amber);border-bottom-color:#F0DCB4}

/* Comparison table. Scrolls inside itself; the page body never scrolls
   sideways because of it. */
.table-scroll{overflow-x:auto;margin-block:2rem;border:1px solid var(--border);border-radius:var(--radius-lg)}
/* Chromium focuses overflow containers on its own; Firefox and Safari do not,
   which strands a keyboard user on the clipped columns at 320px. Script adds
   tabindex only while the table actually overflows, so a table that fits does
   not become a pointless tab stop. */
.table-scroll[tabindex]:focus-visible{outline:2.5px solid var(--blue);outline-offset:2px}
.prose table{border-collapse:collapse;width:100%;min-width:460px;font-size:.92rem}
.prose th,.prose td{text-align:left;padding:.85rem 1.1rem;border-bottom:1px solid var(--border);vertical-align:top}
.prose thead th{
  background:var(--paper-warm);font-family:var(--font-mono);font-size:.66rem;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--navy-soft);
}
.prose tbody tr:last-child td{border-bottom:none}
.prose td{color:var(--navy-soft)}
.prose td strong{color:var(--navy)}

/* ---------- interactive tools ---------- */
/* Every .tool ships with the `hidden` attribute and is unhidden by script, so a
   reader without JavaScript never meets a calculator that cannot calculate.
   The prose around each tool always states the same conclusion on its own —
   the tool sharpens the argument, it never carries it alone. */
.tool{
  border:1px solid var(--blue-line);border-radius:var(--radius-lg);background:#fff;
  box-shadow:var(--shadow-card);overflow:hidden;margin-block:2.5rem;
}
.tool-head{
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:.5rem 1rem;
  padding:1rem 1.35rem;border-bottom:1px solid var(--border);background:var(--blue-tint);
}
.tool-head h3{font-size:1.05rem;margin:0;letter-spacing:-.01em}
.tool-tag{
  font-family:var(--font-mono);font-size:.6rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--blue-deep);
}
.tool-body{padding:1.35rem}
.tool-intro{font-size:.88rem;color:var(--ink-faint);margin-bottom:1.35rem}

.tool-fields{display:grid;gap:1.1rem}
.field{display:grid;gap:.45rem;min-width:0}
.field-row{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}
.field label{
  font-family:var(--font-mono);font-size:.66rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--navy-soft);
}
.field-val{
  font-family:var(--font-mono);font-size:.82rem;font-weight:600;color:var(--blue-deep);
  font-variant-numeric:tabular-nums;
}
.field .hint{font-size:.78rem;color:var(--ink-faint);line-height:1.4}
.field input[type="text"],.field input[type="number"],.field select{
  font-family:var(--font-body);font-size:1rem;color:var(--navy);width:100%;min-height:44px;
  border:1.5px solid var(--border);border-radius:var(--radius-sm);padding:.6em .8em;background:#fff;
  transition:border-color .18s ease;
}
.field input::placeholder{color:#9AA8BC}
.field input:focus,.field select:focus{border-color:var(--blue)}
/* accent-color brands the native range and checkbox without rebuilding either
   one out of divs, which is how they stay keyboard- and AT-correct. */
.field input[type="range"]{width:100%;accent-color:var(--blue);height:24px;cursor:pointer}

.tool-out{margin-top:1.5rem;border-top:1px dashed var(--border);padding-top:1.35rem;display:grid;gap:1.1rem}
.tool-figures{display:grid;gap:.75rem}
.figure{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--paper-warm);padding:.9rem 1rem}
.figure .n{
  font-family:var(--font-display);font-weight:800;font-size:1.45rem;line-height:1.1;
  letter-spacing:-.02em;color:var(--navy);font-variant-numeric:tabular-nums;
}
.figure .l{
  font-family:var(--font-mono);font-size:.6rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-faint);margin-top:.4rem;
}
.tool-sentence{font-size:1rem;color:var(--navy-soft);line-height:1.6}
.tool-sentence b{color:var(--navy);font-weight:600}
.tool-note{font-size:.78rem;color:var(--ink-faint);line-height:1.5}
.tool-actions{display:flex;flex-wrap:wrap;gap:.6rem}
.btn-sm{font-size:.85rem;padding:.6em 1.2em;min-height:40px}
.tool-noscript{
  border:1px dashed var(--border);border-radius:var(--radius-md);background:var(--paper-warm);
  padding:1rem 1.2rem;font-size:.88rem;color:var(--ink-faint);margin-block:2rem;
}

/* angle builder */
.angle-state{
  font-family:var(--font-mono);font-size:.68rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;display:flex;align-items:center;gap:.55em;
}
.angle-state::before{content:"";width:8px;height:8px;border-radius:50%;flex:none;background:var(--ink-faint)}
.angle-state.ready{color:var(--green)}
.angle-state.ready::before{background:var(--green);box-shadow:0 0 0 4px var(--green-tint)}
.angle-state.waiting{color:var(--amber)}
.angle-state.waiting::before{background:var(--amber);box-shadow:0 0 0 4px var(--amber-tint)}
.angle-line{
  border-left:3px solid var(--border);padding:.2rem 0 .2rem 1.1rem;
  font-size:1rem;line-height:1.6;color:var(--navy-soft);
}
.angle-line.ready{border-left-color:var(--green)}
.angle-line b{color:var(--navy);font-weight:600}
.angle-line .blank{color:var(--ink-faint);font-style:italic}

/* pre-send checklist */
/* Real <input type="checkbox"> in real <label>s: it is tickable with the script
   switched off, and only the progress bar, the copy button and the saved state
   are enhancements. */
.checklist{display:grid;margin-block:1.5rem}
.check-item{
  display:flex;gap:.9rem;align-items:flex-start;padding:.8rem .2rem;
  border-bottom:1px solid var(--border);cursor:pointer;
}
.check-item:last-of-type{border-bottom:none}
.check-item input{width:20px;height:20px;flex:none;margin-top:.2rem;accent-color:var(--blue);cursor:pointer}
.check-item span{font-size:.97rem;color:var(--navy-soft);line-height:1.55}
.check-item input:checked ~ span{color:var(--ink-faint)}
.check-progress{display:grid;gap:.7rem;margin-top:1.35rem;border-top:1px dashed var(--border);padding-top:1.25rem}
.check-count{
  font-family:var(--font-mono);font-size:.7rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--navy-soft);font-variant-numeric:tabular-nums;
}
.check-count.done{color:var(--green)}
.check-bar{height:6px;border-radius:999px;background:var(--slate-tint);overflow:hidden}
/* scaleX rather than width: the same reason the reading progress bar uses it. */
.check-bar i{
  display:block;height:100%;background:var(--green);transform:scaleX(0);transform-origin:0 50%;
  transition:transform .3s cubic-bezier(.2,.7,.2,1);
}

/* ---------- heading anchors ---------- */
/* A plain link, not a clipboard button: it needs no script, no permission, and
   no confirmation state, and the URL bar does the rest. */
.prose h2{position:relative}
.anchor{
  font-family:var(--font-mono);font-weight:400;color:var(--blue-line);text-decoration:none;
  margin-left:.4em;opacity:0;transition:opacity .18s ease,color .18s ease;
}
.prose h2:hover .anchor,.anchor:focus-visible{opacity:1}
.anchor:hover{color:var(--blue)}
@media(hover:none){ .anchor{opacity:1;color:var(--blue-line)} }

@media(min-width:560px){
  .tool-fields.cols-2{grid-template-columns:1fr 1fr}
  .tool-figures{grid-template-columns:repeat(3,1fr)}
}

/* ---------- table of contents ---------- */
.toc{position:sticky;top:calc(var(--nav-h) + 24px);align-self:start}
.toc-label{
  font-family:var(--font-mono);font-size:.66rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:.9rem;
}
.toc ol{list-style:none;padding:0;border-left:1px solid var(--border)}
.toc li{margin:0}
.toc a{
  display:block;padding:.5rem 0 .5rem 1rem;margin-left:-1px;
  border-left:2px solid transparent;color:var(--ink-faint);
  text-decoration:none;font-size:.87rem;line-height:1.35;
  transition:color .18s ease,border-color .18s ease;
}
.toc a:hover{color:var(--navy)}
/* aria-current is the state; the styling reads off it, so the announced
   position and the drawn position cannot disagree. */
.toc a[aria-current="true"]{color:var(--blue-deep);border-left-color:var(--blue);font-weight:600}

/* ---------- end-of-article CTA ---------- */
.art-cta{
  border:1px solid var(--blue-line);border-radius:var(--radius-lg);background:var(--blue-tint);
  padding:clamp(1.5rem,4vw,2.25rem);margin-top:3.5rem;max-width:var(--measure);
}
.art-cta h2{font-size:1.35rem;margin:0 0 .6rem}
.art-cta p{color:var(--navy-soft);font-size:.97rem;margin-bottom:1.35rem}
.art-cta .actions{display:flex;flex-wrap:wrap;gap:.7rem}

/* ---------- article index ---------- */
.idx-head{padding:clamp(3rem,7vw,5rem) 0 clamp(1.5rem,3vw,2.5rem)}
.idx-head h1{font-size:clamp(2.2rem,6vw,3.5rem);letter-spacing:-.03em;max-width:18ch}
.idx-list{display:grid;gap:1.1rem;padding-bottom:clamp(3rem,7vw,5rem)}
.art-card{
  display:grid;gap:.85rem;align-content:start;
  border:1px solid var(--border);border-radius:var(--radius-lg);
  background:#fff;box-shadow:var(--shadow-card);padding:1.6rem 1.5rem;position:relative;
  transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;
}
.art-card:hover{transform:translateY(-4px);border-color:var(--blue-line);box-shadow:var(--shadow-pop)}
/* The whole card is the target; the heading link stretches over it so the
   accessible name stays the title instead of the card's entire text. */
.art-card h2{font-size:1.3rem;letter-spacing:-.02em}
.art-card h2 a{color:var(--navy);text-decoration:none}
.art-card h2 a::after{content:"";position:absolute;inset:0}
.art-card:hover h2 a{color:var(--blue-deep)}
.art-card p{color:var(--navy-soft);font-size:.97rem;max-width:64ch}
.art-tag{
  font-family:var(--font-mono);font-size:.62rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--blue-deep);background:var(--blue-tint);
  border-radius:999px;padding:.32em .85em;width:max-content;
}
.art-tag.green{color:var(--green);background:var(--green-tint)}
.art-tag.amber{color:var(--amber);background:var(--amber-tint)}
.art-card .art-meta{margin-top:.25rem}
/* Says the article carries something to use, not just something to read.
   It is the reason to open one of these over a search result. */
.art-tool{
  display:inline-flex;align-items:center;gap:.55em;
  font-family:var(--font-mono);font-size:.63rem;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--blue-deep);
}
.art-tool::before{
  content:"";width:6px;height:6px;border-radius:50%;flex:none;
  background:var(--blue);box-shadow:0 0 0 3px var(--blue-tint);
}

/* ---------- cta band (shared with the root page) ---------- */
.cta-band{
  padding:clamp(4rem,9vw,6.5rem) 0;overflow:hidden;position:relative;
  background:linear-gradient(135deg,var(--blue-deep),var(--blue));
}
.cta-band .kicker{color:#fff}
.cta-band .kicker::before{background:var(--mint);box-shadow:0 0 0 4px rgba(125,247,198,.22)}
.cta-inner{text-align:center;position:relative;z-index:1}
.cta-inner h2{color:#fff;font-size:clamp(1.7rem,4.6vw,2.6rem);margin-bottom:1.5rem}
.cta-inner .micro{
  margin-top:1.1rem;font-family:var(--font-mono);font-size:.76rem;
  color:rgba(255,255,255,.75);max-width:44ch;margin-inline:auto;
}
.cta-actions{display:flex;flex-wrap:wrap;gap:.8rem;justify-content:center}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--border);padding:2.5rem 0 2rem;background:var(--paper-warm)}
.foot{display:grid;gap:1.5rem}
.foot-top,.foot-bottom{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.6rem 1.5rem}
.foot-bottom{border-top:1px solid var(--border);padding-top:1.25rem}
.foot small{font-family:var(--font-mono);font-size:.68rem;color:var(--ink-faint);letter-spacing:.04em}
.foot-links{display:flex;flex-wrap:wrap;gap:.6rem 1.25rem}
.foot-links a{font-size:.85rem;color:var(--navy-soft);text-decoration:none;transition:color .18s ease}
.foot-links a:hover{color:var(--blue)}
.made-by a{color:var(--blue);text-decoration:none;font-weight:600}
.made-by a:hover{text-decoration:underline}

/* ---------- responsive ---------- */
@media(min-width:1000px){
  /* TOC to the left of the text: the measure stays honest and the reader's
     eye does not have to cross the column to know where they are. */
  .art-layout{grid-template-columns:220px minmax(0,1fr);gap:4rem}
  .idx-list{grid-template-columns:1fr 1fr}
}
@media(min-width:720px) and (max-width:999px){
  .idx-list{grid-template-columns:1fr 1fr}
}
@media(max-width:999px){
  /* Below the two-column breakpoint the sticky TOC would eat the top of every
     screen, so it collapses into a plain block under the header. */
  .toc{
    position:static;border:1px solid var(--border);border-radius:var(--radius-lg);
    background:var(--paper-warm);padding:1.1rem 1.25rem;
  }
  .toc ol{border-left:none}
  .toc a{padding:.4rem 0;border-left:none}
  .toc a[aria-current="true"]{border-left:none}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .reveal{opacity:1;transform:none}
  html{scroll-behavior:auto}
  /* The progress bar still tracks position; it just stops being a moving
     thing. Hiding it would remove information, so it stays. */
}
