/* ===========================================================================
   pulse-design-tokens.css
   The visual system the prototypes were built from, extracted.

   Every value here already appears in the prototypes as a literal. This file
   is the layer that should have shipped with them — it is not a new design.

   CORRECTED AFTER APPLICATION. An earlier version of this note said "load
   once and everything inherits". That is false in this app and cost a round
   trip, so read this instead:

   THE APP DOES NOT READ --pulse-*. Each user's skin is written inline on
   <body>, which wins over anything declared here. Loading this file alone
   changes nothing.

   IT WORKS VIA A BRIDGE. pulse-theme.css registers a skin preset and maps
   the app's own tokens onto body. That bridge is what moves the screens;
   this file is the source of truth the bridge points at.

   THE BRIDGE MUST DEREFERENCE, NEVER DUPLICATE. Write
   --app-radius: var(--pulse-r-panel), not --app-radius: 12px. A bridge
   carrying its own hex and radius values is a second copy of the design
   system, and it drifts the moment either side is touched -- corners came
   out 12px against the 11px below on the first application, which is that
   drift on day one.

   THE CEILING. ~941 hard-coded hex colours in app.css do not follow tokens
   and cannot be reached from here. This layer governs what is tokenised;
   the rest is a per-file job and should be counted separately rather than
   assumed covered.

   Light skins: see the block at the end, same preset convention as
   build-launch.css.
   =========================================================================== */

