/* ================================================================
   @quoriam/ui — component styles (P2.0)
   Consumes tokens.css ONLY. Zero hardcoded colors — every color,
   radius, size, duration and easing resolves through a custom
   property defined in tokens.css. Anatomy + states per
   showcase/brand/quoriam-ui-standard.md §7, §10–§12.
   Class prefix: `qui-` (collision-safe when vendored).
   ================================================================ */

/* ---------------------------------------------------------------
   Card base — borderless; separation = surface tint (+ lift on
   hover only). Never a colored edge. (§1, §6)
   --------------------------------------------------------------- */
.qui-card {
  background: var(--surface);
  border-radius: var(--radius-xl);
  position: relative;
  transition:
    background var(--dur-lift) var(--ease-state),
    transform var(--dur-lift) var(--ease-state),
    box-shadow var(--dur-lift) var(--ease-state);
}
.qui-card--hoverable:hover {
  background: var(--surface-2);
  transform: translateY(-2px);
  box-shadow: var(--lift-shadow);
}

/* ---------------------------------------------------------------
   KpiCard (§12) — squircle icon · label/sub · provenance chip ·
   mono tabular value w/ half-size unit · delta pill + context ·
   sparkline slot. NULL value renders "—", never 0 (§1.3).
   --------------------------------------------------------------- */
.qui-kpi {
  padding: var(--space-8) var(--space-9) var(--space-7); /* 16 20 14 */
  display: flex;
  flex-direction: column;
  font-family: var(--font-body);
}
.qui-kpi--hero { padding: var(--space-9) var(--space-10) var(--space-8); }

.qui-kpi__top {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  margin-bottom: var(--space-5);
}
.qui-squircle {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-lg);
  background: var(--accent-soft);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  flex: none;
}
.qui-squircle svg { width: 16px; height: 16px; stroke-width: 1.6; }

.qui-kpi__label {
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  color: var(--muted);
  padding-top: 1px;
  line-height: var(--leading-ui);
}
.qui-kpi__label small {
  display: block;
  font-weight: var(--weight-regular);
  font-size: var(--text-micro);
  color: var(--subtle);
}

/* provenance chip (§11) — MEASURED / DERIVED, top-right, mono pill */
.qui-prov {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.1em;
  padding: var(--space-1) var(--space-4); /* 2 8 — pill */
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  color: var(--muted);
  white-space: nowrap;
}
.qui-prov--measured { background: var(--ok-soft); color: var(--ok-ink); }
.qui-prov--derived  { background: var(--surface-3); color: var(--muted); }
/* MANUAL = human-entered: a distinct lineage, dashed to read "entered, not sensed" */
.qui-prov--manual   { background: var(--surface-2); color: var(--muted); border: 1px dashed var(--hair); } /* --muted clears AA on surface-2 (dark --subtle was 4.29); matches --derived (0.6.1 a11y) */

.qui-kpi__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--num-kpi);
  line-height: var(--leading-numeral);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-display);
  color: var(--ink);
}
.qui-kpi--hero .qui-kpi__value { font-size: var(--num-hero); }
.qui-kpi__value .qui-kpi__unit {
  /* units at ~half numeral size, muted (§3 unit styling) */
  font-size: var(--text-body-lg);
  color: var(--subtle);
  margin-left: var(--space-2);
  font-weight: var(--weight-regular);
}
.qui-kpi--hero .qui-kpi__value .qui-kpi__unit { font-size: var(--text-heading); }
.qui-kpi__value--null { color: var(--subtle); }

.qui-kpi__row2 {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-5);
  flex-wrap: wrap;
}
.qui-delta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
}
.qui-delta--up,
.qui-delta--down-good { color: var(--ok-ink); background: var(--ok-soft); }
.qui-delta--down,
.qui-delta--up-bad { color: var(--bad-ink); background: var(--bad-soft); }
.qui-delta--null {
  color: var(--subtle);
  background: var(--surface-2);
  font-weight: var(--weight-regular);
}
.qui-delta svg { width: 8px; height: 8px; }
.qui-kpi__sub { font-size: var(--text-micro); color: var(--subtle); }

.qui-kpi__spark { margin-top: auto; padding-top: var(--space-6); }
.qui-kpi__spark svg { width: 100%; height: 34px; display: block; }
.qui-kpi--hero .qui-kpi__spark svg { height: 84px; }
.qui-spark__line {
  stroke: var(--accent);
  stroke-width: 1.6;
  fill: none;
  stroke-linejoin: round;
}
.qui-spark__dot { fill: var(--accent); }

/* ---------------------------------------------------------------
   StatusChip (§7) — label ALWAYS paired with the dot (colorblind
   safe); offline/info dots are hollow (shape ≠ color alone);
   pulse only while live-alerting; glows are dark-only via tokens.
   --------------------------------------------------------------- */
.qui-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.qui-chip__dot { width: 5px; height: 5px; border-radius: var(--radius-round); flex: none; }

.qui-chip--ok      { background: var(--ok-soft);    color: var(--ok-ink); }
.qui-chip--ok      .qui-chip__dot { background: var(--ok); }
.qui-chip--warn    { background: var(--warn-soft);  color: var(--warn-ink); }
.qui-chip--warn    .qui-chip__dot { background: var(--warn); box-shadow: var(--glow-warn); }
.qui-chip--crit    { background: var(--bad-soft);   color: var(--bad-ink); }
.qui-chip--crit    .qui-chip__dot { background: var(--bad); box-shadow: var(--glow-bad); }
.qui-chip--neutral { background: var(--surface-3);  color: var(--muted); }
.qui-chip--neutral .qui-chip__dot { background: currentColor; }
.qui-chip--offline { background: var(--surface-3);  color: var(--muted); }
.qui-chip--offline .qui-chip__dot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--off); }
.qui-chip--info    { background: var(--surface-3);  color: var(--muted); }
.qui-chip--info    .qui-chip__dot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--subtle); }

/* machine-state family — SEPARATE axis. Per the hard rule (status color in
   dots), the hue lives in the dot; the label stays --muted for AA on the soft
   wash. run~ok-green / down~bad-red echo the value family but read as STATE. */
.qui-chip--state-run, .qui-chip--state-idle, .qui-chip--state-setup,
.qui-chip--state-fault, .qui-chip--state-down, .qui-chip--state-maint { color: var(--muted); }
.qui-chip--state-run   { background: var(--run-soft); }   .qui-chip--state-run   .qui-chip__dot { background: var(--run);   box-shadow: var(--glow-ok); }
.qui-chip--state-idle  { background: var(--idle-soft); }  .qui-chip--state-idle  .qui-chip__dot { background: var(--idle); }
.qui-chip--state-setup { background: var(--setup-soft); } .qui-chip--state-setup .qui-chip__dot { background: var(--setup); }
.qui-chip--state-fault { background: var(--fault-soft); } .qui-chip--state-fault .qui-chip__dot { background: var(--fault); box-shadow: var(--glow-bad); }
.qui-chip--state-down  { background: var(--down-soft); }  .qui-chip--state-down  .qui-chip__dot { background: var(--down);  box-shadow: var(--glow-bad); }
.qui-chip--state-maint { background: var(--maint-soft); } .qui-chip--state-maint .qui-chip__dot { background: var(--maint); }

/* pulse = live signal ONLY (caller opts in via `pulse` prop) */
.qui-chip--pulse .qui-chip__dot { animation: qui-pulse var(--pulse-warn) ease-in-out infinite; }
.qui-chip--crit.qui-chip--pulse .qui-chip__dot { animation-duration: var(--pulse-crit); }
@keyframes qui-pulse { 50% { opacity: 0.35; } }

/* ---------------------------------------------------------------
   ChartFrame (§12) — panel head (display h2 + mono meta + legend +
   range seg control) · chart slot · optional foot. The chart
   itself is the caller's (ECharts/SVG); the frame is the contract.
   --------------------------------------------------------------- */
.qui-panel {
  background: var(--surface);
  border-radius: var(--radius-xl);
  font-family: var(--font-body);
}
.qui-panel__head {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-8) var(--space-9) var(--space-4);
  flex-wrap: wrap;
}
.qui-panel__head h2 {
  font-family: var(--font-display);
  font-size: var(--text-body-lg);
  font-weight: var(--weight-medium);
  letter-spacing: -0.015em;
  margin: 0;
  color: var(--ink);
}
.qui-panel__meta {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--subtle);
}
.qui-panel__right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.qui-chartframe__body { padding: var(--space-3) var(--space-9) var(--space-3); }
.qui-chartframe__body svg, .qui-chartframe__body canvas { max-width: 100%; }
.qui-chartframe__foot {
  display: flex;
  gap: var(--space-8);
  padding: var(--space-1) var(--space-9) var(--space-7);
  align-items: center;
  font-size: var(--text-micro);
  color: var(--subtle);
}

/* segmented range control — aria-pressed mirrors .is-active */
.qui-seg {
  display: flex;
  background: var(--surface-2);
  border-radius: var(--radius-lg);
  padding: var(--space-1);
  gap: var(--space-1);
}
.qui-seg button {
  border: none;
  background: none;
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-6);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  font-family: var(--font-mono);
  color: var(--subtle);
  cursor: pointer;
  transition: background var(--dur-hover) var(--ease-state), color var(--dur-hover) var(--ease-state);
}
.qui-seg button:hover { color: var(--muted); }
.qui-seg button:active { transform: translateY(1px); }
.qui-seg button.is-active { background: var(--surface-3); color: var(--ink); }
.qui-seg button:disabled { opacity: 0.55; cursor: not-allowed; }

/* ---------------------------------------------------------------
   EmptyState (§12) — circle art slot · title · sub explaining WHY
   empty + last occurrence · quiet action. Never a bare "No data".
   --------------------------------------------------------------- */
.qui-empty {
  padding: var(--space-10) var(--space-9);
  text-align: center;
  font-family: var(--font-body);
}
.qui-empty__art {
  width: 60px;
  height: 60px;
  margin: 0 auto var(--space-6);
  border-radius: var(--radius-round);
  background: var(--surface-2);
  display: grid;
  place-items: center;
  color: var(--subtle);
}
.qui-empty__title {
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  color: var(--ink);
}
.qui-empty__sub {
  font-size: var(--text-caption);
  color: var(--subtle);
  margin: var(--space-2) auto 0;
  max-width: 230px;
  line-height: var(--leading-ui);
}
.qui-empty__btn {
  margin-top: var(--space-6);
  display: inline-block;
  padding: var(--space-3) var(--space-7);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  color: var(--ink);
  cursor: pointer;
  border: none;
  font-family: inherit;
  transition: background var(--dur-hover) var(--ease-state);
}
.qui-empty__btn:hover { background: var(--surface-3); }
.qui-empty__btn:active { transform: translateY(1px); }

/* ---------------------------------------------------------------
   Loading skeleton (§10) — shimmer only while loading
   --------------------------------------------------------------- */
.qui-skel {
  position: relative;
  color: transparent !important;
  border-radius: var(--radius-md);
  overflow: hidden;
  user-select: none;
  pointer-events: none;
}
.qui-skel::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--surface-3);
  border-radius: var(--radius-md);
}
.qui-skel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--shimmer);
  background-size: 220% 100%;
  animation: qui-shimmer 1.1s linear infinite;
}
@keyframes qui-shimmer {
  from { background-position: 160% 0; }
  to   { background-position: -60% 0; }
}
.qui-skel > * { visibility: hidden; }

/* ===============================================================
   K2 — Data & viz components (DataTable, AlertFeed, HeatStrip,
   Donut, InsightCard, FamilyStrip). Append-only fenced sections;
   tokens-only, both themes, null-honesty, RM-safe. Shared helpers
   first, then per-component blocks.
   =============================================================== */

/* ── K2: shared (numeric + mono-id helpers) ── */
.qui-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.qui-num__unit { color: var(--subtle); }
.qui-td-null { color: var(--subtle); }
.qui-assetid {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  background: var(--surface-2);
  color: var(--muted);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* ── K2: DataTable ──
   Uppercase mono th (scope=col), rows separated by --hair-soft top
   border only (§6); built-in cell kinds; density-aware paddings;
   hover tint; clickable rows become real buttons; aria-sort header
   buttons; skeleton + empty slots. */
.qui-table-wrap { font-family: var(--font-body); width: 100%; overflow-x: auto; }
.qui-table { width: 100%; border-collapse: separate; border-spacing: 0; }
.qui-table__caption {
  text-align: left;
  font-size: var(--text-caption);
  color: var(--subtle);
  padding: var(--space-2) var(--space-6) var(--space-5);
}
.qui-th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--subtle);
  padding: var(--space-3) var(--space-6);
  white-space: nowrap;
  vertical-align: bottom;
}
.qui-th--end { text-align: right; }
.qui-th__sort {
  appearance: none;
  border: none;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0;
}
.qui-th--end .qui-th__sort { flex-direction: row-reverse; }
.qui-th__sort:hover { color: var(--muted); }
.qui-th__glyph { width: 8px; height: 11px; flex: none; color: var(--accent-ink); }

.qui-td {
  font-size: var(--text-body);
  color: var(--ink);
  padding: var(--space-5) var(--space-6); /* cozy: 10 12 */
  border-top: 1px solid var(--hair-soft);
  vertical-align: middle;
}
.qui-td--end { text-align: right; }
.qui-table--compact .qui-td { padding: var(--space-3) var(--space-6); } /* compact: 6 12 */
.qui-tr { transition: background var(--dur-hover) var(--ease-state); }
.qui-table--interactive .qui-tr--clickable:hover { background: var(--surface-2); }
.qui-tr--clickable:hover .qui-td:first-child { border-top-left-radius: var(--radius-md); border-bottom-left-radius: var(--radius-md); }
.qui-tr--clickable:hover .qui-td:last-child { border-top-right-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); }
.qui-tr__btn {
  appearance: none;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: inherit;
  padding: 0;
  width: 100%;
  display: block;
}
.qui-tr__btn:active { transform: translateY(1px); }

/* utilization cell — track + ≥3:1 accent fill + mono pct */
.qui-util { display: inline-flex; align-items: center; gap: var(--space-4); min-width: 128px; width: 100%; justify-content: flex-end; }
.qui-util__track { flex: 1; height: 5px; border-radius: var(--radius-pill); background: var(--bar-track); overflow: hidden; min-width: 56px; }
.qui-util__fill { display: block; height: 100%; background: var(--accent); border-radius: var(--radius-pill); }
.qui-util__pct { font-size: var(--text-caption); color: var(--muted); min-width: 34px; text-align: right; }

/* numeric unit inside a cell */
.qui-num__unit { font-size: var(--text-caption); }

/* skeleton cell + empty slot */
.qui-skel-cell {
  display: block;
  height: 12px;
  width: 70%;
  border-radius: var(--radius-sm);
  background: var(--surface-3);
  position: relative;
  overflow: hidden;
}
.qui-skel-cell::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--shimmer);
  background-size: 220% 100%;
  animation: qui-shimmer 1.1s linear infinite;
}
.qui-td--end .qui-skel-cell { margin-left: auto; width: 50%; }
.qui-table__empty { border-top: 1px solid var(--hair-soft); }

