/* Nobedan — design tokens.
 *
 * The single source for colour, type, space and rule values. Nothing else in
 * the codebase should carry a raw hex, a raw px rule width, or a magic type
 * size. Light-only for now (DESIGN.md); when a dark rendition is decided it
 * becomes a second block here and nowhere else.
 */

:root {
	/* ── THE ACCENT ────────────────────────────────────────────────────
	 * PLACEHOLDER. The Nobedan hue is deliberately TBD — it gets picked
	 * against real content, not against swatches (DESIGN.md, "One hue per
	 * thing"). This one value is the only thing to change: everything
	 * else derives from it with color-mix(). Current stand-in sits in the
	 * candidate territory (warm coral / darkroom safelight) and is light
	 * enough that ink reads on it at 7.4:1, which is the constraint a
	 * full-bleed colour block imposes — "the hue as ground, ink on top."
	 * Any replacement must keep >= 7:1 against --ink or the colour blocks
	 * stop working.
	 */
	--accent: #f2865e;

	/* ── Ink on paper — the default field ─────────────────────────────
	 * Two layers on purpose. The *-base pair are the physical colours and
	 * never change below the root; --ink and --paper are the roles, and a
	 * full-bleed block may swap them (see .bleed--ink in layout.css).
	 * Anything derived from a role has to be re-derived wherever the role
	 * is swapped — custom properties resolve where they are declared.
	 */
	--ink-base: #151311;
	--paper-base: #fbfaf7;

	--ink: var(--ink-base);
	--paper: var(--paper-base);

	/* Ink at reduced presence. Mixed toward paper, never toward grey, so
	 * secondary text stays warm. */
	--ink-muted: color-mix(in oklab, var(--ink) 66%, var(--paper));
	--ink-faint: color-mix(in oklab, var(--ink) 42%, var(--paper));

	/* Accent derivations. Only the ground exists so far; anything else the
	 * hue needs is a color-mix() against --accent at the point of use,
	 * added here when a second surface actually wants it. */
	--accent-ground: var(--accent);

	/* ── The secondary hues ────────────────────────────────────────────
	 * Proposal 001, round 3: the three months and the pulse's three series
	 * each want their own hue. Orange is the accent; the rest are placed
	 * here so no file below carries a raw hex. Tune against real content
	 * like the accent; --hue-yellow and --hue-green are also grounds, so
	 * they keep ink legible (>= 7:1). */
	--hue-orange: var(--accent);
	--hue-yellow: #f0c050;
	--hue-green: #8ec26a;
	--hue-green-light: #d5e366;
	--hue-teal: #3ea3c2;

	/* ── Rules carry all structure ──────────────────────────────────────
	 * No boxes, no cards, no shadows.
	 *
	 * A rule is never grey. Every rule on every surface is drawn in the
	 * body text colour, and hierarchy is carried by *width alone* — four
	 * weights, each half the one above it. The three colour names below
	 * survive only because the instrument shadow roots reference them;
	 * they all resolve to the same ink, and a rule that needs to be
	 * quieter takes a thinner width, never a paler colour.
	 *
	 * The finest weight is a fraction of a CSS pixel on purpose: on a 2x
	 * display it is one crisp device pixel, and on a 1x display the
	 * compositor antialiases it. That is ink at a sub-pixel width — the
	 * *colour* is still the text colour, which is the rule that matters.
	 */
	--rule-fine-width: 0.5px;
	--rule-hairline-width: 1px;
	--rule-medium-width: 2px;
	--rule-heavy-width: 5px;

	--rule-color: var(--ink);
	--rule-color-quiet: var(--ink);
	--rule-color-strong: var(--ink);
	/* Deliberately no `--rule-hairline: 1px solid var(--rule-color)`
	 * shorthand: a custom property resolves its var()s where it is
	 * declared, so a shorthand defined here would freeze the root's rule
	 * colour and ignore the override inside a colour block. Borders are
	 * written out as width + solid + colour at each use. */

	/* ── Type families ──────────────────────────────────────────────────
	 * Grand is a warm geometric grotesque: fall back through the
	 * geometric humanists the host may have (Avenir, Futura, Century
	 * Gothic) before the generic system sans, so the fallback keeps the
	 * round-o skeleton rather than collapsing to Helvetica.
	 *
	 * 1980 Black Wide is ultra-heavy and *wide*: Impact and
	 * Haettenschweiler are deliberately excluded — they are condensed,
	 * the opposite failure. Arial Black is the only widely-installed face
	 * in the right register; expect the fallback to set narrower.
	 */
	--font-grand:
		"Grand", "Avenir Next", "Avenir", "Futura", "Century Gothic",
		"URW Gothic", system-ui, -apple-system, "Segoe UI", sans-serif;
	--font-1980:
		"1980 Black Wide", "Arial Black", "Archivo Black",
		"Helvetica Neue Black", var(--font-grand);

	/* There is no Nobedan mono yet (DESIGN.md). This is the host's own
	 * monospace, used only for literal code and file paths — never for
	 * numeric matter, which sets in Grand and aligns natively. When the
	 * Nobedan mono exists it replaces the head of this stack. */
	--font-mono:
		ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
		"Liberation Mono", monospace;

	/* ── Weight axis — hierarchy comes from here and from size ───────── */
	--weight-thin: 200;
	--weight-light: 300;
	--weight-regular: 400;
	--weight-medium: 500;
	--weight-bold: 700;

	/* ── Type scale ─────────────────────────────────────────────────────
	 * THREE SIZES CARRY THE DOCUMENT: caption, body, heading. Each is
	 * exactly 1.5x the one below it, so adjacent sizes never look like a
	 * mistake — a size either is the next step or it does not exist. The
	 * ratio is written as arithmetic rather than as three hand-tuned
	 * clamps so it cannot drift: change --text-body and the whole
	 * document rescales in proportion.
	 *
	 * --text-hero is the one sanctioned exception, and it obeys the same
	 * ratio (one step above heading, 2.25x body). It is a *copy*
	 * treatment, not a heading size: the question a section opens with,
	 * the sentence a section rests on, a card's number. One per section,
	 * at most.
	 *
	 * Everything below the rule is the display register — the masthead,
	 * the rationed 1980 moments (about three per artifact), the colophon
	 * furniture. Those are design elements, outside the document scale,
	 * and they are the only sizes on the page that are not one of the
	 * four above.
	 */
	--text-body: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
	--text-caption: calc(var(--text-body) / 1.5);
	--text-heading: calc(var(--text-body) * 1.5);
	--text-hero: calc(var(--text-body) * 2.25);

	/* ── The graphic register — the second sanctioned exception ─────────
	 * A card is a graphic, not copy: a numeral doing the talking, one word
	 * naming it, and a few lines of supporting text that are read *after*
	 * the number, not instead of it. Set that text at body size and the
	 * block stops being a graphic and becomes three more paragraphs.
	 *
	 * So the register has two sizes of its own and they are used nowhere
	 * else — never in running copy, never for a paragraph that sits beside
	 * one. Both stay on the ladder's arithmetic:
	 *
	 *   --text-graphic — one HALF step below body. 1.2247 is sqrt(1.5), so
	 *     two of these steps are exactly one step of the document scale and
	 *     the ratio still cannot drift.
	 *   --text-graphic-figure — the numeral. Bigger than the hero and
	 *     simpler, but clamped to a third of the sheet: three cards across
	 *     a wide row is the widest a card ever gets, and the display
	 *     register would overshoot it by half.
	 */
	--text-graphic: calc(var(--text-body) / 1.2247);
	--text-graphic-figure: clamp(2.75rem, 1.9rem + 3vw, 4rem);

	--text-masthead: clamp(2.25rem, 1.7rem + 2.6vw, 3.75rem);
	--text-display: clamp(3rem, 1.4rem + 7.6vw, 7.5rem);
	/* Ceiling set so a seven-character word in 1980 Black Wide still fits
	 * the sheet column on one line. Longer moments do not exist. */
	--text-mega: clamp(3.25rem, 0.4rem + 13vw, 10rem);

	/* Names from the pre-three-size scale, kept only because the
	 * instrument shadow roots (the per-client js directories) still
	 * reference them. They
	 * are aliases onto the scale above and add no sizes of their own;
	 * retire them when those scripts are migrated. */
	--text-label: var(--text-caption);
	--text-small: var(--text-caption);
	--text-lead: var(--text-heading);
	--text-3: var(--text-heading);
	--text-2: var(--text-heading);
	--text-1: var(--text-masthead);

	/* Tracking. Grand needs negative tracking as it gets large; labels
	 * need positive tracking because they are set in caps. */
	--track-mega: -0.03em;
	--track-display: -0.045em;
	--track-head: -0.03em;
	--track-body: 0;
	--track-label: 0.09em;

	/* Leading. */
	--leading-mega: 0.82;
	--leading-display: 0.9;
	--leading-head: 1.06;
	--leading-body: 1.5;
	--leading-tight: 1.25;

	/* ── Space scale ────────────────────────────────────────────────── */
	--space-3xs: 0.25rem;
	--space-2xs: 0.375rem;
	--space-xs: 0.625rem;
	--space-s: 1rem;
	--space-m: 1.5rem;
	--space-l: 2.25rem;
	--space-xl: 3.5rem;
	--space-2xl: 5.5rem;
	--space-3xl: 8rem;

	/* ── Page measure ───────────────────────────────────────────────────
	 * Generous margins; a few hundred words per screen, not walls.
	 */
	--page-margin: clamp(1.25rem, 5vw, 5rem);
	--sheet-max: 58rem;
	--label-col: 11rem;
	--gutter: clamp(1.25rem, 3.5vw, 3rem);
	--measure: 36rem;

	/* Vertical rhythm of a spec-sheet row — deliberately lopsided.
	 *
	 * A rule belongs to the heading BELOW it, not to the paragraph above
	 * it: it announces the next thing rather than underlining the last
	 * one. So the space between a rule and its own heading is a quarter
	 * of the space between the previous section's last line and that
	 * rule. --row-lead is the short side (rule to heading), --row-trail
	 * the long one (content to the next rule).
	 */
	--row-lead: clamp(var(--space-xs), 1.1vw, var(--space-s));
	--row-trail: clamp(var(--space-l), 4vw, var(--space-2xl));
	/* Old symmetric name, still read by the instrument shadow roots. */
	--row-pad: var(--row-trail);
}
