/* ================================================================
   Time Champ Quality Intelligence — quality.css
   Product-specific components layered on tokens.css (the kit) and
   core.css. Everything here is SHARED: every module builder uses these
   classes so nine parallel slices still read as one organism.
   Nothing in this file hardcodes a colour — tokens only.
   ================================================================ */

/* ---------- 404 / error surface ---------- */
.nf-wrap{max-width:520px;margin:16vh auto;text-align:center;padding:0 24px}
.nf-wrap h2{font-size:19px;font-weight:600;letter-spacing:-.012em;margin-top:14px}
.nf-wrap p{margin-top:9px;color:var(--ink-2);font-size:13.5px;line-height:1.6}
.nf-code{display:inline-block;font-family:var(--mono);font-size:11px;color:var(--ink-3);
  background:var(--surface-2);border:1px solid var(--hairline);border-radius:6px;padding:3px 9px}

/* ---------- rail foot: pinned assistant ---------- */
.sb-pinned{display:flex;flex-direction:column;gap:2px;padding:0 8px 8px;border-bottom:1px solid var(--hairline-2);margin-bottom:8px}
.sb-pinned .nav-it .ic-ai{color:var(--viz-ai)}
.sb-pinned .nav-it:hover .ic-ai{animation:aiTwinkle 900ms var(--ease-out)}
@keyframes aiTwinkle{0%{transform:scale(1) rotate(0)}45%{transform:scale(1.18) rotate(9deg)}100%{transform:scale(1) rotate(0)}}

/* ---------- page header ---------- */
.pg{max-width:1160px;margin:0 auto}
.pg-head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:18px}
.pg-title{font-size:24px;font-weight:600;letter-spacing:-.022em;line-height:1.2}
.pg-sub{margin-top:5px;color:var(--ink-2);font-size:13px;line-height:1.55;max-width:74ch}
.pg-acts{display:flex;align-items:center;gap:8px;flex:none}
.ovl{font-size:10.5px;font-weight:650;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3)}

/* ---------- verdict chips (the meaning contract, §6) ----------
   One hue per meaning, everywhere. Auto-fail is ALWAYS text-labelled as
   well as coloured — its hue sits close to "missed" by design (they are
   the same family of bad) and must never rely on colour alone. */
.vch{display:inline-flex;align-items:center;gap:5px;height:21px;padding:0 8px;border-radius:999px;
  font-size:11px;font-weight:600;letter-spacing:-.002em;white-space:nowrap;border:1px solid transparent;
  transition:transform var(--t-fast) var(--ease-spring),box-shadow var(--t-fast) var(--ease-out)}
