/* =========================================================
   components.css

   The design system's components where bridge.css and concept.css do not already
   draw them. Scoped like those two (html[data-ui="next"]) so it competes on equal
   terms with them until A10 strips the prefix from all three at once, and loaded
   after them so a component defined here wins a tie.
   ========================================================= */

/* ---------- Button: the variants and sizes concept.css does not have ---------- */
/* Amber with night text: a call to action on night or marketing surfaces only.
   White on amber fails contrast (1.9:1); night on amber is 11.6:1. */
html[data-ui="next"] .btn.btn-accent{
  background:var(--amber); color:var(--on-amber); border-color:var(--amber);
}
html[data-ui="next"] .btn.btn-accent:hover{ background:var(--amber-hover); border-color:var(--amber-hover); }

/* 56px: a gloved hand on a scanner's screen. */
html[data-ui="next"] .btn.btn-touch{ min-height:var(--touch-min); padding:0 20px; font-size:15px; }

/* Icon only: square, the glyph centred. */
html[data-ui="next"] .btn.btn-icon{ padding:0; width:32px; justify-content:center; }
html[data-ui="next"] .btn.btn-icon.btn-sm{ width:28px; }
html[data-ui="next"] .btn.btn-icon.btn-lg{ width:38px; }
html[data-ui="next"] .btn.btn-icon.btn-touch{ width:var(--touch-min); }

/* ---------- Segmented, small ---------- */
html[data-ui="next"] .seg.seg-sm button{ padding:4px 10px; font-size:12.5px; }

/* ---------- Pager: the gap between page runs ---------- */
html[data-ui="next"] .pager .pager-gap{ align-self:center; padding:0 4px; color:var(--ink-faint); }

/* ---------- Progress: a bar coloured by meaning ---------- */
html[data-ui="next"] .progress-bar.is-good{ background:var(--good); }
html[data-ui="next"] .progress-bar.is-warn{ background:var(--warn); }
html[data-ui="next"] .progress-bar.is-crit{ background:var(--crit); }

/* ---------- Accordion, on <details> ---------- */
html[data-ui="next"] .vn-acc{ border:1px solid var(--line); border-radius:var(--radius-md); background:var(--surface-raised); overflow:hidden; }
html[data-ui="next"] .vn-acc-item + .vn-acc-item{ border-top:1px solid var(--line); }
html[data-ui="next"] .vn-acc-head{
  display:flex; align-items:center; gap:10px;
  padding:12px 16px; cursor:pointer; list-style:none;
  font-weight:600; color:var(--ink);
}
html[data-ui="next"] .vn-acc-head::-webkit-details-marker{ display:none; }
html[data-ui="next"] .vn-acc-head:hover{ background:color-mix(in srgb, var(--ink) 4%, transparent); }
html[data-ui="next"] .vn-acc-title{ flex:1; min-width:0; }
html[data-ui="next"] .vn-acc-chev{ color:var(--ink-muted); transition:rotate .18s var(--ease); }
html[data-ui="next"] .vn-acc-item[open] > .vn-acc-head .vn-acc-chev{ rotate:180deg; }
html[data-ui="next"] .vn-acc-body{ padding:4px 16px 16px; color:var(--ink-muted); }

/* ---------- Toasts ---------- */
html[data-ui="next"] .vn-toasts{
  position:fixed; left:50%; bottom:24px; translate:-50% 0;
  z-index:var(--z-toast);
  display:flex; flex-direction:column; align-items:center; gap:8px;
  pointer-events:none;
}
html[data-ui="next"] .vn-toast{
  pointer-events:auto;
  display:flex; align-items:center; gap:12px;
  min-width:280px; max-width:min(520px, calc(100vw - 32px));
  padding:10px 10px 10px 14px;
  background:var(--night); color:var(--on-night);
  border-radius:var(--radius-sm); box-shadow:var(--shadow-pop);
  font-size:13.5px;
  animation:vn-toast-in .22s var(--ease) both;
}
/* The tone is a 3px edge, so the text stays on night and keeps its contrast. */
html[data-ui="next"] .vn-toast.is-good{ box-shadow:inset 3px 0 0 var(--good-night), var(--shadow-pop); }
html[data-ui="next"] .vn-toast.is-warn{ box-shadow:inset 3px 0 0 var(--warn-night), var(--shadow-pop); }
html[data-ui="next"] .vn-toast.is-crit{ box-shadow:inset 3px 0 0 var(--crit-night), var(--shadow-pop); }
html[data-ui="next"] .vn-toast.is-info{ box-shadow:inset 3px 0 0 var(--signal-night), var(--shadow-pop); }
html[data-ui="next"] .vn-toast-text{ flex:1; min-width:0; }
html[data-ui="next"] .vn-toast-action{
  background:none; border:0; padding:4px 6px; border-radius:var(--radius-xs);
  color:var(--amber); font-weight:600; cursor:pointer;
}
html[data-ui="next"] .vn-toast-action:hover{ background:var(--night-raised); }
html[data-ui="next"] .vn-toast-x{
  background:none; border:0; padding:4px; border-radius:var(--radius-xs);
  color:var(--on-night-muted); cursor:pointer; display:inline-flex;
}
html[data-ui="next"] .vn-toast-x:hover{ color:var(--on-night); background:var(--night-raised); }
@keyframes vn-toast-in{ from{ opacity:0; translate:0 8px; } to{ opacity:1; translate:0 0; } }
@media (prefers-reduced-motion:reduce){
  html[data-ui="next"] .vn-toast{ animation:none; }
  html[data-ui="next"] .vn-acc-chev{ transition:none; }
}

