/* Vinx Call Intelligence — design system.
   Brand values taken from vinxpestcontrol.com. Brand dresses the chrome; it
   never encodes a number. The data palette below is validated separately for
   lightness band, chroma, colourblind separation and contrast in both themes,
   and does not change when the brand does. */

:root{
  --vinx-teal:#194342; --vinx-teal-deep:#0F2A29;
  --vinx-green:#3AB54B; --vinx-green-ink:#1F7C34; --vinx-gold:#F5A623;

  --paper:#F1F3F1; --surface:#fff; --surface-2:#FAFBFA; --surface-3:#EDF0EE;
  /* SECONDARY TEXT THAT CAN ACTUALLY BE READ — 5 Oct 2026.
     Measured every text node on seven pages against the surface behind it:
     63 distinct selectors came in under 4.5:1, and nearly all of them traced
     to these two tokens rather than to any one rule. --muted carried most of
     the explanatory writing on the app at 3.64:1 and --faint carried dates and
     counts at 2.12:1. Both moved the smallest distance that clears 4.5 on all
     four light surfaces, hue held, and the three steps are kept apart so the
     hierarchy still reads: 7.1 / 5.4 / 4.5. */
  --ink:#241F20; --ink-2:#4A514D; --muted:#5C635F; --faint:#666F69;
  --rule:#E4E7E4; --rule-strong:#C9D0CB;
  --accent:#1F7C34; --accent-soft:#EAF6EC; --accent-2:#3AB54B;

  --cat-1:#2C6FB5; --cat-2:#C4562A; --cat-3:#8B5FBF;
  --cat-4:#4E9C3F; --cat-5:#B52E8E; --cat-6:#8A7412;
  --good:#1E7A54; --mid:#647069; --bad:#B02418;
  /* Amber as TEXT, which --vinx-gold cannot be: #F5A623 on its own soft
     background is 1.83:1. The fill colour stays what it was. */
  --gold-ink:#9B6307;
  /* Chart marks. Grey was doing two jobs at once — "the middle outcome" and
     "no data" — so a bar showing 0% overcame looked exactly like a rung nobody
     had measured. The middle now has a colour of its own.
     Validated together against this surface (adjacent CVD ΔE 12.6 protan,
     normal-vision 21.8, all three clear 3:1): see the palette check in the
     commit that introduced them. Do not nudge these by eye. */
  --st-good:#1E7A54; --st-mid:#C08A1E; --st-bad:#B02418;
  --track:#EDF0EE;
  --good-soft:#E3F1EA; --mid-soft:#EDF0EE; --bad-soft:#F9E7E4; --gold-soft:#FDF2DF;
  --seq-1:#D8E4F2; --seq-3:#6F9CD0; --seq-5:#2C6FB5; --seq-6:#1E4E80;

  --shadow:0 1px 2px rgba(25,67,66,.06),0 10px 28px -20px rgba(25,67,66,.35);
  --radius:11px;
}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){
  --vinx-teal:#0C1F1E; --vinx-teal-deep:#081716;
  --vinx-green:#4FCB60; --vinx-green-ink:#5FD070; --vinx-gold:#EDB65A;
  --paper:#0B1312; --surface:#131F1D; --surface-2:#182724; --surface-3:#21322E;
  --ink:#E9EFEA; --ink-2:#C2CBC6; --muted:#A8B2AC; --faint:#8E9892;
  --rule:#25332F; --rule-strong:#394A45;
  --accent:#5FD070; --accent-soft:#12281A; --accent-2:#4FCB60;
  --cat-1:#4A88CC; --cat-2:#CE7346; --cat-3:#A277CE;
  --cat-4:#5FA84E; --cat-5:#CE4E9E; --cat-6:#A8892A;
  /* The red moved from #CC4F42 to clear 4.5:1 on the dark surfaces and on its
     own soft chip; it was 3.52:1, so error text and "lost" labels were the
     least readable thing on the page in dark mode. --st-bad below is the chart
     red and is left alone: it is validated for colour-vision separation
     against the amber beside it, and that is a different job. */
  --good:#2E9E71; --mid:#8D9891; --bad:#D46C61;
  --gold-ink:#EDB65A;
  /* Dark is chosen, not flipped: its own steps, validated against the dark
     surface. The red moves off --bad because amber and #CC4F42 sit too close
     together down here (normal-vision ΔE 13.5, below the floor of 15). */
  --st-good:#2E9E71; --st-mid:#C08A1E; --st-bad:#D8453A;
  --track:#21322E;
  --good-soft:#122A20; --mid-soft:#1D2521; --bad-soft:#2C1714; --gold-soft:#2A2112;
  --seq-1:#1B2B3C; --seq-3:#31648E; --seq-5:#4A88CC; --seq-6:#7DAEE0;
  --shadow:0 1px 2px rgba(0,0,0,.5),0 10px 28px -20px rgba(0,0,0,.85);
}}

/* FOUR NAMES THAT WERE NEVER DEFINED — 5 Oct 2026.
   --line, --card, --hover and --sunk are used eleven times between them, every
   one without a fallback, and none of them was ever declared. A var() with no
   fallback that resolves to nothing does not fall back to something sensible:
   the whole declaration is thrown away. So the dividing lines between the six
   steps, the background and border on every pick button, the row hover on the
   data tables and the highlight on the transcript line you just clicked were
   all simply not being drawn.
   Aliases rather than new colours, so dark mode keeps working on its own: these
   resolve against :root, and :root is where the dark block redefines the tokens
   underneath them. */
:root{
  --line:var(--rule);
  --card:var(--surface);
  --hover:var(--surface-3);
  --sunk:var(--accent-soft);
}
*{box-sizing:border-box}
/* <s> IS A LABEL HERE, NOT A STRIKETHROUGH — 5 Oct 2026.
   Thirty-two places in the page scripts use <s> for the small secondary line
   beside a heading or a number, and text-decoration:none was being reapplied
   per selector, twenty-odd times. Every selector somebody forgot rendered the
   label struck through: the rubric name beside "The six steps", the rep and
   duration under the caller on the calibration player, and others. One rule,
   once, instead of remembering every time. */
s{text-decoration:none}
/* Nothing in this app showed a focus ring. Reps share machines and a manager
   tabbing through the calibration form had no way to see where they were. */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:5px}
