/* ============================================================
   SIGNAL FIELD — styles.css
   World: a warm instrument panel under a drifting aurora, in two
   renditions. Daylight (the default) sits on warm linen; Night
   sits on near-black. One accent through both — Xavier's brand
   gold: outline = information, fill = action.
   Layout follows claude.com/plugins: card grid + detail pages.
   Default lives on :root, so no-JS and crawlers get it; theme.js
   opts into Night with html[data-theme="dark"]. See DESIGN.md.
   ============================================================ */

:root {
  /* ---- Daylight: the default rendition ----
     Warm linen ground from the AI 101 course's printed-paper build.
     One gold family, two duties: --accent is the text-duty gold
     (the Night gold reads 1.5:1 on linen), --accent-fill keeps the
     brand-gold tile with ink text (6.4:1, the course's own pairing). */
  --bg: #F2ECE0;
  --bg-raise: #E7DECB;
  --ink: #1A1815;
  --body-ink: #4F473D;   /* 7.76:1 on linen */
  --muted: #665C4E;      /* 5.57:1 linen, 4.90:1 sand — holds at the mono step */
  --line: rgba(26, 24, 21, 0.12);
  --line-bright: rgba(26, 24, 21, 0.28);

  --accent: #6F5631;     /* text-duty gold: 5.85:1 linen, 5.15:1 sand */
  --accent-soft: rgba(111, 86, 49, 0.10);
  --accent-line: rgba(111, 86, 49, 0.38);
  --accent-fill: #B6966F;
  --on-accent: #1A1815;

  /* aurora on linen: pools can't lighten a light ground, so they stain it
     toward sand. Alphas are contrast-capped — the darkest composite
     ≈#E7DDCC keeps --muted at 4.87:1. Raising them breaks WCAG, not taste. */
  --aurora-gold: rgba(182, 150, 111, 0.18);
  --aurora-copper: rgba(190, 130, 80, 0.10);
  --aurora-bronze: rgba(140, 95, 55, 0.08);

  --glass: rgba(255, 255, 255, 0.55);
  --glass-hover: rgba(255, 255, 255, 0.75);
  --card-glow: rgba(111, 86, 49, 0.28);
  --pulse-rgb: 111, 86, 49;
  --select: rgba(182, 150, 111, 0.40);

  --font-display: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Fragment Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --pad: clamp(20px, 5vw, 48px);
  /* ONE container for every surface — the log, the course and the curator all
     sit in this width, so the three tabs share their left and right edges and
     nothing shifts as you cross between them. Floors at the original 1180 so
     the desktop rhythm the design was tuned at is unchanged; ceilings at 1440,
     the widest the reading surfaces stay comfortable at (the card grid adds a
     column there instead of stretching). */
  --page-w: clamp(1180px, 90vw, 1440px);
  --radius: 16px;
  --radius-sm: 10px;
  /* smallest comfortable hit area for a pointer or thumb */
  --tap: 44px;
  /* every mono label reads off this one step — chips, counts, section
     labels — so a size change is one line and nothing drifts out of step */
  --m-size: 0.85rem;
  /* wayfinding sits a step above the label tier: the masthead, the tabs and
     the breadcrumbs are read before anything else, where the label step's
     density is the wrong trade */
  --nav-size: 1rem;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- Signal Field, Night ----------
   The dark rendition: the warm near-black instrument panel the site was
   first drawn in. Gold runs luminous here, so the aurora alphas run low
   and the fill treatment is the pale brand gold on the void.
   Opt-in — theme.js sets html[data-theme="dark"] from the stored choice. */

html[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0a0908;
  --bg-raise: #131110;
  --ink: #f4f2ef;
  --body-ink: #c4bfb6;
  --muted: #948d82;
  --line: rgba(244, 242, 239, 0.1);
  --line-bright: rgba(244, 242, 239, 0.24);

  --accent: #e0bf91;
  --accent-soft: rgba(224, 191, 145, 0.13);
  --accent-line: rgba(224, 191, 145, 0.3);
  /* on the void the accent needs no darkening, so fill IS the accent */
  --accent-fill: var(--accent);
  --on-accent: var(--bg);

  --aurora-gold: rgba(224, 191, 145, 0.1);
  --aurora-copper: rgba(190, 130, 80, 0.14);
  --aurora-bronze: rgba(140, 95, 55, 0.12);

  --glass: rgba(255, 255, 255, 0.025);
  --glass-hover: rgba(255, 255, 255, 0.04);
  --card-glow: rgba(224, 191, 145, 0.3);
  --pulse-rgb: 224, 191, 145;
  --select: rgba(224, 191, 145, 0.3);
}

/* ---------- base ---------- */

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; color-scheme: light; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.7;
  color: var(--body-ink);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

::selection { background: var(--select); color: var(--ink); }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--pad);
  top: -48px;
  z-index: 30;
  padding: 8px 14px;
  background: var(--bg-raise);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--m-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: top 0.2s var(--ease-out);
}
.skip-link:focus { top: 12px; }