/* ---------- Logo ---------- */
/* The lockup and the mark never squeeze in a flex row; their width follows the height. */
html[data-ui="next"] .vn-logo,
html[data-ui="next"] .vn-mark{ flex-shrink:0; width:auto; }
/* A brand without a lockup of its own: its mark and its name, set in the wordmark's place. */
html[data-ui="next"] .vn-logo-named{ display:inline-flex; align-items:center; gap:.4em; font-family:var(--font-sans);
  font-weight:700; line-height:1; letter-spacing:-.01em; color:var(--ink); white-space:nowrap; }
html[data-ui="next"] .vn-logo-named.vn-logo-night{ color:var(--on-night); }

/* ---------- Radio-button groups (btn-check + label.btn) ---------- */
/* The checked option reads as Segmented's: a teal tint, teal text. Bootstrap drew it
   from variables the design system's buttons never set, so it only got an outline. */
html[data-ui="next"] .btn-check:checked + .btn,
html[data-ui="next"] .btn-check:active + .btn{
  background:var(--signal-soft); color:var(--signal);
  border-color:color-mix(in srgb, var(--signal) 30%, transparent);
  font-weight:600;
}
html[data-ui="next"] .btn-check:focus-visible + .btn{ outline:2px solid var(--focus); outline-offset:2px; }

/* =========================================================
   A5: the existing components in the approved Vision look
   (brand/design-reference/components: StatusChip, Tabs, DeviceTable,
   Button). Same markup and classes; only the paint changes.
   ========================================================= */

/* Chips: soft-filled pills, no outline. */
html[data-ui="next"] .chip{
  border-radius:var(--radius-full);
  border-color:transparent;
  background:var(--surface-sunken);
  color:var(--ink-muted);
  font-weight:600;
  padding:2px 9px;
}
html[data-ui="next"] .chip.chip-on{ background:var(--signal-soft); color:var(--signal); border-color:transparent; }
html[data-ui="next"] .chip.chip-off{ background:var(--surface-sunken); color:var(--ink-muted); }
html[data-ui="next"] .chip.chip-warn{ background:var(--warn-soft); color:var(--warn); border-color:transparent; }
html[data-ui="next"] .chip.chip-crit,
html[data-ui="next"] .chip.chip-alert{ background:var(--crit-soft); color:var(--crit); border-color:transparent; }

/* Tabs: the current tab is ink, underlined in ink. Teal is for links and data. */
html[data-ui="next"] .tabs button.on{ color:var(--ink); border-bottom-color:var(--ink); font-weight:600; }

/* Table heads: small uppercase labels, as the reference's device table. */
html[data-ui="next"] table.tbl th{
  font-size:11px; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-muted);
}
html[data-ui="next"] table.tbl tbody tr:hover > td{ background:var(--surface); }

/* Primary buttons: ink with a hairline of light along the top edge. */
html[data-ui="next"] .btn.btn-blue{ box-shadow:inset 0 1px 0 color-mix(in srgb, var(--on-inverse) 12%, transparent), var(--shadow-1); }
html[data-ui="next"] .btn.btn-accent{ box-shadow:inset 0 1px 0 color-mix(in srgb, var(--on-inverse) 35%, transparent), var(--shadow-1); }

/* =========================================================
   D1: status chips, the instrument strip and the fleet table
   (brand/design-reference/components: StatusChip, LocationLabel,
   DeviceTable). The readouts are the family's own: no cards,
   no delta pills, a drawing per figure.
   ========================================================= */

/* ---------- Status: one shape for every state ---------- */
/* StatusChip, StatusDot and the identity history's .dot-* rows share it. */
html[data-ui="next"] .vn-status,
html[data-ui="next"] .dot.dot-good,
html[data-ui="next"] .dot.dot-warn,
html[data-ui="next"] .dot.dot-crit,
html[data-ui="next"] .dot.dot-idle,
html[data-ui="next"] .dot.dot-info{
  display:inline-flex; align-items:center; gap:7px;
  height:24px; padding:0 10px 0 8px;
  border-radius:var(--radius-full);
  font-size:12.5px; line-height:1; font-weight:600; white-space:nowrap;
  background:var(--surface-sunken); color:var(--ink-muted);
}
html[data-ui="next"] .vn-status::before,
html[data-ui="next"] .dot.dot-good::before,
html[data-ui="next"] .dot.dot-warn::before,
html[data-ui="next"] .dot.dot-crit::before,
html[data-ui="next"] .dot.dot-idle::before,
html[data-ui="next"] .dot.dot-info::before{
  content:""; flex:none; width:6px; height:6px;
  border-radius:var(--radius-full); background:currentColor;
  box-shadow:0 0 0 3px color-mix(in srgb, currentColor 22%, transparent);
}
html[data-ui="next"] .vn-status-good, html[data-ui="next"] .dot.dot-good{ background:var(--good-soft); color:var(--good); }
html[data-ui="next"] .vn-status-warn, html[data-ui="next"] .dot.dot-warn{ background:var(--warn-soft); color:var(--warn); }
html[data-ui="next"] .vn-status-crit, html[data-ui="next"] .dot.dot-crit{ background:var(--crit-soft); color:var(--crit); }
html[data-ui="next"] .vn-status-info, html[data-ui="next"] .dot.dot-info{ background:var(--signal-soft); color:var(--signal); }
html[data-ui="next"] .vn-status-live::before{ animation:vn-pulse 1.8s ease-out infinite; }
@keyframes vn-pulse{
  0%{ box-shadow:0 0 0 0 color-mix(in srgb, currentColor 45%, transparent); }
  100%{ box-shadow:0 0 0 7px color-mix(in srgb, currentColor 0%, transparent); }
}
@media (prefers-reduced-motion:reduce){ html[data-ui="next"] .vn-status-live::before{ animation:none; } }

/* ---------- Instrument strip ---------- */
/* The hairlines are each cell's left and top edge, drawn over its neighbour; the outer ones
   are clipped. A short last row leaves no grey gaps, as a gap-on-a-line background would. */
