/* ==========================================================================
   BINMAN "Depot" design system (spec 6.2).

   Municipal waste-depot signage: a concrete ground, stencilled headings,
   sodium-amber wayfinding, one accent and everything else quiet.

   Deliberately differentiated from the marcdeller.com house brand, from
   GOBSMACKED's instrument panel and from KINFOLK's field guide. The house
   header and #1e73be palette do NOT apply here. They apply to the README.

   Every token is defined on bare :root first, then redefined under both
   @media (prefers-color-scheme: dark) and [data-theme="dark"], so no colour
   exists in only one theme (spec 4.4 acceptance criterion).
   ========================================================================== */

/* Fonts are linked from base.html rather than @import-ed: an @import is
   resolved serially after this file parses, and it was also producing a
   stray document-relative request for /vendor/fonts/fonts.css. */

:root {
  color-scheme: light;

  --bg: #E9EAE5;          /* concrete */
  --surface: #F7F7F4;
  --surface-2: #DFE1DA;
  --ink: #15171A;
  --line: #C9CBC3;
  --accent-soft: #F6E3D3;
  --good: #2C6D60;
  --bad: #A33A2A;

  /* These three were darkened from the spec 6.2 values after axe-core measured
     real contrast failures in the light theme: muted 4.25, accent 2.97 and warn
     3.05 against --surface-2, all under the 4.5 needed for body text. Each is
     now the deepest tone that still reads as the same colour, solved against the
     darkest light surface. The dark theme measured clean and is unchanged.
     Spec 6.2 values were --muted #6A6F68, --accent #D65B0A, --warn #9A7B10. */
  --muted: #61655F;       /* 4.50 on surface-2, 5.53 on surface */
  --accent: #A64708;      /* sodium amber, 4.51 on surface-2 */
  --warn: #79610D;        /* 4.51 on surface-2 */
  /* Text that sits ON the accent fill. White over the light dark-theme amber
     measured 2.35, so each theme names its own readable counterpart. */
  --on-accent: #FFFFFF;   /* 5.96 on the light-theme accent */

  --display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --body: 'Spline Sans', system-ui, -apple-system, sans-serif;
  --data: 'IBM Plex Mono', ui-monospace, Menlo, monospace;

  /* derived tokens, so a theme override of the base cascades */
  --shadow: 0 1px 2px rgb(21 23 26 / 8%), 0 4px 12px rgb(21 23 26 / 6%);
  --focus: var(--accent);
  --rail-w: 15.5rem;
  --radius: 3px;          /* signage is not rounded */
  --gutter: 1rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #131512;
    --surface: #1C1F1B;
    --surface-2: #252923;
    --ink: #E7E9E2;
    --muted: #8D938A;
    --line: #2F342D;
    --accent: #FF8A33;
    --accent-soft: #3A2415;
    --good: #5CBCA3;
    --warn: #D4AC3A;
    --bad: #E07A62;
    --on-accent: #15171A;   /* 8.4 on the dark-theme accent; white measured 2.35 */
    --shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 4px 14px rgb(0 0 0 / 30%);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #131512;
  --surface: #1C1F1B;
  --surface-2: #252923;
  --ink: #E7E9E2;
  --muted: #8D938A;
  --line: #2F342D;
  --accent: #FF8A33;
  --accent-soft: #3A2415;
  --good: #5CBCA3;
  --warn: #D4AC3A;
  --bad: #E07A62;
  --on-accent: #15171A;   /* 8.4 on the dark-theme accent; white measured 2.35 */
  --shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 4px 14px rgb(0 0 0 / 30%);
}

/* -------------------------------------------------------------------------- */
/* reset and base                                                             */
/* -------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

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

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.01em;
  margin: 0 0 0.5rem;
  line-height: 1.15;
}

/* Stencilled headings: the depot signage cue. */
h1 { font-size: 1.5rem; text-transform: uppercase; letter-spacing: 0.06em; }
h2 { font-size: 1.1rem; text-transform: uppercase; letter-spacing: 0.05em; }
h3 { font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }

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

code, kbd, samp, .mono { font-family: var(--data); font-size: 0.86em; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--gutter); top: -3rem; z-index: 100;
  background: var(--accent); color: #fff; padding: 0.5rem 0.75rem;
  border-radius: var(--radius); transition: top 0.15s;
}
.skip-link:focus { top: var(--gutter); }

/* -------------------------------------------------------------------------- */
/* header                                                                     */
/* -------------------------------------------------------------------------- */

