/* Components. Every value comes from a token in tokens.css. */

/* --- Utility -------------------------------------------------------------- */

.eyebrow {
  display: block;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
}

.eyebrow-dim { color: var(--ink-4); }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.dim { color: var(--ink-3); }
.dimmer { color: var(--ink-4); }
.small { font-size: 12px; }
.tiny { font-size: 11px; }
.strike { text-decoration: line-through; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.spacer { margin-left: auto; }
.stack { display: grid; gap: 18px; }
.stack-sm { display: grid; gap: 10px; }
.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }

/* --- Mark ---------------------------------------------------------------- */

/* The mark is the artwork itself, which already carries the mint-to-periwinkle
 * gradient, so it needs no fill behind it. Height comes from aspect-ratio, so a
 * caller sets width alone and cannot stretch the logo by accident. */
.mark {
  display: inline-block;
  flex: none;
  aspect-ratio: 1.003;
  /* 136%, not the 141.8% that would make the artwork exactly fill the box:
   * the outermost strokes sit on the boundary at that size and lose half
   * their width to background-clip. This keeps ~2% margin all round. */
  background: url("../brand/mark.png") center / 136% no-repeat;
}

/* --- Avatar -------------------------------------------------------------- */

.avatar {
  display: grid;
  place-items: center;
  flex: none;
  border-radius: 99px;
  background: linear-gradient(150deg, var(--surface-hover), var(--surface-2));
  border: 1px solid var(--line-strong);
  color: var(--ink-2);
  font-family: var(--font-mono);
  font-weight: 600;
}

/* --- Panel --------------------------------------------------------------- */

.panel {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 20px;
}

.panel-flush { padding: 0; overflow: hidden; }

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.panel-flush > .panel-head {
  padding: 17px 20px 14px;
  margin-bottom: 0;
  border-bottom: 1px solid var(--line);
}

.panel-title { font-size: 17px; font-weight: 500; color: var(--ink); }
.panel-note { margin-top: 4px; font-size: 12px; color: var(--ink-3); }

/* --- Pill ---------------------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: 99px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid transparent;
}

.pill.dot::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 99px;
  background: currentColor;
  flex: none;
}

.t-accent {
  color: var(--accent);
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 26%, transparent);
}
.t-good {
  color: var(--good);
  background: color-mix(in srgb, var(--good) 12%, transparent);
  border-color: color-mix(in srgb, var(--good) 28%, transparent);
}
.t-warn {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}
.t-alarm {
  color: var(--alarm);
  background: var(--alarm-wash);
  border-color: color-mix(in srgb, var(--alarm) 32%, transparent);
}
.t-neutral {
  color: var(--ink-2);
  background: var(--surface-2);
  border-color: var(--line);
}
.t-quiet { color: var(--ink-3); background: transparent; border-color: var(--line); }

/* --- Buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 20px;
  border-radius: var(--r-btn);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  border: 1px solid transparent;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

/* The primary action lifts off the page rather than only being coloured.
 *
 * `--shadow-btn` is its own token because the shadow has to be the button's own
 * colour rather than the page's: a warm brown shadow under a periwinkle button
 * reads as smudge, and the tint under a filled control is always a darker step
 * of the fill. The dark theme sets it to the brand glow instead, which is how
 * that theme lifts anything.
 *
 * The fill itself is unchanged. It measures 4.96:1 against the white it
 * carries, and a more saturated step would have to take the label with it. */
.btn-primary {
  background: var(--accent-btn);
  color: var(--ink-on-accent);
  box-shadow: var(--shadow-btn);
}
.btn-primary:hover {
  background: var(--accent-btn-hover);
  box-shadow: var(--shadow-btn-hover);
}

/* The outline needs a border somebody can see. It read --line-strong, which is
 * a hairline for dividing a card, not for drawing a control: at 1.47:1 on white
 * the button had no edge until you hovered it. It takes the ink ramp instead,
 * so the outline is the same family as its own label. */
