/* ============================================================================
   TEAKDECK — design system

   The register is a private trustee's statement: a document of record, not a
   trading terminal. But a landing page has a different job from the app's
   interior — it has seconds to SHOW what the product is. So the marketing page
   uses the same materials (paper, ink, hairlines, tabular figures) arranged as
   a product page: header, grid, framed panels, and the notice itself on display.

   Rejected: dark + neon (the trading register, and every competitor);
   warm cream + soft cards (the ubiquitous "thoughtful software" look — reads
   soft, and softness undercuts authority for someone trusting you with $2m);
   Swiss modernism (kept the grid discipline, refused the coldness and the
   small type — this audience is 45-70).

   Three commitments:
     1. NO SHADOWS, NO SOFT FLOATING CARDS, NO LARGE RADII. Structure comes from
        hairline frames and whitespace, as in a printed statement. Framed panels
        are allowed; drop-shadowed blobs are not.
     2. NO RED/GREEN, and no color-coded good/bad anywhere. Attention is
        signaled by ANNOTATION — a mark in the margin, the way an editor flags
        a line. Inside band means no mark at all.
     3. MOTION MAY EASE, IT MAY NEVER RECRUIT. Revised 2026-08-20 (D34) from an
        earlier "essentially no motion", which aimed at austerity when the target
        is composure. Easing is welcome: transitions, gentle reveals, a chart
        arriving. Recruiting is banned outright — numbers that count up, rows
        that flash on change, badges, pulsing, anything live-updating. A figure
        that animates when it changes is TRAINING THE USER TO WATCH IT, which
        works directly against D33. Motion should be noticed only in its
        absence: if a user could describe an animation afterwards, it was too
        much. prefers-reduced-motion is honored throughout, without exception.
   ========================================================================= */

/* ------------------------------------------------------------------ fonts --
   Self-hosted: no third-party request from a page about someone's money.

   Newsreader — finer and higher-contrast than a workhorse text serif, with an
   optical-size axis so the same family carries a 56px headline and 17px body.
   IBM Plex Sans — UI, labels, figures. Reads engineered; Inter reads default.
*/
@font-face {
  font-family: 'Newsreader';
  src: url('/fonts/Newsreader-Variable.woff2') format('woff2-variations');
  font-weight: 200 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Newsreader';
  src: url('/fonts/Newsreader-Italic-Variable.woff2') format('woff2-variations');
  font-weight: 200 800; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/fonts/IBMPlexSans-Variable.woff2') format('woff2-variations');
  font-weight: 100 700; font-style: normal; font-display: swap;
}

/* ----------------------------------------------------------------- tokens --
   Paper is COOL, not cream. A yellow undertone reads cozy; a barely-there
   green-gray reads paper, ledger, institutional calm. Page ground is toned and
   the content surface is true white — paper on a desk.

   Accent is fountain-pen blue-black: the color of ink and annotation, which
   ties to "letters to your future self". Not navy, not gold, and emphatically
   not any red — red reads as loss in a financial context however chosen.
*/
:root {
  --paper:        #f7f9f7;
  --sheet:        #ffffff;
  --ink:          #16191a;
  --ink-muted:    #565e60;
  --ink-faint:    #8b9395;
  --rule:         #e3e8e4;
  --rule-strong:  #c9d1cb;
  --accent:       #2f3e7e;
  --accent-wash:  #f2f4fa;
  --amber:        #8a6a1f;

  --page-max:  1180px;
  --prose-max: 60ch;

  --step--2: 0.75rem;
  --step--1: 0.875rem;
  --step-0:  1.0625rem;   /* 17px. 45-70 audience; do not shrink. */
  --step-1:  1.1875rem;
  --step-2:  1.5rem;
  --step-3:  2rem;
  --step-4:  2.75rem;
  --step-5:  3.75rem;

  --serif: 'Newsreader', 'Iowan Old Style', Palatino, Georgia, serif;
  --sans:  'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;

  color-scheme: light dark;
}

