/* ================================================================
   UI KIT DETAIL — kit-detail.css
   The record and admin moves. Pairs with kit-detail.js.
   Requires tokens.css + kit-ext.css (lifecycle palette + the ribbon
   vocabulary) + kit-core.css (.plate, .pop-menu) loaded first.
   Components: event feed (.ef) · position meter (.pm) · period
   (.pd) · field (.kf) · settings (.stg) · feed card (.fdc).
   Tokens only — no hex, no invented radii, durations or shadows.
   Nothing here animates on an idle loop.
   ================================================================ */

/* shared chevron — the same door affordance as .spl-go, one physics */
.kd-go{flex:none;align-self:center;margin-left:2px;color:var(--ink-3);opacity:0;transform:translateX(-4px);transition:opacity var(--t-fast) ease,transform var(--t-fast) ease}
@keyframes kd-settle{0%{opacity:0;transform:translateY(-4px)}100%{opacity:1;transform:none}}
@keyframes kd-shake{0%,100%{transform:none}25%{transform:translateX(-4px)}60%{transform:translateX(3px)}85%{transform:translateX(-1px)}}

/* ================================================================
   1 · EVENT FEED  (.ef) — shift-grouped rows, the ribbon's marks
       in the gutter. No spine, no dots: the width goes to facts.
   ================================================================ */
/* which streams this feed speaks for — a partial feed must say so */
.ef-streams{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:0 2px 10px;border-bottom:1px solid var(--hairline-2);margin-bottom:4px}
.ef-str-l{font-size:10px;font-weight:650;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);margin-right:2px}
.ef-str{font-size:10.5px;font-weight:600;color:var(--ink-2);border:1px solid var(--hairline);border-radius:99px;padding:1.5px 9px;background:var(--surface);white-space:nowrap}
.ef-str.miss{color:var(--warn-ink);border:1.5px dashed color-mix(in srgb,var(--warn) 55%,var(--hairline));background:transparent;transition:border-color var(--t-fast) ease,transform var(--t-fast) var(--ease-spring)}
.ef-str.miss:hover{border-color:var(--warn);transform:translateY(-1px)}

/* group header — the shift, said once for every row under it */
.ef-gh{display:flex;align-items:baseline;gap:8px;padding:14px 2px 6px;border-bottom:1px solid var(--hairline)}
.ef-body>.ef-gh:first-child{padding-top:4px}
.ef-gh-l{font-size:10.5px;font-weight:650;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2)}
.ef-gh-n{font-size:10.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* a row: mono time · custody mark · the specific fact · evidence doors */
.ef-row{display:flex;align-items:flex-start;gap:11px;padding:8px 2px;border-bottom:1px solid var(--hairline-2);transition:background var(--t-fast) ease}
.ef-row:hover{background:var(--surface-2)}
.ef-row.open{cursor:pointer}
.ef-row.open:hover .ef-head,.ef-row.open:focus-visible .ef-head{color:var(--accent-ink)}
.ef-row.open:hover .kd-go,.ef-row.open:focus-visible .kd-go{opacity:1;transform:none;color:var(--accent-ink)}
.ef-time{flex:0 0 40px;font-family:var(--mono);font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums;padding-top:2px}
.ef-main{min-width:0;flex:1}
.ef-head{display:block;font-size:12.5px;font-weight:550;color:var(--ink);transition:color var(--t-fast) ease}
.ef-sub{display:block;font-size:11px;color:var(--ink-3);margin-top:1px}
/* rows settle in once (22ms stagger, capped), then hold still */
@keyframes ef-in{0%{opacity:0;transform:translateY(3px)}100%{opacity:1;transform:none}}
.ef-row,.ef-gh{animation:ef-in var(--t-med) var(--ease-out) both}

/* the gutter mark — the ribbon's three marks at feed scale, so the
   feed and the hero read as ONE fact at two zoom levels:
   solid confirmed · hatched provisional · open red-edged gap */
.ef-mk{flex:none;width:12px;height:14px;border-radius:3px;margin-top:2px;cursor:help;transition:transform var(--t-fast) var(--ease-spring)}
.ef-mk:hover{transform:scale(1.25)}
.ef-mk.ok{background:var(--lc-use)}
.ef-mk.prov{background:repeating-linear-gradient(45deg,var(--lc-use) 0 2.5px,color-mix(in srgb,var(--lc-use) 22%,var(--surface)) 2.5px 5px);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--lc-use) 55%,var(--surface))}
.ef-mk.gap{background:var(--lc-missing-bg);border-left:2px solid var(--lc-missing);border-right:2px solid var(--lc-missing);border-top:1.5px dashed var(--lc-missing);border-bottom:1.5px dashed var(--lc-missing);border-radius:1px}
.ef-mk.none{background:transparent;border:1.5px solid var(--hairline);border-radius:50%;width:9px;height:9px;margin-top:4px}

