/* Reusable UI components. Every one is driven by tokens, so both themes and
   any future rebrand are a change to tokens.css alone. */

/* --- Button ---------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  height: 34px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: 1;
  white-space: nowrap;
  transition: background-color var(--duration-fast) ease,
              border-color var(--duration-fast) ease,
              color var(--duration-fast) ease,
              box-shadow var(--duration-fast) ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(0.5px); }
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}
.btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* Dark text on gold. White on this accent tops out at 2.7:1; the pairing
   below is 9.3:1, and is what the storefront's gold buttons already do.
   Hover darkens a step (6.7:1), which still passes comfortably. */
.btn--primary {
  background: var(--accent-400);
  color: var(--accent-contrast);
  border-color: var(--accent-400);
  box-shadow: var(--shadow-xs);
}
.btn--primary:hover { background: var(--accent-500); border-color: var(--accent-500); }

.btn--secondary {
  background: var(--bg-surface);
  color: var(--text-primary);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}
.btn--secondary:hover { background: var(--bg-hover); }

.btn--ghost { background: transparent; color: var(--text-secondary); }
.btn--ghost:hover { background: var(--bg-hover); color: var(--text-primary); }

.btn--danger {
  background: var(--danger-text);
  color: #fff;
  border-color: var(--danger-text);
}
.btn--danger:hover { filter: brightness(0.92); }

/* Destructive but secondary in the visual hierarchy: used for row actions
   where a solid red button would shout on every line. */
.btn--danger-quiet {
  background: var(--bg-surface);
  color: var(--danger-text);
  border-color: var(--danger-border);
}
.btn--danger-quiet:hover { background: var(--danger-surface); }

.btn--sm { height: 28px; padding: 0 var(--space-3); font-size: var(--text-sm); }
.btn--lg { height: 40px; padding: 0 var(--space-5); font-size: var(--text-md); }
.btn--icon { width: 34px; padding: 0; }
.btn--icon.btn--sm { width: 28px; }
.btn--block { width: 100%; }

/* --- Badge ----------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  line-height: 1.5;
  white-space: nowrap;
}
.badge--neutral { background: var(--bg-sunken); color: var(--text-secondary); border-color: var(--border-subtle); }
.badge--success { background: var(--success-surface); color: var(--success-text); border-color: var(--success-border); }
.badge--warning { background: var(--warning-surface); color: var(--warning-text); border-color: var(--warning-border); }
.badge--danger  { background: var(--danger-surface);  color: var(--danger-text);  border-color: var(--danger-border); }
.badge--info    { background: var(--info-surface);    color: var(--info-text);    border-color: var(--info-border); }
.badge--accent  { background: var(--bg-selected);     color: var(--text-accent);  border-color: var(--accent-200); }

/* Status must not be conveyed by colour alone (WCAG 1.4.1), so every status
   badge carries a shape as well as a hue. */
.badge__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}

/* --- Card ------------------------------------------------------------------ */

.card {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
}
/* A flex row, because base.css resets svg to display:block - so an icon
   inside a title breaks the line unless the title lays its children out.
   For a title that is only text this behaves exactly as a block did. */
.card__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
}
.card__title svg { flex: 0 0 auto; color: var(--text-muted); }
.card__body { padding: var(--space-5); }
.card__body--flush { padding: 0; }
.card__footer {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--border-subtle);
  background: var(--bg-sunken);
}

/* --- Stat tile -------------------------------------------------------------- */

.stat { display: flex; flex-direction: column; gap: var(--space-1); }
.stat__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
}
.stat__value {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.stat__meta { font-size: var(--text-xs); color: var(--text-muted); }

/* --- Table ------------------------------------------------------------------ */

/* The wrapper scrolls, not the page, so a 20-column table stays usable. */
.table-wrap {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.table { font-size: var(--text-sm); }

.table thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--bg-sunken);
  text-align: left;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  white-space: nowrap;
}

.table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--bg-hover); }

.table__num { text-align: right; font-variant-numeric: tabular-nums; }
.table__actions { width: 1%; white-space: nowrap; text-align: right; }

/* Sortable column headers. */
.table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.table__sort:hover { color: var(--text-primary); }
.table__sort[aria-sort] { color: var(--text-accent); }

