/* ============================================================================
   KG MAX — design-bible shared layer.  Loaded right after tokens.css in every
   shell (dashboard, max, auth, admin, scan).  Brand primitives shared across all
   domains: the live-CSS MAX mark (ported 1:1 from design-bible/MAX Logo - Michroma
   .html — replaces every KG logo), the ring-motion spinner (the new loading icon +
   Max "thinking" bubble), and bible utilities. The mark is brand-locked: its
   Energy Red (ember arc, the "x", glow, hover-bloom) routes through --max-red,
   NOT --user-accent — the logo never follows the operator accent picker (which
   still themes chrome/CTAs everywhere else). Respects prefers-reduced-motion.
   ============================================================================ */

button, input, select, textarea { font: inherit; letter-spacing: inherit; color: inherit; }

/* ---------------------------------------------------------------- THE MAX MARK
   CANON (design-bible/MAX Logo - Michroma.html): a thin ring = silver band +
   energy-red arc (peak 45°, 150° spread, feathering both ways) + a feathered
   shadow arc opposite, built with border + mask-composite:exclude.  The lockup
   threads the "max" wordmark (Michroma; "ma" silver, "x" red) THROUGH the ring.

   Markup — symbol (ring only):
     <span class="max-mark" style="--d:40px"><i class="mk-band"></i>
       <i class="mk-energy"></i><i class="mk-shadow"></i></span>
   Markup — lockup (word through ring):
     <span class="max-lockup" style="--d:120px">
       <span class="max-mark max-mark--fade"><i class="mk-band"></i>
         <i class="mk-energy"></i><i class="mk-shadow"></i></span>
       <span class="mk-word"><span class="ma">ma</span><span class="x">x</span></span></span>
   Size: set --d (ring diameter); --sw (stroke) + --wf (word size) derive from it. */
