/* Swarm design tokens — the Evidence Bundle world. OKLCH only.
   Light is default (the 9am office); dark is the 8pm lift lobby.
   Materials, not greys: manila board, paper, blue-black ink, pink tape, gold seal.
   Do not add a value here that DESIGN.md does not document. */

@import url('https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300..800;1,400&family=Courier+Prime:ital,wght@0,400;0,700;1,400&display=swap');

:root {
  /* --- brand: gold is the exhibit seal and the primary action, nothing else --- */
  --gold: oklch(78% 0.15 78);
  --gold-ink: oklch(50% 0.13 78);        /* gold as text on paper */
  --gold-hover: oklch(83% 0.15 78);      /* seal under the hand */
  --gold-quiet: oklch(78% 0.15 78 / 0.14);
  --on-gold: oklch(22% 0.015 265);
  --focus: oklch(50% 0.13 78);

  /* --- tape: the barrister's tie. Structural marker, never decoration --- */
  --tape: oklch(66% 0.16 15);
  --tape-quiet: oklch(66% 0.16 15 / 0.12);
  /* Ink on a tape fill. It was a literal oklch(99% 0 0) until M6 first used the
     tape sticker — a pure neutral, which this system does not have (the No
     Neutral Grey Rule), and a colour check_contrast.py had never seen. */
  --on-tape: oklch(22% 0.015 265);

  /* --- annotation ink --- */
  --ink-blue: oklch(45% 0.15 265);

  /* --- ground and ink: LIGHT (default) ---
     Retuned in M8 from a saturated manila board (91% L, 0.024 C) to a warm
     near-white. The reason is not fashion, it is arithmetic: the old ground and
     the page were 7.5 points of lightness apart, which is a big step, and a big
     step reads as heavy. Every tool in this category — Wrike, Smartsheet, ClickUp
     — sits at a 2 to 3 point step and lets a hairline do the rest, which is why
     they look crisp and this looked like a folder.

     What is deliberately kept: the HUE. Every ground is still at 85, so nothing
     in here is a dead neutral grey (the No Neutral Grey Rule). Next to the gold
     it reads warm rather than clinical, which is the difference between "white"
     and "paper".

     What changes as a consequence: the hairline now carries more of the
     separation than the tonal step does. DESIGN.md always said depth is a step
     PLUS a hairline; the balance between the two has moved. --- */
  --canvas: oklch(97.2% 0.004 85);       /* the desk: warm near-white */
  --surface: oklch(99.4% 0.002 85);      /* the page, a shade lighter still */
  --sunken: oklch(94.6% 0.006 85);       /* divider stock, chips, insets */
  --text: oklch(22% 0.015 265);          /* blue-black ink, never neutral black */
  --body: oklch(32% 0.012 265);
  --muted: oklch(48% 0.010 265);
  --faint: oklch(47% 0.010 265);
  /* Darker than the old 78% relative to its ground, because it is doing more
     work now: on a near-white page a 78% rule is nearly invisible. */
  --hairline: oklch(87% 0.008 85);
  /* Three grounds now, each about a point and a half apart, hairlines doing the
     rest: the rail is the desk, the page area sits on it, and a list or a card is
     the sheet on top. That is the same paper-on-board idea the old manila ground
     had, played an octave quieter — and it is what makes Smartsheet and ClickUp
     read as crisp rather than flat. */
  --rail: oklch(96.1% 0.005 85);
  --solid-cta: oklch(22% 0.015 265);
  --solid-cta-ink: oklch(98.5% 0.005 85);

  /* --- status: colour is the third signal, after label and mark --- */
  --ok: oklch(45% 0.13 150);
  --attention: oklch(46% 0.13 70);
  --risk: oklch(48% 0.19 25);
  --neutral: var(--muted);


  /* --- the stages: a colour each ------------------------------------------
     Arvind: "Each stage has a colour code which users can identify with colours
     easily." He is right, and this does not break the Status rule — it completes
     it. The rule is mark, then label, then colour, in that order of load-bearing;
     it never said colour was forbidden, only that it must not be the ONLY thing
     carrying the fact. Every stage still has its own drawn mark and its own word.
     A person who cannot see the difference between 195 and 305 loses nothing.

     What the hues had to avoid: gold is 78 and belongs to the seal and the primary
     action (the Seal Rule), tape is 15, risk is 25, attention is 70. So the stage
     set lives in the arc from 150 round to 345 and never enters the reserved band.
     The two ends of the machine are the two colours everybody already knows:
     green is done, and the undecided end is barely a colour at all.

     Every value here was solved rather than picked. Each ink clears 4.5:1 on the
     page, the card, divider stock AND on its own tint — four grounds × seven
     stages × two modes, all of which check_contrast.py now asserts. --- */
  --st-triage:    oklch(47% 0.045 265);   /* nothing decided: nearly ink */
  --st-ready:     oklch(45% 0.100 195);   /* teal */
  --st-progress:  oklch(47% 0.140 250);   /* blue */
  --st-review:    oklch(48% 0.130 305);   /* violet */
  --st-approval:  oklch(49% 0.140 345);   /* magenta */
  --st-done:      oklch(45% 0.130 150);   /* green */
  --st-cancelled: oklch(47% 0.012 265);   /* the dead state: no colour to give */

  /* The tints are opaque, not alpha. A translucent tint is a different colour on
     every ground it lands on, which means the contrast checker can only ever
     measure one of them — and the board puts these on three. */
  --st-triage-bg:    oklch(93% 0.052 265);
  --st-ready-bg:     oklch(93% 0.052 195);
  --st-progress-bg:  oklch(93% 0.052 250);
  --st-review-bg:    oklch(93% 0.052 305);
  --st-approval-bg:  oklch(93% 0.052 345);
  --st-done-bg:      oklch(93% 0.052 150);
  --st-cancelled-bg: oklch(93% 0.016 265);

  /* --- depth: paper offset, not blur. Shadow only for what truly floats --- */
  --shadow-panel: 0 18px 44px oklch(22% 0.015 265 / 0.16);
  --shadow-cta: none;

  /* --- type: two faces. Public Sans is civic-document; Courier is the
         transcript. Courier carries evidence because court records are set
         in it — world-native, not a decorative mono. --- */
  --font-ui: 'Public Sans', system-ui, -apple-system, sans-serif;
  --font-display: 'Public Sans', system-ui, sans-serif;
  --font-mono: 'Courier Prime', Courier, monospace;

  --t-11: 0.6875rem; --t-12: 0.75rem;  --t-13: 0.8125rem; --t-14: 0.875rem;
  --t-16: 1rem;      --t-18: 1.125rem; --t-20: 1.25rem;   --t-24: 1.5rem;
  --t-28: 1.75rem;   --t-32: 2rem;     --t-40: 2.5rem;    --t-48: 3rem;

  /* --- space: 4 8 16 24 32 48 72. Document margins are regular --- */
  --s-0: 4px; --s-1: 8px; --s-2: 16px; --s-3: 24px;
  --s-4: 32px; --s-5: 48px; --s-6: 72px;

  /* --- shape: the document is square, the label is round.
         Stock is cut: 2px is the whole vocabulary for buttons, cards, inputs and
         panels, and a tab rounds its top corners only. What sits ON the stock is a
         different object — a round adhesive label — and it is fully rounded. See
         D053 and DESIGN.md § Shapes. There is no radius between 3px and a pill:
         an 8px corner is the bug this rule exists to catch. --- */
  --r-xs: 1px; --r-sm: 2px; --r-md: 3px; --r-tab: 3px 3px 0 0;
  --r-pill: 999px;
  /* The left rail's selected item: a divider tab turned on its side, rounding the
     two corners away from the page so the tab and the page read as one piece. */
  --r-spine: 3px 0 0 3px;

  --e: cubic-bezier(0.2, 0, 0, 1);
  --d-state: 100ms; --d-move: 180ms; --d-panel: 280ms;
}