html[data-ui="next"] .vn-readouts{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));
  background:var(--surface-raised);
  border:1px solid var(--line); border-radius:var(--radius-md);
  overflow:hidden;
}
html[data-ui="next"] .vn-readout{
  display:flex; flex-direction:column; gap:10px; min-width:0;
  padding:var(--space-4) var(--space-5) var(--space-4);
  background:var(--surface-raised); color:var(--ink); text-decoration:none;
  box-shadow:-1px 0 0 var(--line), 0 -1px 0 var(--line);
}
html[data-ui="next"] a.vn-readout-link:hover{ background:var(--surface); }
html[data-ui="next"] a.vn-readout-link:focus-visible{ outline:2px solid var(--focus); outline-offset:-2px; }
html[data-ui="next"] .vn-readout-label{
  font:var(--type-label); letter-spacing:.1em; text-transform:uppercase; color:var(--ink-muted);
}
html[data-ui="next"] .vn-readout-value{
  font:var(--type-metric); font-variant-numeric:tabular-nums; letter-spacing:-.01em;
  display:flex; align-items:baseline; gap:6px; min-width:0;
}
html[data-ui="next"] .vn-readout-of{ font:500 15px/1 var(--font-sans); color:var(--ink-muted); letter-spacing:0; }
html[data-ui="next"] .vn-readout-visual{ display:block; }
html[data-ui="next"] .vn-readout-note{
  display:flex; flex-wrap:wrap; gap:6px 10px; align-items:center;
  font-size:12.5px; line-height:16px; color:var(--ink-muted);
}

/* The fleet as a barcode. */
/* Spread across the readout like a printed code, whether the fleet is 12 devices or 400. */
html[data-ui="next"] .vn-fleet{ display:flex; align-items:stretch; justify-content:space-between; gap:1px; height:28px; overflow:hidden; }
html[data-ui="next"] .vn-fleet i{ flex:1 1 0; min-width:1px; max-width:3px; border-radius:1px; background:var(--ink); }
html[data-ui="next"] .vn-fleet i.w{ max-width:6px; flex-grow:2; }
html[data-ui="next"] .vn-fleet i.q{ background:var(--line-strong); }
html[data-ui="next"] .vn-fleet i.warn{ background:var(--warn); }
html[data-ui="next"] .vn-fleet i.crit{ background:var(--crit); }

/* The day as its hours. */
html[data-ui="next"] .vn-hours{ display:block; }
html[data-ui="next"] .vn-hours-cols{ display:grid; grid-template-columns:repeat(24, 1fr); gap:2px; align-items:end; height:28px; }
html[data-ui="next"] .vn-hours-cols i{
  display:block; height:calc(var(--h) * 1%); min-height:2px; border-radius:1px 1px 0 0;
  background:color-mix(in srgb, var(--ink) 38%, transparent);
}
html[data-ui="next"] .vn-hours-cols i.zero{ background:var(--line); }
html[data-ui="next"] .vn-hours-cols i.now{ background:var(--amber); min-height:4px; }
html[data-ui="next"] .vn-hours-cols i.next{ height:2px; background:var(--line); }
html[data-ui="next"] .vn-hours-ticks{
  display:grid; grid-template-columns:repeat(4, 1fr); margin-top:4px;
  font:500 10px/1 var(--font-sans); letter-spacing:.06em; color:var(--ink-faint); font-variant-numeric:tabular-nums;
}
html[data-ui="next"] .vn-hours-ticks b{ font-weight:500; }

/* ---------- Location label: the amber beam label ---------- */
html[data-ui="next"] .vn-loc{
  display:inline-flex; align-items:center; gap:10px; height:40px; padding:0 12px 0 8px;
  border-radius:var(--radius-xs); background:var(--amber); color:var(--on-amber);
  box-shadow:inset 0 -2px 0 color-mix(in srgb, var(--night) 12%, transparent);
}
html[data-ui="next"] .vn-loc-bars{ display:block; width:30px; height:24px; }
html[data-ui="next"] .vn-loc-bars rect{ fill:var(--on-amber); }
html[data-ui="next"] .vn-loc-code{ font:var(--type-location); line-height:1; letter-spacing:.06em; font-variant-numeric:tabular-nums; }
html[data-ui="next"] .vn-loc-code i{ font-style:normal; opacity:.4; padding:0 1px; }
html[data-ui="next"] .vn-loc-sm{ height:24px; gap:6px; padding:0 7px 0 5px; }
html[data-ui="next"] .vn-loc-sm .vn-loc-bars{ width:16px; height:13px; }
html[data-ui="next"] .vn-loc-sm .vn-loc-code{ font-size:12.5px; }

/* ---------- Signal and battery ---------- */
html[data-ui="next"] .vn-signal{ display:inline-flex; align-items:center; white-space:nowrap; }
html[data-ui="next"] .vn-bars{ display:inline-flex; align-items:flex-end; gap:2px; height:14px; margin-right:8px; }
html[data-ui="next"] .vn-bars i{ width:3px; border-radius:1px; background:var(--line); }
html[data-ui="next"] .vn-bars i:nth-child(1){ height:4px; }
html[data-ui="next"] .vn-bars i:nth-child(2){ height:7px; }
html[data-ui="next"] .vn-bars i:nth-child(3){ height:10px; }
html[data-ui="next"] .vn-bars i:nth-child(4){ height:14px; }
html[data-ui="next"] .vn-bars[data-level="4"] i,
html[data-ui="next"] .vn-bars[data-level="3"] i:nth-child(-n+3),
html[data-ui="next"] .vn-bars[data-level="2"] i:nth-child(-n+2){ background:var(--ink); }
html[data-ui="next"] .vn-bars[data-level="1"] i:nth-child(1){ background:var(--warn); }
html[data-ui="next"] .vn-dbm{ font-size:12px; color:var(--ink-muted); font-variant-numeric:tabular-nums; }
html[data-ui="next"] .vn-batt{ display:inline-flex; align-items:center; gap:8px; font-size:13px; font-variant-numeric:tabular-nums; white-space:nowrap; }
html[data-ui="next"] .vn-batt i{ position:relative; width:44px; height:6px; border-radius:var(--radius-full); background:var(--surface-sunken); overflow:hidden; }
html[data-ui="next"] .vn-batt i::before{ content:""; position:absolute; inset:0 auto 0 0; width:calc(var(--pct) * 1%); border-radius:inherit; background:var(--ink-muted); }
html[data-ui="next"] .vn-batt-low{ color:var(--warn); font-weight:600; }
html[data-ui="next"] .vn-batt-low i::before{ background:var(--warn); }

