/* ================================================================
   unreason3d.com — shared stylesheet

   PALETTE AND TYPE ARE THE APP'S OWN, deliberately. --bg, --ink,
   --ink-faint, --accent and --panel-edge are lifted verbatim from
   unreason3d.html's :root so the site and the tool read as one hand's
   work rather than a marketing skin over a different object. The one
   place they diverge is body copy: the app is mono throughout because
   every string in it is a command, a number or a label. This site has
   pages meant to be read end to end, and 900 words of monospace is a
   punishment. So mono stays for chrome, labels, command names and
   figures — the things that ARE app-shaped — and prose gets a serif.
   ================================================================ */

:root {
  --bg: #0a0d10;
  --panel: rgba(15, 19, 24, 0.92);
  --panel-edge: rgba(255, 255, 255, 0.08);
  --ink: #dbe4e8;
  --ink-faint: #9aa8b0;
  --accent: #5b8fd9;
  --accent-dim: rgba(91, 143, 217, 0.25);
  --warn: #f6d158;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --prose: "Iowan Old Style", "Palatino Linotype", Palatino, Charter, Georgia, serif;
  --measure: 34rem;

  /* THE MONO SCALE. Chrome, labels and captions are all set in the app's
     monospace, and left to themselves they drift into a dozen sizes a pixel
     apart, which is a scale nobody chose. There are three, and the only reason
     to add a fourth is a job none of these does.
       --label    running chrome and section labels
       --label-sm captions and inline flags, small enough to sit beside prose
       --label-lg the one loud mono thing on a page, the launch control
     Caps need tracking to hold apart and smaller caps need more of it, so the
     two tracking values are tied to the two label sizes, not chosen per rule. */
  --label: 0.78rem;
  --label-sm: 0.68rem;
  --label-lg: 0.88rem;
  --track: 0.12em;
  --track-sm: 0.16em;
}

@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/syne-700.woff2') format('woff2');
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--prose);
  font-size: 1.0625rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- */
/* CHROME                                                           */
/* ---------------------------------------------------------------- */

.skip {
  position: absolute; left: -9999px;
  background: var(--accent); color: #06090c;
  padding: 0.5rem 0.9rem; font-family: var(--mono); font-size: var(--label);
}
.skip:focus { left: 0.5rem; top: 0.5rem; z-index: 100; }

.siteHead {
  border-bottom: 1px solid var(--panel-edge);
  padding: 1rem 1.5rem;
  display: flex; flex-wrap: wrap; gap: 1rem 2rem;
  align-items: baseline; justify-content: space-between;
}

.wordmark {
  font-family: 'Syne', var(--mono);
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
}
.wordmark:hover { color: var(--accent); }

/* THE MARK. Two U extrusions joined by U-shaped excursions as one continuous
   wire, gold band at the crossing; frame 0 of the turntable render.

   The source clip carries no usable alpha. It was rendered against a
   transparent background, but the H.264 encode is yuv420p and flattened it
   onto pure black. These PNGs carry an alpha channel recovered from
   luminance: exact where the render is bright, soft where it is dark. On a
   light ground that reads as a slightly translucent facet on the gold band;
   on this near-black page it does not show at all. A true alpha re-export
   replaces the files with no markup change. */
.logoMark {
  display: inline-block; width: 1.7rem; height: 1.7rem;
  margin-right: 0.5rem; vertical-align: -0.42rem;
}

/* The turntable is composited with `screen` rather than keyed. The clip
   sits on pure black and this page's ground is #0a0d10, so screening it
   is mathematically almost exact and — unlike a luminance key — cannot
   fringe or erode the dark side of the form. */
.turntable {
  display: block; width: min(22rem, 70vw); height: auto;
  margin: 0 auto; mix-blend-mode: screen;
}
.siteNav { font-family: var(--mono); font-size: var(--label); letter-spacing: 0.02em; }
.siteNav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 1.1rem; }
.siteNav a { color: var(--ink-faint); text-decoration: none; }
.siteNav a:hover { color: var(--accent); }
.siteNav a[aria-current="page"] { color: var(--ink); border-bottom: 1px solid var(--accent); }

/* THE WAY BACK TO renato.design, as its own emblem rather than as the word.

   Sized by its ink, not by its box. The emblem's viewBox carries about 16%
   padding top and bottom, so the letterforms are 68% of the box height and a
   box set to the nav's 1em renders visibly smaller than the link beside it.
   1.5em of box lands the ink at roughly 1em. The mark is 5.59:1, so the width
   follows from the aspect and is not asserted.

   It is another site's mark. It keeps its own two fills and is not recolored
   to this palette, and it is not dimmed to the nav's --ink-faint: the dark
   purple half goes to mud on this ground the moment opacity comes off it.

   The extra gap falls on the first .navOut after a page link, so the nav shows
   where this site stops without needing a rule or a bullet. */
