/* Design tokens and fonts, shared by every page a browser renders.
 *
 * The landing page (static/index.html) and the dashboard both link this: it is
 * the one place the palette, the font stacks, the @font-face declarations and
 * the border-box reset live. Page-specific rules go in that page's own file
 * (landing.css, and later dashboard.css) so this stays small and stable.
 *
 * Served by nginx from /assets/ — see nginx/snippets/location-assets.conf.
 */

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/dm-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/dm-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- the palette ----------------------------------------------------------
 *
 * Every colour a page uses is a custom property declared HERE and nowhere else.
 * A page stylesheet that writes a literal is a colour that cannot be themed and
 * that drifts the first time someone edits the other copy — which is what
 * happened to this project: dashboard.css once carried 73 hex literals, and
 * making the dashboard light meant touching every one of them.
 *
 * There are two palettes, because the product deliberately has two surfaces:
 * the marketing page and the top bar are dark, and the product UI inside the
 * bar is light. The dark set is the default; `body.dashboard` swaps in the light
 * one. See "Two palettes" in docs/design.md.
 *
 * Names are roles, not colours. `--quiet` is "a label, quieter than body text",
 * which is a decision that survives a repaint; `--grey-600` is not.
 */
:root {
  /* Surfaces. `--soft` is the louder panel and `--panel` the ordinary one;
     `--field-bg` and `--code-bg` start at the same dark value here but are
     separate tokens because a light input wants to be white and a light code
     block wants a tint. */
  --bg: #080808;
  --panel: #101010;
  --soft: #161616;
  --field-bg: #0b0b0b;
  --field-bg-readonly: #101010;
  --code-bg: #0b0b0b;
  --notice-bg: #121212;
  --mark-bg: #151515;

  /* Text, quietest last. */
  --fg: #f2f2ef;
  --muted: #858585;
  --quiet: #6f6f6f;
  --faint: #555555;
  --link: #9a9a9a;

  /* Lines: structural, then the hairline between rows, then the border of a
     control or a chip. */
  --line: #292929;
  --hairline: #161616;
  --edge: #3a3a3a;
  --chip-line: #3a3a3a;
  --control: #414141;
  --field-line: #333333;
  --code-line: #333333;
  --mark-line: #2b2b2b;

  /* Fills that carry no meaning: an idle dot, an empty bar. */
  --idle: #3a3a3a;
  --bar-idle: #262626;

  /* Controls. */
  --button-fg: #bbbbbb;
  --notice-fg: #bbbbbb;
  --notice-line: #555555;
  --tag-fg: #b9b9b9;
  --accent-bg: #eeeeee;
  --accent-fg: #080808;
  --accent-line: #eeeeee;
  --focus: #6a6a6a;

  /* Status. Each one is a pair — a text colour and the border or bar that goes
     with it — plus a glow for the dot's halo. */
  --ok-fg: #7fb98d;
  --ok-line: #2f5a38;
  --ok-bar: #3f6a4a;
  --ok-glow: rgba(127, 185, 141, 0.13);
  --bad-fg: #d08a72;
  --bad-line: #6a3a2c;
  --bad-bar: #7a4436;
  --bad-strong: #c0664f;
  --bad-glow: rgba(208, 138, 114, 0.13);
  --bad-notice-fg: #e0a190;
  --bad-notice-line: #a8492f;
  --good-notice-fg: #9fc9a8;
  --good-notice-line: #2f5a38;
  --warn-fg: #d8c07a;
  --warn-line: #5c4e26;
  --warn-glow: rgba(216, 192, 122, 0.13);
}

/* Corner radii, one scale for both palettes. Small on purpose: this is a dense
   product UI, and a large radius on a 1px-bordered surface eats the border it
   sits inside and makes a table row look like a pill. Three steps is the whole
   scale — if a fourth is ever needed, the third was wrong.

   --r-sm  tags, badges, the histogram bars
   --r     buttons, inputs, notices, code blocks, the flash of a focused field
   --r-lg  panels, cards, the product shot */
