/* essays.gorewood.games — Demoscene Void design system.
   World: cracktro title screens. Ivory text riding baselines over an
   emissive black void; three dust fields drifting at layered speeds; one
   signal-amber accent; rank is depth (brightness + letterspacing), never
   size alone; prose is never enclosed by rules or boxes.
   Direction contract: see the HTML comment atop <body> in the base layout.
   Tokens only — no raw colors below the :root block. */

/* ---------- fonts ---------- */

@font-face {
  font-family: "Departure Mono";
  src: url("/assets/fonts/DepartureMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: url("/assets/fonts/atkinson-hyperlegible-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: url("/assets/fonts/atkinson-hyperlegible-latin-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: url("/assets/fonts/atkinson-hyperlegible-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/assets/fonts/bricolage-grotesque-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/assets/fonts/bricolage-grotesque-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/assets/fonts/bricolage-grotesque-latin-800-normal.woff2") format("woff2");
  font-weight: 800;
  font-display: swap;
}

/* ---------- tokens ---------- */

:root {
  color-scheme: dark;

  --void: #000000;
  --ash: #1a1a1a;
  --dust: #4a4a4a;
  --frost: #8f8f8f;
  --ivory: #e6e2d6;
  --signal: #ffb000;
  --phosphor: #56c8d8; /* CRT cyan: links, figure labels, meta accents */

  --font-bitmap: "Departure Mono", "Courier New", monospace;
  --font-display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Atkinson Hyperlegible", "Helvetica Neue", Arial, sans-serif;

  --measure: 66ch;
  --rail: clamp(1.25rem, 6vw, 7rem); /* left rail; baselines read as continuing past it */
  --page-max: 90rem; /* ultrawide cap: the page centers, the dust stays full-bleed */
  --step: 1.5rem; /* one baseline unit; vertical rhythm rides it */

  /* depth-as-rank: queue rows step back through these */
  --depth-0: var(--ivory);
  --depth-1: #c9c5ba;
  --depth-2: #a8a49a;
  --depth-3: var(--frost);
}

/* ---------- ground ---------- */

* { box-sizing: border-box; }

html {
  background: var(--void);
  scrollbar-color: var(--dust) var(--void);
  scrollbar-width: thin;
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--void);
  color: var(--ivory);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.75;
  padding: 0 var(--rail) calc(var(--step) * 2);
  overflow-x: hidden;
}

main { flex: 1; }

::selection {
  background: var(--signal);
  color: var(--void);
}

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

/* ---------- dust fields: three layers, far to near, drifting ---------- */

.dust,
.dust::before,
.dust::after {
  position: fixed;
  inset: 0;
  width: calc(100% + 520px);
  pointer-events: none;
  z-index: 0;
  content: "";
}

/* Dust is a committed material, not a compliance token: each field mixes
   several co-prime gradient tiles at varied dot sizes so no periodic lattice
   reads, and every field is actually perceptible on the void. A mask keeps
   the prose column quiet — the dust lives loudest in the open right field. */

.dust,
.dust::before,
.dust::after {
  -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.35) 52%, #000 78%);
  mask-image: linear-gradient(to right, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.35) 52%, #000 78%);
}

