/* ============================================================
   J.D. HALVORSEN — jdhalvorsen.com
   "The Yard Ledger" — dark slate, dome-pale ink, one
   phosphor-teal accent. Industrial hard-SF: hull plate,
   manifests, tally marks. Flat, engineered, no chrome.
   Fonts self-hosted (OFL).

   PALETTE IS SHARED WITH THE VIDEO BRAND — the "Signals from the
   Black" channel kit (Hub: backend/assets/channels/signals/brand/
   DESIGN.md, locked 2026-07-19). Accent, deep phosphor and the rust
   counter below are that kit's exact values, so a viewer arriving
   from a video meets the same signal colour. Don't drift them
   independently; change the kit first, then mirror it here.
   ============================================================ */

/* ---------- fonts (both variable: one file each) ---------- */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(/fonts/spacegrotesk-var-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-var-latin.woff2) format('woff2');
}

:root {
  /* color / ground — slate, hull plate at night */
  --ground:        #14181B;
  --panel:         #1B2125;
  --panel-deep:    #0F1214;
  /* color / ink — dome-pale warm white */
  --ink:           #E9E4D9;
  --muted:         #99A19D;
  --faint:         #667070;
  /* color / lines */
  --line:          #4A5553;
  --line-soft:     #262D30;
  /* color / accent (exactly one) — phosphor teal, the signal */
  --accent:        #4FD6C9;
  --accent-deep:   #2A9E93;
  --on-accent:     #14181B;
  /* the one counter-colour — oxidized rust, used sparingly */
  --counter:       #B4693F;
  /* semantic */
  --err:           #DE7A5C;
  /* type */
  --font-display:  'Space Grotesk', 'Segoe UI', sans-serif;
  --font-mono:     'JetBrains Mono', 'Consolas', monospace;
  --w-bold:        700;
  --w-semi:        600;
  --w-medium:      500;
  --w-regular:     400;
  --w-light:       300;
  --track-tight:  -0.02em;
  --track-label:   0.09em;
  /* type scale */
  --text-display:  clamp(36px, 6vw, 68px);
  --text-body:     17px;
  --text-small:    14px;
  --text-data:     15px;
  --text-label:    12px;
  /* spacing */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px;
  --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;
  /* rules */
  --rule-hair:     1px solid var(--line-soft);
  --rule-ink:      1px solid var(--line);
  --rule-frame:    2px solid var(--line);
  /* motion */
  --dur-tick:      150ms;
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);
}

* { margin: 0; box-sizing: border-box; }
html { height: 100%; }
body {
  min-height: 100%;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: var(--w-light);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--accent); }
img { max-width: 100%; display: block; }
::selection { background: var(--accent); color: var(--on-accent); }

/* mono ledger text */
.label {
  font: var(--w-medium) var(--text-label)/1.2 var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--faint);
}

/* the torch cut — the brand's mark: a bar with one cut through it */
.cut {
  width: 64px; height: 4px;
  background: linear-gradient(90deg, var(--accent) 0 46px, transparent 46px 52px, var(--accent) 52px 64px);
}

/* tally marks — sleeve tallies, one per hull worked */
.tally {
  display: inline-block; width: 18px; height: 14px;
  background: repeating-linear-gradient(90deg, var(--accent) 0 3px, transparent 3px 8px);
}

/* wordmark plate (utility pages): tally + stacked name */
.plate { display: inline-flex; flex-direction: column; align-items: center; gap: var(--s-3); }
.plate .tally { width: 28px; height: 16px; }
.plate .wm {
  font: var(--w-semi) 21px/1.25 var(--font-display); text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink); text-align: center;
}
.plate .wm-sub {
  font: var(--w-regular) var(--text-label)/1.4 var(--font-mono); text-transform: uppercase;
  letter-spacing: var(--track-label); color: var(--faint);
}

