/**
 * KMHCO ERP Component Library
 *
 * Component CSS for the shared partial library (issue #70).
 * All values use design-system.css tokens only — no raw values.
 * Mobile-first; layered upward with min-width queries.
 */

/* ============================================
   LAYOUT UTILITIES
   ============================================ */

/* ``.page`` (the app shell's <main>) is the scroll container at >=768px
   (see "APP SHELL — LAYOUT" below) and must stay full-width so its own
   scrollbar sits at the real viewport edge, not floating partway across a
   centred column. The reading-width cap, centring, and padding instead
   live on ``.page__inner`` — the wrapper directly inside <main> — which a
   scrollbar never attaches to (see docs/design/patterns.md § app shell,
   Issue #799 follow-up). */
.page__inner {
  max-width: var(--layout-max);
  margin: 0 auto;
  padding: var(--space-4);
}
@media (min-width: 768px) {
  .page__inner { padding: var(--space-6); }
}

.stack > * + * { margin-top: var(--space-5); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.cluster--sm {
  gap: var(--space-2);
}

.cluster--between {
  justify-content: space-between;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}

/* ============================================
   ERROR PAGES (Issue #279)
   ============================================ */
/* In-shell 403 / 404 page styles. The 500 page is fully self-contained
   (inline critical CSS) because Django renders it with an empty context —
   see templates/500.html. Tokens only; no raw values. */

.error-page {
  max-width: 36rem;            /* matches prose width in design system */
  margin-inline: auto;
}

.error-page__lede {
  font-size: var(--font-size-lg);
  color: var(--color-ink-900);
  margin: 0 0 var(--space-5);
}

.error-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block: var(--space-5);
}

.error-page__meta {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  margin-top: var(--space-6);
}

.error-page__meta code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  background: var(--color-cream-100);
  border: 1px solid var(--color-border-subtle);
  border-radius: 6px;
  padding: 0.0625rem 0.3125rem;
}

.tnum {
  font-variant-numeric: tabular-nums;
}

/* Eyebrow — uppercase tracked label (ledger-rule motif, principles §7) */
.eyebrow {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-brand-600);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  margin: 0;
}

/* Display font utility */
.font-display {
  font-family: var(--font-display);
}

/* ============================================
   BUTTON
   ============================================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  border: var(--border-thin);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--transition-fast),
              color var(--transition-fast),
              border-color var(--transition-fast),
              box-shadow var(--transition-fast);
  height: var(--control-height-md);
  padding: 0 var(--space-4);
}

.btn:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  background: var(--color-brand-200);
  color: var(--color-ink-300);
  border-color: var(--color-border-subtle);
  cursor: not-allowed;
}

/* Sizes */
.btn--sm {
  height: var(--control-height-sm);
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
}

.btn--md {
  height: var(--control-height-md);
  padding: 0 var(--space-4);
  font-size: var(--font-size-base);
}

.btn__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.btn__label {
  display: inline-flex;
  align-items: center;
}

.icon {
  display: inline-block;
  width: var(--icon-size-md);
  height: var(--icon-size-md);
  flex: 0 0 auto;
  object-fit: contain;
  vertical-align: middle;
}

.btn--sm .btn__icon,
.chip__icon,
.table-sort__icon,
.alert__icon { width: var(--icon-size-sm); height: var(--icon-size-sm); }

.btn--icon-lg > .icon { width: var(--icon-size-lg); height: var(--icon-size-lg); }

.icon-loading { display: inline-flex; }
.icon-loading .icon { animation: icon-spin 1s linear infinite; }
@keyframes icon-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .icon-loading .icon { animation-duration: 2s; }
}

/* .btn's display would otherwise beat the UA [hidden] rule (e.g. the lone
   rule's remove button in a repeatable form group). */
.btn[hidden] { display: none; }

.btn--icon {
  width: var(--control-height-md);
  padding: 0;
}

.btn--icon-lg {
  width: calc(var(--control-touch-min) + var(--space-5));
  height: var(--control-touch-min);
  font-size: var(--font-size-lg);
}

.btn--sm.btn--icon {
  width: var(--control-height-sm);
  padding: 0;
}

/* ============================================
   ICON-ONLY TOOLTIP (docs/design/components.md
   "Icon-only button + tooltip")
   ============================================
   A CSS-only tooltip paired with an icon-only `.btn--icon` control. The
   visible hint text lives in `[data-tooltip]`; the same string must already
   be the button's `aria-label` (single-string contract). The tooltip is a
   progressive enhancement — keyboard and assistive-technology users get the
   accessible name whether or not the bubble is ever visible. */

[data-tooltip] {
  position: relative;
}

/* The bubble — built from a `::after` carrying the attribute's content. */
[data-tooltip]:hover:not(:disabled):not([aria-disabled="true"])::after,
[data-tooltip]:focus-visible:not(:disabled):not([aria-disabled="true"])::after {
  content: attr(data-tooltip);
  position: absolute;
  /* Sit above the control by default; clamp inside the viewport edge so the
     bubble never overflows on narrow row-action strips. */
  bottom: calc(100% + var(--space-2));
  left: 50%;
  transform: translateX(-50%);
  max-width: 18rem;
  padding: var(--space-2) var(--space-3);
  background: var(--color-ink-900);
  color: #fff;
  font-size: var(--font-size-sm);
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
  white-space: normal;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  pointer-events: none;
  z-index: 10;
  /* Slight entry so the bubble feels like a hover hint, not a flash. */
  opacity: 1;
  transition: opacity 80ms ease-out;
}

/* Arrow — a small filled triangle pointing down to the control. */
[data-tooltip]:hover:not(:disabled):not([aria-disabled="true"])::before,
[data-tooltip]:focus-visible:not(:disabled):not([aria-disabled="true"])::before {
  content: "";
  position: absolute;
  bottom: calc(100% + var(--space-2) - 6px);
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--color-ink-900);
  pointer-events: none;
  z-index: 10;
}

/* Keep a row-action strip readable on narrow widths — let the bubble
   wrap rather than clip; the `max-width` above combined with `text-align:
   center` handles short hints, longer ones wrap within the cap. */
@media (prefers-reduced-motion: reduce) {
  [data-tooltip]:hover::after,
  [data-tooltip]:focus-visible::after { transition: none; }
}

/* Variants */
.btn--primary {
  background: var(--color-brand-600);
  color: #fff;
  border-color: var(--color-brand-600);
}
.btn--primary:hover:not(:disabled) { background: var(--color-brand-500); }
.btn--primary:active:not(:disabled) { background: var(--color-brand-700); }

.btn--secondary {
  background: var(--color-surface-card);
  color: var(--color-ink-900);
}
.btn--secondary:hover:not(:disabled) { background: var(--color-surface-hover); }

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--color-ink-700);
}
.btn--ghost:hover:not(:disabled) { background: var(--color-brand-50); }

.btn--danger {
  background: var(--color-status-error);
  color: #fff;
  border-color: var(--color-status-error);
}
.btn--danger:hover:not(:disabled) { background: var(--color-status-error-hover); }

.btn--link {
  background: transparent;
  border: none;
  color: var(--color-brand-600);
  padding: 0;
  height: auto;
}
.btn--link:hover:not(:disabled) { text-decoration: underline; }

/* ============================================
   FORM FIELD
   ============================================ */

.field {
  margin-bottom: var(--space-4);
}

.field__label {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-700);
  margin-bottom: var(--space-1);
}

.field__required {
  color: var(--color-status-error);
  margin-left: 2px;
}

.field__control {
  display: block;
  width: 100%;
  height: var(--control-height-md);
  padding: 0 var(--space-3);
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  color: var(--color-ink-900);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  transition: border-color var(--transition-fast),
              box-shadow var(--transition-fast);
}
.field__control:focus {
  outline: none;
  border-color: var(--color-brand-600);
  box-shadow: 0 0 0 3px var(--color-brand-100);
}

.field textarea.field__control {
  height: auto;
  min-height: 100px;
  padding: var(--space-2) var(--space-3);
  line-height: var(--line-height-normal);
}

.field select.field__control,
.toolbar__filters select.field__control {
  appearance: none;
  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 fill='%235f6f66' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  padding-right: var(--space-8);
}

.field--checkbox,
.field--radio {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.field--checkbox .field__label,
.field--radio .field__label {
  margin-bottom: 0;
  order: 1;
}
.field--checkbox .field__control,
.field--radio .field__control {
  width: auto;
  height: auto;
  order: 0;
}

.field--error .field__control {
  border-color: var(--color-status-error);
}
.field--error .field__control:focus {
  box-shadow: 0 0 0 3px var(--color-status-error-bg);
}

.field__help {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  margin-top: var(--space-1);
}

.field__error {
  font-size: var(--font-size-sm);
  color: var(--color-status-error);
  margin-top: var(--space-1);
}

.field--group {
  border: none;
  padding: 0;
  margin-bottom: var(--space-4);
}
.field--group legend {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-700);
  margin-bottom: var(--space-2);
}

/* ============================================
   CHECKBOX / RADIO GROUP (mobile-first choice list)
   Used by the form-field partial when the bound widget is
   CheckboxSelectMultiple or RadioSelect. See docs/design/components.md.
   ============================================ */

.field--choice-group {
  border: var(--border-thin);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4);
  background: var(--color-surface-card);
}
.field--choice-group__legend {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-700);
  margin-bottom: var(--space-2);
  padding: 0;
}
.field--choice-group__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.field--choice-group__item {
  margin: 0;
}
.field--choice-group__label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2);
  min-height: var(--control-touch-min); /* 44px touch target */
  cursor: pointer;
  border-radius: var(--radius-sm);
  color: var(--color-ink-900);
  font-size: var(--font-size-base);
  line-height: var(--line-height-snug);
}
.field--choice-group__label:hover {
  background: var(--color-surface-hover);
}
.field--choice-group__label--disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.field--choice-group__label--disabled:hover {
  background: transparent;
}
.field--choice-group__label input[type="checkbox"],
.field--choice-group__label input[type="radio"] {
  width: 1.125rem;   /* 18px visual */
  height: 1.125rem;
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--color-brand-600);
}
.field--choice-group__label input[type="checkbox"]:focus-visible,
.field--choice-group__label input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}
.field--choice-group__badge {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
  font-style: italic;
  margin-left: var(--space-2);
}
.field--choice-group__text {
  flex: 1 1 auto;
}
.field--choice-group--horizontal .field--choice-group__list {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.field--choice-group + .field__help,
.field--choice-group + .field__error {
  margin-left: var(--space-1);
}
.field--choice-group.field--error {
  border-color: var(--color-status-error);
}

/* ============================================
   QUIZ OPTION (hand-rolled radio + label pair)
   Practice-quiz options are rendered straight from quiz JSON (see
   quiz_take.html), not the bound-field partial above, so they cannot use
   `.field--choice-group__label`. `.cluster`/`.cluster--sm` is a chip-layout
   utility (`align-items: center`) never meant for a control+label pair
   whose label can wrap — reusing it let a long option's text wrap while
   the radio stayed vertically centered against the whole block, orphaning
   it off the first line (issue #707 AC-B5). See docs/design/components.md.
   ============================================ */

.quiz-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
}
.quiz-option input[type="radio"] {
  flex: 0 0 auto;
  width: 1.125rem;
  height: 1.125rem;
  margin: 0;
  margin-top: 0.2em; /* optical alignment with the first line of wrapped text */
  accent-color: var(--color-brand-600);
}
.quiz-option input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}
.quiz-option span {
  flex: 1 1 auto;
  min-width: 0; /* allow long option text to wrap instead of forcing overflow */
}

.quiz-hint {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}
.quiz-hint summary {
  color: var(--color-brand-700);
  cursor: pointer;
  font-weight: 600;
}
.quiz-hint p {
  margin: var(--space-1) 0 0;
}

/* ============================================
   STATUS CHIP / BADGE
   ============================================ */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-full);
  white-space: nowrap;
}

.chip__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-sm);
}

.chip__label {
  display: inline-flex;
  align-items: center;
}

.chip-list {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  vertical-align: middle;
}

.chip--success { color: var(--color-status-success); background: var(--color-status-success-bg); }
.chip--warning { color: var(--color-status-warning); background: var(--color-status-warning-bg); }
.chip--error   { color: var(--color-status-error);   background: var(--color-status-error-bg); }
.chip--info    { color: var(--color-status-info);    background: var(--color-status-info-bg); }
.chip--neutral { color: var(--color-ink-700);       background: var(--color-cream-200); }

/* ============================================
   CARD
   ============================================ */

.card {
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  min-width: 0;
  max-width: 100%;
}
.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-4) 0;
  min-width: 0;
  max-width: 100%;
}
/* Identity block + text-button cluster: the cluster wraps under the title
   when both don't fit (phones) instead of overflowing the card. */