.app-header {
  display: flex; align-items: center; gap: 1rem;
  padding: 0.6rem var(--gutter);
  background: var(--surface);
  border-bottom: 2px solid var(--line);
  position: sticky; top: 0; z-index: 20;
  flex-wrap: wrap;
}

.brand { display: flex; align-items: baseline; gap: 0.55rem; text-decoration: none; color: var(--ink); }
.brand__mark { width: 26px; height: 26px; flex: none; align-self: center; }
.brand__name {
  font-family: var(--display); font-weight: 700; font-size: 1.05rem;
  text-transform: uppercase; letter-spacing: 0.1em;
}
.brand__sub { color: var(--muted); font-size: 0.72rem; letter-spacing: 0.04em; }

.app-nav { display: flex; gap: 0.15rem; flex-wrap: wrap; }
.app-nav a {
  padding: 0.35rem 0.65rem; border-radius: var(--radius);
  color: var(--muted); text-decoration: none;
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em;
  font-family: var(--display); font-weight: 600;
  border: 1px solid transparent;
}
.app-nav a:hover { background: var(--surface-2); color: var(--ink); }
.app-nav a[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent); border-color: var(--accent);
}

.header-tools { margin-left: auto; display: flex; align-items: center; gap: 0.6rem; }

.theme-toggle {
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.3rem 0.5rem; cursor: pointer; font-size: 0.95rem; line-height: 1;
}
.theme-toggle:hover { border-color: var(--accent); }

/* -------------------------------------------------------------------------- */
/* ternary triangle (spec 6.3): always visible, also a control                */
/* -------------------------------------------------------------------------- */

.triangle { width: 62px; height: 56px; flex: none; cursor: pointer; }
.triangle .tri-edge { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.triangle .tri-edge.is-live { stroke: var(--accent); stroke-width: 2.5; }
.triangle .tri-corner {
  fill: var(--surface-2); stroke: var(--line); stroke-width: 1.5;
  transition: fill 0.2s, stroke 0.2s;
}
.triangle .tri-corner.is-pinned { fill: var(--accent); stroke: var(--accent); }
.triangle .tri-corner:hover { stroke: var(--accent); }
.triangle .tri-centre { fill: none; stroke: var(--line); stroke-width: 1.5; stroke-dasharray: 2 2; }
.triangle .tri-centre.is-resolved { fill: var(--good); stroke: var(--good); stroke-dasharray: none; }
.triangle .tri-label {
  font-family: var(--data); font-size: 7px; fill: var(--muted);
  text-anchor: middle; dominant-baseline: middle; pointer-events: none;
}

/* -------------------------------------------------------------------------- */
/* split ledger layout (spec 6.3)                                             */
/* -------------------------------------------------------------------------- */

.ledger {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  gap: 0;
  min-height: calc(100vh - 58px);
}

.rail {
  background: var(--surface);
  border-right: 2px solid var(--line);
  padding: 0.9rem var(--gutter);
  display: flex; flex-direction: column; gap: 1.1rem;
  overflow-y: auto;
}

.rail__modules { display: flex; flex-direction: column; gap: 0.2rem; }
.rail__modules a {
  display: block; padding: 0.45rem 0.6rem; border-radius: var(--radius);
  text-decoration: none; color: var(--ink); font-size: 0.85rem;
  border-left: 3px solid transparent;
}
.rail__modules a:hover { background: var(--surface-2); }
.rail__modules a[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent);
  border-left-color: var(--accent); font-weight: 600;
}
.rail__modules .count { color: var(--muted); font-family: var(--data); font-size: 0.75rem; float: right; }

/* the query stack: the app's audit trail, pastes into a methods section */
.stack { border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
.stack__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.4rem 0.55rem; border-bottom: 1px solid var(--line);
}
.stack__head h3 { margin: 0; font-size: 0.72rem; }
.stack__list { list-style: none; margin: 0; padding: 0.3rem; font-family: var(--data); font-size: 0.74rem; }
.stack__list li {
  display: flex; justify-content: space-between; gap: 0.4rem; align-items: baseline;
  padding: 0.25rem 0.3rem; border-radius: 2px;
}
.stack__list li + li { border-top: 1px dashed var(--line); }
.stack__list .drop {
  background: none; border: 0; color: var(--muted); cursor: pointer;
  font-family: var(--data); padding: 0 0.2rem;
}
.stack__list .drop:hover { color: var(--bad); }
.stack__empty { color: var(--muted); padding: 0.45rem; font-size: 0.76rem; font-family: var(--body); }

