/* Solera controller dashboard — dark theme.
 *
 * All colors are tokens on :root so a light theme is a second token set plus a
 * toggle, not a rewrite. Objectivity is the brand face; until its woff2 is
 * bundled we fall back to a geometric system stack (the controller serves
 * locally and may have no internet, so no web-font CDN). */

/* Brand typeface. Files are bundled into the binary and served from /fonts
 * (no CDN — controller runs offline). The 500–600 range maps to Medium so
 * semibold UI text doesn't get faux-bolded. */
@font-face {
  font-family: "Objectivity";
  src: url("/fonts/Objectivity-Light.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Objectivity";
  src: url("/fonts/Objectivity-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Objectivity";
  src: url("/fonts/Objectivity-Medium.woff2") format("woff2");
  font-weight: 500 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Objectivity";
  src: url("/fonts/Objectivity-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  /* Brand */
  --solera-dark-blue: #29357e;
  --solera-royal-blue: #5f77bc;
  --solera-orange: #ee8425;
  --solera-orange-dim: #b5631a;

  /* Dark theme surfaces */
  --bg: #10162e;
  --bg-glow: #18204a;
  --panel: #1b2348;
  --vessel: #222c5c;
  --vessel-stroke: #3a4684;
  --text: #eef1fb;
  --text-dim: #9aa3cc;
  --text-faint: #6f78a6;

  /* Functional encoding */
  --hot: #e8513b;            /* hot fluid — kept distinct from the interactive orange */
  --warm: #f0a23c;           /* warm fluid (e.g. hot-water return) — amber, between cold and hot */
  --cold: #5f8fe0;           /* cold fluid */
  --relay-off: #2b3666;
  --relay-off-stroke: #46538f;
  --ok: #3ea66a;
  --warn: #caa23b;
  --down: #c8503b;

  /* Objectivity is the brand face; until its woff2 is bundled we fall back to
   * geometric faces that ship locally (Avenir/Futura) — closer to Objectivity
   * than system-ui — then generic sans. No web-font CDN (controller runs offline). */
  --font: "Objectivity", "Avenir Next", "Avenir", "Futura", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font-family: var(--font);
  background: radial-gradient(1100px 700px at 72% -12%, var(--bg-glow), var(--bg));
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
/* Non-responsive: the app and inset wrap tightly to the explicitly-sized
 * schematic (laptop/tablet; a phone layout would be its own thing). Pinned to
 * the left so nothing shifts as the window widens. */
.app { width: fit-content; margin: 0; padding: 26px 24px; }

/* Header */
.topbar { display: flex; align-items: center; gap: 18px; margin-bottom: 20px; }
.brand { display: flex; align-items: center; gap: 6px; }
/* Optical centering: with the wordmark's box-center sitting slightly above its
 * visible text center, the swirl appears to hang low. Nudge it up so the swirl
 * extends equally above SOLERA and below SYSTEMS. */
.brand .mark { transform: translateY(-2px); }
/* Logo lockup: SOLERA over SYSTEMS, both white, SYSTEMS letter-spread to span
 * SOLERA's width (the brand wordmark). .name shrinks to SOLERA's width; SYSTEMS
 * justifies across it. */
.brand .name { display: inline-block; line-height: 1; color: #fff; }
.brand .name b { display: block; font-weight: 500; letter-spacing: 0.2em; margin-right: -0.2em; font-size: 19px; }
/* SYSTEMS: per-letter flex distribution spans SOLERA's width in every browser
 * (single-word CSS justify is unreliable). */
.brand .name .sys { display: flex; justify-content: space-between; width: 100%; margin-top: 5px; font-weight: 400; font-size: 11px; }
.brand .name .sys i { font-style: normal; }
.divider { width: 1px; height: 26px; background: var(--vessel-stroke); }
.title { line-height: 1; }
.title-name { font-size: 15px; color: var(--text-dim); font-weight: 500; letter-spacing: 0.02em; }
.title-id { font-size: 11px; color: var(--text-faint); font-weight: 400; letter-spacing: 0.04em; margin-top: 4px; }
.spacer { flex: 1; }
/* Padding is asymmetric on both axes to optically center the text:
 *  - left +1 compensates for trailing letter-spacing (text reads left of box center)
 *  - top +1 / bottom -1 compensates for font metrics (cap-to-baseline mass sits
 *    above the line-box center). */
.pill { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; padding: 7px 13px 5px 14px; border-radius: 999px; border: 1px solid var(--vessel-stroke); color: var(--text-dim); }
.pill.mode { color: var(--solera-orange); border-color: var(--solera-orange-dim); }
.status { font-size: 12px; color: var(--text-faint); display: flex; align-items: center; gap: 7px; }
.status .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); }
/* Optical centering: the cap-to-baseline mass of the font sits above the line-
 * box center, so nudge the text down by 1px to match the dot. */
.status #status-text { transform: translateY(1px); }
.status.stale .dot { background: var(--warn); }
.status.down .dot { background: var(--down); }

/* Panel + schematic */
.panel { background: var(--panel); border: 1px solid var(--vessel-stroke); border-radius: 16px; padding: 12px; width: fit-content; }
.schematic { display: block; }  /* explicit width/height set by fitSchematic — do not force width:100% */

.vessel { fill: var(--vessel); stroke: var(--vessel-stroke); stroke-width: 1.5; }
.vessel-label { fill: var(--text); font-size: 15px; font-weight: 600; letter-spacing: 0.03em; }
.vessel-sub { fill: var(--text-faint); font-size: 10px; letter-spacing: 0.16em; }
/* Iconographic detail inside vessels (plate pack, fan, lid seam). The bright
 * detail matches the component line idiom; the faint variant is for seams. */
.vessel-detail { fill: none; stroke: var(--text-dim); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.vessel-detail-faint { fill: none; stroke: var(--vessel-stroke); stroke-width: 1.5; }
.vessel-hub { fill: var(--text-dim); stroke: none; }

.pipe { fill: none; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.pipe.hot { stroke: var(--hot); }
.pipe.warm { stroke: var(--warm); }
.pipe.cold { stroke: var(--cold); }
.pipe-hit { fill: none; stroke: transparent; stroke-width: 16; pointer-events: stroke; }
.port { fill: var(--text-faint); font-size: 11px; letter-spacing: 0.12em; }
/* Junctions (tees): lines just intersect; the anchor shows only in dev so it
 * can be dragged. */
.junction { fill: var(--solera-orange); stroke: #fff; stroke-width: 1; visibility: hidden; cursor: move; }
.schematic.editable .junction { visibility: visible; }

/* Component symbols — stroked, engineering-native (P&ID-literate) line idiom.
 * Shape geometry lives in app.js; these tokens carry the look. */
.sym-line { fill: none; stroke: var(--text-dim); stroke-width: 2; }
.sym-line-inner { fill: none; stroke: var(--text-dim); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.sym-tag { fill: var(--text-dim); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; }

/* RTD well / taped-on thermocouple — small circle that interrupts the pipe. */
.rtd-well { fill: var(--bg); stroke: var(--text-dim); stroke-width: 2; }

.flow-arrow { stroke: none; }
.flow-arrow.hot { fill: var(--hot); }
.flow-arrow.warm { fill: var(--warm); }
.flow-arrow.cold { fill: var(--cold); }

.temp { fill: var(--text); font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }
.temp-tag { fill: var(--text-dim); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; }

/* Relays — interactive, in place */
.relay { cursor: pointer; }
.relay .node { fill: var(--relay-off); stroke: var(--relay-off-stroke); stroke-width: 1.5; transition: fill .15s ease, stroke .15s ease; }
.relay .glyph { fill: var(--text-dim); font-size: 11px; font-weight: 700; }
.relay .label { fill: var(--text-dim); font-size: 10.5px; }
.relay .state { fill: var(--text-faint); font-size: 9px; letter-spacing: 0.12em; }
.relay:hover .node { stroke: var(--solera-orange); }
.relay.on .node { fill: var(--solera-orange); stroke: var(--solera-orange); }
.relay.on .glyph { fill: #1b1205; }
.relay.on .state { fill: var(--solera-orange); }

/* Same interactive encoding for the line symbols. */
.relay:hover .sym-line, .relay:hover .sym-line-inner { stroke: var(--solera-orange); }
.relay.on .sym-line, .relay.on .sym-line-inner { stroke: var(--solera-orange); }
.relay.on .sym-tag { fill: var(--solera-orange); }

/* Dev-only controls */
.dev-btn { font-family: var(--font); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; padding: 6px 13px; border-radius: 999px; background: transparent; color: var(--hot); border: 1px solid var(--hot); cursor: pointer; }
.dev-btn:hover { background: var(--hot); color: #fff; }
.hidden { display: none; }
.schematic.editable [data-id] { cursor: move; }
.elbow { fill: var(--solera-orange); stroke: #fff; stroke-width: 1; visibility: hidden; cursor: move; }
.schematic.editable .elbow { visibility: visible; }