/* ---------------- masthead ---------------- */
.masthead {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: var(--s-4); border-bottom: var(--rule-hair);
  position: sticky; top: 0; z-index: 50; background: var(--ground);
  width: 100%; padding: var(--s-4) max(var(--s-5), calc((100% - 1240px) / 2));
}
.masthead .brand {
  display: inline-flex; align-items: center; gap: var(--s-3);
  text-decoration: none;
  font: var(--w-semi) 14px/1.1 var(--font-display); text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--ink);
}
.masthead .brand .tally { width: 16px; height: 12px; }
.masthead nav { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-5); }
.masthead nav a:not(.btn) {
  font: var(--w-medium) 14px/1.2 var(--font-display);
  color: var(--muted); text-decoration: none;
}
.masthead nav a:not(.btn):hover { color: var(--accent); }
.masthead nav a[aria-current="page"] { color: var(--ink); border-bottom: 2px solid var(--accent); padding-bottom: 3px; }

/* ---------------- buttons ---------------- */
.btn {
  display: inline-block; padding: 15px 26px; border: 1px solid var(--line);
  cursor: pointer; text-decoration: none;
  font: var(--w-semi) 15px/1 var(--font-display); color: var(--ink);
  background: transparent; transition: border-color var(--dur-tick) var(--ease-out), background var(--dur-tick) var(--ease-out), color var(--dur-tick) var(--ease-out);
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn:active { transform: translateY(1px); }
.btn-fill { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-fill:hover { background: var(--ink); border-color: var(--ink); color: var(--ground); }
.btn-sm { padding: 11px 18px; font-size: 14px; }

/* ---------------- zones (page sections) ---------------- */
.zone { padding: var(--s-9) 0; }
.plated { background: var(--panel-deep); border-block: var(--rule-hair); }
.rail { max-width: 1240px; margin: 0 auto; padding: 0 var(--s-5); }

/* entry line — a ledger entry heading: tally, mono label, rule to the edge */
.entry-line { display: flex; align-items: center; gap: var(--s-4); }
.entry-line .tally { flex: 0 0 auto; }
.entry-line .e-label {
  flex: 0 0 auto;
  font: var(--w-medium) var(--text-label)/1.2 var(--font-mono); text-transform: uppercase;
  letter-spacing: var(--track-label); color: var(--accent);
}
.entry-line::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line-soft); }

.zone h2 { margin-top: var(--s-5); font: var(--w-semi) clamp(28px, 4vw, 44px)/1.1 var(--font-display); letter-spacing: var(--track-tight); text-wrap: balance; max-width: 26ch; }
.intro { margin-top: var(--s-4); color: var(--muted); text-wrap: pretty; max-width: 64ch; }
.copy { color: var(--muted); text-wrap: pretty; margin-top: var(--s-4); }
.copy strong, .intro strong { color: var(--ink); font-weight: var(--w-medium); }
.copy em, .intro em { font-style: normal; color: var(--accent); }
.actions { margin-top: var(--s-6); display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); }
.mt-6 { margin-top: var(--s-6); }

/* ---------------- yard log (lore / world entries) ----------------
   Open ledger entries: hairline rules and type only, no panels. */
.yardlog { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--s-9); margin-top: var(--s-6); border-top: var(--rule-ink); }
@media (max-width: 780px) { .yardlog { grid-template-columns: 1fr; } }
.log-entry { padding: var(--s-6) 0; border-bottom: var(--rule-hair); }
.log-entry .l-label { font: var(--w-medium) var(--text-label)/1.2 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--accent); }
.log-entry h3 { margin-top: var(--s-3); font: var(--w-semi) 20px/1.25 var(--font-display); letter-spacing: -0.01em; text-wrap: balance; }
.log-entry p { margin-top: var(--s-3); color: var(--muted); font-size: 15.5px; line-height: 1.65; }
.log-entry p em { font-style: normal; color: var(--ink); }