.btn-ghost {
  color: var(--ink-2);
  border-color: var(--btn-ghost-line);
}
.btn-ghost:hover {
  background: var(--surface-hover);
  color: var(--ink);
  border-color: var(--ink-3);
}
.btn-danger {
  color: var(--alarm);
  border-color: color-mix(in srgb, var(--alarm) 40%, transparent);
}
.btn-danger:hover { background: var(--alarm-wash); }
.btn-sm { padding: 6px 15px; font-size: 12px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* The one primary action on a form page, at a size that says so. 40px is also
 * comfortably above the 44px-with-padding touch guidance once the surrounding
 * gap is counted, and it stops the submit button reading as the least
 * important control in the card. */
.btn-block {
  width: 100%;
  min-height: 40px;
  font-size: 14px;
}

/* --- Forms --------------------------------------------------------------- */

/* `align-content: start` is what stops a field being stretched by its neighbour.

   In a `.grid-2` the two columns are the same height, so a field beside a taller
   one is given the extra height, and its own auto rows then absorbed it: on the
   treatments screen the Treatment select rendered 62px tall against a 43px price
   row beside it, and its label sat 14px lower than the label next to it. Two
   fields on one line that agree on neither their tops nor their heights is what
   "line up the input boxes" was reporting.

   The spare height goes to the bottom of the field now, where it is invisible,
   rather than into the control. */
.field { display: grid; gap: 6px; min-width: 0; align-content: start; }
.label { font-size: 12px; color: var(--ink-3); }
.hint { font-size: 11px; color: var(--ink-4); }

.input,
.textarea,
.select {
  width: 100%;
  background: var(--surface-2);
  /* A resting border, where this was `transparent` and only drew one on hover.
   *
   * On the dark theme that works: --surface-2 is a lighter navy than the panel
   * behind it, so a field has an edge whether or not it has a border. On paper
   * --surface-2 is pure white, and half the forms in this product sit on a
   * white card, so a field was a white box on a white box and the only thing
   * saying where to type was the placeholder.
   *
   * --line-strong rather than --line, because this is the edge of a control
   * somebody has to find, not a divider between two areas. */
  border: 1px solid var(--line-strong);
  border-radius: var(--r-3);
  padding: 10px 12px;
  font-size: 14px;
  color: var(--ink);
  font-family: inherit;
  transition: border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.input:hover, .textarea:hover, .select:hover { border-color: var(--ink-4); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--accent);
  /* A ring as well as a colour. A one pixel border changing hue is the weakest
   * focus cue there is, and it is the one people who tab through a form rely
   * on. --focus-ring is a per theme value, because the alpha that reads on
   * paper and the alpha that reads on navy are not the same number. */
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-4); }
.textarea { min-height: 76px; resize: vertical; }
.select { appearance: none; cursor: pointer; }

.check {
  appearance: none;
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: var(--r-1);
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  display: grid;
  place-content: center;
  cursor: pointer;
}
.check:checked { background: var(--accent); border-color: var(--accent); }
.check:checked::after {
  content: "";
  width: 8px;
  height: 4px;
  border-left: 1.8px solid var(--ink-on-accent);
  border-bottom: 1.8px solid var(--ink-on-accent);
  transform: rotate(-45deg) translate(0.5px, -1px);
}

.toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-2);
  cursor: pointer;
  white-space: nowrap;
}

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }

@media (max-width: 760px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
}

/* --- Stats --------------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}

.stat {
  background: var(--surface-1);
  padding: 15px 17px 17px;
  display: grid;
  gap: 7px;
  min-width: 0;
}

.stat-value {
  font-family: var(--font-mono);
  font-size: 25px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.stat-value.alarm { color: var(--alarm); }
.stat-value.good { color: var(--good); }
.stat-sub { font-size: 12px; color: var(--ink-3); }

/* A stat that opens something. The affordance is deliberately quiet until
 * hover: four tiles all shouting "Open" is worse than none of them. */
