:root {
  /* Editorial / instrument surfaces */
  --paper: #f3f0e8;
  --paper-2: #fbfaf6;
  --ink: #101318;
  --muted: #617086;
  --line: #9aa7b5;
  --navy: #041426;
  --navy-2: #09233b;

  /* Approved INDEX:80 palette */
  --blue: #1557ff;
  --cyan: #00cbe8;
  --purple: #a746ff;
  --green: #10b981;
  --amber: #f5b82e;
  --coral: #ff5a45;

  /* Hard, stepped pixel-shadow — solid offset, never blurred */
  --shadow: 3px 3px 0 var(--shadow-color, var(--ink));
  --shadow-lg: 5px 5px 0 var(--shadow-color, var(--ink));
  --shadow-dark: 3px 3px 0 rgba(0,203,232,.28);

  /* Type: bitmap/pixel identity for interface chrome, a readable face for prose */
  --font-pixel: "Silkscreen", ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-body: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Per-page accent — overridden per template via body[data-mode] below */
  --accent: var(--blue);

  /* Theme-system semantic tokens. Defaults equal WEB 1.0 / LIGHT, so the
     current appearance is the no-attribute baseline (and the no-JS
     fallback). html[data-theme][data-color-mode] blocks below override
     these per state; most consumer rules reference the tokens, not the
     raw palette. --paper/--ink/--line/--navy aliases are kept so the
     diff stays small. */
  --magenta: #c93ff0;
  --page-bg: #f7f4ed;
  --page-bg-2: #ece8df;
  --panel-bg: var(--paper-2);
  --panel-bg-2: #f2eee2;
  --text: var(--ink);
  --border: var(--ink);
  --header-bg: rgba(251,250,246,.96);
  --nav-hover-bg: var(--amber);
  --nav-hover-text: #101318;
  --nav-hover-edge: var(--ink);
  --nav-active-bg: #fff4b8;
  --nav-active-text: var(--ink);
  --nav-active-edge: var(--amber);
  --brand-accent: var(--blue);
  --cta-bg: var(--blue);
  --cta-text: #fff;
  --link: var(--blue);
  --systembar-bg: var(--navy);
  --systembar-text: #d7e6f7;
  --key-bg: #0e2237;
  --key-text: #d7e6f7;
  --key-border: #4e6984;
  --key-shadow: #000;
  --key-active-bg: var(--amber);
  --key-active-text: #101318;
  --search-bg: var(--navy-2);
  --shadow-color: var(--ink);
}
* { box-sizing: border-box; }
/* Reserve the vertical-scrollbar gutter permanently, so filtering the
   directory (which changes page height) never shifts the centered
   .page-grid horizontally as the scrollbar appears/disappears.
   overflow-y:scroll is the fallback for browsers without
   scrollbar-gutter — both reserve the same space, so declaring both is
   safe rather than redundant. */