/* --- Form ------------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field + .field { margin-top: var(--space-4); }

.label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.label__optional { font-weight: var(--weight-normal); color: var(--text-muted); }

.input, .select, .textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  min-height: 34px;
  background: var(--bg-surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--text-primary);
  transition: border-color var(--duration-fast) ease, box-shadow var(--duration-fast) ease;
}
.input::placeholder, .textarea::placeholder { color: var(--text-muted); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px var(--bg-selected);
}
.input:disabled, .select:disabled, .textarea:disabled {
  background: var(--bg-sunken);
  color: var(--text-muted);
  cursor: not-allowed;
}
.textarea { min-height: 96px; resize: vertical; }

.select {
  appearance: none;
  padding-right: var(--space-8);
  /* Chevron drawn inline so no icon font or extra request is needed. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5' fill='none' stroke='%236f7987' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}

.hint { font-size: var(--text-xs); color: var(--text-muted); }

/* Errors are announced with text and an icon, never colour alone. */
.field--invalid .input,
.field--invalid .select,
.field--invalid .textarea { border-color: var(--danger-text); }
.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--danger-text);
  font-weight: var(--weight-medium);
}

.checkbox, .radio {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-base);
}
.checkbox input, .radio input {
  width: 16px; height: 16px;
  margin-top: 2px;
  accent-color: var(--accent-600);
  flex: 0 0 auto;
  cursor: pointer;
}

.fieldset { border: none; padding: 0; }
/* Same reason as .card__title: base.css resets svg to display:block, so a
   legend carrying an icon needs to lay its children out or the icon takes a
   line of its own. */
.fieldset__legend {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-1);
}
.fieldset__legend svg { flex: 0 0 auto; color: var(--text-muted); }

/* --- Alert ------------------------------------------------------------------ */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: var(--text-base);
}
.alert--success { background: var(--success-surface); border-color: var(--success-border); color: var(--success-text); }
.alert--warning { background: var(--warning-surface); border-color: var(--warning-border); color: var(--warning-text); }
.alert--danger  { background: var(--danger-surface);  border-color: var(--danger-border);  color: var(--danger-text); }
.alert--info    { background: var(--info-surface);    border-color: var(--info-border);    color: var(--info-text); }
.alert svg { flex: 0 0 auto; width: 16px; height: 16px; margin-top: 2px; }

/* --- Toast ------------------------------------------------------------------ */

.toasts {
  position: fixed;
  bottom: var(--space-5);
  right: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: min(380px, calc(100vw - var(--space-8)));
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  font-size: var(--text-base);
  animation: toast-in var(--duration-base) var(--ease);
}
.toast--success { border-left-color: var(--success-text); }
.toast--danger  { border-left-color: var(--danger-text); }
.toast--warning { border-left-color: var(--warning-text); }
.toast--info    { border-left-color: var(--info-text); }
.toast__close { color: var(--text-muted); margin-left: auto; flex: 0 0 auto; }
.toast__close:hover { color: var(--text-primary); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- Empty state ------------------------------------------------------------ */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-12) var(--space-5);
  color: var(--text-secondary);
}
.empty__icon {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: var(--radius-lg);
  background: var(--bg-sunken);
  color: var(--text-muted);
}
.empty__title { font-size: var(--text-md); font-weight: var(--weight-semibold); color: var(--text-primary); }
.empty__body { max-width: 44ch; font-size: var(--text-base); }

/* --- Skeleton ---------------------------------------------------------------
   Shown while a Turbo Frame loads, so a slow query reads as "working" rather
   than "broken". */
.skeleton {
  background: linear-gradient(90deg, var(--bg-sunken) 25%, var(--bg-hover) 37%, var(--bg-sunken) 63%);
  background-size: 400% 100%;
  animation: skeleton 1.4s ease infinite;
  border-radius: var(--radius-sm);
}
.skeleton--text { height: 0.8em; margin: 0.2em 0; }
.skeleton--line { height: 12px; }

@keyframes skeleton {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

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

.avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-100);
  color: var(--accent-800);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  flex: 0 0 auto;
  text-transform: uppercase;
}
.avatar--lg { width: 40px; height: 40px; font-size: var(--text-sm); }

/* --- Dropdown ----------------------------------------------------------------
   Built on <details> so it opens, closes and is keyboard operable with no
   JavaScript; the Stimulus controller only adds click-outside and Escape. */
