/* ==========================================================================
   Hegemann Schorsch — site layer on top of the terminal design system.

   terminal.css carries the tokens, the base and the two keyframes; this file
   carries the layouts and the motion. Three conventions run through it:

   1. Structural lines are characters, not borders. A rule is one long run of
      ═ or ─ clipped by its container, which is why it never wraps and never
      needs to know how wide it is. The runs live here as generated content so
      the markup stays readable and 200 glyphs stay out of the accessibility
      tree. Short straight lines that carry no character of their own (row
      separators, the tree's continuation line, the stat dividers) are ordinary
      1px borders.
   2. --dim is chrome only. It is 3.2:1 on black and fails text contrast, so
      it draws rules, tree glyphs, permission strings and the shell-prompt
      ornament — all of which are aria-hidden — and never carries prose.
      Everything a reader actually needs sits on --mid or above.
   3. Motion is additive. Nothing here hides content on its own: the hidden
      start states are scoped to html.js / html.boot, which only the script
      sets, so without JavaScript — or with reduced motion — every page is
      simply there. See site.js for the choreography.
   ========================================================================== */

/* ── utilities ───────────────────────────────────────────────────────────── */

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: 10px 16px; background: var(--acc); color: #000;
  font-size: var(--fs-chrome); letter-spacing: .06em;
}
.skip-link:focus { left: 0; }

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

/* Every link in this design is bracketed and there are no buttons. The
   brackets are a property of the link style, not of the copy, so they live
   here; being inside the <a> box they invert with it on hover. Links that
   leave the site open a new tab and say so with an arrow inside the bracket. */
.lnk::before { content: "[ "; }
.lnk::after  { content: " ]"; }
.lnk.ext::after { content: " ↗ ]"; }

/* ── the character rules ─────────────────────────────────────────────────── */

.rule, .rule-fill {
  color: var(--dim);
  overflow: hidden;
  white-space: nowrap;
  font-size: var(--fs-chrome);
  /* Box-drawing glyphs only join into a continuous line at zero tracking, and
     these runs sit inside header rows that set .06em. */
  letter-spacing: 0;
}
.rule-fill { flex: 1; }
.rule::before      { content: "════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════"; }
.rule-fill::before { content: "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"; }

/* The shell prompt: ornament, dim and aria-hidden. `hs` takes the accent. The
   command after the prompt is real text; the script retypes it on reveal. */
.ps1 { color: var(--dim); }
.ps1-user { color: var(--acc); }
.prompt {
  display: flex; align-items: center; gap: 8px;
  font-size: var(--fs-chrome); color: var(--dim); margin: 0 0 18px;
  min-height: 1.85em;
}
.prompt .cmd { color: var(--mid); white-space: pre; }
.prompt .cmd-cur { display: none; width: 7px; height: 13px; }
.prompt .cmd.typing + .cmd-cur { display: inline-block; animation: none; }

/* ── shell ───────────────────────────────────────────────────────────────── */