:root[data-theme="dark"] {
  --rail: oklch(16% 0.018 265);
  --gold: oklch(82% 0.16 78);
  --gold-ink: oklch(82% 0.16 78);
  --gold-hover: oklch(87% 0.15 78);
  --focus: oklch(82% 0.16 78);
  --tape: oklch(72% 0.15 15);
  --on-tape: oklch(22% 0.015 265);
  --ink-blue: oklch(72% 0.12 265);

  --canvas: oklch(19% 0.020 265);
  --surface: oklch(24% 0.018 265);
  --sunken: oklch(15% 0.020 265);
  --text: oklch(94% 0.008 85);
  --body: oklch(87% 0.008 85);
  --muted: oklch(70% 0.008 265);
  --faint: oklch(68% 0.008 265);
  --hairline: oklch(34% 0.018 265);
  --solid-cta: oklch(94% 0.008 85);
  --solid-cta-ink: oklch(19% 0.020 265);

  --ok: oklch(74% 0.13 150);
  --attention: oklch(79% 0.13 70);
  --risk: oklch(68% 0.17 25);


  --st-triage:    oklch(74% 0.043 265);
  --st-ready:     oklch(73% 0.095 195);
  --st-progress:  oklch(74% 0.133 250);
  --st-review:    oklch(75% 0.123 305);
  --st-approval:  oklch(75% 0.133 345);
  --st-done:      oklch(73% 0.123 150);
  --st-cancelled: oklch(74% 0.011 265);

  --st-triage-bg:    oklch(29.5% 0.050 265);
  --st-ready-bg:     oklch(29.5% 0.050 195);
  --st-progress-bg:  oklch(29.5% 0.050 250);
  --st-review-bg:    oklch(29.5% 0.050 305);
  --st-approval-bg:  oklch(29.5% 0.050 345);
  --st-done-bg:      oklch(29.5% 0.050 150);
  --st-cancelled-bg: oklch(29.5% 0.015 265);

  --shadow-panel: 0 18px 44px oklch(8% 0.02 265 / 0.55);
}