/* ── K2: AlertFeed ──
   Severity chip WITH text (never dot-only); relative meta rolls to
   minutes; aria-live polite; new-item slide + single flash (RM kills
   it globally via tokens.css); cap + view-all. */
.qui-feed { font-family: var(--font-body); }
.qui-feed__list { list-style: none; margin: 0; padding: 0; }
.qui-feed__item {
  padding: var(--space-6) var(--space-6);
  border-top: 1px solid var(--hair-soft);
  transition: background var(--dur-hover) var(--ease-state);
}
.qui-feed__item:first-child { border-top: none; }
.qui-feed__item:hover { background: var(--surface-2); }
.qui-feed__head { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.qui-feed__title { font-size: var(--text-body-sm); font-weight: var(--weight-medium); color: var(--ink); }
.qui-feed__meta {
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--subtle);
  display: flex;
  gap: var(--space-3);
}
.qui-feed__actions { margin-top: var(--space-5); display: flex; gap: var(--space-4); }
.qui-feed__foot { padding: var(--space-5) var(--space-6); border-top: 1px solid var(--hair-soft); }
.qui-feed__viewall {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--accent-ink);
  cursor: pointer;
}
/* new-item enter: slide in + one flash, then settle. RM-killed globally. */
.qui-feed__item--enter { animation: qui-feed-enter var(--dur-popover) var(--ease-entrance) both, qui-feed-flash 1s var(--ease-fade) 1; }
@keyframes qui-feed-enter { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes qui-feed-flash { 0% { background: var(--accent-soft); } 100% { background: transparent; } }

/* ── K2: HeatStrip ──
   Contrast-floored ramp: light cells paint --accent-ink, dark paint
   --accent (token-swapped); opacity floor ≥.70 set inline by the
   component. Focusable cells (role=img) with hover+focus tooltip. */
.qui-heat { font-family: var(--font-body); display: inline-flex; flex-direction: column; gap: var(--space-3); }
.qui-heat__label {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--subtle);
}
.qui-heat__cells { display: flex; gap: 3px; }
.qui-heat__cell {
  flex: 1 1 0;
  min-width: 10px;
  height: 18px;
  border-radius: var(--radius-xs);
  background: var(--accent-ink); /* light: accent-ink keeps the floor ≥3:1 */
  position: relative;
  cursor: default;
  transition: transform var(--dur-hover) var(--ease-state);
}
[data-theme="dark"] .qui-heat__cell, .dark .qui-heat__cell { background: var(--accent); }
.qui-heat__cell--empty { background: var(--bar-track); opacity: 1; }
.qui-heat__cell:hover, .qui-heat__cell:focus-visible { transform: scaleY(1.25); }
/* tooltip on hover AND focus */
.qui-heat__cell::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface-3);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  white-space: nowrap;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  box-shadow: var(--lift-shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-hover) var(--ease-state);
  z-index: var(--z-popover);
}
.qui-heat__cell:hover::after, .qui-heat__cell:focus-visible::after { opacity: 1; }
.qui-heat__axis { display: flex; gap: 3px; }
.qui-heat__tick {
  flex: 1 1 0;
  min-width: 10px;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--subtle);
  text-align: left;
}

/* ── K2: Donut ──
   SVG ring (track + status arcs, 2.5px gaps), color-independent text
   legend, center slot, draw-in once (RM-static via the component's JS
   gate + the CSS transition that tokens.css kills under RM). */
.qui-donut { display: flex; align-items: center; gap: var(--space-9); font-family: var(--font-body); }
.qui-donut__ring { position: relative; flex: none; }
.qui-donut__arc {
  /* component sets dasharray inline: collapsed → real on draw.
     This transition animates that swap once; RM kills it (tokens.css). */
  transition: stroke-dasharray var(--dur-draw) var(--ease-draw);
}
.qui-donut__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  text-align: center;
  line-height: var(--leading-numeral);
}
.qui-donut__total { font-size: var(--text-title); font-weight: var(--weight-medium); color: var(--ink); line-height: var(--leading-numeral); }
.qui-donut__legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); min-width: 132px; }
.qui-donut__legrow { display: flex; align-items: center; gap: var(--space-4); font-size: var(--text-body-sm); }
.qui-donut__sw { width: 8px; height: 8px; border-radius: var(--radius-xs); flex: none; }
.qui-donut__leglabel { color: var(--muted); }
.qui-donut__legval { margin-left: auto; color: var(--ink); font-size: var(--text-caption); }

/* ── K2: InsightCard ──
   The one sanctioned accent-soft gradient wash; mono kicker; message;
   confidence + provenance chips; action slot. Never a colored border. */
.qui-insight {
  display: flex;
  flex-direction: column;
  padding: var(--space-8) var(--space-9);
  background:
    linear-gradient(135deg, var(--accent-soft-2), transparent 55%),
    var(--surface);
}
.qui-insight__top { display: flex; align-items: center; gap: var(--space-5); margin-bottom: var(--space-6); }
.qui-insight__sparkle { color: var(--accent-ink); }
.qui-insight__kicker {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--accent-ink);
}
.qui-insight__top .qui-prov { margin-left: auto; }
.qui-insight__msg {
  font-size: var(--text-body);
  line-height: var(--leading-ui);
  color: var(--ink);
  margin: 0;
}
.qui-insight__msg strong, .qui-insight__msg b { font-weight: var(--weight-semibold); }
/* footer: action anchored bottom-left, meta bottom-right, on ONE baseline;
   margin-top:auto pins it to the card bottom (flex column) so cards of
   differing height align their footers; wraps gracefully when narrow. */
.qui-insight__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: var(--space-7);
}
.qui-insight__meta {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--subtle);
}
.qui-insight__action { margin: 0; }
.qui-insight__btn {
  appearance: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  padding: var(--space-3) var(--space-7);
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--accent-ink);
  transition: background var(--dur-hover) var(--ease-state), color var(--dur-hover) var(--ease-state);
}
.qui-insight__btn:hover { background: var(--accent); color: var(--accent-contrast); }
.qui-insight__btn:active { transform: translateY(1px); }
/* confidence chip variant of the provenance pill */
.qui-conf { background: var(--surface-3); color: var(--muted); }

/* ── K2: FamilyStrip ──
   4-app grid; per-app accent override via .qui-app-<key> wrapper class
   (sets --accent / --accent-ink locally so the family re-accents). */
.qui-family { font-family: var(--font-body); }
.qui-family__header {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--subtle);
  margin-bottom: var(--space-6);
}
.qui-family__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gap-card); }
.qui-fam { padding: var(--space-7) var(--space-8); display: flex; flex-direction: column; gap: var(--space-6); }
.qui-fam__lockup { display: flex; align-items: center; gap: var(--space-4); }
.qui-fam__glyph { width: 24px; height: 24px; color: var(--accent-ink); display: grid; place-items: center; flex: none; }
.qui-fam__glyph svg { width: 20px; height: 20px; }
.qui-fam__name {
  font-family: var(--font-display);
  font-size: var(--text-title);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-display);
  color: var(--ink);
  line-height: var(--leading-heading);
}
.qui-fam__byline { display: block; font-family: var(--font-mono); font-size: var(--text-micro); font-weight: var(--weight-regular); letter-spacing: normal; color: var(--subtle); }
.qui-fam__kpi { display: flex; flex-direction: column; gap: var(--space-1); }
.qui-fam__kpilabel { font-size: var(--text-micro); color: var(--subtle); text-transform: uppercase; letter-spacing: var(--tracking-label); font-family: var(--font-mono); }
.qui-fam__kpival { font-size: var(--text-title); color: var(--ink); }
.qui-fam__unit { font-size: var(--text-caption); color: var(--subtle); }
@media (max-width: 900px) { .qui-family__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* per-app accent overrides (the re-accent proof) */
.qui-app-forge        { --accent: #FF6B00; --accent-ink: #b34a00; }
[data-theme="dark"] .qui-app-forge       , .dark .qui-app-forge        { --accent-ink: #ff8a3d; }
.qui-app-bedrock      { --accent: #C2410C; --accent-ink: #9a3412; }
[data-theme="dark"] .qui-app-bedrock     , .dark .qui-app-bedrock      { --accent-ink: #fb923c; }
.qui-app-supplychainos{ --accent: #0E7490; --accent-ink: #0b5d72; }
[data-theme="dark"] .qui-app-supplychainos, .dark .qui-app-supplychainos { --accent-ink: #38bdf8; }
.qui-app-dociq        { --accent: #7C3AED; --accent-ink: #6028c4; }
[data-theme="dark"] .qui-app-dociq       , .dark .qui-app-dociq        { --accent-ink: #a78bfa; }

/* ---------------------------------------------------------------
   Baseline plumbing — focus ring + reduced motion are defined in
   tokens.css; nothing here may override them.
   --------------------------------------------------------------- */

/* ════════════════════════════════════════════════════════════════
   K1 — shell & interactive chrome (PageShell, TopBar, CommandPalette,
   Popover/MenuPopover, Toast). Behaviour from Radix + cmdk; every
   color/size/radius/duration below resolves through a tokens.css
   custom property. Overlay open-motion is transform/opacity only and
   dies under prefers-reduced-motion (tokens.css global kill).
   ════════════════════════════════════════════════════════════════ */

/* ── K1: PageShell ── */
.qui-shell {
  display: grid;
  grid-template-columns: 216px 1fr;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
}
.qui-shell--collapsed { grid-template-columns: 60px 1fr; }

.qui-skiplink {
  position: fixed;
  top: var(--space-2);
  left: var(--space-2);
  z-index: var(--z-toast);
  transform: translateY(-150%);
  padding: var(--space-3) var(--space-7);
  background: var(--surface-3);
  color: var(--ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--lift-shadow);
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: transform var(--dur-hover) var(--ease-state);
}
.qui-skiplink:focus-visible { transform: translateY(0); }

.qui-shell__side {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  overflow: hidden;
}
.qui-shell__brand {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-7) var(--space-8);
  min-height: 56px;
}
.qui-shell__collapse {
  margin-left: auto;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border: none;
  background: none;
  color: var(--subtle);
  border-radius: var(--radius-md);
  cursor: pointer;
  flex: none;
  transition: background var(--dur-hover) var(--ease-state), color var(--dur-hover) var(--ease-state);
}
.qui-shell__collapse svg { width: 14px; height: 14px; }
.qui-shell__collapse:hover { background: var(--surface-2); color: var(--ink); }
.qui-shell__collapse:active { transform: translateY(1px); }
.qui-shell--collapsed .qui-shell__brand { padding-inline: 0; justify-content: center; }
.qui-shell--collapsed .qui-shell__collapse { margin-left: 0; }

.qui-shell__nav {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.qui-nav__group { display: flex; flex-direction: column; gap: 2px; }
.qui-nav__grouplabel {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--subtle);
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.qui-nav__item {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: var(--text-body);
  font-weight: var(--weight-regular);
  font-family: inherit;
  text-decoration: none;
  text-align: left;
  width: 100%;
  border: none;
  background: none;
  cursor: pointer;
  transition: background var(--dur-hover) var(--ease-state), color var(--dur-hover) var(--ease-state);
}
.qui-nav__item:hover { background: var(--surface); color: var(--ink); }
.qui-nav__item:active { transform: translateY(1px); }
.qui-nav__item.is-active {
  background: var(--surface-2);
  color: var(--ink);
  font-weight: var(--weight-medium);
}
.qui-nav__icon {
  width: 16px;
  height: 16px;
  flex: none;
  display: grid;
  place-items: center;
  color: var(--subtle);
}
.qui-nav__icon svg { width: 16px; height: 16px; }
.qui-nav__item.is-active .qui-nav__icon { color: var(--accent-ink); }
.qui-nav__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qui-nav__count {
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  padding: 1px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--bad-soft);
  color: var(--bad-ink);
}
.qui-shell--collapsed .qui-nav__label,
.qui-shell--collapsed .qui-nav__count,
.qui-shell--collapsed .qui-nav__grouplabel { display: none; }
.qui-shell--collapsed .qui-nav__item { justify-content: center; padding-inline: 0; }

.qui-shell__footer {
  padding: var(--space-6) var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--subtle);
}
.qui-shell--collapsed .qui-shell__footer { display: none; }

.qui-shell__col { display: flex; flex-direction: column; min-width: 0; min-height: 100vh; }
.qui-shell__main { flex: 1; outline: none; }
.qui-shell__content {
  max-width: var(--maxw-app);
  margin: 0 auto;
  padding: var(--pad-content);
}
@media (max-width: 1180px) {
  .qui-shell { grid-template-columns: 60px 1fr; }
  .qui-shell .qui-nav__label,
  .qui-shell .qui-nav__count,
  .qui-shell .qui-nav__grouplabel,
  .qui-shell .qui-shell__footer { display: none; }
  .qui-shell .qui-nav__item { justify-content: center; padding-inline: 0; }
  .qui-shell .qui-shell__brand { padding-inline: 0; justify-content: center; }
}

/* ── K1: TopBar ── */
.qui-topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
  background: var(--blur-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  font-family: var(--font-body);
}
.qui-topbar__bar {
  display: flex;
  align-items: center;
  gap: var(--space-7);
  min-height: 56px;
  padding: 0 var(--pad-content);
  max-width: var(--maxw-app);
  margin: 0 auto;
}
.qui-topbar__lockup { display: flex; align-items: baseline; gap: var(--space-3); flex: none; }

.qui-crumbs ol { display: flex; align-items: center; gap: var(--space-3); list-style: none; margin: 0; padding: 0; }
.qui-crumbs li { display: flex; align-items: center; gap: var(--space-3); }
.qui-crumbs a,
.qui-crumbs button {
  font-size: var(--text-body-sm);
  color: var(--subtle);
  text-decoration: none;
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
  padding: 0;
  transition: color var(--dur-hover) var(--ease-state);
}
.qui-crumbs a:hover,
.qui-crumbs button:hover { color: var(--ink); }
.qui-crumbs .is-current { font-size: var(--text-body-sm); color: var(--muted); font-weight: var(--weight-medium); }
.qui-crumbs__sep { color: var(--subtle); font-size: var(--text-body-sm); }

.qui-topbar__right { margin-left: auto; display: flex; align-items: center; gap: var(--space-5); flex: none; }

.qui-cmdbtn {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 184px;
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: var(--text-body-sm);
  cursor: pointer;
  transition: background var(--dur-hover) var(--ease-state), color var(--dur-hover) var(--ease-state);
}
.qui-cmdbtn:hover { background: var(--surface-3); color: var(--muted); }
.qui-cmdbtn:active { transform: translateY(1px); }
.qui-cmdbtn__icon { width: 14px; height: 14px; display: grid; place-items: center; flex: none; }
.qui-cmdbtn__icon svg { width: 14px; height: 14px; }
.qui-cmdbtn__ph { flex: 1; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.qui-kbd {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--muted);
  background: var(--surface-3);
  border-radius: var(--radius-xs);
  padding: 1px var(--space-3);
  flex: none;
}

.qui-fresh { display: inline-flex; align-items: center; gap: var(--space-3); }
.qui-fresh__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-round);
  background: var(--ok);
  flex: none;
}
.qui-fresh__dot.is-live { animation: qui-pulse var(--pulse-fresh) ease-in-out infinite; }
.qui-fresh__label { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); white-space: nowrap; }

.qui-iconbtn {
  position: relative;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-lg);
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  flex: none;
  transition: background var(--dur-hover) var(--ease-state), color var(--dur-hover) var(--ease-state);
}
.qui-iconbtn svg { width: 18px; height: 18px; }
.qui-iconbtn:hover { background: var(--surface-2); color: var(--ink); }
.qui-iconbtn:active { transform: translateY(1px); }
.qui-iconbtn__badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: var(--weight-medium);
  line-height: 15px;
  text-align: center;
  background: var(--accent-ink);
  color: #fff;
}
[data-theme="dark"] .qui-iconbtn__badge, .dark .qui-iconbtn__badge { background: var(--accent); color: var(--accent-contrast); }

.qui-topbar__notif { position: relative; display: inline-flex; }
.qui-topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-4) var(--pad-content);
  max-width: var(--maxw-app);
  margin: 0 auto;
}

