/* Sparkle Motion's shared stylesheet, in SMACSS order:
     1. tokens   the scales everything is built from (custom properties)
     2. base     plain elements, no classes
     3. layout   l-*: the page's big regions
     4. modules  reusable parts (nav, panel, field, seg, meter, entry, …),
                 their pieces named module-piece
     5. state    is-*: on, off, ok, warn, bad, edit, shown; and the
                 Design | Test modes
   Pages add only their own modules, built from the same tokens. Scripts
   find elements by id, data-*, or js-* hooks: never by these classes. */

/* ---- 1. Tokens ---- */
:root {
  /* Spacing: one scale for every margin, padding and gap. */
  --space-1: 2px;
  --space-2: 4px;
  --space-3: 8px;
  --space-4: 12px;
  --space-5: 16px;
  --space-6: 24px;
  --space-7: 32px;

  /* Type: one scale for every font size. */
  --font-xs: 11px;
  --font-sm: 12px;
  --font-md: 13px;
  --font-lg: 15px;
  --font-xl: 18px;
  --font-2xl: 22px;
  --font-body: system-ui, sans-serif;
  --font-mono: ui-monospace, monospace;
  --leading: 1.45;

  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;

  /* Colour (the one dark theme). */
  --c-page: #000;
  --c-stage: #060708;
  --c-sunk: #030405;
  --c-surface: #161b20;
  --c-glass: #161b20cc;
  --c-overlay: #0b0e11cc;
  --c-hover: #11161b;
  --c-raised: #1c232a;
  --c-line-faint: #11161b;
  --c-line: #1f252c;
  --c-line-strong: #262d35;
  --c-track: #1a1f24;
  --c-text: #9aa4ae;
  --c-text-soft: #c9d1d9;
  --c-text-strong: #dde3e9;
  --c-text-bright: #fff;
  --c-muted: #7d8894;
  --c-faint: #75808c;            /* the dimmest text: 4.5:1 on the page, stage and hover (not on a pick: see .is-on) */
  --c-accent: #fc3;
  --c-accent-bg: #2a2410;
  --c-accent-mark: #fc3a;        /* the accent, see-through: marks on a timeline */
  --c-ok: #3c6;
  --c-warn: #fa3;
  --c-bad: #f55;
  --c-info: #7aa7d9;
  --c-tag: #e2b04a;
  --c-bad-bg: #3a1414;
  --c-bad-text: #fcc;
  --c-bad-line: #a33;
  --c-ok-bg: #13301c;
  --c-ok-text: #cfc;
  --c-ok-line: #3a6;
  --c-off-line: #6a2222;
  --c-off-text: #f88;
  --c-feeds-line: #2a3a2a;

  /* Drawings (the 3D view reads these with themeGL; the cards' svg uses them too). */
  --c-scene-line: #2c343c;       /* card scenery strokes */
  --c-scene-edge: #1f2a33;       /* a solid thing's edges, on a card */
  --c-scene-frame: #57636f;      /* an outline thing's frame */
  --c-scene-bounds: #9e8033;     /* the box a thing fits in */
  --c-cable-mains: #735433;
  --c-cable-power: #d98c33;
  --c-cable-data: #33a6d9;
  --c-cable-dim: #333840;        /* a cable that isn't the pick's */
  --c-port-plug: #3cf;
  --c-port-end: #889;
  --c-port-tail: #f93;
  --c-port-fed: #ff4;
  --c-uncounted: #5a5a64;        /* mains, or not said: not in a measure */
  /* One ramp for every measure: bad (red) through the edge (white) to fine (green). */
  --c-ramp-bad: #ff2828;
  --c-ramp-edge: #fff;
  --c-ramp-fine: #28e65a;
  --c-rainbow: linear-gradient(90deg, #e33, #fc3, #3d6, #39f, #c3f);

  --control-pad: var(--space-2) var(--space-3);
  --side-left: 230px;
  --side-right: 320px;
}

/* ---- 2. Base ---- */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; background: var(--c-page); color: var(--c-text); font: var(--font-md) / var(--leading) var(--font-body); }
h1 { font-size: var(--font-lg); color: var(--c-text-strong); margin: 0 0 var(--space-3); font-weight: 600; }
h2 { font-size: var(--font-sm); color: var(--c-text-strong); margin: var(--space-4) 0 var(--space-2); text-transform: uppercase; letter-spacing: .06em; font-weight: 600; }
h3 { font-size: var(--font-md); color: var(--c-text-bright); margin: 0 0 var(--space-3); font-weight: 600; }
p { margin: 0 0 var(--space-3); }
a { color: var(--c-text-soft); }
b { color: var(--c-text-strong); }
small { font-size: var(--font-xs); color: var(--c-muted); }
code { font: var(--font-xs) var(--font-mono); color: var(--c-muted); }
button, select, input { font: inherit; color: var(--c-text-soft); background: var(--c-surface); border: 1px solid var(--c-line-strong); border-radius: var(--radius-md); padding: var(--control-pad); }
button { cursor: pointer; }
button:hover { border-color: var(--c-accent); }
button:disabled { opacity: .4; cursor: default; }
:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
/* Rows fill their scrolling column, which would clip a ring outside them. */
.list-item:focus-visible, .supply:focus-visible, .tree-node:focus-visible, .tree-leaf:focus-visible, .entry-pick:focus-visible { outline-offset: -2px; }
button:disabled:hover { border-color: var(--c-line-strong); }
input[type=number] { width: 64px; }
input[type=color] { width: 40px; height: 24px; padding: 0; border: 0; background: none; }
input[type=range] { accent-color: var(--c-accent); }
[hidden] { display: none !important; }