.dust {
  /* far field: fine, slow */
  background-image: radial-gradient(circle, #333333 1px, transparent 1px),
    radial-gradient(circle, #2b2b2b 1px, transparent 1px),
    radial-gradient(circle, #3a3a3a 1px, transparent 1px);
  background-size: 233px 181px, 307px 253px, 173px 137px;
  background-position: 40px 30px, 180px 120px, 90px 200px;
  animation: drift 240s linear infinite;
}

.dust::before {
  /* mid field */
  background-image: radial-gradient(circle, var(--dust) 1px, transparent 1px),
    radial-gradient(circle, #565656 1.5px, transparent 1.5px),
    radial-gradient(circle, #414141 1px, transparent 1px);
  background-size: 389px 293px, 449px 331px, 281px 227px;
  background-position: 90px 70px, 300px 210px, 40px 300px;
  opacity: 0.75;
  animation: drift 120s linear infinite;
}

.dust::after {
  /* near field: coarse, faster */
  background-image: radial-gradient(circle, #5d5d5d 2px, transparent 2px),
    radial-gradient(circle, #4f4f4f 3px, transparent 3px);
  background-size: 587px 439px, 907px 683px;
  background-position: 200px 140px, 500px 400px;
  opacity: 0.6;
  animation: drift 64s linear infinite;
}

@keyframes drift {
  to { transform: translateX(-520px); }
}

/* the work sits above the dust */
.site-header, main, .site-footer {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--page-max);
  margin-left: auto;
  margin-right: auto;
}

/* ---------- signature: the amber caret ---------- */

@keyframes caret-blink {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0; }
}

.cursor {
  display: inline-block;
  width: 0.55em;
  height: 0.95em;
  margin-left: 0.18em;
  vertical-align: -0.08em;
  background: var(--signal);
  animation: caret-blink 1.1s step-end infinite;
}

@media (prefers-reduced-motion: reduce) {
  .dust, .dust::before, .dust::after { animation: none; }
  .cursor { animation: none; }
}

/* ---------- chrome ---------- */

.site-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--step);
  padding: calc(var(--step) * 1.25) 0 0;
  font-family: var(--font-bitmap);
}

.site-name {
  color: var(--ivory);
  font-size: 1.05rem;
  letter-spacing: 0.08em;
  text-decoration: none;
}
.site-name:hover { color: var(--signal); }

.site-nav {
  display: flex;
  gap: 1.75rem;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
}
.site-nav a {
  color: var(--frost);
  text-decoration: none;
}
/* caret space is reserved so the hover never shifts siblings */
.site-nav a::before { content: "> "; color: var(--signal); opacity: 0; }
.site-nav a:hover { color: var(--signal); }
.site-nav a:hover::before { opacity: 1; }

.site-footer {
  margin-top: calc(var(--step) * 4);
  font-family: var(--font-bitmap);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--frost);
}
.site-footer a { color: var(--ivory); text-decoration: none; }
.site-footer a:hover { color: var(--signal); }
.site-footer p { margin: 0; }

/* ---------- home ---------- */

.masthead {
  margin: calc(var(--step) * 3) 0 calc(var(--step) * 2);
}

.masthead-title {
  font-family: var(--font-bitmap);
  font-weight: 400;
  font-size: clamp(3.5rem, 12vw, 7.5rem);
  line-height: 0.95;
  letter-spacing: -0.01em;
  margin: 0 0 var(--step) -0.06em; /* ride past the rail's optical edge */
  color: var(--ivory);
}
.masthead-title .tick { color: var(--signal); }

.masthead-sub {
  max-width: 44ch;
  margin: 0;
  color: var(--frost);
}

/* the queue */

.post-list {
  list-style: none;
  margin: calc(var(--step) * 2) 0 0;
  padding: 0;
}

.post-list li {
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  align-items: baseline;
  padding: calc(var(--step) * 0.75) 0;
  color: var(--row-ink, var(--ivory));
}

/* depth-as-rank: newest brightest and widest-set, older rows step back in
   both brightness and letterspacing */
.post-list li:nth-child(1) { --row-ink: var(--depth-0); letter-spacing: 0.015em; }
.post-list li:nth-child(2) { --row-ink: var(--depth-1); letter-spacing: 0.005em; }
.post-list li:nth-child(3) { --row-ink: var(--depth-2); letter-spacing: -0.005em; }
.post-list li:nth-child(n + 4) { --row-ink: var(--depth-3); letter-spacing: -0.01em; }

.post-list .row-caret {
  font-family: var(--font-bitmap);
  color: var(--dust);
}
.post-list li:first-child .row-caret { color: var(--signal); }

.post-list a {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.15rem, 2.8vw, 1.6rem);
  line-height: 1.3;
  color: inherit;
  text-decoration: none;
}
.post-list a:hover { color: var(--signal); }

.post-list .row-meta {
  grid-column: 2;
  margin-top: 0.35rem;
  font-family: var(--font-bitmap);
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  color: var(--frost);
}

/* measured geometry: reading time as a dot meter */
.meter { color: var(--dust); letter-spacing: 0.22em; }
.meter .lit { color: var(--signal); }

.queue-idle {
  font-family: var(--font-bitmap);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
  color: var(--frost);
  margin: calc(var(--step) * 2) 0;
}

.draft-badge {
  font-family: var(--font-bitmap);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  color: var(--signal);
  text-transform: lowercase;
}

/* ---------- track index ---------- */

.track-header h1,
.track h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 6vw, 3.5rem);
  line-height: 1.05;
  margin: calc(var(--step) * 2.5) 0 var(--step);
}