/* Light-first is itself the positioning move — nearly every finance product
   defaults dark. Dark is supported, not led with. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #101314; --sheet: #171b1c; --ink: #e7ebe8; --ink-muted: #9aa3a4;
    --ink-faint: #6d7678; --rule: #262c2d; --rule-strong: #3a4243;
    --accent: #97a5e6; --accent-wash: #1b2030; --amber: #c9a866;
  }
}
:root[data-theme='dark'] {
  --paper: #101314; --sheet: #171b1c; --ink: #e7ebe8; --ink-muted: #9aa3a4;
  --ink-faint: #6d7678; --rule: #262c2d; --rule-strong: #3a4243;
  --accent: #97a5e6; --accent-wash: #1b2030; --amber: #c9a866;
}
:root[data-theme='light'] {
  --paper: #f7f9f7; --sheet: #ffffff; --ink: #16191a; --ink-muted: #565e60;
  --ink-faint: #8b9395; --rule: #e3e8e4; --rule-strong: #c9d1cb;
  --accent: #2f3e7e; --accent-wash: #f2f4fa; --amber: #8a6a1f;
}

/* ------------------------------------------------------------------- base -- */
*, *::before, *::after { box-sizing: border-box; }
/* Smooth scrolling for in-page anchors.
   This is NOT a violation of commitment 3 ("essentially no motion"), and it is
   worth saying why so it does not get stripped out later. That commitment is
   about the product not animating AT the reader — nothing pulses, slides in, or
   competes for attention. A jump-cut between two points on a long page is
   disorienting: you arrive with no idea how far you moved or what you passed.
   The scroll is the one piece of motion that REDUCES agitation rather than
   creating it, which is the same test everything else here is held to.

   scroll-padding-top clears the sticky masthead so an anchor target does not
   land underneath it. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(66px + 1.5rem);
}

/* Some people get motion sick from scroll animation, and some simply asked not
   to have it. Honor that — a preference is a stated intention, which is the one
   kind of instruction this product always obeys. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--step-0);
  line-height: 1.6;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}

img, svg { max-width: 100%; height: auto; }

/* ----------------------------------------------------------------- header -- */
/* Sticky. On a long page the way back is always the masthead, and hunting for
   it by scrolling to the top is friction with no purpose.

   It does NOT shrink on scroll. A header that resizes as you read is motion
   aimed at the reader, which is exactly what commitment 3 rules out — and the
   masthead is only 66px, so there is little space to reclaim and a good deal of
   stability to lose.

   Separation from the content beneath comes from the sheet/paper contrast plus
   the hairline rule, both of which are already there.

   A scroll-driven variant that darkened the rule once content passed underneath
   was built and then removed. Chrome reports support for animation-timeline via
   CSS.supports(), attaches a ScrollTimeline, and then leaves that timeline
   permanently inactive — timeline.currentTime stays null at any scroll offset,
   so the rule never changed. It was decoration that did not work, which is
   worse than no decoration. If it is ever re-attempted, verify
   timeline.currentTime is non-null while scrolled BEFORE keeping it. */
/* Development banner. An honest notice while the product is pre-launch. Held to
   the same rule as everything else — no motion, no red box (design commitment
   2); it states a fact and stops. Not sticky: it scrolls away and the masthead
   takes the top. Removed together with noindex at launch. */
.dev-banner {
  background: var(--accent-wash);
  border-bottom: 1px solid var(--rule);
  color: var(--ink-muted);
  font-family: var(--sans);
  font-size: var(--step--1);
  line-height: 1.45;
  text-align: center;
  padding: 0.5rem clamp(1rem, 4vw, 2.5rem);
}
.dev-banner strong { color: var(--amber); font-weight: 600; }
@media print { .dev-banner { display: none; } }