/* ── K1: CommandPalette ── */
.qui-cmdk__scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  background: var(--scrim);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: qui-scrim-in var(--dur-popover) var(--ease-fade);
}
.qui-cmdk {
  position: fixed;
  z-index: var(--z-scrim);
  top: 18vh;
  left: 50%;
  transform: translateX(-50%);
  width: min(560px, calc(100vw - var(--space-12)));
  max-height: 64vh;
  display: flex;
  flex-direction: column;
  background: var(--surface-2);
  border-radius: var(--radius-xl);
  box-shadow: var(--lift-shadow);
  overflow: hidden;
  font-family: var(--font-body);
  animation: qui-palette-in var(--dur-popover) var(--ease-entrance);
}
@keyframes qui-scrim-in { from { opacity: 0; } }
@keyframes qui-palette-in {
  from { opacity: 0; transform: translateX(-50%) translateY(-14px) scale(0.985); }
}

.qui-cmdk__inputrow {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-6) var(--space-8);
  position: relative;
}
.qui-cmdk__inputrow::after {
  content: "";
  position: absolute;
  left: var(--space-8);
  right: var(--space-8);
  bottom: 0;
  height: 1px;
  background: var(--hair-soft);
}
.qui-cmdk__inputrow:focus-within::after { height: 2px; background: var(--accent-ink); }
.qui-cmdk__searchicon { width: 16px; height: 16px; color: var(--subtle); flex: none; display: grid; place-items: center; }
.qui-cmdk__searchicon svg { width: 16px; height: 16px; }
.qui-cmdk__input {
  flex: 1;
  border: none;
  outline: none;
  background: none;
  color: var(--ink);
  font-family: inherit;
  font-size: var(--text-body-lg);
}
.qui-cmdk__input::placeholder { color: var(--subtle); }

.qui-cmdk__list { overflow-y: auto; padding: var(--space-3); scroll-padding-block: var(--space-3); }
.qui-cmdk__group { padding-bottom: var(--space-2); }
.qui-cmdk__group [cmdk-group-heading] {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--subtle);
  padding: var(--space-5) var(--space-5) var(--space-3);
}
.qui-cmdk__item {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: var(--text-body);
  cursor: pointer;
  user-select: none;
}
.qui-cmdk__item[data-selected="true"] { background: var(--surface-3); color: var(--ink); }
.qui-cmdk__item[data-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.qui-cmdk__itemicon { width: 16px; height: 16px; flex: none; color: var(--subtle); display: grid; place-items: center; }
.qui-cmdk__itemicon svg { width: 16px; height: 16px; }
.qui-cmdk__item[data-selected="true"] .qui-cmdk__itemicon { color: var(--accent-ink); }
.qui-cmdk__itemlabel { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qui-cmdk__shortcut { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); flex: none; }
.qui-cmdk__enter { width: 14px; height: 14px; flex: none; color: var(--accent-ink); opacity: 0; }
.qui-cmdk__enter svg { width: 14px; height: 14px; }
.qui-cmdk__item[data-selected="true"] .qui-cmdk__enter { opacity: 1; }
.qui-cmdk__empty {
  padding: var(--space-9) var(--space-5);
  text-align: center;
  font-size: var(--text-body-sm);
  color: var(--subtle);
}

/* ── K1: Popover ── */
.qui-popover {
  z-index: var(--z-popover);
  min-width: 264px;
  max-width: min(360px, calc(100vw - var(--space-10)));
  padding: var(--space-3);
  background: var(--surface-2);
  border-radius: var(--radius-xl);
  box-shadow: var(--lift-shadow);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--ink);
  transform-origin: var(--radix-popover-content-transform-origin, var(--radix-dropdown-menu-content-transform-origin));
}
.qui-popover[data-state="open"] { animation: qui-pop-in var(--dur-popover) var(--ease-entrance); }
.qui-popover[data-side="top"][data-state="open"] { animation-name: qui-pop-in-up; }
@keyframes qui-pop-in { from { opacity: 0; transform: translateY(-6px); } }
@keyframes qui-pop-in-up { from { opacity: 0; transform: translateY(6px); } }
.qui-popover__heading {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--subtle);
  padding: var(--space-4) var(--space-5) var(--space-3);
}

/* ── K1: MenuPopover ── */
.qui-menu { min-width: 200px; }
.qui-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: var(--text-body);
  cursor: pointer;
  user-select: none;
  outline: none;
}
.qui-menu__item[data-highlighted] { background: var(--surface-3); color: var(--ink); }
.qui-menu__item[data-disabled] { opacity: 0.55; cursor: not-allowed; }
.qui-menu__item--critical { color: var(--bad-ink); }
.qui-menu__item--critical[data-highlighted] { background: var(--bad-soft); color: var(--bad-ink); }
.qui-menu__icon { width: 16px; height: 16px; flex: none; color: var(--subtle); display: grid; place-items: center; }
.qui-menu__icon svg { width: 16px; height: 16px; }
.qui-menu__item--critical .qui-menu__icon { color: var(--bad-ink); }
.qui-menu__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qui-menu__shortcut { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); flex: none; }
.qui-menu__sep { height: 1px; background: var(--hair-soft); margin: var(--space-3) var(--space-2); }

/* ── K1: Toast ── */
.qui-toast__viewport {
  position: fixed;
  bottom: var(--space-9);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  width: min(380px, calc(100vw - var(--space-10)));
  max-width: 100vw;
  margin: 0;
  padding: 0;
  list-style: none;
  outline: none;
}
.qui-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-6);
  background: var(--surface-3);
  border-radius: var(--radius-lg);
  box-shadow: var(--lift-shadow);
  font-size: var(--text-body-sm);
}
.qui-toast[data-state="open"] { animation: qui-toast-in var(--dur-toast) var(--ease-fade); }
.qui-toast[data-state="closed"] { animation: qui-toast-out var(--dur-toast) var(--ease-fade) forwards; }
.qui-toast[data-swipe="move"] { transform: translateX(var(--radix-toast-swipe-move-x)); }
.qui-toast[data-swipe="cancel"] { transform: translateX(0); transition: transform var(--dur-hover) var(--ease-state); }
.qui-toast[data-swipe="end"] { animation: qui-toast-out var(--dur-toast) var(--ease-fade) forwards; }
@keyframes qui-toast-in { from { opacity: 0; transform: translateY(12px); } }
@keyframes qui-toast-out { to { opacity: 0; transform: translateY(8px); } }

.qui-toast__icon { width: 16px; height: 16px; flex: none; margin-top: 1px; display: grid; place-items: center; }
.qui-toast__icon svg { width: 16px; height: 16px; }
.qui-toast--info .qui-toast__icon { color: var(--subtle); }
.qui-toast--success .qui-toast__icon { color: var(--ok-ink); }
.qui-toast--warning .qui-toast__icon { color: var(--warn-ink); }
.qui-toast--critical .qui-toast__icon { color: var(--bad-ink); }

.qui-toast__body { flex: 1; min-width: 0; }
.qui-toast__title { font-weight: var(--weight-medium); color: var(--ink); line-height: var(--leading-ui); }
.qui-toast__variant {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.qui-toast--info .qui-toast__variant { color: var(--subtle); }
.qui-toast--success .qui-toast__variant { color: var(--ok-ink); }
.qui-toast--warning .qui-toast__variant { color: var(--warn-ink); }
.qui-toast--critical .qui-toast__variant { color: var(--bad-ink); }
.qui-toast__desc { color: var(--muted); font-size: var(--text-caption); margin-top: 1px; line-height: var(--leading-ui); }

.qui-toast__action {
  flex: none;
  align-self: center;
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-md);
  border: none;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: background var(--dur-hover) var(--ease-state);
}
.qui-toast__action:hover { background: var(--surface-2); }
.qui-toast__action:active { transform: translateY(1px); }
.qui-toast__close {
  flex: none;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  border: none;
  background: none;
  color: var(--subtle);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--dur-hover) var(--ease-state), background var(--dur-hover) var(--ease-state);
}
.qui-toast__close svg { width: 12px; height: 12px; }
.qui-toast__close:hover { color: var(--ink); background: var(--surface-2); }

/* ===============================================================
   K4: planning & scheduling — KanbanBoard, GanttChart, Calendar
   Zero-dependency. Tokens-only. §1: state is a dot/tint/ring, never
   a colored border. Animations are RM-killed globally via tokens.css.
   =============================================================== */

/* sr-only utility (announcer / labels) */
.qui-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;
}

/* ── K4: KanbanBoard ── */
.qui-kanban { display: flex; gap: var(--space-6); align-items: flex-start; overflow-x: auto; font-family: var(--font-body); }
.qui-kanban__col {
  flex: 0 0 248px; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-lg);
  min-height: 120px;
}
.qui-kanban__colhead {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-5) var(--space-6); border-bottom: 1px solid var(--hair-soft);
}
.qui-kanban__collabel { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: .08em; color: var(--subtle); }
.qui-kanban__count { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); background: var(--surface-3); border-radius: var(--radius-pill); padding: 1px 7px; }
.qui-kanban__list { list-style: none; margin: 0; padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-5); min-height: 48px; }
.qui-kanban__empty { text-align: center; color: var(--subtle); font-family: var(--font-mono); padding: var(--space-6) 0; }
.qui-kanban__card {
  background: var(--surface-2); border: 1px solid var(--hair); border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-6); cursor: grab; outline: none;
  transition: background var(--dur-hover) var(--ease-state), border-color var(--dur-hover) var(--ease-state), box-shadow var(--dur-hover) var(--ease-state);
}
.qui-kanban__card:hover { background: var(--surface-3); border-color: var(--hair); }
.qui-kanban__card:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft), inset 0 0 0 1px var(--accent); }
.qui-kanban__card.is-grabbed { box-shadow: inset 0 0 0 1px var(--accent), 0 4px 16px var(--scrim); cursor: grabbing; }
.qui-kanban__cardtop { display: flex; align-items: center; gap: var(--space-4); }
.qui-kanban__cardtitle { font-size: var(--text-body-sm); font-weight: var(--weight-medium); color: var(--ink); }
.qui-kanban__pri { width: 7px; height: 7px; border-radius: var(--radius-round); flex: 0 0 auto; }
.qui-kanban__pri--crit { background: var(--bad); } .qui-kanban__pri--high { background: var(--warn); }
.qui-kanban__pri--med { background: var(--accent); } .qui-kanban__pri--low { background: var(--off); }
.qui-kanban__cardmeta { margin-top: var(--space-3); display: flex; gap: var(--space-4); align-items: center; font-family: var(--font-mono); font-size: var(--text-micro); color: var(--muted); }
.qui-kanban__tag { background: var(--surface-3); border-radius: var(--radius-xs); padding: 1px 6px; color: var(--muted); }

/* ── K4: GanttChart ── */
.qui-gantt { box-sizing: border-box; --qui-gantt-gutter: 120px; font-family: var(--font-body); width: 100%; }
.qui-gantt__axis { display: grid; grid-template-columns: var(--qui-gantt-gutter) 1fr; align-items: center; padding-bottom: var(--space-4); }
.qui-gantt__axisticks { position: relative; height: 14px; }
.qui-gantt__tick { position: absolute; transform: translateX(-50%); font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); white-space: nowrap; }
.qui-gantt__body { position: relative; }
.qui-gantt__now { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--accent); box-shadow: 0 0 6px var(--accent-soft); z-index: 2; }
.qui-gantt__row { display: grid; grid-template-columns: var(--qui-gantt-gutter) 1fr; align-items: center; border-top: 1px solid var(--hair-soft); }
.qui-gantt__rowlabel { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted); padding: var(--space-4) var(--space-5) var(--space-4) 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qui-gantt__lane { position: relative; height: 30px; }
.qui-gantt__bar {
  position: absolute; top: 50%; transform: translateY(-50%); height: 20px;
  border: none; border-radius: var(--radius-sm); cursor: pointer; overflow: hidden;
  display: flex; align-items: center; padding: 0 var(--space-4);
  font-family: var(--font-mono); font-size: var(--text-micro); color: var(--ink);
  background: var(--surface-3);
  transition: filter var(--dur-hover) var(--ease-state), box-shadow var(--dur-hover) var(--ease-state);
}
.qui-gantt__bar:hover { filter: brightness(1.06); }
.qui-gantt__bar:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft); outline: none; }
.qui-gantt__bar--active { background: var(--accent); color: var(--accent-contrast); }
.qui-gantt__bar--done { background: var(--ok-soft); color: var(--ok-ink); }
.qui-gantt__bar--warn { background: var(--warn-soft); color: var(--warn-ink); }
.qui-gantt__bar--bad { background: var(--bad-soft); color: var(--bad-ink); }
.qui-gantt__barlabel { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qui-gantt__flag { position: absolute; top: 3px; right: 3px; width: 5px; height: 5px; border-radius: var(--radius-round); background: var(--bad); }

/* ── K4: Calendar ── */
/* container-fluid: fills its cell up to a sensible cap, shrinks without
   overflow (7-col aspect-ratio grid scales). Override --qui-cal-max to fill a
   wide dashboard cell fully. */
.qui-cal { box-sizing: border-box; width: 100%; max-width: var(--qui-cal-max, 340px); min-width: 0; font-family: var(--font-body); background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-lg); padding: var(--space-6); }
.qui-cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-5); }
.qui-cal__title { font-family: var(--font-display); font-weight: var(--weight-medium); font-size: var(--text-body-lg); color: var(--ink); }
.qui-cal__year { color: var(--subtle); }
.qui-cal__nav { width: 26px; height: 26px; border: 1px solid var(--hair); background: var(--surface-2); border-radius: var(--radius-sm); color: var(--muted); cursor: pointer; font-size: var(--text-body); line-height: 1; }
.qui-cal__nav:hover { background: var(--surface-3); color: var(--ink); }
.qui-cal__dow, .qui-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-2); }
.qui-cal__dowcell { text-align: center; font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: .04em; color: var(--subtle); padding-bottom: var(--space-3); }
.qui-cal__pad { aspect-ratio: 1; }
.qui-cal__day {
  position: relative; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: var(--radius-md); cursor: pointer;
  color: var(--ink); font-family: var(--font-mono); font-size: var(--text-caption);
  transition: background var(--dur-hover) var(--ease-state);
}
.qui-cal__day:hover { background: var(--surface-2); }
.qui-cal__day:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-soft); }
.qui-cal__day.has-heat { background: rgb(255 107 0 / calc(var(--qui-cal-heat, 0) * 0.32)); }
.qui-cal__day.is-today { box-shadow: inset 0 0 0 1px var(--accent); }
.qui-cal__day.is-selected { background: var(--accent); color: var(--accent-contrast); }
.qui-cal__day.is-selected.is-today { box-shadow: none; }
.qui-cal__day:disabled { color: var(--off); cursor: not-allowed; }
.qui-cal__dot { position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: var(--radius-round); }
.qui-cal__dot--accent { background: var(--accent); } .qui-cal__dot--ok { background: var(--ok); }
.qui-cal__dot--warn { background: var(--warn); } .qui-cal__dot--bad { background: var(--bad); }
.qui-cal__day.is-selected .qui-cal__dot { background: var(--accent-contrast); }