:root{--r-sm:3px;--r:6px;--r-lg:10px}

/* The product UI is light. Everything inside the top bar is not — a dark chrome
   bar over a light workspace is the shape the product wants: the bar is brand
   and navigation, the page is where data lives, and data reads better dark-on-
   light at this density.

   Scoped to `body.dashboard`, which only base.html sets. The landing page keeps
   the dark default because it has no such class; it is a pitch, not a workspace. */
body.dashboard {
  --bg: #ffffff;
  --panel: #ffffff;
  --soft: #f7f7f7;
  --field-bg: #ffffff;
  --field-bg-readonly: #f6f6f6;
  --code-bg: #f6f8fa;
  --notice-bg: #f8f8f8;
  --mark-bg: #f2f2f2;

  --fg: #111111;
  --muted: #5f5f5f;
  --quiet: #6b6b6b;
  --faint: #767676;
  --link: #4a4a4a;

  --line: #e5e5e5;
  --hairline: #f0f0f0;
  --edge: #c9c9c9;
  --chip-line: #d8d8d8;
  --control: #c9c9c9;
  --field-line: #d0d0d0;
  --code-line: #e1e4e8;
  --mark-line: #dcdcdc;

  --idle: #b0b0b0;
  --bar-idle: #d9d9d9;

  --button-fg: #444444;
  --notice-fg: #444444;
  --notice-line: #d0d0d0;
  --tag-fg: #444444;
  /* The primary button inverts: on a dark page the loudest thing is a white
     fill, on a light one it is a near-black one. */
  --accent-bg: #111111;
  --accent-fg: #ffffff;
  --accent-line: #111111;
  --focus: #111111;

  --ok-fg: #0f6b2f;
  --ok-line: #b7dfc0;
  /* The bars are mid-tones rather than the dark palette's muted greens: on
     white, a bar has to clear 3:1 against its background or the histogram stops
     being readable at a glance, which is the only reason it exists. The dark
     values could be quieter because a light bar on black is already visible. */
  --ok-bar: #4c9a63;
  --ok-glow: rgba(15, 107, 47, 0.12);
  --bad-fg: #b3261e;
  --bad-line: #f0c2b8;
  --bad-bar: #cf6b55;
  --bad-strong: #b3261e;
  --bad-glow: rgba(179, 38, 30, 0.12);
  --bad-notice-fg: #a3372a;
  --bad-notice-line: #c0392b;
  --good-notice-fg: #0f6b2f;
  --good-notice-line: #1a7f37;
  --warn-fg: #8a6116;
  --warn-line: #e6d5a8;
  --warn-glow: rgba(138, 97, 22, 0.12);
}

/* The chrome bar keeps the dark palette inside a light page, so the tokens the
   header reads are re-pinned to their dark values. Declared as tokens rather
   than as colours on each rule for the same reason as everything above: the
   header's `.linkish` sign-out and its focus ring have to stay legible on the
   dark bar, and `--link` is now a dark grey meant for a white page. */
body.dashboard .topbar {
  --bg: #080808;
  --fg: #f2f2ef;
  --muted: #858585;
  --line: #292929;
  --soft: #161616;
  --link: #9a9a9a;
  --focus: #6a6a6a;
  background: var(--bg);
}

/* The page baseline. Shared, not landing-specific: the dashboard links this
   file too, and a baseline that lives in one page's stylesheet renders the
   other on white with browser-default serif — which is exactly what happened
   when this rule lived in landing.css. */
/* Every box sizes from its border, so `width: 100%` means the whole container
   rather than the container plus the control's own padding — the dashboard's
   full-width button and inputs (dashboard.css has no reset of its own) used to
   poke 36px out of their card. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: 'Space Grotesk', sans-serif;
  overflow-x: hidden;
}

/* Phone browsers inflate text to their own judgement when a phone is turned to
   landscape; every width here is already chosen in media queries, so the
   inflation only breaks line lengths the layout had already settled. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}