.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid var(--rule);
  background: var(--sheet);
}
.masthead__inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2.5rem);
  height: 66px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

/* Logo placeholder — a ruled monogram, replaceable with a mark later. */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--ink);
}
.logo__mark {
  color: var(--accent);
  flex: none;
}
.logo__descriptor {
  font-family: var(--sans);
  font-size: 0.625rem;
  font-weight: 550;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-left: 0.55rem;
  padding-left: 0.6rem;
  border-left: 1px solid var(--rule-strong);
}
@media (max-width: 560px) { .logo__descriptor { display: none; } }

.logo__word {
  font-family: var(--serif);
  font-size: var(--step-1);
  font-weight: 500;
  letter-spacing: 0.01em;
}

.nav { display: flex; align-items: center; gap: 1.75rem; }
.nav a {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-muted);
  text-decoration: none;
}
.nav a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 0.2em; }
.nav a.nav__signin { color: var(--accent); font-weight: 500; }

.nav__toggle {
  display: none;
  background: none;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0.4rem 0.55rem;
  cursor: pointer;
  color: var(--ink);
}
.nav__toggle svg { display: block; }

@media (max-width: 820px) {
  .nav__toggle { display: block; }
  .nav {
    display: none;
    position: absolute;
    top: 66px; left: 0; right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--sheet);
    border-bottom: 1px solid var(--rule);
    padding: 0.5rem clamp(1rem, 4vw, 2.5rem) 1rem;
    z-index: 20;
  }
  .nav[data-open='true'] { display: flex; }
  .nav a {
    width: 100%;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--rule);
    font-size: var(--step-0);
  }
  .masthead__inner { position: relative; }
}

/* ---------------------------------------------------------------- layout -- */
.wrap {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2.5rem);
}
.section { padding: clamp(3rem, 7vw, 5.5rem) 0; }
.section + .section { border-top: 1px solid var(--rule); }
.section--tint { background: var(--sheet); border-top: 1px solid var(--rule); }

.grid { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--hero { grid-template-columns: 1fr; align-items: center; }

@media (min-width: 860px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--hero { grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); }
}

.prose { max-width: var(--prose-max); }

/* ------------------------------------------------------------------- type -- */
h1, h2, h3 {
  font-family: var(--serif);
  line-height: 1.1;
  letter-spacing: -0.015em;
  text-wrap: balance;
  margin: 0 0 0.55em;
  font-weight: 400;   /* Newsreader is fine enough that 400 carries a headline. */
}
h1 { font-size: clamp(2.25rem, 5.2vw, var(--step-5)); }
h2 { font-size: clamp(var(--step-3), 3.6vw, var(--step-4)); }
h3 { font-size: var(--step-1); font-weight: 500; letter-spacing: 0; }

p { margin: 0 0 1em; }
.lede { font-size: var(--step-2); line-height: 1.4; color: var(--ink-muted); }

.label {
  font-family: var(--sans);
  font-size: var(--step--2);
  font-weight: 550;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: block;
  margin-bottom: 0.85rem;
}

blockquote {
  margin: 0;
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
  font-style: italic;
}
blockquote p:last-child { margin-bottom: 0; }

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

/* --------------------------------------------------------------- controls -- */
.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-top: 1.75rem; }

.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: var(--step-0);
  font-weight: 500;
  padding: 0.75rem 1.5rem;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  border-radius: 2px;      /* 2px, not 8. Paper has corners. */
  transition: opacity 120ms linear;
}
.btn:hover { opacity: 0.88; }
.btn--quiet { background: transparent; color: var(--accent); border-color: var(--rule-strong); }

.microcopy {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-faint);
  margin-top: 0.9rem;
}

:where(a, button, input, textarea, summary):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------- panels --
   A framed region, not a floating card. Hairline border, square-ish corners,
   NO shadow. This is what lets the page look like a product without adopting
   the soft-card language of every other fintech site.