.card__header--actions {
  flex-wrap: wrap;
  gap: var(--space-3);
}
.card__header--actions > :first-child {
  min-width: 0;
  overflow-wrap: anywhere;
}
.card__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  color: var(--color-ink-900);
  margin: 0;
  word-break: break-word;
}
.card__body {
  padding: var(--space-4);
  min-width: 0;
  max-width: 100%;
}
.card__footer {
  padding: 0 var(--space-4) var(--space-4);
}

.card--link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: box-shadow var(--transition-fast);
}
.card--link:hover { box-shadow: var(--shadow-md); }

.card--stat {
  text-align: center;
  padding: var(--space-5);
}
.card--stat .stat__value {
  font-family: var(--font-display);
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  font-variant-numeric: tabular-nums;
}
.card--stat .stat__label {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  margin-top: var(--space-1);
}

/* Standalone stat display (used outside card--stat) */
.stat-group {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

/* ============================================
   DATA TABLE
   ============================================ */

.table-wrapper {
  overflow: hidden;
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  background: var(--color-surface-card);
  min-width: 0;
  max-width: 100%;
}

.table-region {
  min-width: 0;
  max-width: 100%;
  container-name: table-region;
  container-type: inline-size;
}

/* Wide-content variant (docs/design/components.md → Wide-content variant):
   the region measures three quarters of its real width, so the one shared
   60rem card query below fires when the real width is 80rem. Its children
   are stretched back to the full real width, so nothing renders narrower.
   This keeps a single copy of the card rules instead of a second query. */
.table-region--wide-content {
  width: 75%;
}

.table-region--wide-content > * {
  width: calc(100% * 4 / 3);
  max-width: none;
}

/* Column alignment applies to the columned presentation; card presentation
   resets it to left below so label/value lines read as one column. */
.data-table [data-align="center"] { text-align: center; }
.data-table [data-align="right"] { text-align: right; }

.table-controls {
  min-width: 0;
}

.table-viewport {
  max-height: none;
  overflow: visible;
  min-width: 0;
  max-width: 100%;
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--font-size-base);
}

.data-table caption {
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  text-align: left;
  caption-side: bottom;
}

.data-table thead {
  position: sticky;
  top: 0;
  z-index: 2;
  border-bottom: 2px solid var(--color-border-default);
  background: var(--color-surface-subtle);
}

.data-table th {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-500);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.data-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border-subtle);
  color: var(--color-ink-900);
  font-variant-numeric: tabular-nums;
}

.data-table--compact th {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--font-size-xs);
}

.data-table--compact td {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
}

.data-table--compact .chip {
  padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-xs);
}

.data-table tbody tr:hover { background: var(--color-surface-hover); }

/* Heading of a titled table section — tables never sit in cards
   (Issue #836, components.md § Data table → Framing). */
.table-section__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  color: var(--color-ink-900);
  margin: 0;
}

/* Totals footer (Issue #836, components.md § Data table → Totals footer). */
.data-table tfoot td {
  border-top: 2px solid var(--color-border-default);
  border-bottom: none;
  font-weight: var(--font-weight-semibold);
}

.table-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: inherit;
  text-decoration: none;
}

.table-sort:hover {
  color: var(--color-brand-600);
}

.table-sort:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.table-sort__icon {
  color: var(--color-ink-400);
  font-size: var(--font-size-sm);
}

.table-header-controls {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.filter-popover {
  position: relative;
}

.filter-popover--mobile {
  display: none;
}

.filter-popover__mobile-label {
  display: none;
}

.filter-popover__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--control-height-sm);
  min-height: var(--control-height-sm);
  border-radius: var(--radius-md);
  cursor: pointer;
  list-style: none;
}

.filter-popover__trigger::-webkit-details-marker {
  display: none;
}

.filter-popover__trigger:hover,
.filter-popover__trigger:focus-visible,
.filter-popover--active .filter-popover__trigger {
  background: var(--color-brand-50);
}

.filter-popover--active .filter-popover__trigger {
  outline: 1px solid var(--color-brand-600);
}

.filter-popover__panel {
  position: absolute;
  z-index: 5;
  top: calc(100% + var(--space-1));
  left: 0;
  display: grid;
  gap: var(--space-3);
  min-width: 16rem;
  padding: var(--space-3);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-lg);
  color: var(--color-ink-900);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-normal);
  letter-spacing: normal;
  text-transform: none;
}

.filter-popover__search {
  width: 100%;
}

.filter-popover__options {
  display: grid;
  gap: var(--space-1);
  max-height: 14rem;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  border: 0;
}

.filter-popover__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-touch-min);
  padding-inline: var(--space-2);
  border-radius: var(--radius-md);
  cursor: pointer;
}

.filter-popover__option:hover {
  background: var(--color-surface-hover);
}

.filter-popover__actions {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: var(--border-thin);
}

.table-toolbar.toolbar--list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.table-filter-drawer {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
}

.table-filter-drawer[hidden] {
  display: none;
}

.table-toolbar .toolbar__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  max-width: none;
  flex: 1 1 auto;
}

.table-toolbar .toolbar__filters input[type="search"] {
  /* The search box used to share this row with the relational-filter
     comboboxes (Issue #799 follow-up removed those into column popovers),
     so it stayed capped at a small fixed width even though it is now often
     the row's only control. Let it grow to fill the space next to the
     primary actions instead of leaving that space empty. */
  width: 100%;
  max-width: 32rem;
  flex: 1 1 20rem;
}

.table-toolbar__primary-actions {
  flex: 0 0 auto;
}

.table-filter-strip {
  display: none;
}

.active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.active-filters__label {
  color: var(--color-ink-500);
  font-size: var(--font-size-sm);
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--control-height-sm);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-brand-50);
  color: var(--color-brand-700);
  font-size: var(--font-size-sm);
  text-decoration: none;
}

.active-filters__clear {
  color: var(--color-brand-700);
  font-size: var(--font-size-sm);
}

.active-filters__remove {
  display: inline-flex;
  align-items: center;
  color: inherit;
}

/* Responsive: mobile toolbar chrome (search/filter drawer, the floating
   add-FAB, the horizontal filter-chip strip). This is
   real viewport-narrow phone chrome, not a reaction to the table's allocated
   width, so it stays a viewport media query — matching the 767px breakpoint
   static/js/app.js already uses for the same drawer — rather than the
   table-region container query below. Desktop/laptop viewports keep the full
   toolbar (relational filters included) even when the table itself reformats
   into cards because the sidebar narrows its container below 60rem. */
@media (max-width: 767px) {
  .table-toolbar.toolbar--list {
    display: block;
    margin-bottom: 0;
  }

  .table-filter-drawer {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    margin-bottom: var(--space-2);
  }

  .table-toolbar .toolbar__filters {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-width: 0;
    max-width: none;
  }

  .table-toolbar .toolbar__filters input[type="search"] {
    width: 100%;
    min-width: 0;
    max-width: none;
    flex: 1 1 auto;
  }

  .table-toolbar__primary-actions {
    position: fixed;
    right: var(--space-4);
    bottom: var(--space-4);
    z-index: 40;
  }

  .table-toolbar__primary-actions .btn--icon-lg {
    width: calc(var(--control-touch-min) + var(--space-3));
    height: calc(var(--control-touch-min) + var(--space-3));
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-lg);
  }

  .active-filters {
    flex-wrap: nowrap;
    margin-bottom: var(--space-2);
    overflow-x: auto;
    scrollbar-width: none;
  }

  .active-filters > .cluster {
    flex-wrap: nowrap;
  }

  .active-filters__label,
  .active-filters__clear,
  .filter-chip {
    flex: 0 0 auto;
  }

  .active-filters::-webkit-scrollbar {
    display: none;
  }
}

/* Responsive: compact record cards based on allocated content width.
   Shared table-region container threshold from docs/design/foundations.md —
   60rem, not a viewport breakpoint. It must stay below the widest region a
   standard page offers (1200px - 2 × 32px padding = 1136px) or tables can never
   leave card mode (Issue #831). Screens must not override it locally; a
   table too wide for 60rem opts into .table-region--wide-content above.
   The per-column filter popover normally lives in <thead>, which this same
   query hides below; the mobile-variant popover in .table-filter-strip
   takes over as the only way to reach it, on desktop as much as on phones —
   whenever the table itself is in card mode. */
@container table-region (max-width: 60rem) {
  .table-filter-strip {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    min-width: 0;
    margin: 0;
    padding: 0;
    overflow: visible;
  }

  .table-filter-strip:empty {
    display: none;
  }

  .table-filter-strip:has(.filter-popover[open]) {
    overflow: visible;
  }

  .filter-popover--mobile {
    display: block;
    position: static;
    flex: 0 0 auto;
  }

  .filter-popover--mobile .filter-popover__trigger {
    gap: var(--space-1);
    min-height: var(--control-touch-min);
    padding-inline: var(--space-2);
    border: var(--border-thin);
  }

  .filter-popover__mobile-label {
    display: inline;
    color: var(--color-ink-700);
    font-size: var(--font-size-sm);
  }

  .filter-popover--mobile .filter-popover__panel {
    top: calc(100% + var(--space-1));
    right: 0;
    left: 0;
    width: 100%;
    min-width: 0;
    max-width: none;
  }

  .table-viewport {
    max-height: none;
    overflow: visible;
  }

  .data-table thead {
    position: static;
  }

  .data-table thead { display: none; }
  .table-wrapper {
    overflow: visible;
    border: 0;
    background: transparent;
  }
  .table-wrapper:has(.data-table__empty-row) {
    overflow: hidden;
    border: var(--border-thin);
    background: var(--color-surface-card);
  }
  .data-table,
  .data-table tbody,
  .data-table tr,
  .data-table td { display: block; }
  .data-table tbody {
    display: grid;
    gap: var(--space-2);
  }
  /* A wrapping flex line, not a fixed grid (Issue #833): primary · badge ·
     actions lead, every other cell is a full-width line below. A cluster too
     wide to sit beside an 8rem primary wraps onto its own line instead of
     squeezing the primary to nothing (components.md § Data table). */
  .data-table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: var(--space-2);
    row-gap: 0;
    padding: var(--space-2) var(--space-3);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    background: var(--color-surface-card);
  }
  .data-table tfoot {
    display: block;
    margin-top: var(--space-2);
  }
  .data-table tfoot tr {
    background: var(--color-surface-subtle);
  }
  .data-table tfoot td {
    border-top: none;
  }
  .data-table tr.data-table__empty-row {
    display: block;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
  }
  .data-table__empty-row td::before {
    content: none;
    display: none;
  }
  .data-table td,
  .data-table td[data-align] {
    padding: 0;
    border-bottom: none;
    line-height: var(--line-height-tight);
    text-align: left;
  }
  .data-table tr > td {
    flex: 1 1 100%;
    min-width: 0;
  }
  .data-table td::before {
    content: attr(data-label);
    display: inline;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--color-ink-500);
    margin-right: var(--space-1);
  }

  .data-table td[data-mobile-role="hidden"] {
    display: none;
  }

  /* Unassigned-cell fallback (Issue #833): a cell with no card role spans the
     card as a label/value line instead of auto-placing into the narrow
     primary · badge · actions slots. Column lists still declare roles
     (patterns.md § Column contract); this is the safety net. */
  .data-table td:not([data-cell-role]):not([data-mobile-role]) {
    flex: 1 1 100%;
    min-width: 0;
  }

  /* Typography on the cell too, so a plain-text title (e.g. an employee name)
     is as prominent as one wrapped in a link. */
  .data-table td[data-cell-role="primary"] {
    order: -3;
    flex: 1 1 8rem;
    min-width: 0;
    overflow-wrap: anywhere;
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-ink-900);
  }
  .data-table td[data-cell-role="primary"]::before {
    content: none;
    display: none;
  }
  .data-table td[data-cell-role="primary"] > * {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-ink-900);
    line-height: var(--line-height-tight);
  }

  .data-table td[data-mobile-role="badge"] {
    display: flex;
    order: -2;
    flex: 0 0 auto;
    align-items: center;
  }

  .data-table td[data-mobile-role="badge"]::before {
    content: none;
    display: none;
  }

  .data-table td[data-mobile-role="actions"] {
    display: flex;
    order: -1;
    flex: 0 0 auto;
    margin-left: auto;
    justify-content: flex-end;
    align-items: center;
  }
  .data-table td[data-mobile-role="actions"]::before {
    content: none;
    display: none;
  }
  .data-table td[data-mobile-role="actions"] .row-actions {
    gap: 0;
  }

  /* Row selection (#887 exam question picker): the checkbox leads the card,
     on the left, before the primary fact. */
  .data-table td[data-mobile-role="select"] {
    display: flex;
    order: -4;
    flex: 0 0 auto;
    align-items: flex-start;
    padding-top: 2px;
  }
  .data-table td[data-mobile-role="select"]::before {
    content: none;
    display: none;
  }

  /* Workflow actions (Issue #844): text state transitions form the card's
     last line — full width, below the details, left-aligned and wrapping. */
  .data-table td[data-mobile-role="workflow"] {
    order: 1;
    flex: 1 1 100%;
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: var(--border-thin);
  }
  .data-table td[data-mobile-role="workflow"]:not(:has(button)) {
    display: none;
  }
  .data-table td[data-mobile-role="workflow"]::before {
    content: none;
    display: none;
  }
  .data-table td[data-mobile-role="workflow"] .row-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
  }

  .data-table td[data-mobile-role="meta"] {
    display: block;
    color: var(--color-ink-600);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-tight);
    margin: 0;
    padding: 0;
  }
  .data-table td[data-mobile-role="meta"]::before {
    content: attr(data-label) ": ";
    display: inline;
    font-weight: var(--font-weight-medium);
    color: var(--color-ink-500);
  }
  .data-table td[data-mobile-role="body"] {
    margin-top: var(--space-1);
    color: var(--color-ink-700);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-tight);
  }

  .data-table td[data-mobile-role="body"]::before {
    display: block;
    margin: 0 0 var(--space-1);
  }

  .data-table td[data-mobile-role="body"] .chip-list {
    display: flex;
  }
}