.max-mark {
  --d: 40px;
  --sw: max(1.3px, calc(var(--d) * 0.018));   /* canon stroke ~1.8% of diameter; 1.3px floor keeps the ring visible at tiny (header/spinner) sizes */
  --energy: var(--max-red, #ff381f);
  --mk-bg: var(--bg, #09090a);     /* surface the shadow melts the ring into */
  --hot: 45deg; --spread: 75deg;
  --shadow-hot: 225deg; --shadow-spread: 90deg;
  position: relative;
  width: var(--d); height: var(--d);
  flex: 0 0 auto;
  display: inline-block;
  vertical-align: middle;
  border-radius: 50%;
}
.max-mark > i {
  position: absolute; inset: 0; border-radius: 50%; box-sizing: border-box;
  border: var(--sw) solid transparent;
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
/* Mark tones: graphite/steel is the LIGHT default (reads on white cards + light
   headers); dark/MAX — and the forced .--silver modifier, for dark overlays like
   the splash — restore the bright silver band. Mirrors tokens.css light/dark/auto. */
.max-mark .mk-band {
  background: linear-gradient(155deg, #5c5f67, #34373d 40%, #60636b 70%, #232529) border-box;
}
:root[data-theme="dark"] .max-mark .mk-band,
:root[data-theme="max"] .max-mark .mk-band,
.max-mark--silver .mk-band,
.max-lockup--silver .mk-band {
  background: linear-gradient(155deg, #f4f4f5, #c6c7ca 42%, #84858a 74%, #5f6064) border-box;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .max-mark .mk-band {
    background: linear-gradient(155deg, #f4f4f5, #c6c7ca 42%, #84858a 74%, #5f6064) border-box;
  }
}
.max-mark .mk-energy {
  background: conic-gradient(from calc(var(--hot) - 180deg),
    color-mix(in srgb, var(--energy), transparent 100%) calc(180deg - var(--spread)),
    color-mix(in srgb, var(--energy), transparent 82%)  calc(180deg - var(--spread) * 0.80),
    color-mix(in srgb, var(--energy), transparent 52%)  calc(180deg - var(--spread) * 0.58),
    color-mix(in srgb, var(--energy), transparent 22%)  calc(180deg - var(--spread) * 0.36),
    var(--energy)                                        calc(180deg - var(--spread) * 0.16),
    color-mix(in srgb, var(--energy) 60%, white)        180deg,
    var(--energy)                                        calc(180deg + var(--spread) * 0.16),
    color-mix(in srgb, var(--energy), transparent 22%)  calc(180deg + var(--spread) * 0.36),
    color-mix(in srgb, var(--energy), transparent 52%)  calc(180deg + var(--spread) * 0.58),
    color-mix(in srgb, var(--energy), transparent 82%)  calc(180deg + var(--spread) * 0.80),
    color-mix(in srgb, var(--energy), transparent 100%) calc(180deg + var(--spread)),
    color-mix(in srgb, var(--energy), transparent 100%) 360deg) border-box;
}
.max-mark .mk-shadow {
  background: conic-gradient(from calc(var(--shadow-hot) - 180deg),
    transparent calc(180deg - var(--shadow-spread)),
    color-mix(in srgb, var(--mk-bg), transparent 88%) calc(180deg - var(--shadow-spread) * 0.82),
    color-mix(in srgb, var(--mk-bg), transparent 68%) calc(180deg - var(--shadow-spread) * 0.62),
    color-mix(in srgb, var(--mk-bg), transparent 40%) calc(180deg - var(--shadow-spread) * 0.40),
    color-mix(in srgb, var(--mk-bg), transparent 16%) calc(180deg - var(--shadow-spread) * 0.20),
    var(--mk-bg) 180deg,
    color-mix(in srgb, var(--mk-bg), transparent 16%) calc(180deg + var(--shadow-spread) * 0.20),
    color-mix(in srgb, var(--mk-bg), transparent 40%) calc(180deg + var(--shadow-spread) * 0.40),
    color-mix(in srgb, var(--mk-bg), transparent 68%) calc(180deg + var(--shadow-spread) * 0.62),
    color-mix(in srgb, var(--mk-bg), transparent 88%) calc(180deg + var(--shadow-spread) * 0.82),
    transparent calc(180deg + var(--shadow-spread)),
    transparent 360deg) border-box;
}
/* horizontal gap where the wordmark crosses the ring (lockup only) */
.max-mark--fade {
  -webkit-mask: linear-gradient(to bottom, #000 0, #000 30%, transparent 35%, transparent 65%, #000 70%, #000 100%);
          mask: linear-gradient(to bottom, #000 0, #000 30%, transparent 35%, transparent 65%, #000 70%, #000 100%);
}
.max-mark.is-glow { filter: drop-shadow(0 0 calc(var(--d) * 0.18) color-mix(in srgb, var(--max-red, #ff381f) 42%, transparent)); }

/* hero lockup — wordmark threaded through the ring */
.max-lockup {
  --d: 120px;
  --wf: calc(var(--d) * 0.40);
  position: relative;
  display: inline-block;
  line-height: 1;
}
.max-lockup > .max-mark { --d: inherit; }
.max-lockup .mk-word {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, calc(-50% - var(--d) * 0.084));   /* center x-height band on the ring axis (canon optical nudge) */
  font-family: var(--font-wordmark, "Michroma", var(--font-display));
  font-weight: 400;
  font-size: var(--wf);
  line-height: 1;
  white-space: nowrap;
  letter-spacing: -0.02em;
  user-select: none;
}
.max-lockup .ma {
  background: linear-gradient(180deg, #3a3e46 0%, #1a1f26 62%, #0e1116 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
:root[data-theme="dark"] .max-lockup .ma,
:root[data-theme="max"] .max-lockup .ma,
.max-lockup--silver .ma {
  background: linear-gradient(180deg, #ffffff 0%, #ededef 26%, #bcbdc1 64%, #898a8e 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .max-lockup .ma {
    background: linear-gradient(180deg, #ffffff 0%, #ededef 26%, #bcbdc1 64%, #898a8e 100%);
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  }
}
.max-lockup .x {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--max-red, #ff381f) 62%, white) 0%,
    var(--max-red, #ff381f) 58%,
    color-mix(in srgb, var(--max-red, #ff381f) 82%, black) 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}

/* ------------------------------------------------------------- RING-MOTION
   The loading icon + Max "thinking" = the MAX ring with the energy arc orbiting. */
@keyframes max-ring-spin { to { transform: rotate(360deg); } }
.max-spinner .mk-energy { animation: max-ring-spin 1.3s linear infinite; transform-origin: 50% 50%; }
.max-spinner .mk-shadow { display: none; }   /* a clean chase, no fixed melt while spinning */

/* "Brain overdrive": the chat thinking ring is JS-driven (views/chat.js
   driveThinkingRing) — a single continuous rotation whose SPEED eases between
   levels + a HEAT value that ramps an ember flare, so the mark glides
   idle → spin-up → (rarely) fire → wind-down with NO keyframe reset. .is-engine
   hands rotation to JS (the flare filter/scale are set inline per frame);
   reduced-motion no-ops the engine, leaving the plain spin below. */
.max-spinner.is-engine .mk-energy { animation: none; }

.max-thinking {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--text-dim);
}
.max-thinking .max-mark { --d: 18px; --mk-bg: transparent; }
.max-thinking .mt-label::after { content: ""; animation: max-think-dots 1.4s steps(1, end) infinite; }
@keyframes max-think-dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }

/* Max chat in-flight "thinking" — the MAX ring spinning beside the rotating status line */
.chat-stream-status { display: inline-flex; align-items: center; gap: 9px; }
.chat-stream-status .chat-stream-ring { --d: 17px; flex: 0 0 auto; }

/* ----------------------------------------------------------- LOGO POWER-ON
   Hover/focus the brand mark (host carries .max-poweron) → the energy arc spools
   up two turns (turbine-style ease-out) and the whole ring blooms red. */
@keyframes max-ring-poweron { from { transform: rotate(0); } to { transform: rotate(720deg); } }
@keyframes max-logo-bloom {
  0%   { filter: drop-shadow(0 0 4px  color-mix(in srgb, var(--max-red, #ff381f) 18%, transparent)); }
  42%  { filter: drop-shadow(0 0 17px color-mix(in srgb, var(--max-red, #ff381f) 82%, transparent)) saturate(1.22) brightness(1.13); }
  100% { filter: drop-shadow(0 0 8px  color-mix(in srgb, var(--max-red, #ff381f) 42%, transparent)); }
}
.max-poweron { cursor: pointer; }
.max-poweron:hover .mk-energy,
.max-poweron:focus-visible .mk-energy {
  animation: max-ring-poweron 1s cubic-bezier(.16, .74, .18, 1);
  transform-origin: 50% 50%;
}
.max-poweron:hover .max-lockup,
.max-poweron:hover > .max-mark,
.max-poweron:focus-visible .max-lockup,
.max-poweron:focus-visible > .max-mark { animation: max-logo-bloom 1s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .max-poweron:hover .mk-energy, .max-poweron:focus-visible .mk-energy { animation: none; }
  .max-poweron:hover .max-lockup, .max-poweron:focus-visible .max-lockup,
  .max-poweron:hover > .max-mark, .max-poweron:focus-visible > .max-mark {
    animation: none;
    filter: drop-shadow(0 0 11px color-mix(in srgb, var(--max-red, #ff381f) 55%, transparent));
  }
}

/* -------------------------------------------------------------- UTILITIES
   Bible eyebrow: UPPERCASE, wide-tracked, mono — the section/label voice. */
.kg-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: var(--fw-semi, 600);
  letter-spacing: var(--tracking-eyebrow, 0.2em);
  text-transform: uppercase;
  color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .max-spinner .mk-energy { animation-duration: 3.2s; }
  .max-thinking .mt-label::after { animation: none; content: "…"; }
}

/* ---------------------------------------------------------------- FEEDBACK
   Bible feedback primitives (design-bible/components/feedback). Mapped onto the
   dashboard's LOCKED tokens (--green/--warn/--red/--accent/--brand) via the same
   color-mix tint pattern as .crm-inv — store/type/state semantics are reused,
   never re-colored. The labeled spinner is the existing .max-thinking (ring +
   mono "Thinking…"); Badge + ProgressBar are added here. */
/* Canonical sub-tab voice — pillar sheets should adopt this instead of one-off tab CSS. */
.kg-tab {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: var(--fw-semi, 600);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-bottom: 2px solid transparent;
}
.kg-tab.is-active, .kg-tab.active { color: var(--brand); border-color: var(--brand); }

.ui-badge {
  display: inline-flex; align-items: center; gap: 6px; vertical-align: middle;
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; line-height: 1;
  letter-spacing: 0.02em; padding: 5px 10px; border-radius: var(--r-pill);
  border: 1px solid transparent; white-space: nowrap;
}
/* Canonical badge dot (this is what P3's box-write badge used — see
   views/admin-doctrine.js): 8px circle, currentColor by default so it inherits
   the parent .ui-badge--variant color for free. The .dot-ok/-warn/-danger/-info
   modifiers are an explicit-color escape hatch for a dot whose state differs
   from the badge's own variant (e.g. a neutral badge carrying a colored status
   dot) — same semantic tokens, just addressable standalone. */
.ui-badge .ui-badge-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: currentColor; }
.ui-badge-dot.dot-ok     { background: var(--green); }
.ui-badge-dot.dot-warn   { background: var(--warn); }
.ui-badge-dot.dot-danger { background: var(--red); }
.ui-badge-dot.dot-info   { background: var(--text-dim); }
.ui-badge--success  { color: var(--green); background: color-mix(in srgb, var(--green) 14%, transparent); }
.ui-badge--warning  { color: var(--warn);  background: color-mix(in srgb, var(--warn) 15%, transparent); }
.ui-badge--critical { color: var(--red);   background: color-mix(in srgb, var(--red) 13%, transparent); }
.ui-badge--info     { color: var(--text-dim); background: color-mix(in srgb, var(--text-muted) 14%, transparent); }
.ui-badge--neutral  { color: var(--text-dim); background: color-mix(in srgb, var(--text-muted) 10%, transparent); border-color: var(--border); }
.ui-badge--accent   { font-family: var(--font-display); font-weight: 600; color: #fff; background: var(--brand); box-shadow: var(--glow-red-sm); }
.ui-badge--critical .ui-badge-dot { box-shadow: 0 0 6px color-mix(in srgb, var(--red) 70%, transparent); }

/* ---------------------------------------------------------------- PAGE HEADER
   KGF.dom.pageHeader({eyebrow, title, subtitle, accentWord}) — shared/page-header.js. */
.kg-page-header { margin: 0 0 14px; }
.kg-eyebrow-dashed {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--brand); margin: 0 0 8px;
}
.kg-eyebrow-dashed::before { content: ''; display: inline-block; width: 16px; height: 2px; background: var(--brand); flex: 0 0 auto; }
.kg-ph-title {
  margin: 0; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(20px, 2.4vw, 28px); line-height: 1.15;
  letter-spacing: var(--tracking-tight); color: var(--text);
}
.kg-ph-accent { color: var(--brand); }
.kg-ph-sub {
  margin: 4px 0 0; font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--text-muted);
}

/* ----------------------------------------------------------------- EMPTY STATE
   KGF.dom.emptyState({title, note, variant}) / KGF.dom.loadingState(label) —
   shared/empty-state.js. Attention-style card: panel bg (not darker than
   canvas), 1px border, generous radius. */
.kg-empty {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center; padding: 32px 20px; margin: 0 auto;
  max-width: 420px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.kg-empty-title-row { display: flex; align-items: center; gap: 8px; }
.kg-empty-icon { color: var(--warn); flex: 0 0 auto; }
.kg-empty-title {
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--text);
}
.kg-empty-note { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; max-width: 40ch; }

.kg-loading { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 32px 0; }
.kg-loading-label {
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--text-muted);
}

/* ------------------------------------------------------ CONSTRAINED UI KIT
   App.ui owns the structural classes below. Feature views provide content and
   data, not one-off visual recipes. New tables, cards, filters, fields, buttons,
   and page shells should be assembled through shared/ui.js. */
.ui-page { min-width: 0; }
.ui-page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.ui-page-actions, .ui-card-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }

.ui-card {
  min-width: 0; padding: 18px 20px; background: var(--panel);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--edge-highlight), var(--sh-1);
}
.ui-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
.ui-card-heading { min-width: 0; }
.ui-card-title {
  margin: 2px 0 0; font-family: var(--font-display); font-size: 17px;
  font-weight: var(--fw-bold); letter-spacing: var(--tracking-tight); line-height: 1.2;
  color: var(--text-primary); text-wrap: balance;
}
.ui-card-note { margin-top: 4px; font-size: 12.5px; line-height: 1.45; color: var(--text-muted); text-wrap: pretty; }
.ui-card-body { min-width: 0; }

.ui-control {
  min-height: 36px; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-sunken); color: var(--text); font-family: var(--font-sans);
  font-size: 13px; font-weight: var(--fw-semi); line-height: 1.2;
  transition: background-color var(--hover-dur) var(--hover-ease),
              border-color var(--hover-dur) var(--hover-ease),
              color var(--hover-dur) var(--hover-ease),
              box-shadow var(--hover-dur) var(--hover-ease);
}
.ui-control:focus-visible, .ui-field-control:focus-visible, .ui-table-sort:focus-visible,
.js-copy:focus-visible { outline: none; box-shadow: var(--ring-focus); }
.ui-button { display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 8px 13px; cursor: pointer; }
.ui-button:hover { border-color: var(--hover-border); background: var(--hover-bg); }
.ui-button--primary { color: var(--user-accent-text); background: var(--brand); border-color: var(--brand); box-shadow: var(--glow-red-sm); }
.ui-button--primary:hover { background: color-mix(in srgb, var(--brand) 90%, black); border-color: var(--brand); }
.ui-button--danger { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.ui-button:disabled { opacity: 0.5; cursor: not-allowed; }
.ui-button svg { flex: 0 0 auto; }
@media (hover: hover) {
  .ui-button:active { transform: scale(0.97); transition-duration: var(--dur-fast); }
  .ui-button--primary:active { transform: scale(0.96); filter: brightness(0.92); box-shadow: none; }
}
.ui-input, .ui-select, .ui-textarea { padding: 8px 10px; }
.ui-input::placeholder, .ui-textarea::placeholder { color: var(--text-muted); }
.ui-select { cursor: pointer; }
.ui-textarea { min-height: 88px; resize: vertical; line-height: 1.45; }

.ui-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ui-field-label { font-size: 12px; font-weight: var(--fw-semi); color: var(--text-dim); }
.ui-field-control { width: 100%; }
.ui-field-help { font-size: 11px; line-height: 1.4; color: var(--text-muted); text-wrap: pretty; }
.ui-filter-bar {
  display: flex; align-items: end; gap: 10px; flex-wrap: wrap; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--panel-2);
}
.ui-filter-bar > .ui-field { flex: 1 1 160px; }

.ui-data-table-wrap,
.ui-table-scroll { width: 100%; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ui-data-table { width: 100%; border-collapse: collapse; font-size: 13px; color: var(--text); }
.ui-data-table th, .ui-data-table td { padding: 9px 10px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
.ui-data-table th {
  background: transparent; color: var(--text-muted); font-family: var(--font-sans);
  font-size: 12.5px; font-weight: var(--fw-semi); letter-spacing: 0.03em;
  text-transform: uppercase; white-space: nowrap;
}
.ui-data-table td.numeric, .ui-data-table th.numeric { text-align: right; }
.ui-data-table .numeric { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.ui-data-table tbody tr:hover { background: var(--hover-bg); }
.ui-data-table tbody tr:last-child td { border-bottom: 0; }
.ui-table-id { font-family: var(--font-mono); }
.ui-table-sort {
  display: inline-flex; align-items: center; gap: 5px; width: 100%; padding: 0;
  border: 0; border-radius: var(--r-xs); background: transparent; color: inherit;
  font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer;
}
.ui-data-table th.numeric .ui-table-sort { justify-content: flex-end; }
.ui-table-sort-icon { color: var(--accent); flex: 0 0 auto; }
.ui-table-sort-icon.is-ascending { transform: rotate(180deg); }
.ui-table-action { width: 1%; text-align: right; white-space: nowrap; }
.ui-table-mobile-sort { display: none; }

@media (max-width: 920px) {
  .ui-table-scroll > table {
    display: table;
    table-layout: auto;
    width: max-content;
    min-width: 100%;
  }
  .ui-page-head, .ui-card-head { align-items: stretch; flex-direction: column; }
  .ui-page-actions, .ui-card-actions { justify-content: flex-start; }
  .ui-card { padding: 14px 12px; }
  .ui-control { min-height: 44px; }
  .ui-textarea { min-height: 108px; }
  .ui-filter-bar { align-items: stretch; flex-direction: column; }
  .ui-filter-bar > .ui-field { flex: 0 0 auto; }
  .ui-data-table-wrap[data-mobile="cards"] { overflow: visible; }
  .ui-data-table-wrap[data-mobile="cards"] .ui-table-mobile-sort {
    display: flex; align-items: center; gap: 8px; margin-bottom: 10px;
  }
  .ui-data-table-wrap[data-mobile="cards"] .ui-table-mobile-sort .ui-select { flex: 1 1 auto; }
  .ui-data-table-wrap[data-mobile="cards"] .ui-table-mobile-direction { flex: 0 0 auto; }
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table,
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table tbody,
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table tr,
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table td { display: block; width: 100%; }
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table thead { display: none; }
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table tbody { display: grid; gap: 10px; }
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table tr {
    padding: 5px 10px; border: 1px solid var(--border); border-radius: var(--r-md);
    background: var(--panel-2);
  }
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding: 7px 0; text-align: right; white-space: normal;
  }
  .ui-data-table-wrap[data-mobile="cards"] .ui-data-table td::before {
    content: attr(data-label); flex: 0 0 auto; color: var(--text-muted);
    font-family: var(--font-sans); font-size: 11px; font-weight: var(--fw-semi);
    letter-spacing: 0.03em; text-transform: uppercase; text-align: left;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ui-control { transition-duration: 0.01ms; }
  .ui-button:active { transform: none; }
}

/* ------------------------------------------------------------- WORDMARK GLINT
   Opt-in one-shot sweep across the ring band — ported from design-bible/MAX
   Font + Glint.html (.r2__glint: a narrow conic-gradient highlight arc,
   layered over the ring with the same border+mask-composite:exclude trick as
   .max-mark's own children). app-header.js toggles this modifier once per
   session after the lockup mounts, then removes it on animationend. */
.max-lockup--glint .max-mark::after {
  content: '';
  position: absolute; inset: 0; border-radius: 50%; box-sizing: border-box;
  border: calc(var(--sw) + 1.2px) solid transparent;
  background: conic-gradient(from 0deg,
    rgba(255, 255, 255, 0)     0deg,
    rgba(255, 228, 216, 0.85)  6deg,
    #ffffff                    10deg,
    rgba(255, 176, 150, 0.8)   14deg,
    rgba(255, 90, 55, 0)       22deg,
    rgba(255, 90, 55, 0)       360deg) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  animation: max-glint-sweep 700ms ease-out 1 forwards;
}
@keyframes max-glint-sweep {
  0%   { opacity: 0; transform: rotate(0deg); }
  10%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { opacity: 0; transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .max-lockup--glint .max-mark::after { animation: none; }
}

/* ProgressBar — deterministic (set inline width on .ui-progress-fill) or
   .is-indeterminate ("converging inputs": the 38% bar sweeps left→right). */
.ui-progress { display: flex; flex-direction: column; gap: 8px; font-family: var(--font-sans); }
.ui-progress-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.ui-progress-label { font-size: 12.5px; color: var(--text-dim); font-weight: 500; }
.ui-progress-val { font-family: var(--font-mono); font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; }
.ui-progress-track {
  position: relative; height: 8px; border-radius: var(--r-pill);
  background: var(--bg-sunken); border: 1px solid var(--border-subtle, var(--border)); overflow: hidden;
}
.ui-progress-track.is-lg { height: 12px; }
.ui-progress-fill {
  position: absolute; inset: 0 auto 0 0; width: 0; border-radius: var(--r-pill);
  background: var(--gradient-energy); box-shadow: var(--glow-red-sm);
  transition: width var(--dur-slow) var(--ease-out);
}
.ui-progress.is-indeterminate .ui-progress-fill { width: 38%; animation: kgf-prog-slide 1.25s var(--ease-standard) infinite; }
@keyframes kgf-prog-slide { 0% { left: -40%; } 100% { left: 100%; } }
@media (prefers-reduced-motion: reduce) {
  .ui-progress.is-indeterminate .ui-progress-fill { animation-duration: 2.8s; }
}

/* ------------------------------------------------------------------- SWITCH
   input[type=checkbox].ui-switch — the bible track/thumb toggle, replacing
   OS-default checkboxes on genuine on/off settings (dense multi-select grids
   keep plain checkboxes). Pure CSS on the native input, so keyboard + AT come
   free: track = sunken pill, thumb = muted dot; checked = Energy Red fill,
   white thumb. */
input[type="checkbox"].ui-switch {
  -webkit-appearance: none; appearance: none;
  width: 34px; height: 20px; flex: 0 0 auto;
  border-radius: var(--r-pill); border: 1px solid var(--border-strong);
  background: var(--bg-sunken);
  position: relative; cursor: pointer; margin: 0; vertical-align: middle;
  transition: background var(--dur-fast, 120ms) var(--ease-standard),
              border-color var(--dur-fast, 120ms) var(--ease-standard);
}
input[type="checkbox"].ui-switch::before {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--text-muted);
  transition: transform var(--dur-fast, 120ms) var(--ease-standard),
              background var(--dur-fast, 120ms) var(--ease-standard);
}
input[type="checkbox"].ui-switch:checked {
  background: var(--user-accent); border-color: var(--user-accent);
}
input[type="checkbox"].ui-switch:checked::before {
  transform: translateX(14px); background: #fff;
}
input[type="checkbox"].ui-switch:focus-visible { outline: none; box-shadow: var(--ring-focus); }
input[type="checkbox"].ui-switch:disabled { opacity: 0.5; cursor: not-allowed; }
@media (prefers-reduced-motion: reduce) {
  input[type="checkbox"].ui-switch, input[type="checkbox"].ui-switch::before { transition: none; }
}

/* -------------------------------------------------------------- DELTA BADGE
   .ui-delta — the bible StatCard tile-level delta: mono, tabular, arrow +
   value. up = green / down = red (§2.3: an up-delta is always green) /
   flat = muted. Build via App.kpi.deltaBadge(). */
.ui-delta {
  display: inline-flex; align-items: center; gap: 3px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.ui-delta.up { color: var(--green); }
.ui-delta.down { color: var(--red); }
.ui-delta.flat { color: var(--text-muted); }
.ui-delta svg { display: block; }

/* ------------------------------------------------------------------ SKELETON
   .ui-skel — ghost content rows swept by the shimmer while a KNOWN-shape
   region loads. Loading doctrine (Aaron 2026-07-09): the MAX ring is reserved
   for Max AI surfaces (chat thinking, voice, maxai panes, the max.html boot);
   everything else loads as the telemetry bar (.ui-progress.is-indeterminate,
   unknown shape) or these skeleton rows (known shape). One loader per moment —
   the shimmer IS the signal; never pair skeleton + bar in the same region. */
.ui-skel { display: flex; flex-direction: column; gap: 9px; padding: 4px 0; }
.ui-skel-row {
  height: 13px; border-radius: var(--r-xs);
  background: linear-gradient(90deg,
    var(--bg-sunken) 25%, var(--bg-elevated) 50%, var(--bg-sunken) 75%);
  background-size: 400% 100%;
  animation: kgf-skel-shimmer 1.1s ease infinite;
}
/* Varied widths so the ghost reads as content, not stripes. */
.ui-skel-row:nth-child(3n)   { width: 84%; }
.ui-skel-row:nth-child(3n+2) { width: 94%; }
/* Ghost primitives beyond rows: a circle (gauge ghosts) and a tall canvas
   (map / flow / chart-first views). Same sweep, same reduced-motion rules. */
.ui-skel-circle {
  width: clamp(84px, 9vw, 128px); aspect-ratio: 1; border-radius: 50%;
  background: linear-gradient(90deg,
    var(--bg-sunken) 25%, var(--bg-elevated) 50%, var(--bg-sunken) 75%);
  background-size: 400% 100%;
  animation: kgf-skel-shimmer 1.1s ease infinite;
}
.ui-skel-canvas {
  height: min(52vh, 460px); border-radius: var(--r-md);
  background: linear-gradient(90deg,
    var(--bg-sunken) 25%, var(--bg-elevated) 50%, var(--bg-sunken) 75%);
  background-size: 400% 100%;
  animation: kgf-skel-shimmer 1.1s ease infinite;
}
@keyframes kgf-skel-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ui-skel-row, .ui-skel-circle, .ui-skel-canvas {
    animation: none; background-position: 50% 0;
  }
}
/* Centered-loader bar width (kg-loading / view-loading / shell boots). */
.ui-loading-bar { width: min(220px, 70%); }
