/* ================================================================
   UI KIT EXTENSION — kit-ext.css
   ITAM chain-of-custody components. Pairs with kit-ext.js.
   Requires tokens.css loaded first; extends the same .tc scope.
   Components: custody ribbon (.cr) · floor grid (.fg) · compare
   pane (.cp) · scan capture (.sc) · evidence stack (.es).
   ================================================================ */

/* ---------- lifecycle palette (meaning-contract, playbook §6) ----------
   One colour per device state, identical in every chart/badge/cell.
   Validated computationally (contrast on surface + ΔE ≥ 12 incl.
   protan/deutan simulation) — see palette-check. Red is reserved:
   only `missing` (and a broken custody gap) may use it.
   in-repair and retired sit below 3:1 by design (lighter-amber and
   receded respectively) — both always carry direct labels/tooltips. */
.tc{
  --lc-stock:#82828e;   --lc-stock-ink:#5b5b66;
  --lc-use:var(--accent); --lc-use-ink:var(--accent-ink);
  --lc-transit:#c1780a; --lc-transit-ink:#92590a;
  --lc-repair:#d99a1f;  --lc-repair-ink:#8f6206;
  --lc-missing:#d03b3b; --lc-missing-ink:#ab2f2f;
  --lc-hold:#6b2bd9;    --lc-hold-ink:#5b21b6;
  --lc-retired:#b9b9c2; --lc-retired-ink:#80808b;
  --lc-missing-bg:rgba(208,59,59,.07);
  /* the signature provisional hatch — 45°, fill alternating with surface */
  --hatch-w:4px;
}
.tc[data-theme="paper"]{
  --lc-retired:#b7b5ab; --lc-retired-ink:#807e72;
}
/* state → colour, one rule set reused by every component below */
.lc-stock{--lc:var(--lc-stock);--lc-ink:var(--lc-stock-ink)}
.lc-use{--lc:var(--lc-use);--lc-ink:var(--lc-use-ink)}
.lc-transit{--lc:var(--lc-transit);--lc-ink:var(--lc-transit-ink)}
.lc-repair{--lc:var(--lc-repair);--lc-ink:var(--lc-repair-ink)}
.lc-missing{--lc:var(--lc-missing);--lc-ink:var(--lc-missing-ink)}
.lc-hold{--lc:var(--lc-hold);--lc-ink:var(--lc-hold-ink)}
.lc-retired{--lc:var(--lc-retired);--lc-ink:var(--lc-retired-ink)}
/* legend swatch (shared) */
.lc-sw{width:9px;height:9px;border-radius:3px;background:var(--lc);flex:none}
.lc-sw.hatched{background:repeating-linear-gradient(45deg,var(--lc) 0 2.5px,color-mix(in srgb,var(--lc) 22%,var(--surface)) 2.5px 5px);border:1px solid color-mix(in srgb,var(--lc) 60%,var(--surface))}
.lc-sw.gap{background:var(--lc-missing-bg);border:1.5px dashed var(--lc-missing)}

/* ================================================================
   1 · CUSTODY RIBBON  (.cr) — the hero
   ================================================================ */
.cr{--cr-h:40px}
/* expanded long ribbons scroll rather than squash; padding/margin trick keeps
   hover shadows and the gap flare unclipped */
.cr-scroll{overflow-x:auto;padding:10px 3px;margin:-10px -3px;scrollbar-width:thin}
.cr-inner{min-width:0}
.cr-head{display:flex;align-items:baseline;gap:10px;margin-bottom:10px;flex-wrap:wrap}
.cr-legend{margin-left:auto;display:flex;gap:13px;align-items:center}
.cr-lg{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--ink-2)}
.cr-band{position:relative;display:flex;align-items:center;height:var(--cr-h);gap:0}
/* segment: a plate in the band. Width set inline (∝ duration, min-width floor). */
.cr-seg{position:relative;height:26px;min-width:0;flex:0 1 auto;cursor:pointer;
  background:var(--lc);border-radius:2px;overflow:hidden;display:flex;align-items:center;justify-content:center;
  transform:scaleX(0);transform-origin:left center;
  transition:transform 220ms var(--ease-out),height var(--t-fast) var(--ease-spring),filter var(--t-fast) ease,box-shadow var(--t-fast) ease}