.stat-link {
  position: relative;
  text-decoration: none;
  color: inherit;
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.stat-link:hover,
.stat-link:focus-visible {
  background: var(--surface-2);
}

.stat-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.stat-go {
  position: absolute;
  top: 15px;
  right: 15px;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}

.stat-link:hover .stat-go,
.stat-link:focus-visible .stat-go { opacity: 1; }

/* --- Rows / lists -------------------------------------------------------- */

.rows { display: grid; }

/* The middle track carries the row's own text, and it may not be sized by it.
 *
 * `1fr` is `minmax(auto, 1fr)`, and that `auto` floor is the content's own
 * minimum, so a long word or a long caller string in the middle column widens
 * the track it sits in and squeezes whatever is beside it. Every row in the
 * product survives that today only because `.grow` sets `min-width: 0`, which
 * is the same override written on the child instead of the track: the day
 * somebody puts a middle column in a row without that class, the fault is back.
 *
 * It is the fault the gaps list had, where the question was in the first track
 * instead and the answer box was crushed to 77px. `.gap-row` in shell.css sets
 * its own columns and overrides this line.
 *
 * Measured before changing it, across 563 rows on seven portal pages at 1440px
 * and 375px: every row's box and computed columns are identical either way, so
 * this changes nothing that renders today and only holds for what is added
 * next.
 */
.list-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  width: 100%;
  padding: 12px 20px;
  text-align: left;
  border-top: 1px solid var(--line);
  transition: background var(--dur) var(--ease);
}

.rows > .list-row:first-child { border-top: 0; }
.list-row:hover { background: var(--surface-hover); }

.row-title {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
}

.row-sub {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
}

.row-side { display: flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; }

.stamp { display: grid; justify-items: center; gap: 2px; flex: none; width: 52px; }
.stamp-main {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.stamp-sub {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-4);
}

@media (max-width: 760px) {
  .list-row { grid-template-columns: auto 1fr; row-gap: 9px; }
  .row-side { grid-column: 2; }
}

/* --- Field list ---------------------------------------------------------- */

.fields {
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  overflow: hidden;
}

.fields > div {
  background: var(--surface-1);
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 160px 1fr auto;
  gap: 12px;
  align-items: baseline;
}

.f-label { font-size: 12px; color: var(--ink-3); }
.f-value { font-size: 13px; color: var(--ink); min-width: 0; overflow-wrap: break-word; }

@media (max-width: 640px) {
  .fields > div { grid-template-columns: 1fr; gap: 4px; }
}

/* --- Filters ------------------------------------------------------------- */

.filters { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

.filter {
  padding: 6px 11px;
  border-radius: 99px;
  border: 1px solid var(--line);
  font-size: 12px;
  color: var(--ink-3);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

.filter:hover { color: var(--ink); border-color: var(--line-strong); }
.filter.on {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--accent);
  font-weight: 500;
}
.filter .n { font-family: var(--font-mono); font-size: 10px; margin-left: 5px; opacity: 0.75; }

/* --- Callout ------------------------------------------------------------- */

.callout {
  border-radius: var(--r-3);
  padding: 12px 14px;
  font-size: 13px;
}

.callout-accent {
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
.callout-warn {
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
}
.callout-alarm {
  background: var(--alarm-wash);
  border: 1px solid color-mix(in srgb, var(--alarm) 30%, transparent);
}
.callout-good {
  background: color-mix(in srgb, var(--good) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--good) 34%, transparent);
}

/*
  The Brin number on the dashboard. Large enough to read off a screen while
  typing it into a phone system on the other hand, which is exactly how it gets
  used, and tabular so the groups line up.
*/
/* The number and the month's minutes, side by side.
 *
 * Two facts about the line rather than about any one call, so they share a
 * panel. The minutes sit on the right and their figure is set on the same
 * baseline as the number's, which is what makes the pair read as one row
 * rather than as a panel with something added to it. */
.brin-number {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px 28px;
}

.brin-number-main {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Takes the slack, so the minutes stay against the right edge rather than
   * floating in the middle of a wide panel. */
  flex: 1 1 340px;
  min-width: 0;
}

.brin-usage {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 0 0 auto;
  text-align: right;
  /* Never wider than the sentence beside it needs, so a three digit figure
   * does not push the number's own copy into a column. */
  max-width: 30ch;
}

.brin-usage-value {
  margin: 0;
  font-family: var(--font-sans);
  /* Tabular for the same reason the number is: these two figures sit one
   * above the other across a month and should not shuffle sideways. */
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink-1);
}