.vch svg{width:11px;height:11px;flex:none}
.vch.lg{height:25px;padding:0 11px;font-size:12px}
.v-asked   {color:var(--viz-asked);   background:var(--viz-asked-bg);   border-color:color-mix(in srgb,var(--viz-asked) 22%,transparent)}
.v-partial {color:var(--viz-partial); background:var(--viz-partial-bg); border-color:color-mix(in srgb,var(--viz-partial) 24%,transparent)}
.v-missed  {color:var(--viz-missed);  background:var(--viz-missed-bg);  border-color:color-mix(in srgb,var(--viz-missed) 24%,transparent)}
.v-autofail{color:#fff;background:var(--viz-autofail);border-color:var(--viz-autofail)}
.v-ai      {color:var(--viz-ai);      background:var(--viz-ai-bg);      border-color:color-mix(in srgb,var(--viz-ai) 22%,transparent)}
.v-human   {color:var(--viz-human);   background:var(--viz-human-bg);   border-color:color-mix(in srgb,var(--viz-human) 22%,transparent)}
.v-dispute {color:var(--viz-dispute); background:var(--viz-dispute-bg); border-color:color-mix(in srgb,var(--viz-dispute) 22%,transparent)}
.v-coach   {color:var(--viz-coach);   background:var(--viz-coach-bg);   border-color:color-mix(in srgb,var(--viz-coach) 22%,transparent)}
.v-mute    {color:var(--ink-3);       background:var(--surface-2);      border-color:var(--hairline)}
button.vch,a.vch{cursor:pointer}
button.vch:hover,a.vch:hover{transform:translateY(-1px);box-shadow:0 4px 12px -6px rgba(var(--shadow-c),.28)}
button.vch:active{transform:scale(.965)}

/* legend row */
.vleg{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.vleg .vl{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--ink-2)}
.vleg .vd{width:9px;height:9px;border-radius:3px;flex:none}

/* ---------- score numeral + ring ---------- */
.scorev{font-size:30px;font-weight:350;letter-spacing:-.02em;line-height:1;font-variant-numeric:tabular-nums}
.scorev.sm{font-size:21px}
.scorev .su{font-size:13px;color:var(--ink-3);margin-left:2px;font-weight:400}
/* inline-GRID, not inline. Two things break on a bare `display:inline` span:
   width/height simply do not apply to a non-replaced inline box, and WebKit
   collapses the containing block of a relatively-positioned inline to zero
   width — so `.cap{position:absolute;inset:0}` centred the numeral on a
   zero-width strip at the ring's LEFT EDGE and it hung outside the circle in
   Safari (Chrome happened to get it right). Stacking the svg and the cap in
   one grid cell needs no positioning at all, so every engine agrees.
   The svg fills the box rather than hardcoding 58px, so the `size` argument
   sringHTML() was called with is the size actually drawn — a size:62 ring was
   being squeezed into 58px, shrinking its 5px stroke to 4.7. */
.sring{position:relative;display:inline-grid;place-items:center;vertical-align:middle;
  width:58px;height:58px;flex:none}
.sring svg{grid-area:1/1;display:block;transform:rotate(-90deg);width:100%;height:100%}
.sring .trk{stroke:var(--viz-track)}
.sring .val{stroke-linecap:round;transition:stroke-dashoffset 1.1s var(--ease-out)}
.sring .cap{grid-area:1/1;font-size:15px;font-weight:500;
  letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.sring.pass .val{stroke:var(--viz-asked)} .sring.warnq .val{stroke:var(--viz-partial)}
.sring.fail .val{stroke:var(--viz-missed)} .sring.aiq .val{stroke:var(--viz-ai)}

/* ---------- meter ----------
   `display:block` is load-bearing, not tidiness. An inline box ignores
   `height`, so the moment a module put this class on a <span> the meter
   silently rendered at zero height — a whole column of drift bars that
   simply were not there, under a subtitle promising "zero is the centre
   line". Declared here so the class works on whatever element it lands on. */
.qmeter{display:block;height:6px;border-radius:999px;background:var(--viz-track);overflow:hidden}
.qmeter i,.qmeter span,.qmeter b{display:block;height:100%;border-radius:999px;background:var(--accent);
  width:0;transition:width 1s var(--ease-out)}
.qmeter.good i{background:var(--viz-asked)} .qmeter.warnq i{background:var(--viz-partial)}
.qmeter.bad i{background:var(--viz-missed)} .qmeter.coachq i{background:var(--viz-coach)}

/* ---------- transcript ---------- */
.tx{display:flex;flex-direction:column;gap:2px}
.tx-turn{display:grid;grid-template-columns:46px 78px 1fr;gap:10px;padding:7px 10px;border-radius:8px;
  align-items:start;cursor:pointer;position:relative;
  transition:background var(--t-fast) var(--ease-out),transform var(--t-fast) var(--ease-out)}
.tx-turn:hover{background:var(--surface-2);transform:translateX(2px)}
.tx-turn .tt{font-family:var(--mono);font-size:10px;color:var(--ink-3);padding-top:2px;font-variant-numeric:tabular-nums}
.tx-turn .tw{font-size:11px;font-weight:650;letter-spacing:.02em;text-transform:uppercase;padding-top:2px}
.tx-turn.agent .tw{color:var(--viz-human)} .tx-turn.payer .tw{color:var(--ink-2)}
.tx-turn.ivr .tw{color:var(--ink-3)} .tx-turn.ivr .tb{color:var(--ink-3);font-style:italic}
.tx-turn .tb{font-size:13px;line-height:1.55;color:var(--ink)}
.tx-turn.hit{background:var(--viz-asked-bg)}
.tx-turn.hit::before{content:"";position:absolute;left:0;top:6px;bottom:6px;width:2.5px;border-radius:2px;background:var(--viz-asked)}
.tx-turn.flash{animation:txFlash 1.5s var(--ease-out)}
@keyframes txFlash{0%{background:var(--accent-bg)}55%{background:var(--accent-bg)}100%{background:transparent}}
.tx-turn mark{background:color-mix(in srgb,var(--viz-partial) 30%,transparent);color:inherit;border-radius:3px;padding:0 2px}

/* ---------- checklist ---------- */
.ckq{display:flex;flex-direction:column;gap:6px}
.ckq-it{display:grid;grid-template-columns:22px 1fr auto;gap:10px;align-items:start;padding:9px 11px;
  border:1px solid var(--hairline);border-radius:var(--r-ctl);background:var(--surface);cursor:pointer;
  transition:border-color var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out),transform var(--t-fast) var(--ease-out)}
.ckq-it:hover{border-color:color-mix(in srgb,var(--ink) 16%,var(--hairline));box-shadow:0 5px 16px -10px rgba(var(--shadow-c),.3);transform:translateY(-1px)}
.ckq-it .qmk{width:20px;height:20px;border-radius:6px;display:grid;place-items:center;flex:none;margin-top:1px}
.ckq-it .qmk svg{width:12px;height:12px;stroke-width:2.4}
.ckq-it.asked   .qmk{background:var(--viz-asked-bg);color:var(--viz-asked)}
.ckq-it.partial .qmk{background:var(--viz-partial-bg);color:var(--viz-partial)}
.ckq-it.missed  .qmk{background:var(--viz-missed-bg);color:var(--viz-missed)}
.ckq-it.missed{border-color:color-mix(in srgb,var(--viz-missed) 26%,var(--hairline))}
.ckq-it .qtx{font-size:13px;line-height:1.5}
.ckq-it .qmeta{margin-top:3px;font-size:11px;color:var(--ink-3);display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.ckq-it .qgo{opacity:0;transform:translateX(-3px);transition:all var(--t-fast) var(--ease-out);color:var(--ink-3)}
.ckq-it:hover .qgo{opacity:1;transform:translateX(0)}
/* the tick draws itself when the item enters */
.ckq-it.asked .qmk svg path{stroke-dasharray:22;stroke-dashoffset:22;animation:drawTick .5s var(--ease-out) forwards}
@keyframes drawTick{to{stroke-dashoffset:0}}

/* ---------- kit class collisions ----------
   tokens.css sizes form controls with `.inp,.sel{height:32px}`. Those are
   very generic names, and module builders reasonably used `sel` as a
   "selected" state class and `.inp` on a textarea. Two real consequences,
   both on the hero screen: clicking a checklist question collapsed the card
   to 32px — slicing its own text and hiding the verbs for the very item you
   just clicked — and the override drawer's "reason (goes into the audit
   log)" textarea rendered one line tall, clipping its placeholder mid-word.

   Fixed here rather than in each module: these are the kit's names, the
   collision will recur, and quality.css loads after tokens.css with higher
   specificity. */
.ckq-it.sel, .ckq-it.is-sel { height: auto; }
textarea.inp { height: auto; min-height: 72px; padding: 9px 11px; line-height: 1.5; resize: vertical; }

/* ---------- sticky table headers ----------
   Every long table in the product scrolls under the topbar; without this the
   columns are gone by row eight of a fifty-row page. Applied once here so no
   module has to remember it. */
.tbl thead th, table.tbl thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); }
.tbl thead th::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--hairline); }