.dropdown { position: relative; display: inline-block; }
.dropdown > summary { list-style: none; cursor: pointer; }
.dropdown > summary::-webkit-details-marker { display: none; }

.dropdown__menu {
  position: absolute;
  top: calc(100% + var(--space-1));
  right: 0;
  min-width: 200px;
  z-index: var(--z-dropdown);
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
  animation: dropdown-in var(--duration-fast) var(--ease);
}
.dropdown__menu--left { right: auto; left: 0; }

.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  color: var(--text-primary);
  text-align: left;
}
.dropdown__item:hover { background: var(--bg-hover); text-decoration: none; }
.dropdown__item--danger { color: var(--danger-text); }
.dropdown__divider { height: 1px; background: var(--border-subtle); margin: var(--space-1) 0; }
.dropdown__label {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

@keyframes dropdown-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- Modal -------------------------------------------------------------------
   Native <dialog>: focus trapping, Escape handling and inertness come from the
   platform rather than from hand-written JavaScript. */
.modal {
  padding: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  background: var(--bg-surface);
  color: var(--text-primary);
  width: min(560px, calc(100vw - var(--space-8)));
  max-height: calc(100dvh - var(--space-16));
}
.modal::backdrop { background: rgb(13 17 23 / 0.5); }
.modal__header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5) var(--space-3);
}
.modal__title { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.modal__body { padding: 0 var(--space-5) var(--space-5); }
.modal__footer {
  display: flex; justify-content: flex-end; gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border-subtle);
  background: var(--bg-sunken);
}

/* --- Breadcrumbs -------------------------------------------------------------- */

.breadcrumbs { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); min-width: 0; }
.breadcrumbs__item { color: var(--text-secondary); }
.breadcrumbs__item:last-child { color: var(--text-primary); font-weight: var(--weight-medium); }
.breadcrumbs__sep { color: var(--text-muted); user-select: none; }

/* --- Description list ---------------------------------------------------------- */

.details-list { display: grid; grid-template-columns: minmax(140px, auto) 1fr; gap: var(--space-3) var(--space-5); }
.details-list dt { font-size: var(--text-sm); color: var(--text-secondary); }
.details-list dd { font-size: var(--text-base); margin: 0; min-width: 0; overflow-wrap: break-word; }

@media (max-width: 560px) {
  .details-list { grid-template-columns: 1fr; gap: var(--space-1); }
  .details-list dd { margin-bottom: var(--space-3); }
}

/* --- Search input --------------------------------------------------------------- */

.search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  max-width: 440px;
}
.search__icon {
  position: absolute;
  left: var(--space-3);
  color: var(--text-muted);
  pointer-events: none;
  width: 15px; height: 15px;
}
.search .input { padding-left: var(--space-8); }
.search__hint {
  position: absolute;
  right: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 1px var(--space-1);
  background: var(--bg-sunken);
  pointer-events: none;
}

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

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.pagination__pages { display: flex; align-items: center; gap: var(--space-1); }
.pagination__page {
  min-width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.pagination__page:hover { background: var(--bg-hover); color: var(--text-primary); text-decoration: none; }
.pagination__page[aria-current="page"] {
  background: var(--accent-400);
  border-color: var(--accent-400);
  color: var(--accent-contrast);
  font-weight: var(--weight-semibold);
}
.pagination__gap { color: var(--text-muted); padding: 0 var(--space-1); }

/* --- Conversation thread -------------------------------------------------
   Used by the enquiry screen. The four kinds are distinguished by an edge
   marker and a surface, not by colour alone - the badge in the header
   carries the meaning in words, so the styling is reinforcement rather than
   the only signal (WCAG 1.4.1). */
.thread { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column;
          gap: var(--space-4); }
.thread__item {
  border: 1px solid var(--border-subtle);
  border-inline-start: 3px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-surface);
}
.thread__item--inbound { border-inline-start-color: var(--info-border); background: var(--info-surface); }
.thread__item--outbound { border-inline-start-color: var(--accent-500); }
/* Notes sit back visually: they are the one kind the customer never sees. */
.thread__item--note {
  border-inline-start-color: var(--warning-border);
  background: var(--bg-sunken);
  border-style: dashed;
}
.thread__item--system {
  border: none;
  border-inline-start: 3px solid var(--border-subtle);
  border-radius: 0;
  padding-block: var(--space-1);
  background: none;
  color: var(--text-secondary);
  font-size: var(--text-xs);
}
.thread__meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  font-size: var(--text-sm);
}
.thread__item--system .thread__meta { margin-bottom: 0; font-size: var(--text-xs); }
/* What a customer attached to a review, shown where it is moderated. A
   moderator approving a review is approving its pictures too. */