/* evidence — small kind icons that open; a door, not a decoration */
.ef-evs{display:flex;gap:2px;flex:none;align-self:center}
.ef-ev{width:24px;height:24px;border-radius:6px;display:grid;place-items:center;color:var(--ink-3);cursor:pointer;transition:background var(--t-fast) ease,color var(--t-fast) ease,transform var(--t-fast) var(--ease-spring)}
.ef-ev:hover,.ef-ev:focus-visible{background:var(--accent-bg);color:var(--accent-ink);transform:translateY(-1px)}
.ef-ev:active{transform:scale(.9)}

/* the tail at volume — one honest click, never an infinite scroll */
.ef-more{display:block;width:100%;margin-top:10px;padding:8px;border:1.5px dashed var(--hairline);border-radius:9px;font-size:12px;font-weight:550;color:var(--ink-2);cursor:pointer;font-variant-numeric:tabular-nums;transition:border-color var(--t-fast) ease,color var(--t-fast) ease,background var(--t-fast) ease}
.ef-more:hover{border-color:color-mix(in srgb,var(--ink) 30%,var(--hairline));color:var(--ink);background:var(--surface-2)}
.ef-more:active{transform:scale(.99)}

/* ================================================================
   2 · POSITION METER  (.pm) — a fixed notch, an honest fill.
       Over and under are different geometries, never different
       numbers. NOT ASSESSED hatches the track: no unearned verdict.
   ================================================================ */
.pm{position:relative;padding:2px 0 4px}
.pm.open{cursor:pointer;border-radius:8px;transition:background var(--t-fast) ease}
.pm.open:hover,.pm.open:focus-visible{background:var(--surface-2)}
.pm.open:hover .pm-lbl,.pm.open:focus-visible .pm-lbl{color:var(--accent-ink)}
.pm-top{display:flex;align-items:baseline;gap:8px 10px;flex-wrap:wrap;margin-bottom:8px}
/* the label may wrap the line, never crush into a one-word column */
.pm-lbl{flex:1 1 170px;min-width:0;font-size:12.5px;font-weight:600;color:var(--ink);transition:color var(--t-fast) ease}
.pm-subl{display:block;font-size:11px;font-weight:500;color:var(--ink-3);margin-top:1px}
.pm-read{font-variant-numeric:tabular-nums;white-space:nowrap}
.pm-read b{font-size:15px;font-weight:650;letter-spacing:-.01em}
.pm-read small{font-size:11px;color:var(--ink-3);margin-left:3px}
.pm-noread{font-size:15px;color:var(--ink-3)}
.pm-track{position:relative;height:10px;border-radius:5px;background:var(--viz-track)}
/* actual, drawn from the left — grows from zero on entry, once */
.pm-fill{position:absolute;top:0;bottom:0;left:0;border-radius:5px;background:var(--accent);transform:scaleX(0);transform-origin:left center;transition:transform .45s var(--ease-out)}
.pm-on .pm-fill{transform:scaleX(1)}
/* the beat: the segment past (or shy of) the notch arrives ~120ms
   AFTER the fill lands — the eye reads "…and then past" */