/* ============================================
   ROW ACTIONS (data tables) — touch-target + focus
   ----------------------------------------------
   The cluster lives inside a ``.data-table td``. On desktop the
   ``.btn--sm`` is 32px tall — below the 44px touch target floor. We
   wrap the visible control in extra padding so the hit-area is at
   least ``--control-touch-min`` while the visual size stays 32px.
   On mobile the cluster goes full-width (see the media query above)
   and each control expands to 44px tall.

   Focused state re-uses the standard ``.btn:focus-visible`` ring;
   the wrapper here is just to guarantee the touch target. */
.row-actions { display: inline-flex; gap: var(--space-2); align-items: center; }
.row-actions > * {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--control-touch-min);
  min-width: var(--control-touch-min);
}
.row-actions > .btn { min-height: var(--control-touch-min); }

.row-action {
  border: none;
  background: none;
  color: var(--color-ink-600);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: background-color var(--transition-fast),
              color var(--transition-fast);
}

.row-action:hover {
  background: var(--color-surface-hover);
  color: var(--color-ink-900);
}

.row-action:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}

.row-action--danger {
  color: var(--color-status-error);
}

.row-action--danger:hover {
  background: var(--color-status-error-bg);
  color: var(--color-status-error);
}

.row-action[aria-disabled="true"] {
  color: var(--color-ink-300);
  cursor: not-allowed;
  pointer-events: none;
}

/* PNG icons (Issue #437) carry their own baked-in ink color, so `color`
   above has no effect on them — dim the image itself instead. */
.row-action[aria-disabled="true"] .icon,
.btn:disabled .icon,
.btn[aria-disabled="true"] .icon {
  opacity: 0.4;
}

.row-actions--icons {
  flex-wrap: nowrap;
}

.row-actions--icons > .row-action {
  flex: 0 0 var(--control-touch-min);
}

@media (min-width: 1024px) {
  .data-table--compact .row-actions > * {
    min-height: var(--control-height-sm);
    min-width: var(--control-height-sm);
  }

  .data-table--compact .row-actions--icons > .row-action {
    flex-basis: var(--control-height-sm);
  }
}

/* ============================================
   CRUD DETAIL BASE
   ============================================ */

.detail-base__breadcrumb {
  margin-bottom: var(--space-3);
}

.detail-base__identity {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.detail-base__identity-copy {
  display: grid;
  gap: var(--space-2);
}

.detail-base__chips {
  min-width: 0;
}

.detail-base__identity .page__title {
  margin: 0;
}

.detail-base__actions {
  margin-left: auto;
}

.detail-base__key-facts:empty {
  display: none;
}

.detail-base__tabs {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  overflow-x: auto;
}

@media (max-width: 767px) {
  .detail-base__tabs .tabs {
    display: flex;
    width: 100%;
    margin-bottom: 0;
  }
}

.detail-base__content {
  display: grid;
  gap: var(--space-4);
}

.detail-base__main,
.detail-base__aside {
  display: grid;
  align-content: start;
  gap: var(--space-4);
  min-width: 0;
}

.detail-base__aside:empty {
  display: none;
}

@media (min-width: 1024px) {
  .detail-base__content:has(> .detail-base__aside > *) {
    grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr);
  }

  .detail-base__content:not(:has(> .detail-base__aside > *)) {
    grid-template-columns: minmax(0, 1fr);
  }

  .detail-base__aside:not(:has(> *)) {
    display: none;
  }
}

/* ============================================
   PAGINATION
   ============================================ */

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
}

.pagination__pages {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.pagination__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--control-height-sm);
  height: var(--control-height-sm);
  padding: 0 var(--space-2);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--color-ink-700);
  font-size: var(--font-size-sm);
}
.pagination__page:hover:not([aria-current]) { background: var(--color-surface-hover); }
.pagination__page[aria-current="page"] {
  background: var(--color-brand-600);
  color: #fff;
  border-color: var(--color-brand-600);
}
.pagination__page--disabled {
  color: var(--color-ink-300);
  pointer-events: none;
}

.pagination__info {
  color: var(--color-ink-500);
}

.pagination__icon {
  font-size: var(--font-size-base);
}

@media (max-width: 767px) {
  .pagination {
    align-items: stretch;
    flex-direction: column;
  }

  .pagination__pages {
    flex-wrap: wrap;
  }
}

/* ============================================
   MODAL / DIALOG
   ============================================ */

dialog.modal {
  border: none;
  border-radius: var(--radius-xl);
  padding: 0;
  max-width: min(560px, calc(100vw - var(--space-8)));
  box-shadow: var(--shadow-xl);
  background: var(--color-surface-card);
}
/* A form dialog doesn't shrink-wrap its fields (Issue #844): 35rem, capped
   by the same viewport gutter as max-width. */
dialog.modal--form {
  width: min(35rem, calc(100vw - var(--space-8)));
}
dialog.modal::backdrop {
  background: rgba(26, 31, 28, 0.4);
}

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: var(--border-thin);
}

.modal__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  margin: 0;
}

.modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-touch-min);
  height: var(--control-touch-min);
  border: none;
  background: transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  color: var(--color-ink-500);
  font-size: var(--font-size-lg);
}
.modal__close:hover { background: var(--color-brand-50); }

.modal__body {
  padding: var(--space-5);
  line-height: var(--line-height-normal);
}

.modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: 0 var(--space-5) var(--space-5);
}

/* Form dialog footer, rendered inside the form so Cancel and Submit share
   one row (components/modal_actions.html). */
.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* ============================================
   ALERT / INLINE MESSAGE
   ============================================ */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
}

.alert--success { color: var(--color-status-success); background: var(--color-status-success-bg); }
.alert--warning { color: var(--color-status-warning); background: var(--color-status-warning-bg); }
.alert--error   { color: var(--color-status-error);   background: var(--color-status-error-bg); }
.alert--info    { color: var(--color-status-info);    background: var(--color-status-info-bg); }

/* .alert is align-items: flex-start so a wrapped message keeps its icon on
   the first line; this offset centres the icon on that line instead of
   pinning it to the line box's top edge (#832). */
.alert__icon {
  flex-shrink: 0;
  margin-top: calc((var(--font-size-base) * var(--line-height-normal) - var(--icon-size-sm)) / 2);
}

.alert__text {
  flex: 1;
}

.alert__message { flex: 1; }

.alert__dismiss {
  background: none;
  border: none;
  cursor: pointer;
  color: inherit;
  opacity: 0.6;
  font-size: var(--font-size-lg);
  line-height: 1;
  padding: 0;
  min-width: var(--control-touch-min);
  min-height: var(--control-touch-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.alert__dismiss:hover { opacity: 1; }

/* ============================================
   EMPTY STATE
   ============================================ */

.empty-state {
  text-align: center;
  padding: var(--space-10) var(--space-4);
}

.empty-state__icon {
  display: block;
  width: var(--icon-size-lg);
  height: var(--icon-size-lg);
  margin-left: auto;
  margin-right: auto;
  margin-bottom: var(--space-3);
  opacity: 0.55;
}

.empty-state__heading {
  font-family: var(--font-display);
  font-size: var(--font-size-xl);
  color: var(--color-ink-900);
  margin: 0 0 var(--space-2);
}

.empty-state__message {
  color: var(--color-ink-500);
  max-width: 40ch;
  margin: 0 auto var(--space-5);
}

.empty-state__read-only {
  color: var(--color-ink-500);
  font-size: var(--font-size-sm);
  max-width: 40ch;
  margin: 0 auto;
  font-style: italic;
}

/* ============================================
   LOADING INDICATOR
   ============================================ */

.htmx-indicator {
  opacity: 0;
  transition: opacity 200ms ease-in;
}
.htmx-request .htmx-indicator { opacity: 1; }
.htmx-request.htmx-indicator { opacity: 1; }

.skeleton {
  height: 1em;
  background: var(--color-cream-200);
  border-radius: var(--radius-sm);
  animation: skeleton-pulse 1.5s ease-in-out infinite;
}

@keyframes skeleton-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* ============================================
   BREADCRUMBS
   ============================================ */

.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  padding-bottom: var(--space-3);
}
.breadcrumbs a {
  color: var(--color-ink-500);
  text-decoration: none;
}
.breadcrumbs a:hover { color: var(--color-brand-600); }
.breadcrumbs [aria-current="page"] {
  color: var(--color-ink-700);
  font-weight: var(--font-weight-medium);
}

/* ============================================
   TABS
   ============================================ */

.tabs {
  display: flex;
  border-bottom: var(--border-thin);
  margin-bottom: var(--space-5);
  overflow-x: auto;
}

.tabs__tab {
  display: inline-flex;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  /* Touch-target ≥ 44px tall without changing the visual baseline. */
  min-height: var(--control-touch-min);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-ink-500);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color var(--transition-fast),
              border-color var(--transition-fast),
              background-color var(--transition-fast),
              outline-color var(--transition-fast);
}
/* Focused but not selected — outline + light brand-50 fill so the
   keyboard cursor is unmistakable, and visually distinct from the
   selected bottom-border treatment. */
.tabs__tab:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: -2px;
  background-color: var(--color-brand-50);
  color: var(--color-ink-900);
  border-bottom-color: var(--color-brand-300);
}
.tabs__tab:hover { color: var(--color-ink-700); }
.tabs__tab[aria-selected="true"] {
  color: var(--color-brand-600);
  border-bottom-color: var(--color-brand-600);
}
/* Selected AND focused — keep the brand-600 bottom border (selected)
   and add a 3px brand ring (focused). Both states must be visible. */
.tabs__tab[aria-selected="true"]:focus-visible {
  outline: 3px solid var(--color-brand-600);
  outline-offset: -3px;
  background-color: var(--color-brand-50);
}

/* Mobile tab select — hidden above md breakpoint (768px) */
.tabs__mobile-select {
  display: none;
  margin-bottom: var(--space-5);
}
.tabs__mobile-select .field__control {
  width: 100%;
}

@media (max-width: 767px) {
  .tabs {
    display: none;
  }
  .tabs__mobile-select {
    display: block;
  }
}

/* ============================================
   APP SHELL — NAV HEADER
   ============================================ */

.nav-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 50;
  height: 56px;
  padding: 0 var(--space-4);
  background: var(--color-brand-700);
  color: #fff;
}
.nav-header__left,
.nav-header__right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.nav-header__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  color: inherit;
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.nav-header__logo-img { height: 24px; width: auto; }

.nav-header__drawer-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--control-touch-min);
  height: var(--control-touch-min);
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  border-radius: var(--radius-md);
}
.nav-header__drawer-toggle:hover { background: rgba(255,255,255,0.1); }

.nav-header__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-brand-500);
  color: #fff;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}

.nav-header__user-toggle {
  display: flex;
  align-items: center;
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: var(--space-1);
  border-radius: var(--radius-md);
  min-width: var(--control-touch-min);
  min-height: var(--control-touch-min);
  justify-content: center;
}
.nav-header__user-toggle:hover { background: rgba(255,255,255,0.1); }

.nav-header__user-name {
  font-size: var(--font-size-sm);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 767px) {
  .nav-header__user-name { display: none; }
}