/* mono label utility — signal voice */
.m {
  font-family: var(--font-mono);
  font-size: var(--m-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---------- the aurora ---------- */

.aurora {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--bg);
}
.aurora span {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  will-change: transform;
}
.aurora .a1 {
  width: 60vmax; height: 60vmax;
  left: -18vmax; top: -24vmax;
  background: radial-gradient(closest-side, var(--aurora-gold), transparent 70%);
  animation: drift-1 64s ease-in-out infinite alternate;
}
.aurora .a2 {
  width: 52vmax; height: 52vmax;
  right: -20vmax; top: 4vmax;
  background: radial-gradient(closest-side, var(--aurora-copper), transparent 70%);
  animation: drift-2 76s ease-in-out infinite alternate;
}
.aurora .a3 {
  width: 46vmax; height: 46vmax;
  left: 8vmax; bottom: -26vmax;
  background: radial-gradient(closest-side, var(--aurora-bronze), transparent 70%);
  animation: drift-3 88s ease-in-out infinite alternate;
}
@keyframes drift-1 {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(10vmax, 6vmax, 0) scale(1.15); }
}
@keyframes drift-2 {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to { transform: translate3d(-8vmax, 10vmax, 0) scale(0.95); }
}
@keyframes drift-3 {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(6vmax, -8vmax, 0) scale(1.2); }
}

/* ---------- page scaffold ---------- */

.page {
  max-width: var(--page-w);
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* Detail pages (tools, the curator) share the one container above — no
   narrower cap, so their masthead and tabs line up with the other tabs'.
   The prose inside keeps its own measure caps (.detail-lede, .sections). */

/* ---------- masthead (one bar: wordmark left, sections right) ----------
   User-pinned reference (2026-08-12): the Cold Set / FOLD header pattern —
   the brand as a real wordmark with a muted gloss beside it, and quiet
   tracked-uppercase links whose 1px underline draws in from the left on
   hover. The active page holds that underline in gold. */

.site-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px 28px;
  padding: 26px 0 18px;
  border-bottom: 1px solid var(--line);
}
.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 14px;
  text-decoration: none;
}
.brand:hover { text-decoration: none; }
.brand-mark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.brand-sub { color: var(--muted); }

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px clamp(20px, 2.6vw, 40px);
}
.site-nav a {
  position: relative;
  color: var(--muted);
  text-decoration: none;
  letter-spacing: 0.14em;
  padding-bottom: 6px;
  white-space: nowrap;
  transition: color 0.3s var(--ease-out);
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.4s var(--ease-out);
}
.site-nav a:hover { color: var(--ink); text-decoration: none; }
.site-nav a:hover::after { transform: scaleX(1); }
/* aria-current="page" on the page itself; "true" on a section's detail pages */
.site-nav a[aria-current] { color: var(--ink); }
.site-nav a[aria-current]::after { transform: scaleX(1); background: var(--accent); }

@media (max-width: 430px) {
  .brand-sub { display: none; }
}

/* no-JS is always the static default; a switch that can't switch doesn't render */
html:not(.js) .theme-toggle { display: none; }

/* the light/dark switch — labelled with the theme it takes you to */
.theme-toggle {
  appearance: none;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--muted);
  padding: 6px 12px;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--m-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: color 0.15s ease-out, border-color 0.15s ease-out;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--line-bright); }