.pm-ext{position:absolute;top:0;bottom:0;transform:scaleX(0);transform-origin:left center;transition:transform .3s var(--ease-out)}
.pm-on .pm-ext{transform:scaleX(1)}
.pm-ext.past{background:var(--viz-mute);border-radius:0 5px 5px 0}
.pm-ext.past.worry{background:var(--warn)}
/* the span that never arrived / was paid for and sits idle: hatched */
.pm-ext.short{background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--viz-mute) 55%,transparent) 0 3px,transparent 3px 6px);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--viz-mute) 50%,transparent);border-radius:2px}
.pm-ext.short.worry{background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--warn) 60%,transparent) 0 3px,transparent 3px 6px);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--warn) 55%,transparent)}
/* expected — a fixed notch, not a percentage */
.pm-notch{position:absolute;top:-4px;bottom:-4px;width:2px;border-radius:2px;background:var(--ink);transform:translateX(-50%);z-index:2}
.pm-nl{position:relative;width:max-content;margin-top:5px;transform:translateX(-50%);font-family:var(--mono);font-size:10px;color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.pm-nl.pin-r{transform:translateX(-100%)}
.pm-nl.pin-l{transform:none}
/* the refused verdict — hatched track, stamped; normal, not a failure */
.pm-track.na{height:24px;border-radius:6px;display:grid;place-items:center;background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--viz-mute) 26%,transparent) 0 4px,transparent 4px 8px);border:1px dashed var(--hairline)}
.pm-stamp{background:var(--surface)}
.pm-why{margin-top:7px;font-size:11px;color:var(--ink-3);line-height:1.55;max-width:64ch}
.pm-acts{margin-top:9px}
.pm .chip{flex:none}

/* ================================================================
   3 · PERIOD  (.pd) — shift-shaped presets + a typed custom range,
       and the control PRINTS the window it actually resolved to.
   ================================================================ */