.topbar :focus-visible{outline-color:var(--vinx-green);outline-offset:1px}
body{margin:0;background:var(--paper);color:var(--ink);font-size:14px;line-height:1.5;
  font-family:Poppins,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4,th,.lbl,.brandname{font-family:Oswald,"Arial Narrow",Arial,sans-serif;font-weight:600}
.mono,.n{font-family:"IBM Plex Mono",ui-monospace,Menlo,monospace;font-variant-numeric:tabular-nums}
a{color:var(--accent)}

/* chrome */
.topbar{background:var(--vinx-teal);color:#EAF2EC;position:sticky;top:0;z-index:40}
.topbar-in{max-width:1320px;margin:0 auto;padding:10px 22px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.logo{display:flex;align-items:center;gap:13px;text-decoration:none;color:inherit}
/* The real mark. Sized by height so the wordmark's cap height lines up with
   the product name beside it, and never stretched. */
.logo img{height:26px;width:auto;display:block;flex:0 0 auto}
/* Separates the brand from the product name, the way the other Vinx tools do. */
.logo .brandname{padding-left:13px;border-left:1px solid rgba(255,255,255,.22);
  font-size:14px;letter-spacing:.01em;color:#fff;white-space:nowrap}
nav.tabs{display:flex;gap:2px;margin-left:auto}
nav.tabs a{color:#B9CCC0;text-decoration:none;font-size:13px;padding:6px 11px;border-radius:7px;
  font-family:Oswald,sans-serif;font-weight:500}
nav.tabs a:hover{background:rgba(255,255,255,.08);color:#fff}
nav.tabs a[aria-current]{background:var(--vinx-green);color:#0C2118;font-weight:600}
/* A held team has no views of its own yet. Saying so where the tabs were is
   quieter than four links that would all take you back to sales. */
.tabnote{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:#7E9689;padding:6px 2px;white-space:nowrap}
.who{font-size:11.5px;color:rgba(255,255,255,.55);padding-left:14px;
  border-left:1px solid rgba(255,255,255,.16)}
/* Sign out. Quiet on purpose — it sits beside the name, not in the tab row:
   it is not a place to go, it is a way to leave. Reps share machines and the
   session cookie lasts a fortnight, so it has to be findable without being
   something anyone clicks by accident on the way to Calls. */
.signout{font-size:11px;letter-spacing:.05em;font-weight:500;
  color:rgba(255,255,255,.5);background:transparent;border:0;cursor:pointer;
  padding:4px 8px;margin-left:10px;border-radius:6px;text-transform:uppercase}
.signout:hover:not(:disabled){color:#fff;background:rgba(255,255,255,.12)}
.signout:disabled{cursor:default;opacity:.6}
/* It follows the name, so when the name is hidden this has nothing to sit
   beside — but it must NOT disappear with it: a phone is exactly where
   somebody hands a device over. It keeps its own left border instead. */
/* Superseded by the phone block further down, which puts the tabs on their
   own scrolling row and sends Sign out back up beside the mark. */
.seg{display:flex;background:rgba(255,255,255,.1);border-radius:8px;padding:2px;gap:2px}
.seg button{font:inherit;font-family:Oswald,sans-serif;font-size:12.5px;border:0;background:transparent;
  color:rgba(255,255,255,.7);padding:6px 11px;border-radius:6px;cursor:pointer}
.seg button[aria-pressed=true]{background:var(--vinx-green);color:#0C2118;font-weight:600}

/* The period picker sits on the light page, not on the teal bar. It inherited
   the bar's palette — white text on a 10%-white ground — so on paper every
   unselected period was invisible and the control looked like a single green
   button. That is what "the filters only are for last week" was describing:
   the other six were there and could not be seen. */
.seg.periods{background:var(--surface);border:1px solid var(--rule);box-shadow:var(--shadow);
  flex-wrap:wrap;justify-content:flex-end}
.seg.periods button{color:var(--ink-2);white-space:nowrap}
.seg.periods button:hover{background:var(--surface-3);color:var(--ink)}
.seg.periods button[aria-pressed=true]{background:var(--accent);color:#fff}
.seg.periods button[aria-pressed=true]:hover{background:var(--accent)}

.wrap{max-width:1320px;margin:0 auto;padding:0 22px 70px}
/* Headline left, period picker right, and the picker drops below the headline
   rather than across it when there is not room for both. It was overlapping
   the h1 before, which is how it came to look like part of the sentence. */
.head{padding:34px 0 6px;display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:16px 28px;align-items:start}
.head .headmain{min-width:0}
.head .headctl{justify-self:end}
/* `1fr` is not `minmax(0,1fr)`: a grid column defaults to a min-content floor,
   so the period switcher — one non-wrapping row, 481px of it — held the whole
   header open at 481px inside a 390px phone and cut the headline off at
   "averaging 49". Measured, not spotted: every page's scrollWidth was wider
   than its viewport. */
@media(max-width:760px){.head{grid-template-columns:minmax(0,1fr)}
  .head .headctl{justify-self:stretch;min-width:0;max-width:100%}
  .seg.periods{justify-content:flex-start}}
.head h1{font-size:clamp(20px,2.5vw,26px);letter-spacing:-.01em;line-height:1.25;margin:0;max-width:820px}
.head h1 .up{color:var(--good)} .head h1 .dn{color:var(--bad)}
.head .sub{color:var(--muted);font-size:12.5px;margin-top:10px;font-variant-numeric:tabular-nums}
/* The supporting sentence under the headline. Prose, not mono: it is a
   finding, and the mono row below it is the window and the counts. */
.head .also{font-size:14px;line-height:1.5;color:var(--ink-2);margin:9px 0 0;max-width:760px}
.head .also:empty{display:none}

h2.sec{font-size:17px;margin:36px 0 6px;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
/* The subtitle explains the section, so it is set to be read rather than
   squinted at: the same face as the prose around it, one step down. */
h2.sec span{font-family:inherit;font-size:12.5px;font-weight:400;color:var(--muted);letter-spacing:0}
h2.sec b{font-weight:inherit;font-family:inherit}
p.secsub{color:var(--muted);font-size:12.5px;margin:0 0 13px;max-width:660px}

/* primitives */
.card{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);box-shadow:var(--shadow)}
/* Eight cards on an auto-fit grid became seven across and one orphan on its
   own row, so this was pinned to four columns. Five cards then orphaned the
   fifth instead: one tile alone against three tiles' width of nothing, which
   is the first thing you see on the page.
   A wrapping row rather than a fixed grid. The last line stretches to fill, so
   any count from three to eight lands balanced, and the basis keeps a card wide
   enough for the sentence underneath the number. */
.kpis{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
.kpis>*{flex:1 1 215px;min-width:0}
@media(max-width:430px){.kpis>*{flex-basis:100%}}
.kpi{padding:14px 15px 12px}
.kpi .lbl{font-size:12px;color:var(--muted);font-weight:500}
.kpi .val{font-family:Oswald,sans-serif;font-size:34px;font-weight:600;letter-spacing:-.01em;margin-top:4px;line-height:1}
.kpi .blank{font-family:"IBM Plex Mono",monospace;font-size:19px;color:var(--faint);margin-top:7px}
.kpi .why{font-size:10.5px;color:var(--muted);line-height:1.35;margin-top:5px}
.kpi.hero{background:var(--accent-soft);border-color:var(--vinx-green)}
/* Not a tile. A tile promises a number, and four tiles promising numbers that
   are all em-dashes is a headline row that says nothing at length. */
.waiting{margin-top:10px;padding:9px 14px;border:1px dashed var(--rule-strong);border-radius:8px;
  background:var(--surface-2);color:var(--muted);font-size:12px;line-height:1.5}
.waiting b{color:var(--ink-2);font-weight:600}
.kpi.hero .lbl{color:var(--accent)}

.ladder{padding:18px 20px 14px}
.lrow{display:grid;grid-template-columns:238px minmax(0,1fr) 92px;gap:16px;align-items:center;padding:10px 0}
/* On a phone the three columns left the bar no width at all, so the reason a
   rung was unanswered vanished entirely. Name and figure share the first row;
   the bar takes the full width beneath them. */
@media(max-width:700px){
  .lrow{grid-template-columns:minmax(0,1fr) auto;gap:4px 12px;padding:9px 0}
  .lrow .nm{grid-row:1} .lrow .rt{grid-row:1;text-align:right}
  .lrow .track{grid-column:1/-1;grid-row:2}
  .lrow .rt s{display:inline;margin-left:6px}
  .lrow.pending .rt s{display:none}
}
.lrow .nm{font-size:12.5px;font-weight:500;display:flex;flex-direction:column;align-items:flex-start;gap:2px}
/* The stage name, then what it means in the words a person would use. The
   old "rung 0" beside it was this codebase's vocabulary on a page for a
   sales manager, and it named an order the layout already showed. */
.lrow .nm em{font-style:normal;font-size:11px;color:var(--muted);font-weight:400;line-height:1.3}
.lrow .nm i{width:6px;height:6px;border-radius:50%;flex:none}
.lrow .nm{flex-direction:column;align-items:flex-start;gap:2px}
.lrow .nm em{font-style:normal;font-size:11px;color:var(--muted);font-weight:400;line-height:1.3}
.track{height:10px;background:var(--track);border-radius:5px;overflow:hidden}
/* An unanswered rung. Hatched rather than solid, so at a glance it reads as an
   empty slot rather than as a bar that happens to be grey. */
.track.unknown{background:repeating-linear-gradient(135deg,
  var(--surface-3) 0 6px, var(--surface-2) 6px 12px);border:1px dashed var(--rule-strong)}
/* display:block matters: .fill is a <span>, and height:100% on an inline box
   does nothing at all — every bar in the outcome ladder was rendering at zero
   by zero pixels, which looked exactly like an empty track. */
/* Square at the baseline, 4px rounded at the data end — the end is the value,
   so it is the end that gets the shape. */
.fill{display:block;height:100%;border-radius:0 4px 4px 0;
  transition:width .5s cubic-bezier(.4,0,.2,1)}
.fill[style*="width:100"],.fill[style*="width: 100"]{border-radius:5px}
.lrow .rt{text-align:right;font-family:"IBM Plex Mono",monospace;font-size:14px;font-weight:600;
  font-variant-numeric:tabular-nums}
.lrow .rt s{text-decoration:none;color:var(--muted);font-weight:400;font-size:11px;display:block;
  font-variant-numeric:tabular-nums}
.lrow.pending .nm,.lrow.pending .rt{color:var(--faint)}
/* The reason a rung is unanswered, set inside its empty bar. One line, so an
   unmeasured rung is not the tallest row on the page. */
/* How far a number can be trusted, set under the number itself rather than in
   a footnote. Objective metrics carry no pill — the absence is the signal.
   Named .trust, not .tier: the System page already had a .tier of its own for
   the confidence table, and the collision was setting that whole table in
   uppercase. A shared stylesheet needs names that say which thing they mean. */
.trust{margin-top:7px;display:inline-block;font-family:"IBM Plex Mono",monospace;font-size:9.5px;
  letter-spacing:.07em;text-transform:uppercase;padding:2px 6px;border-radius:4px;cursor:help}
.t-calibrated{background:var(--gold-soft);color:var(--gold-ink)}
.t-provisional{background:var(--surface-3);color:var(--muted)}
.tnote{display:block;line-height:18px;padding:0 9px;font-size:10.5px;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ldrfoot{margin-top:12px;padding-top:12px;border-top:1px solid var(--rule);font-size:12px;color:var(--muted);line-height:1.55}
.ldrfoot b{color:var(--bad)}

table{border-collapse:collapse;width:100%;min-width:840px}
.scroll{overflow-x:auto}
th{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);text-align:right;
  padding:12px;border-bottom:1px solid var(--rule-strong);white-space:nowrap;background:var(--surface-2);cursor:pointer}
th:first-child,td:first-child{text-align:left;padding-left:18px}
/* Words left, figures right. Opt-in per column rather than per cell, so a
   header and its cells cannot drift apart. */
th.l,td.l{text-align:left}
/* A wide table on a phone scrolls inside its own card. The fade says so —
   without it the cut-off column just looks like a broken table. */
.scroll{position:relative}
.scroll::after{content:"";position:absolute;top:0;right:0;bottom:0;width:34px;pointer-events:none;
  background:linear-gradient(to right,transparent,var(--surface));border-radius:0 var(--radius) var(--radius) 0}
@media(hover:hover){.scroll::after{display:none}}
/* A TABLE IS MOSTLY WORDS — 5 Oct 2026.
   Every cell in the app was set in IBM Plex Mono, so the call log rendered rep
   names, customer names, "outbound" and "not graded" on a typewriter. Mono
   earns its place on things you compare character by character — a duration, a
   score, an id — and costs legibility everywhere else, which is most of a
   table. The body face carries tabular figures of its own, so the columns of
   numbers stay in their columns; td.num and .mono opt back in where the
   character grid is the point. */
td{padding:9px 12px;border-bottom:1px solid var(--rule);text-align:right;
  font-size:13px;font-variant-numeric:tabular-nums;color:var(--ink-2)}
tbody tr{cursor:pointer} tbody tr:hover td{background:var(--surface-3)}
tbody tr:last-child td{border-bottom:0}
td.who2{font-family:Oswald,sans-serif;font-weight:600;font-size:13px;color:var(--ink);white-space:nowrap}
td.who2 em{font-style:normal;display:block;font-size:10.5px;color:var(--faint);font-weight:400}
.gap.big{color:var(--bad);font-weight:600} .gap.mid{color:var(--gold-ink);font-weight:600} .gap.ok{color:var(--muted)}
/* A 44px track at 5px tall could not separate 33 from 38, so the bar was
   decoration and the number did all the work. Wider, thicker, on a shared
   0-100 scale, with the value at the tip where a bar's value belongs. */
.meter{display:inline-flex;align-items:center;gap:9px;justify-content:flex-end}
.meter .bar{width:84px;height:8px;border-radius:4px;background:var(--track);overflow:hidden;flex:none}
.meter .bar i{display:block;height:100%;border-radius:0 4px 4px 0}
.meter b{font-family:"IBM Plex Mono",monospace;font-weight:600;font-variant-numeric:tabular-nums;
  min-width:2.2ch;text-align:right}
.pill{display:inline-block;font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.06em;
  text-transform:uppercase;font-weight:600;padding:3px 7px;border-radius:4px}
.p-ok{background:var(--good-soft);color:var(--good)} .p-warn{background:var(--gold-soft);color:var(--gold-ink)}
.p-bad{background:var(--bad-soft);color:var(--bad)} .p-thin{background:var(--surface-3);color:var(--muted)}

/* second look */
.slq{display:flex;flex-direction:column;gap:9px}
/* One column of reading, one strip of doing. The card was three columns: a
   42px gutter holding a single digit, the body, and a 186px rail carrying a
   price, a chip, a button and then a hand's width of nothing. Both side
   columns are gone — the rank sits with the name it ranks, and every control
   is in the footer strip that already spanned the card. */
.slc{overflow:hidden;border-left:3px solid var(--bad)}
.slc.rep{border-left-color:var(--gold-ink)}
.slbody{padding:14px 17px}
.sltop{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.slrank{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;color:var(--muted);
  background:var(--surface-2);border:1px solid var(--rule);border-radius:4px;
  min-width:19px;padding:1px 4px;text-align:center;align-self:center}
.slname{font-family:Oswald,sans-serif;font-size:15px;font-weight:600}
/* The card carried two names with nothing to say which was which — and on a
   caller with no name on file, the only name shown was the rep's, sitting
   exactly where you read the customer. The possessive does the whole job. */
.slwho{font-size:11.5px;color:var(--muted)}
.slage{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;margin-left:auto;color:var(--muted)}
.slwhy{font-size:13px;line-height:1.55;color:var(--ink-2);margin:0 0 9px}
.slchips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
/* Words, not column names, and not shouted. A defect is marked by one red
   pip; five solid red boxes made the least actionable part of the card the
   loudest thing on it. */
.slchip{font-size:11px;font-weight:500;padding:3px 8px 3px 7px;border-radius:4px;
  background:var(--surface-2);color:var(--ink-2);border:1px solid var(--rule-strong);
  display:inline-flex;align-items:center;gap:6px;text-decoration:none}
.slchip::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--bad);flex:none}
.slchip:hover{border-color:var(--accent);color:var(--accent)}
/* The overflow count is not itself an alarm. */
.slchip.more{color:var(--muted);cursor:help}
.slchip.more::before{display:none}
.slsay{background:var(--surface-2);border:1px solid var(--rule);border-left:2px solid var(--accent-2);
  border-radius:0 7px 7px 0;padding:10px 13px}
.slsay .l{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--accent);font-weight:600;margin-bottom:4px}
.slsay p{margin:0;font-size:12.5px;line-height:1.5;color:var(--ink-2);font-style:italic}
.sltier{font-family:"IBM Plex Mono",monospace;font-size:10px;font-weight:600;padding:2px 7px;border-radius:4px}
.sltier.manager{background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-2)}
.sltier.rep{background:var(--surface-3);color:var(--muted);border:1px solid var(--rule-strong)}
/* A button is a label, not a serial number. Mono here made every action in
   the app — including "Sign in" — read as console output. */
.btn{font:inherit;font-size:12.5px;font-weight:500;line-height:1.2;padding:8px 14px;border-radius:8px;
  border:1px solid var(--rule-strong);background:var(--surface);color:var(--ink-2);cursor:pointer;
  text-decoration:none;text-align:center;transition:border-color .12s,color .12s,background .12s}
.btn:hover{border-color:var(--accent);color:var(--accent);background:var(--surface-2)}
.btn.pri{background:var(--vinx-green);border-color:var(--vinx-green);color:#0C2118;font-weight:600}
.btn.pri:hover{background:var(--vinx-green-ink);color:#fff}
/* A disabled button looked identical to an enabled one, so a Save that would
   not save read as a Save that was broken. */
.btn:disabled,.btn:disabled:hover{opacity:.45;cursor:not-allowed;
  background:var(--surface);color:var(--muted);border-color:var(--rule-strong)}
.btnrow{display:flex;gap:6px;flex-wrap:wrap}

/* objections */
.orow{display:grid;grid-template-columns:minmax(0,1fr) 300px 118px;gap:18px;padding:13px 18px;border-bottom:1px solid var(--rule);align-items:center}
.orow:last-child{border-bottom:0}
@media(max-width:760px){.orow{grid-template-columns:1fr;gap:7px}}
.orow .on{font-size:13px;font-weight:600;font-family:Oswald,sans-serif}
.orow .om{font-size:11px;color:var(--muted);margin-top:2px}
/* A 2px gap in the surface colour separates the segments — white doing the
   separating, never a stroke, which would add ink that is not data. */
.sbar{display:flex;gap:2px;height:10px;background:var(--track);border-radius:5px;overflow:hidden}
.sbar i{display:block;height:100%}
.sbar i:first-child{border-radius:5px 0 0 5px}
.sbar i:last-child{border-radius:0 5px 5px 0}
.orow .ov{text-align:right;font-family:"IBM Plex Mono",monospace;font-size:12.5px;font-weight:600;
  font-variant-numeric:tabular-nums}
/* The three counts sit under their own segments rather than in a sentence
   somewhere else, so the bar can be read without translating it first. */
.sbnums{display:flex;gap:2px;margin-top:5px;font-family:"IBM Plex Mono",monospace;font-size:10px;
  color:var(--muted);font-variant-numeric:tabular-nums}
.sbnums span{overflow:hidden;white-space:nowrap}
.key{display:flex;gap:16px;flex-wrap:wrap;padding:11px 18px;background:var(--surface-2);border-top:1px solid var(--rule);
  font-size:11px;color:var(--muted);font-family:"IBM Plex Mono",monospace}
.key span{display:flex;align-items:center;gap:6px} .key i{width:9px;height:9px;border-radius:2px}

/* health */
.health{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px}
.hc{padding:13px 15px}
.hc .hl{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:flex;align-items:center;gap:6px}
.hc .hl i{width:7px;height:7px;border-radius:50%;flex:none}
.hc .hv{font-family:"IBM Plex Mono",monospace;font-size:15px;font-weight:600;margin-top:5px}
.hc .hn{font-size:11px;color:var(--muted);line-height:1.45;margin-top:3px}

.empty{padding:26px 20px;text-align:center;color:var(--muted);font-size:13px}
.empty b{display:block;font-family:Oswald,sans-serif;color:var(--ink);font-size:14px;margin-bottom:4px}
.err{background:var(--bad-soft);border:1px solid var(--bad);color:var(--bad);border-radius:9px;padding:13px 16px;
  font-size:13px;margin:16px 0}
.skel{background:linear-gradient(90deg,var(--surface-3) 25%,var(--surface-2) 50%,var(--surface-3) 75%);
  background-size:200% 100%;animation:sh 1.4s infinite;border-radius:6px;height:14px}
@keyframes sh{0%{background-position:200% 0}100%{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
:focus-visible{outline:2px solid var(--vinx-green);outline-offset:2px;border-radius:4px}
footer{margin-top:40px;padding-top:20px;border-top:1px solid var(--rule);
  font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--faint);line-height:1.7}

/* --- Second Look outcomes -------------------------------------------------
   The queue is only worth having if someone can close an entry out. These
   controls are deliberately blunt: four buttons, one prompt, no modal. */
/* Full-width footer strip, not a fourth item in the narrow rail. */
.slout{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  border-top:1px solid var(--rule);background:var(--surface-2);padding:9px 17px}
.slout .btn.pri{margin-right:2px}
/* A modelled figure, shown as one: quoted value times a recovery rate, not
   money anybody has counted. It used to be the largest type on the card. */
.slout .slval{margin-left:auto;font-family:"IBM Plex Mono",monospace;font-size:11px;
  color:var(--muted);cursor:help}
.slout .l{flex:none;font-size:11.5px;color:var(--muted)}
.slout .obtns { display: flex; flex-wrap: wrap; gap: 5px; }
.slout .btn { font-size: 11.5px; padding: 4px 9px; }
.slout .btn.ok { border-color: var(--good); color: var(--good); }
.slout .btn.warn { border-color: var(--rule-strong); color: var(--muted); }
.slout .btn:disabled { opacity: .45; cursor: default; }
.omsg{font-size:11.5px;flex-basis:100%}
.omsg:empty{display:none}
.omsg.ok { color: var(--good); }
.omsg.bad { color: var(--bad); }
.slheld { font-size: 11.5px; color: var(--gold-ink); }

.recsum { margin-top: 11px; padding: 14px 16px; }
.recsum .l { font-size: 12px; font-weight: 600; color: var(--ink-2);
  margin-bottom: 10px; }
.recsum .rgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px 18px; }
.recsum .rgrid .na { color: var(--faint); }
.recsum .rgrid .rwhy { display: block; font-style: normal; font-size: 10.5px; color: var(--muted);
  line-height: 1.4; margin-top: 3px; }
.recsum .rgrid b { display: block; font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 19px; color: var(--ink); }
.recsum .rgrid s { display: block; text-decoration: none; font-size: 11px; color: var(--muted); margin-top: 2px; }
.recsum .rfoot { margin: 12px 0 0; font-size: 11.5px; color: var(--muted); }

/* --- drill-through --------------------------------------------------------
   Arriving from a number elsewhere in the app, the page says what it is
   showing and offers the way back out. A silently filtered list is how
   someone concludes the data is wrong. */
.drillbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 12px;
  padding:10px 14px;border:1px solid var(--vinx-green);border-radius:10px;
  background:color-mix(in oklab, var(--vinx-green) 8%, transparent)}
.drillbar .dlabel{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.drillbar .dchip{font-size:12.5px;font-weight:600;color:var(--ink)}
.drillbar .dchip + .dchip::before{content:"·";margin-right:8px;color:var(--muted);font-weight:400}
.drillbar .btn{margin-left:auto}

/* The page explains itself once, on request, rather than four times whether or
   not anyone is reading. Documentation is not data and should not compete with
   it for the top of the page. */
.headctl{display:flex;flex-direction:column;align-items:flex-end;gap:9px}
.howto{font-size:12px;color:var(--muted)}
.howto summary{cursor:pointer;list-style:none;
  font-size:11px;letter-spacing:.04em;color:var(--muted);padding:3px 2px;border-radius:5px}
.howto summary::-webkit-details-marker{display:none}
.howto summary::before{content:"?";display:inline-grid;place-items:center;width:14px;height:14px;
  border:1px solid var(--rule-strong);border-radius:50%;margin-right:6px;font-size:9px;
  vertical-align:-2px}
.howto summary:hover{color:var(--ink)}
.howto[open] summary{color:var(--ink)}
.howto-in{margin-top:8px;padding:13px 15px;background:var(--surface);border:1px solid var(--rule);
  border-radius:10px;box-shadow:var(--shadow);max-width:430px;text-align:left;line-height:1.55}
.howto-in p{margin:0 0 9px}
.howto-in p:last-child{margin-bottom:0}
.howto-in p:empty{display:none}
.howto-in b{color:var(--ink)}
@media(max-width:760px){.headctl{align-items:stretch}.howto-in{max-width:none}}

/* A transcript that exists only because Dialpad's own words were readable
   when its audio was not. Marked wherever it appears, so nobody compares a
   score built on it to one built on real audio without knowing. */
.rescued{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.06em;
  text-transform:uppercase;padding:2px 7px;border-radius:4px;
  background:var(--gold-soft);color:var(--gold-ink);font-weight:600}

/* Something excluded from a list, said out loud. A filter the reader cannot
   see is indistinguishable from missing data. */
.notebar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 12px;
  padding:9px 14px;border:1px solid var(--rule);border-radius:9px;background:var(--surface-2);
  font-size:12.5px;color:var(--muted)}
.notebar a{font-weight:600}

/* Anything that leads somewhere says so on hover, consistently. */
.drillable{cursor:pointer}
.drillable:hover{background:var(--surface-2)}
tr.drillable:hover td:first-child{box-shadow:inset 3px 0 0 var(--vinx-green)}

/* --- the rep's one thing ---------------------------------------------------
   A rep opening their own page should land on the single step worth working
   on, with the calls behind it one click away. A list of six scores is a
   report; this is a next action. */
.focus{padding:20px 22px;margin-bottom:14px;border-left:3px solid var(--vinx-green)}
.focus .fk{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.focus .ft{font-family:Oswald,sans-serif;font-size:26px;font-weight:600;margin:5px 0 2px;
  text-transform:capitalize}
.focus .fd{font-size:13.5px;color:var(--ink-2);margin:0 0 14px;max-width:62ch;line-height:1.55}
.focus .btn.pri{display:inline-block}

/* --- a rep's six steps -----------------------------------------------------
   Label, bar, score and the calls behind it, in that order and next to each
   other. The bar is the thing being read, so it gets the space; the score is
   the thing being remembered, so it is the largest. */
.steplist{padding:6px 0}
.steprow{display:grid;grid-template-columns:150px minmax(90px,320px) 46px minmax(0,1fr);
  gap:14px;align-items:center;padding:10px 18px}
.steprow .sname{font-size:13px;font-weight:500}
.steprow .sbar2{height:10px;border-radius:5px;background:var(--track);overflow:hidden;display:block}
.steprow .sbar2 i{display:block;height:100%;border-radius:0 4px 4px 0;background:var(--st-good);
  transition:width .5s cubic-bezier(.4,0,.2,1)}
.steprow .sval{font-family:"IBM Plex Mono",monospace;font-size:16px;font-weight:600;text-align:right;
  font-variant-numeric:tabular-nums}
.steprow .scount{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--muted);white-space:nowrap}
.steprow .scount b{font-weight:600}
/* A status colour arrives with a word beside it, never on its own. */
.weakflag{color:var(--st-bad)}
.weakflag::before{content:"▲ ";font-size:8px;vertical-align:1px}
@media(max-width:700px){
  .steprow{grid-template-columns:minmax(0,1fr) 46px;gap:4px 12px;padding:11px 16px}
  .steprow .sname{grid-row:1} .steprow .sval{grid-row:1}
  .steprow .sbar2{grid-column:1/-1;grid-row:2}
  .steprow .scount{grid-column:1/-1;grid-row:3;white-space:normal}
}

/* --- team switch ----------------------------------------------------------
   Sales is live; retention and service are shown from the start so the shape
   of the product is visible, with "soon" said plainly rather than a tab that
   looks live and then disappoints. */
/* The scope, not a second set of tabs. Quiet text with the live one marked by
   an underline rather than a filled pill, so the eye lands on the page tabs. */
.teamsw{display:flex;align-items:center;gap:3px;padding-left:14px;
  border-left:1px solid rgba(255,255,255,.16)}
.teamsw a{display:flex;align-items:center;gap:6px;text-decoration:none;font-family:Oswald,sans-serif;
  font-weight:500;font-size:12.5px;color:rgba(255,255,255,.5);padding:5px 9px;border-radius:6px;
  white-space:nowrap;transition:color .12s,background .12s}
.teamsw a:hover{background:rgba(255,255,255,.08);color:#fff}
.teamsw a.on{color:#fff;font-weight:600;box-shadow:inset 0 -2px 0 var(--vinx-green)}
.teamsw a s{text-decoration:none;font-family:"IBM Plex Mono",monospace;font-size:8.5px;
  letter-spacing:.09em;text-transform:uppercase;opacity:.5;border:1px solid currentColor;
  border-radius:4px;padding:1px 4px}
@media(max-width:980px){.teamsw a s{display:none}.teamsw a{padding:5px 7px}}
@media(max-width:680px){.teamsw{padding-left:0;border-left:0}.who{display:none}}
/* The same switcher, on a page instead of in the nav bar. Calibrate renders it
   into the content area, where rgba(255,255,255,.5) on paper is a rumour. */
.teamsw.inpage{padding-left:0;border-left:0;margin:0 0 12px;gap:4px}
.teamsw.inpage a{color:var(--muted);border:1px solid var(--rule);background:var(--surface)}
.teamsw.inpage a:hover{background:var(--surface-3);color:var(--ink)}
.teamsw.inpage a.on{color:var(--ink);background:var(--accent-soft);
  border-color:var(--accent);box-shadow:none;font-weight:600}

/* --- finish ---------------------------------------------------------------
   The difference between working and world-class is mostly in the states
   nobody demos: loading, empty, hover, focus, and what a number looks like
   when it cannot be computed. */

/* Skeletons that match the shape of what is coming, so the page does not
   jump when it arrives. */
@keyframes shimmer{0%{background-position:-320px 0}100%{background-position:320px 0}}
.skel{display:block;border-radius:6px;background:linear-gradient(90deg,
  var(--rule) 0%, var(--surface-2) 40%, var(--rule) 80%);
  background-size:320px 100%;animation:shimmer 1.2s linear infinite}
@media (prefers-reduced-motion:reduce){.skel{animation:none}}

/* Every interactive thing gets the same focus ring, once. */
a:focus-visible,button:focus-visible,[role="link"]:focus-visible,[role="tab"]:focus-visible,
[tabindex]:focus-visible{outline:2px solid var(--vinx-green);outline-offset:2px;border-radius:5px}

/* Rows that lead somewhere all behave identically, wherever they are. */
.drillable{cursor:pointer;transition:background .11s,box-shadow .11s}
.drillable:hover{background:var(--surface-2)}
.orow.drillable:hover,.lrow.drillable:hover{box-shadow:inset 3px 0 0 var(--vinx-green)}
.kpi.drillable:hover{box-shadow:0 0 0 1px var(--vinx-green)}

/* A figure that could not be computed never renders as a zero, and says why
   in a way that reads as an answer rather than an error. */
.blank{font-family:Oswald,sans-serif;font-size:30px;font-weight:600;color:var(--rule-strong);line-height:1}
.why{font-size:11px;color:var(--muted);margin-top:6px;line-height:1.45;max-width:34ch}

/* Numbers align on the decimal down a column; names stay left. */
table td:not(.who2),table th:not(:first-child){font-variant-numeric:tabular-nums}

/* Touch targets on a phone — a manager checking the queue between calls. */
@media(max-width:680px){
  .wrap{padding-left:14px;padding-right:14px}
  table{font-size:13px}
  .btn{min-height:38px}
  /* THE TOP BAR ON A PHONE — 5 Oct 2026.
     Eight tabs in a wrapping flex row: the logo and the product name were
     pushed off the bar entirely, "Second Look" and "My calls" each broke over
     two lines, System fell off the right edge, and Sign out landed alone on a
     row of its own behind a stray divider. The brand was missing from the top
     of the page on every phone.
     One row that scrolls sideways instead, which is what a phone expects, with
     the mark kept and the wordmark dropped — at this width the mark is the
     brand and the page title says the rest. */
  .topbar-in{padding:8px 14px;gap:8px}
  .logo .brandname{display:none}
  nav.tabs{order:3;flex:1 0 100%;margin-left:0;flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:1px}
  nav.tabs::-webkit-scrollbar{display:none}
  nav.tabs a{white-space:nowrap;flex:0 0 auto}
  /* One line for identity: the mark, the desk switcher, and the way out.
     The tabs take the line under it. Three stacked rows of chrome on a 390px
     screen is half the fold gone before the page says anything. */
  /* The tour replay is a desktop nicety and it was the 30px that pushed Sign
     out onto a row of its own. */
  .tourreplay{display:none}
  .teamsw{order:2;gap:1px}
  .teamsw a{padding:4px 7px;font-size:11.5px}
  .signout{order:2;margin-left:auto;padding:4px 8px;border-left:0}
  /* Same thing one row down: seven periods wrapped into an uneven second row
     with two buttons stretched across it. */
  .seg.periods{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .seg.periods::-webkit-scrollbar{display:none}
  .seg.periods button{flex:0 0 auto}
}

/* --- honest about thin data ----------------------------------------------
   Early on there are a handful of calls. Saying so plainly reads as rigour;
   showing percentages off four calls without saying so reads as a vendor. */
.thinbar{border:1px solid var(--rule-strong);border-left:3px solid var(--vinx-green);
  border-radius:10px;padding:13px 16px;margin-bottom:14px;background:var(--surface);
  font-size:13px;line-height:1.6;color:var(--ink-2);max-width:78ch}
.thinbar b{color:var(--ink)}

/* One quiet instruction for a first-time viewer, then out of the way. */
.hint{font-size:12.5px;color:var(--muted);padding:9px 14px;margin:0 0 12px;
  border:1px dashed var(--rule-strong);border-radius:9px;background:var(--surface);line-height:1.5}

/* --- the evidence ---------------------------------------------------------
   Every score carries the words it came from, visibly. A score with the quote
   underneath it is a coaching conversation; a score on its own is an opinion,
   and a rep will argue with an opinion. Clicking the quote plays that second
   of the call, which is the whole answer to "how do I know it's not made up". */
.stpwrap{border-bottom:1px solid var(--rule)}
.stpwrap:last-child{border-bottom:0}
/* The seven-stage rubric's criteria, under each stage (14 Oct 2026). */
.crits{margin:0 17px 10px;font-size:12.5px}
.crits summary{cursor:pointer;color:var(--muted);font-size:11.5px;padding:2px 0}
.crits ul{list-style:none;margin:6px 0 0;padding:0;display:grid;gap:7px}
.crit{display:grid;grid-template-columns:1fr auto;gap:2px 10px;align-items:baseline}
.crit .cv{font-variant-numeric:tabular-nums;color:var(--muted);font-weight:600}
.crit.full .cv{color:var(--good)}
.crit.miss .cv{color:var(--bad)}
.crit .cq,.crit .cn{grid-column:1 / -1}
.crit .cq{background:none;border:0;padding:0;text-align:left;font:inherit;color:var(--ink-2);cursor:pointer;font-style:italic}
.crit .cn{color:var(--muted);font-size:11.5px}
.care{font-size:11.5px;color:var(--muted)}
/* width:100% plus a 17px left margin is 17px wider than the parent, which is
   what was dragging the whole call page sideways on a phone. */
.ev{display:flex;align-items:baseline;gap:10px;width:calc(100% - 17px);text-align:left;
  background:transparent;border:0;border-left:2px solid var(--vinx-green);cursor:pointer;font:inherit;
  padding:2px 17px 11px 15px;margin:-4px 0 0 17px}
.ev:hover{background:var(--surface-2)}
.ev .q{font-size:12.5px;line-height:1.5;color:var(--ink-2);font-style:italic}
.ev .evt{margin-left:auto;font-family:"IBM Plex Mono",monospace;font-size:10.5px;
  color:var(--vinx-green);white-space:nowrap;opacity:.75}
.ev:hover .evt{opacity:1}
.ev:hover .q{color:var(--ink)}
/* A quote anywhere on the page is clickable and looks it. */
.qq{cursor:pointer;font-style:italic;border-bottom:1px dotted var(--vinx-green)}
.qq:hover{color:var(--ink);background:var(--surface-2)}

/* The period picker carries seven options now, so it wraps on a narrow screen
   rather than scrolling out of reach. */
.seg.periods{max-width:100%}
@media(min-width:681px){.seg.periods{flex-wrap:wrap}}
.seg.periods button{font-size:12px;padding:6px 10px}


/* A call with no audio gets a card that does not pretend to be a player:
   no waveform, no playhead, no clock, no speed control, no play button.
   What is left is the map of the call, which is true with or without sound. */
.player.noaudio{border-left:3px solid var(--vinx-gold)}
.nomsg{font-size:13px;line-height:1.6;color:var(--ink-2);margin-bottom:14px}
.nomsg b{color:var(--ink);font-weight:600}
/* Without a waveform above them the markers have nothing to sit under, so the
   strip carries its own baseline. */
.marks.bare{border-top:1px solid var(--rule);margin-top:2px;height:26px}
.player.noaudio .controls{border-top:0;margin-top:2px}
.player.noaudio .time{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--muted)}

/* ---- sign-in ------------------------------------------------------------
   The only page a person can reach without being anybody yet, so it says what
   the tool is and nothing else. No navigation: there is nowhere to go. */
.signin-page{background:linear-gradient(160deg,var(--vinx-teal),var(--vinx-teal-deep));min-height:100vh}
.signin{max-width:420px;margin:0 auto;padding:9vh 20px 40px}
.signin-card{padding:26px 26px 22px}
.signin .brand{margin-bottom:14px}
.signin h1{font-size:19px;margin:0 0 18px}
.signin-tabs{width:100%;margin-bottom:18px}
.signin-tabs button{flex:1}
.signin-form{display:flex;flex-direction:column;gap:14px}
/* `hidden` is only display:none in the UA stylesheet, and display:flex above
   beats it — so both forms rendered at once, stacked, and the tabs did
   nothing visible. */
.signin-form[hidden]{display:none}
.signin-form label{display:flex;flex-direction:column;gap:5px;font-size:12.5px;font-weight:500;color:var(--ink-2)}
.signin-form input{font:inherit;font-size:14px;padding:9px 11px;border:1px solid var(--rule-strong);
  border-radius:7px;background:var(--surface);color:var(--ink)}
.signin-form input:focus{outline:2px solid var(--vinx-green);outline-offset:1px;border-color:var(--vinx-green)}
.signin-form label em{font-style:normal;font-weight:400;font-size:11px;color:var(--muted);line-height:1.45}
.signin-form .note{margin:0;font-size:12.5px;color:var(--ink-2);line-height:1.55}
.btn.wide{width:100%;padding:10px;font-size:13px}
.signin-msg{margin-top:14px;font-size:12.5px;line-height:1.5;min-height:1em}
.signin-msg.bad{color:var(--bad)}
.signin-msg.ok{color:var(--accent)}
.signin-foot{max-width:420px;margin:16px auto 0;text-align:center;font-size:11.5px;color:#B6CCC5}

/* The column the table exists to be read for. */
table td.lead{font-family:Oswald,sans-serif;font-size:17px;font-weight:600;color:var(--ink)}
table td.lead s{display:block;text-decoration:none;font-family:"IBM Plex Mono",monospace;
  font-size:10.5px;font-weight:400;color:var(--muted);margin-top:1px}

/* The queue's one line on the team page. It links somewhere; it does not
   restate the queue. */
.slstrip{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding:13px 17px;
  font-size:13.5px;color:var(--ink-2);text-decoration:none;border-left:3px solid var(--vinx-gold)}
.slstrip b{font-family:Oswald,sans-serif;font-size:20px;color:var(--ink);font-weight:600}
.slstrip s{text-decoration:none;font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--muted)}
.slstrip em{margin-left:auto;font-style:normal;font-weight:600;color:var(--accent);font-size:12.5px}
.slstrip:hover em{text-decoration:underline}
.slstrip.quiet{border-left-color:var(--rule-strong);display:block}
.slstrip.quiet s{display:block;margin-top:4px;font-family:inherit;font-size:12px;line-height:1.5}

/* The six steps, per rep. Where a rep falls over is the coaching, and the
   number without a hint of severity makes a wall of grey digits. Colour is a
   background wash, not the text — a light hue is illegible as type. */
table th.stepcol,table td.stepcol{text-align:center;font-size:12px;white-space:nowrap}
table th.stepcol{font-size:10px}
table td.stepcol.ok{background:var(--good-soft);color:var(--st-good);font-weight:600}
table td.stepcol.mid{background:var(--gold-soft);color:#8A6410;font-weight:600}
table td.stepcol.low{background:var(--bad-soft);color:var(--st-bad);font-weight:600}

/* --- one rep, everything about them ---------------------------------------
   The manager view. A leaderboard answers "who"; this answers "what do I say
   to them on Monday", so it is ordered the way that conversation goes: the
   close rate, the step it is leaking from, the habit behind that step, and
   then the calls to listen to. */
.backto{margin:14px 0 -6px;font-size:12.5px}
.backto a{color:var(--muted);text-decoration:none;font-weight:500}
.backto a:hover{color:var(--accent)}

/* The team average rides on the rep's own bar rather than in a second chart
   beside it. Two charts of the same six numbers is the same fact drawn twice,
   and the comparison is the whole point of the second one. */
.steprow .sbar2.vs{overflow:visible;position:relative}
.steprow .sbar2.vs i{border-radius:5px}
.steprow .sbar2.vs u{position:absolute;top:-4px;bottom:-4px;width:2px;margin-left:-1px;
  background:var(--ink-2);border-radius:1px}
.goodflag{color:var(--st-good)}
.goodflag::before{content:"▲ ";font-size:8px;vertical-align:1px}
.key.steplegend{padding:10px 18px 4px}
.key i.teamtick{width:2px;height:12px;background:var(--ink-2);border-radius:1px}

/* A habit, not an anecdote: what it is, how often, and the words that prove
   it. The bar is the share of graded calls, so two habits are comparable at a
   glance without reading either number. */
.habits{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
@media(max-width:860px){.habits{grid-template-columns:1fr}}
.habit{padding:15px 17px 13px;border-left:3px solid var(--st-bad)}
.habit.h-win{border-left-color:var(--st-good)}
.habit .htop{display:flex;align-items:baseline;gap:10px;justify-content:space-between}
.habit .hname{font-family:Oswald,sans-serif;font-size:15px;font-weight:600;line-height:1.25}
.habit .hcalls{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--muted);
  white-space:nowrap;font-variant-numeric:tabular-nums}
.habit .hbar{height:5px;border-radius:3px;background:var(--track);margin:9px 0 11px;overflow:hidden}
.habit .hbar i{display:block;height:100%;background:var(--st-bad);border-radius:3px}
.habit.h-win .hbar i{background:var(--st-good)}
.habit .hq{margin:0 0 10px;padding:8px 11px;background:var(--surface-2);border-radius:8px;
  font-size:13px;line-height:1.5;color:var(--ink)}
.habit .hq .qt::before{content:"“"} .habit .hq .qt::after{content:"”"}
.habit .hq cite{display:block;font-style:normal;font-family:"IBM Plex Mono",monospace;
  font-size:10.5px;color:var(--faint);margin-top:5px}
.habit .hq .hnote{display:block;font-size:12px;color:var(--ink-2);margin-top:6px;line-height:1.45}
.habit .hq .hopen{display:inline-block;margin-top:6px;font-size:11.5px;text-decoration:none;font-weight:600}
.habit .hlink{display:inline-block;font-size:12px;font-weight:600;text-decoration:none}
/* A delta below the team points down. The weak-count arrow points up because
   more weak calls is worse; a −14 pointing up said the opposite of its number. */
.downflag{color:var(--st-bad)}
.downflag::before{content:"▼ ";font-size:8px;vertical-align:1px}
.listmore{padding:12px 18px;border-top:1px solid var(--rule);color:var(--muted);font-size:12.5px;
  line-height:1.5;background:var(--surface-2);border-radius:0 0 var(--radius) var(--radius)}
.listmore a{font-weight:600;text-decoration:none;white-space:nowrap}

/* --- where every qualified call ended up -----------------------------------
   One ordinal bar: won, still winnable, gone, never really there. The 2px
   surface gap between segments is not decoration — the amber and the red sit
   adjacent and measure ΔE 7.2 for a deuteranope, which the palette check
   allows only with secondary encoding. The gap and the written key under it
   are that encoding, so nothing here is carried by colour alone. */
.outcomebar{padding:16px 18px 14px}
.obtotal{font-size:13px;color:var(--ink-2)}
.obtotal b{font-family:Oswald,sans-serif;font-size:22px;font-weight:600;color:var(--ink);
  margin-right:4px;vertical-align:-1px}
.obtotal s{display:block;text-decoration:none;font-size:11.5px;color:var(--muted);margin-top:1px}
.obbar{display:flex;gap:2px;height:34px;margin:13px 0 11px;border-radius:6px;overflow:hidden}
.obseg{display:flex;align-items:center;justify-content:center;min-width:3px;text-decoration:none;
  transition:filter .15s}
.obseg:first-child{border-radius:6px 0 0 6px}
.obseg:last-child{border-radius:0 6px 6px 0}
.obseg:hover{filter:brightness(1.08)}
.obseg i{font-style:normal;font-family:"IBM Plex Mono",monospace;font-size:12px;font-weight:600;
  color:#fff;font-variant-numeric:tabular-nums}
/* White reads on the green, the red and the grey; on the amber it is 2.03:1.
   The segment says which it needs rather than the label assuming. */
.obseg.ondark i{color:#fff}
.obseg.onlight i{color:#2B2203}
.obkey{display:flex;flex-wrap:wrap;gap:6px 20px;font-size:12px;color:var(--muted)}
.obkey span{display:flex;align-items:center;gap:7px}
.obkey i{width:10px;height:10px;border-radius:3px;flex:none}
.obkey b{font-family:"IBM Plex Mono",monospace;color:var(--ink);font-weight:600;
  font-variant-numeric:tabular-nums}

/* Sales the close rate deliberately excludes. A footnote, not a segment: it
   sits under the key rather than in the bar, because putting it in the bar
   would change what the bar's denominator means. */
/* The sales report line. Same shape as the "waiting" note it sits above, but
   this one is an answer rather than an absence, so it reads in the ink colour
   and carries a left rule. */
.waiting.truth{border-left:3px solid var(--st-good);color:var(--ink)}
.waiting.truth s{display:block;margin-top:5px;text-decoration:none;color:var(--muted)}

/* "you are looking at page 1 of N", said where it cannot be mistaken for a
   statement about the whole window. */
.notebar s{display:block;margin-top:4px;text-decoration:none;color:var(--muted);font-size:12px}
.pagenote{margin:0 0 12px;font-size:12.5px;color:var(--muted);line-height:1.55}
.pagenote b{font-family:"IBM Plex Mono",monospace;color:var(--ink);font-weight:600;
  font-variant-numeric:tabular-nums}

.obnote{margin-top:14px;padding-top:12px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--ink)}
.obnote b{font-family:"IBM Plex Mono",monospace;font-weight:600;
  font-variant-numeric:tabular-nums}
.obnote s{display:block;margin-top:4px;text-decoration:none;color:var(--muted);
  font-size:12px;line-height:1.5}

/* --- the moment feed -------------------------------------------------------
   One card, one thing that happened, with the words that caused it. Built
   against a reference version of this strip whose every card read "Invalid
   Date", whose notes stopped mid-word, and whose two tabs used different
   selection rules — so this one shows the call's real date, clamps on whole
   lines with the full text in the title, and says its selection rule out loud
   in the tab row. */
.moments{padding:14px 0 4px;overflow:hidden}
.mtabs{display:flex;align-items:center;gap:8px;padding:0 18px 13px;
  border-bottom:1px solid var(--rule);margin-bottom:14px}
.mtabs button{appearance:none;border:1px solid transparent;background:transparent;cursor:pointer;
  font-family:Oswald,sans-serif;font-size:13px;font-weight:600;letter-spacing:.01em;
  color:var(--muted);padding:6px 12px;border-radius:999px;display:flex;align-items:center;gap:7px;
  transition:background .15s,color .15s,border-color .15s}
.mtabs button:hover{color:var(--ink)}
.mtabs button s{text-decoration:none;font-family:"IBM Plex Mono",monospace;font-size:11px;
  font-weight:500;font-variant-numeric:tabular-nums;opacity:.75}
.mtabs button[aria-selected=true].issues{background:var(--gold-soft);color:#8A6410;border-color:#E4CA92}
.mtabs button[aria-selected=true].wins{background:var(--good-soft);color:var(--st-good);border-color:#A9CFBC}
.mtabs .mnote{margin-left:auto;font-family:"IBM Plex Mono",monospace;font-size:10.5px;
  color:var(--faint);padding-right:4px}

/* A rail, not a grid: these are a stream, and the newest ones matter most, so
   the reader starts at the left and moves as far right as they care to. Snap
   points stop a card being left half-shown by accident — a partial card at the
   right edge is the affordance that says there is more. */
.mrail{display:flex;gap:12px;overflow-x:auto;padding:2px 18px 16px;
  scroll-snap-type:x proximity;scrollbar-width:thin;scrollbar-color:var(--rule-strong) transparent}
.mrail:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:8px}
.mrail::-webkit-scrollbar{height:8px}
.mrail::-webkit-scrollbar-thumb{background:var(--rule-strong);border-radius:4px}
.mrail::-webkit-scrollbar-track{background:transparent}

/* Every slot is a fixed number of lines, so the quote starts at the same height
   on every card, the note starts at the same height, and the footers line up
   across the rail. Left to size themselves, a one-line title and a two-line
   title push everything below them out of step and the row reads as ragged
   rather than as a set. The heights are computed from the line-height rather
   than guessed, and each clamp carries its full text in the title attribute. */
.mcard{flex:0 0 304px;scroll-snap-align:start;display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--rule);border-left:3px solid var(--st-bad);
  border-radius:10px;padding:14px 15px 11px}
.mcard.win{border-left-color:var(--st-good)}
.mcard .mtop{margin-bottom:10px}
.mcard .mflag{font-family:Oswald,sans-serif;font-size:12.5px;font-weight:600;line-height:1.32;
  color:var(--ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;min-height:calc(2 * 1.32 * 12.5px)}
/* The clamp lives on an inner span, never on the card's own child. A direct
   child of a flex column is a flex item, and Chrome blockifies a flex item's
   display: -webkit-box computes to flow-root, the clamp stops applying, and a
   fourth line shows through the bottom of the box. Computed style said
   flow-root while the stylesheet said -webkit-box, which is the only way to
   find this — it cannot be seen by reading the CSS. */
.mcard .mq{margin:0 0 10px;padding:9px 11px;background:var(--surface-2);border-radius:7px;
  font-size:12.5px;line-height:1.5;color:var(--ink);
  min-height:calc(3 * 1.5 * 12.5px + 18px)}
.mcard .mq span{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden}
.mcard .mq span::before{content:"“"} .mcard .mq span::after{content:"”"}
.mcard .mnotetext{margin:0 0 12px;font-size:12px;line-height:1.5;color:var(--ink-2);
  min-height:calc(3 * 1.5 * 12px)}
.mcard .mnotetext span{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden}
.mcard .mfoot{margin-top:auto;display:flex;align-items:baseline;gap:8px;padding-top:9px;
  border-top:1px solid var(--rule);font-size:11.5px}
.mcard .mwho{font-weight:600;color:var(--ink-2);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.mcard .mwhen{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--faint);
  white-space:nowrap}
.mcard .mlisten{margin-left:auto;font-weight:600;text-decoration:none;white-space:nowrap}
@media(max-width:560px){.mcard{flex-basis:82%}}

/* --- the first-run tour -----------------------------------------------------
   A spotlight rather than a modal: the point is to show somebody the number
   they are being told about, in place, on their own data. Four sides of dim
   around a transparent hole, so the target stays legible and everything else
   recedes. */
.tourveil{position:fixed;inset:0;z-index:200;animation:tourIn .18s ease-out}
.tourveil.out{opacity:0;transition:opacity .18s ease}
@keyframes tourIn{from{opacity:0}to{opacity:1}}
.tourhole{position:fixed;border-radius:10px;transition:all .26s cubic-bezier(.4,0,.2,1);
  box-shadow:0 0 0 9999px rgba(9,20,19,.62);pointer-events:none}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]) .tourhole{
  box-shadow:0 0 0 9999px rgba(0,0,0,.72)}}
.tourslot{position:fixed;transition:top .26s cubic-bezier(.4,0,.2,1),left .26s cubic-bezier(.4,0,.2,1)}
.tourcard{width:min(380px,calc(100vw - 24px));background:var(--surface);color:var(--ink);
  border:1px solid var(--rule);border-radius:var(--radius);padding:15px 17px 13px;
  box-shadow:0 18px 44px -18px rgba(9,20,19,.55),0 2px 6px rgba(9,20,19,.12)}
.tourcard h3{margin:2px 0 6px;font-size:16.5px;letter-spacing:.2px}
.tourcard p{margin:0 0 13px;font-size:13px;line-height:1.62;color:var(--ink-2)}
.tourstep{font-size:10.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
.tourbtns{display:flex;align-items:center;justify-content:space-between;gap:10px}
.tourdots{display:flex;gap:5px}
.tourdots i{width:5px;height:5px;border-radius:50%;background:var(--rule-strong);
  transition:background .2s,transform .2s}
.tourdots i.on{background:var(--accent);transform:scale(1.35)}
.tourskip{background:none;border:0;color:var(--muted);font:inherit;font-size:12.5px;
  cursor:pointer;padding:6px 2px}
.tourskip:hover{color:var(--ink)}
.tourreplay{width:22px;height:22px;border-radius:50%;border:1px solid rgba(234,242,236,.3);
  background:transparent;color:#EAF2EC;font:600 11px/1 Poppins,sans-serif;cursor:pointer;
  margin-right:10px;opacity:.65;transition:opacity .15s,border-color .15s}
.tourreplay:hover{opacity:1;border-color:rgba(234,242,236,.65)}

/* ============================================================================
   POLISH PASS
   The bones were right — validated palette, real type, honest empty states.
   What was missing is the part that makes an instrument feel like an
   instrument rather than a report: depth that means something, motion that
   confirms an action, and numbers that line up down a column so the eye can
   compare them without reading.
   Nothing below changes a value, a label, or a rule about blanks.
   ========================================================================== */

/* Figures are compared vertically, so they have to share a width. Tabular
   numerals everywhere a number appears, not only where someone remembered. */
.kpi .val,.kpi .blank,td,.n,.mono,.obtotal b,.pagenote b,.waiting b,.tourstep{
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1,"lnum" 1}

/* Elevation as a signal, not decoration: a card at rest sits almost flat, and
   lifts only when it is something you can open. A page where everything floats
   equally tells you nothing about what is clickable. */
.card{transition:box-shadow .18s ease,border-color .18s ease,transform .18s ease}
.card.drillable,.kpi.drillable{cursor:pointer}
.card.drillable:hover,.kpi.drillable:hover{
  border-color:var(--rule-strong);
  box-shadow:0 1px 2px rgba(25,67,66,.05),0 14px 32px -22px rgba(25,67,66,.45);
  transform:translateY(-1px)}
.kpi.hero.drillable:hover{border-color:var(--vinx-green)}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]) .card.drillable:hover,
  :root:not([data-theme=light]) .kpi.drillable:hover{
    box-shadow:0 1px 2px rgba(0,0,0,.5),0 14px 32px -22px rgba(0,0,0,.9)}}

/* The hero tile carries the number the page is named for. A hairline of the
   brand green down its left edge marks it without another box or another
   colour fill. */
.kpi.hero{position:relative;overflow:hidden}
.kpi.hero::before{content:"";position:absolute;inset:0 auto 0 0;width:3px;
  background:linear-gradient(180deg,var(--vinx-green),var(--accent))}

/* Rows: a readable hover, and a rule that does not shout. A table people scan
   for one name needs the row to answer when the mouse is on it. */
tbody tr{transition:background .12s ease}
tbody tr:hover{background:var(--surface-2)}
tbody tr:last-child td{border-bottom:0}
th{position:sticky;top:0;background:var(--surface);z-index:1;
  box-shadow:inset 0 -1px 0 var(--rule)}

/* Focus that is visible on both grounds and never invisible on the teal
   header. Keyboard users are the ones most likely to be checking a number
   against a spreadsheet. */
a:focus-visible,button:focus-visible,[tabindex]:focus-visible,.btn:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:5px}
.topbar a:focus-visible,.topbar button:focus-visible{outline-color:#8FE39C}

/* Buttons: a press that registers. */
.btn{transition:border-color .15s,color .15s,background .15s,transform .08s}
.btn:active{transform:translateY(1px)}

/* Loading that reads as loading rather than as empty. A skeleton that pulses
   says "coming"; a blank card says "there is none", which is the one thing
   this product must never say by accident. */
@keyframes sheen{0%{background-position:200% 0}100%{background-position:-200% 0}}
.skel{background:linear-gradient(90deg,var(--surface-3) 25%,var(--surface-2) 50%,var(--surface-3) 75%);
  background-size:200% 100%;animation:sheen 1.4s linear infinite;border-radius:6px;color:transparent}
@media (prefers-reduced-motion:reduce){
  .skel{animation:none}
  .card,.btn,tbody tr,.tourhole,.tourslot{transition:none}
  .tourveil{animation:none}
}

/* The header: a thin brand rule under it, so the chrome ends somewhere
   definite instead of bleeding into the page. */
.topbar{box-shadow:inset 0 -1px 0 rgba(58,181,75,.28)}
.topbar-in{gap:16px}

/* Section headings: quieter, with the explanatory half set apart rather than
   competing. */
.sec{letter-spacing:.1px}
.sec span,.sec em{font-family:Poppins,sans-serif;font-weight:400;font-style:normal;
  font-size:12.5px;color:var(--muted);letter-spacing:0}

/* Content arriving should not jump. */
main,.wrap{animation:rise .22s ease-out}
@keyframes rise{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){main,.wrap{animation:none}}

/* --- sign-in --------------------------------------------------------------
   The first thing anyone sees, and for most of the team the only thing they
   will see before deciding whether this looks like something to trust. It was
   a white box floating on a flat field. */
.signin-page{
  background:
    radial-gradient(1100px 620px at 50% -12%, rgba(58,181,75,.14), transparent 62%),
    radial-gradient(700px 460px at 88% 104%, rgba(58,181,75,.07), transparent 60%),
    linear-gradient(165deg, var(--vinx-teal), var(--vinx-teal-deep) 72%);
  min-height:100vh}
.signin{max-width:404px;padding:11vh 20px 40px}
.signin-card{padding:30px 30px 24px;border:1px solid rgba(255,255,255,.1);
  box-shadow:0 34px 70px -34px rgba(0,0,0,.62),0 2px 8px rgba(0,0,0,.16)}
.signin .brand{margin-bottom:18px}
/* The product name reads as the product name, with the eyebrow above it doing
   the work the strapline was doing badly. */
.signin h1{font-size:23px;letter-spacing:-.2px;margin:0 0 7px}
/* Not the company name — the logo two lines above already says that. What a
   first-time signer-in does not know is what the thing does. */
.signin .kicker{font-size:12.5px;line-height:1.55;color:var(--muted);margin:0 0 22px;
  max-width:33ch}
.signin-form input{padding:11px 12px;border-radius:8px;background:var(--surface-2);
  transition:border-color .15s,box-shadow .15s,background .15s}
.signin-form input:hover{border-color:var(--rule-strong)}
.signin-form input:focus{outline:none;background:var(--surface);
  border-color:var(--vinx-green);box-shadow:0 0 0 3px rgba(58,181,75,.18)}
.signin-form input::placeholder{color:var(--faint)}
.btn.pri.wide{padding:11px 14px;font-size:12.5px;letter-spacing:.06em;border-radius:8px;
  box-shadow:0 1px 0 rgba(0,0,0,.06),0 8px 20px -12px rgba(31,124,52,.8)}
.btn.pri.wide:hover{filter:brightness(1.04)}
.signin-tabs{border-radius:8px;overflow:hidden}
.signin-foot{margin-top:20px;color:#B6CCC5}

/* The disqualified breakdown. Same table language as the leaderboard — the
   rows are drillable, so they get the same affordance. */
table.dq{width:100%;border-collapse:collapse}
table.dq th{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  font-weight:600;padding:8px 10px;border-bottom:1px solid var(--line);white-space:nowrap}
table.dq td{padding:9px 10px;border-bottom:1px solid var(--line);font-variant-numeric:tabular-nums;
  text-align:center}
table.dq td.l,table.dq th.l{text-align:left}
table.dq tbody tr{cursor:pointer}
table.dq tbody tr:hover{background:var(--hover)}
table.dq tbody tr:last-child td{border-bottom:0}
.dqwhy{color:var(--muted);font-size:12px}

/* A rep window with too few calls to average. Says the thing, then points at
   the two places that do have an answer. */
.thinsteps{padding:18px 20px}
.thinsteps b{display:block;font-size:14.5px;margin-bottom:6px}
.thinsteps p{color:var(--muted);font-size:12.5px;line-height:1.55;margin:0 0 14px;max-width:62ch}
.thinsteps .btnrow{display:flex;gap:8px;flex-wrap:wrap}

/* Calls where nobody answered. Above the table, not inside it — the absence of
   a conversation is not a reason a conversation failed. */
.nevermet{margin:0 0 14px;padding:10px 14px;border-left:3px solid var(--line);
  background:var(--sunk);font-size:12.5px;color:var(--muted);line-height:1.55}
.nevermet b{color:var(--ink);font-weight:600}
.nevermet a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}

/* ---- Calibration ------------------------------------------------------- */
/* A scoring form beside a transcript beside a player. The form is the work;
   the transcript is the evidence; both have to be on screen at once or the
   person is scoring from memory. */
.calbar{display:flex;align-items:center;gap:10px;margin:0 0 12px;font-size:12.5px}
.calbar b{font-size:14px}
.calbar s{text-decoration:none;color:var(--muted)}
.calcols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;align-items:start;margin-top:14px}
@media (max-width:940px){.calcols{grid-template-columns:minmax(0,1fr)}}
.calcols .tr{max-height:70vh;overflow:auto;position:sticky;top:12px}
.calform{display:flex;flex-direction:column;gap:14px}
.calnote{color:var(--muted);font-size:12px;line-height:1.5;margin:2px 0 10px;max-width:60ch}
.calstep{padding:10px 0;border-bottom:1px solid var(--line)}
.calstep:last-child{border-bottom:0}
.calstep .l{font-weight:600;font-size:13px;margin-bottom:7px;display:flex;gap:8px;align-items:baseline}
.calstep .l s{text-decoration:none;color:var(--muted);font-family:'IBM Plex Mono',monospace;font-size:10.5px}
/* The scoring guide under each step. Collapsed by default: somebody on their
   fortieth call does not want to read it again, and somebody on their first
   cannot score without it. */
.gintent{color:var(--ink-2);font-size:12.5px;line-height:1.55;margin:0 0 9px;max-width:68ch}
.gwrap{margin-top:9px}
.gwrap>summary{cursor:pointer;display:inline-block;font-size:11.5px;color:var(--muted);
  padding:3px 9px;border:1px solid var(--rule);border-radius:999px;list-style:none;
  user-select:none;transition:.12s}
.gwrap>summary::-webkit-details-marker{display:none}
.gwrap>summary::after{content:' ›';display:inline-block;transition:transform .12s}
.gwrap[open]>summary::after{transform:rotate(90deg)}
.gwrap>summary:hover{border-color:var(--rule-strong);color:var(--ink-2)}
.gbody{margin-top:9px;padding:11px 13px;background:var(--surface-2);
  border:1px solid var(--rule);border-radius:9px;max-width:70ch}
.gband{display:grid;grid-template-columns:104px 1fr;gap:10px;align-items:baseline;
  padding:5px 0;font-size:12.5px;line-height:1.55;color:var(--ink-2)}
.gband+.gband{border-top:1px solid var(--rule)}
.gband b{font-size:11px;letter-spacing:.03em;text-transform:uppercase}
.b-strong{color:var(--st-good)} .b-weak{color:var(--gold-ink)} .b-absent{color:var(--st-bad)}
.gnote{margin:8px 0 0;font-size:11.5px;color:var(--muted);line-height:1.5}
.gex{margin-top:10px;padding-top:10px;border-top:1px solid var(--rule)}
.gex p{margin:0 0 7px;font-size:12.5px;line-height:1.6;color:var(--ink-2)}
.gex p b{margin-right:7px;font-size:11px;letter-spacing:.03em;text-transform:uppercase}
.gex s{text-decoration:none;display:block;font-size:11px;color:var(--faint)}
.gchecks{margin-top:10px;padding-top:10px;border-top:1px solid var(--rule)}
.gchecks>s{text-decoration:none;display:block;font-size:11px;letter-spacing:.03em;
  text-transform:uppercase;color:var(--muted);margin-bottom:6px}
.gchecks ul{margin:0;padding-left:17px}
.gchecks li{font-size:12.5px;line-height:1.55;color:var(--ink-2);margin-bottom:4px}
.gchecks li.neg{color:var(--bad)}
.gchecks li i{color:var(--muted);font-style:normal;font-size:11.5px}
.pickrow{display:flex;gap:6px;flex-wrap:wrap}
.pickbtn{font:inherit;font-size:12.5px;padding:7px 12px;border-radius:999px;cursor:pointer;
  border:1px solid var(--line);background:var(--card);color:var(--ink);transition:.12s}
.pickbtn:hover{border-color:var(--rule-strong)}
.pickbtn.on{background:var(--vinx-deep,#194342);border-color:var(--vinx-deep,#194342);color:#fff;font-weight:600}
.calcols .seg{cursor:pointer;padding:3px 6px;border-radius:5px;margin:1px 0;line-height:1.5}
.calcols .seg:hover{background:var(--hover)}
.calcols .seg.on{background:var(--sunk);font-weight:500}
.calcols .seg s{text-decoration:none;color:var(--muted);font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;margin-right:6px}
.calcols .seg.r{color:var(--ink)}
.calcols .seg.c{color:var(--muted)}

/* A queue nobody works. Louder than the open count on purpose: an unworked
   queue and an empty queue look identical if you only print what is waiting. */
.slwarn{margin:0 0 10px;padding:11px 15px;border-radius:10px;font-size:12.5px;line-height:1.55;
  color:var(--ink);background:color-mix(in srgb,var(--bad) 8%,transparent);
  border:1px solid color-mix(in srgb,var(--bad) 28%,transparent)}
.slwarn b{font-family:'IBM Plex Mono',monospace;color:var(--bad)}


/* What was done about a call. The log reads first and the controls sit under
   it, because the question "has anybody already dealt with this" has to be
   answered before the question "what should I do". */
.fulog{list-style:none;margin:0 0 12px;padding:0}
.fulog li{padding:8px 0;border-bottom:1px solid var(--rule)}
.fulog li:last-child{border-bottom:0}
.fulog b{font-size:13px;color:var(--ink)}
.fulog s{display:block;text-decoration:none;font-family:"IBM Plex Mono",monospace;
  font-size:10.5px;color:var(--muted);margin-top:2px}
.funote{font-size:12.5px;color:var(--ink-2);margin-top:5px;line-height:1.5}
.fumuted{font-size:12.5px;color:var(--muted);margin:0 0 12px;line-height:1.5}
.fubtns{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
.fubtns .btn{font-size:12px;padding:5px 10px}
.fuinput{width:100%;box-sizing:border-box;padding:7px 10px;border:1px solid var(--rule-strong);
  border-radius:7px;font:inherit;font-size:12.5px;background:var(--surface-2);color:var(--ink)}
.fuinput::placeholder{color:var(--muted)}

/* Customer Service and Retention, while scoring is off. The page is in two
   halves and the line between them is load-bearing: above it everything is
   true today, below it is the shape of what scoring will add. */
.heldnote{padding:16px 20px;border-left:3px solid var(--vinx-gold);margin-bottom:14px}
.hn-tag{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--gold-ink);margin-bottom:6px}
.heldnote p{margin:0;font-size:13px;line-height:1.6;color:var(--ink-2);max-width:78ch}
.scoreline{display:flex;align-items:center;gap:14px;margin:34px 0 6px;color:var(--muted)}
.scoreline::before,.scoreline::after{content:"";flex:1;height:1px;background:var(--rule-strong)}
.scoreline span{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap}
.rubsrc{padding:14px 18px;border-bottom:1px solid var(--rule);font-size:12px;line-height:1.6;
  color:var(--muted);max-width:96ch}
td.int{font-family:Poppins,system-ui,sans-serif;font-size:12px;line-height:1.5;color:var(--ink-2);
  white-space:normal;min-width:340px}
.notgraded{padding:14px 18px;border-top:1px solid var(--rule);background:var(--surface-2)}
.notgraded b{display:block;font-family:Oswald,sans-serif;font-size:13px;margin-bottom:6px}
.notgraded p{margin:0 0 7px;font-size:12px;line-height:1.55;color:var(--ink-2);max-width:92ch}
.notgraded s{text-decoration:none;font-family:"IBM Plex Mono",monospace;font-size:11px;
  color:var(--ink);margin-right:6px}
.flagwrap{display:flex;flex-wrap:wrap;gap:6px;padding:16px 18px}
.fchip{font-size:11.5px;padding:4px 9px;border-radius:999px;border:1px solid var(--rule-strong);
  color:var(--ink-2);background:var(--surface-2)}
.fchip.high{border-color:#D8B4A0;color:#8A4B2A}
.fchip.critical{border-color:var(--bad);color:var(--bad);font-weight:500}
.fnote{margin:0;padding:0 18px 16px;font-size:11.5px;color:var(--muted);line-height:1.55;max-width:88ch}

/* The QA score table on the two desks. The sales page shows its steps as
   columns across a per-rep table; here they are rows, because a customer
   service manager reads the QA form top to bottom and this IS that form. */
.steptable td.num,.steptable th{white-space:nowrap}
td.num{font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;
  font-size:12.5px;text-align:right}
.blank{color:var(--faint);font-family:"IBM Plex Mono",monospace}

/* Save rate, as counts before it is a percentage. The rate is the headline and
   the two numbers under it are what make it mean anything — a rate over four
   cancellation requests and a rate over four hundred read identically without
   them. */
.saverow{display:flex;flex-wrap:wrap;align-items:baseline;gap:26px;padding:18px 20px;
  border-bottom:1px solid var(--rule)}
.savebig b{font-family:Oswald,sans-serif;font-size:40px;line-height:1;color:var(--ink)}
.savebig s,.savecount s{display:block;text-decoration:none;margin-top:5px;
  font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.savecount b{font-family:Oswald,sans-serif;font-size:23px;line-height:1;color:var(--ink-2)}

/* Commendations, split out of the red-flag table. They arrive in the same
   array from the grader and are the opposite of a red flag: "resolved first
   call — 255" at the top of a table headed RED FLAGS is a manager reading
   their team's best habit as their biggest problem. */
.praise{padding:14px 18px;border-top:1px solid var(--rule);background:var(--surface-2)}
.praise>b{display:block;font-family:Oswald,sans-serif;font-size:12.5px;margin-bottom:9px;
  color:var(--ink-2)}
.praise .flagwrap{padding:0}
.fchip.good{border-color:var(--good);color:var(--good);text-decoration:none;
  display:inline-flex;align-items:center;gap:7px}
.fchip.good i{font-style:normal;font-family:"IBM Plex Mono",monospace;font-size:11px;
  font-variant-numeric:tabular-nums;opacity:.75}
.fchip.good:hover{background:var(--good-soft)}

/* The per-person / per-section matrix on the two desks. A blank cell means
   that section never came up on any of their scored calls — it is not a zero,
   and it must not be shaded like a bad score. */
table td.stepcol.thin{color:var(--faint);background:none;font-weight:400}
.matrix td.stepcol,.matrix th.stepcol{padding-left:9px;padding-right:9px}
.matrix td.lead{white-space:nowrap}
/* Under three calls an average is a number, not a verdict: shown plainly with
   its own count rather than shaded green or red beside averages over thirty. */
table td.stepcol.few{background:none;font-weight:500;color:var(--ink-2)}
table td.stepcol.few i{font-style:normal;font-size:10px;color:var(--faint)}

/* The follow-up work list.
   It was a name, a truncated summary and a COUNT of flags, ordered newest
   first. A count cannot be acted on and time is not the order a queue gets
   worked in, so the row now leads with how bad it is, names what was flagged,
   and carries the actions itself. */
table.fu td{vertical-align:top;padding:14px 18px}
table.fu tr+tr td{border-top:1px solid var(--rule)}
table.fu tr.done{opacity:.45;transition:opacity .25s}
.fu-what{max-width:none}
.fu-what b{display:inline;font-family:Oswald,sans-serif;font-size:15px;letter-spacing:.01em}
.fu-when{margin-left:9px;font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--muted)}
/* The whole summary, not a cut of it. It is two or three sentences by
   construction — the grader is asked for exactly that — and a work list whose
   summary stops mid-sentence makes you open the call to find out whether it
   matters, which is the click this list exists to save. */
.fu-what s{display:block;margin-top:8px;text-decoration:none;font-size:12.5px;line-height:1.6;
  color:var(--ink-2);max-width:105ch}
.fu-flags{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}

/* How bad, in a word, before anything else on the row. */
.sev{display:inline-block;font-family:"IBM Plex Mono",monospace;font-size:9.5px;
  letter-spacing:.09em;text-transform:uppercase;padding:3px 7px;border-radius:4px;
  margin-right:9px;vertical-align:2px;font-weight:600}
.sev.critical{background:var(--bad);color:#fff}
.sev.high{background:var(--bad-soft);color:var(--bad)}
.sev.medium{background:var(--gold-soft);color:#8A6410}
.sev.low{background:var(--surface-3);color:var(--muted)}
.fchip.critical{border-color:var(--bad);color:var(--bad)}
.fchip.more{color:var(--muted)}

/* The actions, on the row. A manager who has to open the call, listen, come
   back and find their place logs the first one and none of the rest. */
.fu-do{width:1%;white-space:nowrap;text-align:right}
/* One row, not a stack. Five buttons down the side made every entry three
   hundred pixels tall and the list four screens long, which is the opposite
   of what a queue needs. */
.fu-acts{display:flex;flex-wrap:nowrap;gap:5px;margin-top:8px;justify-content:flex-end}
.btn.sm{font-size:11px;padding:4px 9px}
.fu-msg{margin-top:7px;font-size:11px;font-family:"IBM Plex Mono",monospace;color:var(--muted);
  min-height:14px}
.fu-msg.ok{color:var(--good)} .fu-msg.bad{color:var(--bad)}
/* The severity bar over the work list. 189 compliance calls and 136 coaching
   notes in one list is not a queue anybody starts. */
.sevbar{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 11px}
.sevpick{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.03em;
  padding:6px 12px;border-radius:999px;border:1px solid var(--rule-strong);
  background:var(--surface);color:var(--ink-2);cursor:pointer}
.sevpick:hover{border-color:var(--ink-2)}
.sevpick.on{background:var(--ink);color:var(--surface);border-color:var(--ink)}
.sevpick.critical{border-color:var(--bad);color:var(--bad)}
.sevpick.critical.on{background:var(--bad);color:#fff}

/* Marking one finding wrong. The cross sits on the chip because the verdict is
   about that finding, not about the call — a manager who can only say "this
   call was fine" gives me a file I cannot fix anything with. */
.fchip{position:relative}
.chipx{border:0;background:none;padding:0 0 0 6px;margin:0;cursor:pointer;
  color:var(--faint);font-size:13px;line-height:1;vertical-align:-1px}
.chipx:hover{color:var(--bad)}
.chipx:disabled{opacity:.4;cursor:default}
.fchip.struck{opacity:.5;text-decoration:line-through}
.btn.sm.wrong{border-color:var(--rule-strong);color:var(--muted)}
.btn.sm.wrong:hover{border-color:var(--bad);color:var(--bad)}
.sevpick.dl{text-decoration:none;border-style:dashed;margin-right:4px}
/* A gap between "which outcome" and "which score band" — two questions, one
   bar, and without it they read as one long row of unrelated buttons. */
.filtsep{display:inline-block;width:1px;height:20px;background:var(--rule-strong);
  margin:0 5px;align-self:center}
/* The name is the link. A row whose only way in was a button at the far right
   made you cross the whole table to open the obvious thing. */
table td.lead a{color:inherit;text-decoration:none;border-bottom:1px solid var(--rule-strong)}
table td.lead a:hover{border-bottom-color:var(--ink)}
.fu-score{font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums}
.fu-score.ok{color:var(--good)} .fu-score.mid{color:var(--gold-ink)} .fu-score.low{color:var(--bad)}

/* --- the bar's two menus (9 Oct 2026) ------------------------------------
   More: the pages past a team's own views, folded together once there is more
   than one. The account: initials, opening to the name and Sign out. */
#admintabs{display:contents}
.dropdown{position:relative;display:flex;align-items:center}
.dropdown > button{font:inherit;cursor:pointer;border:0;background:transparent}
.dropdown > .navmore-btn{color:#B9CCC0;font-family:Oswald,sans-serif;font-weight:500;font-size:13px;
  padding:6px 11px;border-radius:7px;display:flex;align-items:center;gap:5px}
.navmore-btn::after{content:"";width:0;height:0;border-left:4px solid transparent;
  border-right:4px solid transparent;border-top:5px solid currentColor;opacity:.7;margin-top:1px}
.dropdown > .navmore-btn:hover{background:rgba(255,255,255,.08);color:#fff}
.dropdown > .navmore-btn[aria-current]{background:var(--vinx-green);color:#0C2118;font-weight:600}
.dropdown .menu{display:none;position:absolute;right:0;top:calc(100% + 8px);min-width:190px;
  background:#123A39;border:1px solid rgba(255,255,255,.12);border-radius:10px;
  box-shadow:0 12px 28px rgba(0,0,0,.35);padding:6px;flex-direction:column;gap:2px;z-index:60}
.dropdown.open .menu{display:flex}
nav.tabs .dropdown .menu a{display:block;padding:8px 10px;border-radius:7px;white-space:nowrap}
.acct{margin-left:4px}
.acct-btn{padding:2px;border-radius:50%}
.avatar{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.12);color:#fff;font-family:Oswald,sans-serif;font-weight:600;
  font-size:12px;letter-spacing:.03em;border:1px solid rgba(255,255,255,.18)}
.acct-btn:hover .avatar,.acct.open .avatar{background:rgba(255,255,255,.2)}
.acct .menu .who{border-left:0;padding:8px 10px 6px;font-size:12px;color:rgba(255,255,255,.75);
  white-space:nowrap;display:block}
.acct .menu .signout{margin:0;text-align:left;padding:8px 10px;width:100%}
.acct .menu .tourreplay{margin:4px 10px}
@media(max-width:680px){
  /* The tab row scrolls sideways on a phone, and a menu inside a scrolling row
     is clipped. So on a phone the More pages are simply more tabs in the row. */
  .dropdown > .navmore-btn{display:none}
  .navmore .menu{display:contents !important}
  nav.tabs .navmore .menu a{padding:6px 11px}
  .acct{order:2;margin-left:auto}
  .acct .menu .who{display:block}
}

/* --- 9 Oct UI pass ------------------------------------------------------- */
/* Two figures to a row on a phone. One per row put seven full-width tiles
   between the page title and anything you could act on. */
@media(max-width:430px){
  .kpis>*{flex-basis:calc(50% - 5px)}
  .kpi{padding:11px 12px 10px}
  .kpi .val{font-size:26px}
}
/* The call-back panel on a call page. */
.cbpanel{padding:14px 16px;margin-bottom:12px;border-left:3px solid var(--gold-ink)}
.cbpanel.risk{border-left-color:var(--bad)}
.cbhead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.cbback{margin-left:auto;font-size:12px}
.cbissue{font-weight:600;line-height:1.45}
.cbhelp{margin-top:4px;line-height:1.45}
.cblog{margin-top:10px;display:grid;gap:8px}
.cblog input{font:inherit;font-size:13px;padding:8px 10px;border:1px solid var(--rule);border-radius:8px;
  background:var(--surface);color:inherit}
/* Call-backs: the filters, and a lighter way to log the outcome. */
.cbfilters{display:flex;gap:6px;flex-wrap:wrap;margin:14px 0 4px}
.cbfilters .btn{padding:6px 11px}
.cbfilters .btn b{font-weight:600;margin-left:4px;opacity:.7}
.cbcard .note{width:100%;box-sizing:border-box;font:inherit;font-size:13px;padding:8px 10px;
  border:1px solid var(--rule);border-radius:8px;background:var(--surface);color:inherit;margin-bottom:8px}
@media(max-width:520px){
  .cbcard .btnrow .btn{padding:6px 9px;font-size:12px}
}
/* A wide table becomes cards on a phone: each row a block, each cell a line
   with its column name in front. Sideways-scrolling a six-column table on a
   390px screen shows two columns of every row and none of the one you want. */
@media(max-width:680px){
  table.stack thead{display:none}
  table.stack, table.stack tbody, table.stack tr, table.stack td{display:block;width:100%;min-width:0}
  table.stack tr{padding:10px 12px;border-bottom:1px solid var(--line)}
  table.stack td{border:0 !important;padding:2px 0 !important;white-space:normal !important;overflow-wrap:anywhere}
  table.stack td *{white-space:normal !important}
  .card.scroll:has(table.stack){overflow-x:visible}
  table.stack td[data-label]::before{content:attr(data-label);display:block;font-family:"IBM Plex Mono",monospace;
    font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);margin-top:6px}
  table.stack td:first-child::before{margin-top:0}
}

/* === The sidebar (9 Oct 2026) ===========================================
   Tyler: "it feels so top heavy ... a bunch of tabs right across the top."
   The navigation moves down the left, grouped, the way Linear, Stripe and
   Notion lay out a work tool, so the top of every page is the page. On a
   phone it is a drawer behind a menu button. */
:root{--side-w:232px}
body.has-side{padding-left:var(--side-w)}
.side{position:fixed;inset:0 auto 0 0;width:var(--side-w);background:var(--vinx-teal);color:#DCE8E0;
  display:flex;flex-direction:column;padding:16px 12px 12px;box-sizing:border-box;z-index:50;
  border-right:1px solid rgba(255,255,255,.06);overflow-y:auto}
.side-logo{display:flex;align-items:center;gap:10px;padding:2px 8px 16px;text-decoration:none;color:#fff}
.side-logo img{height:24px;width:auto}
.side-logo .brandname{font-size:13px;padding-left:10px;border-left:1px solid rgba(255,255,255,.22);white-space:nowrap}
/* The team switch becomes a segmented control at the top of the sidebar. */
.side .teamsw{display:flex;gap:2px;padding:3px;margin:0 0 14px;border:0;border-radius:9px;
  background:rgba(0,0,0,.22)}
.side .teamsw a{flex:1;justify-content:center;padding:6px 4px;font-size:12px;border-radius:7px;color:rgba(255,255,255,.6)}
.side .teamsw a.on{background:rgba(255,255,255,.12);color:#fff;box-shadow:none}
.sidenav{display:flex;flex-direction:column;gap:1px;margin:0;flex:1}
.sidenav #admintabs{display:flex;flex-direction:column;gap:1px}
.navlbl{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;
  color:rgba(255,255,255,.38);padding:14px 10px 6px}
.sidenav > .navlbl:first-child{padding-top:2px}
.sidenav a{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:8px;text-decoration:none;
  color:rgba(255,255,255,.72);font-family:Poppins,system-ui,sans-serif;font-size:13px;font-weight:500;line-height:1.2}
.sidenav a .ico{flex:0 0 auto;opacity:.75}
.sidenav a:hover{background:rgba(255,255,255,.07);color:#fff}
.sidenav a[aria-current]{background:rgba(255,255,255,.1);color:#fff;font-weight:600;
  box-shadow:inset 3px 0 0 var(--vinx-green)}
.sidenav a[aria-current] .ico{opacity:1;color:var(--vinx-green)}
.side-foot{display:flex;align-items:center;gap:10px;padding:12px 6px 2px;margin-top:12px;
  border-top:1px solid rgba(255,255,255,.08)}
.side-foot .avatar{flex:0 0 auto}
.side-who{display:flex;flex-direction:column;min-width:0}
.side-who .who{border:0;padding:0;font-size:12px;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
.side-who .signout{margin:0;padding:0;text-align:left;font-size:10.5px;color:rgba(255,255,255,.5)}
.side-who .signout:hover:not(:disabled){background:none;color:#fff}
.side .tourreplay{margin-left:auto}
/* The page head no longer sits under a bar: a little air at the top. */
body.has-side .wrap{padding-top:10px}
.mobilebar,.scrim{display:none}

/* Phones and narrow windows: a slim bar with a menu button; the sidebar
   slides in over the page. */
@media(max-width:900px){
  body.has-side{padding-left:0}
  .mobilebar{display:flex;align-items:center;gap:12px;position:sticky;top:0;z-index:40;
    background:var(--vinx-teal);padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.06)}
  .mobilebar .logo img{height:22px}
  .mobilebar .avatar{margin-left:auto}
  .burger{background:none;border:0;color:#fff;padding:4px;cursor:pointer;display:flex}
  .side{transform:translateX(-100%);transition:transform .2s ease;box-shadow:0 0 40px rgba(0,0,0,.4)}
  body.side-open .side{transform:none}
  body.side-open .scrim{display:block;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:45}
  body.has-side .wrap{padding-top:0}
}
.avatar.sm{width:28px;height:28px;font-size:11px}
/* Older phone rules reorder the team switch; inside the sidebar it stays on top. */
.side .teamsw{order:0}
/* Room for the tour button so a long name ellipsizes instead of running under it. */
.side-foot{position:relative;padding-right:40px}
.side-foot .tourreplay{position:absolute;right:4px;top:16px;margin:0}

/* This week's focus on the rep page (21 Oct 2026) */
.wk{padding:16px 18px;margin:14px 0 4px}
.wk h3{margin:4px 0 6px;font-size:16px}
.wk h3 span{font-weight:400;color:var(--muted);font-size:13px;margin-left:6px}
.wk p{margin:6px 0;font-size:13px;line-height:1.55;color:var(--ink-2);max-width:90ch}
.wk .lab{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:600}
.wk blockquote{margin:8px 0;padding:6px 10px;border-left:3px solid var(--accent);background:var(--surface-3);border-radius:6px;font-size:13px;max-width:90ch}
.wk .row{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:10px}
