/* ============================================================================
 * v1-fleet.css: the v1 multi-device fleet figure (.v1fig), real size.
 *
 * ONE stylesheet for both copies of the figure: the gate fixture
 * (web/figures/tsvetok-v1-fleet.html) and the in-page embed (the v1 figure on
 * the Tsvetok case-study page). Each copy links this file from inside its
 * .v1fig root, so check-figure-parity.mjs can assert both reference it.
 *
 * Nothing here is transform-scaled. The figure lays itself out for the width
 * its container gives it (a CSS container query on the .v1fig root):
 *   stack  < 560px   one column, reading order Plate → Satellite → Jetson →
 *                    Bridge → Hue → UniFi; the appliances sit indented so the
 *                    Bridge → UniFi wire runs down its own gutter (a rail)
 *   mid    560-899   plate + Jetson on top, Satellite + Bridge below, Hue and
 *                    UniFi side by side under the Bridge
 *   wide   ≥ 900     the desktop composition: Hue and UniFi beside the Bridge
 * The driver (v1-fleet.js) reads --v1f-mode to pick its connector routes and
 * measures node boxes for every endpoint; no coordinate is typed here.
 *
 * Everything is scoped under .v1fig, and the root pins its own font-family,
 * size, line-height, letter-spacing and text-wrap style so page styles cannot
 * leak in, and the fixture wraps its lines exactly as the page does. The
 * panel is dark in both site themes (figure-local tokens, never page tokens).
 * ==========================================================================*/

.v1fig {
  --v1f-deep-void: #05080A; --v1f-panel-dark: #0B1219; --v1f-code-bg: #0F1620;
  --v1f-neon-gold: #FFD700; --v1f-neon-gold-warm: #F2C24A; --v1f-neon-cyan: #00F0FF; --v1f-accent-violet: #A07AFF;
  --v1f-text-primary: #FFFFFF; --v1f-text-secondary: #A0AAB5; --v1f-text-muted: #7A848F;
  --v1f-cyber-border: rgba(255,215,0,0.50); --v1f-cyber-border-hairline: rgba(255,215,0,0.24);
  --v1f-font-display: "Orbitron", ui-sans-serif, system-ui, sans-serif;
  --v1f-font-mono: "Fira Code", ui-monospace, "SF Mono", Menlo, monospace;
  container: v1fig / inline-size;
  display: block;
  width: 100%;
  color: var(--v1f-text-primary);
  font-family: var(--v1f-font-mono);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
  overflow-wrap: normal;
  hyphens: manual;
  text-wrap-mode: wrap;
  text-wrap-style: pretty;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
}
.v1fig *, .v1fig *::before, .v1fig *::after { margin: 0; padding: 0; box-sizing: border-box; }

/* a token that must never split across lines (SMART-HOME, 192.168.1.0/24 …).
   Set balance / pretty with the text-wrap-style longhand only: the text-wrap
   shorthand also resets text-wrap-mode to wrap, undoing this on any element
   it matches */
.v1fig .v1f-nw { white-space: nowrap; }

/* ---- the dark canvas: faint gold grid, hairline rim, chamfered corners ---- */
.v1fig .v1f-canvas {
  --v1f-cut: 14px;
  position: relative;
  padding: 20px 14px 18px;
  background:
    radial-gradient(120% 90% at 50% 8%, rgba(255,215,0,0.05), rgba(255,215,0,0) 60%),
    linear-gradient(180deg, rgba(11,18,25,0.45) 0%, rgba(5,8,10,0.65) 100%),
    repeating-linear-gradient(0deg, rgba(255,215,0,0.04) 0 1px, transparent 1px 100px),
    repeating-linear-gradient(90deg, rgba(255,215,0,0.04) 0 1px, transparent 1px 100px),
    var(--v1f-deep-void);
  border: 1px solid var(--v1f-cyber-border-hairline);
  clip-path: polygon(var(--v1f-cut) 0%, calc(100% - var(--v1f-cut)) 0%, 100% var(--v1f-cut),
    100% calc(100% - var(--v1f-cut)), calc(100% - var(--v1f-cut)) 100%, var(--v1f-cut) 100%,
    0% calc(100% - var(--v1f-cut)), 0% var(--v1f-cut));
}
.v1fig .v1f-figmeta {
  font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--v1f-text-muted); margin-bottom: 18px;
}

/* L-shaped frame brackets (decor) */
.v1fig .v1f-bracket { position: absolute; z-index: 0; width: 26px; height: 26px; pointer-events: none;
  border: 1.4px solid rgba(242,194,74,0.34); }