.track-header p {
  max-width: var(--measure);
  color: var(--frost);
  margin: 0 0 calc(var(--step) * 1.5);
}

.track-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: part;
}

.track-list li {
  display: grid;
  grid-template-columns: 3rem 1fr;
  align-items: baseline;
  padding: calc(var(--step) * 0.6) 0;
  counter-increment: part;
}

.track-list li::before {
  content: counter(part, decimal-leading-zero);
  font-family: var(--font-bitmap);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: var(--frost);
}

.track-list a {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.05rem, 2.4vw, 1.4rem);
  color: var(--ivory);
  text-decoration: none;
}
.track-list a:hover { color: var(--signal); }

.track-list .row-meta {
  grid-column: 2;
  margin: 0.3rem 0 0;
  font-family: var(--font-bitmap);
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  color: var(--frost);
}

/* ---------- post ---------- */

.post { max-width: none; }

.post-track {
  font-family: var(--font-bitmap);
  font-size: 0.78rem;
  letter-spacing: 0.11em;
  margin: calc(var(--step) * 2.5) 0 0;
  color: var(--frost);
}
.post-track a { color: var(--phosphor); text-decoration: none; }
.post-track a:hover { color: var(--signal); }

.post-header h1,
.post > h1:first-child,
main > h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.1rem, 5.5vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  max-width: 22ch;
  margin: calc(var(--step) * 0.75) 0 var(--step);
  text-wrap: balance;
}

.post-subtitle {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
  line-height: 1.4;
  color: var(--frost);
  max-width: 40ch;
  margin: 0 0 var(--step);
  text-wrap: balance;
}

.post-meta {
  font-family: var(--font-bitmap);
  font-size: 0.78rem;
  letter-spacing: 0.11em;
  color: var(--frost);
  margin: 0 0 calc(var(--step) * 2);
}

/* build-time contents map */
.toc {
  margin: 0 0 calc(var(--step) * 2);
  font-family: var(--font-bitmap);
}
.toc-label {
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  color: var(--phosphor);
  margin: 0 0 0.5rem;
}
.toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--measure);
}
.toc li {
  margin-bottom: 0.45rem;
  padding-left: 1.3rem;
  text-indent: -1.3rem; /* wrapped lines align past the caret */
}
/* .post .toc doubles specificity so the prose-link underline never wins */
.post .toc a, .toc a {
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  color: var(--frost);
  text-decoration: none;
}
.toc a::before { content: "> "; color: var(--dust); }
.post .toc a:hover, .toc a:hover { color: var(--signal); text-decoration: none; }
.toc a:hover::before { color: var(--signal); }

/* wide screens: the contents map rides the right rail instead of pushing
   the opening below the fold. Absolute with top/left auto keeps its static
   vertical position (beside the standfirst) while leaving the flow. */
@media (min-width: 1200px) {
  .post { position: relative; }
  .post .toc {
    position: absolute;
    right: 0;
    width: 19rem;
    margin: 0;
  }
}

/* scroll progress: zero-JS scroll-driven animation. The animation only
   applies inside @supports — without the guard, a browser lacking
   animation-timeline runs a 0s animation and `forwards` pins the bar
   full-width forever. Outside support it stays scaleX(0): invisible. */