.pd{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap}
.pd-win{font-family:var(--mono);font-size:11px;color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.pd-win:empty::before{content:"no window chosen yet";font-family:var(--sans);color:var(--ink-3)}
.pd-win.in{animation:kd-settle var(--t-med) var(--ease-out)}
.pd-pop{max-width:392px}
.pd-pop .pop-sub{font-family:var(--mono);font-size:10px}
/* an unhonourable preset: disabled WITH its reason, in the row —
   it never silently serves a shorter window under a longer label */
.pd-dis{cursor:not-allowed;background:transparent}
.pd-dis:hover{background:transparent;color:var(--ink-2)}
.pd-dis .pop-name{color:var(--ink-3)}
.pd-why{display:block;font-size:10.5px;color:var(--warn-ink);margin-top:1px;white-space:normal;line-height:1.45}
.pd-div{height:1px;background:var(--hairline-2);margin:6px 4px}
.pd-custom{padding:2px 6px 8px}
.pd-dates{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.pd-dates .fld>label{font-size:10.5px}
.pd-dates .inp{width:100%;font-family:var(--mono);font-size:12px}
.pd-shift{display:flex;align-items:center;gap:9px;margin-top:9px}
.pd-sh-l{font-size:10.5px;font-weight:600;color:var(--ink-2)}
.pd-shift .seg button{padding:2.5px 9px;font-size:11px}
.pd-err{min-height:15px;margin-top:8px;font-size:11px;color:var(--warn-ink);line-height:1.5}
.pd-err.hot{animation:kd-shake .32s var(--ease-out)}
.pd-apply{display:flex;align-items:center;gap:9px;margin-top:4px}
.pd-preview{flex:1;min-width:0;font-family:var(--mono);font-size:10.5px;color:var(--ink-2);font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pd-preview:not(:empty){animation:kd-settle var(--t-fast) var(--ease-out)}
.pd-use{flex:none}
.pd-use.dis{opacity:.5;cursor:not-allowed}
.pd-use.dis:hover{background:var(--accent);border-color:var(--accent)}

/* ================================================================
   4 · FIELD  (.kf) — .fld/.inp from tokens.css, at last in use.
       A policy is not a preference: the consequence renders live,
       before the save.
   ================================================================ */
.kf>label{display:flex;align-items:center;gap:6px}
.kf-dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none}
.kf-lock{color:var(--ink-3);display:inline-flex}
.kf-ctl{display:flex;align-items:center;gap:9px}
.kf-in{position:relative;display:inline-flex;align-items:center}
.kf-in .inp{width:130px;font-variant-numeric:tabular-nums}
.kf-in .kf-unit{position:absolute;right:10px;font-size:11px;color:var(--ink-3);pointer-events:none}
.kf-in .kf-unit~.inp,.kf-in:has(.kf-unit) .inp{padding-right:8px}
/* a locked value is designed, not merely disabled */
.kf-in.locked .inp{border-style:dashed;background:var(--surface-2);color:var(--ink-2);cursor:not-allowed}
.kf-in.locked .inp:focus{box-shadow:none;border-color:var(--hairline)}
.kf-word{font-size:12px;color:var(--ink-2)}
/* provenance: who set this — or which default is quietly running */
.kf-prov{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--ink-3);line-height:1.5}
.kf-prov:empty,.kf-prov[hidden]{display:none}
.kf-prov-dirty{color:var(--ink-2);font-variant-numeric:tabular-nums}
.kf-unit-out{font-size:11px;color:var(--ink-3);line-height:1.4}
/* the consequence band — computed from the estate, settles in once.
   `hidden` must win over the explicit display below. */
.kf-eff[hidden]{display:none}
.kf-eff{--eff-c:var(--accent);display:flex;align-items:center;gap:8px;margin-top:2px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--eff-c) 30%,var(--hairline));border-left:3px solid var(--eff-c);border-radius:9px;background:color-mix(in srgb,var(--eff-c) 5%,var(--surface));font-size:12px;color:var(--ink-2);line-height:1.5}
.kf-eff.tone-warn{--eff-c:var(--warn)}
.kf-eff.tone-ok{--eff-c:var(--s-good)}
.kf-eff.tone-bad{--eff-c:var(--lc-missing)} /* earned only by missing/chain facts */
.kf-eff.in{animation:kd-settle var(--t-med) var(--ease-out)}
.kf-eff b{font-weight:650;color:var(--ink);font-variant-numeric:tabular-nums}
.kf-eff.open{cursor:pointer;transition:border-color var(--t-fast) ease,background var(--t-fast) ease}
.kf-eff.open:hover,.kf-eff.open:focus-visible{border-color:color-mix(in srgb,var(--eff-c) 55%,var(--hairline))}
.kf-eff.open:hover .kd-go,.kf-eff.open:focus-visible .kd-go{opacity:1;transform:none;color:var(--accent-ink)}
.kf-eff-b{flex:1;min-width:0}

/* ================================================================
   5 · SETTINGS  (.stg) — sections, one dirty ledger, one save bar.
       First-run is the normal state — said once, calmly.
   ================================================================ */
.stg{display:flex;flex-direction:column;gap:14px;position:relative}
.stg-first[hidden]{display:none}
.stg-first{display:flex;align-items:center;gap:10px;padding:11px 14px;border:1.5px dashed var(--hairline);border-radius:10px;font-size:12px;color:var(--ink-2);line-height:1.55}
.stg-sec{padding:18px 20px 20px}
.stg-h{display:flex;align-items:baseline;gap:10px;margin-bottom:14px}
.stg-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:18px 26px;align-items:start}
/* the save bar — arrives only when something changed, and an error
   keeps every typed value on screen */
.stg-bar[hidden]{display:none}
.stg-bar{position:sticky;bottom:14px;z-index:10;display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--surface);border:1px solid var(--hairline);border-radius:12px;box-shadow:0 12px 40px -10px rgba(var(--shadow-c),.25);opacity:0;transform:translateY(10px);transition:opacity var(--t-fast) ease,transform var(--t-med) var(--ease-spring)}
.stg-bar.on{opacity:1;transform:none}
.stg-bar.err-hit{animation:kd-shake .32s var(--ease-out)}
.stg-bar .sp{flex:1}
.stg-n{font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums}
.stg-err{font-size:11.5px;color:var(--lc-missing-ink);line-height:1.4}
.stg-err:empty{display:none}
.stg-save.busy{pointer-events:none;opacity:.7}