.nav-header__dropdown {
  position: absolute;
  top: 56px;
  right: var(--space-2);
  min-width: 180px;
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-2) 0;
  z-index: 60;
}
.nav-header__dropdown[hidden] { display: none; }
.nav-header__dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-base);
  color: var(--color-ink-700);
  text-decoration: none;
}
.nav-header__dropdown-item:hover { background: var(--color-surface-hover); }
.nav-header__dropdown-item button {
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  width: 100%;
  text-align: left;
  padding: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ============================================
   APP SHELL — PRIMARY NAV
   ============================================ */

.nav-primary {
  width: 240px;
  flex-shrink: 0;
  border-right: var(--border-thin);
  background: var(--color-surface-card);
  padding: var(--space-4) 0;
  overflow-y: auto;
}

.nav-primary__list { list-style: none; margin: 0; padding: 0; }

.nav-primary__item { margin-bottom: var(--space-1); }

.nav-primary__link,
.nav-primary__group-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  text-decoration: none;
  font-size: var(--font-size-base);
  color: var(--color-ink-700);
  font-weight: var(--font-weight-medium);
  /* Touch-target ≥ 44px tall on touch UIs (padding + line-height). */
  min-height: var(--control-touch-min);
  line-height: 1.4;
}

.nav-primary__icon { flex-shrink: 0; }

.nav-primary__link:hover { background: var(--color-surface-hover); color: var(--color-ink-900); }

/* Focused but not current — outline + brand-50 fill so the keyboard
   cursor is unmistakable and visually distinct from the active
   left-rule treatment. */
.nav-primary__link:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: -2px;
  background: var(--color-brand-50);
  color: var(--color-ink-900);
}

.nav-primary__item--active > .nav-primary__link,
.nav-primary__item--active > .nav-primary__group-label {
  color: var(--color-brand-600);
  border-left: 3px solid var(--color-brand-600);
  padding-left: calc(var(--space-4) - 3px);
}
.nav-primary__item--active .nav-primary__link[aria-current="page"] {
  background: var(--color-brand-50);
}
/* Current AND focused — keep the active left rule and add a 3px focus ring
   on the opposite edge so both states are recognisable. */
.nav-primary__item--active > .nav-primary__link:focus-visible {
  outline: 3px solid var(--color-brand-600);
  outline-offset: -3px;
  background: var(--color-brand-50);
}

.nav-primary__group-label {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--font-weight-semibold);
  margin-top: var(--space-3);
}

.nav-primary__sub { list-style: none; margin: 0; padding: 0; }

.nav-primary__sub-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-4) var(--space-1) calc(var(--space-4) + var(--space-4));
  font-size: var(--font-size-base);
  color: var(--color-ink-500);
  text-decoration: none;
  /* Touch-target ≥ 44px tall. */
  min-height: var(--control-touch-min);
  line-height: 1.4;
}
.nav-primary__sub-link:hover { color: var(--color-ink-900); background: var(--color-surface-hover); }
.nav-primary__sub-link:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: -2px;
  background: var(--color-brand-50);
  color: var(--color-ink-900);
}
.nav-primary__sub-link[aria-current="page"] {
  color: var(--color-brand-600);
  background: var(--color-brand-50);
}

@media (min-width: 768px) {
  .nav-primary[data-nav-collapsed] {
    display: none;
  }
}

/* Off-canvas drawer (mobile) */
@media (max-width: 767px) {
  .nav-primary {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    height: 100dvh;
    z-index: 100;
    transform: translateX(-100%);
    transition: transform var(--transition-normal);
  }
  .nav-primary[data-drawer-open] { transform: translateX(0); }

  .drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 99;
    background: rgba(26, 31, 28, 0.4);
  }
  .drawer-backdrop[hidden] { display: none; }
}

/* ============================================
   APP SHELL — LAYOUT
   ============================================ */

.app-layout {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

.app-layout > .page {
  flex: 1;
  min-width: 0;
  padding-top: var(--space-5);
}

.page__content {
  min-width: 0;
}

@media (min-width: 768px) {
  body {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }

  .app-layout {
    overflow: hidden;
  }

  .nav-primary {
    min-height: 0;
  }

  .app-layout > .page {
    overflow-y: auto;
  }
}

@media (min-width: 1024px) {
  .page--wide .page__inner {
    max-width: none;
    margin-inline: 0;
  }

  .page__content--crud-list {
    min-height: 0;
  }
}

/* ============================================
   SCREEN-READER ONLY
   ============================================ */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================
   ACCESSIBLE FOCUS
   ============================================ */

:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}

.messages-stack { margin-bottom: var(--space-4); }
.page-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}

.page-heading .page__title {
  margin: 0;
}

.page__title--display {
  font-family: var(--font-display);
  font-size: var(--font-size-2xl);
}

.page-heading__mobile-actions {
  display: none;
}

@media (max-width: 767px) {
  .page--crud-list .page-heading {
    margin-bottom: var(--space-2);
  }

  .page-heading__mobile-actions {
    display: flex;
    margin-left: auto;
  }

  .list-filter-toggle {
    width: var(--control-touch-min);
    height: var(--control-touch-min);
  }

  .list-filter-toggle[hidden] {
    display: none;
  }
}

.skeleton-stack { padding: var(--space-4); }

/* ============================================
   AUTH PAGE (login, password reset)
   --------------------------------------------
   Auth screens sit outside the app shell as a
   centred card on the paper background. Styles
   extend the .card component; all values are
   design-system tokens — no raw values.
   ============================================ */

/* Layout primitive: vertically + horizontally centre the auth card */
.auth-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: var(--space-4);
}

/* Auth card — inherits .card background, border, radius, shadow */
.auth-card {
  width: 100%;
  max-width: 400px;
}

/* Centred brand block: logo → company eyebrow → brand title → subtitle */
.auth-card__brand {
  text-align: center;
  padding: var(--space-6) var(--space-5) var(--space-4);
}

.auth-card__logo {
  display: block;
  margin: 0 auto var(--space-4);
  height: auto;
}

/* Uppercase tracked eyebrow — extends shared .eyebrow */
.auth-card__eyebrow {
  margin-bottom: var(--space-2);
}

.auth-card__title {
  font-family: var(--font-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  margin: 0 0 var(--space-1);
}

.auth-card__subtitle {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  margin: 0;
}

/* Ledger rule — hairline separator (principles §7). Reusable
   in any card or section to separate header-like content from body. */
.card__rule {
  border: none;
  border-top: 1px solid var(--color-border-subtle);
  margin: 0 var(--space-5);
}

.auth-card__form {
  padding: var(--space-5);
}

.auth-card__errors {
  padding: var(--space-4) var(--space-5) 0;
}

.auth-card__actions {
  margin-top: var(--space-5);
}

.auth-card__actions .btn {
  width: 100%;
}

.auth-card__footer {
  text-align: center;
  padding: 0 var(--space-5) var(--space-5);
  font-size: var(--font-size-sm);
}

.auth-card__footer a {
  color: var(--color-brand-600);
  text-decoration: none;
}

.auth-card__footer a:hover {
  text-decoration: underline;
}

/* Quick-login dropdown — staging-only developer tool. The section is only
   rendered when ``QUICK_LOGIN_ENABLED=True``, which must never be set in
   production. */
.auth-card__quick-login {
  padding: var(--space-5);
}

.quick-login__label {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-500);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: var(--space-3);
}

.quick-login__row {
  display: flex;
  gap: var(--space-3);
  align-items: center;
}

.quick-login__select {
  flex: 1;
}

.quick-login__row .btn {
  white-space: nowrap;
}

/* ============================================
   LANDING / INTERIM DASHBOARD (post-login)
   --------------------------------------------
   Throwaway welcome page inside the app shell;
   will be replaced by #77's role-based dashboard.
   Follows the ledger-rule motif (principles §7).
   ============================================ */

.landing {
  max-width: 70ch;
}

.landing__greeting {
  font-family: var(--font-display);
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  margin: var(--space-3) 0 var(--space-4);
  line-height: var(--line-height-tight);
}

.landing__context {
  color: var(--color-ink-500);
  margin-top: var(--space-5);
  line-height: var(--line-height-relaxed);
}

/* ============================================
   ADMIN SCREEN UTILITIES
   ============================================ */

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

/* Toolbar contract for list screens (Issue #281, F8 of the 2026-07-08
   audit). The filter form sits on the left as a flex cluster; the
   primary action sits flush-right; both share the same vertical
   baseline and gap. Used on /people/employees/, /admin/users/, and
   the enrollments tab. See ``docs/design/components.md`` → Data table. */
.toolbar--list {
  margin-bottom: var(--space-5);
  gap: var(--space-3);
}
.toolbar--list > .toolbar__filters {
  flex: 1 1 auto;
  min-width: 0;
}
.toolbar--list > .btn {
  flex: 0 0 auto;
}

.list-filters {
  width: 100%;
  align-items: stretch;
}

.list-filters .field__control {
  width: 100%;
}

@media (max-width: 767px) {
  .toolbar--list {
    align-items: stretch;
  }

  .toolbar--list > .btn {
    width: 100%;
    justify-content: center;
  }

  .toolbar--list > .btn--icon-lg {
    width: calc(var(--control-touch-min) + var(--space-5));
    align-self: flex-end;
  }
}

@media (min-width: 768px) {
  .list-filters {
    width: auto;
    flex-wrap: nowrap;
    align-items: center;
  }

  .list-filters .field__control {
    width: auto;
  }

  .list-filters input[type="search"].field__control {
    min-width: 16rem;
  }
}

.input-search {
  width: 240px;
}

.input-auto {
  width: auto;
}

.form-inline {
  display: inline;
}

.detail-field {
  margin-top: var(--space-1);
  margin-bottom: 0;
}

.form-card {
  max-width: 600px;
}

.detail-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.detail-section__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  margin: var(--space-5) 0 var(--space-3);
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-4);
}

.detail-overview {
  padding: var(--space-4) 0;
}

.detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
@media (min-width: 768px) {
  .detail-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.detail-grid__item {
  margin: 0;
  /* A long unbroken value (an index hash) wraps instead of widening the
     grid track and scrolling the page sideways on phones (Issue #836). */
  min-width: 0;
}
.detail-grid__item .eyebrow {
  margin-bottom: var(--space-1);
}
.detail-grid__item dd {
  /* Keeps the browser-default dd indent: it sets each value off
     under its label (docs/design/patterns.md, Issue #851). */
  margin-top: var(--space-1);
  margin-bottom: 0;
  overflow-wrap: anywhere;
}

/* ============================================
   MASTER–DETAIL CRUD LIST
   ============================================ */

.master-detail {
  display: grid;
  gap: var(--space-4);
  min-width: 0;
}

.master-detail__master,
.master-detail__detail {
  min-width: 0;
}

.master-detail__detail {
  width: 100%;
  max-width: none;
  padding: var(--space-4);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  background: var(--color-surface-card);
}

.master-detail__heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.master-detail__heading h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--font-size-xl);
}

.key-facts-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  grid-auto-rows: 1fr;
  margin-bottom: var(--space-4);
  overflow: hidden;
  border: var(--border-thin);
  border-radius: var(--radius-lg);
}

.key-facts-strip__item {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  min-height: 5rem;
  padding: var(--space-3);
  border-right: var(--border-thin);
  min-width: 0;
}

.key-facts-strip__item:last-child {
  border-right: 0;
}

.key-facts-strip__label {
  color: var(--color-ink-500);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.key-facts-strip__value {
  grid-column: 1 / -1;
  min-width: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

@media (min-width: 1280px) {
  .page--crud-list .master-detail--selected {
    display: grid;
    grid-template-columns: minmax(0, 45fr) minmax(0, 55fr);
    align-items: start;
  }

  .master-detail--selected > .master-detail__detail {
    width: auto;
    position: sticky;
    top: var(--space-4);
    max-height: 75vh;
    overflow-y: auto;
  }
}

.profile-photo {
  max-width: 150px;
  height: auto;
  border-radius: var(--radius-md);
  border: var(--border-thin);
}

.profile-signature {
  max-width: 250px;
  height: auto;
}

.heading-with-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.muted {
  color: var(--color-ink-500);
}

.page__title {
  font-family: var(--font-display);
  font-size: var(--font-size-2xl);
  margin: 0 0 var(--space-5);
}

.divider {
  border: none;
  border-top: 1px solid var(--color-border-subtle);
  margin: var(--space-5) 0;
}

.tab-panel {
  padding: var(--space-4) 0;
}

.detail-base__main .tab-panel {
  padding-top: 0;
}
.tab-panel[hidden] {
  display: none;
}
.tab-panel {
  animation: tab-fade-in var(--transition-fast) ease;
}
@keyframes tab-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.table-link {
  color: var(--color-brand-600);
  text-decoration: none;
  font-weight: var(--font-weight-medium);
}
.table-link:hover {
  text-decoration: underline;
}

/* Form utilities */
.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Form fieldset group */
.form__group {
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin: 0 0 var(--space-5);
  background: var(--color-surface-card);
}
.form__group--removable {
  position: relative;
  padding-top: var(--space-6);
}
.form__group-remove {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: calc(var(--control-height-sm) - var(--space-1));
  height: calc(var(--control-height-sm) - var(--space-1));
  background: var(--color-surface-elevated);
  border-color: var(--color-border-subtle);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}
.form__group-remove .icon {
  width: calc(var(--icon-size-sm) - var(--space-1));
  height: calc(var(--icon-size-sm) - var(--space-1));
}
@media (max-width: 767px) {
  .form__group { padding: var(--space-4); }
  .form__group--removable { padding-top: var(--space-6); }
}

/* Repeatable form group (#832): one entry of a list the user grows, e.g. a
   CBT question-selection rule. The header line names the entry ("Rule 2")
   and carries its icon-only remove control, so the control can't be read
   as belonging to the next entry. */
.form__group--repeat {
  padding: var(--space-4);
  margin-bottom: var(--space-4);
}
.form__group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--control-height-sm);
  margin-bottom: var(--space-4);
}
.form__group-title {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-900);
}
.form__group--repeat > .alert {
  margin-bottom: var(--space-4);
}
.form__group--repeat > .form__row:last-child {
  margin-bottom: 0;
}