/* ---------------- manifest rows (reading order) ---------------- */
.manifest { margin-top: var(--s-6); border-top: var(--rule-ink); padding: 0; list-style: none; }
.manifest li { display: grid; grid-template-columns: 88px minmax(0, 1fr) minmax(0, 1.55fr); gap: var(--s-5); padding: var(--s-5) 0; border-bottom: var(--rule-hair); align-items: baseline; }
@media (max-width: 780px) { .manifest li { grid-template-columns: 60px 1fr; } .manifest li p { grid-column: 2; } }
.manifest .no { font: var(--w-medium) var(--text-label)/1.4 var(--font-mono); letter-spacing: var(--track-label); color: var(--accent); }
.manifest h3 { font: var(--w-semi) 19px/1.3 var(--font-display); letter-spacing: -0.01em; }
.manifest .m-status { display: block; margin-top: var(--s-1); font: var(--w-medium) var(--text-label)/1.4 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--faint); }
.manifest p { color: var(--muted); font-size: 15.5px; line-height: 1.65; }

/* ---------------- data strip (series facts readout) ----------------
   A full-width telemetry row: label over value, cells split by
   hairlines. No frame, no panel — it reads, it doesn't box. */
.datastrip { display: grid; grid-template-columns: repeat(3, 1fr); margin: var(--s-7) 0 0; border-block: var(--rule-ink); }
.datastrip .d { padding: var(--s-5) var(--s-5); }
.datastrip .d:not(:nth-child(3n+1)) { border-left: var(--rule-hair); }
.datastrip .d:nth-child(n+4) { border-top: var(--rule-hair); }
.datastrip .d:nth-child(3n+1) { padding-left: 0; }
@media (max-width: 780px) {
  .datastrip { grid-template-columns: 1fr 1fr; }
  .datastrip .d { padding: var(--s-4); }
  .datastrip .d:not(:nth-child(3n+1)) { border-left: none; }
  .datastrip .d:not(:nth-child(2n+1)) { border-left: var(--rule-hair); }
  .datastrip .d:nth-child(n+4) { border-top: none; }
  .datastrip .d:nth-child(n+3) { border-top: var(--rule-hair); }
  .datastrip .d:nth-child(2n+1) { padding-left: 0; }
}
.datastrip dt { font: var(--w-medium) var(--text-label)/1.5 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--faint); }
.datastrip dd { margin: var(--s-2) 0 0; font: var(--w-semi) 18px/1.35 var(--font-display); letter-spacing: -0.01em; color: var(--ink); }
.datastrip dd em { font-style: normal; color: var(--accent); }

/* ---------------- spread: heading column + body column ----------------
   A text segment fills the whole rail instead of stranding half of it:
   the heading holds the left column, the body copy the right, and each
   keeps its own comfortable measure. One column on narrow screens. */
.spread {
  display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--s-6) var(--s-9); align-items: start; margin-top: var(--s-5);
}
@media (max-width: 900px) { .spread { grid-template-columns: 1fr; gap: var(--s-5); } }
.spread h1, .spread h2 { margin-top: 0; max-width: 18ch; }
.spread .s-body > :first-child { margin-top: 0; }
.spread .intro, .spread .copy { max-width: none; }

/* ---------------- q&a ---------------- */
.qa { margin-top: var(--s-6); border-top: var(--rule-ink); }
.qa details { border-bottom: var(--rule-hair); }
.qa summary {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-4);
  padding: var(--s-4) 0; cursor: pointer; list-style: none;
  font: var(--w-semi) 18px/1.35 var(--font-display);
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; font: var(--w-medium) 18px/1 var(--font-mono); color: var(--accent); flex: 0 0 auto; }
.qa details[open] summary::after { content: "\2212"; }
.qa .a { padding: 0 0 var(--s-5); color: var(--muted); max-width: 72ch; }
.qa .a p + p { margin-top: var(--s-3); }