@keyframes progress-grow { to { transform: scaleX(1); } }
.progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--signal);
  transform-origin: 0 50%;
  transform: scaleX(0);
  z-index: 2;
}
@supports (animation-timeline: scroll()) {
  .progress {
    animation: progress-grow linear forwards;
    animation-timeline: scroll(root);
  }
}
@media (prefers-reduced-motion: reduce) { .progress { display: none; } }

/* prose — the reading surface. Never enclosed. */

.post p, .post ul, .post ol, main > p, main > ul, main > ol {
  max-width: var(--measure);
}

.post p { margin: 0 0 calc(var(--step) * 0.85); }

.post h2, main > h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.65rem;
  line-height: 1.3;
  max-width: 36ch;
  margin: calc(var(--step) * 3) 0 calc(var(--step) * 0.6);
}
.post h2::before, main > h2::before {
  content: "> ";
  font-family: var(--font-bitmap);
  font-size: 0.8em;
  color: var(--signal);
}

.post h3, main > h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  margin: calc(var(--step) * 1.5) 0 calc(var(--step) * 0.5);
}

.post a, main a { color: var(--phosphor); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--phosphor) 45%, transparent); text-underline-offset: 0.22em; }
.post a:hover, main a:hover { color: var(--signal); text-decoration-color: var(--signal); }

.post strong { color: var(--ivory); }
.post em { font-style: italic; }

/* beat openers: a bold sentence opening a paragraph marks a new beat
   (cairns' newthought, in this world's voice) — brighter, display face,
   with a quiet dust tick hanging in the lead margin. p.beat is tagged at
   build time (a bare CSS :first-child would also hit mid-sentence strongs
   whose paragraph merely starts with an element). */
.post p.beat > strong:first-child {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02em;
  color: var(--signal);
}
.post p.beat > strong:first-child::before {
  content: "■ ";
  font-size: 0.55em;
  color: var(--dust);
  vertical-align: 0.2em;
}

/* standfirst: the opening paragraph reads as a deck, not body copy.
   :is() covers both shapes — with and without the TOC between them. */
.post > :is(header, .toc) + p {
  font-size: 1.2rem;
  line-height: 1.65;
  color: var(--frost);
  max-width: 56ch;
  margin-bottom: calc(var(--step) * 1.5);
}

.post blockquote, main blockquote {
  position: relative;
  margin: calc(var(--step) * 1.25) 0 calc(var(--step) * 1.25) 1.9rem;
  max-width: calc(var(--measure) - 4ch);
  font-size: 1.15rem;
  line-height: 1.6;
  color: var(--frost);
}
.post blockquote::before, main blockquote::before {
  content: ">>";
  position: absolute;
  left: -1.9rem;
  top: 0.15rem;
  font-family: var(--font-bitmap);
  font-size: 0.8rem;
  color: var(--phosphor);
}

.post code, main code {
  font-family: var(--font-bitmap);
  font-size: 0.88em;
  background: var(--ash);
  padding: 0.08em 0.35em;
}

/* figure plates: every pre and diagram is a numbered exhibit */
.post { counter-reset: fig; }

.diagram {
  margin: calc(var(--step) * 1.25) 0;
  max-width: min(88ch, 100%);
}
/* force the SVG to the column: D2's natural size can be enormous, and
   width:100% (not just max-width) scales it down; full detail lives behind
   the view-full-size link */
.diagram svg {
  width: 100%;
  height: auto;
  max-height: 85vh; /* a tall diagram letterboxes instead of eating the page */
  display: block;
}
.diagram-actions {
  margin: 0.5rem 0 0;
  font-family: var(--font-bitmap);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
}