/* Exam question picker (#887, components.md § Exam question picker).
   Mode chooser: a radio group drawn as side-by-side tiles. */
.choice-tiles {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}
@media (min-width: 768px) {
  .choice-tiles { grid-template-columns: 1fr 1fr; }
}
.choice-tile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--control-touch-min);
  padding: var(--space-4);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  background: var(--color-surface-card);
  cursor: pointer;
}
.choice-tile:hover { background: var(--color-surface-hover); }
.choice-tile:has(:checked) {
  border-color: var(--color-brand-600);
  background: var(--color-brand-50);
}
.choice-tile:has(:focus-visible) {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}
.choice-tile input { margin-top: var(--space-1); flex: none; }
.choice-tile__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.choice-tile__title {
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-900);
}
.choice-tile__help {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

/* Picker layout: list left, sticky summary card right at >=1024px; below
   that the summary stacks above the list so the count stays in view. */
.picker-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
}
.picker-layout__main { min-width: 0; }
.picker-layout__aside { order: -1; }
@media (min-width: 1024px) {
  .picker-layout { grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr); }
  .picker-layout__aside {
    order: 0;
    position: sticky;
    top: var(--space-4);
    align-self: start;
  }
}
.picker-summary__total {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
}
.picker-summary__split {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
}
.picker-summary__split dt {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}
.picker-summary__split dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}
.table-check {
  width: 1.25rem;
  height: 1.25rem;
  cursor: pointer;
}
/* Button pager (picker): same look as the link pager, disabled = --disabled. */
button.pagination__page {
  background: transparent;
  cursor: pointer;
  font: inherit;
}
button.pagination__page:disabled {
  color: var(--color-ink-300);
  cursor: default;
}

.form__legend {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-900);
  padding: 0;
  margin-bottom: var(--space-4);
}

/* Form row — responsive two-column layout */
.form__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
@media (min-width: 768px) {
  .form__row {
    grid-template-columns: 1fr 1fr;
  }
}
.form__row .field {
  margin-bottom: 0;
}

.field-with-action {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: end;
}
.field-with-action .field {
  margin-bottom: 0;
}
.field-with-action .btn {
  justify-self: start;
}
@media (min-width: 768px) {
  .field-with-action {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}

/* Form actions — spaced action bar with sticky-bottom on mobile */
.form__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border-subtle);
}
@media (max-width: 767px) {
  .form__actions {
    position: sticky;
    bottom: 0;
    background: var(--color-surface-page);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-4) calc(-1 * var(--space-4)) 0;
    border-top: var(--border-thin);
    z-index: 10;
  }
  .form__actions .btn {
    flex: 1;
  }
}

/* File input — normalize browser chrome */
.field input[type="file"].field__control {
  height: auto;
  padding: var(--space-2) 0;
  border: none;
  background: transparent;
  font-size: var(--font-size-sm);
  color: var(--color-ink-700);
}
.field input[type="file"].field__control::file-selector-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--control-height-sm);
  padding: 0 var(--space-3);
  margin-right: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-ink-700);
  background: var(--color-cream-200);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}
.field input[type="file"].field__control::file-selector-button:hover {
  background: var(--color-cream-300);
}

/* Compact field variant */
.field--sm {
  margin-bottom: var(--space-3);
}

.field--sm .field__label {
  font-size: var(--font-size-xs);
}

.field--sm .field__control {
  height: var(--control-height-sm);
  font-size: var(--font-size-sm);
}

/* Toolbar utilities */
.toolbar__actions {
  display: flex;
  gap: var(--space-3);
  align-items: center;
}

.toolbar__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.toolbar__filters select.field__control {
  width: auto;
  min-width: 200px;
}

.toolbar__search {
  flex: 1;
  min-width: 200px;
}

.toolbar__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  margin: 0;
}

/* Enrollment panel — card treatment for enrollment sections */
.enrollments-panel {
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  background: var(--color-surface-card);
}

/* Nav header utilities */
.nav-header__name {
  font-size: var(--font-size-lg);
}

.nav-header__user-menu {
  position: relative;
}

/* ==========================================================================
   CBT Exam Player (#79)
   ========================================================================== */

.exam-player {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.exam-timer {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface-card);
  border-bottom: 1px solid var(--color-border-default);
  font-variant-numeric: tabular-nums;
}

.exam-timer__label {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.exam-timer__value {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}

.exam-timer__value--warning {
  color: var(--color-status-warning);
}

.exam-timer__value--danger {
  color: var(--color-status-error);
}

.exam-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .exam-layout {
    grid-template-columns: 1fr 200px;
  }
}

.exam-question {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.exam-question__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.exam-question__counter {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.exam-question__points {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.exam-question__meta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  text-align: right;
}

.exam-question__type,
.exam-question__instruction {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.exam-question__instruction {
  margin: 0;
}

.exam-scenario {
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-subtle);
  border-left: 3px solid var(--color-brand-primary);
  border-radius: var(--radius-md);
}

.exam-scenario p {
  margin: var(--space-1) 0 0;
}

.exam-question__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.exam-question__text {
  font-size: var(--font-size-base);
  line-height: 1.6;
}

.option-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  list-style: none;
  padding: 0;
  margin: 0;
}

.option-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color 0.15s;
}

.option-row:hover {
  background: var(--color-surface-hover);
}

/* Authoring options editor (question form). Deliberately not .option-row:
   that is the exam player's bordered, clickable answer row (#832). */
.option-editor {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.option-editor__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.option-editor__row .field__control {
  flex: 1 1 auto;
  min-width: 0;
}

.option-editor__row .field--checkbox,
.option-editor__row .field--radio {
  flex-shrink: 0;
}

.option-editor__add {
  align-self: flex-start;
}

.option-text {
  font-size: var(--font-size-base);
}

.answer-input {
  /* native input hidden inside option-row */
}

.exam-navigator {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-md);
}

@media (max-width: 767px) {
  .exam-navigator {
    order: -1;
  }
}

.exam-navigator__title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
}

.exam-navigator__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-1);
}

.exam-navigator__stats {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.nav-dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-default);
  text-decoration: none;
  color: var(--color-ink-900);
  transition: background-color 0.15s;
}

.nav-dot:hover {
  background: var(--color-surface-hover);
}

/* Answered = success border + a check badge, never the fill alone
   (patterns.md § CBT exam player: "not colour alone", #832). */
.nav-dot--answered {
  position: relative;
  border-color: var(--color-status-success);
  background: var(--color-status-success-bg);
}

.nav-dot__mark {
  position: absolute;
  top: calc(-1 * var(--space-1));
  right: calc(-1 * var(--space-1));
  width: calc(var(--icon-size-sm) - var(--space-1));
  height: calc(var(--icon-size-sm) - var(--space-1));
  border-radius: 50%;
  background: var(--color-surface-card);
}

/* After --answered on purpose: the current dot keeps its brand fill and
   white text whether or not it's answered (was white on pale green). */
.nav-dot--current,
.nav-dot--current.nav-dot--answered {
  border-color: var(--color-brand-primary);
  background: var(--color-brand-primary);
  color: #fff;
}

.exam-actions {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-4);
  border-top: 1px solid var(--color-border-default);
  position: sticky;
  bottom: 0;
  background: var(--color-surface-card);
}

@media (min-width: 768px) {
  .exam-actions {
    position: static;
  }
}

.save-indicator {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  min-height: 1.2em;
}

.save-indicator--saved {
  color: var(--color-status-success);
}

.save-indicator--error {
  color: var(--color-status-error);
}

/* Result screen */
.result {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.result__score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6);
}

.result__score-value {
  font-size: 3rem;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}

.card--correct {
  border-left: 4px solid var(--color-status-success);
}

.card--incorrect {
  border-left: 4px solid var(--color-status-error);
}

.btn--small {
  font-size: var(--font-size-sm);
  padding: var(--space-1) var(--space-2);
}

.btn--disabled {
  opacity: 0.5;
  pointer-events: none;
}

.text-muted {
  color: var(--color-ink-500);
}

.correct {
  color: var(--color-status-success);
}

.incorrect {
  color: var(--color-status-error);
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.form-field__input {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-base);
  font-family: inherit;
}

.form-actions {
  display: flex;
  gap: var(--space-4);
  padding-top: var(--space-4);
}

/* ============================================
   DASHBOARD AND WIDGETS
   ============================================ */
.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.dashboard-greeting {
  font-family: var(--font-display);
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  margin: 0;
}

.dashboard-period {
  padding: var(--space-2) var(--space-4);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  color: var(--color-ink-700);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  cursor: pointer;
}

.dashboard-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

/* Stat row rules: always grid or flex */
.dashboard-stat-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

@media (min-width: 480px) {
  .dashboard-stat-row {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 768px) {
  .dashboard-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .dashboard-stat-row {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1024px) {
  .dashboard-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .dashboard-stat-row.stats-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Span utility for larger widgets */
@media (min-width: 768px) {
  .span-2 {
    grid-column: span 2;
  }
}

/* Mini table inside widgets */
.widget-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--space-2);
}

.widget-table th,
.widget-table td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: var(--border-thin);
  font-size: var(--font-size-sm);
}

.widget-table th {
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-700);
  background: var(--color-cream-100);
}

.widget-table td {
  color: var(--color-ink-900);
}

/* Widget error and retry */
.widget-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-4);
}

.widget-error__message {
  color: var(--color-status-error);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-3);
}

/* Tabular number styling for statistics */
.stat__value.tnum {
  font-variant-numeric: tabular-nums;
}

/* SVG Chart styling */
.widget-chart {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--space-4);
}

.widget-chart svg {
  max-width: 100%;
  height: auto;
}

/* UI/UX Utility Classes */
.link {
  color: var(--color-brand-600);
  text-decoration: none;
}
.link:hover {
  text-decoration: underline;
}

.font-mono {
  font-family: var(--font-mono);
}

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

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

.error-text {
  color: var(--color-status-error);
}

.success-text {
  color: var(--color-status-success);
}

.stack--sm {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* Flex-column children default to min-width: auto (own min-content size),
     which forces a wide child (e.g. a data table) to grow every ancestor up
     to <html> instead of letting an ancestor's own overflow:auto engage
     locally. min-width: 0 lets this flex chain shrink. See #594. */
  min-width: 0;
}

/* Audit feed (admin dashboard widget — Issue #280 / F14) */
.audit-feed {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.audit-feed__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--space-2);
  padding-block: var(--space-1);
  border-bottom: 1px dashed var(--color-border-subtle);
}

.audit-feed__item:last-child {
  border-bottom: none;
}

.audit-feed__actor {
  font-weight: 600;
}

.audit-feed__verb {
  color: var(--color-ink-500);
}

.audit-feed__target {
  color: var(--color-ink-700);
}

.audit-feed__time {
  margin-inline-start: auto;
  color: var(--color-ink-500);
  font-size: var(--font-size-sm);
}

/* Stat placeholder (partner CBT Pass Rate empty state — Issue #280) */
.stat-placeholder__label {
  margin: 0;
  color: var(--color-ink-500);
}

.stat-placeholder__value {
  margin: var(--space-1) 0 0;
  font: var(--font-display) var(--font-size-2xl) / 1 var(--font-display);
  font-variant-numeric: tabular-nums;
}

.stat-placeholder__hint {
  margin: var(--space-1) 0 0;
}

/* Audit practice — workspace shell (Issue #373, DR-2 §2). */

.phase-rail {
  display: block;
  margin-bottom: var(--space-4);
}

.phase-rail__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0;
  margin: 0;
  list-style: none;
}