/* ---------- waveform scrubber ---------- */
.wavebar{display:flex;align-items:flex-end;gap:1.5px;height:38px;cursor:pointer;padding:0 1px}
.wavebar i{flex:1;background:var(--viz-track);border-radius:1.5px;min-height:2px;
  transition:background var(--t-fast) var(--ease-out),transform var(--t-fast) var(--ease-out);transform-origin:bottom}
.wavebar i.on{background:var(--viz-human)}
.wavebar i.mk{background:var(--viz-asked)}
.wavebar i.mkx{background:var(--viz-missed)}
.wavebar:hover i{transform:scaleY(1.06)}

/* ---------- stat strip ---------- */
.strip{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--hairline);border-radius:var(--r-card);
  background:var(--surface);overflow:hidden}
.strip .si{flex:1 1 0;min-width:132px;padding:13px 16px;border-right:1px solid var(--hairline-2);
  transition:background var(--t-fast) var(--ease-out)}
.strip .si:last-child{border-right:0}
.strip .si:hover{background:var(--surface-2)}
.strip .si .sl{font-size:10.5px;font-weight:650;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3)}
.strip .si .sv{margin-top:6px;font-size:24px;font-weight:350;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.strip .si .sf{margin-top:3px;font-size:11.5px;color:var(--ink-3)}

/* ---------- comment / feedback thread ---------- */
.thr{display:flex;flex-direction:column;gap:12px}
.thr-it{display:grid;grid-template-columns:26px 1fr;gap:10px}
.thr-it .u-av{width:26px;height:26px;font-size:10px}
.thr-b{background:var(--surface-2);border:1px solid var(--hairline-2);border-radius:10px;padding:9px 12px}
.thr-b .th{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.thr-b .th b{font-size:12.5px;font-weight:600}
.thr-b .th span{font-size:11px;color:var(--ink-3)}
.thr-b p{margin-top:4px;font-size:13px;line-height:1.55;color:var(--ink-2)}
.thr-re{margin-left:36px}

/* ---------- agent identity row ---------- */
.who{display:inline-flex;align-items:center;gap:8px;min-width:0}
.who .u-av{width:24px;height:24px;font-size:9.5px;flex:none}
.who .wn{font-size:12.5px;font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who .ws{font-size:11px;color:var(--ink-3)}

/* ---------- section shell used by every module ---------- */
.qsec{margin-top:22px}
.qsec-h{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin-bottom:10px}
.qsec-t{font-size:15px;font-weight:600;letter-spacing:-.012em}
.qsec-s{font-size:12px;color:var(--ink-3)}

/* ---------- at-scale helpers ---------- */
.scrolly{max-height:520px;overflow:auto;border-radius:var(--r-ctl)}
.scrolly thead th{position:sticky;top:0;z-index:2;background:var(--surface);
  box-shadow:0 1px 0 var(--hairline)}
.rowcount{font-size:11.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* ---------- watch-only policy note (client persona) ---------- */
.policy{display:flex;align-items:center;gap:8px;padding:8px 12px;border:1px solid var(--hairline);
  border-radius:var(--r-ctl);background:var(--surface-2);font-size:12px;color:var(--ink-2)}
.policy svg{width:14px;height:14px;color:var(--ink-3);flex:none}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  .tx-turn,.ckq-it,.vch,.strip .si,.qmeter i,.sring .val{transition:none!important;animation:none!important}
  .ckq-it.asked .qmk svg path{stroke-dashoffset:0}
}