/* ---------- hero (index) ---------- */

/* Tight to the strip above it: the headline is the first thing on the page,
   so it sits close to the masthead rather than floating in open space. */
.hero {
  padding-block: clamp(24px, 4.5vh, 48px) clamp(40px, 6vh, 64px);
}

.headline {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.6rem, 7vw, 5.25rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.hero-sub {
  max-width: 72ch;
  margin-top: 26px;
  font-size: clamp(1.125rem, 1.8vw, 1.25rem);
  color: var(--body-ink);
}
.hero-cta { margin-top: 16px; color: var(--ink); }
.hero-cta a {
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: var(--accent-line);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.hero-cta a:hover { text-decoration-color: currentColor; }

/* the curator, present on the page: portrait in a gold ring + role */
.hero-byline {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 30px;
  color: var(--muted);
}
.hero-byline a { font-weight: 500; }

/* The gold ring is drawn into portrait.jpg itself, so the CSS border and
   padding this rule used to carry are gone. Adding them back would read as a
   double ring. See assets/README.md before swapping the photo. */
.avatar {
  flex-shrink: 0;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-raise);
}

.byline-name {
  display: block;
  color: var(--ink);
  font-weight: 500;
}
/* the role is identity content, so it sits on the body step, not the label step */
.byline-role {
  display: block;
  color: var(--body-ink);
  margin-top: 2px;
}

/* profile links — gold, mono, on the label step */
.byline-links,
.colophon-links {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 8px;
}
.byline-links a,
.colophon-links a { color: var(--accent); }

/* touch devices get a full-size tap target without changing the desktop rhythm */
@media (pointer: coarse) {
  .byline-links,
  .colophon-links { gap: 6px; margin-top: 2px; }
  .byline-links a,
  .colophon-links a,
  .repo-link,
  .back-link,
  .pager a,
  .crumbs a,
  .site-nav a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    padding-inline: 10px;
    margin-inline: -10px;
  }
}

/* WCAG 2.5.8 asks for 24px on any pointer, not just touch. These standalone
   links render at ~20px from line-height alone. */
.byline-links a,
.colophon-links a,
.repo-link,
.back-link,
.pager a,
.crumbs a,
.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

/* colophon portrait, smaller */
.colophon .avatar { width: 44px; height: 44px; }
.colophon-who {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}


/* hero load choreography (initial states only exist when JS runs) */
.js .hero .headline,
.js .hero .hero-sub,
.js .hero .hero-byline { opacity: 0; transform: translateY(12px); }

.is-loaded .hero .headline { opacity: 1; transform: none; transition: opacity 0.6s ease-out 0.05s, transform 0.6s var(--ease-out) 0.05s; }
.is-loaded .hero .hero-sub { opacity: 1; transform: none; transition: opacity 0.6s ease-out 0.3s, transform 0.6s var(--ease-out) 0.3s; }
.is-loaded .hero .hero-byline { opacity: 1; transform: none; transition: opacity 0.6s ease-out 0.4s, transform 0.6s var(--ease-out) 0.4s; }

/* ---------- category tabs ---------- */

.tabs-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
  padding-bottom: 0;
}

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.tab {
  appearance: none;
  background: transparent;
  border: none;
  position: relative;
  padding: 10px 14px 14px;
  font-family: var(--font-mono);
  font-size: var(--nav-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  /* a tab name is one unit — the row wraps between tabs, never inside one */
  white-space: nowrap;
  transition: color 0.15s ease-out;
}
.tab:hover { color: var(--ink); }
.tab::after {
  content: "";
  position: absolute;
  left: 12px; right: 12px; bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.25s var(--ease-out);
}
.tab[aria-pressed="true"] { color: var(--ink); }
.tab[aria-pressed="true"]::after {
  transform: scaleX(1);
  box-shadow: 0 0 12px 1px var(--accent-soft);
}

.tab-count {
  color: var(--muted);
  font-size: var(--nav-size);
  padding-bottom: 12px;
}


/* ---------- card grid (index) ---------- */

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  padding-block: 36px 8px;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 26px 22px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.25s ease-out,
    background-color 0.25s ease-out,
    transform 0.25s var(--ease-out),
    box-shadow 0.25s ease-out;
}
.card:hover {
  text-decoration: none;
  border-color: var(--line-bright);
  background: var(--glass-hover);
  transform: translateY(-3px);
  box-shadow: 0 12px 40px -18px var(--card-glow);
}
.card:hover .card-open { color: var(--ink); }
.card:hover .card-open::after { transform: translateX(4px); }