:root {
  /* PILLAR COLOURS. Each channel owns one hue, used for its dot, its channel
     label and nothing else. None may equal a state colour (teal = ok,
     amber = attention, red = broken), or a pillar reads as a status. */
  --pulse-pillar-live: oklch(0.80 0.11 210);
  --pulse-pillar-text: oklch(0.74 0.12 255);
  --pulse-pillar-robo: oklch(0.74 0.13 300);
  --pulse-pillar-web:  oklch(0.76 0.13 355);
  --pulse-pillar-ultimate: #aebbd0;

  /* CLIENT COLOURS (R12.2). Twelve categorical hues, 30 degrees apart with
     alternating lightness so neighbours still separate. A client and all of
     its subclients wear the same one (app/PulseClientColor.php hashes the
     client id onto an index); they mark WHO, never a state, and only ever
     appear as a small swatch beside a name that carries the meaning. */
  --pulse-client-0: oklch(0.78 0.13 25);
  --pulse-client-1: oklch(0.7 0.14 55);
  --pulse-client-2: oklch(0.78 0.13 85);
  --pulse-client-3: oklch(0.7 0.14 115);
  --pulse-client-4: oklch(0.78 0.13 145);
  --pulse-client-5: oklch(0.7 0.14 175);
  --pulse-client-6: oklch(0.78 0.13 205);
  --pulse-client-7: oklch(0.7 0.14 235);
  --pulse-client-8: oklch(0.78 0.13 265);
  --pulse-client-9: oklch(0.7 0.14 295);
  --pulse-client-10: oklch(0.78 0.13 325);
  --pulse-client-11: oklch(0.7 0.14 355);

  /* --- surfaces, darkest to lightest ------------------------------------ */
  --pulse-bg:        #0c1418;                 /* page */
  --pulse-well:      oklch(0.14 0.012 215);   /* inset: script text, code, quoted content */
  --pulse-panel:     oklch(0.185 0.014 213);  /* the default card */
  --pulse-panel-2:   oklch(0.21 0.016 212);   /* raised: chips, table headers, nested cards */
  --pulse-rail:      oklch(0.155 0.013 215);  /* left nav */

  /* --- lines ------------------------------------------------------------ */
  --pulse-line:      oklch(0.28 0.018 210);   /* borders */
  --pulse-line-soft: oklch(0.25 0.016 210);   /* row dividers inside a panel */

  /* --- ink, three levels and no more ------------------------------------ */
  --pulse-ink:       oklch(0.95 0.008 210);   /* headings, primary values */
  --pulse-ink-2:     oklch(0.82 0.012 210);   /* body */
  --pulse-ink-3:     oklch(0.62 0.015 210);   /* labels, kickers, metadata */

  /* --- meaning. these four carry state everywhere in the product --------- */
  --pulse-teal:      oklch(0.84 0.13 172);    /* good, done, ours-is-fine */
  --pulse-amber:     oklch(0.82 0.13 75);     /* unproven, held, not-a-result */
  --pulse-red:       oklch(0.70 0.16 20);     /* blocking, failed, irreversible */
  --pulse-blue:      oklch(0.74 0.10 240);    /* informational, someone else's move */
  --pulse-violet:    oklch(0.74 0.11 300);    /* internal-only, specification */

  /* --- brand ------------------------------------------------------------ */
  --pulse-brand:     oklch(0.78 0.13 178);    /* the period in PULSE. — never anything else */

  /* --- action. the button colour, and the last value the bridge duplicated.
     Deliberately NOT --pulse-brand: the brand teal is the wordmark's period
     and appears once per screen. An accent is pressed dozens of times an
     hour, and sharing one value means a brand tweak silently restyles every
     control in the product. */
  --pulse-action:         oklch(0.30 0.05 178);   /* primary button fill */
  --pulse-action-edge:    oklch(0.50 0.08 178);
  --pulse-action-ink:     oklch(0.97 0.04 182);
  --pulse-action-hover:   oklch(0.35 0.06 178);

  /* Destructive. A separate token, not a modifier of the one above, because
     it must be able to WIN: a general button rule that repaints Pause and
     Stop teal is a screen that hides its own brakes. */
  --pulse-danger:         oklch(0.34 0.10 22);
  --pulse-danger-edge:    oklch(0.54 0.14 22);
  --pulse-danger-ink:     oklch(0.96 0.05 25);
  --pulse-danger-hover:   oklch(0.39 0.12 22);

  /* Quiet / secondary: cancel, dismiss, tertiary nav. */
  --pulse-quiet:          oklch(0.22 0.016 212);
  --pulse-quiet-edge:     oklch(0.34 0.02 210);
  --pulse-quiet-ink:      oklch(0.84 0.012 210);

  /* --- tonal fills + matching borders -----------------------------------
     Used for banners and state panels. Fill and border always pair; using a
     fill with a neutral border is what makes a state panel look accidental. */
  --pulse-teal-fill:   oklch(0.19 0.03 172 / 0.30);
  --pulse-teal-edge:   oklch(0.44 0.07 172);
  --pulse-amber-fill:  oklch(0.22 0.05 78 / 0.26);
  --pulse-amber-edge:  oklch(0.48 0.08 78);
  --pulse-red-fill:    oklch(0.22 0.045 22 / 0.28);
  --pulse-red-edge:    oklch(0.48 0.10 22);
  --pulse-blue-fill:   oklch(0.20 0.03 240 / 0.34);
  --pulse-blue-edge:   oklch(0.42 0.06 240);
  --pulse-violet-fill: oklch(0.24 0.05 300 / 0.34);
  --pulse-violet-edge: oklch(0.46 0.08 300);

  /* --- chips: fill, ink, border, per state ------------------------------- */
  --pulse-chip-teal-fill:  oklch(0.30 0.06 170);
  --pulse-chip-teal-ink:   oklch(0.92 0.10 175);
  --pulse-chip-amber-fill: oklch(0.30 0.06 78);
  --pulse-chip-amber-ink:  oklch(0.92 0.10 80);
  --pulse-chip-red-fill:   oklch(0.30 0.07 24);
  --pulse-chip-red-ink:    oklch(0.92 0.09 26);
  --pulse-chip-neutral-fill: oklch(0.24 0.018 212);
  --pulse-chip-neutral-ink:  oklch(0.82 0.012 210);

  /* --- type ------------------------------------------------------------- */
  --pulse-sans: 'Instrument Sans', system-ui, sans-serif;
  --pulse-mono: 'JetBrains Mono', ui-monospace, monospace;

  --pulse-t-kicker:  10px;    /* mono, uppercase, 0.10em — the label above everything */
  --pulse-t-micro:   11.5px;  /* notes under a value */
  --pulse-t-body:    12.5px;  /* dense body: table cells, card copy */
  --pulse-t-read:    13.5px;  /* readable body: paragraphs */
  --pulse-t-lead:    15px;    /* section lead paragraph */
  --pulse-t-h3:      17px;
  --pulse-t-h2:      21px;
  --pulse-t-h1:      30px;
  --pulse-t-stat:    26px;    /* a number that is the point of its card */
  --pulse-t-stat-lg: 32px;

  --pulse-track-kicker: 0.10em;
  --pulse-track-tight:  -0.02em;   /* h2, h3 */
  --pulse-track-h1:     -0.03em;
  --pulse-track-stat:   -0.03em;

  /* --- spacing. eight steps, and resist adding a ninth ------------------- */
  --pulse-s1: 4px;
  --pulse-s2: 8px;
  --pulse-s3: 12px;
  --pulse-s4: 16px;
  --pulse-s5: 20px;
  --pulse-s6: 26px;
  --pulse-s7: 34px;
  --pulse-s8: 42px;

  /* --- radius ----------------------------------------------------------- */
  --pulse-r-chip:    6px;
  --pulse-r-inner:   9px;    /* a card inside a card */
  --pulse-r-panel:   11px;
  --pulse-r-section: 12px;
  --pulse-r-pill:    999px;
}