.v1fig .v1f-bracket.v1f-tl { left: 6px; top: 6px; border-right: 0; border-bottom: 0; }
.v1fig .v1f-bracket.v1f-tr { right: 6px; top: 6px; border-left: 0; border-bottom: 0; }
.v1fig .v1f-bracket.v1f-bl { left: 6px; bottom: 6px; border-right: 0; border-top: 0; }
.v1fig .v1f-bracket.v1f-br { right: 6px; bottom: 6px; border-left: 0; border-top: 0; }

/* ---- the flow: a grid of nodes; wires and edge labels float above it ---- */
.v1fig .v1f-flow {
  --v1f-mode: stack;
  position: relative;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  grid-template-rows: auto 18px auto minmax(96px, auto) auto 92px auto 44px auto 14px auto;
  grid-template-areas:
    "plate  plate"
    ".      ."
    "sat    sat"
    "void   void"
    "jetson jetson"
    ".      ."
    "bridge bridge"
    ".      ."
    ".      hue"
    ".      ."
    ".      unifi";
}
.v1fig .v1f-plate     { grid-area: plate; align-self: start; }
.v1fig #v1-jetson     { grid-area: jetson; }
.v1fig #v1-satellite  { grid-area: sat; }
.v1fig #v1-bridge     { grid-area: bridge; }
.v1fig #v1-hue        { grid-area: hue; }
.v1fig #v1-unifi      { grid-area: unifi; }
.v1fig .v1f-void      { grid-area: void; justify-self: end; align-self: start; margin-top: 26px; }
.v1fig .v1f-appliances { display: contents; }

/* SVG wire layer + edge-label layer: out of flow, same origin as the flow box,
   so the driver draws in the flow's own CSS-pixel space (no scale factor). */
.v1fig .v1f-flow .v1f-wires,
.v1fig .v1f-flow .v1f-labels {
  position: absolute; inset: 0; width: 100%; height: 100%; min-width: 0; max-width: none;
  overflow: visible; pointer-events: none; display: block;
}
.v1fig .v1f-flow .v1f-wires { z-index: 1; }
.v1fig .v1f-flow .v1f-labels { z-index: 4; }

/* ambient light pools (decor), placed on grid areas so they follow the nodes */
.v1fig .v1f-ambient { position: absolute; z-index: 0; pointer-events: none; border-radius: 50%; }
.v1fig .v1f-halo {
  grid-area: jetson; inset: -70px -40px;
  background: radial-gradient(closest-side, rgba(255,215,0,0.24), rgba(255,215,0,0.07) 46%, rgba(255,215,0,0) 74%);
}
.v1fig .v1f-pool {
  grid-row: bridge; grid-column: 1 / -1; inset: -40px -30px;
  background: radial-gradient(closest-side, rgba(255,215,0,0.05), rgba(255,215,0,0) 72%);
}

/* "⌀ no subscriber": labels the dead-end's terminus (the driver ends the
   dashed line beside it). Plain HTML so it reads without JavaScript. */
.v1fig .v1f-void {
  position: relative; z-index: 2;
  font-size: 13px; letter-spacing: 0.07em; color: var(--v1f-neon-gold-warm); opacity: 0.92;
  white-space: nowrap;
}

/* ---- NODE: the un-clipped wrapper carries the glow (drop-shadow survives
        because clip-path lives on the inner panel; clip-path clips after filter) */