*, *::before, *::after { box-sizing: border-box; }

html { color-scheme: light; }
html[data-theme="dark"] { color-scheme: dark; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--body);
  font-family: var(--font-ui);
  font-size: var(--t-16);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-display); color: var(--text); margin: 0; }
h1 { font-size: var(--t-40); font-weight: 800; line-height: 1.08; letter-spacing: -0.02em; }
h2 { font-size: var(--t-24); font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; }
h3 { font-size: var(--t-18); font-weight: 700; line-height: 1.3; }
h4 { font-family: var(--font-ui); font-size: var(--t-16); font-weight: 700; color: var(--text); margin: 0; }

/* The bundle's marginal annotation: Courier, uppercase, tracked. */
.sw-label {
  font-family: var(--font-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}

a { color: var(--gold-ink); text-decoration-thickness: 1px; text-underline-offset: 2px; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.sw-sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------- components --- */

.sw-button {
  font-family: var(--font-ui);
  font-size: var(--t-14);
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 0 var(--s-2);
  min-height: 44px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--d-state) var(--e), border-color var(--d-state) var(--e);
}
.sw-button--primary { background: var(--gold); color: var(--on-gold); }
.sw-button--primary:hover { background: var(--gold-hover); }
.sw-button--solid { background: var(--solid-cta); color: var(--solid-cta-ink); }
.sw-button--secondary { background: transparent; color: var(--text); border-color: var(--hairline); }
.sw-button--secondary:hover { background: var(--sunken); }
.sw-button--ghost { background: transparent; color: var(--muted); font-weight: 400; }
.sw-button--ghost:hover { color: var(--text); }
.sw-button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Paper on board: a page is lighter than its folder and carries a hairline.
   No shadow — the tonal step is the depth. */
.sw-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  padding: var(--s-3);
}

/* A panel is the other thing that truly floats — a modal, a command palette. Shadow,
   no border: one edge signal, not two. A hairline plus a 44px blur is the generated-UI
   tell Impeccable flags, and this system already separates surfaces by tone. */
.sw-panel {
  background: var(--surface);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-panel);
}

/* ------------------------------------------------------------------ the mark
   Every mark in the product is an inline SVG on a 16-unit grid, and this is the
   only place that decides how big one is. That sentence could not be written
   before M8: the marks were characters, sixteen of the twenty-two were in
   neither shipped font, and each one was therefore sized by whichever font the
   operating system substituted. Same pill, three different mark heights; same
   product, a different set of marks on macOS and on Android. See I-064.

   `flex: none` matters more than it looks. A mark inside a flex pill was being
   squeezed by a long label, which is the other half of "the icons are almost
   invisible". */
.sw-mark {
  flex: none;
  width: 16px; height: 16px;
  display: block;
  overflow: visible;   /* a 1.55 stroke on the 16-unit boundary is not clipped */
}
.sw-mark--sm { width: 14px; height: 14px; }
.sw-mark--lg { width: 20px; height: 20px; }

/* A mark is a fact, not a decoration, so it carries the same ink as the words
   beside it. The one exception is a mark in a quiet chip, where the label is the
   thing being read and the mark is confirming it. */
.sw-mark { color: inherit; }

/* The exhibit sticker. Small, square, and it carries a reference, never a mood. */
.sw-sticker {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--t-11);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--gold);
  color: var(--on-gold);
}
.sw-sticker--tape { background: var(--tape); color: var(--on-tape); }

.sw-chip {
  display: inline-flex; align-items: center; gap: var(--s-0);
  font-size: var(--t-12); font-weight: 600;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--sunken); color: var(--body);
  border: 1px solid var(--hairline);
}
.sw-chip--selected { background: var(--gold-quiet); border-color: var(--gold-ink); color: var(--text); }