/* ===========================================================================
   Components. Eight of them. Everything in the prototypes is one of these or
   a composition of two.
   =========================================================================== */

body {
  margin: 0;
  background: var(--pulse-bg);
  color: var(--pulse-ink);
  font-family: var(--pulse-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a         { color: oklch(0.80 0.10 190); text-decoration: none; }
a:hover   { color: oklch(0.90 0.11 190); }

/* 1. KICKER — the mono label above a heading, a card, a column.
      The single most load-bearing element in the visual system: it is what
      makes a dense screen scannable without adding prose. */
.p-kicker {
  font-family: var(--pulse-mono);
  font-size: var(--pulse-t-kicker);
  letter-spacing: var(--pulse-track-kicker);
  text-transform: uppercase;
  color: var(--pulse-ink-3);
}
.p-kicker--teal   { color: var(--pulse-teal); }
.p-kicker--amber  { color: var(--pulse-amber); }
.p-kicker--red    { color: oklch(0.86 0.10 25); }
.p-kicker--blue   { color: oklch(0.82 0.10 240); }
.p-kicker--violet { color: oklch(0.88 0.09 300); }

/* 2. PANEL — the default container. */
.p-panel {
  background: var(--pulse-panel);
  border: 1px solid var(--pulse-line);
  border-radius: var(--pulse-r-panel);
  padding: var(--pulse-s4) 18px;
}
.p-panel--flush { padding: 0; overflow: hidden; }   /* for tables */

/* 3. NOTE — a tonal panel that carries state. Fill and edge always paired. */
.p-note {
  border-radius: var(--pulse-r-panel);
  padding: var(--pulse-s4) 18px;
  border: 1px solid var(--pulse-line);
  background: var(--pulse-panel);
}
.p-note--teal   { background: var(--pulse-teal-fill);   border-color: var(--pulse-teal-edge); }
.p-note--amber  { background: var(--pulse-amber-fill);  border-color: var(--pulse-amber-edge); }
.p-note--red    { background: var(--pulse-red-fill);    border-color: var(--pulse-red-edge); }
.p-note--blue   { background: var(--pulse-blue-fill);   border-color: var(--pulse-blue-edge); }
.p-note--violet { background: var(--pulse-violet-fill); border-color: var(--pulse-violet-edge); }

/* 4. CHIP — status, code, badge. */
.p-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--pulse-s2);
  font-family: var(--pulse-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  padding: 3px 10px;
  border-radius: var(--pulse-r-chip);
  background: var(--pulse-chip-neutral-fill);
  color: var(--pulse-chip-neutral-ink);
  border: 1px solid var(--pulse-line);
  white-space: nowrap;
}
.p-chip--teal  { background: var(--pulse-chip-teal-fill);  color: var(--pulse-chip-teal-ink);  border-color: var(--pulse-teal-edge); }
.p-chip--amber { background: var(--pulse-chip-amber-fill); color: var(--pulse-chip-amber-ink); border-color: var(--pulse-amber-edge); }
.p-chip--red   { background: var(--pulse-chip-red-fill);   color: var(--pulse-chip-red-ink);   border-color: var(--pulse-red-edge); }
.p-chip--pill  { border-radius: var(--pulse-r-pill); padding: 5px 12px; }

/* 5. STAT — a number that is the point, with its label above and note below. */
.p-stat__label { font-family: var(--pulse-mono); font-size: 9.5px; letter-spacing: var(--pulse-track-kicker); color: var(--pulse-ink-3); }
.p-stat__value { font-size: var(--pulse-t-stat); font-weight: 600; letter-spacing: var(--pulse-track-stat); font-variant-numeric: tabular-nums; margin-top: var(--pulse-s1); }
.p-stat__note  { font-size: var(--pulse-t-micro); color: var(--pulse-ink-3); margin-top: 3px; text-wrap: pretty; }

/* 6. ROW — a list item inside a panel, optionally state-edged on the left. */
.p-row {
  display: grid;
  gap: var(--pulse-s3);
  align-items: baseline;
  padding: var(--pulse-s3) 0;
  border-top: 1px solid var(--pulse-line-soft);
}
.p-row--carded {
  border: 1px solid var(--pulse-line);
  border-left-width: 3px;
  border-radius: var(--pulse-r-inner);
  padding: var(--pulse-s3) 14px;
  background: var(--pulse-panel-2);
}
.p-row--teal  { border-left-color: var(--pulse-teal); }
.p-row--amber { border-left-color: var(--pulse-amber); }
.p-row--red   { border-left-color: var(--pulse-red); }
.p-row--blue  { border-left-color: var(--pulse-blue); }

/* 7. TABLE — header row is mono kickers on a raised surface. */
.p-table__head {
  display: grid;
  gap: var(--pulse-s3);
  padding: var(--pulse-s3) 18px;
  background: var(--pulse-panel-2);
  font-family: var(--pulse-mono);
  font-size: 9px;
  letter-spacing: var(--pulse-track-kicker);
  text-transform: uppercase;
  color: var(--pulse-ink-3);
}
.p-table__row {
  display: grid;
  gap: var(--pulse-s3);
  padding: var(--pulse-s3) 18px;
  border-top: 1px solid var(--pulse-line-soft);
  align-items: baseline;
}
.p-num { font-family: var(--pulse-mono); font-variant-numeric: tabular-nums; text-align: right; }

/* 8. WELL — inset surface for quoted content: script text, a message body,
      a code-ish value. Goes DARKER than its parent on dark skins. */
.p-well {
  background: var(--pulse-well);
  border: 1px solid var(--pulse-line-soft);
  border-radius: var(--pulse-r-inner);
  padding: var(--pulse-s3) 14px;
}

/* 9. BUTTON — three intents. Destructive is a peer of primary, never a
      variant of it, and carries higher specificity so a general button rule
      cannot repaint it. */
.p-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--pulse-s2);
  font-family: var(--pulse-sans);
  font-size: 13px;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: var(--pulse-r-inner);
  cursor: pointer;
  background: var(--pulse-quiet);
  border: 1px solid var(--pulse-quiet-edge);
  color: var(--pulse-quiet-ink);
}
.p-btn:hover { filter: brightness(1.15); }