/* ---------- Fleet table cells ---------- */
html[data-ui="next"] .vn-dev{ display:flex; align-items:center; gap:12px; min-width:0; }
html[data-ui="next"] .vn-dev-ico{ width:34px; height:34px; flex:none; border-radius:9px; display:grid; place-items:center; background:var(--surface-sunken); color:var(--ink-muted); }
html[data-ui="next"] .vn-dev-ico svg{ width:18px; height:18px; }
html[data-ui="next"] .vn-dev-name{ display:block; font-weight:600; color:var(--ink); }
html[data-ui="next"] .vn-dev-id{ display:block; font-size:12px; line-height:16px; color:var(--ink-muted); font-variant-numeric:tabular-nums; }
html[data-ui="next"] .vn-op{ display:flex; align-items:center; gap:10px; white-space:nowrap; }
html[data-ui="next"] .vn-avatar{
  width:26px; height:26px; flex:none; border-radius:var(--radius-full);
  display:grid; place-items:center; font-size:10.5px; font-weight:600; letter-spacing:.02em;
  background:var(--surface-sunken); color:var(--ink);
}
html[data-ui="next"] .vn-count{
  display:inline-grid; place-items:center; min-width:20px; height:18px; padding:0 6px; margin-left:6px;
  border-radius:var(--radius-full); background:var(--surface-sunken); color:var(--ink-muted);
  font-size:11.5px; font-weight:600; font-variant-numeric:tabular-nums;
}
html[data-ui="next"] .vn-count-crit{ background:var(--crit-soft); color:var(--crit); }

/* The fleet table's tabs sit on the panel head's rule instead of drawing a second, shorter one. */
html[data-ui="next"] .vn-fleet-panel > .panel-head{ padding-bottom:0; align-items:flex-end; }
html[data-ui="next"] .vn-fleet-panel > .panel-head .tabs{ border-bottom:0; margin-bottom:-1px; }

/* ---------- Health: rules as gauges against their threshold ---------- */
/* Same hairline grid as the readouts, no coloured edges and no tinted cards: the state
   is the word under each rule, and the rail shows how close the value is to alerting. */