.shell {
  max-width: var(--shell-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  align-items: start;
}

/* ── sidebar ─────────────────────────────────────────────────────────────── */

.sidebar {
  position: sticky; top: 0; align-self: start; height: 100vh;
  border-right: 1px solid var(--dim);
  padding: 34px 24px 28px 40px;
  display: flex; flex-direction: column; gap: 24px;
  font-size: var(--fs-chrome);
}
.sidebar-spacer { flex: 1; }

.brand {
  display: flex; align-items: center; gap: 13px;
  margin: 0; font-size: inherit; font-weight: 400;
}
.brand-mark {
  display: flex; flex-direction: column; gap: 5px;
  width: 24px; flex: none;
}
.brand-mark span { height: 2px; background: var(--txt); transform-origin: left center; }
.brand-mark span + span { width: 62%; background: var(--acc); }
.brand-word {
  font-size: 11.5px; letter-spacing: .16em; color: var(--acc);
  text-transform: uppercase; white-space: nowrap;
}

/* file tree — the page navigation */
.tree { display: flex; flex-direction: column; gap: 1px; line-height: var(--lh-tree); }
.tree-head {
  font-size: var(--fs-meta); letter-spacing: .04em; color: var(--dim);
  margin: 0 0 6px;
}
.tree a { display: flex; align-items: baseline; gap: 8px; }
.tree-glyph { color: var(--dim); flex: none; white-space: pre; letter-spacing: 0; }
.tree-idx { font-size: var(--fs-meta); color: var(--acc); align-self: center; flex: none; }
.tree-name { color: var(--txt); }
.tree-sub { font-size: var(--fs-meta); line-height: 1.9; }
.tree-sub .tree-name { color: var(--mid); }
/* The row inverts as one block on hover, so the parts stop colouring
   themselves and inherit the inverted ink instead. */
.tree a:hover .tree-glyph, .tree a:hover .tree-idx, .tree a:hover .tree-name,
.tree a:focus-visible .tree-glyph, .tree a:focus-visible .tree-idx,
.tree a:focus-visible .tree-name { color: inherit; }
/* scrollspy: the section on screen takes the accent, like a highlighted file */
.tree a[aria-current="true"] .tree-name { color: var(--acc); }
.tree a[aria-current="true"] .tree-glyph { color: var(--mid); }

/* // ENV */
.env {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-meta); line-height: 1.85;
}
.env-head { letter-spacing: .14em; color: var(--mid); margin: 0; }
.env-row { display: flex; justify-content: space-between; gap: 10px; margin: 0; }
.env-key { color: var(--mid); flex: none; }
.env-val { color: var(--txt); }
.env-val .is-current { color: var(--acc); }
.env-val .sep { color: var(--dim); }