.v1fig .v1f-node {
  position: relative; z-index: 3; min-width: 0;
  display: flex; flex-direction: column;
  filter: drop-shadow(0 14px 22px rgba(0,0,0,0.72)) drop-shadow(0 0 12px rgba(242,194,74,0.10));
}
.v1fig .v1f-node .v1f-panel {
  --ch: 13px;
  --chamfer: polygon(var(--ch) 0, calc(100% - var(--ch)) 0, 100% var(--ch), 100% calc(100% - var(--ch)),
    calc(100% - var(--ch)) 100%, var(--ch) 100%, 0 calc(100% - var(--ch)), 0 var(--ch));
  position: relative; flex: 1 1 auto;
  display: flex; flex-direction: column; gap: 5px;
  padding: 16px 16px;
  /* solid background-COLOR so the verify-figure gate recognises the panel as a box */
  background-color: var(--v1f-panel-dark);
  background-image: linear-gradient(168deg, rgba(22,31,42,0.55), rgba(11,18,25,0) 60%);
  clip-path: var(--chamfer);
}
/* the chamfered gold rim: a 1.3px ring that follows the bevel (mask exclude) */
.v1fig .v1f-node .v1f-panel::before {
  content: ''; position: absolute; inset: 0; padding: 1.3px; pointer-events: none;
  background: linear-gradient(150deg, var(--v1f-neon-gold-warm), rgba(242,194,74,0.30) 52%, var(--v1f-neon-gold-warm));
  clip-path: var(--chamfer);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
/* the inner parallel stroke ~6px inside the rim: the double-stroke panel */
.v1fig .v1f-node .v1f-panel::after {
  content: ''; position: absolute; inset: 6px; padding: 0.9px; pointer-events: none;
  --ch2: 6px; background: var(--v1f-neon-gold); opacity: 0.34;
  clip-path: polygon(var(--ch2) 0, calc(100% - var(--ch2)) 0, 100% var(--ch2), 100% calc(100% - var(--ch2)),
    calc(100% - var(--ch2)) 100%, var(--ch2) 100%, 0 calc(100% - var(--ch2)), 0 var(--ch2));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.v1fig .v1f-node.v1f-plate .v1f-panel::after,
.v1fig .v1f-node.v1f-chip .v1f-panel::after { display: none; }

/* corner accents: a fixed L-bracket re-stroking each accented chamfer */
.v1fig .v1f-node .v1f-acc { position: absolute; width: 25px; height: 25px; overflow: visible; pointer-events: none; }
.v1fig .v1f-node .v1f-acc path { fill: none; stroke: var(--v1f-neon-gold); stroke-width: 1; stroke-opacity: 0.45;
  stroke-linecap: round; stroke-linejoin: round; }
.v1fig .v1f-node .v1f-acc.v1f-tl { left: 0; top: 0; }
.v1fig .v1f-node .v1f-acc.v1f-tr { right: 0; top: 0; transform: scaleX(-1); }
.v1fig .v1f-node .v1f-acc.v1f-bl { left: 0; bottom: 0; transform: scaleY(-1); }
.v1fig .v1f-node .v1f-acc.v1f-br { right: 0; bottom: 0; transform: scale(-1, -1); }
.v1fig .v1f-node.v1f-brain .v1f-acc path { stroke: var(--v1f-neon-gold-warm); stroke-width: 1.2; stroke-opacity: 0.85; }
.v1fig .v1f-node.v1f-plate .v1f-acc path { stroke: var(--v1f-neon-gold-warm); stroke-width: 1.2; stroke-opacity: 0.9; }

/* BRAIN: the Jetson, warmer and brighter, with a thicker rim */
.v1fig .v1f-node.v1f-brain {
  filter: drop-shadow(0 14px 26px rgba(0,0,0,0.70)) drop-shadow(0 0 30px rgba(255,215,0,0.20)) drop-shadow(0 0 10px rgba(255,215,0,0.28));
}
.v1fig .v1f-node.v1f-brain .v1f-panel {
  padding: 18px 18px;
  background-color: #0B1219;
  background-image: linear-gradient(170deg, rgba(40,32,8,0.55), rgba(11,18,25,0) 62%);
}
.v1fig .v1f-node.v1f-brain .v1f-panel::before {
  padding: 1.7px;
  background: linear-gradient(150deg, var(--v1f-neon-gold), var(--v1f-neon-gold-warm) 55%, var(--v1f-neon-gold));
}

/* PLATE: the trigger-gap receipt, deep-void interior and warm rim */
.v1fig .v1f-node.v1f-plate .v1f-panel { --ch: 11px; background: rgba(5,8,10,0.80); }
.v1fig .v1f-node.v1f-plate .v1f-panel::before {
  background: linear-gradient(150deg, var(--v1f-neon-gold-warm), rgba(242,194,74,0.22) 55%, var(--v1f-neon-gold-warm));
}

/* CHIP: a small network appliance, cyan rim */
.v1fig .v1f-node.v1f-chip { filter: drop-shadow(0 10px 16px rgba(0,0,0,0.7)) drop-shadow(0 0 10px rgba(0,240,255,0.10)); }
.v1fig .v1f-node.v1f-chip .v1f-panel { --ch: 9px; padding: 12px 16px; gap: 4px; background: rgba(15,22,32,0.92); }
.v1fig .v1f-node.v1f-chip .v1f-panel::before {
  background: linear-gradient(150deg, var(--v1f-neon-cyan), rgba(0,240,255,0.28) 55%, var(--v1f-neon-cyan));
}

/* ---- type ---- */
/* a tag that wraps (phones) is balanced, so no word is left alone on a line */
.v1fig .v1f-node .v1f-tag {
  font-size: 13px; font-weight: 500; line-height: 1.3; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--v1f-neon-gold-warm); text-wrap-style: balance;
}
.v1fig .v1f-node .v1f-tag.v1f-cyan { color: var(--v1f-neon-cyan); }
.v1fig .v1f-node .v1f-title {
  font-family: var(--v1f-font-display); font-weight: 600; font-size: 17px; line-height: 1.2;
  letter-spacing: 0.01em; color: var(--v1f-text-primary); margin-bottom: 2px;
}
.v1fig .v1f-node.v1f-brain .v1f-title { font-size: 18px; }
.v1fig .v1f-node .v1f-title.v1f-sm { font-size: 16px; }
.v1fig .v1f-node .v1f-sub { font-size: 14px; line-height: 1.45; color: var(--v1f-text-secondary); }
.v1fig .v1f-node .v1f-sub.v1f-muted { color: var(--v1f-text-muted); }
.v1fig .v1f-node .v1f-sub.v1f-cyan { color: var(--v1f-neon-cyan); }
.v1fig .v1f-node .v1f-sub.v1f-violet { color: var(--v1f-accent-violet); }
.v1fig .v1f-node .v1f-sub.v1f-warm { color: var(--v1f-neon-gold-warm); }
.v1fig .v1f-node .v1f-rule { height: 1px; flex: none; background: linear-gradient(90deg, rgba(255,215,0,0.34), rgba(255,215,0,0.06)); margin: 4px 0 2px; }

/* ---- edge labels (created by the driver, centred on their own wire) ---- */
.v1fig .v1f-wlabel {
  position: absolute; transform: translate(-50%, -50%);
  background: var(--v1f-deep-void); padding: 4px 11px;
  border: 1px solid rgba(242,194,74,0.45);
  clip-path: polygon(6px 0, calc(100% - 6px) 0, 100% 50%, calc(100% - 6px) 100%, 6px 100%, 0 50%);
  font-size: 13px; line-height: 1.3; color: var(--v1f-text-secondary); white-space: nowrap;
}

/* ---- legend ---- */
.v1fig .v1f-legend {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 22px; margin-top: 22px;
  font-size: 13px; letter-spacing: 0.04em; color: var(--v1f-text-muted);
}
.v1fig .v1f-legend .v1f-item { display: inline-flex; align-items: center; gap: 8px; }
.v1fig .v1f-legend .v1f-swatch { display: inline-block; flex: none; width: 24px; height: 0; border-top: 2px solid var(--v1f-neon-gold-warm); }
.v1fig .v1f-legend .v1f-swatch.v1f-dash { border-top-style: dashed; }
.v1fig .v1f-legend .v1f-swatch.v1f-cyan { border-top-color: var(--v1f-neon-cyan); }
.v1fig .v1f-legend .v1f-lbl,
.v1fig .v1f-legend .v1f-strong { color: var(--v1f-text-secondary); }

/* ---- mid: two columns, the appliances side by side under the Bridge ---- */
@container v1fig (min-width: 560px) {
  .v1fig .v1f-canvas { --v1f-cut: 18px; padding: 26px 22px 22px; }
  .v1fig .v1f-figmeta { margin-bottom: 22px; }
  .v1fig .v1f-flow {
    --v1f-mode: mid;
    grid-template-columns: minmax(0, 1fr) 28px minmax(0, 1fr);
    grid-template-rows: auto auto 76px auto 40px auto;
    grid-template-areas:
      "plate . jetson"
      "void  . jetson"
      ".     . ."
      "sat   . bridge"
      ".     . ."
      ".     . chips";
  }
  .v1fig .v1f-void { justify-self: end; align-self: end; margin: 14px 0 0; }
  .v1fig .v1f-appliances {
    grid-area: chips; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 16px;
  }
  .v1fig #v1-hue, .v1fig #v1-unifi { grid-area: auto; }
  .v1fig .v1f-pool { grid-row: sat; grid-column: 1 / -1; }
}

/* ---- wide: the desktop composition, Hue and UniFi beside the Bridge ---- */
@container v1fig (min-width: 900px) {
  .v1fig .v1f-canvas { --v1f-cut: 22px; padding: 30px 28px 26px; }
  .v1fig .v1f-flow {
    --v1f-mode: wide;
    grid-template-columns: minmax(0, 1fr) 40px minmax(0, 1fr) 52px max-content;
    grid-template-rows: auto auto 80px auto;
    grid-template-areas:
      "plate . jetson . ."
      "void  . jetson . ."
      ".     . .      . ."
      "sat   . bridge . chips";
  }
  .v1fig .v1f-node .v1f-panel { padding: 18px 18px; }
  .v1fig .v1f-node.v1f-brain .v1f-panel { padding: 20px 20px; }
  .v1fig .v1f-node.v1f-chip .v1f-panel { padding: 13px 18px; }
  .v1fig .v1f-appliances {
    grid-area: chips; display: flex; flex-direction: column; justify-content: center; gap: 22px;
  }
  .v1fig .v1f-halo { inset: -90px -70px; }
  /* the legend in two rows: the three keys, then the hardware note with the
     summary stamp closing the row on the right */
  .v1fig .v1f-legend { display: grid; grid-template-columns: repeat(3, max-content) minmax(0, 1fr); gap: 10px 26px; }
  .v1fig .v1f-legend .v1f-note { grid-row: 2; grid-column: 1 / -1; justify-self: start; }
  .v1fig .v1f-legend .v1f-strong { grid-row: 2; grid-column: 1 / -1; justify-self: end; }
}