*/
.panel {
  background: var(--sheet);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: clamp(1.25rem, 3vw, 2rem);
}
.panel__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding-bottom: 0.85rem;
  margin-bottom: 1.15rem;
  border-bottom: 1px solid var(--rule);
}
.panel__title {
  font-family: var(--sans);
  font-size: var(--step--1);
  font-weight: 550;
  letter-spacing: 0.02em;
}
.panel__meta { font-family: var(--sans); font-size: var(--step--2); color: var(--ink-faint); }

/* ---------------------------------------------------------------- figures -- */
.figure, td.num, .stat__value, .amt {
  font-family: var(--sans);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

/* Income first. The largest number anywhere is what the portfolio PAYS,
   never what it is worth. */
.stat__value {
  font-size: clamp(var(--step-4), 7vw, 3.5rem);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1;
  display: block;
}
.stat__caption {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-muted);
  margin-top: 0.6rem;
}

/* Ruled rows, not striped cells. A statement, not a spreadsheet. */
.ledger { width: 100%; border-collapse: collapse; font-family: var(--sans); font-size: var(--step--1); }
.ledger th {
  text-align: left;
  font-size: var(--step--2);
  font-weight: 550;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0 0 0.55rem;
  border-bottom: 1px solid var(--rule-strong);
}
.ledger td { padding: 0.6rem 0; border-bottom: 1px solid var(--rule); }
.ledger tr:last-child td { border-bottom: 0; }
.ledger .num { text-align: right; font-variant-numeric: tabular-nums lining-nums; }

/* Commitment 2. Outside band is ANNOTATED, not coloured. Presence of the mark
   carries the meaning; every other row has nothing. */
.ledger tr[data-flagged] td:first-child { box-shadow: inset 2px 0 0 var(--accent); padding-left: 0.6rem; }
.flagnote { font-family: var(--sans); font-size: var(--step--2); color: var(--ink-muted); }

/* Terse negative-space list for "what this is not". */
.nots { list-style: none; padding: 0; margin: 0; display: grid; gap: 0; }
.nots li { padding: 0.9rem 0; border-bottom: 1px solid var(--rule); }
.nots li:first-child { border-top: 1px solid var(--rule); }
.nots b { font-weight: 500; }
.nots span { color: var(--ink-muted); }

/* ---------------------------------------------------------------- pricing -- */
.tier { border: 1px solid var(--rule-strong); border-radius: 2px; padding: 1.5rem; background: var(--sheet); }
.tier__name { font-family: var(--sans); font-size: var(--step--1); font-weight: 550; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); }
.tier__price { font-family: var(--sans); font-variant-numeric: tabular-nums lining-nums; font-size: var(--step-4); font-weight: 300; line-height: 1.1; margin: 0.5rem 0 0.15rem; }
.tier__per { font-family: var(--sans); font-size: var(--step--1); color: var(--ink-faint); }
.tier ul { list-style: none; padding: 0; margin: 1.1rem 0 0; font-size: var(--step--1); }
.tier li { padding: 0.45rem 0; border-top: 1px solid var(--rule); }

/* --------------------------------------------------------------- footnote -- */
.foot { border-top: 1px solid var(--rule); background: var(--sheet); }
.foot__inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 2rem clamp(1rem, 4vw, 2.5rem);
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-faint);
}
.foot p { max-width: 68ch; }

.skip-link { position: absolute; left: -9999px; }
.skip-link:focus {
  left: 1rem; top: 1rem; z-index: 30;
  background: var(--sheet); color: var(--ink);
  padding: 0.5rem 0.9rem; border: 1px solid var(--accent);
}

/* --------------------------------------------------------- holding pages --
   Placeholder routes that exist so the front page has no dead links. They say
   plainly that the thing is not built, which is cheaper than an apology later.
*/
.holding { max-width: 46rem; padding-top: clamp(1rem, 5vw, 3rem); }
.holding h1 { font-size: clamp(2rem, 4.5vw, var(--step-4)); }
.holding p { margin-bottom: 1.15em; }
.holding .microcopy { border-top: 1px solid var(--rule); padding-top: 1rem; margin-top: 2.5rem; }