/* Smaller and quieter than the figure it follows. The used minutes are what
 * somebody is looking for; the allowance is the context for it. */
.brin-usage-of {
  margin-left: 7px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-3);
}

.brin-usage-note { margin: 0; }

/* Under 640px there is no room for two columns, and a right-aligned block
 * under a left-aligned one reads as a mistake rather than as a layout. */
@media (max-width: 640px) {
  .brin-usage {
    text-align: left;
    max-width: none;
  }
}
.brin-number-value {
  margin: 0;
  /*
    Tabular sans rather than mono. The digits still line up, which is what
    matters when somebody reads this off the screen while typing it into a
    phone system, but a monospaced number reads as code and this product is
    meant to feel like a business's own front desk rather than a console.
  */
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink-1);
  /* Selectable in one click, because copying it by hand is the point. */
  user-select: all;
}
.brin-number-waiting {
  /* Not a number, so it must not read as one. */
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 500;
  color: var(--ink-3);
  user-select: auto;
}

.empty {
  padding: 34px 20px;
  text-align: center;
  display: grid;
  gap: 6px;
  justify-items: center;
  color: var(--ink-3);
  font-size: 13px;
}

/* --- Meter --------------------------------------------------------------- */

.meter { height: 4px; border-radius: 99px; background: var(--surface-2); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 99px; background: var(--brand-gradient-h); }
.meter > span.good { background: var(--good); }
.meter > span.warn { background: var(--warn); }
.meter > span.alarm { background: var(--alarm); }

/* --- Terms --------------------------------------------------------------- */
/* A reading measure. Legal text nobody can read is legal text nobody read. */

.terms { max-width: 720px; gap: 22px; }
.terms-title { font-size: 27px; font-weight: 500; letter-spacing: -0.016em; }
.terms-lede { font-size: 13px; color: var(--ink-3); }
.terms-s { display: grid; gap: 10px; }
.terms-s h2 {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: var(--ls-tight);
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.terms-s p { font-size: 14px; line-height: 1.62; color: var(--ink-2); }
.terms-s h3 {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: var(--ls-tight);
  color: var(--ink-2);
  margin-top: 4px;
}
.terms-toc {
  display: grid;
  gap: 8px;
  padding: 15px 17px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface-2);
}
.terms-toc ol {
  margin: 0;
  padding-left: 19px;
  display: grid;
  gap: 4px;
  column-gap: 20px;
}
.terms-toc li { font-size: 13px; color: var(--ink-3); }
.terms-toc a { color: var(--ink-2); text-decoration: none; }
.terms-toc a:hover { color: var(--accent); text-decoration: underline; }
@media (min-width: 620px) {
  .terms-toc ol { grid-template-columns: 1fr 1fr; }
}
.terms-s b { font-weight: 600; color: var(--ink); }
.terms-list { display: grid; gap: 9px; }
.terms-list li {
  font-size: 14px;
  line-height: 1.62;
  color: var(--ink-2);
  padding-left: 15px;
  position: relative;
}
.terms-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 4px;
  height: 4px;
  border-radius: 99px;
  background: var(--ink-4);
}

/* --- Flash --------------------------------------------------------------- */

.flashes { display: grid; gap: 8px; margin-bottom: 16px; }

.flash {
  border-radius: var(--r-3);
  padding: 11px 13px;
  font-size: 13px;
}

.flash.ok {
  background: color-mix(in srgb, var(--good) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--good) 34%, transparent);
}
.flash.error {
  background: var(--alarm-wash);
  border: 1px solid color-mix(in srgb, var(--alarm) 34%, transparent);
}

/* --- Lifecycle (signature element) -------------------------------------- */
/*
 * Ten steps, in order, because the order carries information a reviewer needs:
 * exactly how far a call got and which step stopped it.
 */

.spine { display: grid; }

.spine li {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 12px;
  position: relative;
  padding-bottom: 14px;
}

.spine li:last-child { padding-bottom: 0; }

