/* ============================================================================
   tool-theme.css — dark mode AND the shared control chrome for the STANDALONE
   tools (the ones the toolkit embeds in an iframe: hatch, truss, stair,
   waffle, panelizer, …).

   Those tools all share one CSS skeleton whose colours are already five
   variables:

     --bg  page   --surface  panels/header/sidebar   --line  rules
     --ink text   --accent   the brand red-orange

   …so dark mode is just a second set of values. Nothing inside a tool needs
   editing; each one links this file and `tool-theme.js`.

   Link it AFTER the tool's own <style> so these declarations win.

   WHAT DOES NOT INVERT: the drawing itself. Every one of these tools paints its
   canvas ground explicitly (`fillStyle="#fff"; fillRect(...)`) before drawing in
   dark ink, so the sheet stays white in both modes — the same rule the React
   tools follow for their 3D viewports. A drawing tool showing a white sheet is
   correct; a drawing tool showing invisible geometry is not.
   ============================================================================ */

/* The five skeleton tokens are declared by each tool. Everything below is
   ADDITIONAL vocabulary the tools' stylesheets were spelling as raw hexes —
   declared here for BOTH modes so a tool can reference them either way. */
:root {
  color-scheme: light;

  --wash: #f0f0ee;                        /* panel / row fill */
  --wash-2: #eef1f4;                      /* the cooler second fill */
  --surface-92: rgba(255, 255, 255, 0.92); /* floating readouts over the canvas */
  --bg-85: rgba(245, 245, 243, 0.85);
  --accent-strong: #d93a1f;               /* the pressed / hover accent */

  --ok: #0f6e4f;   /* 5.5:1 on --ok-wash; #12805c landed at 4.35:1 */
  --ok-2: #1f9d57;
  --warn: #c47b00;
  --warn-2: #f5a623;
  --bad: #b42318;
  --bad-2: #dd1111;
  --info: #1f5fd9;
  --info-2: #0a84ff;
  --muted: #9aa1a8;
  --slate: #33383d;

  --ok-wash: #e7f4ec;   /* pass/fail table cells */
  --bad-wash: #fcebea;
  --ink-rgb: 17 17 17;  /* for the tools' rgba(17,17,17, α) scrims */
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0b0b0c;      /* page — same as the public site and the toolkit shell */
  --surface: #151618; /* header, sidebar, panels: one step up from the page */
  --line: #33343a;    /* rules and hairlines */
  --ink: #f2f0ec;     /* the one ink — warm off-white, ~16:1 on the surface */

  /* The brand red stays the brand red: it is used for fills with white labels,
     and it already clears 5.5:1 as text on this page. */
  --accent: #ff3b21;

  --wash: #1d1e21;
  --wash-2: #23252a;
  --surface-92: rgba(21, 22, 24, 0.92);
  --bg-85: rgba(11, 11, 12, 0.85);
  --accent-strong: #ff7a5c;

  /* Status colours, lifted off the dark ground — the light-mode values sit
     between 2:1 and 4:1 there, which is unreadable for the small type they
     carry. */
  --ok: #4ec99a;
  --ok-2: #5cd18a;
  --warn: #e8b04a;
  --warn-2: #f5c069;
  --bad: #f2796d;
  --bad-2: #ff7b6e;
  --info: #74a8ff;
  --info-2: #58a6ff;
  --muted: #8b9199;
  --slate: #c9ccd2;

  --ok-wash: #10301f;
  --bad-wash: #3a1614;
  --ink-rgb: 242 240 236;

  /* Tool-specific extras (proportion / isovist). Both are mid-blues that go
     unreadable on a dark ground, so they lift; the orange already works. */
  --score: #5ba3ff;
  --sel: #4da3ff;
  --goalhl: #ff8c00;
}

/* ══════════════════════════════════════════════════════════════════════════
   THE CONTROL PROTOCOL, mirrored (2026-08-04)
   ══════════════════════════════════════════════════════════════════════════
   The React toolkit draws every slider from one block in src/app/globals.css.
   The 25 embedded tools share this stylesheet instead, so the same rules are
   restated here in THIS file's vocabulary — `--ink` for the drawn parts,
   `--line` for the hairline track (both are declared by every tool's own
   <style>, and re-declared above for dark mode). No hexes: a slider must look
   identical to the app's in light AND dark.

   Because this file is linked after each tool's <style>, these single-class
   selectors win over the tools' own `input[type="range"] { accent-color: … }`
   without touching a single tool.

     • HIT AREA. The native track is ~4px tall and miserable on a trackpad.
       The pointer box is 1.25rem tall; the drawn track is 4px inside it.
     • THE THUMB IS INK, not the OS accent and not the brand red — a control
       is chrome, and chrome is ink. 14px, square, like the shell's boxes. */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 1.25rem;
  background: transparent;
  cursor: pointer;
  accent-color: var(--ink);
}
input[type="range"]:disabled {
  cursor: not-allowed;
}
/* WebKit / Blink */
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--line);
  border-radius: 0;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  height: 14px;
  width: 14px;
  margin-top: -5px; /* centre the 14px thumb on the 4px track */
  background: var(--ink);
  border: 0;
  border-radius: 0;
}
input[type="range"]:disabled::-webkit-slider-thumb {
  background: var(--line);
}
/* Firefox */
input[type="range"]::-moz-range-track {
  height: 4px;
  background: var(--line);
  border-radius: 0;
}
input[type="range"]::-moz-range-thumb {
  height: 14px;
  width: 14px;
  background: var(--ink);
  border: 0;
  border-radius: 0;
}
input[type="range"]:disabled::-moz-range-thumb {
  background: var(--line);
}
/* <datalist> ticks would otherwise render as browser-chrome text. */
input[type="range"] + datalist {
  display: none;
}