/* ---------------- muster (reader-list form) ---------------- */
.muster { width: min(560px, 100%); }
.muster form { display: flex; flex-wrap: wrap; gap: var(--s-3); }
input[type="email"], input[type="text"], textarea {
  min-width: 0; padding: 16px 18px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); font: var(--w-regular) 15px/1.4 var(--font-mono);
}
input::placeholder, textarea::placeholder { color: var(--faint); }
input:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
.muster form input[type="email"] { flex: 1 1 260px; }
.muster form button {
  padding: 16px 26px; border: none; cursor: pointer;
  background: var(--accent); color: var(--on-accent); font: var(--w-bold) 15px/1 var(--font-display);
  transition: background var(--dur-tick) var(--ease-out); flex: 1 0 auto;
}
.muster form button:hover { background: var(--ink); }
.muster form button:active { transform: translateY(1px); }
.muster form button:disabled { background: var(--faint); cursor: default; }
.nofill { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.smallprint { margin-top: var(--s-4); font: var(--w-regular) 13px/1.65 var(--font-mono); color: var(--muted); }
.smallprint a { color: var(--muted); }
.note { margin-top: var(--s-4); font: var(--w-medium) var(--text-data)/1.6 var(--font-mono); display: none; max-width: 46ch; }
.note.err { color: var(--err); }
.aboard { margin-top: var(--s-6); display: none; flex-direction: column; gap: var(--s-4); }
/* Phosphor marks what is live: this is the thing that just happened. */
.aboard p { font: var(--w-medium) var(--text-data)/1.6 var(--font-mono); max-width: 46ch; color: var(--accent); }
/* The hero muster is centred, so its confirmation centres with it; the
   closing-zone muster stays left, with the rest of that column. */
.hero .aboard { align-items: center; }

/* ---------------- motion: staged reveals ----------------
   Reveal candidates are hidden ONLY under html.live (added by a one-line
   inline script in each page's <head>), so the page never flashes and
   no-JS visitors always see everything. reveal.js adds .up on intersect. */
@media (prefers-reduced-motion: no-preference) {
  html.live :is(.yardlog > .log-entry, .manifest > li, .qa details, .datastrip > .d):not(.up) {
    opacity: 0; transform: translateY(12px);
  }
  html.live :is(.yardlog > .log-entry, .manifest > li, .qa details, .datastrip > .d) {
    transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
  }
}

/* ---------------- footer ---------------- */
footer {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
  gap: var(--s-4) var(--s-6); border-top: var(--rule-hair);
  padding: var(--s-6) max(var(--s-5), calc((100% - 1240px) / 2));
  font: var(--w-regular) 12px/1.5 var(--font-mono); color: var(--faint);
}
footer .f-brand { text-transform: uppercase; letter-spacing: var(--track-label); }
footer nav { display: flex; flex-wrap: wrap; gap: var(--s-5); }
footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--accent); }

/* legal pages */
.papers { max-width: 720px; margin: 0 auto; padding: var(--s-8) var(--s-5) var(--s-9); }
.papers h1 { font: var(--w-semi) 34px/1.1 var(--font-display); letter-spacing: var(--track-tight); margin: var(--s-4) 0 var(--s-2); }
.papers .sub { color: var(--muted); font-size: var(--text-small); }
.papers h2 { font: var(--w-semi) 20px/1.25 var(--font-display); margin: var(--s-7) 0 var(--s-3); padding-top: var(--s-4); border-top: var(--rule-hair); }
.papers h3 { font: var(--w-semi) 17px/1.3 var(--font-display); margin: var(--s-5) 0 var(--s-2); }
.papers p, .papers li { color: var(--muted); margin-bottom: var(--s-3); }
.papers ul { padding-left: 22px; margin-bottom: var(--s-4); }
.papers code { font: var(--w-medium) 14px/1 var(--font-mono); color: var(--ink); }
.papers .back { display: inline-block; margin-top: var(--s-7); font: var(--w-medium) var(--text-label)/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label); }