html { background: var(--page-bg); color: var(--text); overflow-y: scroll; scrollbar-gutter: stable; }
body { margin: 0; font-family: var(--font-body); background: linear-gradient(180deg,var(--page-bg) 0,var(--page-bg-2) 100%); }
a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
.skip-link { position: absolute; left:-9999px; }
.skip-link:focus { left:1rem; top:1rem; z-index:99; background:#fff; padding:.5rem; }

/* Page-mode accents. Discover shares Home's blue (both are the index/world
   view); Data stays cyan on its dark instrument surfaces; Project reads as
   an archival record (emerald "verified" stamp feel); Learn is editorial
   warmth (amber); Governance is civic/participation (purple); News is wire
   urgency (coral). Layout/behaviour never changes per mode — only accent
   colour and a handful of mode-specific surface treatments below. */
body[data-mode="home"], body[data-mode="discover"] { --accent: var(--blue); }
body[data-mode="data"] { --accent: var(--cyan); }
body[data-mode="project"] { --accent: var(--green); }
body[data-mode="learn"] { --accent: var(--amber); }
body[data-mode="governance"] { --accent: var(--purple); }
body[data-mode="news"] { --accent: var(--coral); }

/* ============================================================
   V0.05 PROTOTYPE — colour/depth polish (review only, not rolled out)
   Public-family colour system: a project's Editorial-Registry
   "Public Family" gets a deterministic accent used ONLY for small,
   sparing accents (a category/metadata icon, one panel edge, tag
   tint) — never for project logos or body copy. Reuses the six
   approved palette colours only.

   --family-accent      : raw hue — for low-opacity tints and thicker
                           decorative borders, where WCAG's text/icon
                           contrast minimum doesn't apply.
   --family-accent-icon : the same hue, darkened toward --ink with
                           color-mix() where the raw hue alone would
                           fail ~3:1 against the light cream panels
                           (measured: raw cyan ~1.9:1, green ~2.4:1,
                           amber ~1.7:1 against --paper-2 — all below
                           the graphical-object minimum). Blue and
                           purple already clear ~4-5:1 and are used
                           as-is. This is the only reason color-mix()
                           appears here — it's a same-hue accessibility
                           adjustment, not a new colour.

   Both variables are unset outside body[data-family="…"], so every
   consumer below falls back via var(--family-accent, <existing
   default>) and renders exactly as before when no family is set
   (e.g. the About/Method page, homepage, directory). */
body[data-family="defi-markets"] {
  --family-accent: var(--cyan);
  --family-accent-icon: color-mix(in srgb, var(--cyan) 68%, var(--ink) 32%);
}
body[data-family="governance-identity"] {
  --family-accent: var(--purple);
  --family-accent-icon: var(--purple);
}
body[data-family="infrastructure-tools"] {
  --family-accent: var(--blue);
  --family-accent-icon: var(--blue);
}
body[data-family="culture-creators"] {
  --family-accent: var(--amber);
  --family-accent-icon: color-mix(in srgb, var(--amber) 65%, var(--ink) 35%);
}
body[data-family="real-world-utility"] {
  --family-accent: var(--green);
  --family-accent-icon: color-mix(in srgb, var(--green) 65%, var(--ink) 35%);
}

/* ============================================================
   Theme System Option A — prototype starting palettes (DEV).
   WEB 1.0 / LIGHT is the :root baseline above, restated here so all
   four states read from one place. body[data-mode] and
   body[data-family] accent rules are untouched and keep working in
   every state; --blue is redefined per state so interactive blue
   follows the palette with a one-line cascade. */
html[data-theme="web1"][data-color-mode="light"] {
  --blue: #1557ff;
  --page-bg: #f7f4ed;
  --page-bg-2: #ece8df;
  --panel-bg: #fbfaf6;
  --panel-bg-2: #f2eee2;
  --text: #101318;
  --muted: #617086;
  --border: #101318;
  --line: #9aa7b5;
  --header-bg: rgba(251,250,246,.96);
  --nav-hover-bg: #f5b82e;
  --nav-hover-text: #101318;
  --nav-hover-edge: #101318;
  --nav-active-bg: #fff4b8;
  --nav-active-text: #101318;
  --nav-active-edge: #f5b82e;
  --brand-accent: #1557ff;
  --cta-bg: #1557ff;
  --cta-text: #fff;
  --link: #1557ff;
  --systembar-bg: #041426;
  --systembar-text: #d7e6f7;
  --key-bg: #0e2237;
  --key-text: #d7e6f7;
  --key-border: #4e6984;
  --key-shadow: #000;
  --key-active-bg: #f5b82e;
  --key-active-text: #101318;
  --search-bg: #09233b;
  --shadow-color: #101318;
}
/* WEB 1.0 / DARK — restrained dark counterpart, not neon. */
html[data-theme="web1"][data-color-mode="dark"] {
  --blue: #6d9bff;
  --page-bg: #0b1220;
  --page-bg-2: #080d17;
  --paper: #0b1220;
  --paper-2: #131c2e;
  --panel-bg: #131c2e;
  --panel-bg-2: #0f1626;
  --ink: #e9eff7;
  --text: #e9eff7;
  --muted: #93a5bb;
  --border: #3d5170;
  --line: #33455e;
  --navy: #060d18;
  --navy-2: #0b1728;
  --header-bg: rgba(11,18,32,.97);
  --nav-hover-bg: #f5b82e;
  --nav-hover-text: #101318;
  --nav-hover-edge: #101318;
  --nav-active-bg: #2b2410;
  --nav-active-text: #ffd97a;
  --nav-active-edge: #f5b82e;
  --brand-accent: #6d9bff;
  --cta-bg: #2f62d6;
  --cta-text: #fff;
  --link: #6d9bff;
  --systembar-bg: #04090f;
  --systembar-text: #c9d9ec;
  --key-bg: #131c2e;
  --key-text: #c9d9ec;
  --key-border: #3d5170;
  --key-shadow: #000;
  --key-active-bg: #f5b82e;
  --key-active-text: #101318;
  --search-bg: #0b1728;
  --shadow-color: #000;
}
/* ARCADE / LIGHT — warm console/paper base, selective cyan/magenta/yellow. */
html[data-theme="arcade"][data-color-mode="light"] {
  --blue: #0b54ff;
  --magenta: #b62fd6;
  --cyan: #00a5c7;
  --page-bg: #f7efdc;
  --page-bg-2: #eedfc3;
  --paper: #f7efdc;
  --paper-2: #fff8e8;
  --panel-bg: #fff8e8;
  --panel-bg-2: #f6ead0;
  --ink: #241a12;
  --text: #241a12;
  --muted: #7a6a58;
  --border: #241a12;
  --line: #b09a72;
  --navy: #2b1436;
  --navy-2: #3a1c48;
  --header-bg: rgba(255,248,232,.96);
  --nav-hover-bg: #ffd93e;
  --nav-hover-text: #241a12;
  --nav-hover-edge: #241a12;
  --nav-active-bg: #ffe98a;
  --nav-active-text: #241a12;
  --nav-active-edge: #b62fd6;
  --brand-accent: #b62fd6;
  --cta-bg: #0b54ff;
  --cta-text: #fff;
  --link: #0b54ff;
  --systembar-bg: #2b1436;
  --systembar-text: #ffe9c9;
  --key-bg: #3a1c48;
  --key-text: #ffe9c9;
  --key-border: #8a6a9e;
  --key-shadow: #12081a;
  --key-active-bg: #ffd93e;
  --key-active-text: #241a12;
  --search-bg: #3a1c48;
  --shadow-color: #241a12;
}
/* ARCADE / DARK — midnight/navy base, cyan structure, magenta secondary,
   yellow active-navigation cue. */
html[data-theme="arcade"][data-color-mode="dark"] {
  --blue: #35e0ff;
  --magenta: #ff5ce1;
  --cyan: #35e0ff;
  --page-bg: #060a18;
  --page-bg-2: #04060f;
  --paper: #060a18;
  --paper-2: #0d1530;
  --panel-bg: #0d1530;
  --panel-bg-2: #0a1026;
  --ink: #d8f1ff;
  --text: #d8f1ff;
  --muted: #8fa8c7;
  --border: #3d6a8a;
  --line: #274b63;
  --navy: #04060f;
  --navy-2: #0a1230;
  --header-bg: rgba(6,10,24,.97);
  --nav-hover-bg: #ffd93e;
  --nav-hover-text: #101318;
  --nav-hover-edge: #101318;
  --nav-active-bg: #3a2f10;
  --nav-active-text: #ffd93e;
  --nav-active-edge: #ffd93e;
  --brand-accent: #ff5ce1;
  --cta-bg: #c93ff0;
  --cta-text: #160818;
  --link: #35e0ff;
  --systembar-bg: #04060f;
  --systembar-text: #9beaff;
  --key-bg: #0d1530;
  --key-text: #9beaff;
  --key-border: #35e0ff;
  --key-shadow: #000;
  --key-active-bg: #ffd93e;
  --key-active-text: #101318;
  --search-bg: #0a1230;
  --shadow-color: #000;
}

.system-bar { display:flex; flex-wrap:wrap; align-items:center; gap:.35rem .8rem; padding:.45rem 1rem; background:var(--systembar-bg); color:var(--systembar-text); font: 700 .72rem/1.2 var(--font-pixel); letter-spacing:.09em; }
/* Dedicated layout hooks — theme.js tags the first/last child at runtime
   when a page's markup predates these classes, so no positional
   :first-child/:last-child selector is load-bearing. The status element no
   longer owns a cursor: the one persistent cursor lives beside the
   wordmark (.wordmark::after, see main-core.js). */
.system-bar .system-slogan { flex:1 1 auto; min-width:0; grid-area:slogan; }
.system-bar .system-status { margin-left:auto; white-space:nowrap; display:inline-flex; align-items:center; gap:.4em; grid-area:status; }
/* Theme controls: two logical groups (theme, colour mode) of old
   keyboard/F-key-style keys. Inactive keys read raised via the hard
   offset shadow; the active key reads depressed/illuminated. */
.theme-controls { display:flex; flex-wrap:wrap; gap:.3rem .45rem; align-items:center; grid-area:keys; }
.theme-group { display:flex; gap:.3rem; align-items:center; }
.theme-group + .theme-group { margin-left:.15rem; }
.theme-key { appearance:none; font:700 .62rem/1 var(--font-pixel); letter-spacing:.06em; padding:.42rem .55rem; min-height:2rem; min-width:2.6rem; background:var(--key-bg); color:var(--key-text); border:2px solid var(--key-border); border-radius:3px; box-shadow:2px 2px 0 var(--key-shadow); cursor:pointer; }
.theme-key:hover { filter:brightness(1.15); }
.theme-key:focus-visible { outline:2px solid var(--key-text); outline-offset:2px; }
.theme-key[aria-pressed="true"] { background:var(--key-active-bg); color:var(--key-active-text); border-color:var(--key-active-text); box-shadow:inset 2px 2px 0 rgba(0,0,0,.4); transform:translate(2px,2px); }
@media (prefers-reduced-motion: reduce) {
  .theme-key { transition:none; }
  .theme-key[aria-pressed="true"] { transform:none; }
}
/* ARCADE interface accents — three emojis, arcade-scoped only (WEB 1.0
   renders exactly as before). Each is a CSS pseudo-element with an empty
   accessible name, so no markup, content or ARIA text changes.
   - 🎮 badges the ARCADE theme key (absolutely positioned: no key growth)
   - 🕹️ leads the system-bar slogan
   - 👾 replaces the status dot, in the same footprint */
html[data-theme="arcade"] .theme-key[data-set-theme="arcade"] { position:relative; }
html[data-theme="arcade"] .theme-key[data-set-theme="arcade"]::after { content:"\1F3AE"; content:"\1F3AE" / ""; position:absolute; top:-.5rem; right:-.35rem; font-size:.7rem; line-height:1; pointer-events:none; transform:none; }
html[data-theme="arcade"] .system-slogan::before { content:"\1F579\FE0F"; content:"\1F579\FE0F" / ""; margin-right:.5em; }
html[data-theme="arcade"] .status-dot { width:1em; height:1em; background:none; box-shadow:none; font-size:.7rem; line-height:1; text-align:center; }
html[data-theme="arcade"] .status-dot::before { content:"\1F47E"; content:"\1F47E" / ""; }
@keyframes cursor-blink { 0%,49% { opacity:1; } 50%,100% { opacity:0; } }
@media (max-width: 640px) {
  /* Compact second row for the keys: slogan and status keep row one,
     controls take the full second row. No horizontal overflow at 390px. */
  .system-bar { display:grid; grid-template-columns:minmax(0,1fr) auto; grid-template-areas:"slogan status" "keys keys"; font-size:.62rem; }
  .system-bar .system-slogan { font-size:.6rem; }
  .system-bar .system-status { margin-left:0; justify-self:end; }
  .theme-controls { grid-column:1 / -1; }
  .theme-key { padding:.4rem .5rem; min-height:2.1rem; }
}
.status-dot { display:inline-block; width:.6rem; height:.6rem; background:var(--green); box-shadow:0 0 0 2px rgba(16,185,129,.25), 0 0 .5rem rgba(16,185,129,.7); }
.site-header { border-bottom:1px solid #536477; background:var(--header-bg); }
.brand-row { min-height:auto; display:flex; align-items:center; gap:.7rem; padding:.5rem 1.2rem; }
.wordmark { text-decoration:none; font: 700 clamp(1.3rem,2.4vw,1.9rem)/1 var(--font-pixel); letter-spacing:-.02em; color:var(--text); }
.wordmark b { color:var(--brand-accent); }
.network-label { font:500 clamp(.75rem,1.1vw,.95rem)/1 var(--font-pixel); color:var(--muted); }
.main-nav { display:flex; flex-wrap:wrap; border-top:1px solid var(--line); }
.main-nav > a { min-height:2.1rem; display:flex; align-items:center; gap:.4rem; padding:.5rem .9rem; border-right:1px solid var(--line); color:var(--text); text-decoration:none; font:700 .78rem/1 var(--font-pixel); }
.main-nav > a:hover, .main-nav > a[aria-current="page"] { background:var(--nav-active-bg); color:var(--nav-active-text); box-shadow:inset 0 -3px 0 var(--nav-active-edge); }
.search-box { display:flex; align-items:center; gap:.5rem; min-height:2.3rem; padding:.5rem .7rem; background:var(--search-bg); color:var(--cyan); font:700 .78rem/1 var(--font-pixel); border:1px solid #4e6984; }
.search-box input { width:100%; border:1px solid #4e6984; background:#071829; color:white; font:700 .78rem/1 var(--font-pixel); padding:.4rem .6rem; }
.search-box input::placeholder { font-family: var(--font-body); font-weight:500; }
.page-grid { display:grid; grid-template-columns:minmax(0,2fr) minmax(320px,1fr); gap:.8rem; padding:.8rem; max-width:1600px; margin:0 auto; }
.page-grid > * { min-width:0; }
/* V0.05 PROTOTYPE: a faint vertical shade replaces the previously flat
   --paper-2 fill — same cream tone top-to-bottom, just enough gradient
   to read as a lit surface rather than a flat swatch. Hard pixel-shadow
   (--shadow, defined at :root) is untouched: still a solid stepped
   offset, never blurred. */
.panel { background:linear-gradient(180deg, var(--panel-bg) 0%, var(--panel-bg-2) 100%); border:2px solid var(--border); box-shadow:var(--shadow); }
/* Three decorative squares before the heading: the base square is a real
   flex item whose declared width covers its own box-shadow copies too
   (box-shadow paints outside an element's box without affecting layout,
   so sizing the element to only its own square and reserving the rest
   via padding on a sibling is what let long/differently-rendered heading
   text collide with the shadow-painted copies before). Giving ::before
   an explicit width equal to the full visual span it paints into means
   the flex layout — not a padding guess — reserves the exact space, so
   the heading (also a normal flex item, via gap) can never overlap it. */
/* V0.05 PROTOTYPE: a very light tint of the page's own --accent (already
   varies per data-mode — green/amber/purple/etc.) replaces the flat
   #eceff3 fill, with a slightly deeper cream at the foot for the same
   "lit surface" read as .panel above. 9% is deliberately restrained —
   a wash, not a coloured bar. Unaffected on dark panels (see
   .dark .panel-title override just below, unchanged). */
.panel-title { display:flex; align-items:center; gap:.7rem; padding:.48rem .7rem; border-bottom:2px solid var(--ink); background:linear-gradient(180deg, color-mix(in srgb, var(--accent) 9%, #eef1f5 91%) 0%, #e3e7ec 100%); }
.panel-title::before { content:""; flex:0 0 auto; width:2.05rem; height:.45rem; background:var(--accent); box-shadow: .8rem 0 0 var(--line), 1.6rem 0 0 var(--line); }
.dark .panel-title { background:#0c2338; border-color:#36526e; }
.dark .panel-title::before { box-shadow: .8rem 0 0 #2e4e69, 1.6rem 0 0 #2e4e69; }
.panel-title h2 { flex:1 1 auto; min-width:0; margin:0; font:700 .9rem/1 var(--font-pixel); letter-spacing:.04em; }
.hero-panel { display:grid; grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr); min-height:410px; overflow:hidden; background:linear-gradient(180deg,#92dbff 0,#59bff0 52%,#4c9fc3 53%,#2d789f 100%); }
.hero-copy { padding:clamp(1.4rem,4vw,3.2rem); position:relative; z-index:2; max-width:760px; }
.eyebrow { display:inline-block; font:700 .8rem/1 var(--font-pixel); letter-spacing:.22em; color:var(--navy); background:rgba(255,255,255,.55); border:1px solid var(--navy); padding:.2rem .5rem; }
.hero h1 { margin:.6rem 0; font:700 clamp(2.6rem,6vw,5.6rem)/.95 var(--font-pixel); letter-spacing:-.01em; }
.hero h1 span { color:#1557ff; }
.hero h1 small { display:block; margin:.75rem 0 0 .1rem; font-size:.32em; letter-spacing:.1em; color:#244866; }
.strap { font:700 .9rem/1.3 var(--font-pixel); letter-spacing:.14em; border-bottom:2px solid var(--accent); display:inline-block; padding-bottom:.2rem; }
.hero-copy > p:not(.strap) { max-width:620px; font-family:var(--font-body); font-weight:500; line-height:1.5; }
.actions { display:flex; flex-wrap:wrap; gap:.7rem; margin-top:1.3rem; }
.button { display:inline-block; border:2px solid var(--border); background:#eef7fb; padding:.68rem 1rem; text-decoration:none; color:#101318; font:700 .8rem/1 var(--font-pixel); box-shadow:3px 3px 0 var(--shadow-color, var(--ink)); }
.button:hover { transform:translate(1px,1px); box-shadow:2px 2px 0 var(--shadow-color, var(--ink)); }
.button.primary { background:var(--cta-bg); color:var(--cta-text); border-color:var(--border); }
/* The project page's single strongest CTA (its primary outbound link) —
   distinct from .button.primary (used elsewhere, e.g. the cookie-consent
   banner) so tuning one never moves the other. Deliberately blue, not
   green/amber — those already carry editorial/status meaning on this page. */
.button.cta-primary { background:var(--cta-bg); color:var(--cta-text); padding:1rem 1.6rem; font-size:.95rem; letter-spacing:.02em; }
/* A link the verification engine has flagged DEAD/SUNSET/PARKED renders
   here instead of a normal .button — inert (a <span>, no href), dashed
   border and no drop-shadow so it visually reads as disabled rather than
   clickable, per the Verification & Link-History Standard's public-safety
   rule (never present a known-dead destination as a normal CTA). */
.button.is-link-suppressed { background:var(--paper-2); color:var(--muted); border-style:dashed; border-color:var(--coral); box-shadow:none; cursor:not-allowed; opacity:.85; }
.button.is-link-suppressed:hover { transform:none; box-shadow:none; }
/* Destination hint — hover/keyboard-focus tooltip showing where an
   external CTA button actually goes ("Marketplace / App" -> the real
   hostname+path), instead of relying on the browser's own status-bar
   link preview (inconsistent across browsers, absent on touch/keyboard).
   The text is generator-computed (data-dest, see generate-project-pages.mjs
   formatLinkDestination()), so this is pure CSS — no JS, no layout shift
   (absolutely positioned, pointer-events:none so it can never intercept
   a click), reused as-is by every .button that carries data-dest. */
.button[data-dest] { position: relative; }
.button[data-dest]::after {
  content: attr(data-dest);
  position: absolute;
  left: 50%;
  bottom: calc(100% + .45rem);
  transform: translate(-50%, .25rem);
  max-width: min(85vw, 280px);
  background: var(--navy);
  color: #eaf6ff;
  font: 700 .62rem/1.3 var(--font-pixel);
  letter-spacing: .01em;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: .32rem .55rem;
  border: 1px solid #36526e;
  box-shadow: var(--shadow-dark);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
  z-index: 5;
}
.button[data-dest]:hover::after,
.button[data-dest]:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}
@media (prefers-reduced-motion: reduce) {
  .button[data-dest]::after { transition: none; }
}
.pixel-scene { position:relative; min-height:100%; overflow:hidden; }
.dark { background:var(--navy); color:#eaf6ff; border-color:#36526e; box-shadow:var(--shadow-dark); }
.dark .panel-title { border-color:#36526e; }
.healthy { color:var(--green); font:700 .75rem/1 var(--font-pixel); }
.metric-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); }
.metric-grid > div { min-width:0; min-height:68px; padding:.55rem .8rem; border-right:1px solid #2e4e69; border-bottom:1px solid #2e4e69; }
.metric-grid span, .metric-grid small { display:block; font:600 .66rem/1.3 var(--font-pixel); color:#9cb7cd; }
.metric-grid strong { display:block; margin:.25rem 0; font:700 1.2rem/1 var(--font-pixel); overflow-wrap:anywhere; }
/* /META panel: keep the dark navy panel-title framing (".dark .panel-title"
   above still applies, unchanged), but the metadata cells themselves get a
   light cream body — a full solid-navy panel read as too visually dominant.
   Thin navy dividers are kept between cells so the structured look remains.
   Scoped to .profile-instrument only — the homepage's own dark stat panel
   (.network-panel) keeps its original all-navy treatment. */
.profile-instrument.dark { background:var(--paper-2); color:var(--ink); box-shadow:var(--shadow); }
.profile-instrument .metric-grid > div { border-right-color:var(--navy); border-bottom-color:var(--navy); }
.profile-instrument .metric-grid span, .profile-instrument .metric-grid small { color:var(--muted); }
.profile-instrument .metric-grid strong { color:var(--ink); }
.source-line, .prototype-note { margin:.65rem .8rem; font:600 .64rem/1.4 var(--font-pixel); color:var(--muted); }
.dark .source-line { color:#7ebcd5; }
.project-list { list-style:none; margin:0; padding:0; }

/* Directory panel: category bar + search + compact filterable rows, driven
   by data/projects.json. Always full-width, even inside a 2-column
   page-grid (the homepage) — it's the dominant element and needs the
   whole row to show as many records as possible per viewport. */
.directory { grid-column:1 / -1; margin-top:.4rem; }
.icon { width:1em; height:1em; display:inline-block; vertical-align:-.15em; }
.directory-toolbar { display:flex; flex-wrap:wrap; gap:.5rem; align-items:center; justify-content:space-between; padding:.45rem .7rem; border-bottom:1px solid var(--line); }
.directory-count { font:700 .72rem/1 var(--font-pixel); color:var(--muted); letter-spacing:.06em; }
.category-bar { display:flex; flex-wrap:wrap; gap:.4rem; flex:1 1 auto; }
/* Clickable controls read as INDEX blue (border+text) so they're visibly
   interactive against the light surface; active/current state fills
   solid blue instead. The hard black pixel-shadow stays on both states —
   that's the depth cue, not the clickability cue. */
.cat-chip { border:2px solid var(--blue); background:#eef2f6; color:var(--blue); font:700 .66rem/1 var(--font-pixel); letter-spacing:.03em; padding:.4rem .55rem; cursor:pointer; box-shadow:2px 2px 0 var(--ink); }
.cat-chip span { color:var(--muted); font-weight:600; }
.cat-chip:hover { background:#e0e8f0; border-color:var(--blue); }
.cat-chip.active { background:var(--blue); color:#fff; border-color:var(--ink); }
.cat-chip.active span { color:#cfe0ff; }
.directory-search { flex:0 1 260px; }
.dir-list { max-height:none; }
.dir-row, .dir-head { display:grid; grid-template-columns:2.2rem 1.4rem minmax(0,1fr) minmax(0,1.6fr) minmax(6rem,8rem) 2.6rem; align-items:center; gap:.6rem; padding:.32rem .7rem; }
.dir-row { border-bottom:1px solid #d8dfe6; font-family:var(--font-body); font-size:.82rem; }
.dir-row:nth-child(even) { background:rgba(21,87,255,.035); }
.dir-row:hover { background:#eef4fa; }
.dir-head { border-bottom:1px solid var(--line); font:700 .64rem/1 var(--font-pixel); letter-spacing:.04em; color:var(--muted); }
.dir-sort { cursor:pointer; background:none; border:0; padding:0; margin:0; font:inherit; color:var(--blue); text-align:left; }
.dir-sort:hover { text-decoration:underline; }
.dir-sort.active { text-decoration:underline; }
.dir-sort.active::after { content:"▲"; display:inline-block; margin-left:.35em; font-size:.85em; }
.dir-sort.active[data-dir="desc"]::after { content:"▼"; }
.dir-index { color:var(--muted); font:700 .72rem/1 var(--font-pixel); }
.dir-icon { color:var(--blue); width:1.05rem; height:1.05rem; }
.dir-name { font-weight:700; color:var(--ink); text-decoration:none; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dir-name:hover { color:var(--blue); text-decoration:underline; }
.dir-featured { color:var(--blue); }
/* Compact ₳ glyph marker for verified Cardano Treasury funding (Catalyst /
   Funding Ref on record) — same dense-row convention as .dir-featured's
   "★", just its own colour so a factual verification marker never reads
   as the same thing as an editorial Featured pick. */
.dir-treasury { color:var(--green); font-weight:700; }
.dir-desc { color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dir-cat { color:var(--muted); font:700 .68rem/1 var(--font-pixel); letter-spacing:.03em; }
.dir-link { color:var(--muted); text-decoration:none; font:700 .8rem/1 var(--font-pixel); }
.dir-link:hover { color:var(--blue); text-decoration:underline; }
.dir-empty { padding:1rem .8rem; color:var(--muted); font:600 .8rem/1.4 var(--font-pixel); }

/* /cardano/ full-directory page — dense catalogue mode */
.single-column { grid-template-columns:1fr; }
.directory-hero { min-height:auto; background:linear-gradient(180deg,#92dbff 0,#59bff0 100%); }
.discover-h1 { margin:.6rem 0; font:700 clamp(2.3rem,5.4vw,4.6rem)/1 var(--font-pixel); letter-spacing:-.01em; }
.discover-h1 small { display:block; margin-top:.5rem; font-size:.32em; letter-spacing:.1em; color:#244866; }
body[data-mode="discover"] .dir-row { padding-top:.4rem; padding-bottom:.4rem; font-size:.82rem; }
.feature-grid { grid-column:1 / -1; display:grid; grid-template-columns:repeat(4,1fr); gap:.6rem; }
.feature { padding:.7rem; min-height:110px; }
.feature .icon { font-size:1.4rem; color:var(--blue); }
.feature h2 { font:700 .9rem/1 var(--font-pixel); }
.feature p { line-height:1.4; font-family:var(--font-body); font-size:.85rem; }
.methodology { grid-column:1 / -1; }
/* V0.05 PROTOTYPE: the methodology panel is the page's key section, so it
   gets a stronger editorial (amber) top edge than the plain .panel
   default — scoped to the About/Method page only via data-page="about"
   (added to that page's <body> tag), never to /learn/ generally, which
   also carries data-mode="learn" but not this attribute. */
body[data-page="about"] .methodology { border-top:4px solid var(--amber); }
.method-flow { display:grid; grid-template-columns:1fr auto 1fr auto 1fr auto 1fr; align-items:center; gap:.6rem; padding:.7rem; text-align:center; }
.method-flow div { border:2px solid var(--ink); background:#fff; padding:.6rem .5rem; font:700 .78rem/1.3 var(--font-pixel); box-shadow:2px 2px 0 var(--ink); }
/* V0.05 PROTOTYPE: a faint amber wash (was flat #fff) on each of the four
   flow steps — still a hard black border/shadow, just less blank inside. */
body[data-page="about"] .method-flow div { background:color-mix(in srgb, var(--amber) 10%, #fff 90%); }
.method-flow small { color:var(--muted); font-weight:600; font-family:var(--font-body); }
.method-art { grid-column:1 / -1; display:flex; align-items:center; gap:.8rem; padding:0 .7rem .7rem; }
.method-art img { width:56px; height:56px; border:2px solid var(--ink); box-shadow:3px 3px 0 var(--ink); flex:0 0 auto; image-rendering:auto; }
.method-art p { margin:0; font-size:.82rem; line-height:1.45; color:var(--muted); font-family:var(--font-body); }
.site-footer { padding:.7rem 1rem .8rem; border-top:1px solid var(--line); font:700 .7rem/1 var(--font-pixel); }
.footer-nav { display:flex; flex-wrap:wrap; gap:.4rem 1.1rem; padding-bottom:.55rem; margin-bottom:.55rem; border-bottom:1px solid var(--line); }
.footer-nav a { color:var(--ink); text-decoration:none; }
.footer-nav a:hover, .footer-nav a[aria-current="page"] { color:var(--accent); text-decoration:underline; }
.footer-meta { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:1rem; }
.footer-brand b { color:var(--brand-accent); }
.footer-social { color:var(--muted); text-decoration:none; white-space:nowrap; }
.footer-social:hover { color:var(--accent); text-decoration:underline; text-underline-offset:2px; }
.footer-consent-toggle { background:none; border:0; padding:0; color:inherit; font:inherit; cursor:pointer; text-decoration:underline; text-underline-offset:2px; }
.footer-consent-toggle:hover { color:var(--blue); }

/* Analytics consent banner — injected by assets/js/analytics.js, production only */
#index80-consent { position:fixed; left:0; right:0; bottom:0; z-index:999; display:flex; flex-wrap:wrap; align-items:center; gap:.8rem; justify-content:space-between; padding:.9rem 1rem; background:var(--navy); color:#eaf6ff; border-top:2px solid var(--ink); box-shadow:0 -3px 0 rgba(0,0,0,.25); }
#index80-consent p { margin:0; max-width:62ch; font-size:.8rem; line-height:1.5; font-family:var(--font-body); }
#index80-consent a { color:var(--cyan); }
#index80-consent .consent-actions { display:flex; gap:.6rem; flex:0 0 auto; }

/* ============================================================
   V0.03 — shared component patterns (hero media, badges, shells,
   pathway/topic/link grids, dashboard, project profile)
   ============================================================ */

/* Hero media: approved production illustrations used full-bleed inside
   the hero-panel, replacing/backing the CSS pixel-scene where used. */
.hero-art { position:relative; min-height:100%; overflow:hidden; background:#0c2338; }
.hero-art img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; image-rendering:auto; }
.hero-art .terminal { position:absolute; right:6%; bottom:8%; z-index:2; border:2px solid var(--navy); background:rgba(232,246,248,.96); color:#101318; padding:.7rem; font:700 .78rem/1.1 var(--font-pixel); box-shadow:4px 4px 0 var(--navy); }

/* Shared hero system (V0.04) — one consistent panel used by Home, Data,
   Learn, Governance and About: full-bleed art behind everything, copy on
   the left over a translucent gradient scrim so text stays readable
   regardless of what's behind it, same overall proportions on every page.
   Originally built for the homepage only ("compact hero"); extended
   2026-09-13 to every section page — Governance's hero moved from an
   inline SVG ballot icon in a hard two-column grid to the same full-bleed
   illustrated artwork (index80-hero-governance.webp) and shell as the
   others, so all five read as one system instead of two different
   layouts. */
.hero-panel.compact-hero { display:flex; align-items:stretch; position:relative; min-height:clamp(220px,32vw,320px); }
.compact-hero .hero-art { position:absolute; inset:0; z-index:0; }
.compact-hero .hero-art img { object-position:42% 35%; }
.compact-hero .hero-art .terminal { z-index:2; }
/* Data/Learn/Governance/About's approved artwork is composed with the
   subject deliberately concentrated in the right ~50% of a 3:1 image and a
   plain sky/water gradient filling the left half (built for exactly this
   text-overlay use) — cropped from the right edge inward instead of
   centered, so narrower viewports lose empty sky first, never the subject. */
.compact-hero .hero-art-right img { object-position:78% 42%; }
.compact-hero .hero-copy {
  position:relative; z-index:1; width:min(100%,560px); max-width:560px;
  padding:clamp(1rem,2.5vw,1.6rem);
  background:linear-gradient(100deg, rgba(251,250,246,.9) 0%, rgba(251,250,246,.74) 35%, rgba(251,250,246,.3) 62%, rgba(251,250,246,0) 84%);
}
.compact-hero.hero h1, .compact-hero .section-hero h1, .compact-hero.section-hero h1 { font-size:clamp(1.5rem,3vw,2.3rem); margin:.4rem 0; }
.compact-hero .eyebrow { font-size:.7rem; }
.compact-hero .strap { font-size:.78rem; }
.compact-hero .hero-copy > p:not(.strap) { font-size:.85rem; line-height:1.45; margin:.5rem 0; }
.compact-hero .actions { margin-top:.7rem; }
/* Dark-hero variant (Data): same left scrim, tinted to the page's own dark
   navy instead of the light-cream tone the other pages use, so white
   hero-copy text keeps full contrast against the dark astronaut/dashboard
   artwork behind it. */
.compact-hero.dark-hero .hero-copy {
  background:linear-gradient(100deg, rgba(4,20,38,.92) 0%, rgba(4,20,38,.78) 35%, rgba(4,20,38,.32) 62%, rgba(4,20,38,0) 84%);
}
@media (max-width: 720px) {
  /* Selector must match the base rule's specificity (.hero-panel.compact-hero,
     two classes) — a bare .compact-hero here is a lower-specificity no-op
     against that base rule regardless of media-query/source order, which
     silently left every page stretch-aligned (not bottom-anchored) on
     mobile until this was traced during the 2026-09-13 hero rollout. */
  .hero-panel.compact-hero { min-height:clamp(360px,120vw,460px); align-items:flex-end; }
  .compact-hero .hero-art img { object-position:16% 58%; }
  .compact-hero .hero-art-right img { object-position:70% 38%; }
  .compact-hero .hero-copy {
    width:100%; max-width:none; text-align:left;
    background:linear-gradient(0deg, rgba(251,250,246,.95) 0%, rgba(251,250,246,.95) 55%, rgba(251,250,246,0) 100%);
  }
  .compact-hero.dark-hero .hero-copy {
    background:linear-gradient(0deg, rgba(4,20,38,.95) 0%, rgba(4,20,38,.95) 55%, rgba(4,20,38,0) 100%);
  }
}

/* Generic framed image used on data/learn pages */
.img-frame { display:block; width:100%; height:auto; border:2px solid var(--navy); box-shadow:4px 4px 0 rgba(4,20,38,.35); }
.dark .img-frame { border-color:#36526e; box-shadow:4px 4px 0 rgba(0,0,0,.4); }

/* Status / feed badges — square LED marker, neutral by default, only ever
   green when backed by data */
.badge { display:inline-flex; align-items:center; gap:.35rem; font:700 .66rem/1 var(--font-pixel); letter-spacing:.05em; padding:.3rem .5rem; border:2px solid currentColor; }
.badge::before { content:"■"; font-size:.55rem; }
.badge-pending { color:#9cb7cd; }
.badge-review { color:var(--amber); }
.badge-live { color:var(--green); }
.dark .badge-pending { color:#9cb7cd; }

/* Simple hero/lede used at the top of shell pages (data/learn/governance/news/projects) */
.section-hero { min-height:auto; background:linear-gradient(180deg,#92dbff 0,#59bff0 100%); }
.section-hero.dark-hero { background:linear-gradient(180deg,#0a2a44 0,#041426 100%); color:#eaf6ff; }
.section-hero .eyebrow.on-dark { color:#8fd6ec; background:rgba(4,20,38,.55); border-color:#4e6984; }
.section-hero h1 { margin:.6rem 0; font:700 clamp(2.2rem,5vw,4.2rem)/1 var(--font-pixel); letter-spacing:-.01em; }
.section-hero h1 small { display:block; margin-top:.5rem; font-size:.32em; letter-spacing:.1em; color:#244866; }
.section-hero.dark-hero h1 small { color:#8fb3cc; }
.section-hero p { max-width:640px; font-family:var(--font-body); font-weight:500; line-height:1.55; }
/* .section-hero's own min-height:auto would otherwise win the cascade over
   .compact-hero's clamp() (defined earlier in the file, same specificity,
   later selector wins) on every page below that still carries both classes
   — pin it back to the shared compact-hero height explicitly. */
.section-hero.compact-hero { min-height:clamp(220px,32vw,320px); }
@media (max-width: 720px) {
  .section-hero.compact-hero { min-height:clamp(360px,120vw,460px); }
}

/* Pathway cards on the homepage reuse .feature-grid / .feature */

/* Learn: editorial topic index — warmer, magazine-card treatment */
.topic-grid { grid-column:1 / -1; display:grid; grid-template-columns:repeat(3,1fr); gap:.8rem; }
.topic-card { padding:1rem; display:flex; flex-direction:column; gap:.5rem; min-height:150px; border-top:4px solid var(--amber); }
.topic-card h3 { margin:0; font:700 .88rem/1.3 var(--font-pixel); }
.topic-card p { margin:0; line-height:1.5; flex:1; font-family:var(--font-body); }
.topic-card .badge { align-self:flex-start; }

/* Governance / News: shell panels with a linked-record list */
.shell-panel { grid-column:1 / -1; padding:clamp(1rem,3vw,2rem); }
.shell-panel h2 { margin:0 0 .6rem; font:700 1.05rem/1.3 var(--font-pixel); }
.shell-panel p { line-height:1.55; max-width:760px; font-family:var(--font-body); }
/* V0.05 PROTOTYPE: a small coloured square (the same decorative-square
   language already used by .panel-title::before) ahead of each
   secondary heading on the About/Method page — distinguishes sections
   with colour without turning them into cards. CSS-only, no markup or
   icon-set change; scoped to data-page="about" only. */
body[data-page="about"] .shell-panel h2::before {
  content:""; display:inline-block; width:.6rem; height:.6rem; margin-right:.5rem;
  background:var(--amber); box-shadow:.1rem .1rem 0 var(--ink);
}
.link-row-list { list-style:none; margin:1rem 0 0; padding:0; border-top:1px solid var(--line); }
.link-row { display:grid; grid-template-columns:1.4rem minmax(0,1.4fr) minmax(0,1fr) auto; align-items:center; gap:.6rem; padding:.6rem .2rem; border-bottom:1px solid #d8dfe6; font-family:var(--font-body); font-size:.85rem; }
.dark .link-row { border-bottom-color:#2e4e69; }
.link-row a.dir-name { font-weight:700; }
.empty-note { padding:1rem 0; color:var(--muted); font:600 .8rem/1.4 var(--font-pixel); }

/* Governance mode: civic/participation — purple corner tab on shell panels */
body[data-mode="governance"] .shell-panel { border-top:4px solid var(--purple); }

/* News mode: wire/bulletin — teletype rule above the shell, ticker-style label */
body[data-mode="news"] .shell-panel { border-top:4px solid var(--coral); position:relative; }
body[data-mode="news"] .shell-panel::before {
  content:"WIRE"; position:absolute; top:-1px; right:0; background:var(--coral); color:#fff;
  font:700 .6rem/1 var(--font-pixel); letter-spacing:.15em; padding:.25rem .5rem;
}
body[data-mode="news"] .shell-panel h2 { border-bottom:1px dashed var(--line); padding-bottom:.5rem; }

/* Data page: dark instrument/dashboard */
.dashboard-grid { grid-column:1 / -1; display:grid; grid-template-columns:1.3fr 1fr; gap:.8rem; }
.dashboard-media { display:flex; flex-direction:column; gap:.8rem; }
.dashboard-media figure { margin:0; }
.dashboard-media figcaption { margin-top:.4rem; font:600 .65rem/1.3 var(--font-pixel); color:#9cb7cd; }
.feed-grid { display:grid; grid-template-columns:1fr 1fr; }
.feed-grid > div { min-height:68px; padding:.55rem .8rem; border-right:1px solid #2e4e69; border-bottom:1px solid #2e4e69; }
.feed-grid span, .feed-grid small { display:block; font:600 .66rem/1.3 var(--font-pixel); color:#9cb7cd; }
.feed-grid strong { display:block; margin:.25rem 0; font:700 1.2rem/1 var(--font-pixel); }

/* Project profile template — archival database-record mode */
body[data-mode="project"] .profile-header { position:relative; border-top:4px solid var(--green); }
body[data-mode="project"] .profile-header::after {
  content:"RECORD"; position:absolute; top:-1px; right:0; background:var(--green); color:#052e1f;
  font:700 .6rem/1 var(--font-pixel); letter-spacing:.15em; padding:.25rem .5rem;
}
.profile-header { grid-column:1 / -1; padding:.6rem clamp(1rem,3vw,2rem); display:flex; flex-wrap:wrap; gap:.8rem; justify-content:space-between; align-items:flex-start; }
.profile-heading { display:flex; align-items:center; gap:.6rem; flex-wrap:wrap; }
/* V0.05 PROTOTYPE: falls back to the existing green project-mode accent
   when no --family-accent-icon is set (see the family-colour block near
   the top of this file) — so a project with no recognised Public Family
   renders exactly as before. */
.profile-heading .icon { width:1.4rem; height:1.4rem; color:var(--family-accent-icon, var(--accent)); }
.profile-heading h1 { margin:0; font:700 clamp(1.3rem,3vw,2rem)/1.1 var(--font-pixel); letter-spacing:-.01em; }
/* Fixed height, auto width: a square favicon and a wide wordmark logo both
   read correctly at a glance — no forced square crop, no stretching. Height
   only (not a fixed box) is what keeps the heading row the same height on
   every project regardless of the source image's own aspect ratio. */
.profile-icon { display:inline-flex; align-items:center; height:3rem; flex:none; }
.profile-icon-img { display:block; height:3rem; width:auto; max-width:12rem; object-fit:contain; }
.profile-cat { margin:0 0 .3rem; font:700 .72rem/1 var(--font-pixel); color:var(--muted); letter-spacing:.05em; }

/* Identity strip (profile-header) is immediately followed by this row:
   left = the single primary CTA, right = category + summary + tags —
   using the wide desktop measure horizontally instead of stacking
   everything as separate full-width rows underneath the title. */
.profile-body { grid-column:1 / -1; display:grid; grid-template-columns:minmax(220px,300px) 1fr; gap:1rem; padding:0 clamp(1rem,3vw,2rem) 1rem; }
.profile-cta { display:flex; flex-direction:column; align-items:flex-start; gap:.5rem; }
.profile-cta .link-buttons { display:flex; flex-direction:column; gap:.5rem; width:100%; }
.profile-cta .button { width:100%; text-align:center; justify-content:center; }
.profile-cta .button.cta-primary { font-size:.95rem; }
.profile-cta .button:not(.cta-primary) { font-size:.72rem; padding:.5rem .7rem; }
.profile-info { min-width:0; }
.profile-summary-text { margin:0 0 .6rem; line-height:1.5; font-family:var(--font-body); }
.profile-tags { display:flex; flex-wrap:wrap; gap:.35rem; align-items:center; }
/* V0.05 PROTOTYPE: a faint family-tinted wash (falls back to the previous
   flat #eef2f6 with no family set) plus a family-coloured left edge —
   the chip's own dark text/border stays untouched, so this is purely a
   decorative tint, never load-bearing for reading the tag text. */
.tag-chip {
  border:1px solid #101318;
  border-left:3px solid var(--family-accent, #101318);
  background: color-mix(in srgb, var(--family-accent, #cfd8e2) 12%, #eef2f6 88%);
  color:#101318;
  font:700 .64rem/1 var(--font-pixel); padding:.3rem .5rem .3rem .45rem;
}
/* "₳ TREASURY FUNDED" — a fact badge (verified Cardano Treasury funding
   on record), not an award: outline-only like .tag-chip, no fill/gradient
   ribbon, same weight as the rest of the directory's factual markers. The
   ₳ glyph is the icon — no separate SVG symbol. Used both near the H1 on
   the project profile page and (as .ada-glyph alone) inside a metric-grid
   entry — see treasuryBadge()/treasuryMetric() in generate-project-pages.mjs. */
.badge-treasury { display:inline-flex; align-items:center; gap:.3em; border:1px solid #101318; background:#eef2f6; color:#101318; font:700 .62rem/1 var(--font-pixel); letter-spacing:.04em; padding:.32rem .55rem; white-space:nowrap; }
.metric-grid > .treasury-metric { grid-column:1 / -1; }
.treasury-scope-note { display:block; margin-top:.35rem; font:400 .68rem/1.4 var(--font-body); color:var(--muted); letter-spacing:0; }
.ada-glyph { color:var(--green); font-weight:700; font-size:.85em; }

/* Combined image + metadata rectangle: an official project image (when
   harvested) sits left of the compact metric panel; with no image the
   metadata simply expands to the full width rather than reserving a
   blank image slot. */
/* V0.05 PROTOTYPE: the one deliberate "panel accent" from the brief — a
   narrow family-coloured left edge on the media/metadata panel. Falls
   back to the existing --green project accent when no family is set. */
body[data-mode="project"] .profile-media-meta { border-left:4px solid var(--family-accent, var(--green)); }
.profile-media-meta { grid-column:1 / -1; display:grid; grid-template-columns:minmax(200px,320px) 1fr; }
.profile-media-meta.no-image { grid-template-columns:1fr; }
.profile-media { overflow:hidden; background:var(--paper-2); border-right:2px solid var(--ink); }
.profile-media img { display:block; width:100%; height:100%; max-height:16rem; object-fit:contain; }

/* On-chain identifier cell inside the (dark) metric-grid — full width so
   the truncated value + copy + explorer-link row has room, never a raw
   unbroken hex string. */
.policy-id-cell { grid-column:1 / -1; min-width:0; min-height:auto; padding:.55rem .8rem; }
.policy-id-cell > span { display:block; font:600 .66rem/1.3 var(--font-pixel); color:#9cb7cd; margin-bottom:.3rem; }
.policy-id-value { display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; font:700 1rem/1 var(--font-pixel); }
.policy-id-value code { font:600 .8rem/1 ui-monospace, SFMono-Regular, Menlo, monospace; background:rgba(255,255,255,.08); color:#eaf6ff; padding:.3rem .5rem; }
.copy-btn { background:none; border:1px solid #4e6984; color:#9cb7cd; cursor:pointer; font-size:.85rem; line-height:1; padding:.3rem .45rem; }
.copy-btn:hover { color:#eaf6ff; border-color:#7ebcd5; }
.policy-id-value a { color:#7ebcd5; text-decoration:none; font-size:.85rem; }
.policy-id-value a:hover { color:#eaf6ff; }
/* Provenance is a native <details>/<summary> disclosure — collapsed by
   default so the record's editorial sources stay available but don't cost
   permanent vertical space on the profile page (see generator template). */
.profile-source { grid-column:1 / -1; }
.profile-source > summary { cursor:pointer; list-style:none; }
.profile-source > summary::-webkit-details-marker { display:none; }
.disclosure-caret { display:inline-block; transition:transform .15s; }
details[open] > summary .disclosure-caret { transform:rotate(90deg); }
.source-list { margin:0; padding:.45rem .9rem .8rem; list-style:none; font:600 .74rem/1.6 var(--font-body); color:var(--muted); }
.back-to-directory { display:inline-block; margin:.7rem 0 0 .1rem; font-family:var(--font-body); }

/* /submit/ — reuses the existing D1 + Turnstile backend (functions/api/submit.js) */
/* /submit/ composition — the same clipboard/robot-left, form-right card
   proven on the prelaunch site, reused here around the current site's
   own header/nav/footer chrome and the existing D1/Turnstile backend
   (visual reuse only; fields/IDs/script are unchanged). */
.submit-panel { position:relative; max-width:980px; margin:0 auto; padding:clamp(1.6rem,3.5vw,2.6rem); padding-top:clamp(2rem,4vw,3rem); }
.clip { position:absolute; top:-1.1rem; left:50%; transform:translateX(-50%); width:96px; height:34px; background:linear-gradient(180deg,#d7dee6 0%,#aeb9c4 100%); border:2px solid var(--ink); border-radius:6px; box-shadow:var(--shadow); }
.clip span { position:absolute; top:50%; width:8px; height:8px; background:#7c8896; border:1px solid var(--ink); border-radius:50%; transform:translateY(-50%); }
.clip span:first-child { left:16px; }
.clip span:last-child { right:16px; }
.submit-panel__grid { display:grid; grid-template-columns:minmax(180px,240px) minmax(0,1fr); gap:clamp(1.2rem,3vw,2rem); align-items:start; }
.submit-art { margin:0; display:flex; align-items:start; justify-content:center; }
.submit-art img { width:100%; height:auto; max-width:220px; }
.submit-panel__body { min-width:0; }
.submit-panel__head { display:flex; align-items:center; gap:.9rem; margin-bottom:.9rem; }
.head-globe { width:3.4rem; height:3.4rem; flex:0 0 auto; border:2px solid var(--ink); box-shadow:var(--shadow); }
.submit-panel__head h2 { margin:0; font:700 clamp(1.3rem,3vw,1.7rem)/1.15 var(--font-pixel); letter-spacing:-.01em; }
.brand-inline b { color:var(--brand-accent); }
.submit-sub { margin:.3rem 0 0; font:700 .72rem/1 var(--font-pixel); letter-spacing:.08em; color:var(--muted); }
.submit-explainer { margin:0 0 1.1rem; padding:.7rem .9rem; background:#eef7fb; border:1px solid var(--line); border-left:3px solid var(--cyan); font-family:var(--font-body); font-size:.86rem; line-height:1.5; color:var(--ink); }
.submit-footnote { margin:1.2rem 0 0; text-align:center; font:700 .72rem/1 var(--font-pixel); letter-spacing:.06em; color:var(--muted); }
@media (max-width:720px) {
  .submit-panel__grid { grid-template-columns:1fr; }
  .submit-art img { max-width:140px; }
}
@media (max-width:560px) {
  .clip { width:76px; height:28px; }
  .submit-panel { padding-top:2.3rem; }
}

.submit-form { padding:clamp(1rem,3vw,2rem) 0 0; display:flex; flex-direction:column; gap:1rem; max-width:640px; }
.form-field { display:flex; flex-direction:column; gap:.35rem; }
.form-field label { font:700 .78rem/1.2 var(--font-pixel); }
.form-field .req { color:var(--coral); }
.form-field .optional { color:var(--muted); font-weight:600; font-family:var(--font-body); font-size:.75rem; }
.form-field .field-help { margin:0; color:var(--muted); font:500 .78rem/1.4 var(--font-body); }
.form-field input, .form-field textarea, .form-field select {
  border:2px solid var(--ink); background:var(--paper-2); color:var(--ink);
  font-family:var(--font-body); font-size:.9rem; padding:.55rem .7rem; width:100%;
}
.form-field textarea { resize:vertical; font-family:var(--font-body); }
.form-actions { display:flex; flex-direction:column; gap:.6rem; align-items:flex-start; }
.form-note { margin:0; color:var(--muted); font:600 .78rem/1.4 var(--font-body); }
.form-result { margin:0; padding:.6rem .8rem; border:2px solid var(--ink); font:600 .85rem/1.5 var(--font-body); }
.form-result.is-success { border-color:var(--green); background:#eafdf2; }
.form-result.is-error { border-color:var(--coral); background:#fff1ee; }

/* /about/ — Charter, Support and Founder sections */
.charter-summary { display:flex; flex-wrap:wrap; gap:.4rem; padding:.7rem clamp(1rem,3vw,2rem) 0; }
.support-panel { display:grid; grid-template-columns:1fr auto; gap:1.5rem; align-items:start; padding:clamp(1rem,3vw,2rem); }
.support-copy p { line-height:1.55; font-family:var(--font-body); max-width:60ch; }
.support-note { margin:.8rem 0; padding:.6rem .8rem; border:2px solid var(--amber); background:#fff8e8; font:600 .8rem/1.5 var(--font-body); max-width:60ch; }
.support-address-block { display:flex; flex-direction:column; gap:.5rem; margin-top:1rem; }
.support-handle { font:700 1.1rem/1 var(--font-pixel); color:var(--blue); }
.support-address {
  display:block; word-break:break-all; border:2px solid var(--ink); background:var(--paper-2);
  padding:.6rem .7rem; font:600 .78rem/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; max-width:60ch;
}
.support-actions { display:flex; flex-wrap:wrap; gap:.6rem; align-items:center; }
.support-qr { flex:0 0 auto; text-align:center; }
.support-qr img { display:block; width:140px; height:140px; border:2px solid var(--ink); box-shadow:var(--shadow); image-rendering:pixelated; }
.support-qr figcaption { margin-top:.4rem; font:600 .66rem/1.3 var(--font-pixel); color:var(--muted); }
@media (max-width: 720px) {
  .support-panel { grid-template-columns:1fr; }
  .support-qr { justify-self:start; }
}

/* /about/charter/ — the full approved Charter text, durable plain HTML */
.charter-doc { padding:clamp(1rem,3vw,2rem); max-width:74ch; font-family:var(--font-body); line-height:1.6; }
.charter-doc h2 { margin:1.6rem 0 .5rem; font:700 1rem/1.3 var(--font-pixel); }
.charter-doc h2:first-child { margin-top:0; }
.charter-doc p { margin:0 0 .9rem; }
.charter-doc ul { margin:0 0 .9rem; padding-left:1.3rem; }
.charter-doc .charter-meta { color:var(--muted); font:600 .78rem/1.5 var(--font-pixel); margin-bottom:1.4rem; }

/* /about/ — founder section: avatar + compact fact-based copy, nothing more */
.founder-panel { display:flex; gap:1.1rem; align-items:flex-start; padding:clamp(1rem,3vw,2rem); }
.founder-avatar { flex:0 0 auto; display:block; }
.founder-avatar img { display:block; width:96px; height:96px; border:2px solid var(--ink); box-shadow:var(--shadow); object-fit:cover; }
.founder-copy { min-width:0; }
.founder-copy h2 { margin:0 0 .5rem; font:700 1.05rem/1.3 var(--font-pixel); }
.founder-copy p { margin:0 0 .7rem; line-height:1.55; font-family:var(--font-body); max-width:70ch; }
.founder-note { color:var(--muted); font-size:.85rem; }
@media (max-width:560px) {
  .founder-panel { flex-direction:column; align-items:center; text-align:center; }
  .founder-copy p { max-width:none; }
}

/* /people/charles-hoskinson/ — split hero: plain editorial copy on the
   left, a small contained static X-profile card on the right. Replaces
   an earlier full-bleed photo-behind-text treatment where the scrim
   caused the heading/paragraph to overlap Charles's face and
   microphone. The card is static markup only — no live X embed, no
   follower count, no post content. */
.charles-hero { grid-column:1/-1; display:grid; grid-template-columns:minmax(0,1.5fr) minmax(220px,270px); gap:1.4rem; align-items:start; padding:clamp(1.2rem,3vw,2.2rem); background:var(--paper-2); }
.charles-hero-copy { max-width:640px; }
.charles-hero-copy h1 { margin:.6rem 0; font:700 clamp(1.8rem,4vw,3rem)/1.05 var(--font-pixel); letter-spacing:-.01em; }
.charles-hero-copy h1 small { display:block; margin-top:.4rem; font-size:.34em; letter-spacing:.1em; color:var(--muted); }
.charles-hero-copy > p:not(.strap) { font-family:var(--font-body); font-weight:500; line-height:1.55; margin:.7rem 0; }
.x-profile-card { border:2px solid var(--ink); background:var(--paper-2); box-shadow:var(--shadow); padding:1.1rem 1rem; text-align:center; }
.x-profile-avatar { display:block; width:76px; height:76px; margin:0 auto .6rem; border:2px solid var(--ink); border-radius:50%; object-fit:cover; }
.x-profile-name { display:block; font:700 .9rem/1.2 var(--font-pixel); }
.x-profile-handle { display:block; margin-top:.15rem; color:var(--muted); font:600 .78rem/1.3 var(--font-body); }
.x-profile-bio { margin:.6rem 0 .9rem; font-size:.8rem; line-height:1.4; font-family:var(--font-body); }
.x-profile-card .button { width:100%; text-align:center; justify-content:center; font-size:.72rem; padding:.55rem .6rem; }
@media (max-width:900px) {
  .charles-hero { grid-template-columns:1fr; }
  .x-profile-card { max-width:280px; margin:0 auto; }
}

@media (max-width: 1050px) {
  .page-grid { grid-template-columns:1fr; }
  .feature-grid { grid-template-columns:1fr 1fr; }
  .hero-panel { grid-template-columns:1fr; }
  .pixel-scene, .hero-art { min-height:260px; }
  .topic-grid { grid-template-columns:1fr 1fr; }
  .dashboard-grid { grid-template-columns:1fr; }
  .profile-meta, .profile-body, .profile-media-meta { grid-template-columns:1fr; }
  .method-art { flex-wrap:wrap; }
}
/* Directory rows: description is the first thing to go on a narrower
   screen (a "nice to have" column), category next — name/icon/site
   link stay usable at every width. */
@media (max-width: 900px) {
  .dir-row, .dir-head { grid-template-columns:2.2rem 1.4rem minmax(0,1fr) minmax(6rem,8rem) 2.6rem; }
  .dir-desc { display:none; }
}
@media (max-width: 640px) {
  .brand-row { flex-wrap:wrap; }
  .hero h1, .section-hero h1 { font-size:2.9rem; }
  .compact-hero.hero h1 { font-size:1.6rem; }
  .feature-grid { grid-template-columns:1fr; }
  .method-flow { grid-template-columns:1fr; }
  .method-flow > span { transform:rotate(90deg); }
  .footer-meta { flex-direction:column; align-items:flex-start; }
  .dir-row, .dir-head { grid-template-columns:1.6rem 1.2rem 1fr 2.4rem; }
  .dir-cat { display:none; }
  .directory-search { flex-basis:100%; }
  .topic-grid { grid-template-columns:1fr; }
  .feed-grid { grid-template-columns:1fr; }
  .link-row { grid-template-columns:1.2rem 1fr auto; }
  .link-row .dir-cat { display:none; }
  .panel-title { gap:.5rem; }
  .panel-title::before { width:1.8rem; height:.4rem; box-shadow:.7rem 0 0 var(--line), 1.4rem 0 0 var(--line); }
}

/* ============================================================
   Theme System Option A — dark colour-mode readability.
   These panels/boxes keep deliberately light fills in every state,
   so their text must stay dark when the global text colour lightens.
   Light heroes keep light-sky artwork in every state for the same
   reason. Higher specificity than the base rules by construction. */
html[data-color-mode="dark"] .panel-title { background:linear-gradient(180deg, #1a2740 0%, #121b2e 100%); }
html[data-color-mode="dark"] .hero-panel:not(.dark-hero),
html[data-color-mode="dark"] .section-hero:not(.dark-hero),
html[data-color-mode="dark"] .directory-hero { color:#101318; }
html[data-color-mode="dark"] .hero-panel:not(.dark-hero) a,
html[data-color-mode="dark"] .section-hero:not(.dark-hero) a,
html[data-color-mode="dark"] .directory-hero a { color:#0b36c4; }
html[data-color-mode="dark"] .dir-row:hover { background:#1a2740; }
html[data-color-mode="dark"] .dir-row:nth-child(even) { background:rgba(109,155,255,.07); }
html[data-color-mode="dark"] .cat-chip { border-color:#2f62d6; color:#2f62d6; }
html[data-color-mode="dark"] .cat-chip.active { color:#0b1220; }
html[data-color-mode="dark"] .cat-chip.active span { color:#1c2a44; }
html[data-color-mode="dark"] .method-flow div { background:#141d2e; border-color:var(--border); }
html[data-color-mode="dark"] body[data-page="about"] .method-flow div { background:color-mix(in srgb, var(--amber) 14%, #141d2e 86%); }
html[data-color-mode="dark"] .submit-explainer { background:#12233a; border-color:var(--line); color:var(--text); }
html[data-color-mode="dark"] .support-note { background:#231a08; border-color:var(--amber); color:var(--text); }
html[data-color-mode="dark"] .form-result.is-success { background:#0a2e1f; border-color:var(--green); color:var(--text); }
html[data-color-mode="dark"] .form-result.is-error { background:#3a1410; border-color:var(--coral); color:var(--text); }

/* ============================================================
   Theme System Option A — ARCADE directory/game-system reach (DEV).
   Every selector here is arcade-scoped: WEB 1.0 renders exactly as
   before. Same arcade palette values, extended into the dominant
   repeated directory components — chips, header, rows, search
   framing — so Arcade reads as its own colour system. No layout,
   typography, content, or data-mode/data-family changes. */

/* ARCADE / LIGHT — magenta play on the warm console/paper base. */
html[data-theme="arcade"][data-color-mode="light"] .cat-chip { border:1px solid var(--magenta); color:var(--blue); background:#fff3d6; box-shadow:none; }
html[data-theme="arcade"][data-color-mode="light"] .cat-chip span { color:#7a6a58; }
html[data-theme="arcade"][data-color-mode="light"] .cat-chip:hover { background:#ffe9a8; border-color:var(--magenta); }
html[data-theme="arcade"][data-color-mode="light"] .cat-chip.active { background:var(--magenta); border:2px solid #241a12; color:#fff8e8; box-shadow:2px 2px 0 #241a12; }
html[data-theme="arcade"][data-color-mode="light"] .cat-chip.active span { color:#ffd93e; }
html[data-theme="arcade"][data-color-mode="light"] .dir-icon { color:var(--magenta); fill:currentColor; }
html[data-theme="arcade"][data-color-mode="light"] .directory-toolbar { border-bottom-color:var(--magenta); }
html[data-theme="arcade"][data-color-mode="light"] .dir-head { border-bottom-color:var(--magenta); }
html[data-theme="arcade"][data-color-mode="light"] .dir-index { color:var(--magenta); }
html[data-theme="arcade"][data-color-mode="light"] .dir-row:nth-child(even) { background:rgba(182,47,214,.07); }
html[data-theme="arcade"][data-color-mode="light"] .dir-row:hover { background:#ffefd0; }
html[data-theme="arcade"][data-color-mode="light"] .search-box { border-color:var(--magenta); }
html[data-theme="arcade"][data-color-mode="light"] .search-box input { border-color:var(--magenta); }

/* ARCADE / DARK — cyan structure, magenta secondary, yellow active. */
html[data-theme="arcade"][data-color-mode="dark"] .cat-chip { border:1px solid var(--magenta); color:var(--magenta); background:#120a24; box-shadow:none; }
html[data-theme="arcade"][data-color-mode="dark"] .cat-chip span { color:#8fa8c7; }
html[data-theme="arcade"][data-color-mode="dark"] .cat-chip:hover { background:#1e1038; }
html[data-theme="arcade"][data-color-mode="dark"] .cat-chip.active { background:#ffd93e; border:2px solid #ffd93e; color:#101318; box-shadow:2px 2px 0 var(--magenta); }
html[data-theme="arcade"][data-color-mode="dark"] .cat-chip.active span { color:#5a4300; }
html[data-theme="arcade"][data-color-mode="dark"] .dir-icon { color:var(--cyan); fill:currentColor; }
html[data-theme="arcade"][data-color-mode="dark"] .directory-toolbar { border-bottom-color:var(--cyan); }
html[data-theme="arcade"][data-color-mode="dark"] .dir-head { border-bottom-color:var(--cyan); color:#9beaff; }
html[data-theme="arcade"][data-color-mode="dark"] .dir-index { color:var(--magenta); }
html[data-theme="arcade"][data-color-mode="dark"] .dir-row { border-bottom-color:#1c3350; }
html[data-theme="arcade"][data-color-mode="dark"] .dir-row:nth-child(even) { background:rgba(53,224,255,.06); }
html[data-theme="arcade"][data-color-mode="dark"] .dir-row:hover { background:#10203a; }
html[data-theme="arcade"][data-color-mode="dark"] .search-box { border-color:var(--cyan); }
html[data-theme="arcade"][data-color-mode="dark"] .search-box input { border-color:var(--cyan); background:#04060f; }