/* ---------- card illustration ----------
   Gold monoline schematics on the same warm near-black as the page, so the
   artwork sits in the card rather than on it — no frame, no plate. */
.card-art {
  display: block;
  width: 100%;
  max-width: 168px;
  height: auto;
  margin: -4px auto 4px;
  opacity: 0.88;
  transition: opacity 0.25s ease-out, transform 0.25s var(--ease-out);
}
.card:hover .card-art {
  opacity: 1;
  transform: scale(1.03);
}

/* the monolines exist in two inkings: assets/cards/light/ (re-inked for
   linen — the default the markup ships) and assets/cards/ (pale gold at low
   stroke alpha, drawn to glow on the void). theme.js swaps them on toggle;
   see assets/cards/lighten.py */

.card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.card-cat {
  color: var(--accent);
  font-size: var(--m-size);
  padding: 5px 10px;
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  background: var(--accent-soft);
}

.card-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* the 3–4 line argument on the card face. Set a touch smaller and tighter
   than body copy so a four-line blurb doesn't outweigh the tool name. */
.card-tag {
  color: var(--body-ink);
  font-size: 0.9375rem;
  line-height: 1.55;
  flex: 1;
  text-wrap: pretty;
}

.card-open {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: var(--m-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color 0.2s ease-out;
}
.card-open::after {
  content: "→";
  transition: transform 0.25s var(--ease-out);
}

/* cards hidden by the active filter */
.card[data-filtered="out"] { display: none; }

/* filter re-reveal: surviving cards rise back in */
.card.refilter { animation: card-in 0.4s var(--ease-out) both; }
@keyframes card-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}


/* scroll/load reveal (classes only ever added by JS) */
.reveal { opacity: 0; transform: translateY(14px); }
.reveal.in {
  opacity: 1;
  transform: none;
  transition: opacity 0.55s ease-out, transform 0.55s var(--ease-out);
}

/* ---------- detail page (tool.html) ---------- */

.crumbs {
  display: flex;
  align-items: center;
  font-size: var(--nav-size);
  gap: 10px;
  padding-top: 34px;
  color: var(--muted);
}
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--ink); text-decoration: none; }
.crumbs .sep { color: var(--line-bright); }
.crumbs .here { color: var(--ink); }

/* Two columns, two rows: the head and the sections stack down the left while
   the meta card spans both on the right. Before this the sections lived
   outside the grid, so the tall meta card set the row height and left a dead
   band under the lede. */
.detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  grid-template-rows: auto auto;
  column-gap: clamp(28px, 3.5vw, 56px);
  padding-block: clamp(24px, 4vh, 44px) 24px;
}
.detail-main { grid-column: 1; grid-row: 1; }
.meta { grid-column: 2; grid-row: 1 / span 2; }
.detail .sections { grid-column: 1; grid-row: 2; margin-top: 34px; }

.detail-art {
  display: block;
  width: 132px;
  height: auto;
  margin-bottom: 20px;
  opacity: 0.9;
}

.detail-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.2rem, 5.4vw, 4rem);
  line-height: 1.02;
  letter-spacing: -0.025em;
  color: var(--ink);
}

.detail-lede {
  margin-top: 24px;
  font-size: clamp(1.05rem, 1.8vw, 1.3rem);
  line-height: 1.6;
  color: var(--body-ink);
  max-width: 34em;
}

.js .detail-main > * { opacity: 0; transform: translateY(12px); }
.is-loaded .detail-main > * { opacity: 1; transform: none; }
.is-loaded .detail-main > *:nth-child(1) { transition: opacity 0.55s ease-out 0.05s, transform 0.55s var(--ease-out) 0.05s; }
.is-loaded .detail-main > *:nth-child(2) { transition: opacity 0.55s ease-out 0.18s, transform 0.55s var(--ease-out) 0.18s; }