/* ---- 3. Layout ---- */
/* l-page: the page's margins. */
.l-page { padding: var(--space-4) var(--space-5); }
/* l-studio: a list, the stage, and panels, filling the window under the nav. */
.l-studio { display: grid; grid-template-columns: var(--side-left) minmax(0, 1fr) var(--side-right); gap: var(--space-4); height: calc(100vh - 72px); }
.l-studio > * { min-height: 0; overflow: auto; }
/* l-column: a side column of panels, which a page may reorder (order). */
.l-column { display: flex; flex-direction: column; gap: var(--space-3); }
.l-column > * { flex: none; }
/* l-split: main content and a side column. */
.l-split { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--space-5); align-items: start; }
@media (max-width: 800px) { .l-split { grid-template-columns: 1fr; } }

/* ---- 4. Modules ---- */

/* nav: the bar across every page. */
.nav { display: flex; gap: var(--space-2); align-items: center; margin: 0 0 var(--space-4); }
.nav-brand { color: var(--c-text-strong); font-size: var(--font-lg); margin-right: var(--space-4); }
.nav-link { color: var(--c-text); text-decoration: none; padding: var(--space-2) var(--space-4); border-radius: var(--radius-md); border: 1px solid transparent; }
.nav-link:hover { color: var(--c-text-bright); }
.nav-end { margin-left: auto; }

/* seg: a segmented switch (one choice of a few). */
.seg { display: inline-flex; }
.seg > button { border-radius: 0; margin-left: -1px; }
.seg > button:first-child { border-radius: var(--radius-md) 0 0 var(--radius-md); margin-left: 0; }
.seg > button:last-child { border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.seg > button:only-child { border-radius: var(--radius-md); }
.seg > button:not(.is-on) { color: var(--c-muted); }
.seg-fill { display: flex; } .seg-fill > button { flex: 1; }
.seg-small > button { padding: var(--space-1) var(--space-3); font-size: var(--font-sm); }

/* heading: a heading with controls at its end. */
.heading { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); margin: var(--space-4) 0 var(--space-3); }
.heading > h2 { margin: 0; }
aside > .heading:first-child, aside > h2:first-child { margin-top: 0; }

/* button-link: a link that looks like a button (a download, a way back). */
.button-link { display: inline-block; color: var(--c-text-soft); background: var(--c-surface); border: 1px solid var(--c-line-strong); border-radius: var(--radius-md); padding: var(--control-pad); text-decoration: none; }
.button-link:hover { border-color: var(--c-accent); }
/* link-button: a button that reads as a link (in a sentence or a list). */
.link-button { font: inherit; color: var(--c-accent); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: none; }
.link-button:hover { text-decoration: underline; }

/* toolbar: buttons in a row. */
.toolbar { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; margin: 0 0 var(--space-3); }
.toolbar-gap { width: var(--space-3); }

/* panel: a bordered box of related things. */
.panel { border: 1px solid var(--c-line); border-radius: var(--radius-lg); padding: var(--space-4); }
.panel > :last-child { margin-bottom: 0; }