/* status block */
.status { display: flex; flex-direction: column; gap: 10px; font-size: var(--fs-meta); }
.status-row { display: flex; align-items: center; gap: 8px; margin: 0; }
.status-key { color: var(--mid); letter-spacing: .1em; }
.status-val { color: var(--acc); }
.status-links { margin: 0; display: flex; flex-wrap: wrap; gap: 6px 12px; }
.status-legal { margin: 0; color: var(--dim); }
.status-legal a { color: var(--mid); }
.status-legal a:hover, .status-legal a:focus-visible { color: #000; }

/* ── the sidebar shell ───────────────────────────────────────────────────────
   The prompt at the bottom of the sidebar is a real one. Without JavaScript
   it is an inert line of ornament; with it, site.js wires the input to a
   handful of commands that walk the page. Output stacks above the prompt the
   way a terminal scrolls, capped so it never pushes the sidebar out of view.
   ───────────────────────────────────────────────────────────────────────── */
.term { margin-top: 4px; }
.term-out { margin: 0 0 4px; display: flex; flex-direction: column; gap: 1px; max-height: 15em; overflow: hidden; justify-content: flex-end; }
.term-out:empty { display: none; }
.term-line {
  margin: 0; font-size: var(--fs-meta); line-height: 1.6;
  color: var(--txt); white-space: pre-wrap; word-break: break-word;
}
.term-line.is-cmd { color: var(--mid); }
.term-line.is-cmd::before { content: "$ "; color: var(--dim); }
.term-line.is-err { color: var(--acc); }
.term-line.is-dim { color: var(--mid); }
.term-form { display: flex; align-items: center; gap: 8px; margin: 0; font-size: var(--fs-chrome); }
.term-in {
  flex: 0 1 auto; min-width: 1ch; max-width: 100%;
  margin: 0; padding: 0; border: 0; background: none; outline: none;
  color: var(--acc); font: inherit; letter-spacing: inherit;
  caret-color: transparent;
}
.term-in::placeholder { color: transparent; }
.term-hint { margin: 4px 0 0; font-size: var(--fs-meta); color: var(--mid); }
.term-hint .sep { color: var(--dim); }
.term:focus-within .term-hint { visibility: hidden; }
/* Without the script the input has no behaviour to offer, so it stays a
   prompt and a cursor. */
html:not(.js) .term-in, html:not(.js) .term-hint { display: none; }

/* ── main column ─────────────────────────────────────────────────────────── */

.main { min-width: 0; padding: 34px 40px 80px; }
.main > .rule { margin-bottom: 32px; }

.sec { margin-bottom: var(--section-gap); scroll-margin-top: 20px; }
.sec:last-of-type { margin-bottom: 0; }

/* ┌─ 02 · PROJEKTE/ ──────────────… */
.sec-head {
  display: flex; align-items: baseline; gap: 0;
  font-size: var(--fs-chrome); font-weight: 400; letter-spacing: .06em;
  margin: 0 0 22px;
}
.sec-corner, .sec-sep { color: var(--dim); white-space: pre; letter-spacing: 0; }
.sec-idx { color: var(--acc); }
.sec-label { color: var(--acc); text-transform: uppercase; white-space: nowrap; }
.sec-foot { display: flex; margin-top: 26px; }
.sec-foot .corner { color: var(--dim); letter-spacing: 0; }

.sec-body { padding-left: var(--box-indent); }

/* the row of controls that some section heads carry, e.g. expand/collapse */
.sec-tools {
  display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline;
  margin: 0 0 18px; font-size: var(--fs-meta);
}
.sec-tools .lnk { color: var(--mid); }
.sec-tools .lnk:hover, .sec-tools .lnk:focus-visible { color: #000; }

/* ── 01 intro ────────────────────────────────────────────────────────────── */

.intro-lead {
  margin: 0; max-width: 88ch;
  font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--acc);
}
.intro-lead + .intro-lead { margin-top: 14px; color: var(--txt); }

/* A fetch block — the mark in block characters next to a column of facts,
   the way a terminal introduces a machine. Facts only; nothing decorative
   carries information. */
.fetch {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 34px;
  align-items: start; margin: 30px 0 0; max-width: 88ch;
}
/* the mark, at fetch size: the same two bars as the brand mark */
.fetch-art { display: flex; flex-direction: column; gap: 10px; width: 96px; padding-top: 7px; }
.fetch-art span { display: block; height: 7px; background: var(--txt); }
.fetch-art span + span { width: 62%; background: var(--acc); }
.fetch-rows {
  margin: 0; display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: 3px 18px; font-size: var(--fs-chrome); line-height: 1.7;
}
.fetch-rows dt { color: var(--mid); letter-spacing: .08em; text-transform: uppercase; font-size: var(--fs-meta); align-self: baseline; }
.fetch-rows dd { margin: 0; color: var(--txt); }
.fetch-rows dd .n { color: var(--acc); }

/* ── 02 projekte: a directory of folders ─────────────────────────────────────
   Each project is a <details>: closed it is one line of the tree, open it is
   the folder's contents. Native disclosure does the work — keyboard, screen
   readers and no-JS all get the real thing — and the script only adds the
   height animation and a way to open a folder by URL hash.
   ───────────────────────────────────────────────────────────────────────── */

.dir { display: flex; flex-direction: column; }

.folder { margin: 0; }
.folder > summary {
  list-style: none; cursor: pointer;
  display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto auto;
  gap: 0 14px; align-items: baseline;
  padding: 9px 6px 9px 0; margin: 0 0 0 -6px;
  font-size: var(--fs-chrome);
}
.folder > summary::-webkit-details-marker { display: none; }
.folder > summary::marker { content: ""; }
.folder-glyph { color: var(--dim); white-space: pre; letter-spacing: 0; padding-left: 6px; }
.folder-name { color: var(--acc); font-size: var(--fs-title); font-weight: 500; white-space: nowrap; }
.folder-tag { color: var(--txt); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.folder-state {
  color: var(--mid); font-size: var(--fs-meta); letter-spacing: .1em;
  text-transform: uppercase; white-space: nowrap;
}
.folder-toggle { color: var(--mid); font-size: var(--fs-meta); white-space: nowrap; }
.folder-toggle::before { content: "[ " attr(data-open) " ]"; }
.folder[open] > summary .folder-toggle::before { content: "[ " attr(data-close) " ]"; }
/* the whole line inverts, exactly like a tree row */
.folder > summary:hover, .folder > summary:focus-visible { background: var(--acc); color: #000; outline: none; }
.folder > summary:hover > *, .folder > summary:focus-visible > * { color: inherit; }
.folder > summary:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

/* the folder's contents hang off the tree's continuation line */
.folder-body { overflow: hidden; }
.folder-inner {
  margin: 0 0 0 6px; padding: 14px 0 30px 28px;
  border-left: 1px solid var(--dim);
}
.folder.last .folder-inner { border-left-color: transparent; }

.proj {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 20px 44px; align-items: start;
}
.proj-text { min-width: 0; }
.proj-media { min-width: 0; }

/* file headings inside a folder: `README.md`, `arbeitsweise.md` */
.file-head {
  margin: 0 0 12px; font-size: var(--fs-meta); letter-spacing: .06em;
  color: var(--mid); display: flex; align-items: baseline; gap: 0;
}
.file-head .fh-glyph { color: var(--dim); white-space: pre; letter-spacing: 0; }
.file-head .fh-name { color: var(--mid); }
.file-head .rule-fill { margin-left: 8px; }
.proj-text .file-head + .file-head, .file-head.later { margin-top: 26px; }

.proj-title {
  margin: 0 0 4px; font-weight: 400; font-size: var(--fs-display);
  letter-spacing: .04em; color: var(--acc); line-height: var(--lh-heading);
}
.proj-claim {
  margin: 0 0 16px; font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--acc);
}
.proj-text > p { max-width: 68ch; margin: 0 0 14px; }
.proj-note { color: var(--mid); }
.proj-quote {
  margin: 18px 0 16px; padding: 2px 0 2px 16px; border-left: 1px solid var(--acc);
  max-width: 64ch; color: var(--acc); font-size: var(--fs-lead); line-height: var(--lh-lead);
}
.proj-quote cite { display: block; margin-top: 6px; font-style: normal; font-size: var(--fs-meta); color: var(--mid); }
.proj-links { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 18px 0 0; font-size: var(--fs-chrome); }

/* key/value facts — STATUS · STACK · DATEN … */
.kv {
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: 4px 18px; margin: 16px 0 0; font-size: var(--fs-chrome); line-height: 1.7; max-width: 72ch;
}
.kv dt { color: var(--mid); font-size: var(--fs-meta); letter-spacing: .1em; text-transform: uppercase; align-self: baseline; }
.kv dd { margin: 0; color: var(--txt); }
.kv dd .n { color: var(--acc); }

/* the screenshot, framed in characters rather than in a border */
.shot { margin: 0; min-width: 0; }
.shot-line {
  display: flex; align-items: baseline;
  font-size: var(--fs-meta); color: var(--dim);
  white-space: nowrap; overflow: hidden;
}
.shot-line .label { white-space: pre; }
.shot img {
  display: block; width: 100%;
  height: auto; aspect-ratio: 16 / 10; object-fit: cover;
  border-left: 1px solid var(--dim); border-right: 1px solid var(--dim);
}
.shot figcaption { margin: 6px 0 0; font-size: var(--fs-meta); color: var(--mid); }

/* A capture: a terminal session drawn in the page's own type, for the
   projects that have no window to photograph. Real text, so it reads and it
   indexes, and each line arrives in order when its folder opens. */
.cap {
  margin: 0; font-size: 11.5px; line-height: 1.75; color: var(--txt);
  border-left: 1px solid var(--dim); border-right: 1px solid var(--dim);
  padding: 14px 16px; aspect-ratio: 16 / 10; overflow: hidden;
  letter-spacing: 0;
}
.cap .c-acc { color: var(--acc); }
.cap .c-mid { color: var(--mid); }
.cap .c-dim { color: var(--dim); }
.cap-line { display: block; white-space: pre; overflow: hidden; }
.cap .cursor { width: 6px; height: 12px; vertical-align: -1px; }

/* separators between facts are ornament */
.sep { color: var(--dim); }

.stats {
  display: flex; flex-wrap: wrap; align-items: baseline;
  list-style: none; margin: 22px 0 0; padding: 0;
  font-size: var(--fs-chrome); color: var(--mid);
}
.stats li { display: flex; align-items: baseline; gap: 8px; padding: 0 12px; }
.stats li:first-child { padding-left: 0; }
.stats li + li { border-left: 1px solid var(--dim); }
.stat-num { font-size: var(--fs-stat); color: var(--acc); }
.stats-note { margin: 6px 0 0; font-size: var(--fs-meta); color: var(--mid); }

/* arbeitsweise.md inside the Bundestakt folder */
.work {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: 22px 30px; max-width: 72ch;
}
.work-label {
  font-size: var(--fs-chrome); letter-spacing: .1em; color: var(--acc);
  margin: 0 0 8px;
}
.work p { margin: 0; }

/* ── rows: insights and lists share one grammar ──────────────────────────── */

.row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 24px; align-items: baseline;
  padding: 16px 0; border-bottom: 1px solid var(--row-border);
}
.rows > .row:first-child, .sec-body > .row:first-child { padding-top: 0; }

.row-meta {
  margin: 0; font-size: var(--fs-meta); color: var(--mid); white-space: nowrap;
}
.row-meta .perm, .row-meta .read, .row-meta .lang, .row-meta .date { display: block; }
.row-meta .perm { color: var(--dim); }
.row-meta .read, .row-meta .lang { text-transform: uppercase; }

.row-main { min-width: 0; }
.row-title {
  margin: 0 0 6px;
  font-weight: 500; font-size: var(--fs-title); line-height: var(--lh-heading);
  color: var(--acc);
}
.row-title a { color: inherit; }
.row-main p { margin: 0; max-width: 76ch; }
.row-act { margin: 0; font-size: var(--fs-chrome); white-space: nowrap; }
.row-act .empty { color: var(--dim); }

.more { margin: 22px 0 0; font-size: var(--fs-chrome); }

/* ── 04 team: two files, one per person ──────────────────────────────────── */

.team {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
  gap: 34px 44px; align-items: start;
}
.card { min-width: 0; }
.card-name {
  margin: 0 0 2px; font-weight: 400; font-size: var(--fs-display);
  letter-spacing: .04em; color: var(--acc); line-height: var(--lh-heading);
}
.card-role { margin: 0 0 14px; font-size: var(--fs-chrome); color: var(--mid); letter-spacing: .04em; }
.card-bio { margin: 16px 0 0; max-width: 60ch; }
.card-bio p { margin: 0 0 12px; }
.card .proj-links { margin-top: 14px; }

.closing {
  margin: 34px 0 0; max-width: 76ch; color: var(--mid);
}
.closing .hash { color: var(--dim); }

/* ── page footer ─────────────────────────────────────────────────────────── */

.foot {
  display: flex; align-items: center; gap: 10px 18px; flex-wrap: wrap;
  margin-top: 40px; font-size: var(--fs-chrome); color: var(--dim);
}
.foot .cursor { width: 8px; height: 14px; }
.foot-spacer { flex: 1; }
.foot-copy { color: var(--mid); }
.foot .lnk { color: var(--mid); }
.foot .lnk:hover, .foot .lnk:focus-visible { color: #000; }

/* ══ motion ══════════════════════════════════════════════════════════════════
   Two moments. The boot: on a first visit in a session the home page assembles
   itself — the mark draws, the tree lists, the rule sweeps, the prompt types
   its command and the intro arrives. Under two seconds, once, and any key or
   click ends it. The reveal: every section below the fold fades up as it is
   scrolled to, and its prompt types. Both are gated on html.js / html.boot,
   which only the script sets, and both are switched off by reduced motion.
   ═════════════════════════════════════════════════════════════════════════ */

@keyframes fade-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes draw-x  { from { transform: scaleX(0); } to { transform: none; } }
@keyframes wipe    { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes scan    { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0); } }

/* the boot */
html.boot .brand-mark span { animation: draw-x .45s cubic-bezier(.2,.7,.2,1) both; }
html.boot .brand-mark span + span { animation-delay: .12s; }
html.boot .brand-word { animation: fade .4s .25s both; }
html.boot .tree > * { animation: fade-up .35s both; }
html.boot .tree > :nth-child(1)  { animation-delay: .30s; }
html.boot .tree > :nth-child(2)  { animation-delay: .34s; }
html.boot .tree > :nth-child(3)  { animation-delay: .38s; }
html.boot .tree > :nth-child(4)  { animation-delay: .42s; }
html.boot .tree > :nth-child(5)  { animation-delay: .46s; }
html.boot .tree > :nth-child(6)  { animation-delay: .50s; }
html.boot .tree > :nth-child(7)  { animation-delay: .54s; }
html.boot .tree > :nth-child(8)  { animation-delay: .58s; }
html.boot .tree > :nth-child(9)  { animation-delay: .62s; }
html.boot .tree > :nth-child(10) { animation-delay: .66s; }
html.boot .tree > :nth-child(n+11) { animation-delay: .70s; }
html.boot .env    { animation: fade-up .4s .75s both; }
html.boot .status { animation: fade-up .4s .85s both; }
html.boot .main > .rule { animation: wipe .7s .2s cubic-bezier(.2,.7,.2,1) both; }
html.boot #p-intro .prompt { animation: fade .3s .55s both; }
html.boot #p-intro .intro-lead { animation: fade-up .55s 1.05s cubic-bezier(.2,.7,.2,1) both; }
html.boot #p-intro .intro-lead + .intro-lead { animation-delay: 1.2s; }
html.boot #p-intro .fetch { animation: fade-up .55s 1.4s cubic-bezier(.2,.7,.2,1) both; }
/* everything after the intro waits for the reveal, which the script starts
   once the boot has landed */
html.boot .reveal { opacity: 0; }

/* the reveal */
html.js .reveal {
  opacity: 0; transform: translateY(12px);
  transition: opacity .55s ease, transform .55s cubic-bezier(.2,.7,.2,1);
}
html.js .reveal.in { opacity: 1; transform: none; }
html.js .reveal .sec-head .rule-fill { clip-path: inset(0 100% 0 0); }
html.js .reveal.in .sec-head .rule-fill { animation: wipe .8s .15s cubic-bezier(.2,.7,.2,1) both; }

/* a folder opening: the screenshot scans in, a capture prints line by line */
.folder[open] .shot img { animation: scan .6s cubic-bezier(.2,.7,.2,1) both; }
.folder[open] .cap-line { animation: fade .25s both; }
.folder[open] .cap-line:nth-child(1)  { animation-delay: .10s; }
.folder[open] .cap-line:nth-child(2)  { animation-delay: .22s; }
.folder[open] .cap-line:nth-child(3)  { animation-delay: .30s; }
.folder[open] .cap-line:nth-child(4)  { animation-delay: .40s; }
.folder[open] .cap-line:nth-child(5)  { animation-delay: .50s; }
.folder[open] .cap-line:nth-child(6)  { animation-delay: .60s; }
.folder[open] .cap-line:nth-child(7)  { animation-delay: .70s; }
.folder[open] .cap-line:nth-child(8)  { animation-delay: .80s; }
.folder[open] .cap-line:nth-child(9)  { animation-delay: .90s; }
.folder[open] .cap-line:nth-child(10) { animation-delay: 1.0s; }
.folder[open] .cap-line:nth-child(11) { animation-delay: 1.1s; }
.folder[open] .cap-line:nth-child(n+12) { animation-delay: 1.2s; }

/* the `matrix` easter egg draws on this */
.mx {
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  z-index: 60; pointer-events: none; transition: opacity .5s ease;
}

@media (prefers-reduced-motion: reduce) {
  html.js .reveal { opacity: 1; transform: none; transition: none; }
  html.js .reveal .sec-head .rule-fill, html.js .reveal.in .sec-head .rule-fill { clip-path: none; animation: none; }
  .folder[open] .shot img, .folder[open] .cap-line { animation: none; }
  html.boot * { animation: none !important; }
  .mx { display: none; }
}

/* ══ subpages ════════════════════════════════════════════════════════════════
   Subpages carry no sidebar — it is the home page's navigation, and repeating
   it around a legal text would be chrome for chrome's sake. They get a top bar
   instead, and their column is 860px wide so that on a 1440px screen the text
   starts within a few pixels of where the home page's main column starts.
   ═════════════════════════════════════════════════════════════════════════ */

:root { --page-max: 860px; }

.page { max-width: var(--page-max); margin: 0 auto; padding: 30px 40px 60px; }

/* ── top bar ─────────────────────────────────────────────────────────────── */

.topbar {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  font-size: var(--fs-chrome); margin-bottom: 10px;
}
.topbar-brand { display: flex; align-items: center; gap: 13px; }
.topbar-brand .brand-word { font-size: 11.5px; }
.topbar-brand:hover .brand-mark span,
.topbar-brand:focus-visible .brand-mark span { background: #000; }
.topbar-brand:hover .brand-word,
.topbar-brand:focus-visible .brand-word { color: inherit; }
.topbar-nav { display: flex; gap: 16px; flex-wrap: wrap; }
.topbar-spacer { flex: 1; }
.lang-switch {
  display: flex; align-items: baseline; gap: 8px;
  margin: 0; font-size: var(--fs-meta); color: var(--dim);
}
.lang-switch .is-current { color: var(--acc); }

/* ── page furniture ──────────────────────────────────────────────────────── */

.page-title {
  margin: 0 0 14px; font-size: 20px; line-height: 1.45;
  font-weight: 500; letter-spacing: .02em; color: var(--acc);
}
.page-lead { margin: 0 0 30px; max-width: 76ch; color: var(--mid); }
.text-muted { color: var(--mid); }

.pagefoot { margin-top: 52px; }
.pagefoot .foot { margin-top: 14px; }
.pagefoot .foot a { color: var(--mid); }
.pagefoot .foot a:hover, .pagefoot .foot a:focus-visible { color: #000; }

.back { display: inline-block; font-size: var(--fs-chrome); margin-bottom: 26px; }

/* the insights index groups its posts in topic folders; a folder there is
   the same <details> as a project folder, with rows inside */
.page .folder-inner { padding-bottom: 12px; }
.page .folder-count { color: var(--mid); font-size: var(--fs-meta); white-space: nowrap; }

/* ── article ─────────────────────────────────────────────────────────────── */

.article-meta {
  margin: 0 0 12px; font-size: var(--fs-chrome); color: var(--mid);
}
.article-meta .hash { color: var(--dim); }
.article h1 {
  margin: 0 0 18px; font-size: 20px; line-height: 1.45;
  font-weight: 500; letter-spacing: .02em; color: var(--acc);
  max-width: 60ch;
}
.article-standfirst {
  margin: 0 0 18px; max-width: 72ch;
  font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--acc);
}
.article-byline {
  margin: 0 0 32px; padding-bottom: 22px;
  font-size: var(--fs-chrome); color: var(--mid);
  border-bottom: 1px solid var(--row-border);
}

.article-body { font-size: var(--fs-lead); line-height: var(--lh-body); }
.article-body > p, .article-body > ul, .article-body > ol { max-width: 72ch; }
.article-body p { margin: 0 0 18px; }
.article-body h2 {
  margin: 38px 0 14px; font-size: var(--fs-name); line-height: var(--lh-heading);
  font-weight: 500; letter-spacing: .04em; color: var(--acc);
}
.article-body h3 {
  margin: 28px 0 10px; font-size: var(--fs-lead); line-height: var(--lh-heading);
  font-weight: 500; color: var(--acc);
}
.article-body ul, .article-body ol { margin: 0 0 18px; padding-left: 20px; }
.article-body li { margin-bottom: 8px; }
.article-body li::marker { color: var(--dim); }
.article-body strong { font-weight: 500; color: var(--acc); }
.article-body em { font-style: normal; color: var(--acc); }
.article-body a { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--dim); }
.article-body a:hover, .article-body a:focus-visible { text-decoration: none; }

.article-foot {
  margin-top: 40px; padding-top: 22px;
  border-top: 1px solid var(--row-border); color: var(--mid);
}

.link-row { display: flex; flex-wrap: wrap; gap: 18px; margin: 26px 0 0; }

code {
  font-size: 12.5px; padding: 0 5px;
  border: 1px solid var(--dim); color: var(--acc);
}

.callout {
  margin: 30px 0; padding: 2px 0 2px 20px;
  border-left: 1px solid var(--acc); max-width: 72ch;
}
.callout p { margin: 0; }
.callout p + p { margin-top: 10px; }
.callout-quote p:first-child {
  font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--acc);
}