html[data-ui="next"] .vn-gauges{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(210px, 1fr));
  background:var(--surface-raised);
  border:1px solid var(--line); border-radius:var(--radius-md);
  overflow:hidden;
}
html[data-ui="next"] .vn-gauge{
  display:flex; flex-direction:column; gap:8px; min-width:0;
  padding:var(--space-3) var(--space-4) var(--space-3);
  box-shadow:-1px 0 0 var(--line), 0 -1px 0 var(--line);
}
html[data-ui="next"] .vn-gauge-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:8px; min-width:0; }
html[data-ui="next"] .vn-gauge-name{
  font-size:12.5px; line-height:16px; font-weight:500; color:var(--ink-muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
}
html[data-ui="next"] .vn-gauge-info{ flex:none; width:13px; height:13px; margin-top:1px; color:var(--ink-faint); cursor:help; }
html[data-ui="next"] .vn-gauge-value{
  font:600 22px/26px var(--font-display); font-variant-numeric:tabular-nums; letter-spacing:-.01em;
  color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
html[data-ui="next"] .vn-gauge-unit{ font:500 12px/1 var(--font-sans); color:var(--ink-muted); margin-left:4px; letter-spacing:0; }
html[data-ui="next"] .vn-gauge-foot{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  font-size:11.5px; line-height:14px; color:var(--ink-muted); white-space:nowrap; min-width:0;
}
html[data-ui="next"] .vn-gauge-rule{ overflow:hidden; text-overflow:ellipsis; min-width:0; font-variant-numeric:tabular-nums; }
html[data-ui="next"] .vn-gauge-state{ display:inline-flex; align-items:center; gap:6px; flex:none; font-weight:600; }
html[data-ui="next"] .vn-gauge-state::before{ content:""; width:6px; height:6px; border-radius:var(--radius-full); background:currentColor; }
html[data-ui="next"] .vn-gauge.is-healthy .vn-gauge-state{ color:var(--good); }
html[data-ui="next"] .vn-gauge.is-warning .vn-gauge-state,
html[data-ui="next"] .vn-gauge.is-warning .vn-gauge-value{ color:var(--warn); }
html[data-ui="next"] .vn-gauge.is-breaching .vn-gauge-state,
html[data-ui="next"] .vn-gauge.is-breaching .vn-gauge-value{ color:var(--crit); }
html[data-ui="next"] .vn-gauge.is-unknown .vn-gauge-value{ color:var(--ink-faint); font-size:17px; }
html[data-ui="next"] .vn-gauge.is-disabled > *{ opacity:.5; }

/* The threshold rail. */
html[data-ui="next"] .vn-thr{ display:block; padding:4px 0; }
html[data-ui="next"] .vn-thr-track{ position:relative; display:block; height:6px; border-radius:var(--radius-full); background:var(--surface-sunken); }
html[data-ui="next"] .vn-thr-zone{
  position:absolute; top:0; bottom:0; border-radius:var(--radius-full);
  background:repeating-linear-gradient(-45deg, var(--line-strong) 0 3px, transparent 3px 6px);
}
html[data-ui="next"] .vn-thr-crit .vn-thr-zone{ background:repeating-linear-gradient(-45deg, var(--crit) 0 3px, transparent 3px 6px); }
html[data-ui="next"] .vn-thr-warn .vn-thr-zone{ background:repeating-linear-gradient(-45deg, var(--warn) 0 3px, transparent 3px 6px); }
html[data-ui="next"] .vn-thr-notch{ position:absolute; left:50%; top:-4px; bottom:-4px; width:2px; margin-left:-1px; border-radius:1px; background:var(--ink); }
html[data-ui="next"] .vn-thr-mark{
  position:absolute; top:50%; width:12px; height:12px; margin:-6px 0 0 -6px;
  border-radius:var(--radius-full); background:var(--ink);
  box-shadow:0 0 0 2px var(--surface-raised);
}
html[data-ui="next"] .vn-thr-good .vn-thr-mark{ background:var(--good); }
html[data-ui="next"] .vn-thr-warn .vn-thr-mark{ background:var(--warn); }
html[data-ui="next"] .vn-thr-crit .vn-thr-mark{ background:var(--crit); }
html[data-ui="next"] .vn-thr-quiet .vn-thr-notch{ background:var(--line-strong); }

/* ---------- A stat tile that leads somewhere (Ui/Stat with an Href) ----------
   The whole tile is the link: no underline, the ink of a plain tile, and the Signal edge of a link card on hover and
   for the keyboard, so a count reads as the way to what it counts. */
html[data-ui="next"] a.stat.is-link{ color:var(--ink); text-decoration:none; transition:border-color .12s ease, box-shadow .12s ease; }
html[data-ui="next"] a.stat.is-link:hover{ border-color:color-mix(in srgb, var(--signal) 45%, var(--line)); box-shadow:var(--shadow-pop); color:var(--ink); }
html[data-ui="next"] a.stat.is-link:focus-visible{ outline:2px solid var(--signal); outline-offset:2px; }
html[data-ui="next"] a.stat.is-link:hover .stat-label{ color:var(--signal); }

/* ---------- The page head's right end (Ui/PageShell): the page's actions, then a quiet Help ---------- */
html[data-ui="next"] .page-head-actions{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
html[data-ui="next"] a.page-help{
  display:inline-flex; align-items:center; gap:5px; min-height:28px; padding:0 8px; border-radius:var(--radius-sm);
  font-size:12.5px; font-weight:500; color:var(--ink-muted); text-decoration:none; white-space:nowrap;
}
html[data-ui="next"] a.page-help:hover{ color:var(--signal); background:color-mix(in srgb, var(--signal) 8%, transparent); }
html[data-ui="next"] a.page-help:focus-visible{ outline:2px solid var(--signal); outline-offset:2px; }
html[data-ui="next"] a.page-help .ico{ width:14px; height:14px; }

/* ---------- Administration: rows, small forms, choices, cards ----------
   The pieces an administration page is built from (the suite's organisation pages first), drawn once here so every
   app's settings look the same. */

/* The buttons at the end of a table row, on the right, never wrapping under each other. */
html[data-ui="next"] .tbl td.row-actions{ text-align:right; white-space:nowrap; width:1%; }
html[data-ui="next"] :not(td).row-actions{ display:flex; justify-content:flex-end; align-items:center; gap:6px; }
html[data-ui="next"] .tbl td.row-actions > *{ display:inline-flex; vertical-align:middle; margin-left:6px; }
html[data-ui="next"] .tbl td.row-actions > *:first-child{ margin-left:0; }
/* The room of an action a row doesn't have (a site without Retire), so the actions of every row line up. */
html[data-ui="next"] .row-action-gap{ visibility:hidden; pointer-events:none; }

/* A dropdown says it is one: a chevron on the right, drawn with two gradients so its colour is a token. */
html[data-ui="next"] select.inp:not([multiple]){
  appearance:none; padding-right:30px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%),
    linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%;
  background-size:5px 5px, 5px 5px;
  background-repeat:no-repeat;
}

/* A search box with room for its words (Find an organisation). */
html[data-ui="next"] .search.search-wide{ min-width:min(18rem, 100%); max-width:28rem; }

/* A form of one field and a button, inside a row or a cell; on a phone the button goes under the field rather than
   past the screen's edge. */
html[data-ui="next"] .inline-form{ display:inline-flex; align-items:center; flex-wrap:wrap; gap:6px; margin:0; max-width:100%; }
html[data-ui="next"] .inp.inp-sm{ height:28px; padding:0 8px; font-size:12.5px; width:8.5rem; }

/* A role given at a place, with its Remove beside it. */
html[data-ui="next"] .assignment{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
html[data-ui="next"] .assignment + .assignment{ margin-top:2px; }

/* A form's vertical rhythm, and a long list of ticks in a box of its own. */
html[data-ui="next"] .form-stack{ display:grid; gap:var(--space-3); }
html[data-ui="next"] .form-stack > .field{ margin-bottom:0; }
html[data-ui="next"] .form-stack > .btn{ justify-self:start; }
html[data-ui="next"] fieldset.field{ border:0; padding:0; margin:0; min-width:0; }
html[data-ui="next"] fieldset.field > legend{ padding:0; margin-bottom:6px; }
html[data-ui="next"] .check-list{
  display:grid; gap:6px; max-height:320px; overflow-y:auto;
  padding:10px 12px; border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--surface);
}
html[data-ui="next"] .check-list .check{ align-items:flex-start; color:var(--ink); }
html[data-ui="next"] .check-list .check input{ margin-top:2px; flex-shrink:0; }
/* A long list of ticks under the headings of its areas (Printers, Vision Account), each area a small heading. */
html[data-ui="next"] .check-list .check-area{
  margin-top:6px; font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--ink-muted);
}
html[data-ui="next"] .check-list .check-area:first-child{ margin-top:0; }
html[data-ui="next"] .check-list .check-app{ font-size:12.5px; font-weight:700; color:var(--ink); }
html[data-ui="next"] .check-list .check-app ~ .check-app{ margin-top:8px; padding-top:8px; border-top:1px solid var(--line); }

/* A choice with words under it (Choice.razor): the radio, the label in bold, a muted line below, on one edge. Its
   fields (.choice-more, inside a .choice-group) show only while it is the one picked; without :has() they all show,
   and the form posts the same. */
html[data-ui="next"] .choice, html[data-ui="next"] .field label.choice{ display:grid; grid-template-columns:auto minmax(0,1fr); column-gap:10px; align-items:start; cursor:pointer; margin:0; }
html[data-ui="next"] .choice > input{ margin:3px 0 0; flex-shrink:0; }
html[data-ui="next"] .choice-label{ display:block; font-weight:600; color:var(--ink); }
html[data-ui="next"] .choice-text{ display:block; margin-top:2px; font-size:12.5px; line-height:1.45; color:var(--ink-muted); }
html[data-ui="next"] .choices{ display:grid; gap:var(--space-3); }
html[data-ui="next"] .choice-more{ display:grid; gap:var(--space-3); margin:var(--space-2) 0 0 24px; }
html[data-ui="next"] .choice-more > .field{ margin-bottom:0; }
html[data-ui="next"] .choice-group:has(> .choice > input[type="radio"]):not(:has(> .choice > input:checked)) > .choice-more{ display:none; }

/* Permissions grouped by area, compact: "Printers: add, remove, calibrate". */
html[data-ui="next"] .perm-areas{ list-style:none; margin:0; padding:0; display:grid; gap:2px; font-size:12.5px; }
html[data-ui="next"] .perm-areas b{ font-weight:600; color:var(--ink); }
html[data-ui="next"] details.perm-more > summary{ cursor:pointer; font-size:12.5px; color:var(--ink-muted); }
html[data-ui="next"] details.perm-more[open] > summary{ margin-bottom:4px; }

/* Numbered steps. */
html[data-ui="next"] .steps{ display:grid; gap:var(--space-3); margin:0 0 var(--space-4); padding-left:1.25rem; }

/* Label and value pairs to copy: a secret, an id, an endpoint. */
html[data-ui="next"] .secret-list{ display:grid; grid-template-columns:max-content minmax(0,1fr); gap:10px 16px; margin:0 0 var(--space-4); align-items:baseline; }
html[data-ui="next"] .secret-list dt{ font-size:12px; color:var(--ink-muted); font-weight:500; }
html[data-ui="next"] .secret-list dd{ margin:0; overflow-wrap:anywhere; }

/* A confirm step (a <details>): the button opens what will happen right under it, with Cancel and the danger button.
   In a panel's body it opens in the flow. In a table row it lies over the rows below, anchored to its button's right
   edge, so opening it never widens or re-flows the row; the table's scrolling box lets it out while it is open. */
html[data-ui="next"] details.confirm{ display:inline-block; }
html[data-ui="next"] details.confirm > summary{ list-style:none; cursor:pointer; }
html[data-ui="next"] details.confirm > summary::-webkit-details-marker{ display:none; }
html[data-ui="next"] details.confirm[open] > summary{ display:none; }
html[data-ui="next"] td details.confirm{ position:relative; }
html[data-ui="next"] td details.confirm[open] > summary{ display:inline-flex; }
html[data-ui="next"] td details.confirm > .confirm-pop{
  position:absolute; right:0; top:calc(100% + 4px); z-index:var(--z-pop, 50); box-shadow:var(--shadow-pop);
}
html[data-ui="next"] .tbl-wrap:has(td details.confirm[open]){ overflow:visible; }
html[data-ui="next"] .confirm-pop{
  display:grid; gap:8px; width:min(20rem, 80vw); padding:10px 12px; text-align:left; white-space:normal;
  border:1px solid color-mix(in srgb, var(--crit) 40%, var(--line)); border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--crit) 5%, var(--surface-raised));
}
html[data-ui="next"] .confirm-pop p{ margin:0; }
html[data-ui="next"] .confirm-title{ font-weight:600; color:var(--ink); }
html[data-ui="next"] .confirm-actions{ display:flex; justify-content:flex-end; gap:6px; }
/* The same step holding a small form that isn't a removal (Give a role, Edit, Add below): the plain panel look. */
html[data-ui="next"] .confirm-pop.give-pop{ width:min(22rem, 90vw); border-color:var(--line); background:var(--surface-raised); }
/* On a phone a table scrolls sideways inside its panel, and a step anchored to a button at the row's end would open
   off the screen (or, with the table let out, push the page sideways). There it opens as a sheet at the foot of the
   screen instead, full width less the gutters, and the table keeps scrolling in its own box. */