.cr.cr-on .cr-seg{transform:scaleX(1)}
.cr-seg:first-child{border-top-left-radius:8px;border-bottom-left-radius:8px}
.cr-seg:last-child{border-top-right-radius:8px;border-bottom-right-radius:8px}
.cr-seg:hover,.cr-seg:focus-visible{height:32px;filter:brightness(.95) saturate(1.08);box-shadow:0 3px 10px -3px color-mix(in srgb,var(--lc) 55%,transparent);z-index:2}
.cr-seg:active{height:29px;transition-duration:60ms}
/* provisional — the signature hatch (received, not yet countersigned) */
.cr-seg.provisional{background:repeating-linear-gradient(45deg,var(--lc) 0 var(--hatch-w),color-mix(in srgb,var(--lc) 24%,var(--surface)) var(--hatch-w) calc(var(--hatch-w)*2));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--lc) 55%,var(--surface))}
/* in-segment holder label — only rendered when the segment is wide enough */
.cr-lbl{font-size:10px;font-weight:600;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 8px;letter-spacing:.01em;text-shadow:0 1px 1px rgba(0,0,0,.18);pointer-events:none}
.cr-seg.lc-repair .cr-lbl,.cr-seg.lc-retired .cr-lbl,.cr-seg.lc-stock .cr-lbl{color:rgba(23,23,26,.8);text-shadow:none}
.cr-seg.provisional .cr-lbl{color:var(--lc-ink);text-shadow:none;background:color-mix(in srgb,var(--surface) 78%,transparent);border-radius:4px;line-height:15px;padding:0 6px}
/* broken — an open gap with a red edge. Nobody signed. The finding. */
.cr-gap{position:relative;height:var(--cr-h);flex:0 1 auto;min-width:34px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:var(--lc-missing-bg);border-left:2px solid var(--lc-missing);border-right:2px solid var(--lc-missing);
  opacity:0;transition:opacity 200ms ease,background var(--t-fast) ease}
.cr.cr-on .cr-gap{opacity:1}
.cr-gap:hover,.cr-gap:focus-visible{background:rgba(208,59,59,.13)}
.cr-gap::before,.cr-gap::after{content:"";position:absolute;left:-2px;right:-2px;height:0;border-top:2px dashed var(--lc-missing)}
.cr-gap::before{top:0}.cr-gap::after{bottom:0}
.cr-gap-lbl{font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--lc-missing-ink);white-space:nowrap;overflow:hidden;padding:0 6px}
/* the eye lands here first: one bloom after the band finishes drawing — never loops */
@keyframes cr-gap-flare{0%{box-shadow:0 0 0 0 rgba(208,59,59,.45)}100%{box-shadow:0 0 0 14px rgba(208,59,59,0)}}
.cr.cr-on .cr-gap.flare{animation:cr-gap-flare .7s var(--ease-out) 1 both}
/* join — a handover mark between two custodies */
.cr-join{position:relative;z-index:1;flex:none;width:7px;height:7px;margin:0 -3.5px;border-radius:50%;
  background:var(--surface);border:1.5px solid var(--ink-3);
  opacity:0;transform:scale(.4);transition:opacity 150ms ease,transform 200ms var(--ease-spring),border-color var(--t-fast) ease,background var(--t-fast) ease;cursor:default}