.review-media { display: flex; flex-direction: column; gap: var(--space-2); }

.review-media__grid { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.review-media__item {
  display: block;
  line-height: 0;
  border-radius: var(--radius);
  overflow: hidden;
}

.review-media__item img { width: 6rem; height: 6rem; object-fit: cover; }

.review-media__video { width: 100%; max-width: 26rem; border-radius: var(--radius); background: #000; }

.thread__body { font-size: var(--text-sm); line-height: var(--leading-normal); overflow-wrap: break-word; }
.thread__body p { margin: 0 0 var(--space-2); }
.thread__body p:last-child { margin-bottom: 0; }
.thread__item--system .thread__body { font-size: var(--text-xs); }

/* --- Star rating ---------------------------------------------------------
   The glyphs are decorative; the accessible name comes from the surrounding
   text, so screen readers hear "4 stars" rather than a run of asterisks. */
.stars { color: var(--warning-text); letter-spacing: 0.08em; white-space: nowrap; }

/* --- Two-factor enrolment ------------------------------------------------ */

/* The QR keeps a white background in both themes. A dark-mode inversion would
   produce a light-on-dark code, which many phone scanners refuse to read. */
.qr {
  display: block;
  background: #fff;
  padding: var(--space-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

/* The TOTP secret, shown for hand entry when a camera will not cooperate. */
.code-block {
  display: block;
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--bg-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.08em;
  word-break: break-all;
  user-select: all;
}

.backup-codes__list {
  margin: 0;
  padding-left: var(--space-6);
  font-family: var(--font-mono);
  font-size: var(--text-md);
  line-height: 2;
}
.backup-codes__list code { letter-spacing: 0.06em; }

/* Printed backup codes are the fallback for losing a phone, so the print view
   drops the application shell and leaves the codes on the page alone. */
@media print {
  .sidebar, .topbar, .breadcrumbs, .page-header__actions, .card__footer, .toasts { display: none !important; }
  .card { border: none; box-shadow: none; }
  .backup-codes__list { line-height: 2.4; }
}

/* --- Permission picker ---------------------------------------------------- */

.permission-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.permission {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.permission:hover { background: var(--bg-hover); }
.permission:has(input:checked) { border-color: var(--border-focus); background: var(--bg-selected); }

/* A permission the operator does not hold. Shown rather than hidden, so the
   picker looks the same to everyone and the reason is visible. */
.permission--locked { cursor: not-allowed; opacity: 0.6; }
.permission--locked:hover { background: none; }

.permission__key {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-primary);
}
.permission__description {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

/* --- Impersonation banner ------------------------------------------------- */

/* Sticky and high contrast on purpose. Someone who forgets they are
   impersonating will take an action believing it is their own, and the audit
   trail will correctly record that they did. */
.impersonation-bar {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: #7c2d12;
  color: #ffffff;
  font-size: var(--text-sm);
}
.impersonation-bar span { display: inline-flex; align-items: center; gap: var(--space-2); }
.impersonation-bar strong { font-weight: var(--weight-semibold); }
.impersonation-bar form { margin: 0; }

/* The shell's single grid row is 100dvh, so without this the banner pushes the
   sidebar off the bottom of the page. */
.impersonation-bar ~ .shell { grid-template-rows: calc(100dvh - 40px); }

@media print { .impersonation-bar { display: none; } }

/* --- Charts --------------------------------------------------------------- */

/* preserveAspectRatio="none" means the SVG stretches to the card, so the user
   space is a fixed 0..100 square and every coordinate is a percentage. */
.chart { display: block; width: 100%; }
.chart__bar { fill: var(--text-accent); opacity: 0.85; }
.chart__bar--current { opacity: 1; }
.chart__line {
  fill: none;
  stroke: var(--text-accent);
  stroke-width: 2;
  /* The user space is square but the rendered box is not, so a plain stroke
     would be stretched with it. Non-scaling-stroke keeps it even. */
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
}
.chart--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed var(--border-subtle);
  border-radius: var(--radius-md);
  color: var(--text-muted);
  font-size: var(--text-xs);
}

/* --- Search results ------------------------------------------------------- */

.result-list { list-style: none; margin: 0; padding: 0; }
.result-list > li + li { border-top: 1px solid var(--border-subtle); }

.result {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3);
  align-items: center;
  /* Tighter than a table row: a result list is scanned, not read, and the
     previous spacing pushed a three-group search well past one screen. */
  padding: var(--space-2) var(--space-4);
  color: inherit;
  text-decoration: none;
}
.result:hover, .result:focus-visible { background: var(--bg-hover); }
.result:focus-visible { outline: 2px solid var(--border-focus); outline-offset: -2px; }
.result__icon { display: inline-flex; color: var(--text-muted); }
.result__body { min-width: 0; }
.result__title {
  display: block;
  font-weight: var(--weight-medium);
  /* One line each. A long product name must not reflow the whole list. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.result__subtitle {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Underlined rather than filled: a coloured block behind part of a title
   reads as a selection, and several of them in a list look like damage. */
.result mark {
  background: none;
  color: inherit;
  font-weight: var(--weight-semibold);
  box-shadow: inset 0 -2px 0 var(--text-accent);
}
.result__go { color: var(--text-muted); opacity: 0; transition: opacity 80ms linear; }
.result:hover .result__go, .result:focus-visible .result__go { opacity: 1; }

/* --- Command palette ------------------------------------------------------ */

.topbar__search {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: var(--bg-sunken);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  text-decoration: none;
}
.topbar__search:hover { background: var(--bg-hover); color: var(--text-primary); }
.topbar__kbd, .palette__kbd, .palette__footer kbd {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  padding: 1px var(--space-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--text-muted);
}
/* The label is the first thing to go on a narrow screen; the icon and the
   shortcut still say what it is. */
@media (max-width: 720px) { .topbar__search-label { display: none; } }

.palette__scrim {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgb(0 0 0 / 45%);
}

.palette__dialog {
  position: fixed;
  z-index: 201;
  top: 12vh;
  left: 50%;
  transform: translateX(-50%);
  width: min(640px, calc(100vw - var(--space-8)));
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 64px rgb(0 0 0 / 28%);
  overflow: hidden;
}

.palette__search {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.palette__icon { color: var(--text-muted); display: inline-flex; }
.palette__input {
  flex: 1;
  border: none;
  background: none;
  color: var(--text-primary);
  font-size: var(--text-md);
  outline: none;
}
.palette__input::-webkit-search-cancel-button { display: none; }

.palette__body { overflow-y: auto; }
.palette__results { list-style: none; margin: 0; padding: 0; }
.palette__result .result { padding: var(--space-2) var(--space-4); grid-template-columns: auto 1fr auto; }
.palette__result--active .result { background: var(--bg-selected); }
.palette__group {
  align-self: center;
  font-size: var(--text-2xs);
  color: var(--text-muted);
  white-space: nowrap;
}
.palette__status {
  margin: 0;
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.palette__footer {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.palette__link { margin-left: auto; color: var(--text-link); }

/* Stops the page behind the dialog from scrolling under it. */
body.is-palette-open { overflow: hidden; }

/* --- Saved views ---------------------------------------------------------- */

.saved-views {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.saved-views__list { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }

.chip-group { display: inline-flex; align-items: center; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: var(--bg-surface);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  text-decoration: none;
  white-space: nowrap;
}
.chip:hover { background: var(--bg-hover); color: var(--text-primary); }
.chip--active {
  background: var(--bg-inverse);
  border-color: var(--bg-inverse);
  color: var(--text-inverse);
}
.chip__badge { display: inline-flex; margin-left: calc(var(--space-1) * -1); color: var(--text-muted); }
.chip__remove {
  display: inline-flex;
  align-items: center;
  padding: 2px;
  margin-left: 2px;
  border: none;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}
.chip__remove:hover { color: var(--text-danger, #b42318); }

.saved-views__save { display: flex; align-items: center; gap: var(--space-2); }
.saved-views__share { font-size: var(--text-xs); white-space: nowrap; }
.input--sm { padding: var(--space-1) var(--space-2); font-size: var(--text-sm); width: 180px; }