.siteNav li:not(.navOut) + .navOut { margin-left: 0.6rem; }
.siteNav .navOut { display: flex; align-items: center; }
.siteNav .navOut img { height: 1.5em; width: auto; display: block; }

main { padding: 0 1.5rem 5rem; }

.wrap { max-width: var(--measure); margin: 0 auto; }
.wrap--wide { max-width: 62rem; margin: 0 auto; }

/* ---------------------------------------------------------------- */
/* TYPE                                                             */
/* ---------------------------------------------------------------- */

h1 {
  font-family: 'Syne', var(--mono);
  font-weight: 700;
  font-size: clamp(1.9rem, 5vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 2.5rem 0 0.5rem;
}

/* A HEADLINE HELD TO ONE LINE. `nowrap` on its own overflows the column, so
   the size is solved from the string's measured em-width rather than guessed:
   divide the available width by a divisor that clears the wider of Syne 700
   and the mono fallback, and the line holds before the webfont lands and
   after. That divisor belongs to one specific string, so each page carries its
   own and editing the headline means remeasuring. The cost is real: a long
   line fitted this way resolves below body-copy size at phone widths, and only
   a shorter headline buys the size back. */
h1.h1--fit { white-space: nowrap; }

.standfirst {
  font-size: 1.2rem;
  color: var(--ink-faint);
  margin: 0 0 2.5rem;
}

h2 {
  font-family: var(--mono);
  font-weight: 600;
  font-size: var(--label);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-faint);
  border-top: 1px solid var(--panel-edge);
  padding-top: 0.9rem;
  margin: 3.5rem 0 1.2rem;
}

/* THE SECTION LABELS HANG IN THE MARGIN, and the page is deliberately
   left-weighted because of it: the column stays centered, the labels reach out
   past it, and the right margin is left empty. A rule over a centered label with
   the text beneath it is the arrangement every article on the web already has.

   The label is a float with a negative left margin larger than its own width, so
   it sits entirely outside the column and the prose is not indented around it.
   That takes it out of the column's vertical flow too, which is why the element
   after it carries the space the label used to occupy.

   The breakpoint is the arithmetic, not a guess: the column is --measure and the
   label needs 13rem to its left, so below 74rem there is nowhere to hang it and
   it goes back above the text with its rule. */
@media (min-width: 74rem) {
  main .wrap h2 {
    float: left;
    clear: left;
    width: 10rem;
    margin: 0.35rem 0 0 -13rem;
    padding-top: 0;
    border-top: none;
    text-align: right;
    color: var(--ink-faint);
  }
  main .wrap h2 + * { margin-top: 3.2rem; }
  main .wrap h2 + .cols,
  main .wrap h2 + ul.plain,
  main .wrap h2 + ol { margin-top: 3.2rem; }

  /* A full-bleed figure reaches further left than the column does, so without
     this it can come to rest beside a hanging label and run through it. */
  main .wrap .figWide { clear: left; }
}

h3 {
  font-family: var(--prose);
  font-weight: 600;
  font-size: 1.15rem;
  margin: 2.2rem 0 0.6rem;
}

p { margin: 0 0 1.15rem; }

a { color: var(--accent); text-underline-offset: 0.15em; }

strong { font-weight: 600; }

code, .cmd {
  font-family: var(--mono);
  font-size: 0.88em;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--panel-edge);
  border-radius: 2px;
  padding: 0.05em 0.22em;
  white-space: nowrap;
}

/* A command name paired with what Rhino calls it — the alias bridge from
   the app itself, which is a teaching feature and not an apology. */
.cmd .rhino { color: var(--ink-faint); }

ul.plain { list-style: none; padding: 0; margin: 0 0 1.5rem; }
ul.plain > li {
  border-top: 1px solid var(--panel-edge);
  padding: 0.7rem 0;
}
ul.plain > li:last-child { border-bottom: 1px solid var(--panel-edge); }

/* ---------------------------------------------------------------- */
/* THE TWO RECURRING REGISTERS                                      */
/*                                                                  */
/* They are different things and must not look alike. SCAR TISSUE   */
/* is about what did not get built — it is retrospective, personal, */
/* and its whole job is to be skippable without losing the argument.*/
/* PARTIAL is about what IS built but does not yet do the whole     */
/* job — it is a live status, it sits inside the claim it qualifies,*/
/* and skipping it would leave the reader believing something       */
/* untrue. So: scar tissue is a quiet gray aside that interrupts    */
/* the column; partial is a small bright inline flag that does not. */
/* ---------------------------------------------------------------- */