.table-wrap { overflow-x: auto; margin: 26px 0; }
.table { width: 100%; min-width: 520px; border-collapse: collapse; font-size: var(--fs-body); }
.table th {
  text-align: left; font-weight: 500; color: var(--acc);
  padding: 0 18px 10px 0; border-bottom: 1px solid var(--dim);
}
.table td {
  vertical-align: top; color: var(--txt);
  padding: 12px 18px 12px 0; border-bottom: 1px solid var(--row-border);
}
.table tr > *:last-child { padding-right: 0; }

/* sources at the end of an article */
.sources { font-size: var(--fs-body); color: var(--mid); }
.sources li { margin-bottom: 8px; }

/* ── legal pages ─────────────────────────────────────────────────────────── */

.legal { max-width: 76ch; }
.legal h1 {
  margin: 0 0 26px; font-size: 20px; line-height: 1.45;
  font-weight: 500; letter-spacing: .02em; color: var(--acc);
}
.legal h2 {
  margin: 34px 0 12px; font-size: var(--fs-title); line-height: var(--lh-heading);
  font-weight: 500; letter-spacing: .04em; color: var(--acc);
  scroll-margin-top: 24px;
}
.legal h3 {
  margin: 24px 0 8px; font-size: var(--fs-body); line-height: var(--lh-heading);
  font-weight: 500; color: var(--acc);
}
.legal p, .legal li { margin: 0 0 14px; }
.legal ul { margin: 0 0 16px; padding-left: 20px; }
.legal li::marker { color: var(--dim); }
.legal strong { font-weight: 500; color: var(--acc); }
.legal address { font-style: normal; margin: 0 0 14px; color: var(--txt); }

