/* Shared components for both consoles. Depends on tokens.css + base.css.

   One definition per component, used by the admin console and the tenant
   portal alike. Previously each page carried its own copy and they had drifted
   — different button radii, different card padding, buttons that were
   full-width in one console and inline in the other. Divergence like that is
   what the standard's "keep behaviour consistent across similar components"
   rule exists to prevent, and it can only be enforced from one file. */

/* ============================================================
   BUTTONS
   Three levels of hierarchy, per the standard: primary (filled brand),
   secondary (.ghost, neutral outline), destructive (.danger, text-style).
   One primary button per content group.

   `.btn` is inline-sized. Full width is opt-in via `.btn.block` — the portal
   used to have it the other way round, which is why every one of its variants
   needed a `width:auto` override.
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: 0 var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: var(--accent);
  color: var(--on-accent);
  font-family: inherit;
  font-size: var(--font-size-label);
  font-weight: var(--weight-strong);
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--motion-fast) var(--ease),
              border-color var(--motion-fast) var(--ease),
              transform var(--motion-fast) var(--ease),
              filter var(--motion-fast) var(--ease);
}
.btn:hover { filter: brightness(1.08); }
/* Pressed returns to the resting position — no lingering lift. */
.btn:active { transform: translateY(0) scale(.985); filter: brightness(.96); }
.btn:disabled {
  opacity: .5;
  cursor: not-allowed;
  filter: none;
  transform: none;
  box-shadow: none;
}

.btn.block { width: 100%; }

/* Dense variant for toolbars and in-table actions. Height comes from the token
   so `@media (pointer: coarse)` in base.css can restore a full 44px target on
   touch without this rule knowing about it. */
.btn.sm {
  min-height: var(--control-h-sm);
  padding: 0 var(--space-3);
  font-size: var(--font-size-caption);
}

.btn.ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--line);
}
.btn.ghost:hover { border-color: var(--accent2); filter: none; background: rgba(59, 130, 246, .08); }

.btn.danger {
  background: transparent;
  color: var(--danger);
  border-color: var(--line);
}
.btn.danger:hover { border-color: var(--danger); filter: none; background: rgba(239, 106, 127, .08); }

/* A button stacked straight under a field had nothing separating them. `label`
   in base.css owns the label-to-input gap, but no rule owned input-to-button,
   so the control sat flush against the field it submits. Measuring the rendered
   geometry of all 24 field/button pairs in the app found three at exactly 0px
   (portal Settings twice, the signup form); the other 21 look right only because
   whoever wrote that markup remembered to add `.mt-*` by hand. Spacing that
   depends on being remembered breaks again on the next form, so it becomes a
   default here — matching `label`'s own --space-3 so the vertical rhythm of a
   form is one value throughout.

   Wrapped in :where() deliberately: zero specificity makes this a floor that
   anything more explicit silently beats — the eight buttons already carrying
   `.mt-2` keep their wider 16px, rather than being quietly tightened by a rule
   meant only to fix the ones set to nothing. */
:where(input, select, textarea) + :where(.btn, button) {
  margin-top: var(--space-3);
}
/* Except in a row: `.flex`/`.row` already space their children with `gap`, and
   a top margin there would drop the button out of line with its field. */
.flex > .btn, .flex > button,
.row > .btn, .row > button { margin-top: 0; }

/* ============================================================
   SURFACES
   ============================================================ */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--space-6);
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-1);
}

.highlight-box {
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-line);
  border-radius: var(--radius-control);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-3) 0;
}
.highlight-box label { color: var(--accent); }

.hintbox {
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--space-3);
  font-size: var(--font-size-label);
  color: var(--muted);
  word-break: break-all;
}

pre {
  white-space: pre-wrap;
  word-break: break-word;
  font-family: var(--font-mono);
  font-size: var(--font-size-caption);
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--space-3);
  color: var(--muted);
}

/* ---------- Collapsible section ----------
   A real <details>/<summary>, so keyboard operation and expanded/collapsed
   state are correct for free. Chevron down when collapsed, up when open; the
   whole summary row is the hit target, at the standard's 48px minimum. */
details.section {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-1);
}
details.section summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-body);
  font-weight: var(--weight-strong);
  cursor: pointer;
  user-select: none;
  list-style: none;
}
details.section summary::-webkit-details-marker { display: none; }
details.section summary::before {
  content: '▸';
  color: var(--muted);
  font-size: 11px;
  width: 10px;
  transition: transform var(--motion) var(--ease);
}
details.section[open] summary::before { content: '▾'; }
details.section summary .hint { font-weight: var(--weight-body); color: var(--muted); font-size: var(--font-size-label); }
details.section[open] summary { border-bottom: 1px solid var(--line); margin-bottom: var(--space-4); }
details.section .sbody { padding: 0 var(--space-4) var(--space-4); }

