/* loomd's palette -- one source of truth, loomd/theme.ts. Served at /theme.css for apps to link. */
:root {
  color-scheme: dark light;
  --bg: #11131a;
  --fg: #dde;
  --panel: #181b24;
  --line: #2a2f3a;
  --line-hover: #456;
  --dim: #667;
  --dim2: #778;
  --head: #889;
  --ok: #6a6;
  --busy: #da6;
  --you: #8bd;
  --you-tag: #456;
  --agent-tag: #465;
  --notice: #b95;
  --danger-bg: #332a2a;
  --danger-fg: #c99;
  --img-line: #333;
  /* Token colours for code blocks. Same variable trick as everything else here, so the light block below
     themes them without a second rule. */
  /* The user's turn gets a band, like the CLI's ansi 48;5;238. */
  --you-bg: #22262e;
  /* THREE SIZES FOR TEXT, audited 2026-09-01 (web_shell_css.ts carries the reasoning): 16px is what you READ
     and TYPE, 14px is the chrome you OPERATE, 12px is deliberately de-emphasised. In the palette because it
     belongs to the same promise the colours make -- an app that links this sheet CANNOT disagree with the
     panel around it, which is how one shipped app once painted itself dark inside a light loomd.

     2026-10-05: a FOURTH name (--fs-readout, 21px) existed here for exactly one day, for the pairing code's
     readout - the element it styled was deleted with the pairing panel (POST /pair, the QR, 'show a code',
     d679ecb) and a tier nothing spends is not a tier. The paragraph that earned it is in the history of this
     file, not here: a name without a consumer is the drift the audit below is for. */
  --fs-body: 16px;
  --fs-ui: 14px;
  --fs-meta: 12px;
  /* THE SPACE BETWEEN TWO ICON BUTTONS, and it is the SAME fault as the button's own radius, one level up:
     two pages each wrote their own (0.75rem here on the board, 0.4rem in the viewer -- 12px against 6.4px,
     four buttons of the same size in two strips that are visibly not the same strip), and it was reported
     from the two pages side by side (2026-10-09). The board's 0.75rem is the one kept, by the precedent
     written into .loom-icon below: the board is the page the viewer was asked to align with. It is also
     --sp-3 exactly (web_shell_css.ts), so no new number was invented -- but the scale is NOT published to
     the app pages this sheet is served to, so the NAME has to be, and .loom-icons below is what spends it.
     A name needs a consumer: if the strip rule ever goes, this goes with it. */
  --icon-gap: 0.75rem;
  --str: #9c9;
  --kw: #c9a;
  --num: #d9a;
  --fn: #9bd;
}
/* LIGHT. Not a second stylesheet: the same variables, so any rule added later themes itself. */
@media (prefers-color-scheme: light) {
  :root {
    /* THE THREE SIZES ARE NOT A COLOUR and do not change with the scheme -- they are repeated here because
       tests/app_viewer_test.ts holds every published name to appearing in BOTH blocks, the rule that stops a
       colour being defined in one scheme only, and an exemption for sizes is exactly where a colour would
       later hide. */
    --fs-body: 16px;
    --fs-ui: 14px;
    --fs-meta: 12px;
    --icon-gap: 0.75rem;
    --bg: #fbfbfd;
    --fg: #1a1d24;
    --panel: #f2f3f7;
    --line: #d4d7e0;
    --line-hover: #99a;
    --dim: #6b7180;
    --dim2: #5a6070;
    --head: #555c6b;
    --ok: #2a7a2a;
    --busy: #9a5b00;
    --you: #1c5fa8;
    --you-tag: #8a93a5;
    --agent-tag: #5a8a5a;
    --notice: #8a5a00;
    --danger-bg: #f7e8e8;
    --danger-fg: #a33;
    --img-line: #ccd;
    --you-bg: #eceef4;
    --str: #0a7;
    --kw: #a05;
    --num: #b60;
    --fn: #05a;
  }
}

/* THE STRIP OF ICON BUTTONS: the space between them comes from HERE -- from these two declarations and from
   nowhere else. THE DRIFT, measured on both pages in a real browser 2026-10-09: the board's .icons carried
   "gap: 0.75rem" and the viewer's #actions carried "gap: 0.4rem", one declaration per page, exactly the
   shape the button's own radius had (6px and 4px) until that was collected one level down. Two numbers kept
   in step by discipline drift; a number that exists once cannot drift from itself. A strip that looks like
   every other strip names this class and writes no gap of its own -- tests/app_icon_test.ts reads each
   page's own sheet and fails a rule on the strip's element that declares a gap or a margin.

   THE ALIGNMENT IS NOT HERE, deliberately: the board pushes its strip right with a heading that takes the
   slack (flex:1), the viewer with margin-left:auto. Those are two legitimate ways to reach the same right
   edge -- layout, not the space INSIDE the strip -- and the page keeps them.

   The gap below is the button's own measurement rather than a step of the page rhythm: the same family as
   the 40px button and its 20px glyph, and it cannot be var(--sp-3), because this sheet is ALSO served on
   its own to app pages, whose documents have no scale to spend. sp-keep */
.loom-icons {
  display: flex;
  gap: var(--icon-gap);
}
/* THE ICON BUTTON, and it is the ONE piece of chrome here rather than a layout: a glyph button is a
   DECISION (40 x 40 CSS px is the hit target on a phone, 20 px of glyph inside, stroked in the text
   colour), and a decision copied per page is the drift this whole file exists to stop -- the palette was
   copied four times and one copy disagreed. Two shipped app pages had their own copy of this rule and a
   third was written by hand before anyone looked, which is how a product stops looking like one product.
   PREFIXED, because pages we do not own link this sheet: the bare class name is a name an app may already use, and a
   collision here is a specificity fight nobody can debug from the app's side.

   The markup it expects is a button carrying this class and holding ONE 24x24 svg whose paths are stroked:
   that is what makes the glyph the same everywhere. Written in prose rather than as a tag, on purpose --
   this sheet is INLINED into loomd's own pages, so a real element in here would become dead markup inside
   those pages' own style element, shipped to every one of them and read by none. What a loomd response is
   held to says NOTHING about drawing: the live PAIRING CODE appears in no usable form in anything a caller
   can read, and that is the whole rule (noCodeIn, tests/pair_code_guard.ts). An svg in a response WAS
   refused once, as a proxy for "no QR carrying a code" -- and there has been no QR since 2026-10-05
   (Xiaohu). No test looks for the tag now, so this paragraph stays prose for the bytes: it describes the
   markup a page builds, it is not markup.
   An app page that keeps its own layout and takes only this is the intended use: no layout, no colour and
   no button face here -- those stay the page's, which is why this is four properties and a glyph. */
.loom-icon {
  width: 40px;
  height: 40px;
  padding: 0;
  display: grid;
  place-items: center;
  /* THE FACE TOO, and not only the geometry: the two app pages had 6px and 4px of radius here, which is the
     same drift one level down -- two buttons of the same size that are visibly not the same button. The
     board's radius is the one kept, because it is the page the viewer was asked to match. */
  color: var(--fg);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}
.loom-icon:hover {
  border-color: var(--line-hover);
}
.loom-icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}
