/* Ruhkery — one stylesheet over the tokens (assets/tokens.css).
   No build. Areas colour themselves from --hue, which comes from content, so
   adding an area is a content change, not a CSS change.

   TWO GROUNDS. The topbar and the footer are the logo's own near-black; the
   reading surface between them is paper. That is not decoration — the mark is
   drawn for a dark canvas and looks wrong on white, while research entries and
   CRM tables are not read on black. Each ground has its own verified text
   colours in tokens.css (--on-dark-* against --ink-deep, --ink-* against
   --paper) and they are not interchangeable. */

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--paper); color: var(--ink);
  font-family: var(--sans); font-size: var(--step-0); line-height: var(--leading-normal);
  display: flex; flex-direction: column; min-height: 100vh;
}
a { color: inherit; }
code { font-family: var(--mono); font-size: 0.88em; background: var(--sunk); padding: 1px 5px; border-radius: 4px; }

/* ---------- chrome: the brand ground ---------- */
.topbar {
  display: flex; align-items: center; gap: var(--s6);
  padding: 0 var(--s6); height: 64px; flex: none;
  background: var(--ink-deep); color: var(--on-dark);
  border-bottom: 1px solid var(--ink-raise);
  /* the mark hangs out of this box */
  overflow: visible; position: relative; z-index: 3;
}
/* The faint constellation behind the mark in the logo, as a ground rather than
   an image: two soft radial washes, no request, no file to keep in sync. */
.topbar {
  background-image:
    radial-gradient(60ch 20ch at 12% 140%, rgb(23 151 207 / 14%), transparent 70%),
    radial-gradient(40ch 16ch at 88% -40%, rgb(111 198 235 / 10%), transparent 70%);
}

.wordmark {
  display: flex; align-items: center; gap: var(--s3);
  text-decoration: none; color: var(--on-dark);
  font-weight: var(--wordmark-weight); font-size: 20px;
  letter-spacing: var(--wordmark-tracking); text-transform: uppercase;
}
.wordmark img {
  width: var(--chrome-mark-size); height: var(--chrome-mark-size); display: block;
  /* Hangs past the bottom edge. `position: relative` gives it a stacking
     context so it sits OVER the content it now overlaps rather than under it. */
  position: relative; top: var(--chrome-mark-drop); z-index: 2;
  filter: var(--chrome-mark-glow);
}
.wordmark .division {
  font-size: 11px; font-weight: 700; letter-spacing: var(--tagline-tracking);
  color: var(--on-dark-accent); align-self: center; padding-top: 2px;
}
.wordmark:hover .division { color: var(--brand-200); }

.nav { display: flex; gap: var(--s5); }
.nav a {
  text-decoration: none; color: var(--on-dark-muted); font-size: 15px; font-weight: 500;
  padding: var(--s1) 0; border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--on-dark); border-bottom-color: var(--brand-500); }
.nav a:active { color: var(--on-dark-accent); }
.nav-lock { color: var(--on-dark-faint); margin-left: 4px; }
.account { margin-left: auto; display: flex; align-items: center; gap: var(--s4); font-size: 14px; }
.who { color: var(--on-dark-muted); }

.btn {
  display: inline-block; text-decoration: none;
  background: var(--brand-600); color: var(--ink-invert);
  padding: 9px 16px; border-radius: 8px;
  font-size: 14px; font-weight: 600;
}
.btn:hover { background: var(--brand-700); }
.btn:active { transform: translateY(1px); }
.btn-quiet { background: transparent; color: var(--ink-muted); border: 1px solid var(--line-strong); }
.btn-quiet:hover { background: var(--sunk); color: var(--ink); }

/* On the dark chrome a quiet button has to borrow the dark ground's palette,
   or it renders as invisible grey-on-black. */