/* ============================================================
   TABS
   ============================================================ */
.tabs {
  display: flex;
  gap: var(--space-1);
  margin: var(--space-1) 0 var(--space-4);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.tab {
  min-height: var(--control-h);
  padding: 0 var(--space-3);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: var(--font-size-label);
  font-weight: var(--weight-label);
  cursor: pointer;
  transition: color var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease);
}
.tab:hover { color: var(--text); }
/* Selected state carries a border as well as a colour change, so it does not
   depend on colour alone. */
.tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: var(--weight-strong); }

/* ============================================================
   TABLES
   The container scrolls, never the page.
   ============================================================ */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: var(--font-size-label); }
th, td { text-align: left; padding: var(--space-2); border-bottom: 1px solid var(--line); }
th {
  color: var(--muted);
  font-size: var(--font-size-caption);
  font-weight: var(--weight-strong);
  text-transform: uppercase;
  letter-spacing: .04em;
  white-space: nowrap;
}
td { max-width: 340px; overflow-wrap: break-word; }
td.trunc { max-width: 220px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
tbody tr:hover { background: rgba(59, 130, 246, .05); }

/* ============================================================
   BADGES + STATUS
   Status is never colour alone — a badge always carries its own text label.
   ============================================================ */
.badge {
  display: inline-block;
  font-size: var(--font-size-caption);
  font-weight: var(--weight-label);
  padding: 2px var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
}
.badge.ok { color: var(--accent); border-color: var(--accent-soft-line); }
.badge.err { color: var(--danger); border-color: var(--danger-soft-line); }
.badge.warn { color: var(--warn); border-color: #5a4620; }

.err { color: var(--danger); font-size: var(--font-size-label); margin-top: var(--space-2); min-height: 16px; }

/* ============================================================
   MODALS — elevation level 3
   ============================================================ */
.modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: rgba(0, 0, 0, .6);
}
.modal .box {
  width: 420px;
  max-width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--space-6);
  box-shadow: var(--shadow-3);
}
.modal .box.wide { width: 600px; }

/* Follow-up notes inside the notes modal. */
.note-item {
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--space-3);
  margin-bottom: var(--space-2);
}
.note-meta { margin-left: auto; font-size: var(--font-size-caption); color: var(--muted); }
.note-body { margin-top: var(--space-2); font-size: var(--font-size-label); }

/* Operator key gate — a full-page block, not a dismissible overlay. */
.keygate {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: var(--bg);
}
.keygate .box {
  width: 380px;
  max-width: 100%;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--space-8);
  box-shadow: var(--shadow-3);
}

/* ============================================================
   TOAST — announced via role="status" on the element itself
   ============================================================ */
.toast {
  position: fixed;
  bottom: var(--space-6);
  left: 50%;
  z-index: 100;
  max-width: 90vw;
  padding: var(--space-3) var(--space-6);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  font-size: var(--font-size-label);
  box-shadow: var(--shadow-2);
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(6px);
  transition: opacity var(--motion) var(--ease), transform var(--motion) var(--ease);
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
/* Prefixed with a glyph so success and failure differ by more than hue. */
.toast.ok { border-color: var(--accent-soft-line); color: var(--accent); }
.toast.ok::before { content: '✓ '; }
.toast.err { border-color: var(--danger-soft-line); color: var(--danger); }
.toast.err::before { content: '⚠ '; }

/* ============================================================
   PAGINATION
   ============================================================ */
.pager { gap: var(--space-1); margin-top: var(--space-3); flex-wrap: wrap; }
.pager .btn.active { border-color: var(--accent); color: var(--accent); }
.pager .ellipsis { color: var(--muted); padding: 0 2px; font-size: var(--font-size-caption); }

/* ============================================================
   HINT ICON
   Hover *and* focus, because touch and keyboard users have no hover state and
   the standard forbids hiding information behind one.
   ============================================================ */
.hint-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #1c2740;
  color: var(--muted);
  font-size: 10px;
  font-weight: var(--weight-heading);
  vertical-align: middle;
  cursor: help;
}
.hint-ico:hover, .hint-ico:focus { background: var(--accent2); color: var(--on-accent); }
.hint-ico::after {
  content: attr(data-tip);
  position: absolute;
  bottom: 130%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  width: 220px;
  max-width: 60vw;
  padding: var(--space-2) var(--space-3);
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  color: var(--text);
  font-size: var(--font-size-caption);
  font-weight: var(--weight-body);
  line-height: 1.45;
  white-space: normal;
  box-shadow: var(--shadow-2);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--motion-fast) var(--ease);
}
.hint-ico:hover::after, .hint-ico:focus::after { opacity: 1; }