.cr.cr-on .cr-join{opacity:1;transform:scale(1)}
.cr-join:hover{border-color:var(--ink);transform:scale(1.35)}
.cr-join.unconfirmed{border-style:dashed;border-color:var(--warn-ink)}
/* collapsed-middle expander: "+34" pill in the band */
.cr-more{flex:none;height:26px;padding:0 10px;margin:0 3px;display:flex;align-items:center;gap:4px;cursor:pointer;
  font-size:10.5px;font-weight:650;font-variant-numeric:tabular-nums;color:var(--ink-2);
  background:var(--surface);border:1.5px dashed var(--hairline);border-radius:99px;
  opacity:0;transition:opacity 200ms ease,border-color var(--t-fast) ease,color var(--t-fast) ease,transform var(--t-fast) var(--ease-spring)}
.cr.cr-on .cr-more{opacity:1}
.cr-more:hover{border-color:color-mix(in srgb,var(--ink) 35%,var(--hairline));color:var(--ink);transform:scaleY(1.12)}
.cr-more:active{transform:scaleY(1)}
.cr-fold{margin-left:auto;font-size:11px;font-weight:550;color:var(--ink-3);cursor:pointer;display:inline-flex;align-items:center;gap:4px;transition:color var(--t-fast) ease}
.cr-fold:hover{color:var(--accent-ink)}
/* axis under the band */
.cr-axis{display:flex;justify-content:space-between;margin-top:7px;font-family:var(--mono);font-size:10px;color:var(--ink-3)}
.cr-axis .cr-total{color:var(--ink-2);font-weight:600}
@media (prefers-reduced-motion:reduce){
  .cr-seg,.cr-gap,.cr-join,.cr-more{transition-delay:0ms!important}
  .cr.cr-on .cr-gap.flare{animation:none}
}

/* ================================================================
   2 · FLOOR GRID  (.fg)
   ================================================================ */
.fg-head{display:flex;align-items:center;gap:14px;margin-bottom:14px;flex-wrap:wrap}
.fg-site{display:flex;flex-direction:column;gap:1px}
.fg-site b{font-size:13.5px;font-weight:600;letter-spacing:-.008em}
.fg-site span{font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.fg-head .seg{margin-left:auto}
.fg-legend{display:flex;gap:12px;flex-wrap:wrap;margin-top:12px;padding-top:10px;border-top:1px solid var(--hairline-2)}
.fg-lg{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--ink-2)}
.fg-lg .fg-cell{width:12px;height:12px;cursor:default;transform:none}
.fg-floor{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:10px}
/* aisle rhythm: every other bay column pair separated by the grid gap is enough;
   the bay itself is the readable unit */