/* ================================================================
   6 · FEED CARD  (.fdc) — one feed, two angles. never-connected is
       first-run chrome; failing carries the same danger hairline as
       the failed state card, because it is the same fact.
   ================================================================ */
.fdc{position:relative;padding:14px 16px 13px;display:flex;flex-direction:column;gap:10px}
.fdc.click{cursor:pointer}
.fdc-head{display:flex;align-items:center;gap:10px}
.fdc-id{flex:1;min-width:0}
.fdc-id b{display:block;font-size:13px;font-weight:600;letter-spacing:-.008em}
.fdc-id span{display:block;font-size:11px;color:var(--ink-3);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* the status mark — solid core + static halo; nothing pulses */
.fdc-mk{flex:none;width:9px;height:9px;border-radius:50%}
.fdc[data-st="healthy"] .fdc-mk{background:var(--s-good);box-shadow:0 0 0 2.5px color-mix(in srgb,var(--s-good) 16%,transparent)}
.fdc[data-st="stale"] .fdc-mk,.fdc[data-st="degraded"] .fdc-mk{background:var(--warn);box-shadow:0 0 0 2.5px color-mix(in srgb,var(--warn) 20%,transparent)}
.fdc[data-st="failing"] .fdc-mk{background:var(--lc-missing);box-shadow:0 0 0 2.5px color-mix(in srgb,var(--lc-missing) 16%,transparent)}
.fdc[data-st="never"] .fdc-mk{background:transparent;border:1.5px dashed var(--accent-ink)}
.fdc[data-st="na"] .fdc-mk{background:transparent;border:1.5px solid var(--viz-mute)}
/* failing — the danger-tinted hairline, same mark as the failed card */
.fdc[data-st="failing"]::before{content:"";position:absolute;top:-1px;left:14px;right:14px;height:2px;border-radius:2px;background:color-mix(in srgb,var(--lc-missing) 68%,var(--surface))}
/* never-connected — first-run, forward-looking, never an error face */
.fdc[data-st="never"]{border-style:dashed}
.fdc[data-st="na"]{color:var(--ink-2)}
.fdc-body{display:flex;flex-direction:column;gap:8px}
.fdc-why{font-size:12px;color:var(--ink-2);line-height:1.6;max-width:52ch}
.fdc-note{font-size:11px;color:var(--ink-3);line-height:1.55}
.fdc-err{display:flex;flex-direction:column;gap:2px;padding:8px 11px;border:1px solid color-mix(in srgb,var(--danger) 40%,var(--hairline));border-left-width:3px;border-radius:8px;background:color-mix(in srgb,var(--danger) 5%,var(--surface))}
.fdc-err-t{font-family:var(--mono);font-size:10.5px;color:var(--lc-missing-ink);line-height:1.5}
.fdc-err-m{font-size:10.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
/* the foot wraps rather than crushing the owner behind the buttons */
.fdc-foot{display:flex;align-items:center;gap:9px;row-gap:9px;flex-wrap:wrap;padding-top:10px;border-top:1px solid var(--hairline-2);margin-top:auto}
.fdc-owner{display:flex;align-items:center;gap:8px;min-width:0;flex:1 1 150px}
.fdc-owner .u-av{width:22px;height:22px;font-size:9px;flex:none}
.fdc-owner-n{font-size:11.5px;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fdc-owner-w{font-size:10.5px;color:var(--ink-3);line-height:1.4}
.fdc-acts{margin-left:auto;display:flex;gap:6px;flex:none}
/* the spec list inside a card sits tighter than a full face */
.fdc .spl-row{padding:5.5px 8px}
.fdc .spl-l{flex-basis:112px}

@media (prefers-reduced-motion:reduce){
  .ef-row,.ef-gh{animation:none}
  .pm-fill,.pm-ext{transform:scaleX(1);transition:none}
  .pd-win.in,.kf-eff.in{animation:none}
}
