/* ==========================================================================
   Launch Suit DS tokens: the single source for color, type, space and motion.
   Every other Launch Suit DS file and the docs page read from here; components
   only ever use the semantic tokens (--canvas, --text, --accent…), never raw
   values. Tweak live in docs/index.html, then use "Copy tokens.css" there and
   paste it over this file.
   ========================================================================== */

/* ---------- Primitives ----------
   Three ramps, named by hue and step: orange, blue and grayscale, 50 (lightest)
   to 950 (darkest). Every ramp shares the same perceived lightness per step
   (OKLCH L: .985 .962 .905 .83 .75 .67 .54 .42 .30 .21 .16), holds one hue
   end to end, and is most vivid mid-ramp. Built in OKLCH, written as hex.
   - orange: hue 37, pinned at 500 to international orange (#ff4f00)
   - blue: hue 248, the studio backdrop (a muted, low-chroma blue)
   - grayscale: hue 262, a faint cool tint
   Primitives are never used in components; the brand and semantic tiers below
   point at them. */
:root {
	--orange-50: #fff8f7;
	--orange-100: #ffeee9;
	--orange-200: #ffd5c8;
	--orange-300: #ffb19a;
	--orange-400: #ff8763;
	--orange-500: #ff4f00;
	--orange-600: #c03900;
	--orange-700: #882600;
	--orange-800: #551400;
	--orange-900: #310800;
	--orange-950: #1e0401;

	--blue-50: #f6fbff;
	--blue-100: #e9f4ff;
	--blue-200: #cee2f6;
	--blue-300: #accbea;
	--blue-400: #8bb2d9;
	--blue-500: #6d9ac4;
	--blue-600: #3e73a3;
	--blue-700: #0e5083;
	--blue-800: #003054;
	--blue-900: #001931;
	--blue-950: #010e1d;

	--grayscale-50: #f9fafc;
	--grayscale-100: #f1f2f6;
	--grayscale-200: #dde0e5;
	--grayscale-300: #c3c7cf;
	--grayscale-400: #a9aeb7;
	--grayscale-500: #90959f;
	--grayscale-600: #696f79;
	--grayscale-700: #474d58;
	--grayscale-800: #282e38;
	--grayscale-900: #15181f;
	--grayscale-950: #0b0d12;

	--white: #ffffff;
}

/* ---------- Brand ----------
   The colors of NASA's launch entry suit (the "pumpkin suit"): international
   orange fabric against a studio-blue backdrop, a blue-black helmet, a white
   liner. Photo: docs/launch-entry-suit.webp. Each names a primitive; use them
   for brand assets, and let components use the semantic tokens below. */
:root {
	--suit-orange: var(--orange-500);        /* international orange (aerospace) */
	--suit-orange-shade: var(--orange-600);  /* the fabric in its lit folds */
	--helmet: var(--grayscale-950);          /* helmet and boots: a blue-black */
	--backdrop-deep: var(--blue-700);        /* studio backdrop, floor */
	--backdrop-light: var(--blue-500);       /* studio backdrop, where the light hits */
	--liner: var(--grayscale-100);           /* helmet liner and visor white */
}

/* ---------- Semantic color ----------
   What components use. Night is the default. Day overrides the same tokens.
   The theme comes from the system unless the visitor picks one with the toggle
   (data-theme on <html>, set before first paint). Contrast ratios are against
   --canvas. The selectors also work on any element, so docs/index.html can show
   both themes side by side. */
:root,
[data-theme="dark"] {
	--canvas: var(--helmet);                 /* the helmet's blue-black */
	--surface: var(--grayscale-900);         /* cards, popovers, buttons */
	--surface-hover: var(--grayscale-800);
	--line: var(--grayscale-800);            /* hairlines, decoration only (1.4:1) */
	--text: var(--liner);                    /* 17.4:1 */
	--muted: var(--grayscale-400);           /* 8.7:1, descriptions, labels, tags */
	--faint: var(--muted);                   /* two text colors only (text and muted); kept for decoration */
	--accent: var(--suit-orange);            /* 5.9:1, pixel details and small highlights */
	--accent-ink: var(--suit-orange);        /* orange that has to pass as text */
	--on-accent: var(--helmet);              /* text on an orange fill (5.9:1) */
	--blue: var(--backdrop-light);           /* 6.5:1, a cool supporting color, used sparingly */
	--mention: var(--text);                  /* mention names at rest */
	--ring: rgb(255 255 255 / 0.06);
	--ring-hover: rgb(255 255 255 / 0.1);
	--shadow-card: 0 1px 2px -1px rgb(0 0 0 / 0.5), 0 2px 4px 0 rgb(0 0 0 / 0.3);
	--shadow-card-hover: 0 2px 4px -1px rgb(0 0 0 / 0.6), 0 6px 12px -2px rgb(0 0 0 / 0.4);
	--shadow-pop: 0 8px 24px -8px rgb(0 0 0 / 0.6);

	color-scheme: dark;
}