/* ===============================================================
   K5: dashboard frame — WidgetFrame, LoadingSkeleton, ErrorState,
   DetailPanel. FILL-THE-CONTAINER law: roots fill width + height,
   bodies flex to fill (min-height:0), no fixed outer dimensions.
   =============================================================== */

/* ── K5: WidgetFrame (the dashboard widget container) ── */
.qui-widget {
  box-sizing: border-box; display: flex; flex-direction: column;
  width: 100%; height: 100%; min-height: 0; min-width: 0;
  background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-lg);
  font-family: var(--font-body); overflow: hidden;
}
.qui-widget__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-5); padding: var(--space-6) var(--space-7); border-bottom: 1px solid var(--hair-soft); }
.qui-widget__titles { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.qui-widget__title { font-size: var(--text-body); font-weight: var(--weight-medium); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qui-widget__sub { font-size: var(--text-micro); color: var(--subtle); }
.qui-widget__controls { display: flex; align-items: center; gap: var(--space-4); flex: none; }
.qui-widget__seg { display: inline-flex; border: 1px solid var(--hair); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); }
.qui-widget__segbtn { font-family: var(--font-mono); font-size: var(--text-micro); padding: 3px 8px; border: none; background: transparent; color: var(--muted); cursor: pointer; }
.qui-widget__segbtn.is-active { background: var(--accent-soft); color: var(--accent-ink); }
.qui-widget__body { flex: 1; min-height: 0; min-width: 0; padding: var(--space-6); display: flex; flex-direction: column; overflow: auto; }
/* A single direct child (chart / state) fills the body when there is room,
   but keeps at least its content height and lets the body SCROLL rather than
   crop when the cell is too short (fill-the-container law: contain, never clip). */
.qui-widget__body > * { flex: 1 1 auto; min-height: min-content; }

/* ── K5: LoadingSkeleton ──
   NOTE: the bare `.qui-skel` class is ALSO used by KpiCard as a shimmer
   *modifier* on the card itself (a different component). To avoid that
   container layout (flex column / width:height 100%) leaking onto the
   KpiCard skeleton and inflating its scrollWidth, scope these K5
   container rules to the variant-carrying class the LoadingSkeleton
   ALWAYS emits (qui-skel--text|chart|card). KpiCard never sets a variant. */
.qui-skel--text, .qui-skel--chart, .qui-skel--card { display: flex; flex-direction: column; gap: var(--space-5); width: 100%; height: 100%; min-height: 0; min-width: 0; }
.qui-skel__line, .qui-skel__block { background: var(--surface-3); border-radius: var(--radius-sm); position: relative; overflow: hidden; }
.qui-skel__line { height: 12px; }
.qui-skel__line--head { height: 14px; }
.qui-skel__block { flex: 1; min-height: 80px; }
.qui-skel--chart { gap: 0; }
/* shimmer sweep — RM-killed globally via tokens.css */
.qui-skel__line::after, .qui-skel__block::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--shimmer, rgba(255,255,255,.06)), transparent);
  transform: translateX(-100%); animation: qui-shimmer 1.4s infinite;
}
@keyframes qui-shimmer { 100% { transform: translateX(100%); } }

/* ── K5: ErrorState ── */
.qui-errstate { box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: var(--space-3); width: 100%; height: 100%; min-height: 0; padding: var(--space-6); color: var(--muted); }
.qui-errstate__art { width: 28px; height: 28px; color: var(--bad); }
.qui-errstate__art svg { width: 100%; height: 100%; }
.qui-errstate__title { font-size: var(--text-body-sm); font-weight: var(--weight-medium); color: var(--ink); margin: 0; }
.qui-errstate__msg { font-size: var(--text-caption); color: var(--subtle); margin: 0; max-width: 36ch; }
.qui-errstate__retry { margin-top: var(--space-3); font-family: var(--font-body); font-size: var(--text-caption); font-weight: var(--weight-medium); padding: var(--space-3) var(--space-7); border: 1px solid var(--hair); border-radius: var(--radius-md); background: var(--surface-2); color: var(--ink); cursor: pointer; }
.qui-errstate__retry:hover { background: var(--surface-3); }

/* ── K5: DetailPanel (side drawer) ── */
.qui-detail { position: fixed; inset: 0; z-index: 50; }
.qui-detail__scrim { position: absolute; inset: 0; background: var(--scrim); }
.qui-detail__panel {
  position: absolute; top: 0; bottom: 0; width: var(--qui-detail-w, min(420px, 100%));
  display: flex; flex-direction: column; background: var(--surface); box-shadow: var(--lift-shadow);
  outline: none; animation: qui-detail-in var(--dur-popover, .18s) var(--ease-entrance, ease) both;
}
.qui-detail__panel--right { right: 0; border-left: 1px solid var(--hair); }
.qui-detail__panel--left { left: 0; border-right: 1px solid var(--hair); }
@keyframes qui-detail-in { from { transform: translateX(var(--qui-detail-from, 12px)); opacity: .6; } to { transform: none; opacity: 1; } }
.qui-detail__panel--left { --qui-detail-from: -12px; }
.qui-detail__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-5); padding: var(--space-6) var(--space-7); border-bottom: 1px solid var(--hair-soft); }
.qui-detail__title { font-family: var(--font-display); font-weight: var(--weight-medium); font-size: var(--text-body-lg); color: var(--ink); margin: 0; }
.qui-detail__close { width: 28px; height: 28px; border: none; background: transparent; border-radius: var(--radius-sm); color: var(--subtle); cursor: pointer; }
.qui-detail__close svg { width: 14px; height: 14px; }
.qui-detail__close:hover { background: var(--surface-2); color: var(--ink); }
.qui-detail__body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-7); font-size: var(--text-body); color: var(--muted); }
.qui-detail__foot { padding: var(--space-6) var(--space-7); border-top: 1px solid var(--hair-soft); display: flex; justify-content: flex-end; gap: var(--space-4); }

/* ===============================================================
   K6: charts — one ECharts wrapper (fill-container) + BulletChart.
   FILL-THE-CONTAINER law: charts fill width+height, min-height floor,
   resize via ResizeObserver; NULL→EmptyState (never a fabricated zero).
   =============================================================== */
.qui-echart { width: 100%; height: 100%; min-height: var(--qui-chart-min, 160px); min-width: 0; }
/* the canvas root echarts injects must fill the wrapper */
.qui-echart > div:first-child { width: 100% !important; height: 100% !important; }

/* ── K6: BulletChart (lightweight inline indicator) ── */
.qui-bullet { display: flex; align-items: center; gap: var(--space-5); width: 100%; font-family: var(--font-body); }
.qui-bullet__label { font-size: var(--text-caption); color: var(--muted); white-space: nowrap; flex: none; }
.qui-bullet__track { position: relative; flex: 1; min-width: 0; height: 8px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.qui-bullet__band { position: absolute; top: 0; bottom: 0; opacity: .35; }
.qui-bullet__band--ok { background: var(--ok); }
.qui-bullet__band--warn { background: var(--warn); }
.qui-bullet__band--bad { background: var(--bad); }
.qui-bullet__measure { position: absolute; left: 0; top: 2px; bottom: 2px; border-radius: var(--radius-pill); background: var(--accent); }
.qui-bullet__target { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink); transform: translateX(-1px); }
.qui-bullet__val { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--ink); white-space: nowrap; flex: none; }

/* ===============================================================
   SPATIAL (§2) — net-new Vantage set: FloorPlanMap/GeoMap,
   AssetMarker, MovementTrail, Geofence, ProximityRing.
   Tokens-only, both themes. Accent = fills/dots/strokes only.
   Ported from CD "Quoriam CD - Spatial" (classes renamed to qui-*).
   =============================================================== */

/* shared stage — floor plan + geo map share .qui-spatial-stage */
.qui-spatial { width: 100%; }
.qui-spatial-stage {
  position: relative; border: 1px solid var(--hair); border-radius: var(--radius-sm);
  overflow: hidden; background: var(--surface-2); height: 340px; min-height: 280px;
}
.qui-spatial-stage--center { display: flex; align-items: center; justify-content: center; }

.qui-fp-grid {
  background-image:
    repeating-linear-gradient(0deg, transparent, transparent 27px, var(--hair) 27px, var(--hair) 28px),
    repeating-linear-gradient(90deg, transparent, transparent 27px, var(--hair) 27px, var(--hair) 28px);
}
.qui-geo-grid {
  background-color: var(--surface-2);
  background-image:
    repeating-linear-gradient(0deg, transparent, transparent 31px, var(--hair-soft) 31px, var(--hair-soft) 32px),
    repeating-linear-gradient(90deg, transparent, transparent 31px, var(--hair-soft) 31px, var(--hair-soft) 32px);
}

/* loading + honest-null states */
.qui-spatial__skel {
  width: 78%; height: 72%; border-radius: var(--radius-xs);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%; animation: qui-spatial-sh 1.4s infinite;
}
@keyframes qui-spatial-sh { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.qui-spatial__empty { text-align: center; color: var(--subtle); padding: var(--space-10) var(--space-9); }
.qui-spatial__empty-dash { font-family: var(--font-mono); font-size: 26px; display: block; margin-bottom: var(--space-3); color: var(--subtle); }
.qui-spatial__empty-why { font-size: var(--text-caption); color: var(--muted); max-width: 40ch; margin: 0 auto; }

/* rooms + overlay shapes */
.qui-fp-room {
  position: absolute; border: 1px solid var(--hair); background: color-mix(in srgb, var(--surface) 50%, transparent);
  border-radius: var(--radius-xs); padding: 4px 6px; overflow: hidden;
}
.qui-fp-room__label { font-family: var(--font-mono); font-size: 8.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.qui-fp-shape {
  position: absolute; border: 1.5px solid var(--accent); background: var(--accent-soft);
  border-radius: var(--radius-xs); pointer-events: none;
}
.qui-fp-shape__label { position: absolute; top: 3px; left: 5px; font-family: var(--font-mono); font-size: 8px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent-ink); }

/* marker — state by SHAPE (not color alone), two-chip tooltip */
.qui-marker-host { display: flex; align-items: center; justify-content: center; }
.qui-marker-host--positioned { position: absolute; transform: translate(-50%, -50%); width: 24px; height: 24px; cursor: pointer; z-index: 5; }
.qui-marker { position: relative; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
.qui-marker__pin {
  width: 13px; height: 13px; border-radius: var(--radius-round); border: 2px solid var(--surface);
  box-shadow: var(--lift-shadow); position: relative; z-index: 2;
}
.qui-marker--run .qui-marker__pin { background: var(--run); }
.qui-marker--idle .qui-marker__pin { background: var(--idle); }
.qui-marker--setup .qui-marker__pin { background: var(--setup); border-radius: 2px; }
.qui-marker--fault .qui-marker__pin { background: var(--fault); clip-path: polygon(50% 4%, 96% 96%, 4% 96%); border-radius: 0; }
.qui-marker--down .qui-marker__pin { background: var(--down); width: 13px; height: 4px; border-radius: 1px; }
.qui-marker--maint .qui-marker__pin { background: var(--maint); transform: rotate(45deg); border-radius: 2px; }
.qui-marker--offline .qui-marker__pin { border-style: dashed; background: transparent; box-shadow: none; }
.qui-marker__warn { position: absolute; top: -3px; right: -3px; width: 10px; height: 10px; border-radius: var(--radius-round); background: var(--warn); border: 1.5px solid var(--surface); z-index: 3; }
.qui-marker__unc {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: var(--radius-round);
  border: 1px dashed color-mix(in srgb, var(--accent) 55%, transparent); background: var(--accent-soft-2); z-index: 0;
}
.qui-marker__tip {
  position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%);
  background: var(--surface-3); border: 1px solid var(--hair); border-radius: var(--radius-sm);
  padding: 7px 9px; min-width: 150px; opacity: 0; pointer-events: none;
  transition: opacity var(--dur-press, .12s) var(--ease-state, ease); box-shadow: var(--lift-shadow); z-index: 20;
}
.qui-marker-host:hover { z-index: 18; }
.qui-marker-host:hover .qui-marker__tip,
.qui-marker-host:focus-visible .qui-marker__tip { opacity: 1; }
.qui-marker__tip-title { font-size: var(--text-body-sm); font-weight: var(--weight-medium); color: var(--ink); white-space: nowrap; display: flex; align-items: center; gap: 6px; }
.qui-marker__tip-coord { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); margin-top: 4px; white-space: nowrap; }
.qui-marker__tip-chips { display: flex; gap: 5px; margin-top: 6px; flex-wrap: wrap; }

/* anonymized people presence — zone density ONLY */
.qui-presence { width: 100%; }
.qui-presence__field { position: relative; height: 96px; border-radius: var(--radius-xs); overflow: hidden; border: 1px solid var(--hair); }
.qui-presence__blob { position: absolute; transform: translate(-50%, -50%); border-radius: var(--radius-round); filter: blur(13px); pointer-events: none; }
[data-theme="dark"] .qui-presence__blob, .dark .qui-presence__blob { mix-blend-mode: screen; }
[data-theme="light"] .qui-presence__blob, .light .qui-presence__blob { mix-blend-mode: multiply; }
.qui-presence__caption { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); margin-top: var(--space-4); }