@media (max-width:640px){
  html[data-ui="next"] td details.confirm > .confirm-pop{
    position:fixed; left:16px; right:16px; top:auto; bottom:16px; width:auto; max-height:70vh; overflow-y:auto;
  }
  html[data-ui="next"] .tbl-wrap:has(td details.confirm[open]){ overflow-x:auto; }
}

/* Link tabs: the pages of one rail entry (People: members, invitations, operators) as tabs over the page, links on a
   static page where Ui/Tabs' buttons would need a circuit. The tabs' own look, on <a>. */
html[data-ui="next"] .tabs a{
  font-family:var(--font-sans); font-weight:500; font-size:13.5px; white-space:nowrap; flex-shrink:0;
  color:var(--ink-muted); text-decoration:none; padding:9px 12px; border-bottom:2px solid transparent; margin-bottom:-1px;
  transition:color .12s ease, border-color .12s ease;
}
html[data-ui="next"] .tabs a:hover{ color:var(--ink); }
html[data-ui="next"] .tabs a.on{ color:var(--ink); border-bottom-color:var(--ink); font-weight:600; }

/* A setup checklist: its progress, then each step a link, done ones ticked and quiet. */
html[data-ui="next"] .setup-list{ list-style:none; margin:var(--space-3) 0 0; padding:0; display:grid; gap:2px; }
html[data-ui="next"] .setup-list a, html[data-ui="next"] .setup-list .done{
  display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:var(--radius-sm); color:var(--ink); text-decoration:none;
}
html[data-ui="next"] .setup-list a:hover{ background:color-mix(in srgb, var(--signal) 8%, transparent); color:var(--signal); }
html[data-ui="next"] .setup-list .done{ color:var(--ink-muted); text-decoration:line-through; }
html[data-ui="next"] .setup-list .ico{ width:16px; height:16px; flex-shrink:0; color:var(--ink-muted); }
html[data-ui="next"] .setup-list .done .ico{ color:var(--good); }