.topbar .btn-quiet { color: var(--on-dark-muted); border-color: var(--ink-raise); }
.topbar .btn-quiet:hover { background: rgb(255 255 255 / 8%); color: var(--on-dark); }
.topbar .btn { background: var(--brand-500); color: #02050b; }
.topbar .btn:hover { background: var(--brand-400); }

main { flex: 1; width: 100%; max-width: 860px; margin: 0 auto; padding: 56px 28px 72px; }
main.wide { max-width: 1180px; }

.footer {
  flex: none; display: flex; gap: var(--s5); align-items: center;
  padding: 0 var(--s6); height: 56px;
  border-top: 1px solid var(--ink-raise); background: var(--ink-deep);
  font-size: 13px; color: var(--on-dark-faint);
}
.footer-host { margin-left: auto; font-family: var(--mono); }
.footer a { color: var(--on-dark-muted); }

/* ---------- a mounted module's workspace ----------
   Atlas draws its own workspace; the page around it is the host's. These rules
   are the seam: enough to place the module's head and tabs on our page, and no
   opinion about anything inside the mount point. */
.atlas-module-head {
  display: flex; align-items: flex-end; gap: var(--s6); flex-wrap: wrap;
  margin-bottom: var(--s5);
}
.atlas-module-title {
  font-size: var(--step-3); margin: 0;
  font-weight: var(--wordmark-weight); letter-spacing: 0.06em;
}
/* The attribution rides the heading rather than sitting under it: at this size
   a second line would read as a subtitle competing with the lede below. */
.atlas-module-by {
  font-size: var(--step--1); font-weight: 600; letter-spacing: 0.1em;
  color: var(--ink-faint); text-transform: none;
  margin-left: var(--s1);
}
.atlas-module-lede { color: var(--ink-muted); margin: var(--s1) 0 0; max-width: var(--measure); }
.atlas-module-actions { margin-left: auto; display: flex; align-items: center; gap: var(--s3); }
.atlas-module .explorer-mount { margin-top: var(--s5); }

/* Four columns need more room than a reading measure — but NOT unlimited. The
   explorer caps its own view at 1280px and centres it, so a full-width page
   leaves a gap after the rail and pushes the last column off the screen. The
   page is sized to hold the rail plus that view, and no wider. */
/* The explorer was built to own a viewport: a rail on the left and a canvas
   that fills what is left. Inside the page's reading column it has neither, so
   the module goes FULL BLEED — the same geometry it has standalone — while the
   page furniture above it stays in the column where it belongs.

   `width: 100vw` with a negative half-viewport margin is the standard escape.
   `overflow-x: clip` on the page stops the extra width becoming a sideways
   scrollbar on narrow windows. */
main:has(.atlas-module) { max-width: none; padding-left: 0; padding-right: 0; }
.atlas-module > .atlas-module-head,
.atlas-module > .atlas-module-tabs {
  max-width: 1180px; margin-inline: auto; padding-inline: var(--s6);
}
.atlas-module > .explorer-mount {
  width: 100vw; margin-left: calc(50% - 50vw);
  /* The board is as wide as its columns need. Scroll it rather than clipping —
     `overflow-x: clip` here cut the last column off entirely, which looks like
     a missing column rather than a narrow window. */
  overflow-x: auto;
}

.atlas-module-label { color: var(--ink-faint); font-size: var(--step--1); }
.atlas-module-stamp { color: var(--ink-faint); font-size: var(--step--1); font-family: var(--mono); }
.atlas-module-picker {
  font: inherit; font-family: var(--mono); font-size: var(--step--1);
  color: var(--ink); background: var(--card);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: var(--s1) var(--s2);
}
.atlas-module-picker:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 1px; }