/* sidebar meta */
.meta {
  display: flex;
  flex-direction: column;
  gap: 22px;
  align-self: start;
  padding: 26px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.meta h2 {
  font-family: var(--font-mono);
  font-size: var(--m-size);
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.meta p { color: var(--ink); font-size: 1rem; }
.meta .meta-cat { color: var(--accent); }

/* sections */
.sections {
  border-top: 1px solid var(--line);
  padding-block: 8px 24px;
  /* was 72ch (~605px). The left column is the constraint below ~1440px, so
     this only binds on wider screens and keeps the measure sane there. */
  max-width: 820px;
}

.section {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 0 28px;
  padding: 26px 0;
  border-bottom: 1px solid var(--line);
}
.section h2 {
  font-family: var(--font-mono);
  font-size: var(--m-size);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  padding-top: 6px;
}
.section .body { font-size: 1rem; }

.section ol {
  list-style: none;
  counter-reset: step;
}
/* The number hangs in a gutter, positioned rather than gridded: display:grid
   here would blockify each inline <a> in a step into its own grid item, so a
   linked term dropped into the number column and collided with the prose. */
.section ol li {
  counter-increment: step;
  position: relative;
  padding: 4px 0 4px 38px;
}
.section ol li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 9px;
  font-family: var(--font-mono);
  font-size: var(--m-size);
  color: var(--muted);
}


/* command block */
.specimen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 6px;
  padding: 14px 16px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
/* where the grey line gets typed — the one thing a newcomer can't infer */
.specimen-where {
  flex-basis: 100%;
  color: var(--muted);
}
.specimen code {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.copy-btn {
  position: relative;
  appearance: none;
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  color: var(--accent);
  padding: 8px 14px;
  font-family: var(--font-mono);
  font-size: var(--m-size);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.15s ease-out, color 0.15s ease-out, box-shadow 0.2s ease-out;
  flex-shrink: 0;
}
.copy-btn:hover {
  background: var(--accent-fill);
  color: var(--on-accent);
  box-shadow: 0 0 18px 2px var(--accent-soft);
}
.copy-btn.copied {
  background: var(--accent-fill);
  color: var(--on-accent);
  animation: pulse-ring 0.5s ease-out;
}
@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 rgba(var(--pulse-rgb), 0.6); }
  100% { box-shadow: 0 0 0 14px rgba(var(--pulse-rgb), 0); }
}