/* Checkboxes and radios draw in the ink too, so a rail reads as one system. */
input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--ink);
}

/* ── Tightened control chrome ───────────────────────────────────────────────
   The tools share one rail skeleton (.sidebar / .panel > .group > .label,
   .row, .val, .hint, .check, .btn). Tightening it here shortens every rail at
   once — the same "minimise scrolling" pass the React rails got. Scoped to the
   rail on purpose: the same class names appear on floating canvas toolbars and
   on rhino-python's full-width search, which must NOT shrink. Nothing below
   changes a layout mode; only rhythm, size and colour. */
/* Only `.sidebar` gets a new padding: `.panel` is a flex shell in some tools
   (diagram-studio's right dock, scale-bar's dropdowns) whose children own the
   inset — padding there would shift their whole layout. */
.sidebar {
  padding: 12px;
  gap: 12px;
}
.sidebar .group,
.panel .group {
  gap: 6px;
}
.sidebar .group > .label,
.panel .group > .label {
  padding-bottom: 4px;
}
.sidebar .row,
.panel .row {
  gap: 8px;
  min-height: 1.25rem;
}
.sidebar .row label,
.panel .row label,
.sidebar .check,
.panel .check {
  font-size: 12px;
  line-height: 1.3;
}
.sidebar .row .val,
.panel .row .val {
  font-size: 11px;
  line-height: 1.3;
}
.sidebar .check,
.panel .check {
  gap: 6px;
}
.sidebar .hint,
.panel .hint {
  font-size: 11px;
  line-height: 1.4;
}
.sidebar input[type="number"],
.sidebar input[type="text"],
.sidebar select,
.panel input[type="number"],
.panel input[type="text"],
.panel select {
  padding: 4px 6px;
  font-size: 12px;
  line-height: 1.35;
  border-radius: 0;
  color: var(--ink);
}
.sidebar input[type="number"]:focus,
.sidebar input[type="text"]:focus,
.sidebar select:focus,
.panel input[type="number"]:focus,
.panel input[type="text"]:focus,
.panel select:focus {
  /* Border only — the keyboard focus RING stays whatever the tool/browser
     draws. `outline: none` here would silently strip it from 25 tools. */
  border-color: var(--ink);
}
.sidebar .btn,
.panel .btn {
  padding: 6px 10px;
  border-radius: 0;
}

/* No grey. The two secondary strings the shared skeleton carries — a tool's
   header sub-title and the small print under a control — are pinned to the
   theme's one ink, at full contrast, in both modes. (Deliberately narrow:
   `.note` / `.sub` / `.muted` are spelled per-tool and some sit on their own
   coloured grounds, so a blanket rule would invert them into illegibility.) */
header .subtitle,
.sidebar .hint,
.panel .hint {
  color: var(--ink);
}

/* The tools are embedded in an iframe with no toggle of their own — the
   toolkit's toggle drives them (see tool-theme.js). Match the parent's
   cross-fade so the frame does not snap while the page around it eases. */
:root[data-theme] body {
  transition: background-color .18s ease, color .18s ease;
}

@media (prefers-reduced-motion: reduce) {
  :root[data-theme] body {
    transition: none;
  }
}