.spine li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 24px;
  bottom: -2px;
  width: 1px;
}

.node {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 99px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  position: relative;
  z-index: 1;
}

.s-done .node {
  background: color-mix(in srgb, var(--good) 18%, transparent);
  color: var(--good);
  border: 1px solid color-mix(in srgb, var(--good) 45%, transparent);
}
.s-done::before { background: color-mix(in srgb, var(--good) 40%, transparent); }

.s-skipped .node {
  color: var(--ink-4);
  border: 1px dashed var(--line-strong);
}
.s-skipped::before { background: var(--line-strong); }

.s-failed .node {
  background: var(--alarm-wash);
  color: var(--alarm);
  border: 1px solid color-mix(in srgb, var(--alarm) 60%, transparent);
}
.s-failed::before {
  background: repeating-linear-gradient(
    to bottom,
    color-mix(in srgb, var(--alarm) 50%, transparent) 0 3px,
    transparent 3px 6px
  );
}

.s-unreached .node {
  color: var(--ink-4);
  border: 1px solid var(--line);
  opacity: 0.65;
}
.s-unreached::before {
  background: repeating-linear-gradient(
    to bottom, var(--line) 0 3px, transparent 3px 6px
  );
}

.step-label { font-size: 13px; color: var(--ink-2); }
.s-unreached .step-label, .s-skipped .step-label { color: var(--ink-4); }
.s-failed .step-label { color: var(--alarm); font-weight: 500; }

.step-state {
  display: inline-block;
  margin-top: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-4);
}

/* Compact strip, so a call list reads at a glance. */
.lifebar { display: inline-flex; gap: 2px; flex: none; }
.lifebar span { width: 6px; height: 15px; border-radius: 1.5px; }
.lifebar .done { background: color-mix(in srgb, var(--good) 62%, transparent); }
.lifebar .skipped { background: var(--line-strong); }
.lifebar .failed { background: var(--alarm); }
.lifebar .unreached { background: var(--line); }

/* --- Transcript ---------------------------------------------------------- */

.transcript { display: grid; gap: 12px; }
.turn { display: grid; grid-template-columns: 40px 1fr; gap: 12px; }
.turn-at {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-4);
  padding-top: 3px;
  font-variant-numeric: tabular-nums;
}

.bubble {
  border-radius: var(--r-3);
  padding: 9px 12px;
  font-size: 13px;
  min-width: 0;
  overflow-wrap: break-word;
}

.b-caller { background: var(--surface-2); color: var(--ink); }
.b-assistant {
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
}
.b-system {
  border: 1px dashed var(--line-strong);
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 11px;
}

.who {
  display: block;
  margin-bottom: 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.qa-note {
  display: flex;
  gap: 7px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  color: var(--ink-3);
}

.qa-note b {
  color: var(--signal);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.07em;
  flex: none;
}

/* --- The ticket sheet ----------------------------------------------------- */

/* A list row that is a button. Buttons bring their own font, background, and
 * border, none of which match a row, so they are reset here rather than in a
 * style attribute on every one. */
.as-row {
  font: inherit;
  color: inherit;
  background: none;
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
  cursor: pointer;
}

.sheet {
  width: min(94vw, 680px);
  max-height: 88vh;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-card);
  background: var(--surface-1);
  color: var(--ink);
  box-shadow: var(--shadow-elev);
  overflow: hidden;
}

/* Backdrop styling is global, in tokens.css: every dialog blurs
 * what is behind it and holds the page still. */