.btn {
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.3rem 0.55rem; cursor: pointer;
  font-family: var(--display); font-size: 0.72rem;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn--accent { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn--accent:hover { color: var(--on-accent); filter: brightness(1.08); }

.field { display: flex; flex-direction: column; gap: 0.2rem; margin-bottom: 0.5rem; }
.field label { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.field select, .field input {
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.3rem 0.4rem; font-family: var(--data); font-size: 0.8rem;
  min-width: 0;
}
.field select:focus, .field input:focus { border-color: var(--accent); }
/* The rail is 15.5rem wide, which cannot hold three columns without clipping
   the operator label. Field and operator share a row, value gets its own. */
.builder__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
                gap: 0.3rem 0.4rem; }
.builder__row .field:last-child { grid-column: 1 / -1; }

/* -------------------------------------------------------------------------- */
/* main pane                                                                  */
/* -------------------------------------------------------------------------- */

.pane { padding: 0.9rem var(--gutter) 2rem; min-width: 0; }

.pane__head {
  display: flex; align-items: baseline; gap: 0.7rem;
  flex-wrap: wrap; margin-bottom: 0.7rem;
}
.pane__head .meta { color: var(--muted); font-family: var(--data); font-size: 0.78rem; }

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 0.8rem; margin-bottom: 0.9rem;
}
.panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }

.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.9rem; }

.notice {
  border-left: 3px solid var(--accent); background: var(--accent-soft);
  color: var(--ink); padding: 0.6rem 0.75rem; border-radius: var(--radius);
  font-size: 0.85rem; margin-bottom: 0.9rem;
}
.notice--good { border-left-color: var(--good); background: color-mix(in srgb, var(--good) 8%, var(--surface)); }
.notice--bad { border-left-color: var(--bad); background: color-mix(in srgb, var(--bad) 8%, var(--surface)); }

/* stat tiles */
.stats { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.9rem; }
.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 0.5rem 0.7rem; min-width: 7.5rem;
}
.stat__value { font-family: var(--data); font-size: 1.15rem; font-weight: 600; }
.stat__label { color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; }
.stat--good .stat__value { color: var(--good); }
.stat--warn .stat__value { color: var(--warn); }
.stat--bad .stat__value { color: var(--bad); }

/* verdict and class pills */
.pill {
  display: inline-block; padding: 0.05rem 0.4rem; border-radius: 2px;
  font-family: var(--data); font-size: 0.72rem; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--muted); white-space: nowrap;
}
/* Pills sit on alternating table-row backgrounds, so a translucent tint of the
   token colour lands on a different base in odd and even rows and fails contrast
   on the darker one. An opaque --surface background makes the ratio the same
   wherever the pill appears: measured 5.5 to 6.1 for every token. The colour
   coding lives in the border and the text. */
.pill--good { color: var(--good); border-color: var(--good); background: var(--surface); }
.pill--warn { color: var(--warn); border-color: var(--warn); background: var(--surface); }
.pill--bad { color: var(--bad); border-color: var(--bad); background: var(--surface); }
.pill--glue { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

/* -------------------------------------------------------------------------- */
/* Mol* viewer frame (spec 6.4)                                               */
/* -------------------------------------------------------------------------- */

.viewer {
  position: relative; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--radius);
  min-height: 340px; overflow: hidden;
}
.viewer__canvas { position: absolute; inset: 0; }
.viewer__bar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; gap: 0.25rem; align-items: center; flex-wrap: wrap;
  padding: 0.3rem; background: color-mix(in srgb, var(--surface) 88%, transparent);
  border-bottom: 1px solid var(--line);
}
.viewer__bar .btn { font-size: 0.66rem; padding: 0.2rem 0.4rem; }
.viewer__id { margin-left: auto; font-family: var(--data); font-size: 0.72rem; padding-right: 0.3rem; }
.viewer__empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 2rem 1.2rem; color: var(--muted); font-size: 0.88rem;
}
/* An explicit `display` beats the user-agent rule that `[hidden]` relies on, so
   hideEmpty() set hidden=true and the overlay stayed on screen over a viewer
   that had in fact loaded. That is the whole "viewers do not load" symptom: the
   structure was there, behind this. */
.viewer__empty[hidden] { display: none; }
.viewer__overlay {
  position: absolute; bottom: 0.4rem; left: 0.4rem; z-index: 5;
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.3rem 0.45rem; font-family: var(--data); font-size: 0.72rem;
  max-width: calc(100% - 0.8rem);
}
.viewer--tall { min-height: 460px; }