/* ============================================================================
   THE STACKED (MOBILE) LAYOUT — one statement for all 24 embedded tools.

   Every tool here is built on the same skeleton: a full-height `body` in
   `overflow: hidden`, an `.app` row of `.sidebar` + `.stage` (+ `.readout`,
   sometimes wrapped in a `.middle`), with the drawing painted into a canvas or
   svg that fills `.stage`, and the numbers floated OVER that drawing as an
   absolutely-positioned `.readout` / `.legend`.

   On a desktop that is exactly right and nothing below changes it. On a phone
   it failed in three compounding ways, which is what John saw in Rotunda:

     1  The page could not scroll (`body { overflow: hidden }` + `height: 100%`),
        so the whole tool had to fit one screen. Each tool then rationed that
        screen with `vh` caps — 46vh of sidebar, 40vh of readout — and whatever
        was left over, often under 100px, was the DRAWING. The one part of a
        design tool that has to be big got what nobody else claimed.
     2  `.readout` and `.legend` are absolutely positioned at the stage's top-
        left and bottom-left with a `max-width` around 320px. That is a
        comfortable margin note over a 900px drawing and a blackout over a
        360px one — and where a tool has both, they land on top of each other.
     3  Nothing gave the drawing a shape, so it inherited whatever the flexbox
        had spare: a long thin letterbox, in a medium made of plans.

   So, below 900px: the DOCUMENT scrolls (one scroll, not three nested ones and
   a squeeze), the drawing surface is a SQUARE and is FIRST, the numbers fall
   out of the drawing into the flow underneath it, and the controls follow. The
   `vh` caps have to go with them — a tool sized in `vh` inside an iframe the
   embedder is sizing to its content is a feedback loop.

   This file is linked AFTER each tool's own <style>, so these rules win on
   document order at equal specificity. No tool needs editing.
   ============================================================================ */
@media (max-width: 900px) {
  html,
  body {
    height: auto;
    min-height: 100%;
    overflow: visible;
  }

  .app,
  .middle {
    flex-direction: column;
    overflow: visible;
    min-height: 0;
    flex: none;
  }

  /* A header toolbar is a single non-wrapping row of buttons, which is fine at
     900px and 760px wide on a phone. It never showed because `body` clipped it;
     now that the document scrolls, an unwrapped toolbar would scroll the whole
     page sideways. Wrapping only engages where the row genuinely doesn't fit. */
  header,
  header nav,
  header > div {
    flex-wrap: wrap;
  }

  /* Drawing first, then its numbers, then the controls. Landing on forty
     sliders with the drawing somewhere below the fold is how a viewport
     "works" on paper and not in the hand. (`.readout` nested INSIDE `.stage`
     needs no order — unfloated, it already flows directly under the canvas.) */
  .stage,
  .middle {
    order: 1;
  }
  .readout {
    order: 2;
  }
  .sidebar {
    order: 3;
  }

  .stage {
    flex: none;
    width: 100%;
    height: auto;
    min-height: 0;
  }

  /* THE SQUARE. The drawing surface — a canvas, an svg sheet, or the div a
     renderer mounts into — takes the full column width and an equal height.
     `position: relative` is deliberate: several tools pin their surface with
     `inset: 0` against a stage that HAD a height, and once the stage is
     content-sized that would collapse it to nothing.

     `max-height` because a true square is taller than the screen on a tablet,
     and you should not have to scroll to see the bottom of your own drawing.
     A PIXEL cap, not `svh`: this document's height is what the embedder sizes
     the frame to (the height bridge in tool-theme.js), so a viewport-relative
     cap would grow every time the frame it just grew was measured again.

     NOT `#wrap` (scale-bar): that tool draws at true millimetres for a given
     scale, so its box is a measurement, not a layout choice.

     The `#stage > …` half of the selector is not a duplicate: several tools
     size their surface through an ID (`#cv { position: absolute; inset: 0;
     height: 100% }`), and no chain of classes outranks an id. Naming the stage
     by its id — which every tool built on this skeleton carries — buys the one
     point of specificity needed, without `!important` reaching down the whole
     file and overriding the tools that size their sheet from JS on purpose
     (Figure-Ground fits its paper to the plan it loaded, and should). */
  .stage > canvas,
  .stage > svg,
  .stage > #view,
  #stage > canvas,
  #stage > svg,
  #stage > #view {
    position: relative;
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    max-height: 720px;
  }

  /* A SECOND canvas in one stage is an overlay layer, never a second drawing
     (Draughts paints its streamline animation over the plan). It keeps the
     square it just inherited and goes back on top of its sibling, in register —
     stacked, the two layers would draw the same site twice. */
  .stage > canvas + canvas {
    position: absolute;
    top: 0;
    left: 0;
  }

  /* The numbers stop covering the drawing and become the paragraph under it. */
  .readout,
  .legend,
  .analysis {
    position: static;
    width: 100%;
    max-width: none;
    max-height: none;
    overflow: visible;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    border-top: 1px solid var(--line);
    backdrop-filter: none;
  }

  /* No inner scroll wells. The document scrolls; a 46vh porthole onto a
     control rail, dragged inside an iframe, does not. */
  .sidebar,
  .panel {
    width: 100%;
    max-height: none;
    overflow: visible;
    border-left: 0;
    border-right: 0;
  }
  .sidebar {
    border-top: 1px solid var(--line);
  }
}