.sheet-head {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 20px 22px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

.sheet-head-side {
  display: flex;
  gap: 9px;
  align-items: center;
  flex: none;
}

.sheet-title {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: var(--ls-display);
  margin: 5px 0 0;
}

.sheet-meta { font-size: 12px; color: var(--ink-3); margin: 6px 0 0; }

.sheet-close {
  width: 30px;
  height: 30px;
  border-radius: var(--r-2);
  border: 1px solid var(--line);
  background: var(--surface-1);
  color: var(--ink-3);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
}

.sheet-close:hover { color: var(--ink); border-color: var(--line-strong); }

/* The body scrolls, the header does not. A long comment thread should not push
 * the ticket reference off the screen. */
.sheet-body {
  padding: 20px 22px 24px;
  overflow-y: auto;
  max-height: calc(88vh - 108px);
}

.sheet-quote {
  margin: 8px 0 0;
  padding: 12px 14px;
  border-left: 2px solid var(--line-strong);
  background: var(--surface-2);
  border-radius: 0 var(--r-2) var(--r-2) 0;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
}

.sheet-actions {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

/* --- Comments ------------------------------------------------------------- */

/* The left edge carries the audience, because that is the thing an operator
 * most needs to read at a glance and least wants to get wrong. */
.note {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  border-radius: var(--r-3);
  background: var(--surface-2);
  display: grid;
  gap: 8px;
}

.note-shared { border-left-color: var(--good); }
.note-internal { border-left-color: var(--signal); }

.note-who { font-size: 12.5px; font-weight: 600; }
.note-when { font-size: 12px; }
.note-body {
  font-size: 13px;
  line-height: 1.6;
  margin: 0;
  white-space: pre-wrap;
}

/* --- The visibility switch ------------------------------------------------ */

.switch {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  background: var(--surface-2);
  cursor: pointer;
  font-size: 13px;
}

.switch input { margin-top: 2px; flex: none; }
.switch strong { display: block; font-weight: 600; }
.switch-note {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: var(--ink-3);
}

/* When it is on, say so loudly. This is the control that decides whether a
 * client reads the comment. */
.switch:has(input:checked) {
  border-color: color-mix(in srgb, var(--good) 42%, transparent);
  background: color-mix(in srgb, var(--good) 9%, var(--surface-2));
}

/* --- Readiness ------------------------------------------------------------ */

.gate {
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}

.gate-head {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 14px 18px;
  background: var(--surface-2);
}

.gate-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  margin: 0;
}

.ritem {
  background: var(--surface-1);
  padding: 16px 18px;
  display: grid;
  gap: 11px;
}

.ritem-met { border-left: 2px solid var(--good); }
.ritem-partial { border-left: 2px solid var(--warn); }
.ritem-not_met { border-left: 2px solid var(--line-strong); }

.ritem-title { font-size: 13.5px; font-weight: 600; }
.ritem-accept {
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-3);
  margin: 0;
  max-width: 78ch;
}

/* The three-way state control. Radios rather than a dropdown, so all three
 * states and the current one are visible without a click. */
.states { display: flex; gap: 6px; flex-wrap: wrap; }

.states label {
  padding: 5px 12px;
  border-radius: 99px;
  border: 1px solid var(--line);
  font-size: 12px;
  color: var(--ink-3);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

.states label:hover { color: var(--ink); border-color: var(--line-strong); }
.states input { position: absolute; opacity: 0; pointer-events: none; }

.states label:has(input:checked) { font-weight: 500; }
.states label.s-met:has(input:checked) {
  background: color-mix(in srgb, var(--good) 15%, transparent);
  border-color: color-mix(in srgb, var(--good) 40%, transparent);
  color: var(--good);
}
.states label.s-partial:has(input:checked) {
  background: color-mix(in srgb, var(--warn) 15%, transparent);
  border-color: color-mix(in srgb, var(--warn) 40%, transparent);
  color: var(--warn);
}
.states label.s-not_met:has(input:checked) {
  background: var(--surface-hover);
  border-color: var(--line-strong);
  color: var(--ink-2);
}

.states label:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* --- Pagination ----------------------------------------------------------- */

.pager {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
  padding: 14px 18px;
  border-top: 1px solid var(--line);
}

.pager a,
.pager span.here {
  min-width: 32px;
  padding: 6px 10px;
  border-radius: var(--r-2);
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 12px;
  text-align: center;
  color: var(--ink-3);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.pager a:hover { background: var(--surface-hover); color: var(--ink); }

.pager span.here {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--accent);
  font-weight: 500;
}

.pager .off {
  opacity: 0.4;
  pointer-events: none;
}

.pager-gap { color: var(--ink-3); padding: 0 2px; font-size: 12px; }

.pager-note {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-3);
}