/* What waits for someone: each line a link to where it is done. */
html[data-ui="next"] .todo-list{ list-style:none; margin:0; padding:0; display:grid; gap:2px; }
html[data-ui="next"] .todo-list a{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:8px 10px; border-radius:var(--radius-sm); color:var(--ink); text-decoration:none;
}
html[data-ui="next"] .todo-list a:hover{ background:color-mix(in srgb, var(--signal) 8%, transparent); color:var(--signal); }
html[data-ui="next"] .todo-list a .ico{ width:14px; height:14px; color:var(--ink-muted); flex-shrink:0; }

/* Cards that each open a page: an icon, a name, a line about it. On a .grid, so bridge.css's panel-after-panel
   margin leaves the row alone. */
html[data-ui="next"] .link-cards{ display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:var(--gap); }
html[data-ui="next"] a.link-card{
  display:flex; align-items:flex-start; gap:12px; padding:14px 16px;
  color:var(--ink); text-decoration:none; transition:border-color .12s ease, box-shadow .12s ease;
}
html[data-ui="next"] a.link-card:hover{ border-color:color-mix(in srgb, var(--signal) 45%, var(--line)); box-shadow:var(--shadow-pop); }
html[data-ui="next"] a.link-card:focus-visible{ outline:2px solid var(--signal); outline-offset:2px; }
html[data-ui="next"] a.link-card b{ display:block; margin-bottom:2px; }
html[data-ui="next"] a.link-card .vn-small{ display:block; }
html[data-ui="next"] .link-card-icon{
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  width:32px; height:32px; border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--signal) 10%, transparent); color:var(--signal);
}
html[data-ui="next"] .link-card-icon .ico{ width:16px; height:16px; }

/* Lists without bullets (administrators, products), a tree indented by its depth (a site under its company: style
   --depth), and a list of what changes (a catalogue's next version against the published one). */
html[data-ui="next"] .plain-list{ list-style:none; margin:0; padding:0; display:grid; gap:6px; }
html[data-ui="next"] .plain-list.tree-list{ gap:2px; }
html[data-ui="next"] .tree-list > li{ padding-left:calc(var(--depth, 0) * var(--space-4)); }
html[data-ui="next"] .tree-list label.check{ display:flex; align-items:center; gap:8px; }
html[data-ui="next"] .change-list .change-added{ color:var(--good); }
html[data-ui="next"] .change-list .change-removed{ color:var(--crit); }
html[data-ui="next"] .change-list .change-changed{ color:var(--amber-text); }

/* ---------- A help guide: its contents, then the guide at a reading width ----------
   The sections as a list of links in columns, each heading an anchor that clears the top of the page, and the guide's
   tables full width with their rows ruled, the first column a little narrower. */
html[data-ui="next"] .help-toc{ margin:0 0 var(--space-5); padding:var(--space-3) var(--space-4); border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--surface); }
html[data-ui="next"] .help-toc-title{ margin:0 0 6px; font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--ink-muted); }
html[data-ui="next"] .help-toc ul{ list-style:none; margin:0; padding:0; columns:16rem auto; column-gap:var(--space-5); }
html[data-ui="next"] .help-toc li{ break-inside:avoid; padding:2px 0; font-size:13px; }
html[data-ui="next"] .help-guide{ max-width:68rem; line-height:1.6; }
html[data-ui="next"] .help-guide :is(h2, h3){ scroll-margin-top:72px; }
html[data-ui="next"] .help-guide h2{ margin:var(--space-6) 0 var(--space-3); padding-top:var(--space-4); border-top:1px solid var(--line); }
html[data-ui="next"] .help-guide h2:first-child{ margin-top:0; padding-top:0; border-top:0; }
html[data-ui="next"] .help-guide table{ width:100%; border-collapse:collapse; margin:var(--space-3) 0 var(--space-4); font-size:13px; }
html[data-ui="next"] .help-guide :is(th, td){ padding:7px 10px; border-bottom:1px solid var(--line); text-align:left; vertical-align:top; }
html[data-ui="next"] .help-guide th{ font-weight:600; color:var(--ink-muted); }
html[data-ui="next"] .help-guide td:first-child{ width:30%; }
/* On a phone a guide's table scrolls sideways in its own box rather than squeezing its words into slivers. */
@media (max-width:640px){
  html[data-ui="next"] .help-guide table{ display:block; overflow-x:auto; }
  html[data-ui="next"] .help-guide td:first-child{ width:auto; min-width:8rem; }
}

/* ---------- The frame without the rail (Ui/AppBar), as the CaptureTech Suite's SuiteBar ----------
   The portal and someone's own account: the mark and name where the rail would be, the page centred below. */