/* A chip that carries a fact about an item — its priority, its kind, that it is
   blocked. Mark, then label, then colour (the Status rule), so it survives
   greyscale and a colour-blind reader. It is a chip and never a sticker: a
   sticker carries a REFERENCE, and gold is the seal (the Seal Rule). */
.sw-facet {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--font-ui);
  font-size: var(--t-12); font-weight: 600; letter-spacing: 0;
  min-height: 22px;
  padding: 0 8px 0 6px; border-radius: var(--r-pill);
  background: var(--sunken); color: var(--muted);
  border: 1px solid var(--hairline);
  white-space: nowrap; line-height: 1;
}
.sw-facet--risk      { color: var(--risk);      border-color: var(--risk); }
.sw-facet--attention { color: var(--attention); border-color: var(--attention); }
.sw-facet--ok        { color: var(--ok);        border-color: var(--ok); }
.sw-facet--note      { color: var(--ink-blue);  border-color: var(--ink-blue); }

/* Status carries a mark and a label; colour is the third channel. */
.sw-status { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-13); font-weight: 600; }
.sw-status__mark { font-family: var(--font-mono); font-size: var(--t-12); font-weight: 700; }
.sw-status--ok { color: var(--ok); }
.sw-status--attention { color: var(--attention); }
.sw-status--risk { color: var(--risk); }
.sw-status--neutral { color: var(--muted); }

/* THE SIGNATURE COMPONENT.
   The sentence from the source that caused a work item, set in Courier because
   that is what a transcript is set in, on divider stock, with its exhibit
   reference. It appears wherever an inference is shown. It is how the product
   proves it did not invent anything. No side rule: the tonal step is the edge. */
.sw-exhibit {
  background: var(--sunken);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  padding: var(--s-2);
  margin: var(--s-2) 0;
}
.sw-exhibit__quote {
  font-family: var(--font-mono);
  font-size: var(--t-13);
  line-height: 1.75;
  color: var(--text);
  margin: var(--s-1) 0 0;
}
.sw-exhibit__ref {
  font-family: var(--font-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}

.sw-empty { text-align: center; padding: var(--s-5) var(--s-3); color: var(--muted); }

.sw-skeleton {
  background: var(--sunken);
  border-radius: var(--r-xs);
  animation: sw-pulse 1.4s ease-in-out infinite;
}
@keyframes sw-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

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

/* Why the facet stopped being uppercase Courier.
   Arvind: "The pills look so chunky and text is misaligned in them." Both were
   true and both had one cause. Letter-spacing in CSS is added AFTER the last
   character as well as between characters, so 0.08em of tracking put an extra
   sliver of space inside the right edge of every pill and none inside the left:
   the label sat visibly off-centre in its own pill. Uppercase then made the word
   wider than it needed to be, and 11px Courier caps are slow to read at pill
   size, so the pill had to be big to hold a word nobody could read quickly.

   The rule that comes out of it, and that DESIGN.md now carries: mono and
   uppercase are for a REFERENCE — an exhibit number, a short code, a column
   heading. A facet is a word about the item, not a reference to anything, so it
   is set in the UI face at normal case. Courier still carries the evidence; it
   no longer carries the labels.

   `align-items: center`, not baseline, because a 16-unit drawing has no baseline
   to share with a word. Baseline alignment of a mark and a label was the third
   part of the misalignment, and the part that no amount of padding could fix. */

/* ------------------------------------------------------------- stage colouring
   One attribute, two variables. Anything that knows a state sets `data-st` and
   then reads --st-ink and --st-bg; nothing else in the product needs to know that
   "in_review" is violet. That is what stops the board, the list, the table and
   the stage bar from drifting into three different violets. */
[data-st="triage"]            { --st-ink: var(--st-triage);    --st-bg: var(--st-triage-bg); }
[data-st="ready"]             { --st-ink: var(--st-ready);     --st-bg: var(--st-ready-bg); }
[data-st="in_progress"]       { --st-ink: var(--st-progress);  --st-bg: var(--st-progress-bg); }
[data-st="in_review"]         { --st-ink: var(--st-review);    --st-bg: var(--st-review-bg); }
[data-st="awaiting_approval"] { --st-ink: var(--st-approval);  --st-bg: var(--st-approval-bg); }
[data-st="done"]              { --st-ink: var(--st-done);      --st-bg: var(--st-done-bg); }
[data-st="cancelled"]         { --st-ink: var(--st-cancelled); --st-bg: var(--st-cancelled-bg); }