/* ------------------------------------------------------------------ forms --
   The record's own surfaces. Same three commitments as everything else: no
   cards, no shadows, no rounded corners beyond the 2px already in use; no
   red/green and no colour-coded good/bad; essentially no motion.

   Inputs are ruled lines rather than boxes. A box is a container you fill in;
   a ruled line is a place on a page where something is written down, which is
   what this product is for. The focus state darkens the rule and does nothing
   else — no glow, no lift, no transition. */

.field { display: block; margin: 0 0 1.25rem; }
.field__label {
  display: block;
  font-family: var(--sans);
  font-size: var(--step--2);
  font-weight: 550;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.4rem;
}
.field__hint {
  display: block;
  font-family: var(--sans);
  font-size: var(--step--2);
  color: var(--ink-muted);
  margin: 0.35rem 0 0;
  max-width: 52ch;
}

.field input[type='text'],
.field input[type='email'],
.field input[type='number'],
.field input[type='date'],
.field textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--sans);
  font-size: var(--step-0);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  padding: 0.45rem 0;
  appearance: none;
}
.field textarea {
  font-family: var(--serif);
  line-height: 1.55;
  min-height: 7rem;
  resize: vertical;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0.7rem 0.8rem;
}
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--ink);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-faint); }

/* Numbers line up. Tabular figures everywhere a quantity is entered or shown. */
.field input[type='number'] { font-variant-numeric: tabular-nums lining-nums; }

/* Side-by-side fields on wider screens, stacked on narrow. No breakpoint
   gymnastics — the form is short enough that two columns is the whole need. */
.fieldrow { display: grid; gap: 0 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .fieldrow--2 { grid-template-columns: 1fr 1fr; } }

/* Validation messages. Commitment 2 applies here too: this is an ANNOTATION in
   the margin, not a red alarm. The product does not shout at people about their
   own money, and it does not shout at them about a typo either. */
.notice-line {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink);
  border-left: 2px solid var(--accent);
  padding: 0.5rem 0 0.5rem 0.9rem;
  margin: 0 0 1.5rem;
  max-width: 60ch;
}
.notice-line--quiet { border-left-color: var(--rule-strong); color: var(--ink-muted); }

/* A row of holdings, extending .ledger. The letter sits under its holding
   rather than beside it, because the reasoning is the record and the numbers
   are the footnote — reversing that guts the product. */
.entry { border-bottom: 1px solid var(--rule); padding: 1.4rem 0; }
.entry:last-of-type { border-bottom: 0; }
.entry__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 1rem; }
.entry__ticker {
  font-family: var(--sans);
  font-size: var(--step-1);
  font-weight: 550;
  letter-spacing: 0.02em;
}
.entry__meta {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums lining-nums;
}
.entry__letter {
  font-family: var(--serif);
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--ink);
  border-left: 2px solid var(--rule-strong);
  padding: 0.15rem 0 0.15rem 1rem;
  margin: 0.9rem 0 0;
  max-width: var(--prose-max);
}
.entry__asked {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-faint);
  margin: 0.9rem 0 0;
}
.entry__actions { margin: 0.9rem 0 0; display: flex; flex-wrap: wrap; gap: 0.75rem 1.25rem; }
.entry__actions a, .entry__actions button {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-muted);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.entry__actions a:hover, .entry__actions button:hover { color: var(--ink); }

/* The rationale metric. Stated as a fact, never as a score or a grade — no
   progress bar, no colour, no target to hit. Control #4 applies to the user's
   own behaviour as much as to any security. */
.rate { font-family: var(--sans); font-size: var(--step--1); color: var(--ink-muted); }
.rate b { font-weight: 550; color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }

/* ------------------------------------------------------- the one-page doc --
   D21g's shareable object. Set as a DOCUMENT, not a dashboard or a card: a
   rule at the top, the person's own words at reading size, generous space, and
   nothing competing for attention. It should look like something that was
   written, printed, and kept — because that is what it is.

   No panel, no tint, no border box. The whitespace does the containing. */

.creedsheet {
  max-width: 34rem;
  margin: 0 auto;
  padding: 2.5rem 0 0;
  border-top: 2px solid var(--ink);
}
.creed__dateline {
  font-family: var(--sans);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0.5rem 0 3rem;
}
.creed { margin: 0 0 2.75rem; }
.creed__heading {
  font-family: var(--sans);
  font-size: var(--step--2);
  font-weight: 550;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.6rem;
}
/* The person's own words, at the largest reading size on the site. Everything
   else on the page is smaller than this, deliberately. */
.creed__body {
  font-family: var(--serif);
  font-size: var(--step-2);
  line-height: 1.45;
  color: var(--ink);
  margin: 0;
  white-space: pre-wrap;
}

/* Print. Someone will want this on paper, and a shareable object that prints
   badly is not shareable. Everything except the document itself is dropped. */
@media print {
  .masthead, .nav, .actions, .rate, .notice-line, form, .microcopy { display: none !important; }
  body { background: #fff; }
  .creedsheet { max-width: none; border-top-color: #000; }
  .creed__body { font-size: 13pt; }
}

/* --------------------------------------------------------------- journal --
   An article is set as a document to be read, not as a page to be scanned.
   One measure, generous leading, and nothing in the margins competing for
   attention — the same commitments as everywhere else, applied to prose.

   The measure is deliberately narrower than --prose-max. Long-form reading
   wants a shorter line than a landing page does. */

.article { max-width: 38rem; margin: 0 auto; }
/* Byline and date. Sentence case, not caps: uppercase plus letter-spacing is a
   LABEL treatment, and it made a line of ordinary information read as a heading
   competing with the title above it. A byline should be legible and quiet. */
/* Specificity note: this MUST out-rank `.article p` (0,1,1), which sets the
   19px reading size for body copy. As a bare `.article__meta` (0,1,0) it lost,
   and the byline silently rendered at full article size — which is exactly how
   it came to look like a second heading. */
.article .article__meta {
  font-family: var(--sans);
  font-size: var(--step--1);
  line-height: 1.4;
  color: var(--ink-faint);
  margin: 0 0 3rem;
}
.article p {
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.62;
  margin: 0 0 1.4rem;
}
.article h2 {
  font-size: var(--step-2);
  line-height: 1.2;
  margin: 3rem 0 1rem;
}
.article h3 { font-size: var(--step-1); margin: 2.25rem 0 0.75rem; }
.article strong { font-weight: 600; }
.article blockquote {
  margin: 1.8rem 0;
  padding: 0 0 0 1.25rem;
  border-left: 2px solid var(--rule-strong);
}
.article blockquote p { font-style: italic; color: var(--ink-muted); margin: 0; }
.article hr { border: 0; border-top: 1px solid var(--rule); margin: 2.5rem 0; }
.article code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  background: var(--accent-wash);
  padding: 0.1em 0.35em;
  border-radius: 2px;
}
.article ul.nots { margin: 1.4rem 0; }
.article ul.nots li {
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.55;
  padding: 0.7rem 0;
}

/* Tables inside an article scroll rather than forcing the page to. */
.tablewrap { overflow-x: auto; margin: 1.8rem 0; }
.tablewrap .ledger { min-width: 26rem; }

/* The closing disclaimer, which every article carries (control #12). */
.article hr + p { font-size: var(--step--1); color: var(--ink-muted); }

/* ------------------------------------------------------- journal index -- */
/* An index entry is a line in a contents page, not a headline. It was set at
   h2 size, which made a list of four look like four separate articles shouting
   at each other — and the browser's default underline sat there permanently
   while doing nothing on hover, which reads as a broken link rather than a
   live one. Underline on hover only, so the affordance appears when it means
   something. */
.journal-item { border-bottom: 1px solid var(--rule); padding: 1.3rem 0; }
.journal-item:last-of-type { border-bottom: 0; }
.journal-item__title {
  font-family: var(--serif);
  font-size: var(--step-1);
  font-weight: 500;
  line-height: 1.3;
  margin: 0 0 0.3rem;
}
.journal-item__title a { color: var(--ink); text-decoration: none; }
.journal-item__title a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.16em;
}
.journal-item__date {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--ink-faint);
}