.scar {
  border: 1px solid var(--panel-edge);
  border-left: 2px solid var(--ink-faint);
  background: rgba(255, 255, 255, 0.02);
  padding: 1rem 1.2rem 0.3rem;
  margin: 2rem 0;
  color: var(--ink-faint);
  font-size: 0.97rem;
}
.scar > .scarLabel {
  display: block;
  font-family: var(--mono);
  font-size: var(--label-sm);
  letter-spacing: var(--track-sm);
  text-transform: uppercase;
  color: var(--ink-faint);
  opacity: 0.75;
  margin-bottom: 0.5rem;
}
.scar p:last-child { margin-bottom: 0.85rem; }

.partial {
  display: inline-block;
  font-family: var(--mono);
  font-size: var(--label-sm);
  letter-spacing: var(--track-sm);
  text-transform: uppercase;
  color: var(--warn);
  border: 1px solid rgba(246, 209, 88, 0.35);
  border-radius: 2px;
  padding: 0.1em 0.45em;
  vertical-align: 0.08em;
  white-space: nowrap;
}

.partialNote {
  border-top: 1px solid rgba(246, 209, 88, 0.35);
  padding-top: 0.8rem;
  margin: 1.4rem 0 1.6rem;
  font-size: 0.97rem;
  color: var(--ink-faint);
}
.partialNote p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- */
/* WARNINGS                                                         */
/* ---------------------------------------------------------------- */

.warnBlock {
  border: 1px solid rgba(246, 209, 88, 0.35);
  background: rgba(246, 209, 88, 0.06);
  padding: 1rem 1.2rem;
  margin: 2rem 0;
}
.warnBlock > .warnLabel {
  display: block;
  font-family: var(--mono);
  font-size: var(--label-sm);
  letter-spacing: var(--track-sm);
  text-transform: uppercase;
  color: var(--warn);
  margin-bottom: 0.5rem;
}
.warnBlock p:last-child { margin-bottom: 0; }

/* THE DRAWER FORM. The label is the summary, so it keeps the warn styling and
   the body is what opens. The native marker is suppressed on both engines and
   replaced with a triangle that states the state. */
details.warnBlock { padding: 0.8rem 1.2rem; }
details.warnBlock > summary.warnLabel {
  cursor: pointer;
  list-style: none;
  margin-bottom: 0;
}
details.warnBlock > summary.warnLabel::-webkit-details-marker { display: none; }
details.warnBlock > summary.warnLabel::after { content: ' \25B8'; opacity: 0.8; }
details.warnBlock[open] > summary.warnLabel { margin-bottom: 0.6rem; }
details.warnBlock[open] > summary.warnLabel::after { content: ' \25BE'; }

/* ---------------------------------------------------------------- */
/* ASSET PLACEHOLDERS — visible on purpose. A page does not ship    */
/* with an unfilled one, so they must be impossible to miss.        */
/* ---------------------------------------------------------------- */

.assetSlot {
  border: 1px dashed var(--accent-dim);
  background: rgba(91, 143, 217, 0.04);
  padding: 1rem 1.2rem;
  margin: 2rem 0;
  font-family: var(--mono);
  font-size: var(--label);
  line-height: 1.55;
  color: var(--ink-faint);
}
.assetSlot b { color: var(--accent); font-weight: 600; }

/* ---------------------------------------------------------------- */
/* FOOTNOTES                                                        */
/* ---------------------------------------------------------------- */

.fn { font-family: var(--mono); font-size: 0.72em; vertical-align: super; line-height: 0; text-decoration: none; }

.notes {
  border-top: 1px solid var(--panel-edge);
  margin-top: 4rem; padding-top: 1.2rem;
  font-size: 0.92rem; color: var(--ink-faint);
}
.notes ol { padding-left: 1.4rem; margin: 0; }
.notes p { margin-bottom: 0; }
.notes p .fn { vertical-align: baseline; }
.notes li { margin-bottom: 0.7rem; }

/* A FIGURE THAT ESCAPES THE MEASURE. Prose sits at 34rem, which is right for
   reading and far too narrow for a screenshot of an interface — the view-source
   proof is illegible at column width, which defeats the one thing it is there
   to do. This widens to the site's own wide wrap and re-centers on the column's
   center line, which is also the page's. */
.figWide {
  width: min(62rem, calc(100vw - 3rem));
  margin-left: 50%;
  transform: translateX(-50%);
}

/* A FIGURE'S CAPTION. One rule, because four pages had been carrying the same
   declaration inline and had drifted off the label scale. */