/* ============================================================
   CHAT (test agent, portal help widget)
   ============================================================ */
.chatlog {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 88px;
  max-height: 360px;
  overflow-y: auto;
  padding: var(--space-1);
}
.msg {
  max-width: 80%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-card);
  font-size: var(--font-size-label);
  line-height: var(--leading-body);
}
.msg.user { align-self: flex-end; background: #14203c; border: 1px solid #26406f; }
.msg.ai { align-self: flex-start; background: var(--accent-soft); border: 1px solid var(--accent-soft-line); }

.help-widget { position: fixed; right: var(--space-6); bottom: var(--space-6); z-index: 80; }
.help-bubble {
  width: 52px;
  height: 52px;
  border: none;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: var(--on-accent);
  font-size: 22px;
  cursor: pointer;
  box-shadow: var(--shadow-2);
}
.help-bubble:hover { filter: brightness(1.08); }
.help-panel {
  position: fixed;
  right: var(--space-6);
  bottom: 84px;
  display: flex;
  flex-direction: column;
  width: 340px;
  max-width: 90vw;
  height: 440px;
  max-height: 70vh;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-3);
}
.help-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3);
  border-bottom: 1px solid var(--line);
  font-size: var(--font-size-body);
  font-weight: var(--weight-strong);
}
.help-log { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); }
.help-log .msg { max-width: 85%; }
.help-input-row { display: flex; gap: var(--space-2); padding: var(--space-2); border-top: 1px solid var(--line); }
.help-input-row input { flex: 1; width: auto; }

/* ============================================================
   CHARTS
   Legend is always present for a two-series chart, so identity never rests on
   colour alone.
   ============================================================ */
.chart-legend {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-2);
  font-size: var(--font-size-caption);
  color: var(--muted);
}
.chart-legend span { display: inline-flex; align-items: center; gap: var(--space-1); }
.chart-legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }

/* ============================================================
   STATS
   ============================================================ */
.stat .n { font-size: var(--font-size-h2); font-weight: var(--weight-heading); margin-top: var(--space-1); }
.bar {
  height: 10px;
  margin-top: var(--space-2);
  overflow: hidden;
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
}
.bar .fill { height: 100%; background: var(--accent); }

.capbox { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); margin-top: var(--space-3); }
.capbox .k { font-size: var(--font-size-caption); color: var(--muted); }
.capbox .v { font-size: var(--font-size-label); font-weight: var(--weight-strong); color: var(--accent); min-height: 16px; }

.section-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-lg);
  font-weight: var(--weight-strong);
  margin-bottom: var(--space-3);
}
.section-title .count {
  padding: 2px var(--space-2);
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: var(--font-size-caption);
  font-weight: var(--weight-body);
  color: var(--muted);
}

/* ============================================================
   LAYOUT UTILITIES
   Deliberately few — the standard's "keep the number of visual styles
   intentionally small" applies to utilities too.
   ============================================================ */
.flex { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.spacer { flex: 1; }

/* Two columns by default; `.cols-3` for stat rows. Both collapse to one column
   below the tablet breakpoint. */
.row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.row.cols-3 { grid-template-columns: repeat(3, 1fr); }

.muted { color: var(--muted); font-size: var(--font-size-label); }
.empty, .skeleton { color: var(--muted); text-align: center; padding: var(--space-10); font-size: var(--font-size-body); }

.mt-1 { margin-top: var(--space-2); }
.mt-2 { margin-top: var(--space-4); }
.w-sm { max-width: 180px; }
.w-md { max-width: 220px; }

/* Visual-only heading sizes, for when the correct semantic level looks wrong.
   Using these keeps heading order honest — see base.css. */
.h2 { font-size: var(--font-size-h2); font-weight: var(--weight-heading); }
.h3 { font-size: var(--font-size-lg); font-weight: var(--weight-strong); margin-bottom: var(--space-2); }

@media (max-width: 767px) {
  .row, .row.cols-3 { grid-template-columns: 1fr; }
  .capbox { grid-template-columns: 1fr; }
  .help-widget { right: var(--space-3); }
  .help-panel { right: var(--space-3); bottom: 78px; width: calc(100vw - var(--space-6)); }
  /* Inline button pairs stack and go full width rather than shrinking below a
     usable size. */
  .flex > .btn.block-mobile { width: 100%; }
}