/* floating overlays (legend / scalebar / zoom / attribution) */
.qui-ov {
  position: absolute; z-index: 8; background: var(--blur-bg); backdrop-filter: blur(8px);
  border: 1px solid var(--hair); border-radius: var(--radius-sm); box-shadow: var(--lift-shadow);
}
.qui-ov--tl { top: 10px; left: 10px; }
.qui-ov--tr { top: 10px; right: 10px; }
.qui-ov--bl { bottom: 10px; left: 10px; }
.qui-ov--br { bottom: 10px; right: 10px; }
.qui-ov__head { font-family: var(--font-mono); font-size: 8.5px; text-transform: uppercase; letter-spacing: var(--tracking-kicker); color: var(--subtle); padding: 7px 10px 4px; }
.qui-legend { padding: 4px 10px 9px; display: flex; flex-direction: column; gap: 5px; }
.qui-legend__row { display: flex; align-items: center; gap: 7px; font-size: 10.5px; color: var(--muted); }
.qui-legend__sw { width: 11px; height: 11px; border-radius: var(--radius-round); flex: none; border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--hair); }
.qui-legend__sw--square { border-radius: 2px; }
.qui-legend__sw--triangle { clip-path: polygon(50% 0, 100% 100%, 0 100%); border: 0; box-shadow: none; }
.qui-legend__sw--dash { background: transparent !important; border: 1.5px dashed var(--subtle); box-shadow: none; }
.qui-legend__sw--draft { border-color: var(--setup); }
.qui-legend__sw--ring { background: transparent; border: 2px solid var(--accent); box-shadow: none; border-radius: var(--radius-round); }
.qui-scalebar { display: flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 9px; color: var(--muted); padding: 6px 10px; }
.qui-scalebar__bar { height: 5px; border-bottom: 2px solid var(--muted); border-left: 2px solid var(--muted); border-right: 2px solid var(--muted); }
.qui-spatial__attr { position: absolute; font-family: var(--font-mono); font-size: 8px; color: var(--subtle); padding: 4px 8px; }
.qui-zoomctl { display: flex; gap: 3px; padding: 4px; }
.qui-zoomctl button { width: 24px; height: 24px; border: 1px solid var(--hair); background: var(--surface-3); color: var(--muted); border-radius: var(--radius-xs); cursor: pointer; font-size: 13px; line-height: 1; }
.qui-zoomctl button:hover { background: var(--surface-2); color: var(--ink); }

/* movement trail svg */
.qui-trail__svg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3; pointer-events: none; }

/* geofence */
.qui-fence__layout { display: grid; grid-template-columns: 1.5fr 1fr; gap: var(--space-7); }
@media (max-width: 720px) { .qui-fence__layout { grid-template-columns: 1fr; } }
.qui-fence__svg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; }
.qui-fence__pt {
  position: absolute; transform: translate(-50%, -50%); width: 13px; height: 13px; border-radius: var(--radius-round);
  background: var(--surface); border: 2px solid var(--accent); cursor: grab; z-index: 6;
}
/* WCAG 2.5.8: ≥24×24px interactive hit area without enlarging the visual dot. */
.qui-fence__pt::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 24px; height: 24px; border-radius: var(--radius-round);
}
.qui-fence__pt--draft { border-style: dashed; border-color: var(--setup); }
.qui-fence__handle { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 5px; height: 5px; border-radius: var(--radius-round); background: var(--accent); }
.qui-fence__pt--draft .qui-fence__handle { background: var(--setup); }
.qui-fence__side { display: flex; flex-direction: column; gap: var(--space-5); }
.qui-fence__card { border: 1px solid var(--hair); border-radius: var(--radius-sm); background: var(--surface); padding: var(--space-6); }
.qui-fence__actions { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.qui-fence__note { font-size: var(--text-caption); color: var(--muted); }

/* key/value readout (shared by geofence side panel) */
.qui-kv { display: flex; justify-content: space-between; gap: var(--space-6); font-size: var(--text-caption); padding: 3px 0; border-bottom: 1px solid var(--hair-soft); }
.qui-kv:last-child { border-bottom: 0; }
.qui-kv__k { color: var(--muted); }
.qui-kv__v { color: var(--ink); font-family: var(--font-mono); display: inline-flex; align-items: center; }

/* small button (geofence save/discard) — tokens-only */
.qui-btn { font-family: var(--font-body); font-size: var(--text-body-sm); font-weight: var(--weight-medium); padding: 6px 12px; border-radius: var(--radius-xs); border: 1px solid var(--hair); background: var(--surface-3); color: var(--ink); cursor: pointer; transition: background var(--dur-press, .12s) var(--ease-state, ease); }
.qui-btn:hover { background: var(--surface-2); }
.qui-btn--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }
.qui-btn--primary:hover { background: var(--accent-ink); }
.qui-btn--sm { padding: 4px 9px; font-size: var(--text-caption); }

/* proximity ring */
.qui-pr { width: 100%; }
.qui-pr__bar { display: flex; align-items: center; gap: var(--space-5); margin-bottom: var(--space-5); }
.qui-pr__bar-lab { font-family: var(--font-mono); font-size: 9px; text-transform: uppercase; letter-spacing: .1em; color: var(--subtle); }
.qui-pr__chip { margin-left: auto; }
.qui-pr__stage { position: relative; height: 240px; border: 1px solid var(--hair); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); }
.qui-pr__ring {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: var(--radius-round);
  border: 1.5px solid var(--accent); background: radial-gradient(circle, var(--accent-soft), transparent 70%);
}
.qui-pr__ring--secondary { background: none; border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
.qui-pr__ring--live { animation: qui-pr-pulse var(--pulse-fresh, 2.4s) ease-out infinite; }
@keyframes qui-pr-pulse {
  0% { box-shadow: 0 0 0 0 var(--accent-soft); }
  70% { box-shadow: 0 0 0 18px rgba(255,107,0,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,107,0,0); }
}
.qui-pr__src { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 13px; height: 13px; border-radius: var(--radius-round); background: var(--accent); border: 2px solid var(--surface); box-shadow: var(--lift-shadow); z-index: 3; }
.qui-pr__tgt { position: absolute; transform: translate(-50%, -50%); width: 9px; height: 9px; border-radius: var(--radius-round); background: var(--setup); border: 1.5px solid var(--surface); z-index: 2; }
.qui-pr__tick { position: absolute; left: 50%; transform: translateX(-50%); font-family: var(--font-mono); font-size: 8.5px; color: var(--subtle); background: var(--blur-bg); padding: 0 3px; }
.qui-pr__note { font-size: var(--text-caption); color: var(--muted); margin-top: var(--space-4); }

/* ────────────────────────────────────────────────────────────────────────
   §3 DOMAIN ATOMS — OeeGauge / OcrOverlay / EvidenceTrace / SourceDrawer
   Tokens-only; both themes. Charts (§3.2) are ECharts-driven (no CSS here).
   Accent is fills/strokes only; low-confidence / limit marks use --warn.
   ──────────────────────────────────────────────────────────────────────── */

/* ── §3.1 OeeGauge ── */
.qui-oee { width: 100%; }
.qui-oee__bar { display: flex; align-items: center; gap: var(--space-5); margin-bottom: var(--space-5); }
.qui-oee__bar-lab { font-family: var(--font-mono); font-size: 9px; text-transform: uppercase; letter-spacing: .1em; color: var(--subtle); }
.qui-oee__chip { margin-left: auto; }
.qui-oee__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
@media (max-width: 600px) { .qui-oee__grid { grid-template-columns: 1fr; } }
.qui-oee__cell { border: 1px solid var(--hair); border-radius: var(--radius-sm); background: var(--surface); padding: 11px 11px 10px; display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.qui-oee__cell--lead { border-color: var(--hair); background: var(--surface-2); }
.qui-oee__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.qui-oee__name { font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); } /* --muted, not --subtle: clears AA on surface/surface-2 in both themes (0.6.1 a11y) */
.qui-oee__box { height: 128px; position: relative; }
.qui-oee__box--lg { height: 150px; }
.qui-oee__box .qui-echart { width: 100% !important; height: 100% !important; }
.qui-oee__dash { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 30px; color: var(--off); }
.qui-oee__foot { font-size: 10.5px; color: var(--muted); min-height: 15px; line-height: 1.35; }
.qui-oee__mul { font-family: var(--font-mono); font-size: 11px; color: var(--muted); text-align: center; margin: 2px 0 6px; letter-spacing: .02em; }
.qui-oee__mul b { color: var(--ink); }
.qui-oee__x { color: var(--accent-ink); padding: 0 2px; }

/* ── §3.3 OcrOverlay ── */
.qui-ocr { width: 100%; }
.qui-ocr__page { position: relative; border: 1px solid var(--hair); border-radius: var(--radius-xs); background: var(--surface-2); overflow: hidden; width: 100%; box-shadow: inset 0 0 0 1px var(--hair-soft, var(--hair)); }
.qui-ocr__page--center { display: flex; align-items: center; justify-content: center; }
.qui-ocr__skel { width: 84%; height: 88%; border-radius: var(--radius-xs); background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%); background-size: 200% 100%; animation: qui-ocr-sh 1.4s infinite; }
@keyframes qui-ocr-sh { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.qui-ocr__none { text-align: center; color: var(--subtle); padding: 18px; }
.qui-ocr__none-mark { display: block; font-family: var(--font-mono); font-size: 26px; margin-bottom: 6px; color: var(--off); }
.qui-ocr__none-why { font-size: 11px; color: var(--muted); }
.qui-ocr__w { position: absolute; display: flex; align-items: center; border: 1.3px solid var(--idle); border-radius: 2px; padding: 0 3px; white-space: nowrap; font-family: var(--font-mono); color: var(--muted); background: color-mix(in srgb, var(--surface) 30%, transparent); transition: box-shadow var(--dur-hover, .1s) var(--ease-state, ease), opacity var(--dur-hover, .1s) var(--ease-state, ease); cursor: default; overflow: hidden; }
.qui-ocr__w--hi { border-color: var(--run); }
.qui-ocr__w--mid { border-color: var(--idle); }
.qui-ocr__w--lo { border-color: var(--warn); background: var(--warn-soft); color: var(--ink); }
.qui-ocr__w--unk { border-color: var(--subtle); border-style: dashed; } /* no/invalid confidence — neutral dashed, never amber */
.qui-ocr__w--dim { opacity: .9; } /* was .28 — dimmed words are real OCR content (must clear AA: .9 → ~5:1 light / ~7:1 dark). Emphasis on low-confidence words is carried by the --lo/highlight border, so dim is a secondary cue, never the only signal (0.6.1 a11y) */
.qui-ocr__w:hover { z-index: 9; box-shadow: var(--lift-shadow); }
.qui-ocr__cf { position: absolute; bottom: 101%; left: 0; font-size: 8px; background: var(--surface-3); border: 1px solid var(--hair); border-radius: 3px; padding: 1px 4px; opacity: 0; pointer-events: none; transition: opacity var(--dur-hover, .1s) var(--ease-state, ease); white-space: nowrap; color: var(--muted); }
.qui-ocr__w:hover .qui-ocr__cf { opacity: 1; }
.qui-ocr__cf--lo { color: var(--warn-ink); border-color: var(--warn); }
.qui-ocr__caption { font-size: var(--text-caption); color: var(--muted); margin-top: var(--space-4); line-height: var(--leading-prose); }

/* ── §3.4 EvidenceTrace ── */
.qui-ev { width: 100%; }
.qui-ev__answer { border: 1px solid var(--hair); border-radius: var(--radius-sm); background: var(--surface-2); padding: 13px 14px; font-size: var(--text-body); line-height: var(--leading-prose); color: var(--muted); }
.qui-ev__cm { display: inline-flex; align-items: center; justify-content: center; min-width: 15px; height: 15px; padding: 0 3px; margin: 0 1px; border-radius: 3px; font-family: var(--font-mono); font-size: 9px; font-weight: var(--weight-medium); background: var(--accent-soft); color: var(--accent-ink); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); cursor: pointer; vertical-align: 2px; transition: background var(--dur-hover, .1s) var(--ease-state, ease); }
.qui-ev__cm:hover, .qui-ev__cm--on { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }
.qui-ev__trace { display: flex; flex-direction: column; gap: 9px; margin-top: 12px; }
.qui-ev__row { display: grid; grid-template-columns: 30px 1fr; align-items: stretch; gap: 0; cursor: pointer; }
.qui-ev__conn { position: relative; }
.qui-ev__conn-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.qui-ev__pass { border: 1px solid var(--hair); border-radius: var(--radius-sm); background: var(--surface); padding: 9px 11px; min-width: 0; transition: border-color var(--dur-hover, .12s) var(--ease-state, ease), background var(--dur-hover, .12s) var(--ease-state, ease); }
.qui-ev__row:hover .qui-ev__pass, .qui-ev__row--on .qui-ev__pass { border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: var(--surface-2); }
.qui-ev__ph { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; margin-bottom: 4px; }
.qui-ev__pn { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 3px; font-family: var(--font-mono); font-size: 9px; background: var(--accent-soft); color: var(--accent-ink); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); flex: none; }
.qui-ev__pd { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); }
.qui-ev__pq { font-size: 11.5px; color: var(--ink); font-style: italic; }
.qui-ev__pq--empty { color: var(--muted); font-style: normal; font-family: var(--font-mono); } /* --muted, not --off: honest-null indicator must clear AA (0.6.1 a11y) */

/* ── §3.4 SourceDrawer (content only — shell + tabs now use the §1.1
 *    generic Drawer/Tabs primitives; bespoke scrim/trap/tablist removed). ── */
.qui-drawer__cite { padding: 11px 14px; border-bottom: 1px solid var(--hair); display: flex; flex-direction: column; gap: 7px; margin: -13px -14px 13px; }
.qui-drawer__claim { font-size: var(--text-body-sm); color: var(--ink); line-height: 1.5; }
.qui-drawer__chips { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }
.qui-drawer__src { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); }
.qui-drawer__hempty { font-family: var(--font-mono); font-size: 11px; color: var(--muted); padding: 4px 0; }
.qui-drawer__doc { border: 1px solid var(--hair); border-radius: var(--radius-xs); background: var(--surface-2); padding: 12px; font-size: 11.5px; line-height: 1.7; color: var(--muted); }
.qui-drawer__doc mark { background: var(--accent-soft); color: var(--ink); border-bottom: 1.5px solid var(--accent); padding: 0 2px; border-radius: 1px; }
.qui-drawer__orig { font-family: var(--font-mono); font-size: 11px; line-height: 1.7; color: var(--muted); white-space: pre-wrap; border: 1px solid var(--hair); border-radius: var(--radius-xs); background: var(--surface-2); padding: 12px; }
.qui-drawer__hist { display: flex; flex-direction: column; gap: 0; }
.qui-drawer__he { display: grid; grid-template-columns: 122px 1fr; gap: var(--space-5); padding: 8px 0; border-bottom: 1px solid var(--hair); font-size: 11.5px; }
.qui-drawer__he:last-child { border-bottom: 0; }
.qui-drawer__ht { font-family: var(--font-mono); font-size: 10px; color: var(--muted); }
.qui-drawer__hd { color: var(--muted); }