.fg-bay{background:var(--surface-2);border:1px solid var(--hairline-2);border-radius:9px;padding:8px 9px 9px;transition:border-color var(--t-fast) ease,background var(--t-fast) ease}
.fg-bay:hover{border-color:var(--hairline);background:color-mix(in srgb,var(--surface-2) 55%,var(--surface))}
.fg-bay-h{display:flex;align-items:baseline;gap:6px;margin-bottom:7px}
.fg-bay-h b{font-size:10px;font-weight:650;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-2)}
.fg-bay-h span{margin-left:auto;font-family:var(--mono);font-size:9.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.fg-seats{display:grid;grid-template-columns:repeat(5,1fr);gap:5px}
/* a seat: colour = device lifecycle state; solid = someone is on it this
   shift; outline = seat empty this shift; dashed = no device assigned */
.fg-cell{position:relative;aspect-ratio:1;border-radius:5px;cursor:pointer;
  background:var(--lc);border:1.5px solid transparent;
  transition:transform var(--t-fast) var(--ease-spring),box-shadow var(--t-fast) ease,background var(--t-med) ease,border-color var(--t-med) ease}
.fg-cell.empty{background:color-mix(in srgb,var(--lc) 14%,var(--surface));border-color:color-mix(in srgb,var(--lc) 55%,var(--surface))}
.fg-cell.nodev{background:transparent;border:1.5px dashed var(--hairline)}
.fg-cell:hover,.fg-cell:focus-visible{transform:scale(1.22);box-shadow:0 3px 10px -2px color-mix(in srgb,var(--lc,var(--ink)) 50%,transparent);z-index:2}
.fg-cell:active{transform:scale(1.05);transition-duration:60ms}
/* missing device gets a corner notch so it reads even at 12px */
.fg-cell.lc-missing::after{content:"";position:absolute;top:1.5px;right:1.5px;width:5px;height:5px;border-radius:50%;background:var(--surface);opacity:.9}

/* ================================================================
   3 · COMPARE PANE  (.cp) — register vs reality
   ================================================================ */
.cp-head{display:grid;grid-template-columns:var(--cp-lbl,150px) 1fr 1fr var(--cp-act,150px);gap:0 12px;align-items:center;padding:0 8px 9px;border-bottom:1px solid var(--hairline)}
.cp-src{display:flex;align-items:baseline;gap:7px;min-width:0}
.cp-src b{font-size:12px;font-weight:600}
.cp-src span{font-size:10.5px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cp-sum{grid-column:4;text-align:right;font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.cp-sum b{color:var(--warn-ink);font-weight:650}
.cp-row{display:grid;grid-template-columns:var(--cp-lbl,150px) 1fr 1fr var(--cp-act,150px);gap:0 12px;align-items:center;padding:7px 8px;margin:0;border-bottom:1px solid var(--hairline-2);border-radius:7px;transition:background var(--t-fast) ease,opacity var(--t-med) ease}
.cp-rows .cp-row:last-child{border-bottom:0}
.cp-row:hover{background:var(--surface-2)}
.cp-key{font-size:11px;font-weight:600;color:var(--ink-3);letter-spacing:.02em}
.cp-val{font-size:12.5px;font-variant-numeric:tabular-nums;color:var(--ink-2);min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-radius:5px;padding:2px 6px;margin:-2px -6px}
/* matching rows are quiet; the DIFFERENCE itself is marked, not the row */
.cp-row.diff .cp-key{color:var(--ink)}
.cp-row.diff .cp-val.ne{background:rgba(237,161,0,.1);color:var(--warn-ink);font-weight:600;margin:-2px 0;padding:2px 6px;box-shadow:inset 0 0 0 1px rgba(237,161,0,.22)}
/* a value present on one side only */
.cp-val.absent{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.07em;color:var(--ink-3);background:none;box-shadow:inset 0 0 0 1.5px var(--hairline);border-style:none;text-align:center;padding:3px 6px}
.cp-row.diff .cp-val.absent{color:var(--warn-ink);box-shadow:inset 0 0 0 1.5px rgba(237,161,0,.35)}
/* inline resolutions live in the row, appear with intent */
.cp-act{display:flex;gap:5px;justify-content:flex-end;opacity:.55;transition:opacity var(--t-fast) ease}
.cp-row:hover .cp-act,.cp-act:focus-within{opacity:1}
.cp-res{height:23px;padding:0 9px;border-radius:6px;font-size:10.5px;font-weight:600;color:var(--ink-2);border:1px solid var(--hairline);background:var(--surface);transition:all var(--t-fast) ease;white-space:nowrap}
.cp-res:hover{color:var(--ink);border-color:color-mix(in srgb,var(--ink) 25%,var(--hairline));box-shadow:0 1px 2px rgba(var(--shadow-c),.06)}
.cp-res:active{transform:scale(.95)}
/* resolved: the row settles — tint drains, a small verdict chip remains */
.cp-row.resolved .cp-val.ne{background:none;box-shadow:none;color:var(--ink-3);font-weight:400}
.cp-row.resolved .cp-val.kept{color:var(--ink);font-weight:600}
.cp-verdict{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:600;color:var(--s-good-ink);white-space:nowrap}
.cp-verdict svg{flex:none}
@keyframes cp-settle{0%{transform:translateY(-2px);opacity:0}100%{transform:none;opacity:1}}
.cp-verdict{animation:cp-settle .28s var(--ease-spring)}

/* ================================================================
   4 · SCAN CAPTURE  (.sc)
   ================================================================ */
.sc-zone{position:relative;display:flex;align-items:center;gap:12px;min-height:60px;padding:0 16px;cursor:text;
  background:var(--surface);border:1.5px solid var(--hairline);border-radius:10px;
  transition:border-color var(--t-fast) ease,box-shadow var(--t-med) var(--ease-spring)}
.sc-zone:hover{border-color:color-mix(in srgb,var(--ink) 20%,var(--hairline))}
.sc-zone.focus{border-color:color-mix(in srgb,var(--accent) 55%,var(--hairline));box-shadow:0 0 0 4px var(--accent-bg)}
.sc-ic{flex:none;color:var(--ink-3);transition:color var(--t-fast) ease}
.sc-zone.focus .sc-ic{color:var(--accent-ink)}
/* the barcode metaphor: on focus its bars do one quick scan sweep */
.sc-ic .swp{opacity:0}
.sc-zone.focus .sc-ic .swp{animation:sc-sweep .9s var(--ease-out) 1}
@keyframes sc-sweep{0%{opacity:0;transform:translateX(0)}15%{opacity:1}85%{opacity:1}100%{opacity:0;transform:translateX(16px)}}
.sc-zone input{flex:1;border:0;outline:0;background:none;font-family:var(--mono);font-size:15px;letter-spacing:.02em;color:var(--ink);height:58px}
.sc-zone input::placeholder{font-family:var(--sans);font-size:13px;letter-spacing:0;color:var(--ink-3);transition:opacity var(--t-fast) ease}
.sc-zone.focus input::placeholder{opacity:.45}
.sc-hint{flex:none;display:flex;gap:5px;align-items:center}
.sc-hint .kbd{margin:0}
/* transient verdict line under the zone — one message at a time, fades */
.sc-note{min-height:20px;margin-top:6px;padding:0 4px;font-size:11.5px;display:flex;align-items:center;gap:6px;opacity:0;transform:translateY(-3px);transition:opacity var(--t-fast) ease,transform var(--t-fast) var(--ease-out)}
.sc-note.on{opacity:1;transform:none}
.sc-note.ok{color:var(--s-good-ink)}
.sc-note.dupe{color:var(--warn-ink)}
.sc-note.bad{color:var(--lc-missing-ink)}
/* captured list */
.sc-list-h{display:flex;align-items:baseline;gap:8px;margin:10px 4px 2px}
.sc-list-h b{font-size:12px;font-weight:600}
.sc-count{font-size:10.5px;font-weight:650;font-variant-numeric:tabular-nums;color:var(--accent-ink);background:var(--accent-bg);border-radius:99px;padding:1px 8px}
.sc-count.pop{animation:badge-pop .4s var(--ease-spring)} /* reuses tokens.css keyframes */
.sc-badcount{font-size:11px;color:var(--lc-missing-ink);font-variant-numeric:tabular-nums;margin-left:auto}
.sc-rows{margin-top:4px}
.sc-row{display:flex;align-items:center;gap:10px;padding:7px 8px;margin:0 -4px;border-radius:8px;border-bottom:1px solid var(--hairline-2);
  max-height:44px;overflow:hidden;transition:background var(--t-fast) ease,max-height var(--t-med) var(--ease-out),opacity var(--t-med) ease,padding var(--t-med) var(--ease-out)}
.sc-rows .sc-row:last-child{border-bottom:0}
.sc-row:hover{background:var(--surface-2)}
.sc-row.out{max-height:0;opacity:0;padding-top:0;padding-bottom:0;border-bottom-width:0}
@keyframes sc-in{0%{opacity:0;transform:translateY(-6px)}100%{opacity:1;transform:none}}
.sc-row.new{animation:sc-in .26s var(--ease-out)}
.sc-code{font-family:var(--mono);font-size:12.5px;font-weight:600;letter-spacing:.02em}
.sc-dev{font-size:11.5px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sc-way{margin-left:auto;flex:none;font-size:9.5px;font-weight:650;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);border:1px solid var(--hairline);border-radius:4px;padding:1px 6px;background:var(--surface)}
.sc-row.bad{box-shadow:inset 2.5px 0 0 var(--lc-missing)}
.sc-row.bad .sc-code{color:var(--lc-missing-ink)}
.sc-row.bad .sc-dev{color:var(--lc-missing-ink);opacity:.8}
/* duplicate: the existing row answers — one shake, then a brief wash */
@keyframes sc-nudge{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}55%{transform:translateX(3px)}80%{transform:translateX(-1.5px)}}
.sc-row.dupe-hit{animation:sc-nudge .4s var(--ease-out);background:rgba(237,161,0,.1)}
.sc-x{flex:none;width:24px;height:24px;border-radius:6px;display:grid;place-items:center;color:var(--ink-3);opacity:0;transition:opacity var(--t-fast) ease,background var(--t-fast) ease,color var(--t-fast) ease}
.sc-row:hover .sc-x,.sc-x:focus-visible{opacity:1}
.sc-x:hover{background:var(--surface);color:var(--danger)}
.sc-emp{padding:16px 8px;font-size:12px;color:var(--ink-3);text-align:center}

/* ================================================================
   5 · EVIDENCE STACK  (.es)
   ================================================================ */
.es{display:flex;flex-direction:column;gap:7px}
.es-it{display:flex;align-items:center;gap:11px;padding:9px 11px;border-radius:9px;cursor:pointer;
  background:var(--surface);border:1px solid var(--hairline);
  transition:border-color var(--t-fast) ease,box-shadow var(--t-med) ease,transform var(--t-med) var(--ease-spring)}
.es-it:hover,.es-it:focus-visible{transform:translateY(-1px);border-color:color-mix(in srgb,var(--ink) 18%,var(--hairline));box-shadow:0 1px 2px rgba(var(--shadow-c),.04),0 6px 16px -8px rgba(var(--shadow-c),.14)}
.es-it:active{transform:translateY(0) scale(.99);transition-duration:60ms}
/* evidence tiles stay NEUTRAL — colour belongs to the lifecycle contract;
   the icon carries the kind's identity */
.es-ic{flex:none;width:30px;height:30px;border-radius:8px;display:grid;place-items:center;color:var(--ink-2);
  background:var(--surface-2);border:1px solid var(--hairline);
  transition:transform var(--t-med) var(--ease-spring),color var(--t-fast) ease}
.es-it:hover .es-ic{color:var(--accent-ink)}
.es-it:hover .es-ic{transform:rotate(-5deg) scale(1.08)}
.es-meta{min-width:0;display:block}
.es-kind{display:block;font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.es-who{display:block;font-size:11px;color:var(--ink-3);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.es-date{margin-left:auto;flex:none;font-family:var(--mono);font-size:10.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.es-go{flex:none;color:var(--ink-3);opacity:0;transform:translateX(-4px);transition:opacity var(--t-fast) ease,transform var(--t-fast) ease}
.es-it:hover .es-go,.es-it:focus-visible .es-go{opacity:1;transform:none}
/* the deliberate gap: expected, absent, and said out loud. A plate, not prose. */
.es-it.gap{cursor:default;background:transparent;border:1.5px dashed color-mix(in srgb,var(--lc-missing) 42%,var(--hairline))}
.es-it.gap:hover{transform:none;box-shadow:none;border-color:color-mix(in srgb,var(--lc-missing) 62%,var(--hairline))}
.es-it.gap .es-ic{background:transparent;border:1px dashed var(--hairline);color:var(--ink-3);opacity:.75}
.es-it.gap:hover .es-ic{transform:none}
.es-it.gap .es-kind{color:var(--ink-3);font-weight:500}
.es-stamp{margin-left:auto;flex:none;font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:.1em;color:var(--lc-missing-ink);border:1.5px solid color-mix(in srgb,var(--lc-missing) 55%,transparent);border-radius:4px;padding:2.5px 7px;transform:rotate(-1.5deg)}