figure figcaption {
  text-align: center;
  font-family: var(--mono);
  font-size: var(--label-sm);
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  margin-top: 0.7rem;
}

/* A TWO-FRAME COMPARISON. Side by side where there is room, stacked where
   there is not — a pair of screenshots squeezed into half a phone column
   proves nothing. Each frame carries its own label because "which one is
   which" is the entire content of a comparison figure. */
.figPair { display: grid; gap: 0.9rem; }
@media (min-width: 46rem) { .figPair { grid-template-columns: 1fr 1fr; } }
.figPair img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--panel-edge);
}
.figLabel {
  display: block;
  font-family: var(--mono); font-size: var(--label-sm);
  letter-spacing: var(--track-sm); text-transform: uppercase;
  color: var(--ink-faint); margin-top: 0.4rem;
}

/* ---------------------------------------------------------------- */
/* DOORS — the home page's links out                                */
/* ---------------------------------------------------------------- */

.doors { display: grid; gap: 1px; background: var(--panel-edge); border: 1px solid var(--panel-edge); margin: 2.5rem 0; }
.door { background: var(--bg); padding: 1.1rem 1.3rem; text-decoration: none; display: block; }
.door:hover { background: rgba(91, 143, 217, 0.06); }
.door .doorName { font-family: var(--mono); font-size: var(--label); letter-spacing: var(--track); text-transform: uppercase; color: var(--accent); display: block; margin-bottom: 0.35rem; }
.door .doorWhat { color: var(--ink-faint); font-size: 0.97rem; display: block; }

/* ---------------------------------------------------------------- */
/* THREE-COLUMN CAPABILITY LISTS                                    */
/* ---------------------------------------------------------------- */

.cols { display: grid; gap: 2rem; margin: 1.5rem 0 2rem; }
@media (min-width: 60rem) { .cols { grid-template-columns: repeat(3, 1fr); gap: 2.5rem; } }
/* NOT A SECOND UPPERCASE LABEL. h2 above it is already faint uppercase mono
   with a rule over it; repeating that treatment one level down stacked two
   labels the reader had to tell apart by 0.02rem of size. This one is the same
   mono at the same size and carries its grouping in case and weight instead —
   sentence case, full ink, no tracking, sitting directly on its list. */
.cols h3 { margin-top: 0; font-family: var(--mono); font-size: var(--label); letter-spacing: 0.02em; color: var(--ink); font-weight: 600; }
.cols ul { list-style: none; padding: 0; margin: 0; font-size: 0.97rem; }
.cols li { border-top: 1px solid var(--panel-edge); padding: 0.6rem 0; }

/* ---------------------------------------------------------------- */
/* LAUNCH                                                           */
/* ---------------------------------------------------------------- */

.launch {
  display: inline-block;
  font-family: var(--mono); font-size: var(--label-lg); letter-spacing: 0.02em;
  background: var(--accent); color: #06090c;
  border: 1px solid var(--accent);
  padding: 0.7rem 1.4rem; text-decoration: none; border-radius: 2px;
}
.launch:hover { background: transparent; color: var(--accent); }

/* THE LAUNCH CONTROL, INERT. Unused while the app ships — kept because the
   state is one flag away. tools/deploy.py swaps the <a> for a <span> at build
   time when PUBLISH_APP is False, and the disabled styling is what stops a
   live-looking blue button that does nothing from reading as a broken site. */
.launch--off,
.launch--off:hover {
  background: transparent;
  color: var(--ink-faint);
  border-color: var(--panel-edge);
  cursor: default;
}

/* The footnote that says which pages exist but are not served yet. */
.withheld {
  font-family: var(--mono);
  font-size: var(--label-sm);
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  margin: 0 0 0.9rem;
}

.launchRow { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; margin: 2rem 0; }
.launchRow .meta { font-family: var(--mono); font-size: var(--label-sm); color: var(--ink-faint); }

/* ---------------------------------------------------------------- */
/* FOOT                                                             */
/* ---------------------------------------------------------------- */

.siteFoot {
  border-top: 1px solid var(--panel-edge);
  padding: 1.6rem 1.5rem 3rem;
  font-family: var(--mono); font-size: var(--label-sm); line-height: 1.7;
  color: var(--ink-faint);
}
.siteFoot .wrap--wide { display: flex; flex-wrap: wrap; gap: 0.6rem 2rem; justify-content: space-between; }
.siteFoot a { color: var(--ink-faint); }
.siteFoot a:hover { color: var(--accent); }

@media (prefers-reduced-motion: no-preference) {
  a, .door { transition: color 120ms ease, background-color 120ms ease; }
}