/* ── 404 ─────────────────────────────────────────────────────────────────── */

.notfound { max-width: 72ch; padding: 20px 0 40px; }
.notfound .prompt { margin-bottom: 4px; }
.shell-out { margin: 0; font-size: var(--fs-chrome); color: var(--txt); }
.shell-out + .prompt { margin-top: 16px; }
.notfound h1 {
  margin: 30px 0 16px; font-size: var(--fs-display); line-height: 1.4;
  font-weight: 500; letter-spacing: .02em; color: var(--acc);
}
.notfound p { margin: 0 0 18px; }

/* ── responsive ──────────────────────────────────────────────────────────────
   The design is drawn for the desktop shell. Below 1100px a project's text
   and its picture stack; below 860px the sidebar stops being a column and
   becomes the page's top block. The character rules need no attention at any
   width, because they clip instead of wrapping.
   ───────────────────────────────────────────────────────────────────────── */

@media (max-width: 1100px) {
  .proj { grid-template-columns: minmax(0, 1fr); }
  .proj-media { max-width: 640px; }
}

@media (max-width: 860px) {
  .shell { grid-template-columns: minmax(0, 1fr); }

  .sidebar {
    position: static; height: auto;
    border-right: 0; border-bottom: 1px solid var(--dim);
    padding: 22px 20px 20px;
    gap: 18px;
  }
  .sidebar-spacer { display: none; }

  .tree { flex-direction: row; flex-wrap: wrap; gap: 4px 18px; line-height: 1.7; }
  .tree-head, .tree-glyph, .tree a.tree-sub { display: none; }

  .env { gap: 0; }
  .env-head, .env-row { display: none; }
  .env-row.env-lang { display: flex; justify-content: flex-start; gap: 14px; }

  .status { gap: 8px; }
  /* the shell is a desktop toy; the phone gets the prompt as ornament */
  .term { display: none; }

  .main { padding: 24px 20px 60px; }
  .main > .rule { margin-bottom: 24px; }
  .sec { margin-bottom: 40px; }
  .sec-body { padding-left: 0; }

  .fetch { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .fetch-art { display: none; }

  /* name and state on one line, the tag beneath; no glyph, no toggle */
  .folder > summary { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 12px 0; margin: 0; }
  .folder-glyph, .folder-toggle { display: none; }
  .folder-state { justify-self: end; }
  .folder-tag { grid-column: 1 / -1; white-space: normal; }
  .folder-inner { margin-left: 0; padding: 12px 0 22px 0; border-left: 0; }
  .proj { gap: 18px; }
  .kv { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .kv dt { margin-top: 8px; }

  .row { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 18px 0; }
  .row-meta { white-space: normal; }
  .row-meta .perm { display: none; }
  .row-meta .read, .row-meta .lang, .row-meta .date { display: inline; margin-right: 12px; }
  .row-act { white-space: normal; }

  .page { padding: 20px 20px 48px; }
  .topbar { gap: 12px 16px; }
  .topbar-spacer { display: none; }
  .lang-switch { flex-basis: 100%; }
  .table { min-width: 420px; }
}

@media (max-width: 480px) {
  .stats { flex-direction: column; gap: 14px; }
  .stats li { padding: 0; }
  .stats li + li { border-left: 0; }
  .cap { font-size: 10px; aspect-ratio: auto; min-height: 200px; }
}

@media print {
  .sidebar, .skip-link, .rule, .rule-fill, .sec-foot, .prompt, .cursor,
  .topbar, .pagefoot, .back, .folder-toggle, .sec-tools, .term { display: none; }
  .shell { display: block; }
  .main, .page { padding: 0; max-width: none; }
  .folder-body { display: block !important; }
  html.js .reveal { opacity: 1; transform: none; }
}