/* -------------------------------------------------------------------------- */
/* tables (Tabulator overrides, themed from tokens only)                      */
/* -------------------------------------------------------------------------- */

.tabulator {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); font-size: 0.8rem; color: var(--ink);
}
.tabulator .tabulator-header {
  background: var(--surface-2); border-bottom: 2px solid var(--line); color: var(--ink);
}
.tabulator .tabulator-header .tabulator-col {
  background: var(--surface-2); border-right: 1px solid var(--line);
}
.tabulator .tabulator-header .tabulator-col-title {
  font-family: var(--display); font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.tabulator .tabulator-row { background: var(--surface); border-bottom: 1px solid var(--line);
  color: var(--ink); }
.tabulator .tabulator-row .tabulator-cell { color: var(--ink); }
.tabulator .tabulator-row.tabulator-selectable:hover { color: var(--ink); }
.tabulator .tabulator-row.tabulator-row-even { background: var(--bg); }
.tabulator .tabulator-row:hover { background: var(--accent-soft) !important; }
.tabulator .tabulator-row.tabulator-selected { background: var(--accent-soft) !important; }
.tabulator .tabulator-cell { border-right: 1px solid var(--line); font-family: var(--data); }
.tabulator .tabulator-footer {
  background: var(--surface-2); border-top: 1px solid var(--line); color: var(--muted);
}
.tabulator .tabulator-footer .tabulator-page {
  background: var(--surface); border: 1px solid var(--line); color: var(--ink);
}
.tabulator .tabulator-footer .tabulator-page.active { background: var(--accent); color: #fff; }
.tabulator-col-sorter-element .tabulator-arrow { border-bottom-color: var(--muted) !important; }

/* a plain table for the About tab and small summaries */
.grid-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.grid-table th, .grid-table td {
  text-align: left; padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.grid-table th {
  font-family: var(--display); font-size: 0.7rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 2px solid var(--line);
}
.grid-table td.num, .grid-table th.num { text-align: right; font-family: var(--data); }
.grid-table tbody tr:hover { background: var(--surface-2); }

/* -------------------------------------------------------------------------- */
/* About tab                                                                  */
/* -------------------------------------------------------------------------- */

.schematic { width: 100%; height: auto; display: block; }
.schematic text { font-family: var(--data); }
.about-step { border-left: 3px solid var(--accent); padding-left: 0.85rem; margin: 1.4rem 0; }
.about-step__n {
  font-family: var(--display); font-size: 0.7rem; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.08em;
}
.limits { border-left: 3px solid var(--bad); background: color-mix(in srgb, var(--bad) 6%, var(--surface)); padding: 0.7rem 0.85rem; border-radius: var(--radius); }

/* -------------------------------------------------------------------------- */
/* lens graph                                                                 */
/* -------------------------------------------------------------------------- */

.lens { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 0.9rem; }
.lens__canvas {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); min-height: 560px;
}
.lens__canvas .node { stroke: var(--surface); stroke-width: 1.5; cursor: pointer; }
.lens__canvas .node.is-selected { stroke: var(--ink); stroke-width: 2.5; }
.lens__canvas .link { stroke: var(--line); stroke-opacity: 0.75; }
.lens__canvas .node-label { font-family: var(--data); font-size: 9px; fill: var(--muted); pointer-events: none; }

/* -------------------------------------------------------------------------- */
/* responsive: phone width, 16px gutter, no horizontal page scroll            */
/* -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .lens { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  .ledger { grid-template-columns: minmax(0, 1fr); }
  .rail {
    border-right: 0; border-bottom: 2px solid var(--line);
    max-height: none;
  }
  .app-header { gap: 0.6rem; }
  .brand__sub { display: none; }
  .app-nav a { font-size: 0.72rem; padding: 0.3rem 0.45rem; }
  h1 { font-size: 1.2rem; }
  .builder__row { grid-template-columns: minmax(0, 1fr); }
  .viewer { min-height: 280px; }
}

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

@media print {
  .rail, .app-nav, .theme-toggle, .viewer__bar { display: none; }
  body { background: #fff; color: #000; }
}

/* Defensive, and last so it wins on equal specificity: any element carrying the
   `hidden` attribute stays hidden. A class that sets an explicit `display`
   silently overrides the user-agent rule behind `[hidden]`, which is how the
   viewer's empty overlay stayed on top of a structure that had loaded. Anything
   toggled with `hidden` in JS is exposed to the same trap. */
[hidden] { display: none !important; }