[data-theme="light"] {
	--canvas: var(--grayscale-100);
	--surface: var(--white);
	--surface-hover: var(--grayscale-50);
	--line: var(--grayscale-200);
	--text: var(--helmet);                   /* 17.4:1 */
	--muted: var(--grayscale-700);           /* 7.6:1 */
	--faint: var(--muted);
	--accent: var(--suit-orange);            /* 2.95:1: fills and pixels; large type falls just short of 3:1 */
	--accent-ink: var(--suit-orange-shade);  /* 4.9:1, orange for text */
	--on-accent: var(--helmet);
	--blue: var(--backdrop-deep);            /* 7.5:1 */
	--mention: var(--muted);                 /* by day, lighter so mentions don't outweigh the company names */
	--ring: rgb(0 0 0 / 0.07);
	--ring-hover: rgb(0 0 0 / 0.12);
	--shadow-card: 0 1px 2px -1px rgb(0 0 0 / 0.06), 0 2px 4px 0 rgb(0 0 0 / 0.04);
	--shadow-card-hover: 0 2px 4px -1px rgb(0 0 0 / 0.08), 0 6px 12px -2px rgb(0 0 0 / 0.06);
	--shadow-pop: 0 8px 24px -8px rgb(0 0 0 / 0.15);

	color-scheme: light;
}

/* ---------- Base unit ----------
   Launch Suit DS is base 12. Sizes, leading, space and radii are built from
   --unit (12px): multiples of it, or its thirds (4, 8) for small steps, because
   12 divides cleanly into halves, thirds and quarters. Space has no 16: what
   is 8 and 16 elsewhere is 8 and 12 here. Hairlines and pixel art (twinkle
   cells, sprites) keep their own pixel grid. Shared with the CV. */
:root {
	--unit: 12px;
}

/* ---------- Type ----------
   Shared with the CV (2026-09-27): IBM Plex Sans for everything, IBM Plex Mono
   caps for section labels, Newsreader italic for emphasis and the role line.
   On screen, Redaction 50 Italic for the name and company names and Redaction
   70 for "Coming soon" keep the pixel texture. The @font-face rules live in
   fonts.css. Sizes and leading sit on multiples of 4, the unit's thirds: 12,
   16, 20, 24, 28, 32. This is the starting grid; the type scale itself gets tuned later. */
:root {
	--font-sans: "IBM Plex Sans", system-ui, sans-serif;
	--font-mono: "IBM Plex Mono", ui-monospace, monospace;
	--font-serif: "Newsreader Text", Georgia, serif;           /* italic only: emphasis, project titles */
	--font-serif-display: "Newsreader Display", "Newsreader Text", Georgia, serif; /* italic only: large serif display (the CV's name and organization names) */
	--font-display: "Redaction 50", "Newsreader Text", Georgia, serif;
	--font-pixel: "Redaction 70", "Newsreader Text", Georgia, serif;
	--tracking: -0.004em;
	--size-small: var(--unit);                     /* 12px: buttons, popovers, "+N more", section labels */
	--size-tag: var(--unit);                       /* 12px: tags, set apart by weight 500 */
	--size-body: calc(var(--unit) * 4 / 3);        /* 16px */
	--size-heading: calc(var(--unit) * 5 / 3);     /* 20px: company names, always smaller than the name */
	--size-display: calc(var(--unit) * 7 / 3);     /* 28px: the name; counts as large text (3:1 needed; suit orange is 2.95:1 on the day canvas) */
	--size-display-l: calc(var(--unit) * 2);       /* 24px: "Coming soon" */
	--leading-small: calc(var(--unit) * 5 / 3);    /* 20px */
	--leading: calc(var(--unit) * 2);              /* 24px */
	--leading-display: calc(var(--unit) * 8 / 3);  /* 32px: the name */
	--italic-boost: 1.12;                          /* Newsreader italic runs small next to a grotesk; tuned for Geist, retune for Plex (PKS-32) */
}

/* ---------- Space, layout, radii, motion ---------- */
:root {
	--space-3xs: calc(var(--unit) / 6);            /* 2px: hairline nudges only */
	--space-2xs: calc(var(--unit) / 3);            /* 4px */
	--space-xs: calc(var(--unit) * 2 / 3);         /* 8px */
	--space-s: var(--unit);                        /* 12px */
	--space-m: calc(var(--unit) * 2);              /* 24px */
	--space-l: calc(var(--unit) * 3);              /* 36px */
	--space-xl: calc(var(--unit) * 4);             /* 48px */
	--space-2xl: calc(var(--unit) * 6);            /* 72px */
	--space-3xl: calc(var(--unit) * 8);            /* 96px */

	/* Deprecated: the old 4px-based names, mapped to the nearest base-12 step so
	   existing sites keep working. Use the names above; a later minor release
	   removes these. */
	--space-1: var(--space-2xs);
	--space-2: var(--space-xs);
	--space-3: var(--space-s);
	--space-4: var(--space-s);                     /* was 16px */
	--space-6: var(--space-m);
	--space-8: var(--space-l);                     /* was 32px */
	--space-12: var(--space-xl);
	--space-16: var(--space-2xl);                  /* was 64px */
	--space-24: var(--space-3xl);

	--column: calc(var(--unit) * 48);             /* 576px */

	--radius-pill: 999px;
	--radius-card: var(--unit);                    /* 12px */
	--radius-card-inner: calc(var(--unit) * 2 / 3); /* 8px: the card radius minus a 4px inset */
	--radius-icon: calc(var(--unit) * 2 / 3);     /* 8px */

	--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
	--duration-fast: 150ms;
	--duration: 200ms;
}