.repo-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: var(--m-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 34px;
  font-family: var(--font-mono);
  font-size: var(--nav-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.back-link:hover { color: var(--ink); text-decoration: none; }

/* detail prev/next footer nav */
.pager {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  border-top: 1px solid var(--line);
  padding-block: 26px 8px;
}
.pager a {
  font-family: var(--font-mono);
  font-size: var(--nav-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.pager a:hover { color: var(--ink); text-decoration: none; }

/* ---------- colophon ---------- */

/* Two blocks, set like the masthead above it: who on the left, status
   pushed to the far right. The who-block keeps a reading measure of its
   own so the wide left column does not stretch the sentence. */
.colophon {
  margin-top: clamp(64px, 10vh, 112px);
  border-top: 1px solid var(--line);
  padding: 36px 0 56px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 32px 48px;
  align-items: start;
}
.colophon-who p { max-width: 46ch; }

.colophon h2 {
  font-family: var(--font-mono);
  font-size: var(--m-size);
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.colophon p { font-size: 1rem; color: var(--body-ink); }

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  /* .a1/.a2/.a3 outrank a bare `.aurora span`, so name them */
  .aurora .a1, .aurora .a2, .aurora .a3 { animation: none; }
  .js .hero .headline,
  .js .hero .hero-sub,
  .js .hero .hero-byline,
  .js .detail-main > * {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .reveal { opacity: 1; transform: none; transition: none; }
  .card, .card:hover { transform: none; }
  .card:hover .card-art { transform: none; }
  .copy-btn.copied { animation: none; }
}

/* ---------- responsive ----------
   Column tiers are set against --page-w above, which tops out at 1440. Past
   that the container stops growing, so the grid adds a column instead of
   widening the cards — each tier lands them near the ~350px the card design
   was drawn at:

     ≤ 640      1 col
     641–1020   2 col
     1021–1599  3 col   (the original desktop rhythm)
     ≥ 1600     4 col   (container is at its 1440 ceiling: ~320px cards)
   -------------------------------------------------- */

/* --- wide displays: use the space instead of padding it out --- */

@media (min-width: 1600px) {
  .grid { grid-template-columns: repeat(4, 1fr); gap: 22px; }
  /* prose should not track the container this far out */
  .hero-sub { max-width: 60ch; }
}

/* --- tablet --- */

@media (max-width: 1020px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
  /* one column: head, then meta, then sections, so the explicit placement
     from the two-column layout has to be released */
  .detail { grid-template-columns: 1fr; row-gap: 36px; }
  .detail-main,
  .meta,
  .detail .sections { grid-column: 1; grid-row: auto; }
  .detail .sections { margin-top: 0; }
  .meta { flex-direction: row; flex-wrap: wrap; gap: 26px 40px; }
}

/* --- phone --- */

@media (max-width: 640px) {
  .grid { grid-template-columns: 1fr; gap: 14px; }
  .hero { padding-block: 48px 36px; }
  /* the role wraps to 2–3 lines here, so top-align the portrait beside it */
  .hero-byline { align-items: flex-start; }
  .section { grid-template-columns: 1fr; gap: 6px 0; }
  .section h2 { padding-top: 0; }
  .specimen { flex-direction: column; align-items: stretch; gap: 10px; }
  .copy-btn { align-self: flex-start; }
  .colophon { grid-template-columns: 1fr; gap: 24px; }
  .meta { flex-direction: column; gap: 22px; }

  /* mono runs small on a phone, so it keeps the same lift it always had
     over the desktop step — one line, every label. */
  :root { --m-size: 0.925rem; }
  /* the blurb goes back to full body size once it has the width to itself */
  .card-tag { font-size: 1rem; }
}

/* --- small phones: the log has to survive 320px --- */

/* --- phones: the filter row buys width back from its padding --- */

@media (max-width: 430px) {
  .tab { padding-inline: 8px; }
  .tab::after { left: 6px; right: 6px; }
}

@media (max-width: 380px) {
  .card { padding: 20px 18px 18px; }
  .card-name { font-size: 1.3rem; }
}

/* --- coarse pointers at any width --- */

@media (pointer: coarse) {
  .tab { min-height: var(--tap); }
  .copy-btn { min-height: var(--tap); }
}

/* ---------- print ---------- */

@media print {
  /* print is always paper, whichever theme is active — the attribute
     selector (0,2,0) outranks the Night block (0,1,1) */
  :root, :root[data-theme="dark"] {
    --bg: #fff; --bg-raise: #f4f0e6;
    --ink: #111; --body-ink: #333; --muted: #555;
    --line: #bbb; --line-bright: #999;
    --accent: #8a6a3f; --accent-soft: transparent; --accent-line: #8a6a3f;
    --accent-fill: #8a6a3f; --on-accent: #fff;
    --glass: transparent; --glass-hover: transparent;
  }
  body { background: #fff; }
  .aurora, .tabs-row, .site-nav, .skip-link, .theme-toggle, .copy-btn { display: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ---------- the curator page ---------- */

/* the one place the portrait runs large */
.curator-portrait { width: 96px; height: 96px; margin-bottom: 22px; }

/* "On this site": a titled section after the bio, same register as the
   stack map's heading block */
.onsite {
  margin-top: clamp(48px, 8vh, 80px);
  padding-top: clamp(36px, 5vh, 56px);
  border-top: 1px solid var(--line);
}
.onsite h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.onsite > p {
  max-width: 56ch;
  margin-top: 12px;
  color: var(--body-ink);
}
.curator-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 28px;
}
@media (max-width: 640px) { .curator-cards { grid-template-columns: 1fr; } }