/* ================================================================== motion ==
   D34: motion may EASE, it may never RECRUIT.

   Everything below is opt-IN, wrapped in `prefers-reduced-motion: no-preference`
   rather than opted out of under `reduce`. That direction is strictly safer:
   the default state is the FINISHED state, so if an animation never runs —
   because the preference is set, the stylesheet half-loaded, or the browser is
   old — nothing is hidden and nothing is broken. The blanket transition kill
   further up stays as a second net.

   What is deliberately NOT here, and should not be added:

     - Scroll-triggered reveals. They delay the content the reader came for,
       they are the most describable animation there is, and D34's test is that
       motion should be noticed only in its absence. Also the single most
       dated-looking thing a site can do five years later.
     - Anything touching a number. No counting, no flashing on change, no
       highlight on update. A figure that animates when it changes is training
       the reader to watch it, which is the behavior this product exists to
       reduce.
     - Hover lift on panels. That is card language, and commitment 1 rejects it.
     - Parallax, of any kind, ever.

   Durations are 140-240ms. Long enough to read as easing, short enough that
   nobody waits. Transform and opacity only, so everything stays on the
   compositor and holds frame rate on a mid-range phone. */

@media (prefers-reduced-motion: no-preference) {

  /* The page settles rather than slapping into place. Four pixels and a quarter
     of a second — below the threshold at which anyone could describe it
     afterwards, which is exactly the point.

     Only `main` moves. The masthead is position: sticky, and an opacity or
     transform on a sticky element (or any ancestor of one) creates a containing
     block that breaks the stickiness. The bar simply being there while the
     content arrives is also the more natural reading: the frame is fixed, the
     page settles into it. */
  main { animation: settle 240ms cubic-bezier(0.22, 0.61, 0.36, 1) both; }

  @keyframes settle {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: none; }
  }

  /* Interactive state changes ease instead of snapping. These are the ones a
     reader feels without being able to name — the difference between a site
     that responds and one that reacts. */
  a { transition: color 140ms ease; }
  .nav a { transition: color 140ms ease; }
  .journal-item__title a { transition: color 140ms ease; }
  .entry__actions a,
  .entry__actions button { transition: color 140ms ease; }

  .btn {
    transition: opacity 120ms linear,
                background-color 160ms ease,
                border-color 160ms ease,
                color 160ms ease;
  }

  /* The focus rule darkens on focus (see the forms section). Easing it makes
     tabbing through a form feel continuous rather than like a series of jumps.
     Colour only — the border does not thicken, because a field that changes
     size on focus shifts everything below it. */
  .field input[type='text'],
  .field input[type='email'],
  .field input[type='number'],
  .field input[type='date'],
  .field textarea { transition: border-color 160ms ease; }

  /* The mobile navigation. `display` cannot be transitioned, so the element
     appears instantly and then eases in — which is indistinguishable from the
     panel itself easing open, and needs no restructuring of the markup. */
  @media (max-width: 820px) {
    .nav[data-open='true'] { animation: nav-open 180ms ease-out both; }
    @keyframes nav-open {
      from { opacity: 0; transform: translateY(-6px); }
      to   { opacity: 1; transform: none; }
    }
  }
}