.p-btn.p-btn--primary {
  background: var(--pulse-action);
  border-color: var(--pulse-action-edge);
  color: var(--pulse-action-ink);
}
.p-btn.p-btn--primary:hover { background: var(--pulse-action-hover); }

/* Doubled class: specificity 0,2,0 beats a single-class theme button rule
   without !important. Pause and Stop stay red. */
.p-btn.p-btn--danger,
button.p-btn--danger {
  background: var(--pulse-danger);
  border-color: var(--pulse-danger-edge);
  color: var(--pulse-danger-ink);
}
.p-btn.p-btn--danger:hover,
button.p-btn--danger:hover { background: var(--pulse-danger-hover); }

/* Disabled. Lives here beside the component rather than in a pillar sheet --
   styling a token-file component from elsewhere is the drift this file's own
   contract forbids. Additive selector, not a redefinition.

   Without it every disabled control in the product renders as a live one, and
   the worst case is a disabled Stop that looks exactly like a live Stop. The
   doubled class keeps this above .p-btn--danger, which is itself specificity
   0,2,0 -- a disabled destructive button must read disabled, not destructive.

   The :hover reset is required: .p-btn:hover brightens, so without it a
   disabled control lights up under the cursor and invites the click. */
.p-btn:disabled,
.p-btn:disabled.p-btn--primary,
.p-btn:disabled.p-btn--danger,
.p-btn[aria-disabled="true"] {
  background: var(--pulse-quiet);
  border-color: var(--pulse-quiet-edge);
  color: var(--pulse-ink-3);
  cursor: not-allowed;
}
.p-btn:disabled:hover,
.p-btn[aria-disabled="true"]:hover { filter: none; }

/* --- headings ----------------------------------------------------------- */
.p-h1 { margin: 0; font-size: var(--pulse-t-h1); font-weight: 600; letter-spacing: var(--pulse-track-h1); }
.p-h2 { margin: 0; font-size: var(--pulse-t-h2); font-weight: 600; letter-spacing: var(--pulse-track-tight); }
.p-h3 { margin: 0; font-size: var(--pulse-t-h3); font-weight: 600; letter-spacing: var(--pulse-track-tight); }
.p-lead { margin: 0; font-size: var(--pulse-t-lead); color: var(--pulse-ink-2); max-width: 86ch; text-wrap: pretty; }
.p-body { font-size: var(--pulse-t-read); color: var(--pulse-ink-2); text-wrap: pretty; }
.p-dense { font-size: var(--pulse-t-body); color: var(--pulse-ink-2); text-wrap: pretty; }