.atlas-module-tabs { display: flex; gap: var(--s1); border-bottom: 1px solid var(--line); }
.atlas-module-tabs .tab {
  background: none; border: none; cursor: pointer;
  padding: var(--s3) var(--s4);
  font: inherit; font-size: var(--step--1); font-weight: 600;
  color: var(--ink-muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.atlas-module-tabs .tab:hover { color: var(--ink); }
.atlas-module-tabs .tab[aria-selected="true"] { color: var(--brand-700); border-bottom-color: var(--brand-500); }

/* ---------- a gated entry's header ----------
   The mark sits ABOVE the title rather than beside it: at 44px next to a 44px
   heading it would compete, and the point of decoration is to be recognised
   without being read. */
.hero-entry .entry-mark {
  display: block; width: 44px; height: 44px;
  margin: 0 0 var(--s4);
  /* This ground is paper, not chrome, so the mark needs no glow — it is
     navy-on-blue and already has its own contrast here. */
}

/* ---------- sections ---------- */
.hero h1 { font-size: 44px; line-height: 1.1; letter-spacing: -0.03em; margin: 0 0 12px; }
.hero-sub { font-size: 19px; color: var(--ink-muted); margin: 0 0 8px; max-width: var(--measure); }
.prose { margin-top: 44px; }
.prose h2 { font-size: 22px; letter-spacing: -0.01em; margin: 0 0 8px; }
.prose p { color: var(--ink-muted); margin: 0; max-width: var(--measure); }
.unknown-kind p { color: #92400e; background: #fef3c7; padding: 12px 14px; border-radius: 8px; }
.areas { margin-top: 56px; }

/* ---------- the area badges ----------
   Hues run one cool sweep — violet, indigo, blue — CONVERGING on the brand at
   research. That is the same claim the old rainbow made badly: the private
   thinking is the centre of this venture, not a decorative corner of it.

   The lightness is not a taste decision. White type on hsl(hue 82% 52%) — what
   this was — measures 1.56:1 over the teal end and 2.56:1 over the brand hue,
   both far below AA. At 36% every hue in the sweep clears 4.5:1. A hue-driven
   badge cannot pick its own lightness, so the floor is set by the WORST hue in
   the range, and hues that cannot reach it are not in the range. */
.badge-grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.badge {
  display: block; text-decoration: none;
  background:
    linear-gradient(160deg,
      hsl(var(--hue) 82% 36%) 0%,
      hsl(calc(var(--hue) - 26) 74% 28%) 100%);
  color: #fff;
  border-radius: var(--radius);
  padding: 26px 24px 22px;
  box-shadow: var(--shadow-soft);
  position: relative; overflow: hidden;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.badge::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 88% 0%, rgb(255 255 255 / 12%), transparent 60%);
  pointer-events: none;
}
a.badge:hover { transform: translateY(-2px); box-shadow: 0 2px 4px rgb(20 24 31 / 8%), 0 14px 34px rgb(20 24 31 / 12%); }
a.badge:active { transform: translateY(0); }

.badge-name {
  display: inline-block;
  font-family: var(--mono); font-size: 12px; font-weight: 700;
  letter-spacing: 0.16em;
  background: rgb(0 0 0 / 22%);
  padding: 5px 11px; border-radius: 999px;
  margin-bottom: 14px;
}
.badge-title { display: block; font-size: 26px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; }
.badge-desc { margin: 10px 0 16px; font-size: 15px; line-height: 1.5; color: rgb(255 255 255 / 92%); }
.badge-lock, .badge-open {
  display: inline-block; font-size: 12px; font-weight: 600;
  padding: 4px 10px; border-radius: 999px;
  background: rgb(0 0 0 / 20%); color: rgb(255 255 255 / 94%);
}
.badge-open { background: rgb(255 255 255 / 22%); }

.badge-xl { padding: 40px 34px 34px; }
.badge-xl .badge-title { font-size: 40px; }
.badge-xl .badge-desc { font-size: 17px; max-width: 64ch; }
.badge-xl .badge-name { font-size: 13px; }

/* ---------- area index ---------- */
.entries { margin-top: 44px; }
.entries h2 { font-size: 22px; margin: 0 0 20px; }
.entry-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.entry {
  display: block; text-decoration: none;
  background: var(--card); border: 1px solid var(--line-strong);
  border-radius: 12px; padding: 20px;
  transition: border-color 120ms ease, transform 120ms ease;
}
.entry:hover { border-color: var(--ink-faint); transform: translateY(-1px); }
.entry:active { transform: translateY(0); }
.entry h3 { margin: 0 0 6px; font-size: 17px; }
.entry p { margin: 0 0 12px; color: var(--ink-muted); font-size: 15px; }
.entry code { font-size: 12px; color: var(--ink-faint); background: var(--sunk); }
.empty { color: var(--ink-muted); background: var(--card); border: 1px dashed var(--line-strong); border-radius: 12px; padding: 22px; }

/* ---------- stub panels ---------- */
.panel { background: var(--card); border: 1px solid var(--line-strong); border-radius: 12px; padding: 22px; margin-top: 24px; }
.panel h3 { margin: 0 0 10px; font-size: 17px; }
.panel dl { display: grid; grid-template-columns: max-content 1fr; gap: 8px 20px; margin: 0; font-size: 15px; }
.panel dt { color: var(--ink-faint); }
.panel dd { margin: 0; font-family: var(--mono); font-size: 14px; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---------- tables of contents ----------
   Two kinds: the reading list for an area, and the in-page jump list for one
   piece. Both are navigation, so both are numbered and neither competes with
   the prose for weight. */
.toc {
  background: var(--card);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--brand-500);
  border-radius: var(--radius);
  padding: var(--s5) var(--s6);
  margin: var(--s8) 0;
  max-width: var(--measure);
}
.toc-label {
  margin: 0 0 var(--s3);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.toc ol { margin: 0; padding-left: var(--s5); }
.toc li { margin: var(--s2) 0; }
.toc a { color: var(--brand-600); text-decoration: none; font-weight: 500; }
.toc a:hover { text-decoration: underline; }
.toc a:active { color: var(--brand-700); }
.toc-area li { margin: var(--s4) 0; }
.toc-sum { display: block; color: var(--ink-muted); font-size: var(--step--1); margin-top: 2px; }

/* ---------- data tables ---------- */
.table-wrap { overflow-x: auto; margin: var(--s4) 0; }
table.data { border-collapse: collapse; width: 100%; font-size: var(--step--1); min-width: 520px; }
table.data th {
  text-align: left; padding: var(--s2) var(--s4) var(--s2) 0;
  border-bottom: 2px solid var(--brand-500);
  font-weight: 600; color: var(--ink);
  white-space: nowrap;
}
table.data td { padding: var(--s2) var(--s4) var(--s2) 0; border-bottom: 1px solid var(--line); vertical-align: top; color: var(--ink-muted); }
table.data td:first-child { color: var(--ink); font-weight: 500; white-space: nowrap; }

/* prose sections are anchor targets now — keep the heading clear of the topbar */
.prose[id] { scroll-margin-top: var(--s8); }

/* ---------- citation lists ---------- */
ul.links { list-style: none; margin: var(--s4) 0 0; padding: 0; max-width: var(--measure); }
ul.links li { padding: var(--s2) 0; border-bottom: 1px solid var(--line); }
ul.links a { color: var(--brand-600); text-decoration: none; font-weight: 500; }
ul.links a:hover { text-decoration: underline; }
ul.links a:active { color: var(--brand-700); }
.link-note { display: block; color: var(--ink-faint); font-size: var(--step--1); margin-top: 2px; }

/* ---------- the brand lockup ----------
   The full drawn mark. Used once, at the top of the public home page: it is the
   one place with room for the illustration, and repeating it would spend the
   impact it has by being rare.

   The asset is a PNG with a real alpha channel, so it sits on any ground. The
   panel behind it stays dark anyway — the artwork's outlines and its glow were
   drawn for a dark canvas and it is simply strongest there — but that is now a
   choice rather than a constraint the file imposes. */
.hero-brand {
  margin: calc(var(--s12) * -1) calc(var(--s6) * -1) var(--s10);
  padding: var(--s8) var(--s6) var(--s10);
  background: var(--ink-deep);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  text-align: center;
}
.hero-brand .emblem {
  display: block; width: 100%; max-width: 300px; height: auto;
  margin: 0 auto var(--s5);
}
/* The name, set rather than drawn. Tracked and uppercased to match the
   wordmark in the bar, so the two readings of the same word agree. Its size is
   capped in ch rather than px: this is one word, and a viewport-scaled heading
   that outgrows the emblem above it inverts the hierarchy. */
.hero-brand h1 {
  color: var(--on-dark);
  font-weight: var(--wordmark-weight); text-transform: uppercase;
  letter-spacing: 0.14em; font-size: clamp(32px, 7vw, 52px);
  margin: 0 0 var(--s4);
  /* Uppercase tracking adds a trailing gap after the last letter that optical
     centring has to pay back, or the word sits visibly right of the emblem. */
  text-indent: 0.14em;
}
.hero-brand .hero-sub {
  font-size: var(--step-1); max-width: 46ch;
  color: var(--on-dark-muted); margin-left: auto; margin-right: auto;
}