.phase-rail__item {
  flex: 1 1 0;
  min-width: 8rem;
}

.phase-rail__step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-ink-700);
  font-weight: 500;
}

.phase-rail__step--past {
  background: var(--color-status-success-tint, var(--color-surface));
  border-color: var(--color-status-success, var(--color-ink-200));
  color: var(--color-ink-900);
}

.phase-rail__step--current {
  border-color: var(--color-status-info, var(--color-brand-600));
  border-width: 2px;
  font-weight: 600;
}

.phase-rail__step--future {
  color: var(--color-ink-500);
  background: transparent;
}

.phase-rail__marker {
  display: inline-block;
  min-width: 4.5rem;
  padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: 600;
  text-align: center;
  border-radius: var(--radius-sm);
  background: var(--color-ink-100);
  color: var(--color-ink-700);
}

.phase-rail__step--past .phase-rail__marker {
  background: var(--color-status-success-tint, var(--color-ink-100));
  color: var(--color-status-success, var(--color-ink-700));
}

.phase-rail__step--current .phase-rail__marker {
  background: var(--color-status-info-tint, var(--color-ink-100));
  color: var(--color-status-info, var(--color-brand-600));
}

/* Workspace layout — sections on the left, gate panel on the right ≥lg. */
.workspace-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 1024px) {
  .workspace-grid {
    grid-template-columns: 2fr 1fr;
  }
}

/* Gate list — rows of chip + label used in the gate panel and the dashboard. */
.gate-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 0;
  margin: 0;
  list-style: none;
}

.gate-list__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-ink-100);
}

.gate-list__row:last-child {
  border-bottom: 0;
}

/* Inline detail grid for the engagement header (no key/value stacking on lg). */
.detail-grid--inline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  margin: 0;
}

.detail-grid--inline .detail-grid__item {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-2);
}

.detail-grid--inline dt {
  font-weight: 500;
  color: var(--color-ink-500);
}

.detail-grid--inline dd {
  margin: 0;
}

/* ============================================
   PROGRESS BAR (Issue #665, docs/design/components.md)
   ============================================ */

.progress-bar {
  display: block;
  width: 100%;
  background-color: var(--color-cream-300);
  border-radius: var(--radius-full);
  overflow: hidden;
}

.progress-bar--sm {
  height: var(--space-1);
}

.progress-bar--md {
  height: var(--space-2);
}

.progress-bar__track {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  overflow: hidden;
}

.progress-bar__fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-full);
  background-color: var(--color-brand-600);
  transition: width var(--transition-fast);
}

.progress-bar--teal .progress-bar__fill {
  background-color: var(--color-data-teal);
}

/* ============================================
   AUDIO PLAYER (Issue #665, docs/design/components.md)
   ============================================ */

.audio-player {
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
}

.audio-player__progress {
  margin-bottom: var(--space-3);
}

.audio-player__main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.audio-player__now-playing {
  flex: 1 1 12rem;
  min-width: 0;
}

.audio-player__chapter {
  display: block;
  margin-bottom: var(--space-1);
}

.audio-player__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-900);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.audio-player__provenance {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
  margin: var(--space-1) 0 0;
}

.audio-player__timing {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-ink-700);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.audio-player__time-current,
.audio-player__time-total {
  font-variant-numeric: tabular-nums;
}

.audio-player__time-separator {
  color: var(--color-ink-300);
}

.audio-player__transport {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.audio-player__btn {
  width: var(--control-touch-min);
  height: var(--control-touch-min);
  min-width: var(--control-touch-min);
  min-height: var(--control-touch-min);
  padding: 0;
  border-radius: var(--radius-full);
}

.audio-player__btn--prev,
.audio-player__btn--next {
  background: var(--color-surface-card);
  color: var(--color-ink-700);
  border: var(--border-thin);
}

.audio-player__btn--play {
  background: var(--color-brand-600);
  color: #fff;
  border-color: var(--color-brand-600);
}

.audio-player__btn--play:hover:not(:disabled) {
  background: var(--color-brand-500);
}

.audio-player__icon {
  width: var(--icon-size-md);
  height: var(--icon-size-md);
}

.audio-player__btn--play .audio-player__icon {
  width: var(--icon-size-lg);
  height: var(--icon-size-lg);
}

.audio-player__controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.audio-player__native {
  width: 100%;
  min-height: var(--control-touch-min);
  accent-color: var(--color-brand-600);
}

.audio-player__speed {
  font-weight: var(--font-weight-semibold);
}

/* Compact sticky variant */
.audio-player--compact {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  border-bottom: none;
  box-shadow: var(--shadow-md);
  padding: var(--space-3) var(--space-4);
}

.audio-player--compact .audio-player__title {
  font-size: var(--font-size-base);
}

/* ============================================
   STUDY HUB SURFACES (Issue #665, docs/design/study-hub.md)
   ============================================ */

/* Key facts strip */
.study-hub-key-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-subtle);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  min-width: 0;
  max-width: 100%;
}

@media (max-width: 480px) {
  .study-hub-key-facts {
    grid-template-columns: 1fr;
  }
}

.study-hub-key-facts__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.study-hub-key-facts__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--control-height-sm);
  height: var(--control-height-sm);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  color: var(--color-brand-600);
  flex-shrink: 0;
}

.study-hub-key-facts__label {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
  margin-bottom: 2px;
}

.study-hub-key-facts__value {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-900);
  font-variant-numeric: tabular-nums;
}

/* Audio Episode List */
.audio-episode-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  min-width: 0;
}

.audio-episode-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: var(--control-touch-min);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--color-ink-900);
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
  min-width: 0;
}

.audio-episode-row:hover {
  background: var(--color-surface-hover);
  border-color: var(--color-brand-300);
}

.audio-episode-row--playing {
  border-color: var(--color-brand-600);
  background: var(--color-brand-50);
}

.audio-episode-row__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex: 1 1 10rem;
}

.audio-episode-row__number {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-500);
  min-width: 4.5rem;
  flex-shrink: 0;
}

.audio-episode-row__title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.audio-episode-row__status {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.audio-episode-row__duration {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  font-variant-numeric: tabular-nums;
}

.audio-episode-row__action {
  display: inline-flex;
  align-items: center;
}

/* Study Hub Layout */
.study-hub-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

@media (min-width: 1024px) {
  .study-hub-layout {
    grid-template-columns: 2fr 1fr;
  }
}

.study-hub-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.study-hub-rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Practice Card */
.practice-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
}

.practice-card__content {
  flex: 1 1 12rem;
}

.practice-card__title {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-1);
}

.practice-card__desc {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  margin: 0;
}

.practice-card__action {
  flex-shrink: 0;
}

/* Study Resource List */
.study-resource-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.study-resource-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border-subtle);
}

.study-resource-item:last-child {
  border-bottom: none;
}

.study-resource-item__info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.study-resource-item__title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-ink-900);
}

.study-resource-item__meta {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
}

.study-resource-item__status {
  flex-shrink: 0;
}

/* Syllabus Assistant */
.assistant-container {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.assistant-transcript {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--color-surface-subtle);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  min-height: 16rem;
}

.assistant-message {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  max-width: 90%;
}

.assistant-message--user {
  align-self: flex-end;
  background: var(--color-brand-600);
  color: #fff;
}

.assistant-message--user .assistant-message__author {
  color: var(--color-brand-100);
}

.assistant-message--user .assistant-message__time {
  /* Issue #707 AC-G4: --color-brand-200 on this bubble's --color-brand-600
     background computed to a 4.33:1 contrast ratio at this element's 11px
     text size -- just under WCAG AA's 4.5:1 minimum for normal-size text
     (a pre-existing, unrelated defect surfaced by Task 29's full-journey
     axe scan, first flagged as known-but-unfixed by Task 24). --color-
     brand-100 -- already used one line above for this same bubble's
     ``.assistant-message__author`` -- computes to 5.8:1 against the same
     background, comfortably clearing AA.
  */
  color: var(--color-brand-100);
}

.assistant-message--assistant {
  align-self: flex-start;
  background: var(--color-surface-card);
  border: var(--border-thin);
  color: var(--color-ink-900);
}

.assistant-message--thinking {
  align-self: flex-start;
  background: var(--color-surface-subtle);
  border: 1px dashed var(--color-border-strong);
  color: var(--color-ink-500);
  font-style: italic;
}

.assistant-message__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-xs);
}

.assistant-message__author {
  font-weight: var(--font-weight-semibold);
}

.assistant-message__time {
  color: var(--color-ink-500);
  font-variant-numeric: tabular-nums;
}

.assistant-message__body {
  font-size: var(--font-size-base);
  line-height: var(--line-height-relaxed);
  margin: 0;
}

.assistant-message__citations {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border-subtle);
}

.assistant-message__citation-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-500);
}

.assistant-message__citation-list {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-2);
  width: 100%;
}

.assistant-citation {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 100%;
}

.assistant-citation[open] {
  width: 100%;
}

.assistant-citation__summary {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  list-style: none;
}

.assistant-citation__summary::-webkit-details-marker {
  display: none;
}

.assistant-citation__summary:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
  border-radius: var(--radius-full);
}

.assistant-citation__source {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-xs);
  color: var(--color-ink-600);
  font-weight: var(--font-weight-semibold);
}

.assistant-citation__excerpt {
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-subtle);
  border-left: 3px solid var(--color-brand-500);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
  font-style: italic;
  color: var(--color-ink-700);
  line-height: var(--line-height-normal);
  width: 100%;
  box-sizing: border-box;
}

.citation-ref {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25em;
  padding: 0 var(--space-1);
  margin: 0 1px;
  border: 1px solid var(--color-brand-300);
  border-radius: var(--radius-full);
  background: var(--color-brand-50);
  color: var(--color-brand-700);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1.4;
  cursor: pointer;
  vertical-align: super;
}

.citation-ref:hover,
.citation-ref:focus-visible {
  background: var(--color-brand-100);
  outline: none;
}

.citation-ref:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 1px;
}

.assistant-citation-anchor {
  display: inline-flex;
  border-radius: var(--radius-full);
}

.assistant-citation-anchor--highlight {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
  border-radius: var(--radius-full);
}

.assistant-citation-inline {
  display: inline;
}

.assistant-citation-inline__excerpt {
  display: block;
  margin: var(--space-2) 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-subtle);
  border-left: 3px solid var(--color-brand-500);
  border-radius: var(--radius-sm);
  color: var(--color-ink-700);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
}

.assistant-citation-inline__excerpt[hidden] {
  display: none;
}

.assistant-citation-inline__excerpt .assistant-citation__source {
  display: block;
  margin: 0 0 var(--space-1);
}

.assistant-message__attribution {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
  margin-top: var(--space-1);
  font-variant-numeric: tabular-nums;
}

.study-hub-v3__reader-assistant {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: var(--color-surface-subtle);
  border: var(--border-thin);
  border-radius: var(--radius-md);
}

.study-hub-v3__reader-assistant p {
  margin: var(--space-1) 0 0;
}

.study-hub-v3__reader-assistant-form {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.assistant-composer {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
}

.assistant-composer__field {
  width: 100%;
}

.assistant-composer__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}

/* Sync status & Catalogue helpers */
.sync-status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--space-4);
}

/* Curriculum catalogue toolbar — the shared list-screen toolbar contract
   (docs/design/components.md "Data table" / Issue #281). The version
   selector and paper search are two ``.toolbar__filters`` clusters on one
   baseline row; on narrow screens they wrap like every other list toolbar. */
.catalogue-toolbar {
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

/* The visible "Curriculum Version" label sits inline beside its select
   (unlike the sr-only search labels in the shared table toolbar), so it
   must not carry the stacked-field bottom margin that would push the
   select out of vertical alignment with the search box. */
.catalogue-toolbar__label {
  margin-bottom: 0;
}

.catalogue-toolbar > .catalogue-toolbar__filters {
  flex: 0 0 auto;
}

.catalogue-toolbar > .catalogue-toolbar__filters--search {
  margin-left: auto;
  justify-content: flex-end;
}

.catalogue-toolbar__search {
  width: 320px;
  max-width: 100%;
}

@media (max-width: 767px) {
  .catalogue-toolbar > .catalogue-toolbar__filters {
    width: 100%;
  }

  .catalogue-toolbar__version {
    width: 100%;
    max-width: 100%;
  }

  .catalogue-toolbar > .catalogue-toolbar__filters--search {
    margin-left: 0;
    width: 100%;
    justify-content: flex-start;
  }

  .catalogue-toolbar__search {
    width: 100%;
  }
}

.catalogue-comparison {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Curriculum Paper Cards — Student-centric course catalog presentation */
.catalogue-level {
  margin-bottom: var(--space-6);
}

.catalogue-level__header {
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--color-border-subtle);
}

.catalogue-level__title {
  font-family: var(--font-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  margin: 0;
}

.catalogue-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-3);
}