/* ════════════════════════════════════════════════════════════════════════
   §1.1 primitives — form controls + overlays/nav (ported from CD §1.1)
   Tokens-only. Both themes via the canonical token layer. No fixed colors
   except the inverse tooltip/danger contrast handled through tokens.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Button ── */
.qui-btn {
  font-family: var(--font-body); font-weight: var(--weight-medium);
  font-size: var(--text-body); line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 15px; border-radius: var(--radius-md);
  border: 1px solid var(--hair); background: var(--surface-2); color: var(--ink);
  cursor: pointer; transition: background var(--dur-press) var(--ease-state), border-color var(--dur-press) var(--ease-state);
  white-space: nowrap;
}
.qui-btn:hover { background: var(--surface-3); }
.qui-btn:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.qui-btn--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }
.qui-btn--primary:hover { background: var(--accent); filter: brightness(1.06); }
.qui-btn--ghost { background: transparent; border-color: var(--hair); }
.qui-btn--ghost:hover { background: var(--surface-2); }
.qui-btn--danger { background: var(--bad-strong, #DC2626); border-color: var(--bad-strong, #DC2626); color: #fff; } /* --bad-strong #DC2626: white clears AA 4.83 (--bad #EF4444 was 3.76). Literal fallback so an app's own token layer that predates --bad-strong still gets a valid AA fill (0.6.1 a11y) */
.qui-btn--danger:hover { background: var(--bad-strong, #DC2626); filter: brightness(0.92); } /* darken on hover (#ca2323, white 5.56) — brightness(1.06) lightened it to ~4.38 and failed AA */
.qui-btn--link { background: transparent; border-color: transparent; color: var(--accent-ink); padding-left: 4px; padding-right: 4px; }
.qui-btn--link:hover { text-decoration: underline; background: transparent; }
.qui-btn--sm { padding: 6px 11px; font-size: var(--text-body-sm); }
.qui-btn--lg { padding: 12px 20px; font-size: var(--text-body-lg); }
.qui-btn--icon { padding: 9px; width: 36px; }
.qui-btn:disabled, .qui-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.qui-btn__icon { display: inline-flex; align-items: center; }
.qui-btn__spin {
  width: 13px; height: 13px; border-radius: var(--radius-round);
  border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
  border-top-color: currentColor; animation: qui-btn-spin .7s linear infinite;
}
@keyframes qui-btn-spin { to { transform: rotate(360deg); } }

/* ── SegmentedControl ── */
.qui-seg { display: inline-flex; border: 1px solid var(--hair); border-radius: var(--radius-md); overflow: hidden; background: var(--surface); }
.qui-seg__btn {
  font-family: var(--font-mono); font-size: var(--text-caption); padding: 6px 13px;
  border: 0; background: transparent; color: var(--subtle); cursor: pointer;
  transition: color var(--dur-press) var(--ease-state); white-space: nowrap;
}
.qui-seg__btn:hover { color: var(--ink); }
.qui-seg__btn--on { background: var(--accent-soft); color: var(--accent-ink); }
.qui-seg__btn:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; }
.qui-seg__btn:disabled { opacity: .45; cursor: not-allowed; }

/* ── Switch ── */
.qui-switch {
  width: 36px; height: 20px; border-radius: var(--radius-pill);
  background: var(--surface-3); border: 1px solid var(--hair); position: relative;
  display: inline-block; cursor: pointer; flex: none;
  transition: background var(--dur-hover) var(--ease-state), border-color var(--dur-hover) var(--ease-state);
  vertical-align: middle; padding: 0;
}
.qui-switch--on { background: var(--accent); border-color: var(--accent); }
.qui-switch__thumb {
  content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px;
  border-radius: var(--radius-round); background: #fff; transition: left var(--dur-hover) var(--ease-state);
}
.qui-switch--on .qui-switch__thumb { left: 18px; }
.qui-switch--disabled { opacity: .45; cursor: not-allowed; }
.qui-switch:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }

/* ── Input / Textarea / Select ── */
.qui-input {
  font-family: var(--font-body); font-size: var(--text-body); background: var(--bg);
  border: 1px solid var(--hair); border-radius: var(--radius-md); color: var(--ink);
  padding: 8px 11px; width: 100%;
  transition: border-color var(--dur-press) var(--ease-state), box-shadow var(--dur-press) var(--ease-state);
}
.qui-input::placeholder { color: var(--subtle); opacity: .8; }
.qui-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.qui-input--err { border-color: var(--bad); box-shadow: none; }
.qui-input--err:focus { box-shadow: 0 0 0 2px color-mix(in srgb, var(--bad) 22%, transparent); }
.qui-input:disabled { opacity: .5; cursor: not-allowed; background: var(--surface-2); }
.qui-input[readonly] { background: var(--surface-2); color: var(--muted); }
.qui-textarea { resize: vertical; min-height: 64px; line-height: 1.5; }
.qui-select {
  font-family: var(--font-body); font-size: var(--text-body); background-color: var(--bg);
  border: 1px solid var(--hair); border-radius: var(--radius-md); color: var(--ink);
  padding: 8px 30px 8px 11px; cursor: pointer; width: 100%;
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--subtle) 50%), linear-gradient(135deg, var(--subtle) 50%, transparent 50%);
  background-position: calc(100% - 15px) 53%, calc(100% - 10px) 53%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
  transition: border-color var(--dur-press) var(--ease-state), box-shadow var(--dur-press) var(--ease-state);
}
.qui-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.qui-select:disabled { opacity: .5; cursor: not-allowed; background-color: var(--surface-2); }

/* ── badge (shared by MultiSelect + ChipEntry) ── */
.qui-badge {
  display: inline-flex; align-items: center; gap: 5px; background: var(--surface-2);
  border: 1px solid var(--hair); border-radius: var(--radius-sm);
  padding: 2px 4px 2px 8px; font-size: var(--text-caption); color: var(--ink);
}
.qui-badge__x {
  position: relative; width: 15px; height: 15px; border-radius: var(--radius-xs); display: inline-flex;
  align-items: center; justify-content: center; cursor: pointer; color: var(--subtle); font-size: 12px;
}
/* WCAG 2.5.8: ≥24×24px hit area, transparent, without enlarging the visual glyph. */
.qui-badge__x::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  min-width: 24px; min-height: 24px;
}
.qui-badge__x:hover { background: var(--surface-3); color: var(--bad); }

/* ── MultiSelect ── */
.qui-multi {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 38px;
  background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-md); /* --surface (was --bg): a field should read as a distinct surface; also resolves axe bg-detection on the placeholder/clear (0.6.1 a11y) */
  padding: 5px 8px; cursor: pointer; width: 100%;
}
.qui-multi:focus-visible, .qui-multi:focus-within { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
/* the trigger is a <button>: reset UA chrome so text sits on the field --surface,
   not the UA default button background (a dark gray under color-scheme:dark that
   failed contrast against --muted) (0.6.1 a11y) */
.qui-multi__trigger { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; background: transparent; border: none; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.qui-multi__trigger:focus-visible { outline: none; }
.qui-multi--disabled { opacity: .5; cursor: not-allowed; background: var(--surface-2); }
.qui-multi__placeholder { color: var(--muted); font-size: var(--text-body); }
.qui-multi__overflow { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); padding: 0 4px; }
.qui-multi__clear { position: relative; margin-left: auto; background: transparent; border: none; color: var(--muted); cursor: pointer; font-size: var(--text-body); padding: 0 4px; }
/* WCAG 2.5.8: ≥24×24px transparent hit area. */
.qui-multi__clear::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  min-width: 24px; min-height: 24px;
}
.qui-multi__clear:hover { color: var(--bad); }
.qui-multi__list { display: flex; flex-direction: column; min-width: 180px; }
.qui-multi__opt {
  text-align: left; padding: 7px 10px; border: 0; background: transparent;
  font-family: var(--font-body); font-size: var(--text-body-sm); color: var(--ink);
  border-radius: var(--radius-sm); cursor: pointer;
}
.qui-multi__opt:hover { background: var(--surface-2); }
.qui-multi__opt:disabled { opacity: .45; cursor: not-allowed; }
.qui-multi__empty { padding: 7px 10px; color: var(--subtle); font-size: var(--text-body-sm); }

/* ── ChipEntry ── */
.qui-chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; background: var(--bg);
  border: 1px solid var(--hair); border-radius: var(--radius-md); padding: 6px 8px; width: 100%;
}
.qui-chips:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.qui-chips--disabled { opacity: .7; } /* .5 dropped badge text below AA; .7 keeps a disabled look while legible (0.6.1 a11y) */
.qui-chips__input { border: 0; background: transparent; color: var(--ink); font-size: var(--text-body-sm); flex: 1; min-width: 90px; outline: none; font-family: var(--font-body); }
.qui-chips__input::placeholder { color: var(--subtle); }

/* ── DateRange ── */
.qui-daterange {
  display: flex; align-items: center; gap: 8px; font-family: var(--font-body);
  font-size: var(--text-body); background: var(--bg); border: 1px solid var(--hair);
  border-radius: var(--radius-md); color: var(--ink); padding: 8px 11px; width: 100%;
  cursor: pointer; text-align: left;
}
.qui-daterange:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.qui-daterange--disabled { opacity: .5; cursor: not-allowed; background: var(--surface-2); }
.qui-daterange__summary { font-family: var(--font-mono); font-size: var(--text-body-sm); }
.qui-daterange__caret { margin-left: auto; color: var(--subtle); font-size: var(--text-micro); font-family: var(--font-mono); }
.qui-daterange__panel { display: flex; flex-direction: column; gap: 11px; min-width: 220px; }
.qui-daterange__inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.qui-daterange__field { display: flex; flex-direction: column; gap: 4px; }
.qui-daterange__flabel { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: .1em; color: var(--muted); }
.qui-daterange__presets { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--hair); padding-top: 7px; }
.qui-daterange__preset { text-align: left; padding: 6px 8px; border: 0; background: transparent; color: var(--ink); font-size: var(--text-body-sm); border-radius: var(--radius-sm); cursor: pointer; }
.qui-daterange__preset:hover { background: var(--surface-2); color: var(--accent-ink); }

/* ── FormField ── */
.qui-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.qui-field__label { font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); display: flex; gap: 6px; align-items: center; }
.qui-field__req { color: var(--bad); }
.qui-field__hint { font-size: var(--text-micro); color: var(--subtle); }
.qui-field__err { font-size: var(--text-micro); color: var(--bad-ink); } /* --bad-ink: red text clears AA on surface (--bad was 3.60 light) (0.6.1 a11y) */

/* ── FileUpload ── */
.qui-upload { display: flex; flex-direction: column; gap: 10px; }
.qui-upload__drop { border: 1.5px dashed var(--hair); border-radius: var(--radius-md); background: var(--bg); padding: 18px; text-align: center; color: var(--subtle); cursor: pointer; transition: border-color var(--dur-press) var(--ease-state), color var(--dur-press) var(--ease-state); position: relative; }
.qui-upload__drop:hover, .qui-upload__drop--over { border-color: var(--accent); color: var(--accent-ink); }
.qui-upload__drop:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.qui-upload__drop--disabled { opacity: .5; cursor: not-allowed; }
.qui-upload__glyph { font-size: 20px; margin-bottom: 6px; color: var(--subtle); }
.qui-upload__prompt { font-size: var(--text-body-sm); }
.qui-upload__hint { font-family: var(--font-mono); font-size: var(--text-micro); margin-top: 3px; }
.qui-upload__input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.qui-upload__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.qui-upload__file { display: flex; align-items: center; gap: 10px; padding: 8px 11px; border: 1px solid var(--hair); border-radius: var(--radius-md); background: var(--surface); }
.qui-upload__file--error { border-color: var(--bad); }
.qui-upload__ic { width: 26px; height: 26px; border-radius: var(--radius-sm); background: var(--accent-soft); border: 1px solid var(--accent-ink); flex: none; display: flex; align-items: center; justify-content: center; color: var(--accent-ink); font-size: var(--text-caption); font-family: var(--font-mono); }
.qui-upload__file--error .qui-upload__ic { background: var(--bad-soft); border-color: var(--bad); color: var(--bad-ink); }
.qui-upload__meta { flex: 1; min-width: 0; }
.qui-upload__name { font-size: var(--text-body-sm); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qui-upload__sub { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); }
.qui-upload__file--error .qui-upload__sub { color: var(--bad-ink); }
.qui-upload__prog { height: 5px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; margin-top: 5px; }
.qui-upload__prog > i { display: block; height: 100%; background: var(--accent); transition: width var(--dur-lift) var(--ease-state); }
.qui-upload__status { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); flex: none; }
.qui-upload__x { position: relative; border: 0; background: transparent; color: var(--subtle); cursor: pointer; font-size: 14px; line-height: 1; padding: 2px 4px; border-radius: var(--radius-xs); }
/* WCAG 2.5.8: ≥24×24px transparent hit area. */
.qui-upload__x::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  min-width: 24px; min-height: 24px;
}
.qui-upload__x:hover { color: var(--bad); background: var(--surface-2); }

/* ── Modal (Radix Dialog) ── */
.qui-scrim { position: fixed; inset: 0; background: var(--scrim); z-index: var(--z-scrim); }
.qui-modal {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-lg);
  box-shadow: var(--lift-shadow); max-width: calc(100vw - 32px); max-height: calc(100vh - 32px);
  overflow: hidden; z-index: calc(var(--z-scrim) + 1); display: flex; flex-direction: column;
}
.qui-modal:focus-visible { outline: none; }
.qui-modal__title { padding: 13px 15px; border-bottom: 1px solid var(--hair); font-family: var(--font-display); font-weight: var(--weight-medium); font-size: var(--text-title); color: var(--ink); margin: 0; }
.qui-modal__body { padding: 15px; color: var(--muted); font-size: var(--text-body-sm); overflow: auto; }
.qui-modal__footer { padding: 12px 15px; border-top: 1px solid var(--hair); display: flex; justify-content: flex-end; gap: 8px; }
.qui-modal--danger .qui-modal__title { color: var(--ink); }

/* ── Drawer (generic, Radix Dialog) — qui-drawer2 to avoid clash with the
      domain SourceDrawer's qui-drawer* namespace ── */
.qui-drawer2 {
  position: fixed; top: 0; bottom: 0; background: var(--surface);
  box-shadow: var(--lift-shadow); z-index: calc(var(--z-scrim) + 1);
  display: flex; flex-direction: column; max-width: 100vw;
}
.qui-drawer2:focus-visible { outline: none; }
.qui-drawer2--right { right: 0; border-left: 1px solid var(--hair); }
.qui-drawer2--left { left: 0; border-right: 1px solid var(--hair); }
.qui-drawer2__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 13px 14px 11px; border-bottom: 1px solid var(--hair); flex: none; }
.qui-drawer2__title { font-family: var(--font-display); font-weight: var(--weight-medium); font-size: var(--text-title); color: var(--ink); margin: 0; }
.qui-drawer2__sub { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); margin-top: 3px; }
.qui-drawer2__x { width: 26px; height: 26px; border: 1px solid var(--hair); background: var(--surface-3); color: var(--muted); border-radius: var(--radius-xs); cursor: pointer; font-size: 14px; line-height: 1; flex: none; }
.qui-drawer2__x:hover { background: var(--surface-2); color: var(--ink); }
.qui-drawer2__body { flex: 1; overflow: auto; padding: 13px 14px; }
.qui-drawer2__footer { padding: 12px 14px; border-top: 1px solid var(--hair); display: flex; justify-content: flex-end; gap: 8px; flex: none; }