.diagram-expand,
.diagram-close {
  font-family: var(--font-bitmap);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  color: var(--phosphor);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.diagram-expand:hover, .diagram-close:hover { color: var(--signal); }

/* fullscreen diagram overlay (native popover — no JS) */
.diagram-full {
  width: 100vw;
  height: 100dvh;
  max-width: 100vw;
  max-height: 100dvh;
  margin: 0;
  border: 0;
  background: var(--void);
  color: var(--ivory);
  padding: calc(var(--step) * 2) var(--rail);
  overflow: auto;
}
.diagram-full::backdrop { background: rgba(0, 0, 0, 0.85); }
.diagram-full img {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--step);
}
.diagram-close {
  position: sticky;
  top: 0;
  float: right;
}
.diagram::before {
  counter-increment: fig;
  content: "fig " counter(fig, decimal-leading-zero);
  display: block;
  margin-bottom: calc(var(--step) * 0.5);
  font-family: var(--font-bitmap);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  color: var(--phosphor);
}
.post pre, main pre {
  background: var(--ash);
  padding: var(--step);
  margin: calc(var(--step) * 1.25) 0;
  max-width: min(88ch, 100%);
  overflow-x: auto;
  line-height: 1.5;
}
.post pre::before {
  counter-increment: fig;
  content: "fig " counter(fig, decimal-leading-zero);
  display: block;
  margin-bottom: calc(var(--step) * 0.75);
  font-family: var(--font-bitmap);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  color: var(--phosphor);
}
.post pre code, main pre code {
  background: none;
  padding: 0;
  font-size: 0.82rem;
}

.post hr, main hr {
  border: 0;
  margin: calc(var(--step) * 1.5) 0;
  max-width: var(--measure);
  font-family: var(--font-bitmap);
  color: var(--dust);
  text-align: left;
}
.post hr::after, main hr::after { content: "· · ·"; letter-spacing: 0.6em; }

/* footnotes (markdown-it-footnote): dated claims and temporal asides.
   Collapsed <details>; fragment navigation from a ref auto-expands it. */
sup.footnote-ref { font-family: var(--font-bitmap); font-size: 0.7em; }
sup.footnote-ref a, a.footnote-backref { text-decoration: none; }
.post .footnotes {
  font-size: 0.85rem;
  color: var(--frost);
  max-width: var(--measure);
  margin: calc(var(--step) * 2) 0 0;
}
.post .footnotes summary {
  font-family: var(--font-bitmap);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  color: var(--phosphor);
  cursor: pointer;
  list-style: none;
  margin-bottom: 0.5rem;
}
.post .footnotes summary::-webkit-details-marker { display: none; }
.post .footnotes summary::before { content: "+ "; color: var(--dust); }
.post .footnotes[open] summary::before { content: "- "; }
.post .footnotes summary:hover { color: var(--signal); }

.post ul, .post ol { padding-left: 1.4rem; }
.post li { margin-bottom: 0.35rem; }
.post ul { list-style: none; padding-left: 1.55rem; }
.post ul li { position: relative; }
.post ul li::before {
  content: ">";
  position: absolute;
  left: -1.55rem;
  font-family: var(--font-bitmap);
  color: var(--frost);
}

.post img { max-width: 100%; height: auto; }

.post table {
  border-collapse: collapse;
  font-size: 0.92rem;
  font-variant-numeric: tabular-nums;
  margin: 0 0 calc(var(--step) * 0.85);
}
.post th, .post td {
  text-align: left;
  padding: 0.35rem 1.25rem 0.35rem 0;
  vertical-align: top;
}
.post th {
  font-family: var(--font-bitmap);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  color: var(--frost);
}

/* prev/next in track */

.track-nav {
  margin-top: calc(var(--step) * 2.5);
  font-family: var(--font-bitmap);
  font-size: 0.85rem;
  letter-spacing: 0.05em;
}
.track-nav p { margin: 0 0 0.5rem; color: var(--frost); }
.track-nav a { color: var(--ivory); text-decoration: none; }
.track-nav a:hover { color: var(--signal); }
.track-nav a::before { content: "> "; color: var(--signal); }

/* ---------- utility ---------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 40rem) {
  body { font-size: 1rem; }
  .post-list li { grid-template-columns: 1.1rem 1fr; }
  .track-list li { grid-template-columns: 2.2rem 1fr; }
}