.paper-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast);
  gap: var(--space-3);
}

.paper-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
  border-color: var(--color-brand-300);
}

.paper-card__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
}

.paper-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.paper-card__title {
  font-family: var(--font-display);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  margin: 0;
  line-height: var(--line-height-snug);
}

.paper-card__code {
  display: block;
  color: var(--color-ink-500);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  line-height: var(--line-height-tight);
  text-transform: uppercase;
}

.paper-card__header .chip {
  flex-shrink: 0;
  align-self: flex-start;
}

.paper-card__resources {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.paper-card__icon-item {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: var(--color-surface-subtle);
  border-radius: var(--radius-sm);
  cursor: help;
  transition: background-color var(--transition-fast);
}

.paper-card__icon-item:hover {
  background: var(--color-brand-100);
}

.paper-card__icon-item .icon {
  width: 16px;
  height: 16px;
  opacity: 0.8;
}

.paper-card__count-badge {
  position: absolute;
  top: -4px;
  right: -6px;
  font-size: 10px;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  padding: 1px 4px;
  background: var(--color-brand-600);
  color: #fff;
  border-radius: var(--radius-full);
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}

.paper-card__action {
  flex: 0 0 auto;
  width: var(--control-height-sm);
  height: var(--control-height-sm);
  padding: 0;
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-sm);
  transition: background-color var(--transition-fast), transform var(--transition-fast), box-shadow var(--transition-fast);
}

.paper-card__action:hover {
  transform: translateX(2px);
  box-shadow: var(--shadow-md);
}

.paper-card__action .icon {
  width: var(--icon-size-sm);
  height: var(--icon-size-sm);
}

/* Prototype section & screen switcher */
.prototype-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-5);
}

.prototype-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.prototype-nav__item {
  display: inline-flex;
}

.prototype-nav__link {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-ink-700);
  text-decoration: none;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.prototype-nav__link:hover {
  background: var(--color-surface-hover);
  color: var(--color-brand-600);
}

.prototype-nav__link--active {
  background: var(--color-brand-50);
  color: var(--color-brand-600);
  font-weight: var(--font-weight-semibold);
}

.prototype-section {
  padding-top: var(--space-4);
  border-top: 2px solid var(--color-border-default);
  margin-top: var(--space-8);
}

.prototype-section:first-of-type {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
}

.prototype-section__header {
  margin-bottom: var(--space-4);
}

.prototype-section__title {
  font-family: var(--font-display);
  font-size: var(--font-size-2xl);
  color: var(--color-ink-900);
  margin: 0 0 var(--space-1);
}

.prototype-section__desc {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  margin: 0;
}

.prototype-section__content {
  margin-top: var(--space-4);
}

.catalogue-table,
.sync-health-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--font-size-base);
}

.catalogue-table thead,
.sync-health-table thead {
  position: sticky;
  top: 0;
  z-index: 2;
  border-bottom: 2px solid var(--color-border-default);
  background: var(--color-surface-subtle);
}

.catalogue-table th,
.sync-health-table th {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-500);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.catalogue-table td,
.sync-health-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border-subtle);
  color: var(--color-ink-900);
  font-variant-numeric: tabular-nums;
}

.detail-header__identity {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.detail-header__title {
  font-family: var(--font-display);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink-900);
  margin: 0;
  word-break: break-word;
  overflow-wrap: break-word;
}

.detail-header__chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

/* ============================================
   MINDMAP & GUIDE VIEWER (Issue #667)
   ============================================ */

.mindmap-viewer {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.mindmap-canvas {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  background: var(--color-surface-card);
}

.mindmap-canvas[hidden] {
  display: none;
}

.mindmap-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.mindmap-toolbar__zoom {
  min-width: 3.5rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.mindmap-canvas__surface {
  position: relative;
  min-height: clamp(30rem, 70vh, 52rem);
  overflow: hidden;
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--color-surface-subtle);
  cursor: grab;
  touch-action: none;
}

.mindmap-canvas__surface--dragging {
  cursor: grabbing;
}

.mindmap-canvas__content {
  position: absolute;
  inset: 0;
  transform-origin: top left;
}

.mindmap-canvas__map {
  /* Explicit width/height (set in app.js from the content's actual depth/
     row extent — #707 AC-C1) only establish real scrollable/pannable
     extent once this has its own positioning context. */
  position: relative;
}

.mindmap-canvas__node {
  position: absolute;
}

.mindmap-canvas__connectors {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.mindmap-canvas__connectors line {
  stroke: var(--color-border-strong);
  stroke-width: 1.5;
}

.mindmap-canvas__node-toggle {
  min-width: 9rem;
  min-height: var(--control-touch-min);
  padding: var(--space-2) var(--space-3);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  color: var(--color-ink-900);
  font: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.mindmap-canvas__node-toggle:hover {
  border-color: var(--color-brand-600);
}

.mindmap-canvas__children {
  display: contents;
}

/* #707 AC-C2: without this, setting the `hidden` attribute on a collapsed
   node's children container (app.js's toggle handler) has no visual effect
   -- the browser's own `[hidden] { display: none }` UA rule and this file's
   `.mindmap-canvas__children { display: contents }` rule above have equal
   (0,1,0) specificity, so the author rule (this file) wins regardless of
   the `hidden` attribute being set. A `[hidden]` qualifier raises this
   rule's specificity to (0,2,0) so collapsing a branch actually hides it,
   not just its `aria-expanded` bookkeeping. */
.mindmap-canvas__children[hidden] {
  display: none;
}

.mindmap-viewer--enhanced .mindmap-tree {
  display: none;
}

.mindmap-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .mindmap-grid {
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  }
}

.mindmap-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
}

.mindmap-card__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 8rem;
  background: var(--color-surface-subtle);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  color: var(--color-brand-600);
}

.mindmap-card__title {
  font-family: var(--font-display);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  margin: 0;
}

.mindmap-card__meta {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
}

/* Issue #707 AC-B3: the practice quiz attached to this exact source card
   (via PaperStudyQuiz.resource) renders here, inside the card, instead of
   in a separate paper-wide list. */
.mindmap-card__quiz {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: var(--border-thin);
}

.mindmap-card__quiz-title {
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  margin: 0;
}

/* Mobile nested tree for mindmaps and study resources (<768px) */
.mindmap-tree {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.mindmap-tree__node {
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  overflow: hidden;
}

.mindmap-tree__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3);
  cursor: pointer;
  font-weight: var(--font-weight-medium);
  min-height: var(--control-touch-min);
  user-select: none;
}

.mindmap-tree__summary:hover {
  background: var(--color-surface-hover);
}

.mindmap-tree__content {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border-subtle);
  background: var(--color-surface-subtle);
  font-size: var(--font-size-sm);
}

/* Flashcard deck (Issue #707 AC-E3) -- a dedicated question/answer
   component that shares zero class names with .mindmap-tree__* above, so a
   future mindmap-tree styling change can never unintentionally affect
   flashcards (and vice versa). Each card is a real <details class=
   "flashcard"> element -- the no-JS baseline is every card visible as a
   plain list, answers revealed via the browser's own summary/details
   toggle, mirroring the mindmap tree/canvas pair's own fallback pattern
   above. See docs/design/components.md#flashcard. */
.flashcard-deck {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.flashcard {
  display: block;
  overflow: hidden;
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

/* app.js adds this once it takes over: only the active card is shown, and
   every <details> is forced open so the reveal button + `hidden` attribute
   (not the native open/closed state) become the single source of truth for
   whether the answer is visible. */
.flashcard-deck--enhanced .flashcard {
  display: none;
}

.flashcard-deck--enhanced .flashcard.is-active {
  display: flex;
  flex-direction: column;
}

/* Without app.js, the reveal button and Previous/Next controls have no
   click handler and the answer has no `hidden` attribute to toggle -- both
   controls are inert and their aria-expanded/aria-pressed="false" would
   misrepresent an answer that's already visible via native <details>. Hide
   them until app.js adds --enhanced; the details/summary disclosure alone
   is the truthful no-JS reveal mechanism. */
.flashcard-deck:not(.flashcard-deck--enhanced) .flashcard__reveal-button,
.flashcard-deck:not(.flashcard-deck--enhanced) .flashcard__nav {
  display: none;
}

.flashcard__eyebrow {
  display: block;
  margin-bottom: var(--space-2);
  color: var(--color-ink-500);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.08em;
  line-height: var(--line-height-tight);
  text-transform: uppercase;
}

.flashcard__question {
  display: block;
  padding: var(--space-5);
  margin: 0;
  background: var(--color-surface-subtle);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-900);
  line-height: var(--line-height-snug);
}

.flashcard__question::-webkit-details-marker {
  display: none;
}

.flashcard__question::marker {
  content: "";
}

.flashcard__body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  /* Reserve the overlap control's touch target so the card's rounded
     container never clips its lower half when the answer is hidden. */
  min-height: var(--control-touch-min);
}

.flashcard__reveal-button {
  position: absolute;
  z-index: 1;
  top: calc(-1 * var(--space-5));
  right: var(--space-4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-touch-min);
  min-height: var(--control-touch-min);
  padding: 0;
  margin: 0;
  background: var(--color-brand-600);
  color: var(--color-surface-card);
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

.flashcard__reveal-button:hover {
  background: var(--color-brand-700);
}

.flashcard__reveal-button .icon {
  width: 20px;
  height: 20px;
}

.flashcard__toggle-icon {
  transform: rotate(-90deg);
}

.flashcard__reveal-button.is-revealed .flashcard__toggle-icon {
  transform: rotate(90deg);
}

.flashcard__answer {
  padding: var(--space-6) var(--space-5) var(--space-5);
  background: var(--color-brand-50);
  border-top: 1px solid var(--color-brand-100);
  font-size: var(--font-size-lg);
  line-height: var(--line-height-relaxed);
  color: var(--color-ink-700);
}

.flashcard__answer .flashcard__eyebrow {
  color: var(--color-brand-700);
}

.flashcard__answer p {
  margin: 0;
}

.flashcard__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.flashcard__nav-status {
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
}

.study-resource-document {
  margin: 0;
  overflow-wrap: anywhere;
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  line-height: var(--line-height-relaxed);
  color: var(--color-ink-900);
}

.study-resource-frame {
  min-width: 0;
  background: var(--color-surface-card);
}

.study-resource-frame__content {
  max-width: 72rem;
  margin: 0 auto;
  padding: var(--space-6);
}

.study-resource-frame__header {
  padding-bottom: var(--space-5);
  border-bottom: var(--border-thin);
}

.study-resource-frame__header h1 {
  margin: 0;
  color: var(--color-ink-900);
  font-family: var(--font-display);
  font-size: var(--font-size-xl);
  line-height: var(--line-height-snug);
}

.study-resource-frame__header + .study-resource-document {
  padding-top: var(--space-6);
}

.study-resource-document > :first-child {
  margin-top: 0;
}

.study-resource-document > :last-child {
  margin-bottom: 0;
}

.study-hub-tab-panel {
  display: none;
}

.study-hub-tab-panel--active {
  display: block;
}
/* Study Hub v3 learner composition (Issue #721). */
.list-controls { display: flex; flex-direction: column; gap: var(--space-3); }
.list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.list-row__icon { flex: none; width: var(--space-6); height: var(--space-6); color: var(--color-brand-600); display: flex; align-items: center; justify-content: center; }
.list-row__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.list-row__title { font-weight: var(--font-weight-semibold); overflow-wrap: break-word; }
.list-row__meta { font-size: var(--font-size-xs); color: var(--color-ink-500); }
.list-row__badges { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-1); }
.provenance-footer { margin-top: var(--space-6); padding-top: var(--space-3); border-top: var(--border-thin); color: var(--color-ink-500); font-size: var(--font-size-xs); }
.study-hub-v3__panel { display: none; min-width: 0; }
.study-hub-v3__panel--active { display: block; }
#panel-assistant.study-hub-v3__panel--active {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
#panel-mocks.study-hub-v3__panel--active {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
#panel-assistant.study-hub-v3__panel--active > h2,
#panel-assistant.study-hub-v3__panel--active > p,
#panel-assistant.study-hub-v3__panel--active > .list-controls,
#panel-assistant.study-hub-v3__panel--active > #assistant-history-results,
#panel-assistant.study-hub-v3__panel--active > .assistant-transcript,
#panel-assistant.study-hub-v3__panel--active > .assistant-message--thinking,
#panel-assistant.study-hub-v3__panel--active > .assistant-composer,
#panel-assistant.study-hub-v3__panel--active > .provenance-footer {
  margin-block: 0;
}
#panel-mocks.study-hub-v3__panel--active > h2,
#panel-mocks.study-hub-v3__panel--active > p,
#panel-mocks.study-hub-v3__panel--active > .cluster,
#panel-mocks.study-hub-v3__panel--active > .btn,
#panel-mocks.study-hub-v3__panel--active > .table-region,
#panel-mocks.study-hub-v3__panel--active > .provenance-footer {
  margin-block: 0;
}
.study-hub-v3__stats { display: flex; gap: var(--space-4); flex-wrap: wrap; padding: var(--space-3) 0; color: var(--color-ink-500); font-size: var(--font-size-sm); }
.study-hub-v3__stats strong { color: var(--color-ink-900); font-variant-numeric: tabular-nums; }
.study-hub-v3__controls { margin-top: var(--space-4); margin-bottom: var(--space-5); }
.list-controls .field { margin-bottom: 0; }
.study-hub-v3__group-title {
  margin-top: var(--space-6);
  margin-bottom: var(--space-3);
}
.study-hub-v3__materials { margin-top: var(--space-3); }
/* Base list/list-row (docs/design/foundations.md:38-61; prototype styles.css:128-146) */
.study-hub-v3 .list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.study-hub-v3 .list-row { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface-card); border: var(--border-thin); overflow-wrap: break-word; flex-wrap: wrap; }
.study-hub-v3 .list-row--official-source { background: var(--color-brand-100); border-color: var(--color-brand-200); }
.study-hub-v3 .list-row__icon { flex: none; width: var(--space-6); height: var(--space-6); display: flex; align-items: center; justify-content: center; }
.study-hub-v3 .list-row__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.study-hub-v3 .list-row__title { font-weight: var(--font-weight-semibold); }
.study-hub-v3 .list-row__official-pill { margin-left: var(--space-2); vertical-align: middle; }
.study-hub-v3 .list-row__meta { font-size: var(--font-size-xs); color: var(--color-ink-500); }
.study-hub-v3 .list-row__badges { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-1); max-width: 100%; }
/* A quiz-title badge can be longer than the pill pattern's usual short
   label; let it wrap onto a second line rather than force page-level
   horizontal overflow at narrow viewports (AC-G4, 390px). */