/* field: a labelled row of controls. */
.field { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; margin: 0 0 var(--space-3); }
.field-label { flex: none; width: 64px; color: var(--c-muted); }
.field input:not([type]) { max-width: 150px; }
.field-check { display: inline-flex; gap: var(--space-2); align-items: center; }

/* pad: the nudge buttons, a 3 × 3 grid. */
.pad { display: grid; grid-template-columns: repeat(3, 32px); gap: var(--space-2); }
.pad > button { padding: var(--space-1); }

/* kv: a definition list of what something is. */
.kv { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: var(--space-2) var(--space-3); margin: 0 0 var(--space-3); font-size: var(--font-sm); }
.kv dt { color: var(--c-muted); }
.kv dd { margin: 0; color: var(--c-text-soft); }

/* entry: a line in a list, its value at the end. */
.entry { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); padding: var(--space-1) 0; border-bottom: 1px solid var(--c-line-faint); font-size: var(--font-sm); }
.entry > button { padding: 0 var(--space-2); font-size: var(--font-xs); }
.entry-pick { cursor: pointer; }
.entry-pick:hover { background: var(--c-hover); }

/* list: things to pick, one per line. */
.list { list-style: none; margin: 0; padding: 0; }
.list-item { display: flex; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); cursor: pointer; border: 1px solid transparent; }
.list-item:hover { background: var(--c-hover); }
.list-item small { color: var(--c-faint); }

/* tree: a list indented by depth (--depth). */
.tree-node { margin-left: calc(var(--depth, 0) * var(--space-4)); }
.tree-leaf { margin-left: calc(var(--depth, 0) * var(--space-4) + var(--space-5)); padding: var(--space-1) var(--space-3); font-size: var(--font-xs); color: var(--c-muted); cursor: pointer; }
.tree-leaf:hover { color: var(--c-text-soft); }

/* meter: a bar showing a share, and its number. */
.meter { display: flex; align-items: center; gap: var(--space-3); }
.meter-track { position: relative; flex: 1; height: 6px; background: var(--c-track); border-radius: var(--radius-sm); overflow: hidden; }
.meter-fill { position: absolute; inset: 0 auto 0 0; border-radius: var(--radius-sm); }
.meter-value { font-size: var(--font-sm); font-variant-numeric: tabular-nums; min-width: 40px; text-align: right; }

/* log: the design's events. */
.log { font: var(--font-xs) var(--font-mono); }
.log-line { padding: var(--space-1) 0; border-bottom: 1px solid var(--c-line-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.log-line b { color: var(--c-text-soft); font-weight: normal; }

/* stage: the 3D view, and what floats over it. */
.stage { position: relative; background: var(--c-stage); border-radius: var(--radius-lg); overflow: hidden; }
.stage-canvas { display: block; cursor: grab; }
.stage-canvas:active { cursor: grabbing; }
.stage-top-left, .stage-top-right, .stage-bottom-left, .stage-bottom-right { position: absolute; display: flex; gap: var(--space-2); align-items: center; }
.stage-top-left { top: var(--space-3); left: var(--space-3); }
.stage-top-right { top: var(--space-3); right: var(--space-3); }
.stage-bottom-left { bottom: var(--space-3); left: var(--space-3); }
.stage-bottom-right { bottom: var(--space-3); right: var(--space-3); }
.stage button, .stage .button-link { background: var(--c-glass); }
.stage-hint { color: var(--c-faint); font-size: var(--font-sm); }

/* tip: a small label over the stage (what's under the pointer). */
.tip { color: var(--c-text-soft); background: var(--c-overlay); padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); font-size: var(--font-sm); pointer-events: none; }

/* legend: what the colours mean. */
.legend { font-size: var(--font-sm); background: var(--c-overlay); padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); }
.legend-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin: 0 var(--space-2) 0 var(--space-3); vertical-align: -1px; background: var(--dot); }
.legend-dot-mains { --dot: var(--c-cable-mains); }
.legend-dot-power { --dot: var(--c-cable-power); }
.legend-dot-data { --dot: var(--c-cable-data); }
.legend-dot-plug { --dot: var(--c-port-plug); }
.legend-dot-end { --dot: var(--c-port-end); }
.legend-dot-tail { --dot: var(--c-port-tail); }
.legend-dot-fed { --dot: var(--c-port-fed); }
.legend-dot-uncounted { --dot: var(--c-uncounted); }
.legend-ramp { display: inline-block; width: 90px; height: 8px; border-radius: var(--radius-sm); margin: 0 var(--space-2); background: linear-gradient(90deg, var(--c-ramp-bad), var(--c-ramp-edge), var(--c-ramp-fine)); }