html[data-ui="next"] .bar-shell{min-height:100vh;display:flex;flex-direction:column;}
html[data-ui="next"] .bar-top{padding:0 20px;}
html[data-ui="next"] .bar-brand{display:inline-flex;align-items:center;gap:9px;color:var(--ink);font-family:var(--font-display);font-weight:700;font-size:15px;letter-spacing:-0.01em;text-decoration:none;}
html[data-ui="next"] .bar-brand:hover{color:var(--ink);}
/* The mark at the size it was asked for: the topbar's own image rules would stretch it. */
html[data-ui="next"] .bar-brand .vn-mark{width:24px;height:24px;flex-shrink:0;}
html[data-ui="next"] .bar-page{width:100%;max-width:1240px;margin:0 auto;padding:28px 24px 40px;flex:1;}
html[data-ui="next"] .bar-foot{display:flex;flex-wrap:wrap;gap:6px 14px;justify-content:center;padding:18px 24px 26px;font-size:12px;color:var(--ink-muted);}
html[data-ui="next"] .bar-foot a{color:var(--ink-muted);}
html[data-ui="next"] .bar-foot a:hover{color:var(--signal);}
html[data-ui="next"] .bar-skip{position:absolute;left:12px;top:-60px;z-index:200;padding:8px 12px;border-radius:var(--radius-sm);background:var(--surface-raised);color:var(--signal);box-shadow:var(--shadow-pop);font-weight:600;}
html[data-ui="next"] .bar-skip:focus{top:10px;}
@media (max-width: 640px){
  html[data-ui="next"] .bar-top .div{display:none;}
  html[data-ui="next"] .bar-brand span{display:none;}
  html[data-ui="next"] .bar-page{padding:18px 16px 28px;}
}

/* ---------- App tiles (Ui/AppTiles, Ui/AppTile), as the CaptureTech Suite's: the portal's apps ---------- */
html[data-ui="next"] .app-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px;}
html[data-ui="next"] .app-tile{
  --app-accent:var(--signal);
  position:relative;display:flex;flex-direction:column;gap:12px;
  padding:18px 18px 14px;min-height:176px;
  background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-1);color:inherit;text-decoration:none;
  transition:border-color .15s ease, box-shadow .15s ease, transform .15s var(--ease);
}
html[data-ui="next"] .app-accent-signal{--app-accent:var(--signal);}
html[data-ui="next"] .app-accent-amber{--app-accent:var(--amber-text);}
html[data-ui="next"] .app-accent-good{--app-accent:var(--good);}
html[data-ui="next"] .app-accent-night{--app-accent:var(--night);}
html[data-ui="next"] a.app-tile:hover{border-color:color-mix(in srgb, var(--app-accent) 40%, var(--line));box-shadow:var(--shadow-pop);transform:translateY(-1px);color:inherit;}
html[data-ui="next"] a.app-tile:focus-visible{outline:2px solid var(--app-accent);outline-offset:2px;}
html[data-ui="next"] .app-tile-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:12px;
  background:color-mix(in srgb, var(--app-accent) 12%, transparent);
}
html[data-ui="next"] .app-tile-icon .vn-mark{width:28px;height:28px;}
html[data-ui="next"] .app-tile-body{display:flex;flex-direction:column;gap:4px;flex:1;}
html[data-ui="next"] .app-tile-body b{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-0.01em;color:var(--ink);}
html[data-ui="next"] .app-tile-body span{font-size:13px;line-height:1.5;color:var(--ink-muted);}
html[data-ui="next"] .app-tile-body span.app-tile-meta{font-size:12px;color:var(--ink-faint);margin-top:2px;}
html[data-ui="next"] .app-tile-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:24px;}
html[data-ui="next"] .app-open{margin-left:auto;display:inline-flex;align-items:center;gap:5px;font-size:13px;font-weight:600;color:var(--app-accent);}
html[data-ui="next"] .app-open .ico{width:14px;height:14px;transition:transform .15s var(--ease);}
html[data-ui="next"] a.app-tile:hover .app-open .ico{transform:translateX(2px);}
html[data-ui="next"] .app-tile.is-soon{background:var(--surface-sunken);box-shadow:none;border-style:dashed;border-color:color-mix(in srgb, var(--ink-muted) 40%, transparent);}
html[data-ui="next"] .app-tile.is-soon .app-tile-icon{filter:grayscale(.6);opacity:.75;}
html[data-ui="next"] .app-soon{
  padding:1px 7px;border-radius:var(--radius-full);
  font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-muted);background:color-mix(in srgb, var(--ink) 6%, transparent);white-space:nowrap;
}
html[data-ui="next"] .app-tile-foot .link{margin-left:auto;font-size:13px;font-weight:600;white-space:nowrap;}
@media (prefers-reduced-motion:reduce){
  html[data-ui="next"] .app-tile,html[data-ui="next"] .app-open .ico{transition:none;}
  html[data-ui="next"] a.app-tile:hover{transform:none;}
}

/* ---------- Blazor's error bar (VnScripts) ----------
   Blazor only switches #blazor-error-ui to display:block when the page loses its server session to an error; hiding
   it is left to the stylesheet. Nothing hid it, so "Something went wrong and this page stopped responding. Reload" sat
   at the foot of every page, under the rail. Hidden here, and a bar over everything when it is shown. */
#blazor-error-ui{
  display:none;
  position:fixed; left:50%; bottom:20px; translate:-50% 0; z-index:calc(var(--z-toast) + 1);
  max-width:calc(100vw - 32px);
  padding:12px 16px; border-radius:var(--radius-sm);
  background:var(--crit-soft); color:var(--crit); border:1px solid color-mix(in srgb, var(--crit) 35%, transparent);
  box-shadow:var(--shadow-pop); font-size:14px;
}
#blazor-error-ui .reload{ color:inherit; font-weight:600; margin-left:8px; text-decoration:underline; }