/* --- Accounts ------------------------------------------------------------- */

.acct-off { opacity: 0.55; }
.acct-off .row-title { text-decoration: line-through; }

@media (max-width: 640px) {
  .sheet { width: 96vw; max-height: 92vh; }
  .sheet-body { max-height: calc(92vh - 108px); }
  .pager-note { margin-left: 0; width: 100%; }
}

/* ======================================================================
 * Disclosure
 *
 * One collapsible section, built on <details>/<summary> and nothing else.
 * No JavaScript: the element already does open, close, keyboard, and find-in-
 * page, and a scripted reimplementation of it loses the last one silently.
 *
 * Used wherever a page has more on it than anyone needs at once: the call
 * lifecycle, the assistant's answer library, the safety limits.
 * ==================================================================== */

.disclosure {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface-2);
}

.disclosure + .disclosure { margin-top: 9px; }

.disclosure > summary {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 13px 16px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
  border-radius: var(--r-card);
  user-select: none;
}

/* The default marker is replaced rather than hidden, because removing it
 * without putting anything back leaves no sign the row opens. */
.disclosure > summary::-webkit-details-marker { display: none; }

.disclosure > summary::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-right: 1.6px solid var(--ink-3);
  border-bottom: 1.6px solid var(--ink-3);
  transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease);
}

.disclosure[open] > summary::before { transform: rotate(45deg); }

.disclosure > summary:hover { background: var(--surface-hover); }

/* Keyboard focus stays visible. A summary is a real control and loses its
 * outline the moment anyone restyles it without putting one back. */
.disclosure > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.disclosure > summary .tiny { margin-left: auto; }

.disclosure-body {
  padding: 3px 16px 16px;
  border-top: 1px solid var(--line);
  padding-top: 14px;
}

/* --- Password fields ----------------------------------------------------- */

/*
  The show/hide control lives inside the input's own box, so the button belongs
  to the thing being typed in rather than to the field, which may also hold a
  label and a list of rules.
*/
.pw-wrap {
  position: relative;
  display: block;
}

.pw-wrap .input {
  /* Room for the button, so a long password never runs under it. */
  padding-right: 42px;
}

.pw-eye {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
}

.pw-eye:hover { color: var(--ink); background: var(--surface-hover); }
.pw-eye:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pw-eye.on { color: var(--accent); }

.pw-eye svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}

/* One glyph at a time: open eye while hidden, struck-through while shown. */
.pw-eye .pw-shut { display: none; }
.pw-eye.on .pw-open { display: none; }
.pw-eye.on .pw-shut { display: block; }

/*
  The rules, as a list rather than a sentence.

  Every item starts neutral. An untouched field showing five red crosses reads
  as five mistakes somebody has already made, so the ticks only appear once
  there is something to judge, which is what `.pw-rules-live` switches on.
*/
.pw-rules {
  margin: 7px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 3px;
}

.pw-rules li {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--ink-3);
}

.pw-rules li::before {
  content: "";
  flex: none;
  width: 5px;
  height: 5px;
  margin-left: 4px;
  border-radius: 99px;
  background: var(--ink-4);
}

.pw-rules-live li::before {
  /* A ring, so an unmet rule is visibly "not yet" rather than wrong. */
  width: 11px;
  height: 11px;
  margin-left: 0;
  border: 1.5px solid var(--line-strong);
  background: transparent;
}

.pw-rules-live li.met {
  color: var(--good);
}

.pw-rules-live li.met::before {
  border-color: var(--good);
  background: var(--good);
  /* The tick, drawn rather than loaded. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 6.3 5 8.4 9.2 4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 11px 11px;
}


/* The call button with nothing to call.

   Shown rather than hidden, because the control disappearing reads as a page
   that failed to load, while a dimmed one with a sentence beside it reads as a
   step that has not happened yet. `not-allowed` is the cursor that says the
   difference before anybody clicks. */
.dial-btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(1);
}
.dial-btn[disabled]:hover { transform: none; }
.dial-btn[disabled] .dial-ring { animation: none; opacity: 0.3; }