.study-hub-v3 .list-row__badges .chip { max-width: 100%; white-space: normal; text-align: left; }
.study-hub-v3 .list-row__actions { display: flex; gap: var(--space-2); flex: none; width: calc(100% - var(--space-6) - var(--space-3)); margin-left: calc(var(--space-6) + var(--space-3)); }
@media (min-width: 768px) {
  .study-hub-v3 .list-row { flex-wrap: nowrap; align-items: center; }
  .study-hub-v3 .list-row__actions { width: auto; align-self: center; margin-left: 0; }
}
/* Split reader panel (docs/design/components.md "Split reader panel") */
.study-hub-v3__split { display: flex; flex-direction: column; gap: var(--space-5); }
.study-hub-v3__split-list, .study-hub-v3__split-reader { min-width: 0; }
.study-hub-v3__reader { display: flex; flex-direction: column; gap: var(--space-3); position: relative; }
.study-hub-v3__reader-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
}
.study-hub-v3__reader-toolbar-start {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}
.study-hub-v3__reader-toolbar-end {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}
.study-hub-v3__pdf-reader { display: flex; flex-direction: column; gap: var(--space-3); min-height: 0; }
.study-hub-v3__pdf-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; padding: var(--space-2) var(--space-3); background: var(--color-surface-card); border: var(--border-thin); border-radius: var(--radius-md); }
.study-hub-v3__pdf-page-label { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--font-size-sm); }
.study-hub-v3__pdf-page-label input { width: 3.5rem; padding: var(--space-1); border: var(--border-thin); border-radius: var(--radius-sm); text-align: center; font-variant-numeric: tabular-nums; }
.study-hub-v3__pdf-status { margin-left: auto; color: var(--color-ink-500); font-size: var(--font-size-xs); }
.study-hub-v3__pdf-reader:fullscreen { display: flex; padding: var(--space-4); background: var(--color-ink-900); }
.study-hub-v3__pdf-reader:fullscreen .study-hub-v3__pdf-pages { flex: 1; min-height: 0; }
.study-hub-v3__pdf-selection-menu { position: absolute; z-index: 2; max-width: min(22rem, calc(100% - var(--space-4))); padding: var(--space-2); background: var(--color-surface-elevated); border: var(--border-thin); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.study-hub-v3__pdf-selection-actions { display: flex; gap: var(--space-2); }
.annotation-drawer__page-link { padding-inline: var(--space-1); text-decoration: underline; }
.study-hub-v3__pdf-pages { display: flex; justify-content: center; overflow: auto; padding: var(--space-3); background: var(--color-ink-900); border-radius: var(--radius-md); }
.study-hub-v3__pdf-page { position: relative; flex: none; background: var(--color-surface-card); box-shadow: var(--shadow-md); }
.study-hub-v3__pdf-page canvas { display: block; }
.study-hub-v3__pdf-annotation { position: absolute; z-index: 1; pointer-events: none; border-radius: 2px; }
.study-hub-v3__pdf-annotation--highlight { background: rgba(250, 204, 21, 0.45); }
.study-hub-v3__pdf-annotation--note { background: rgba(59, 130, 246, 0.2); outline: 2px solid rgba(37, 99, 235, 0.55); }
.study-hub-v3__pdf-page .textLayer { position: absolute; inset: 0; overflow: hidden; opacity: 0.2; line-height: 1; }
.study-hub-v3__pdf-page .textLayer span { position: absolute; color: transparent; white-space: pre; transform-origin: 0 0; cursor: text; }
.study-hub-v3__reader-title {
  font-family: var(--font-display);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-base);
  color: var(--color-ink-900);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.study-hub-v3__reader-close {
  flex: 0 0 auto;
  width: var(--control-height-sm);
  height: var(--control-height-sm);
  padding: 0;
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-sm);
  transition: background-color var(--transition-fast), transform var(--transition-fast), box-shadow var(--transition-fast);
}
.study-hub-v3__reader-close:hover {
  transform: scale(1.05);
  box-shadow: var(--shadow-md);
}
.study-hub-v3__reader-close .icon {
  width: var(--icon-size-sm);
  height: var(--icon-size-sm);
}
.study-hub-v3__reader-frame { width: 100%; min-height: calc(100vh - 280px); border: var(--border-thin); border-radius: var(--radius-md); }
.study-hub-v3__reader-image-wrap {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  width: 100%;
  min-height: calc(100vh - 280px);
  padding: var(--space-3);
  overflow: auto;
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--color-surface-subtle);
}
.study-hub-v3__reader-image {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: calc(100vh - 320px);
  height: auto;
  object-fit: contain;
}
@media (max-width: 1439.98px) {
  /* Under 1440px (standard laptops & desktops with nav sidebar), collapse to
     a comfortable full-screen reader: the list steps aside rather than squishing. */
  .study-hub-v3__split--open .study-hub-v3__split-list { display: none; }
  .study-hub-v3__split--open .study-hub-v3__split-reader { width: 100%; }
}
@media (min-width: 1440px) {
  .study-hub-v3__split--open { display: grid; grid-template-columns: minmax(300px, 360px) 1fr; gap: var(--space-5); align-items: start; }
}
/* Annotation drawer (docs/design/components.md "Annotation drawer") */
.annotation-drawer { position: absolute; top: 0; right: 0; bottom: 0; width: min(360px, 100%); background: var(--color-surface-card); border-left: var(--border-thin); box-shadow: var(--shadow-lg); padding: var(--space-4); overflow-y: auto; z-index: 10; }
.annotation-drawer[hidden] { display: none; }
.annotation-drawer__filter { display: flex; gap: var(--space-3); border: none; padding: 0; margin: var(--space-3) 0; flex-wrap: wrap; }
.annotation-drawer__entries { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.annotation-drawer__entry { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-2); border: var(--border-thin); border-radius: var(--radius-md); }
.annotation-drawer__swatch { width: var(--space-3); height: var(--space-3); border-radius: var(--radius-full); flex: none; }
.annotation-drawer__text { flex: 1 1 100%; margin: 0; font-size: var(--font-size-sm); }
.annotation-drawer__meta { font-size: var(--font-size-xs); color: var(--color-ink-500); }
@media (max-width: 1023px) {
  .annotation-drawer { top: 0; left: 0; width: 100%; }
}
/* Area-highlight tool (docs/design/components.md "Area-highlight tool") */
.area-highlight-tool { position: relative; margin-bottom: var(--space-3); }
.area-highlight-tool__surface { position: relative; min-height: 40px; }
.area-highlight-tool__popover { position: absolute; z-index: 20; background: var(--color-surface-card); border: var(--border-thin); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: var(--space-3); }
.area-highlight-tool__popover[hidden] { display: none; }
/* Surface 5 — Authorized content administration (docs/design/study-hub.md) */
.study-hub-admin .list-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface-card); border: var(--border-thin); }
.study-hub-admin .list-row__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
@media (min-width: 768px) {
  .list-controls { flex-direction: row; align-items: end; }
  .list-controls .field { flex: 1 1 auto; }
}

/* ============================================
   COMBOBOX / AUTOCOMPLETE SELECT
   ============================================ */

.combobox {
  position: relative;
  width: 100%;
}

/* The source select stays in the form for submission. Hide it by flag, not by
   inline style: htmx's settle step strips inline styles from swapped elements
   with ids, which resurfaced the native select under the combobox. */
select[data-combobox-enhanced="true"] {
  display: none;
}

.combobox__input {
  cursor: pointer;
  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 fill='%235f6f66' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  padding-right: var(--space-8);
}

.combobox__dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 280px;
  overflow-y: auto;
  background: var(--color-surface-card);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  z-index: 100;
  padding: var(--space-1) 0;
  margin: 0;
  list-style: none;
}

.combobox__group-header {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-brand-700);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--color-cream-100);
  border-top: 1px solid var(--color-border-subtle);
  border-bottom: 1px solid var(--color-border-subtle);
  user-select: none;
}
.combobox__group-header:first-child {
  border-top: none;
}

.combobox__option {
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-base);
  color: var(--color-ink-900);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: background-color var(--transition-fast);
}

.combobox__option:hover,
.combobox__option--active {
  background-color: var(--color-brand-50);
  color: var(--color-brand-900);
}

.combobox__option--selected {
  font-weight: var(--font-weight-semibold);
  background-color: var(--color-brand-100);
  color: var(--color-brand-900);
}

/* Option with a secondary description line (Issue #889 — service picker). */
.combobox__option--has-desc {
  flex-direction: column;
  align-items: flex-start;
}

.combobox__option-desc {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-normal);
  color: var(--color-ink-500);
  line-height: var(--line-height-tight);
}

.combobox__empty {
  padding: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-ink-500);
  text-align: center;
}

/* ============================================
   PERIOD NAVIGATOR (docs/design/components.md §Period navigator)
   Shared by period-aware dashboards (M|Q|Y) and reports (D|M|Q|Y).
   ============================================ */

.period-navigator {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  color: var(--color-ink-700);
}

.period-navigator__row {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.period-navigator__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--control-touch-min);
  min-height: var(--control-touch-min);
  padding: var(--space-1) var(--space-2);
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  color: var(--color-ink-700);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}

.period-navigator__btn:hover {
  background: var(--color-surface-hover);
  border-color: var(--color-brand-400);
}

.period-navigator__btn:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: 2px;
}

.period-navigator__btn:disabled,
.period-navigator__btn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
  background: var(--color-surface-subtle);
}

/* Segmented grain control (D | M | Q | Y) */
.period-navigator__segments {
  display: inline-flex;
  border: var(--border-thin);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.period-navigator__segment {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--control-touch-min);
  min-height: var(--control-touch-min);
  padding: var(--space-1) var(--space-2);
  border: none;
  border-right: var(--border-thin);
  background: var(--color-surface-card);
  color: var(--color-ink-500);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold, 600);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.period-navigator__segment:last-child {
  border-right: none;
}

.period-navigator__segment:hover {
  background: var(--color-surface-hover);
  color: var(--color-ink-900);
}

.period-navigator__segment:focus-visible {
  outline: 2px solid var(--color-brand-600);
  outline-offset: -2px;
  z-index: 1;
  position: relative;
}

.period-navigator__segment[aria-current="true"],
.period-navigator__segment--active {
  background: var(--color-brand-600);
  color: #ffffff;
}

.period-navigator__segment[aria-current="true"]:hover,
.period-navigator__segment--active:hover {
  background: var(--color-brand-500);
  color: #ffffff;
}

/* Comparison label */
.period-navigator__comparison {
  font-size: var(--font-size-xs);
  color: var(--color-ink-500);
  padding: 0 var(--space-2);
  margin-top: var(--space-2);
  white-space: nowrap;
}