/* ── Banner ── */
.qui-banner { display: flex; gap: 10px; align-items: flex-start; padding: 10px 13px; border: 1px solid var(--hair); border-radius: var(--radius-md); background: var(--surface); }
.qui-banner__ic { width: 20px; height: 20px; border-radius: var(--radius-sm); flex: none; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: var(--weight-semibold); }
.qui-banner--warn .qui-banner__ic { background: var(--warn-soft); color: var(--warn-ink); }
.qui-banner--bad .qui-banner__ic { background: var(--bad-soft); color: var(--bad-ink); }
.qui-banner--ok .qui-banner__ic { background: var(--ok-soft); color: var(--ok-ink); }
.qui-banner--info .qui-banner__ic { background: var(--setup-soft); color: var(--setup); }
.qui-banner__content { flex: 1; min-width: 0; }
.qui-banner__title { font-size: var(--text-body-sm); color: var(--ink); font-weight: var(--weight-medium); }
.qui-banner__body { font-size: var(--text-caption); color: var(--muted); margin-top: 2px; }
.qui-banner__actions { display: flex; gap: 6px; align-items: center; flex: none; }
.qui-banner__x { position: relative; border: 0; background: transparent; color: var(--subtle); cursor: pointer; font-size: 15px; line-height: 1; padding: 0 2px; flex: none; }
/* WCAG 2.5.8: ≥24×24px transparent hit area. */
.qui-banner__x::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  min-width: 24px; min-height: 24px;
}
.qui-banner__x:hover { color: var(--ink); }

/* ── Breadcrumb ── */
.qui-breadcrumb { font-family: var(--font-mono); font-size: var(--text-caption); }
.qui-breadcrumb__list { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; color: var(--subtle); }
.qui-breadcrumb__item { display: inline-flex; gap: 7px; align-items: center; }
.qui-breadcrumb__current { color: var(--ink); font-weight: var(--weight-medium); }
.qui-breadcrumb__crumb { color: var(--subtle); }
.qui-breadcrumb__link { color: var(--subtle); text-decoration: none; background: transparent; border: 0; font: inherit; cursor: pointer; padding: 0; }
.qui-breadcrumb__link:hover { color: var(--accent-ink); text-decoration: underline; }
.qui-breadcrumb__sep { opacity: .5; }

/* ── Tabs ── */
.qui-tabs__strip { display: flex; gap: 2px; border-bottom: 1px solid var(--hair); }
.qui-tabs__tab { padding: 8px 13px; font-size: var(--text-body-sm); font-family: var(--font-body); color: var(--subtle); cursor: pointer; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; background: transparent; }
.qui-tabs__tab:hover { color: var(--ink); }
.qui-tabs__tab--on { color: var(--accent-ink); border-bottom-color: var(--accent); }
.qui-tabs__tab:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; border-radius: var(--radius-xs); }
.qui-tabs__tab:disabled { opacity: .45; cursor: not-allowed; }
.qui-tabs__panel { padding: 11px 2px; font-size: var(--text-body-sm); color: var(--muted); }
.qui-tabs__panel:focus-visible { outline: none; }

/* ── Accordion ── */
.qui-accordion { border: 1px solid var(--hair); border-radius: var(--radius-md); overflow: hidden; }
.qui-accordion__item + .qui-accordion__item { border-top: 1px solid var(--hair); }
.qui-accordion__heading { margin: 0; }
.qui-accordion__header { width: 100%; padding: 10px 13px; display: flex; justify-content: space-between; align-items: center; cursor: pointer; font-size: var(--text-body-sm); background: var(--surface); border: 0; color: var(--ink); text-align: left; font-family: var(--font-body); }
.qui-accordion__header:hover { background: var(--surface-2); }
.qui-accordion__header:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; }
.qui-accordion__header:disabled { opacity: .45; cursor: not-allowed; }
.qui-accordion__chevron { font-family: var(--font-mono); color: var(--subtle); font-size: var(--text-caption); }
.qui-accordion__region { padding: 11px 13px; border-top: 1px solid var(--hair); font-size: var(--text-body-sm); color: var(--muted); background: var(--bg); }

/* ── Tooltip ── */
.qui-tooltip { position: relative; display: inline-block; }
.qui-tooltip__bubble {
  position: absolute; background: var(--ink); color: var(--bg); font-size: var(--text-caption);
  font-family: var(--font-body); padding: 5px 9px; border-radius: var(--radius-sm);
  white-space: nowrap; opacity: 0; pointer-events: none;
  transition: opacity var(--dur-press) var(--ease-state); z-index: var(--z-popover);
}
.qui-tooltip__bubble--open { opacity: 1; }
.qui-tooltip__bubble--top { bottom: 130%; left: 50%; transform: translateX(-50%); }
.qui-tooltip__bubble--bottom { top: 130%; left: 50%; transform: translateX(-50%); }
.qui-tooltip__bubble--left { right: 115%; top: 50%; transform: translateY(-50%); }
.qui-tooltip__bubble--right { left: 115%; top: 50%; transform: translateY(-50%); }

/* reduced-motion: kill the §1.1 transitions/animations */
@media (prefers-reduced-motion: reduce) {
  .qui-btn, .qui-switch, .qui-switch__thumb, .qui-input, .qui-select, .qui-upload__prog > i,
  .qui-tooltip__bubble, .qui-seg__btn, .qui-upload__drop { transition: none; }
  .qui-btn__spin { animation: none; }
}

/* ===============================================================
   §1.2–1.7 — CD commissioning-wizard governed editors.
   Ported from `Quoriam CD - Inputs & Wizard.dc.html`. Tokens-only,
   both themes, append-only for clean merge. Governed/closed-list
   editors: select & parameterize, never a no-code builder.
   =============================================================== */

/* ── §1.2 HierarchyTree ── */
.qui-tr-tree { border: 1px solid var(--hair); border-radius: var(--radius-lg); background: var(--bg); overflow: hidden; font-family: var(--font-body); }
.qui-tr-row { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--hair); cursor: pointer; }
.qui-tr-row:last-child { border-bottom: 0; }
.qui-tr-row:hover { background: var(--surface-2); }
.qui-tr-row--sel { background: var(--accent-soft); }
.qui-tr-row:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; }
.qui-tr-tw { width: 14px; height: 14px; padding: 0; border: 0; background: none; color: var(--subtle); font-size: 8px; line-height: 1; flex: none; cursor: pointer; transition: transform var(--dur-hover) var(--ease-state); display: inline-flex; align-items: center; justify-content: center; }
.qui-tr-tw--open { transform: rotate(90deg); }
.qui-tr-tw--leaf { opacity: 0; pointer-events: none; }
.qui-tr-tw:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; border-radius: var(--radius-xs); }
.qui-tr-type { font-family: var(--font-mono); font-size: 8px; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--subtle); border: 1px solid var(--hair); border-radius: var(--radius-sm); padding: 1px 5px; flex: none; }
.qui-tr-name { font-size: var(--text-body); color: var(--ink); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qui-tr-meta { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); flex: none; }
.qui-tr-root { font-family: var(--font-mono); font-size: 8px; text-transform: uppercase; letter-spacing: var(--tracking-label); padding: 1px 5px; border-radius: var(--radius-sm); background: var(--accent-soft); color: var(--accent-ink); border: 1px solid var(--accent-ink); flex: none; }

/* ── §1.3 MeterMapper ── */
.qui-mm { font-family: var(--font-body); }
.qui-mm-row { display: grid; grid-template-columns: 1fr auto; gap: var(--space-5); align-items: flex-start; padding: var(--space-5) 0; border-bottom: 1px solid var(--hair); }
.qui-mm-row:last-child { border-bottom: 0; }
.qui-mm-col { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.qui-mm-meter { display: flex; align-items: center; gap: var(--space-4); }
.qui-mm-ic { width: 30px; height: 30px; border-radius: var(--radius-md); background: var(--accent-soft); border: 1px solid var(--accent-ink); display: flex; align-items: center; justify-content: center; flex: none; color: var(--accent-ink); font-family: var(--font-mono); font-size: 9px; }
.qui-mm-name { font-size: var(--text-body); font-weight: var(--weight-medium); color: var(--ink); }
.qui-mm-sub { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); }
.qui-mm-ch { display: grid; grid-template-columns: 1fr 14px 1fr 88px; gap: var(--space-4); align-items: center; padding: var(--space-3) 0; }
.qui-mm-chid { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted); }
.qui-mm-arrow { text-align: center; color: var(--subtle); font-family: var(--font-mono); }
.qui-mm-select { width: 100%; min-width: 0; font-family: var(--font-body); font-size: var(--text-caption); color: var(--ink); background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-md); padding: var(--space-2) var(--space-4); }
.qui-mm-select:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.qui-mm-unit { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted); text-align: right; }
.qui-mm-side { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-end; }

/* ── §1.4 TariffEditor ── */
.qui-tf { display: flex; flex-direction: column; gap: var(--space-5); font-family: var(--font-body); }
.qui-tf-bar { display: flex; flex-wrap: wrap; gap: var(--space-5); align-items: flex-end; }
.qui-tf-field { display: flex; flex-direction: column; gap: var(--space-2); }
.qui-tf-bar .qui-tf-field:nth-of-type(1) { margin-left: auto; }
.qui-tf-flabel { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--subtle); }
.qui-tf-input, .qui-tf-select { font-family: var(--font-body); font-size: var(--text-caption); color: var(--ink); background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-md); padding: var(--space-2) var(--space-4); }
.qui-tf-input--mono { font-family: var(--font-mono); }
.qui-tf-input:focus-visible, .qui-tf-select:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.qui-tf-flat { display: flex; align-items: flex-end; gap: var(--space-5); }
.qui-tf-rate { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--ink); text-align: right; }
.qui-tf-rate--lg { font-size: var(--text-body-lg); }
/* editable rate field: inherits the mono/right-aligned reading style, gains a
   control affordance. Empty (unset) value shows the em-dash placeholder. */
.qui-tf-rate--input { width: 90px; background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-md); padding: var(--space-2) var(--space-4); }
.qui-tf-rate--input.qui-tf-rate--lg { width: 120px; }
.qui-tf-rate--input::placeholder { color: var(--subtle); }
.qui-tf-rate--input:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.qui-tf-perunit { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--subtle); padding-bottom: var(--space-2); }
.qui-tf-tbl { display: flex; flex-direction: column; border: 1px solid var(--hair); border-radius: var(--radius-lg); overflow: hidden; }
.qui-tf-row { display: grid; gap: var(--space-4); align-items: center; padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--hair); font-size: var(--text-caption); color: var(--ink); }
.qui-tf-row:last-child { border-bottom: 0; }
.qui-tf-row--tier { grid-template-columns: 1fr 100px 90px; }
.qui-tf-row--band { grid-template-columns: 14px 1fr 110px 90px; }
.qui-tf-row--head { background: var(--surface-2); font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--muted); } /* --muted clears AA on surface-2 (dark --subtle was 4.29) (0.6.1 a11y) */
.qui-tf-mono { font-family: var(--font-mono); }
.qui-tf-dim { font-family: var(--font-mono); color: var(--subtle); }
.qui-tf-window { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); }
.qui-tf-sw { width: 10px; height: 10px; border-radius: var(--radius-xs); flex: none; }
.qui-tf-sw--default { background: var(--surface-3); }
.qui-tou { display: flex; height: 26px; border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--hair); }
.qui-tou__seg { height: 100%; }
.qui-tou__hours { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); margin: var(--space-2) 0 var(--space-4); }
.qui-tf-banner { display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-4) var(--space-5); border-radius: var(--radius-md); font-size: var(--text-caption); color: var(--ink); }
.qui-tf-banner--warn { background: var(--warn-soft); border: 1px solid var(--warn); }
.qui-tf-banner__ic { font-family: var(--font-mono); font-weight: var(--weight-semibold); color: var(--warn-ink); flex: none; }

/* ── §1.5 RuleEditor ── */
.qui-rule { font-family: var(--font-body); }
.qui-rule-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.qui-rule-field { display: flex; flex-direction: column; gap: var(--space-2); }
.qui-rule-flabel { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--subtle); }
.qui-rule-select, .qui-rule-input { font-family: var(--font-body); font-size: var(--text-caption); color: var(--ink); background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-md); padding: var(--space-2) var(--space-4); }
.qui-rule-input--mono { font-family: var(--font-mono); }
.qui-rule-select:focus-visible, .qui-rule-input:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.qui-rule-pair { display: flex; gap: var(--space-3); }
.qui-rule-pair .qui-rule-input { width: 80px; }
.qui-rule-select--narrow { width: 120px; }
/* Read-only DERIVED threshold unit (canonical metric unit, or "%" for relative).
   Not an input — the unit is governed, never user-entered. */
.qui-rule-unit { display: inline-flex; align-items: center; min-width: 40px; font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted); }
.qui-rule-note { grid-column: 1 / 3; font-size: var(--text-caption); color: var(--muted); line-height: var(--leading-prose); display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }

/* ── §1.6 CapabilityPicker ── */
.qui-cap { font-family: var(--font-body); }
.qui-cap-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(184px, 1fr)); gap: var(--space-5); }
.qui-cap-card { text-align: left; border: 1px solid var(--hair); border-radius: var(--radius-lg); padding: var(--space-5); background: var(--surface); cursor: pointer; display: flex; flex-direction: column; gap: var(--space-3); transition: border-color var(--dur-hover) var(--ease-state), background var(--dur-hover) var(--ease-state); font-family: var(--font-body); }
.qui-cap-card:hover { border-color: var(--subtle); }
.qui-cap-card:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.qui-cap-card--on { border-color: var(--accent); background: var(--accent-soft); }
.qui-cap-card--reserved { cursor: default; }
.qui-cap-card--reserved:hover { border-color: var(--hair); }
.qui-cap-card--reserved.qui-cap-card--on { border-color: var(--accent); }
.qui-cap-card__top { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
.qui-cap-card__name { font-size: var(--text-body); font-weight: var(--weight-medium); color: var(--ink); }
.qui-cap-card__desc { font-size: var(--text-caption); color: var(--muted); line-height: var(--leading-ui); } /* --muted clears AA (0.6.1 a11y) */
.qui-cap-card__resv { font-family: var(--font-mono); font-size: 7.5px; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--maint-ink, #4f3b8f); border: 1px solid var(--maint); background: var(--maint-soft); border-radius: var(--radius-sm); padding: 1px 5px; margin-left: auto; }
.qui-cap-card__sw { width: 26px; height: 14px; border-radius: var(--radius-pill); background: var(--surface-3); border: 1px solid var(--hair); position: relative; flex: none; transition: background var(--dur-hover) var(--ease-state); }
.qui-cap-card__sw::after { content: ""; position: absolute; top: 1px; left: 1px; width: 10px; height: 10px; border-radius: var(--radius-round); background: var(--subtle); transition: transform var(--dur-hover) var(--ease-state); }
.qui-cap-card--on .qui-cap-card__sw { background: var(--accent); border-color: var(--accent); }
.qui-cap-card--on .qui-cap-card__sw::after { transform: translateX(12px); background: var(--accent-contrast); }
.qui-cap-note { margin-top: var(--space-5); font-size: var(--text-caption); color: var(--muted); } /* --muted clears AA (0.6.1 a11y) */

/* ── §1.7 AllocationEditor ── */
.qui-al { display: flex; flex-direction: column; gap: var(--space-5); font-family: var(--font-body); }
.qui-al-bar-row { display: flex; align-items: center; gap: var(--space-4); }
.qui-al-glab { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--subtle); }
.qui-al-parent { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); margin-left: auto; }
.qui-al-stack { display: flex; height: 28px; border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--hair); background: var(--surface-2); }
.qui-al-seg { height: 100%; border-right: 1px solid var(--bg); }
.qui-al-seg:last-child { border-right: 0; }
.qui-al-tbl { display: flex; flex-direction: column; }
.qui-al-row { display: grid; grid-template-columns: 1fr 120px 56px; gap: var(--space-5); align-items: center; padding: var(--space-3) 0; border-bottom: 1px solid var(--hair); }
.qui-al-row:last-child { border-bottom: 0; }
.qui-al-row--head { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--subtle); }
.qui-al-end { text-align: right; }
.qui-al-name { font-size: var(--text-caption); color: var(--ink); }
.qui-al-sub { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--subtle); margin-left: var(--space-3); }
.qui-al-ctrl { min-width: 0; }
.qui-al-input { width: 100%; font-family: var(--font-body); font-size: var(--text-caption); color: var(--ink); background: var(--surface); border: 1px solid var(--hair); border-radius: var(--radius-md); padding: var(--space-2) var(--space-4); }
.qui-al-input--mono { font-family: var(--font-mono); }
.qui-al-input:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.qui-al-mono { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted); }
.qui-al-track { display: block; height: 7px; background: var(--surface-3); border-radius: var(--radius-pill); overflow: hidden; }
.qui-al-track > i { display: block; height: 100%; background: var(--accent); border-radius: var(--radius-pill); }
.qui-al-share { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--ink); text-align: right; }
.qui-al-banner { display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-4) var(--space-5); border-radius: var(--radius-md); font-size: var(--text-caption); color: var(--ink); }
.qui-al-banner--bad { background: var(--bad-soft); border: 1px solid var(--bad); }
.qui-al-banner__ic { font-family: var(--font-mono); font-weight: var(--weight-semibold); color: var(--bad-ink); flex: none; }
.qui-al-hb { display: grid; grid-template-columns: 130px 1fr 44px; gap: var(--space-4); align-items: center; }
.qui-al-hb__l { font-size: var(--text-caption); color: var(--muted); }
.qui-al-hb__t { height: 13px; background: var(--surface-3); border-radius: var(--radius-sm); overflow: hidden; }
.qui-al-hb__f { display: block; height: 100%; background: var(--accent); border-radius: var(--radius-sm); }
.qui-al-hb__v { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted); text-align: right; }
.qui-al-note { font-size: var(--text-caption); color: var(--subtle); }

/* ===================================================================
   RESPONSIVENESS PASS (P2.0) — fill-the-container + reflow at every
   width, both themes. Tactics-first: min-width:0 to unlock flex/grid
   shrink, flex-wrap, fluid widths, and intentional horizontal scroll
   for inherently-wide surfaces (boards/timelines/tables). No fixed
   px layout widths survive below their breakpoint. Tokens only.
   Driven green by e2e/responsive.spec.ts (375 / 768 / 1440, dark+light).
   =================================================================== */

/* ── KpiCard — flex children must shrink; long values/units wrap ──
   Without min-width:0 the mono value + skeleton ghost children keep
   their min-content width and burst the card on narrow widths. */
.qui-kpi { min-width: 0; }
.qui-kpi__top { min-width: 0; }
.qui-kpi__label { min-width: 0; overflow-wrap: anywhere; }
.qui-kpi__value { min-width: 0; overflow-wrap: anywhere; }
.qui-kpi__spark { min-width: 0; }

/* ── DataTable — the panel/wrap must not be widened by the wide table.
   qui-table-wrap already scrolls (overflow-x:auto); the fix is to stop
   the table's min-content from inflating its block ancestors. ── */
.qui-panel { min-width: 0; }
.qui-panel__head { min-width: 0; }
.qui-table-wrap { max-width: 100%; min-width: 0; }
/* a width:100% table inside a scroll-wrap still reports min-content as
   the wrap's scrollWidth; cap the wrap so it owns the scroll, and let
   the table take its natural (scrollable) width inside it. */
.qui-table { min-width: max-content; }

/* ── HeatStrip — fill the container; cells share the row fluidly.
   Was inline-flex (sized to content → overflowed). Now block flex at
   100% width; cells flex evenly with a small min so 24 cells fit a
   phone, and the row scrolls only if it truly cannot (last resort). ── */
.qui-heat { display: flex; width: 100%; min-width: 0; }
.qui-heat__cells { width: 100%; min-width: 0; overflow-x: auto; }
.qui-heat__cell { min-width: 6px; }
.qui-heat__axis { width: 100%; min-width: 0; }
.qui-heat__tick { min-width: 6px; overflow: hidden; }

/* ── Donut — ring + legend reflow to a column on narrow widths.
   The 132px-min legend beside a fixed ring overflowed < ~470px. ── */
.qui-donut { flex-wrap: wrap; min-width: 0; }
.qui-donut__legend { min-width: 0; flex: 1 1 132px; }
.qui-donut__leglabel { overflow-wrap: anywhere; }

/* ── InsightCard — header (kicker + provenance) wraps instead of
   pushing the nowrap provenance chip past the edge. ── */
.qui-insight { min-width: 0; }
.qui-insight__top { flex-wrap: wrap; min-width: 0; }
.qui-insight__kicker { min-width: 0; overflow-wrap: anywhere; }
.qui-insight__top .qui-prov { margin-left: auto; }
.qui-insight__msg { overflow-wrap: anywhere; }

/* ── FamilyStrip — KPI values inside each card must shrink, not spill. ── */
.qui-fam { min-width: 0; }
.qui-fam__kpi { min-width: 0; }
.qui-fam__name { min-width: 0; overflow-wrap: anywhere; }
.qui-fam__kpival { overflow-wrap: anywhere; }
/* one column on the narrowest phones (the 2-col rule kicks in ≤900px). */
@media (max-width: 460px) { .qui-family__grid { grid-template-columns: 1fr; } }

/* ── GanttChart — the last axis tick is centered on the right edge and
   spilled ~12px. Pad the timeline so edge ticks stay inside the box. ── */
.qui-gantt { overflow-x: hidden; }
.qui-gantt__axisticks { overflow: hidden; }
.qui-gantt__tick:last-child { transform: translateX(-100%); }
.qui-gantt__tick:first-child { transform: translateX(0); }

/* ── TopBar — the single chrome row cannot fit lockup + crumbs + ⌘K +
   freshness + actions on a phone. Tactic: let the bar WRAP, let the
   command button flex down to a usable size, and drop the lowest-value
   chrome (breadcrumbs, freshness label) on the narrowest widths. This
   is reflow, not a separate mobile component. ── */
.qui-topbar__bar { flex-wrap: wrap; row-gap: var(--space-4); min-width: 0; }
.qui-topbar__right { min-width: 0; flex: 1 1 auto; justify-content: flex-end; }
.qui-cmdbtn { min-width: 0; flex: 1 1 auto; max-width: 320px; }
.qui-crumbs { min-width: 0; }
.qui-crumbs ol { flex-wrap: wrap; }
@media (max-width: 600px) {
  /* breadcrumbs + the freshness *label* are redundant chrome on a phone;
     the live dot stays (status), the ⌘K + bell + avatar stay (actions). */
  .qui-topbar__bar .qui-crumbs { display: none; }
  .qui-fresh__label { display: none; }
  .qui-cmdbtn { order: 3; flex-basis: 100%; max-width: none; }
}

/* ── PageShell — the 216px side rail cannot coexist with content on a
   phone. Below the tablet breakpoint the rail becomes a TOP nav strip
   (single-column grid), so content gets full width and nothing clips.
   Justified mobile VARIANT: a 216px fixed sidebar fundamentally cannot
   reflow into a < 360px viewport beside real content — collapsing the
   GRID (not building a new component) is the minimal correct reflow. ── */
@media (max-width: 720px) {
  .qui-shell,
  .qui-shell--collapsed { grid-template-columns: 1fr; }
  .qui-shell__side {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4);
    overflow-x: auto;
    border-bottom: 1px solid var(--hair);
  }
  .qui-shell__side > * { min-width: 0; }
}

/* ── Skeleton (generic shimmer modifier, e.g. KpiCard loading) ──
   ROOT CAUSE of the KpiCard skeleton overflow: `.qui-skel` paints its
   shimmer via `::before`/`::after` that are `position:absolute; inset:0`,
   but `.qui-skel`/`.qui-kpi` were NOT a positioned containing block — so
   the pseudos resolved `inset:0` against a WIDER positioned ancestor and
   inflated the card's scrollWidth (574 vs 351). Establishing a local
   positioning context anchors the pseudos to the card. min-width:0 +
   capped descendants keep the ghost content inside the box too. */
.qui-skel { position: relative; min-width: 0; }
.qui-skel > *, .qui-skel * { max-width: 100%; }

/* ── Remaining narrow-width refinements ──────────────────────────── */

/* TopBar command-button placeholder must shrink (ellipsis) inside the
   now-flexible ⌘K button rather than forcing its min-content width. */
.qui-cmdbtn__ph { min-width: 0; }

/* HeatStrip axis — labelled ticks carry ~30px of mono text in a ~13px
   flex slot. The axis is decorative (aria-hidden); float each label so
   the TICK box stays slot-width (no per-tick overflow) while the label
   centers over its tick and may visually spill into adjacent EMPTY ticks
   — the intended "every-3rd-hour" reading. The axis row clips the ends. */
.qui-heat__axis { position: relative; overflow: hidden; }
.qui-heat__tick { position: relative; overflow: visible; }
.qui-heat__tick { display: flex; justify-content: center; }
.qui-heat__tick > * , .qui-heat__tick { line-height: 1; }

/* Donut — at the very narrowest the ring + wrapped legend can still tie;
   let the whole component shrink and the legend take the full row when
   wrapped (already flex 1 1 132px), and cap the ring so it never floors
   the layout wider than the card. */
.qui-donut__ring { max-width: 100%; }
.qui-donut { row-gap: var(--space-6); }

/* InsightCard footer — action + meta on one row; allow them to wrap and
   shrink instead of the meta pushing past the card edge on a phone. */
.qui-insight__foot { min-width: 0; }
.qui-insight__action, .qui-insight__meta { min-width: 0; }
.qui-insight__meta { flex-wrap: wrap; }

/* GanttChart — bar labels are nowrap and can exceed a short bar near the
   timeline edge. Clip the label to its bar (the bar already conveys
   span/colour; the row label carries the full name). */
.qui-gantt__bar { overflow: hidden; }
.qui-gantt__barlabel { min-width: 0; max-width: 100%; }

/* ── Interactive target floor (≥24px, package law) ───────────────────
   These controls were ≤21px tall (text-baseline-sized). Give each a
   24px minimum hit area without disturbing the visual type rhythm. ── */
.qui-th__sort { min-height: 24px; }            /* table sort header button */
.qui-tr__btn { min-height: 24px; }             /* row-click button (cell padding adds more) */
.qui-widget__segbtn { min-height: 24px; min-width: 24px; }  /* widget period segments */
.qui-gantt__bar { min-height: 24px; }          /* timeline bars are tap targets */
.qui-gantt__lane { height: auto; min-height: 30px; }
/* breadcrumb links/buttons + a11y disclosure summary: inline text controls
   get vertical padding to reach a 24px target while staying inline. */
.qui-crumbs a, .qui-crumbs button { min-height: 24px; display: inline-flex; align-items: center; }
.g-a11y > summary { min-height: 24px; }

/* Calendar — must not squish below a usable size when two sit in a
   wrapping flex row; floor the width so the row WRAPS to one column on a
   phone instead of crushing day cells to ~13px (sub-target). At a ~260px
   floor the 7-col aspect-ratio grid yields ≥24px day targets. The day
   BUTTON must also FILL its grid column (buttons don't stretch to a grid
   cell on their own → they were sizing to the ~7px digit). width:100% +
   the existing aspect-ratio:1 makes each day a square ≥24px tap target. */
.qui-cal { min-width: min(260px, 100%); }
.qui-cal__day { width: 100%; min-height: 24px; }

/* Donut — final narrow tie: let the ring itself shrink a touch so the
   wrapped legend never shares a row that exceeds the card by a few px. */
.qui-donut__ring { flex: 0 1 auto; }
.qui-donut__ring svg { max-width: 100%; height: auto; }

/* ── More interactive-target floors ── */
.qui-seg button { min-height: 24px; }          /* ChartFrame range segments */
.qui-gantt__bar { min-width: 24px; }           /* shortest timeline bars stay tappable */
/* TopBar icon/avatar controls keep a 24px floor even when the bar wraps
   and flex squeezes them. */
.qui-iconbtn { min-width: 24px; min-height: 24px; }
.qui-topbar__right button, .qui-topbar__right a { min-width: 24px; min-height: 24px; }

/* ===============================================================
   Layout & typography primitives (§1) — Stack / Group / Grid /
   Paper / Text / Heading / Eyebrow. Zero-dep, tokens-only. The
   per-instance props (gap, surface, size, tone…) are applied as
   inline custom-property-backed styles by the components; these
   rules carry only the structural display mode + family defaults
   so the elements are correct even before inline style applies.
   =============================================================== */
.qui-stack { display: flex; flex-direction: column; min-width: 0; }
.qui-group { display: flex; flex-direction: row; min-width: 0; }
.qui-grid  { display: grid; min-width: 0; }

/* Paper — flat borderless surface (separation = surface tint, §1/§6). */
.qui-paper { box-sizing: border-box; }

/* Text / Heading — token type ladder; never raw px / raw colour. */
.qui-text { font-family: var(--font-body); color: var(--ink); margin: 0; }
.qui-text--eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  line-height: var(--leading-ui);
}
.qui-heading {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold); /* ceiling — never heavier */
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-display);
  color: var(--ink);
  margin: 0;
}