/* --- the wordmark. See LOGO_HANDOFF.md; these are the only correct values. */
.p-wordmark { font-weight: 700; letter-spacing: -0.03em; color: var(--pulse-ink); }
.p-wordmark__dot { letter-spacing: normal; margin-left: 0.06em; color: var(--pulse-brand); }
/* Monochrome contexts (teal flood, single-ink print): both parts take the ink.
   Never invert — the word is ink, the period is teal or the whole mark is one colour. */
.p-wordmark--mono, .p-wordmark--mono .p-wordmark__dot { color: inherit; }

/* ===========================================================================
   Light skins — token overrides only. Same preset convention as
   build-launch.css. Every component above inherits without change.
   =========================================================================== */

body[data-skin-preset="light"],
body[data-skin-preset="sand"],
body[data-skin-preset="coastal_mist"],
body[data-skin-preset="warm_linen"],
body[data-skin-preset="sage_glass"] {
  --pulse-bg:        oklch(0.97 0.004 240);
  --pulse-well:      oklch(1 0 0);              /* inset goes LIGHTER than its parent here */
  --pulse-panel:     oklch(0.985 0.003 240);
  --pulse-panel-2:   oklch(0.95 0.005 240);
  --pulse-rail:      oklch(0.96 0.004 240);

  --pulse-line:      oklch(0.87 0.008 240);
  --pulse-line-soft: oklch(0.92 0.006 240);

  --pulse-ink:       oklch(0.24 0.02 240);
  --pulse-ink-2:     oklch(0.42 0.015 240);
  --pulse-ink-3:     oklch(0.50 0.015 240);

  --pulse-teal:      oklch(0.48 0.12 168);
  --pulse-amber:     oklch(0.52 0.12 62);
  --pulse-red:       oklch(0.52 0.19 25);
  --pulse-blue:      oklch(0.48 0.13 250);
  --pulse-violet:    oklch(0.48 0.14 300);
  --pulse-brand:     oklch(0.62 0.14 178);

  /* client colours, darker for light surfaces (R12.2) */
  --pulse-client-0: oklch(0.52 0.15 25);
  --pulse-client-1: oklch(0.6 0.15 55);
  --pulse-client-2: oklch(0.52 0.15 85);
  --pulse-client-3: oklch(0.6 0.15 115);
  --pulse-client-4: oklch(0.52 0.15 145);
  --pulse-client-5: oklch(0.6 0.15 175);
  --pulse-client-6: oklch(0.52 0.15 205);
  --pulse-client-7: oklch(0.6 0.15 235);
  --pulse-client-8: oklch(0.52 0.15 265);
  --pulse-client-9: oklch(0.6 0.15 295);
  --pulse-client-10: oklch(0.52 0.15 325);
  --pulse-client-11: oklch(0.6 0.15 355);

  --pulse-teal-fill:   oklch(0.95 0.04 168);   --pulse-teal-edge:   oklch(0.74 0.09 168);
  --pulse-amber-fill:  oklch(0.96 0.04 80);    --pulse-amber-edge:  oklch(0.78 0.10 75);
  --pulse-red-fill:    oklch(0.96 0.03 25);    --pulse-red-edge:    oklch(0.76 0.12 25);
  --pulse-blue-fill:   oklch(0.96 0.03 250);   --pulse-blue-edge:   oklch(0.76 0.09 250);
  --pulse-violet-fill: oklch(0.96 0.03 300);   --pulse-violet-edge: oklch(0.76 0.09 300);

  --pulse-chip-teal-fill:  oklch(0.94 0.05 168); --pulse-chip-teal-ink:  oklch(0.34 0.11 168);
  --pulse-chip-amber-fill: oklch(0.93 0.07 80);  --pulse-chip-amber-ink: oklch(0.38 0.10 62);
  --pulse-chip-red-fill:   oklch(0.92 0.06 25);  --pulse-chip-red-ink:   oklch(0.38 0.16 25);
  --pulse-chip-neutral-fill: oklch(0.94 0.005 240); --pulse-chip-neutral-ink: oklch(0.36 0.015 240);

  --pulse-action:       oklch(0.52 0.11 178);  --pulse-action-edge:  oklch(0.44 0.10 178);
  --pulse-action-ink:   oklch(0.99 0.01 180);  --pulse-action-hover: oklch(0.46 0.11 178);
  --pulse-danger:       oklch(0.52 0.19 25);   --pulse-danger-edge:  oklch(0.44 0.18 25);
  --pulse-danger-ink:   oklch(0.99 0.01 25);   --pulse-danger-hover: oklch(0.46 0.19 25);
  --pulse-quiet:        oklch(0.95 0.005 240); --pulse-quiet-edge:   oklch(0.85 0.008 240);
  --pulse-quiet-ink:    oklch(0.32 0.015 240);
}