/* toast: a message that comes and goes. */
.toast { position: fixed; left: 50%; bottom: var(--space-5); transform: translateX(-50%); max-width: 70vw; padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg); background: var(--c-bad-bg); color: var(--c-bad-text); border: 1px solid var(--c-bad-line); visibility: hidden; z-index: 20; }
.toast.is-ok { background: var(--c-ok-bg); color: var(--c-ok-text); border-color: var(--c-ok-line); }

/* viewmode: the look switches (see viewmode.js). */
.viewmode { display: inline-flex; gap: var(--space-2); align-items: center; vertical-align: middle; }
.viewmode-state { color: var(--c-muted); font-size: var(--font-sm); min-width: 64px; text-align: right; }
.viewmode button { padding: var(--space-1) var(--space-3); font-size: var(--font-sm); background: var(--c-glass); }

/* The inventory cards' drawings (svg): scenery and wires, with the looks. */
svg .fill, svg .edge, svg .box { display: none; }
svg .edge { stroke: var(--c-scene-edge); }
svg .box { stroke: var(--c-scene-bounds); stroke-dasharray: 4 3; }
body[data-override=""] svg .fill.s0, body[data-override=""] svg .edge.s0, body[data-override=""] svg .edge.s1, body[data-override=""] svg .box.s2,
body[data-override=solid] svg .fill, body[data-override=solid] svg .edge, body[data-override=outline] svg .edge, body[data-override=bounds] svg .box { display: inline; }
body[data-override=""] svg .edge.s1, body[data-override=outline] svg .edge { stroke: var(--c-scene-frame); }
body[data-wires=off] .preview .wire { display: none; }

/* bulb: a light on an inventory card. Body = its size, glow = size × brightness.
   KEEP the two soft box-shadow halos: overlapping across neighbouring
   bulbs, they make the canvas's collective afterglow. */
.bulb { --l: 0; --s: 4px; --c: #000; --g: calc(var(--s) * var(--l)); position: absolute; width: var(--s); height: var(--s); border-radius: 50%;
  background-color: var(--c);
  box-shadow: 0 0 0 1px #ffffff10, 0 0 calc(var(--g) * .9) calc(var(--g) * .2) var(--c),
    0 0 calc(var(--g) * 3.5) calc(var(--g) * .9) color-mix(in srgb, var(--c) 45%, transparent);
  background-image: radial-gradient(circle at 50% 45%, rgb(255 255 255 / calc(var(--l) * .55)) 0 18%, transparent 40%); }
/* Shapes (lights.Shape), upright: the width stays --s. */
.bulb[data-shape=Square] { border-radius: 15%; }
.bulb[data-shape=Mini] { height: calc(var(--s) * 2.2); margin-top: calc(var(--s) * -.6); }
.bulb[data-shape=Cone], .bulb[data-shape=Strawberry] { border-radius: 0 50% 50% 50%; transform: rotate(45deg); }
.bulb[data-shape=Flame] { border-radius: 0 50% 50% 50%; transform: scale(.8, 1.2) rotate(45deg); }
.bulb[data-shape=Bullet] { border: max(1px, calc(var(--s) * .14)) solid rgb(0 0 0 / .45); box-sizing: border-box; }

/* ---- 5. State ---- */
.is-on { border-color: var(--c-accent) !important; color: var(--c-text-bright) !important; }
.seg > button.is-on, .list-item.is-on, .entry-pick.is-on { background: var(--c-accent-bg); }
.is-on small { color: var(--c-text); } /* small text keeps its contrast on a pick */
.nav-link.is-on { border-color: var(--c-accent); color: var(--c-text-bright); }
.tree-leaf.is-on { color: var(--c-accent); }
.is-ok { color: var(--c-ok); }
.is-warn { color: var(--c-warn); }
.is-bad { color: var(--c-bad); }
.is-edit { color: var(--c-accent); }
.meter-fill.is-ok { background: var(--c-ok); }
.meter-fill.is-warn { background: var(--c-warn); }
.meter-fill.is-bad { background: var(--c-bad); }
.toast.is-shown { visibility: visible; }
.is-off { border-color: var(--c-off-line) !important; color: var(--c-off-text) !important; }
/* The Design | Test modes: each mode's own parts show only in it. */
body[data-mode=design] .only-test, body[data-mode=test] .only-design { display: none !important; }
