@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  [x-cloak] { display: none !important; }

  ::selection {
    color: #fff;
    background: #6b5317;
  }

  body {
    @apply bg-ruforum-surface font-body text-ruforum-text antialiased;
  }

  /* Django-rendered form widgets */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="date"],
  input[type="datetime-local"] {
    @apply block w-full rounded-lg border border-ruforum-border bg-white px-3.5 py-2.5 text-sm text-ruforum-text shadow-sm transition-colors duration-150;
    @apply placeholder:text-ruforum-text-muted/60;
    @apply focus:border-ruforum-primary focus:outline-none focus:ring-2 focus:ring-ruforum-primary/[0.18];
  }

  textarea {
    @apply block w-full resize-y rounded-lg border border-ruforum-border bg-white px-3.5 py-2.5 text-sm text-ruforum-text shadow-sm transition-colors duration-150;
    @apply placeholder:text-ruforum-text-muted/60;
    @apply focus:border-ruforum-primary focus:outline-none focus:ring-2 focus:ring-ruforum-primary/[0.18];
  }

  select {
    @apply block w-full rounded-lg border border-ruforum-border bg-white px-3.5 py-2.5 pr-9 text-sm text-ruforum-text shadow-sm transition-colors duration-150 cursor-pointer;
    @apply focus:border-ruforum-primary focus:outline-none focus:ring-2 focus:ring-ruforum-primary/[0.18];
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%2372675c' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    background-size: 1.2rem;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
  }

  /* File input — give the picker button the brand look */
  input[type="file"] {
    @apply block w-full text-sm text-ruforum-text;
    @apply file:mr-4 file:cursor-pointer file:rounded-lg file:border-0 file:bg-ruforum-primary file:px-4 file:py-2.5 file:font-meta file:text-[11px] file:font-semibold file:uppercase file:tracking-[0.10em] file:text-white;
    @apply hover:file:bg-ruforum-primary-hover;
  }

  /* Checkbox & radio — clean square / dot, brand-coloured when checked */
  input[type="checkbox"],
  input[type="radio"] {
    @apply h-4 w-4 shrink-0 cursor-pointer border border-ruforum-border-strong bg-white shadow-sm transition-colors;
    @apply focus:outline-none focus:ring-2 focus:ring-ruforum-primary/[0.25] focus:ring-offset-1;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
  }
  input[type="checkbox"] { @apply rounded-sm; }
  input[type="radio"] { @apply rounded-full; }

  input[type="checkbox"]:checked,
  input[type="radio"]:checked {
    background-color: #6b5317;
    border-color: #6b5317;
  }
  input[type="checkbox"]:checked {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3E%3Cpath d='M12.78 4.22a.75.75 0 010 1.06L7.06 11l-3.34-3.34a.75.75 0 011.06-1.06L7.06 8.88l4.66-4.66a.75.75 0 011.06 0z'/%3E%3C/svg%3E");
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
  }
  input[type="radio"]:checked {
    background-image: radial-gradient(circle, #ffffff 32%, transparent 36%);
  }
}

@layer components {
  /* REP catalogue search — mock: pill field, white, generous padding (base input[type=search] outranks utilities) */
  .rep-catalogue-q-wrap input[type="search"] {
    @apply rounded-xl border border-ruforum-border bg-white py-3.5 pl-12 pr-4 text-sm text-ruforum-text shadow-sm transition-colors duration-150;
    @apply placeholder:text-ruforum-text-muted/70;
    @apply focus:border-ruforum-primary focus:outline-none focus:ring-2 focus:ring-ruforum-primary/[0.18];
  }

  .rep-catalogue-toolbar select {
    @apply rounded-xl py-3.5;
  }

  /* ── Card ─────────────────────────────────────────────────────── */
  .card {
    @apply rounded-xl border border-ruforum-border bg-white shadow-card;
  }

  /* ── Callout family ───────────────────────────────────────────── */
  /* .callout--warn       = full-width flow-breaking panel (icon + body)
     .callout--warn-inline = compact pill notice (single line, badge-like) */
  .callout {
    @apply flex items-start gap-3 rounded-xl border px-4 py-3 text-sm;
  }
  .callout__icon {
    @apply mt-0.5 h-4 w-4 shrink-0;
  }
  .callout__body {
    @apply min-w-0 flex-1 leading-relaxed;
  }
  .callout--warn {
    @apply border-amber-200 bg-amber-50 text-amber-900;
  }
  .callout--warn .callout__icon {
    @apply text-amber-700;
  }
  .callout--warn-inline {
    @apply inline-flex items-center gap-2 rounded-lg border border-amber-200 bg-amber-50/80 px-3 py-1.5 text-xs font-semibold text-amber-900;
  }
  .callout--warn-inline .callout__icon {
    @apply mt-0 h-3.5 w-3.5 text-amber-700;
  }
  .callout--success { @apply border-emerald-200 bg-emerald-50 text-emerald-900; }
  .callout--success .callout__icon { @apply text-emerald-700; }
  .callout--error   { @apply border-rose-200 bg-rose-50 text-rose-900; }
  .callout--error   .callout__icon { @apply text-rose-700; }
  .callout--info    { @apply border-sky-200 bg-sky-50 text-sky-900; }
  .callout--info    .callout__icon { @apply text-sky-700; }

  /* ── Chip family (small inline status/tag) ─────────────────────── */
  .chip--qa {
    @apply inline-flex items-center gap-1 rounded-md bg-ruforum-primary/[0.08] px-2 py-0.5 font-meta text-[10.5px] font-semibold uppercase tracking-[0.10em] text-ruforum-primary;
  }

  /* ── Primary button ───────────────────────────────────────────────
     border matches bg (invisible) so height/width lines up exactly with
     .btn-secondary / .btn-danger, which both carry a real 1px border.
  */
  .btn-primary {
    @apply inline-flex items-center justify-center gap-2 rounded-lg border border-ruforum-primary bg-ruforum-primary px-4 py-2.5 text-sm font-semibold text-white transition-colors duration-150 hover:border-ruforum-primary-hover hover:bg-ruforum-primary-hover focus:outline-none focus:ring-2 focus:ring-ruforum-primary focus:ring-offset-2;
  }

  /* ── Secondary button ─────────────────────────────────────────── */
  .btn-secondary {
    @apply inline-flex items-center justify-center gap-2 rounded-lg border border-ruforum-border bg-white px-4 py-2.5 text-sm font-medium text-ruforum-text transition-colors duration-150 hover:bg-ruforum-warm-hover focus:outline-none focus:ring-2 focus:ring-ruforum-primary focus:ring-offset-2;
  }

  /* ── Destructive / caution button variant ──────────────────────
     Used for Reject / Cancel / Withdraw in confirmation modals and rails.
     Must precede .btn-sm so the size modifier overrides its padding/font
     (equal specificity → later rule wins).
  */
  .btn-danger {
    @apply inline-flex items-center justify-center gap-2 rounded-lg border border-red-200 bg-white px-4 py-2.5 text-sm font-semibold text-red-700 transition-colors duration-150 hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-500/40 focus:ring-offset-2;
  }

  /* ── Small button modifier (applies after every variant above) ──── */
  .btn-sm {
    padding-top: 0.375rem;
    padding-bottom: 0.375rem;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    font-size: 0.75rem;
    line-height: 1rem;
  }

  /* ── Sidebar nav link — default ───────────────────────────────── */
  .nav-link-default {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    border-radius: 0.5rem;
    padding: 0.625rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 500;
    color: rgba(255,255,255,0.70);
    transition: background-color 150ms, color 150ms;
  }
  .nav-link-default:hover {
    background-color: rgba(255,255,255,0.08);
    color: #ffffff;
  }
  .nav-link-default:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.40);
  }

  /* ── Sidebar nav link — active ────────────────────────────────── */
  .nav-link-active {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    border-radius: 0.5rem;
    padding: 0.625rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 500;
    background-color: #6b5317;
    color: #ffffff;
  }
  .nav-link-active:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.40);
  }

  /* ── Sidebar section label ────────────────────────────────────── */
  .nav-section-label {
    padding: 0.5rem 0.75rem 0.125rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.28);
    font-family: "Archivo Narrow", "Barlow", sans-serif;
  }

  /* ── Sidebar group toggle ─────────────────────────────────────── */
  .nav-group-toggle {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    border-radius: 0.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: rgba(255,255,255,0.60);
    transition: background-color 150ms, color 150ms;
    text-align: left;
    cursor: pointer;
  }
  .nav-group-toggle:hover {
    background-color: rgba(255,255,255,0.07);
    color: rgba(255,255,255,0.90);
  }
  .nav-group-toggle:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.30);
  }

  /* ── Sidebar sub-link — default ───────────────────────────────── */
  .nav-sublink-default {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    border-radius: 0.375rem;
    padding: 0.3125rem 0.75rem 0.3125rem 2.375rem;
    font-size: 0.8125rem;
    color: rgba(255,255,255,0.52);
    transition: background-color 150ms, color 150ms;
  }
  .nav-sublink-default:hover {
    background-color: rgba(255,255,255,0.07);
    color: #ffffff;
  }

  /* ── Sidebar sub-link — active ────────────────────────────────── */
  .nav-sublink-active {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    border-radius: 0.375rem;
    padding: 0.3125rem 0.75rem 0.3125rem 2.375rem;
    font-size: 0.8125rem;
    font-weight: 500;
    background-color: rgba(107,83,23,0.50);
    color: #ffffff;
  }

  /* ── Badge variants ───────────────────────────────────────────── */
  .badge {
    @apply inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold font-meta tracking-wide;
  }
  .badge-primary  { @apply badge bg-ruforum-primary/10 text-ruforum-primary; }
  .badge-neutral  { @apply badge bg-stone-100 text-stone-600; }
  .badge-green    { @apply badge bg-emerald-50 text-emerald-700; }
  .badge-emerald  { @apply badge bg-emerald-50 text-emerald-700; }
  .badge-red      { @apply badge bg-red-50 text-red-700; }
  .badge-rose     { @apply badge bg-rose-50 text-rose-700; }
  .badge-amber    { @apply badge bg-amber-50 text-amber-700; }
  .badge-sky      { @apply badge bg-sky-50 text-sky-700; }
  .badge-violet   { @apply badge bg-violet-50 text-violet-700; }
  .badge--strong.badge-rose    { @apply bg-rose-100 text-rose-800; }
  .badge--strong.badge-amber   { @apply bg-amber-100 text-amber-800; }
  .badge--strong.badge-emerald { @apply bg-emerald-100 text-emerald-800; }
  .badge--strong.badge-green   { @apply bg-emerald-100 text-emerald-800; }
  .badge--strong.badge-sky     { @apply bg-sky-100 text-sky-800; }
  .badge--strong.badge-violet  { @apply bg-violet-100 text-violet-800; }
  .badge--strong.badge-neutral { @apply bg-stone-200 text-stone-800; }

  /* ── Ceremonial display ───────────────────────────────────────── */
  .display-1 {
    @apply font-display font-semibold text-ruforum-text;
    font-size: clamp(2rem, 4vw, 3rem);
    line-height: 1.1;
    letter-spacing: -0.01em;
  }

  /* ── Data table ───────────────────────────────────────────────── */
  .data-table {
    @apply w-full text-left text-sm;
  }
  .data-table thead {
    @apply border-b border-ruforum-border-strong bg-ruforum-surface;
  }
  .data-table thead th {
    @apply px-4 py-2.5 font-meta text-xs font-semibold uppercase tracking-wide text-ruforum-text-muted;
  }
  .data-table tbody tr {
    @apply border-t border-ruforum-border transition-colors duration-75 hover:bg-ruforum-warm-hover;
  }
  .data-table tbody td {
    @apply px-4 py-2.5;
  }
  /* Numeric cells: right-aligned with tabular figures */
  .data-table .td-num {
    @apply text-right tabular-nums;
  }
  /* Row action link — lighter than a button, appropriate for table rows */
  .table-link {
    @apply text-xs font-medium text-ruforum-primary transition-colors hover:text-ruforum-primary-hover hover:underline focus:outline-none focus:ring-1 focus:ring-ruforum-primary rounded;
  }
  .table-link-muted {
    @apply text-xs font-medium text-ruforum-text-muted transition-colors hover:text-ruforum-text focus:outline-none focus:ring-1 focus:ring-ruforum-border rounded;
  }
  /* Semantic action link variants — used for Accept / Request revision in row actions */
  .table-link-success {
    @apply text-xs font-medium text-emerald-700 transition-colors hover:text-emerald-800 hover:underline focus:outline-none focus:ring-1 focus:ring-emerald-500 rounded;
  }
  .table-link-danger {
    @apply text-xs font-medium text-red-700 transition-colors hover:text-red-800 hover:underline focus:outline-none focus:ring-1 focus:ring-red-500 rounded;
  }

  /* ── Sortable column header (paired with components/sortable_th.html) ── */
  /* The `group` marker class is added directly on the <a> in the partial — */
  /* @apply does not support marker utilities, so the hover-reveal of the   */
  /* arrow uses sibling selectors instead of group-hover.                   */
  .sortable-th {
    @apply inline-flex items-center gap-1.5 text-left transition-colors hover:text-ruforum-text focus:outline-none focus:ring-1 focus:ring-ruforum-primary rounded;
  }
  .sortable-th__arrow {
    @apply h-3 w-3 shrink-0 text-ruforum-text-muted opacity-0 transition-opacity;
  }
  .sortable-th:hover .sortable-th__arrow {
    @apply opacity-60;
  }
  .sortable-th--active {
    @apply text-ruforum-primary;
  }
  .sortable-th--active .sortable-th__arrow {
    @apply text-ruforum-primary opacity-100;
  }

  /* ── List toolbar (search + facets + export, above any data-table) ── */
  /* Two-row layout: top row holds search (left) + export (right via      */
  /* ml-auto); bottom row holds the facet rail spanning full width.       */
  .list-toolbar {
    @apply mb-4 flex flex-col gap-y-3;
  }
  .list-toolbar__row {
    @apply flex flex-wrap items-center gap-3;
  }
  .list-toolbar__search {
    @apply flex w-[18rem] max-w-full items-center gap-2 rounded-lg border border-ruforum-border bg-white px-3 py-2 text-sm transition-colors focus-within:border-ruforum-primary focus-within:ring-1 focus-within:ring-ruforum-primary;
  }
  .list-toolbar__search input {
    @apply w-full border-0 bg-transparent p-0 text-sm text-ruforum-text placeholder:text-ruforum-text-muted focus:outline-none focus:ring-0;
  }
  .list-toolbar__facets {
    @apply flex min-w-0 flex-wrap items-center gap-1.5;
  }
  /* Suppress the standalone-mode margins of filter_facets.html when */
  /* it's nested inside a list_toolbar facets wrapper.                */
  .list-toolbar__facets > nav {
    margin: 0;
    padding: 0;
    overflow: visible;
  }
  .list-toolbar__actions {
    @apply ml-auto flex shrink-0 items-center gap-2;
  }

  /* ── REP shared utilities (promoted from inline <style> blocks) ───────────── */

  /* Toggle row + switch — lesson authoring, course settings */
  .toggle-row {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 0.85rem 0;
  }
  .toggle-row__body { flex: 1 1 auto; min-width: 0; }
  .toggle-row__title {
    font-family: "Spectral", serif;
    font-size: 0.95rem;
    font-weight: 600;
    color: oklch(0.18 0.05 65);
    line-height: 1.3;
  }
  .toggle-row__hint {
    margin-top: 0.25rem;
    font-family: "Barlow", sans-serif;
    font-size: 0.78rem;
    line-height: 1.5;
    color: oklch(0.45 0.025 70);
  }
  .toggle-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    width: 2.4rem;
    height: 1.35rem;
    border-radius: 999px;
    background: oklch(0.88 0.025 80);
    border: 1px solid oklch(0.78 0.03 75);
    cursor: pointer;
    transition: background 180ms ease, border-color 180ms ease;
    margin-top: 0.15rem;
  }
  .toggle-switch input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    margin: 0;
  }
  .toggle-switch__thumb {
    position: absolute;
    left: 2px;
    top: 1px;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 999px;
    background: oklch(1 0 0);
    box-shadow: 0 1px 2px oklch(0.30 0.05 70 / 0.20);
    transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .toggle-switch:has(input:checked) {
    background: oklch(0.45 0.07 65);
    border-color: oklch(0.45 0.07 65);
  }
  .toggle-switch:has(input:checked) .toggle-switch__thumb { transform: translateX(1.05rem); }
  .toggle-switch:has(input:focus-visible) {
    outline: 2px solid oklch(0.50 0.07 65);
    outline-offset: 3px;
  }

  /* Form section legend — used inside <section class="rounded-2xl border..."> headers */
  .form-section__legend {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 1.25rem;
    border-bottom: 1px solid oklch(0.92 0.02 80);
    background: oklch(0.98 0.015 80);
  }
  .form-section__legend-eyebrow {
    font-family: "Archivo Narrow", sans-serif;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: oklch(0.50 0.025 70);
  }
  .form-section__legend-title {
    font-family: "Spectral", serif;
    font-size: 0.95rem;
    font-weight: 600;
    color: oklch(0.18 0.05 65);
  }

  /* Tabs (lesson authoring, CV builder) */
  .tabs {
    display: flex;
    align-items: stretch;
    gap: 0;
    border-bottom: 1px solid oklch(0.86 0.025 80);
    margin-bottom: 1.75rem;
  }
  .tabs__btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.85rem 0.25rem;
    margin-right: 1.75rem;
    background: transparent;
    border: none;
    cursor: pointer;
    font-family: "Spectral", serif;
    font-size: 0.95rem;
    font-weight: 600;
    color: oklch(0.50 0.025 70);
    transition: color 160ms ease;
  }
  .tabs__btn:hover { color: oklch(0.30 0.05 65); }
  .tabs__btn:focus-visible {
    outline: 2px solid oklch(0.50 0.07 65);
    outline-offset: 4px;
    border-radius: 0.25rem;
  }
  .tabs__btn--current { color: oklch(0.18 0.05 65); }
  .tabs__btn--current::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: oklch(0.45 0.07 65);
    border-radius: 2px;
  }

  /* Avatar — networking home + discovery (warm-palette deterministic tints) */
  .avatar { display: inline-flex; align-items: center; justify-content: center; }
  .avatar-0 { background: oklch(0.93 0.04 80);  color: oklch(0.32 0.07 65); }
  .avatar-1 { background: oklch(0.92 0.045 110); color: oklch(0.30 0.07 95); }
  .avatar-2 { background: oklch(0.91 0.06 45);  color: oklch(0.32 0.10 30); }
  .avatar-3 { background: oklch(0.93 0.04 25);  color: oklch(0.34 0.08 15); }
  .avatar-4 { background: oklch(0.92 0.04 155); color: oklch(0.30 0.07 140); }
  .avatar-5 { background: oklch(0.93 0.025 250); color: oklch(0.32 0.05 240); }

  /* Networking nav tile — institutional restraint */
  .nav-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    padding: 1.1rem 1.15rem 1rem;
    border-radius: 1rem;
    background: oklch(1 0 0);
    border: 1px solid oklch(0.86 0.025 80);
    transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1),
                box-shadow 180ms cubic-bezier(0.2, 0.8, 0.2, 1),
                border-color 160ms ease;
    overflow: hidden;
  }
  .nav-tile::before {
    content: "";
    position: absolute;
    inset: 0 0 0 88%;
    background: oklch(0.96 0.03 70 / 0.45);
    pointer-events: none;
    transition: opacity 200ms ease;
  }
  .nav-tile:hover {
    transform: translateY(-1px);
    border-color: oklch(0.74 0.05 75);
    box-shadow: 0 6px 18px -10px oklch(0.30 0.05 70 / 0.20);
  }
  .nav-tile:hover::before { opacity: 1.4; }
  .nav-tile:active { transform: translateY(1px); }
  .nav-tile__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.65rem;
    background: oklch(0.94 0.04 75);
    color: oklch(0.30 0.07 65);
  }
  .nav-tile__label {
    font-family: "Archivo Narrow", sans-serif;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: oklch(0.45 0.025 70);
    font-weight: 600;
  }
  .nav-tile__title {
    font-family: "Spectral", serif;
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.2;
    color: oklch(0.22 0.04 70);
  }
  .nav-tile__count {
    font-family: "Spectral", serif;
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1;
    color: oklch(0.30 0.05 65);
    font-variant-numeric: tabular-nums;
  }
  .nav-tile__hint {
    font-family: "Archivo Narrow", sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    color: oklch(0.46 0.04 70);
  }

  /* Person row — networking home directory */
  .person-row {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1.1rem;
    transition: background 120ms ease;
  }
  .person-row:hover { background: oklch(0.97 0.025 75); }
  .person-row + .person-row { border-top: 1px solid oklch(0.92 0.02 80); }

  /* Person card hover lift — networking discovery */
  .person-card {
    transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1),
                box-shadow 180ms cubic-bezier(0.2, 0.8, 0.2, 1),
                border-color 180ms ease;
    will-change: transform;
  }
  .person-card:hover {
    transform: translateY(-1px);
    border-color: oklch(0.78 0.04 75);
    box-shadow: 0 6px 20px -10px oklch(0.30 0.05 70 / 0.18),
                0 1px 0 oklch(0.30 0.05 70 / 0.04);
  }

  /* Filter chip — discovery active-filter pills */
  .filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.4rem 0.25rem 0.7rem;
    border-radius: 999px;
    background: oklch(0.95 0.025 75);
    border: 1px solid oklch(0.85 0.04 75);
    font-family: "Archivo Narrow", sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    color: oklch(0.30 0.05 70);
    line-height: 1;
    transition: transform 80ms ease;
  }
  .filter-chip:active { transform: scale(0.97); }
  .filter-chip__label { text-transform: uppercase; opacity: 0.7; font-weight: 600; }
  .filter-chip__value {
    font-family: "Barlow", sans-serif;
    font-size: 0.78rem;
    letter-spacing: 0;
    text-transform: none;
    color: oklch(0.22 0.04 70);
  }
  .filter-chip__x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 999px;
    background: oklch(1 0 0 / 0.6);
    color: oklch(0.30 0.05 70);
    transition: background 120ms ease;
  }
  .filter-chip__x:hover { background: oklch(0.86 0.06 30); color: oklch(0.32 0.10 25); }

  /* Filter disclosure pill — discovery toolbar */
  .filter-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.5rem 0.85rem;
    font-family: "Archivo Narrow", sans-serif;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 600;
    color: oklch(0.28 0.04 70);
    background: oklch(1 0 0);
    border: 1px solid oklch(0.86 0.03 80);
    border-radius: 999px;
    transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
  }
  .filter-toggle:hover { background: oklch(0.96 0.025 80); border-color: oklch(0.74 0.05 75); }
  .filter-toggle:active { transform: translateY(1px); }
  .filter-toggle--active {
    background: oklch(0.94 0.05 75);
    border-color: oklch(0.70 0.07 70);
    color: oklch(0.20 0.05 65);
  }

  /* Wiki link affordance — distinguishes resolved vs missing pages */
  .wiki-link { color: var(--ruforum-primary, #6b5317); border-bottom: 1px solid currentColor; }
  .wiki-link:hover { background: rgba(107, 83, 23, 0.06); }
  .wiki-link--missing { color: #b45309; border-bottom-style: dashed; }

  /* Live session pulse — list.html "Live now" indicator */
  .live-now-pulse { position: relative; display: inline-flex; align-items: center; gap: 0.4rem; }
  .live-now-pulse::before {
    content: "";
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 999px;
    background: oklch(0.62 0.16 145);
    box-shadow: 0 0 0 0 oklch(0.62 0.16 145 / 0.6);
    animation: live-pulse 1.5s ease-out infinite;
  }
  @keyframes live-pulse {
    0%   { box-shadow: 0 0 0 0 oklch(0.62 0.16 145 / 0.6); }
    100% { box-shadow: 0 0 0 10px oklch(0.62 0.16 145 / 0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .live-now-pulse::before { animation: none; }
  }

  /* ── Filter form (uniform label-above-control grid used in expenditure_list, ── */
  /* ── stipend_list, audit_log, anywhere multiple labeled filters need to align) ─ */
  .filter-form {
    @apply flex flex-wrap items-end gap-3;
  }
  .filter-form__actions {
    @apply ml-auto flex shrink-0 items-end pb-px;
  }
  .filter-field {
    @apply flex min-w-0 flex-col gap-1;
  }
  .filter-field--grow {
    @apply w-full max-w-md flex-1;
  }
  .filter-field__label {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .filter-field__control {
    @apply flex items-center;
  }
  .filter-field__input {
    @apply w-full rounded-lg border border-ruforum-border bg-white px-3 py-1.5 text-sm text-ruforum-text transition-colors placeholder:text-ruforum-text-muted focus:border-ruforum-primary focus:outline-none focus:ring-1 focus:ring-ruforum-primary;
    /* Match input heights across <input>, <select>, and date pickers */
    line-height: 1.5rem;
  }

  /* @tailwindcss/forms plugin emits `input[type=search]` rules with        */
  /* (0,1,1) specificity that beats plain `.filter-field__input` (0,1,0).  */
  /* Repeat the class selector to bump our specificity to (0,2,0), which   */
  /* wins per-property comparison against the plugin's defaults.           */
  input.filter-field__input,
  select.filter-field__input,
  textarea.filter-field__input {
    @apply rounded-lg border border-ruforum-border bg-white px-3 py-1.5 text-sm text-ruforum-text;
    box-shadow: none;
  }
  /* Search field with leading icon — restore the 2.5rem left-pad that      */
  /* `pl-10` would otherwise lose to the plugin's `input[type=search]`.    */
  input.filter-field__input.pl-10 {
    padding-left: 2.5rem;
  }
  /* <select> draws a chevron via @tailwindcss/forms; the px-3 above clips   */
  /* its room, so the value text collides with the chevron. Restore the     */
  /* right padding (and a sane min-width so short option sets aren't cramped). */
  select.filter-field__input {
    padding-right: 2.25rem;
    min-width: 11rem;
  }

  /* ── Card toolbar (search + actions row inside a card) ─────────── */
  .card-toolbar {
    @apply flex items-center justify-between gap-3 border-b border-ruforum-border px-4 py-3;
  }

  /* ── Form section header ──────────────────────────────────────── */
  .form-section-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #72675c;
    font-family: "Archivo Narrow", "Barlow", sans-serif;
  }

  /* ── Form field label / help / error (used by the finance form pages) ──
     `.form-help` gets a distinct "hint rail" treatment — a subtle primary-tinted
     left rule + small muted text — so field descriptions read as guidance,
     visually separate from labels, values, and errors. */
  .form-label {
    @apply mb-1.5 block text-sm font-medium text-ruforum-text;
  }
  .form-help {
    @apply mt-2 border-l-2 border-ruforum-primary/30 pl-2.5 text-xs italic leading-relaxed text-ruforum-text-muted;
  }
  .form-error {
    @apply mt-1.5 text-xs font-medium text-red-700;
  }

  /* ── Form field label ─────────────────────────────────────────── */
  .field-label {
    @apply block text-sm font-medium text-ruforum-text mb-1.5;
  }
  .field-hint {
    @apply mt-1 text-xs text-ruforum-text-muted;
  }
  .field-error {
    @apply mt-1 text-xs text-red-600;
  }

  /* ── Repository: academic-monograph document row ───────────────
     Replaces generic card grids on browse / search / collection.
     Documents are listed with editorial spacing and divider lines,
     not boxed cards.
  */
  .doc-row {
    @apply border-b border-ruforum-border pt-6 pb-6 first:pt-0 last:border-b-0 last:pb-0;
  }
  .doc-row__eyebrow {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .doc-row__title {
    @apply mt-1.5 block font-display text-xl font-semibold leading-snug text-ruforum-text transition-colors hover:text-ruforum-primary;
  }
  .doc-row__authors {
    @apply mt-1 font-display italic text-sm leading-snug text-ruforum-text/75;
  }
  .doc-row__snippet {
    @apply mt-2 max-w-[72ch] text-[0.9375rem] leading-relaxed text-ruforum-text/85;
  }
  .doc-row__meta {
    @apply mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .doc-row__meta > span + span::before {
    content: "·";
    @apply mr-3 text-ruforum-text-muted/50;
  }

  /* Facet chip (filter row replacement for bare selects) */
  .facet-chip {
    @apply inline-flex items-center gap-1.5 rounded-full border border-ruforum-border bg-white px-3 py-1 font-meta text-[11px] font-medium uppercase tracking-[0.08em] text-ruforum-text-muted transition-colors hover:border-ruforum-border-strong hover:text-ruforum-text;
  }
  .facet-chip:active { transform: scale(0.97); }
  .facet-chip--active {
    @apply border-ruforum-primary bg-ruforum-primary/10 text-ruforum-primary hover:border-ruforum-primary hover:text-ruforum-primary;
  }
  .facet-count {
    @apply ml-1 rounded-sm bg-ruforum-surface px-1.5 py-0.5 text-[10px] font-semibold text-ruforum-text-muted tabular-nums;
  }
  .facet-chip--active .facet-count {
    @apply bg-white/60 text-ruforum-primary;
  }
  .facet-group-label {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }

  /* Hit-count eyebrow above search results */
  .hit-count {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted tabular-nums;
  }
  .hit-count strong {
    @apply font-display text-xl font-semibold normal-case tracking-normal text-ruforum-text;
  }

  /* Stat card (analytics dashboards) */
  .stat-card {
    @apply rounded-xl border border-ruforum-border bg-white px-5 py-5;
  }
  .stat-card__label {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .stat-card__value {
    @apply mt-2 font-display text-3xl font-semibold leading-none text-ruforum-text tabular-nums;
  }
  .stat-card__delta {
    @apply mt-2 font-meta text-xs text-ruforum-text-muted tabular-nums;
  }
  .stat-card--hero {
    @apply bg-ruforum-surface-warm border-ruforum-border-strong py-7;
  }
  .stat-card--hero .stat-card__value {
    @apply text-4xl;
  }
  /* Clickable filter-tile variant — used by triage strips on list pages.
     Active-state ring is bound via [data-active="true"] so callers can
     drive it from a query-param (e.g. ?severity=critical). */
  .stat-card--filter {
    @apply block cursor-pointer transition-all hover:border-ruforum-primary/40 hover:shadow-sm;
  }
  .stat-card--filter[data-active="true"] {
    @apply border-ruforum-primary ring-2 ring-ruforum-primary/15;
  }
  .stat-card__hint {
    @apply mt-1 font-meta text-[10px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }

  /* ── Meta-typography ladder ──────────────────────────────────────
     Replaces the recurring magic-number type sites (text-[10px]
     tracking-[0.14em], …) littered across MEL. xs/sm/md carry
     size + tracking only; pair with `text-ruforum-text-muted` (or
     a specific colour) at the call site, and add `font-semibold
     uppercase` only where the eyebrow treatment is intended.
     `font-meta-eyebrow` is the all-in-one form for the dominant
     section-subtitle eyebrow used at the top of nearly every page. */
  .font-meta-xs {
    @apply font-meta text-[10px] tracking-[0.14em];
  }
  .font-meta-sm {
    @apply font-meta text-[11px] tracking-[0.12em];
  }
  .font-meta-md {
    @apply font-meta text-[12px] tracking-[0.10em];
  }
  .font-meta-eyebrow {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.14em];
  }

  /* Horizontal bar visualisation (used in 'by type', 'compliance', etc.) */
  .h-bar { @apply relative; }
  .h-bar__row {
    @apply flex items-center justify-between gap-4 py-2;
  }
  .h-bar__label {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.10em] text-ruforum-text;
  }
  .h-bar__value {
    @apply font-meta text-xs text-ruforum-text-muted tabular-nums;
  }
  .h-bar__track {
    @apply mt-1 h-1.5 w-full overflow-hidden rounded-full bg-ruforum-surface;
  }
  .h-bar__fill {
    @apply h-full rounded-full bg-ruforum-primary;
  }

  /* Ranked list (used for 'top queries' etc.) */
  .ranked {
    @apply divide-y divide-ruforum-border;
  }

  /* ── Assistant chat polish ────────────────────────────────────────────
     Markdown rendered by marked + DOMPurify. Tailwind preflight strips list
     markers; we restore them scoped to .assistant-md. */
  .assistant-md > :first-child { margin-top: 0; }
  .assistant-md > :last-child { margin-bottom: 0; }
  .assistant-md p { @apply my-1 leading-snug; }
  .assistant-md ul { @apply my-1.5 list-disc pl-5 space-y-0.5; }
  .assistant-md ol { @apply my-1.5 list-decimal pl-5 space-y-0.5; }
  .assistant-md li > p { @apply my-0; }
  .assistant-md li > ul, .assistant-md li > ol { @apply my-0.5; }
  .assistant-md h1 { @apply font-display text-base font-semibold mt-2 mb-1; }
  .assistant-md h2 { @apply font-display text-base font-semibold mt-2 mb-1; }
  .assistant-md h3 { @apply font-display text-sm font-semibold mt-2 mb-1; }
  .assistant-md strong { @apply font-semibold; }
  .assistant-md em { @apply italic; }
  .assistant-md a {
    @apply text-ruforum-primary underline decoration-ruforum-primary/40 underline-offset-2 hover:decoration-ruforum-primary;
  }
  .assistant-md code {
    @apply rounded bg-ruforum-surface/80 px-1 py-0.5 text-[0.85em] font-mono;
  }
  .assistant-md pre {
    @apply my-2 overflow-x-auto rounded-lg bg-ruforum-surface/80 px-3 py-2;
  }
  .assistant-md pre code { @apply bg-transparent p-0; }
  /* No left-rule blockquote — italic indent for typographic emphasis instead. */
  .assistant-md blockquote {
    @apply my-1.5 italic pl-3 text-ruforum-text/85;
  }
  .assistant-md hr { @apply my-3 border-ruforum-border; }
  .assistant-md table { @apply my-2 w-full text-left text-xs; }
  .assistant-md th, .assistant-md td {
    @apply border border-ruforum-border px-2 py-1;
  }
  .assistant-md th { @apply bg-ruforum-surface-warm font-semibold; }

  /* Streaming cursor — solid block tucked at the end of the assistant bubble
     while tokens are arriving. Disappears when the stream is done. */
  .assistant-md.is-streaming::after {
    content: "";
    display: inline-block;
    width: 0.5ch;
    height: 1em;
    margin-left: 0.1ch;
    vertical-align: -0.15em;
    background: currentColor;
    opacity: 0.7;
    animation: assistant-cursor 1s steps(2) infinite;
  }
  @keyframes assistant-cursor {
    50% { opacity: 0; }
  }

  /* Floating action button — warm-tinted shadow, gentle lift on hover. */
  .assistant-fab {
    box-shadow:
      0 1px 2px rgba(66,48,12,0.10),
      0 6px 16px rgba(66,48,12,0.18),
      0 16px 40px rgba(66,48,12,0.18);
  }
  .assistant-fab:active { transform: translateY(0); }

  /* Panel — warm-tinted shadow stack, no harsh black drop-shadow. */
  .assistant-panel {
    box-shadow:
      0 2px 4px rgba(66,48,12,0.06),
      0 12px 28px rgba(66,48,12,0.14),
      0 32px 64px rgba(66,48,12,0.16);
  }

  /* Header icon button — restrained 32×32 hit target, white-on-brown. */
  .assistant-icon-btn {
    @apply inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-white/85 transition-colors;
    @apply hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white/40;
  }
  .assistant-icon-btn.is-active { @apply bg-white/15 text-white; }

  /* Message entrance — subtle slide + fade. Respects reduced motion. */
  @keyframes assistant-msg-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .assistant-msg-in {
    animation: assistant-msg-in 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  @media (prefers-reduced-motion: reduce) {
    .assistant-msg-in { animation: none; }
    .assistant-fab { transition: none; }
    .assistant-md.is-streaming::after { animation: none; opacity: 0.7; }
  }

  /* Hover-revealed copy button on assistant bubbles. */
  .assistant-bubble-actions {
    @apply pointer-events-none absolute -top-1 right-1 flex translate-y-1 opacity-0 transition-all duration-150;
  }
  .assistant-bubble:hover .assistant-bubble-actions,
  .assistant-bubble:focus-within .assistant-bubble-actions {
    @apply pointer-events-auto translate-y-0 opacity-100;
  }
  .assistant-copy-btn {
    @apply inline-flex h-7 w-7 items-center justify-center rounded-md border border-ruforum-border bg-white text-ruforum-text-muted transition-colors hover:border-ruforum-primary/40 hover:text-ruforum-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-ruforum-primary/30;
  }

  /* Conversation history rows — refined hover w/ subtle warm tint. */
  .assistant-history-row {
    @apply flex w-full items-start justify-between gap-3 px-4 py-3 text-left transition-colors;
    @apply hover:bg-ruforum-warm-hover/70 focus:bg-ruforum-warm-hover/70 focus:outline-none;
  }
  .assistant-history-row__chevron {
    @apply h-3.5 w-3.5 shrink-0 self-center text-ruforum-text-muted/40 transition-all;
  }
  .assistant-history-row:hover .assistant-history-row__chevron,
  .assistant-history-row:focus .assistant-history-row__chevron {
    @apply translate-x-0.5 text-ruforum-primary;
  }
  .assistant-history-group-label {
    @apply sticky top-0 z-10 bg-ruforum-surface-warm/95 px-4 py-1.5 font-meta text-[10px] font-semibold uppercase tracking-[0.16em] text-ruforum-text-muted backdrop-blur;
  }

  /* Editorial-feeling empty-state suggestion chip. */
  .assistant-suggestion {
    @apply inline-flex items-center gap-2 rounded-full border border-ruforum-border bg-white px-3.5 py-1.5 text-left text-[0.8rem] leading-snug text-ruforum-text/80 transition-all;
    @apply hover:-translate-y-0.5 hover:border-ruforum-primary/30 hover:bg-ruforum-surface-warm hover:text-ruforum-text hover:shadow-card;
    @apply focus:outline-none focus-visible:ring-2 focus-visible:ring-ruforum-primary/30;
  }
  .assistant-suggestion__arrow {
    @apply text-ruforum-text-muted/40 transition-all;
  }
  .assistant-suggestion:hover .assistant-suggestion__arrow,
  .assistant-suggestion:focus .assistant-suggestion__arrow {
    @apply translate-x-0.5 text-ruforum-primary;
  }

  /* Send button — fixed footprint, compact, brand-tinted; disabled state. */
  .assistant-send-btn {
    @apply inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-ruforum-primary text-white transition-all duration-150;
    @apply hover:bg-ruforum-primary-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-ruforum-primary/40 focus-visible:ring-offset-2;
  }
  .assistant-send-btn:disabled {
    @apply cursor-not-allowed bg-ruforum-border text-white/70 hover:bg-ruforum-border;
  }

  /* Floating "scroll to latest" affordance shown when user has scrolled away. */
  .assistant-scroll-jump {
    @apply pointer-events-none absolute bottom-3 left-1/2 -translate-x-1/2 inline-flex items-center gap-1.5 rounded-full border border-ruforum-border bg-white px-3 py-1 font-meta text-[0.65rem] font-semibold uppercase tracking-[0.16em] text-ruforum-text-muted opacity-0 transition-all duration-200;
    box-shadow: 0 2px 8px rgba(66,48,12,0.10);
  }
  .assistant-scroll-jump.is-visible {
    @apply pointer-events-auto translate-y-0 opacity-100;
  }
  .assistant-scroll-jump:hover {
    @apply border-ruforum-primary/40 text-ruforum-primary;
  }
  .ranked__row {
    @apply flex items-baseline gap-4 py-2.5;
  }
  .ranked__index {
    @apply font-meta text-[11px] font-semibold tabular-nums uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .ranked__label {
    @apply font-display italic text-[0.9375rem] text-ruforum-text;
  }
  .ranked__value {
    @apply ml-auto font-meta text-xs tabular-nums text-ruforum-text-muted;
  }

  /* Vertical timeline (version history + QA decision trail) */
  .timeline {
    @apply relative pl-6;
  }
  .timeline::before {
    content: "";
    @apply absolute left-[5px] top-1 bottom-1 w-0.5 bg-ruforum-border;
  }
  .timeline-node {
    @apply relative pb-7 last:pb-0;
  }
  .timeline-node::before {
    content: "";
    @apply absolute -left-6 top-1.5 h-3 w-3 rounded-full border-2 border-ruforum-border-strong bg-white;
  }
  .timeline-node--active::before {
    @apply border-ruforum-primary bg-ruforum-primary;
  }

  /* Read-column — used on document detail abstract / AI summary */
  .read-col {
    @apply max-w-[72ch] text-[0.9375rem] leading-[1.7] text-ruforum-text;
  }

  /* Quiet section header (replaces heavy h2 with divider) */
  .section-head {
    @apply mb-5 flex items-baseline justify-between gap-4 border-b border-ruforum-border pb-2;
  }
  .section-head__title {
    @apply font-display text-lg font-semibold text-ruforum-text;
  }
  .section-head__aside {
    @apply font-meta text-[11px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }

  /* AI-generated content marker (amber, never indigo) */
  .ai-marker {
    @apply inline-flex items-center gap-1.5 rounded-full bg-amber-50 px-2.5 py-0.5 font-meta text-[10px] font-semibold uppercase tracking-[0.12em] text-amber-800;
  }
  .ai-bleed {
    @apply rounded-lg bg-amber-50/50 px-5 py-4;
  }

  /* Snippet highlight (FTS query hits) */
  mark.snippet {
    background-color: #fce8b8;
    @apply rounded-sm px-0.5 text-ruforum-text;
  }

  /* Quiet meta row used on document detail masthead */
  .meta-row {
    @apply flex flex-wrap items-center gap-x-3 gap-y-1 font-meta text-[11px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .meta-row > * + *::before {
    content: "·";
    @apply mr-3 text-ruforum-text-muted/50;
  }

  /* Definition list rows (sidebar metadata, qa metadata, etc.) */
  .meta-list {
    @apply divide-y divide-ruforum-border;
  }
  .meta-list__row {
    @apply flex items-baseline justify-between gap-4 py-2.5;
  }
  .meta-list__label {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .meta-list__value {
    @apply font-body text-sm text-ruforum-text text-right;
  }
  .meta-list__value--num {
    @apply font-body tabular-nums text-sm text-ruforum-text text-right;
  }

  /* Repository wordmark — used on browse hero */
  .repo-wordmark {
    @apply font-display font-semibold leading-[1.05] tracking-tight text-ruforum-text;
    font-size: clamp(2rem, 4vw, 3rem);
  }
  .repo-eyebrow {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.18em] text-ruforum-text-muted;
  }

  /* Pill-shaped search input override (browse + search hero).
     Anchored to the tag so specificity beats the input[type="search"] base rule. */
  input.repo-search-input,
  input[type="search"].repo-search-input {
    @apply h-12 w-full rounded-full border border-ruforum-border-strong bg-white text-base text-ruforum-text shadow-sm transition-colors;
    padding-left: 3rem;
    padding-right: 1rem;
  }
  input.repo-search-input::placeholder,
  input[type="search"].repo-search-input::placeholder {
    @apply text-ruforum-text-muted/70;
  }
  input.repo-search-input:focus,
  input[type="search"].repo-search-input:focus {
    @apply border-ruforum-primary outline-none ring-2 ring-ruforum-primary/[0.18];
  }
  .repo-search-icon {
    @apply pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-ruforum-text-muted;
    z-index: 1;
  }

  /* Sticky sidebar shell (filter rail / detail metadata) */
  .repo-sticky {
    position: sticky;
    top: calc(3.5rem + 2.25rem + 1.25rem); /* topbar + breadcrumb + breathing room */
  }

  /* Segmented control (used in share modal: VIEW / COMMENT / EDIT) */
  .segmented {
    @apply inline-flex rounded-full border border-ruforum-border bg-white p-0.5;
  }
  .segmented label {
    @apply cursor-pointer rounded-full px-3 py-1 font-meta text-[11px] font-semibold uppercase tracking-[0.10em] text-ruforum-text-muted transition-colors;
  }
  .segmented input { @apply sr-only; }
  .segmented input:checked + span {
    @apply bg-ruforum-primary text-white;
  }
  .segmented input:checked + span,
  .segmented label > span {
    @apply inline-flex items-center justify-center rounded-full px-3 py-1 -mx-3 -my-1;
  }

  /* Cite dropdown body */
  .cite-popover {
    @apply absolute right-0 mt-2 w-80 rounded-xl border border-ruforum-border bg-white p-4 shadow-dropdown;
  }

  /* ── Card-section header pattern ────────────────────────────────
     Use as the first child of a `.card > fieldset` (or `<section>`).
     Renders a numbered eyebrow + Spectral title + thin warm divider.
  */
  .card-section {
    @apply px-6 pt-6 pb-7;
  }
  .card-section + .card-section {
    @apply border-t border-ruforum-border;
  }
  .card-section__head {
    @apply mb-5 flex items-baseline justify-between gap-4 border-b border-ruforum-border pb-3;
  }
  .card-section__step {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted tabular-nums;
  }
  .card-section__title {
    @apply font-display text-lg font-semibold leading-snug text-ruforum-text;
  }
  .card-section__aside {
    @apply font-meta text-[10px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .card-section__lede {
    @apply mt-1 max-w-[60ch] text-sm leading-relaxed text-ruforum-text-muted;
  }

  /* Footer action bar inside a .card */
  .card-footer {
    @apply flex flex-wrap items-center justify-between gap-3 rounded-b-xl border-t border-ruforum-border bg-ruforum-surface-warm px-6 py-4;
  }

  .form-input {
    @apply block w-full rounded-lg border border-ruforum-border bg-white px-3 py-2 text-sm text-ruforum-text shadow-sm focus:border-ruforum-primary focus:outline-none focus:ring-1 focus:ring-ruforum-primary;
  }

  /* Saved formset row marked for deletion via RemoveFormsetRow().
     Visually fades + strikes the row so the user knows it will be removed
     on save, while leaving an undo path (clicking Remove again toggles back). */
  .formset-row--marked-delete {
    @apply opacity-50;
  }
  .formset-row--marked-delete::after {
    content: "Will be removed on save";
    @apply mt-2 block font-meta text-[10px] uppercase tracking-[0.12em] text-red-700;
  }

  /* ── Wizard stepper progress indicator ─────────────────────
     Used with components/forms/wizard_progress.html and the
     wizardForm() Alpine component (static/js/wizard-form.js).
  */
  .wizard-progress__pill {
    @apply inline-flex items-center gap-2 rounded-full border border-ruforum-border bg-white px-3 py-1.5 font-meta text-xs font-medium text-ruforum-text-muted transition hover:border-ruforum-primary/50 hover:text-ruforum-text;
  }
  .wizard-progress__num {
    @apply inline-flex h-5 w-5 items-center justify-center rounded-full border border-ruforum-border bg-ruforum-surface-warm text-[10px] font-semibold tabular-nums text-ruforum-text-muted;
  }
  .wizard-progress__title {
    @apply hidden sm:inline;
  }
  .wizard-progress__sep {
    @apply select-none text-ruforum-text-muted/50;
  }
  .wizard-progress__pill--active {
    @apply border-ruforum-primary bg-ruforum-primary/5 text-ruforum-text;
  }
  .wizard-progress__pill--active .wizard-progress__num {
    @apply border-ruforum-primary bg-ruforum-primary text-white;
  }
  .wizard-progress__pill--done {
    @apply border-emerald-200 bg-emerald-50 text-emerald-800;
  }
  .wizard-progress__pill--done .wizard-progress__num {
    @apply border-emerald-200 bg-emerald-100 text-emerald-800;
  }

  /* ══════════════════════════════════════════════════════════════════
     REP — Wave 1/2 component system
     Adds: performance ramp · sticky tables · kbd hints · command palette ·
     skeletons · learner weekly plan · course prospectus · immersive
     lesson reader · quiz question palette.
  ══════════════════════════════════════════════════════════════════ */

  /* ── Performance color ramp ─────────────────────────────────────
     Unified badges across gradebook, quiz results, analytics.
     Intentionally NOT a coloured stripe border — full rounded pill.
  */
  .score-pill {
    @apply inline-flex items-center gap-1 rounded-full px-2 py-0.5 font-meta text-[11px] font-semibold tabular-nums tracking-wide;
  }
  .score-pass { @apply score-pill bg-emerald-50 text-emerald-800 ring-1 ring-inset ring-emerald-200/70; }
  .score-warn { @apply score-pill bg-amber-50  text-amber-800  ring-1 ring-inset ring-amber-200/70; }
  .score-fail { @apply score-pill bg-red-50    text-red-800    ring-1 ring-inset ring-red-200/70; }
  .score-muted{ @apply score-pill bg-stone-100 text-stone-600  ring-1 ring-inset ring-stone-200/70; }

  /* ── Sticky table column utilities ──────────────────────────────
     Wrap <table> in .table-frame and add .table-col-stick to <td>/<th>
     cells that should freeze during horizontal scroll.
  */
  .table-frame {
    @apply relative w-full overflow-x-auto rounded-xl border border-ruforum-border bg-white;
  }
  .table-frame .table-col-stick-l {
    position: sticky;
    left: 0;
    background: inherit;
    z-index: 2;
  }
  .table-frame thead .table-col-stick-l {
    background: #f0ebe0; /* ruforum-surface */
    z-index: 3;
  }
  .table-frame tbody tr:hover .table-col-stick-l {
    background: #f5efe4; /* ruforum-warm-hover */
  }
  .table-frame .table-col-stick-r {
    position: sticky;
    right: 0;
    background: inherit;
    z-index: 2;
    box-shadow: -4px 0 8px -4px rgba(66,48,12,0.10);
  }
  /* Explicit bg modifiers for frozen columns that need to be opaque against
     scrolled content (e.g. gradebook "Course total" column). Scoped under
     .table-frame so they out-specify the base `background: inherit` on
     .table-col-stick-r (otherwise the pinned column is transparent and the
     last scrolled column bleeds through its header/cells). */
  .table-frame .table-col-stick--head { background: oklch(0.94 0.025 80); }
  .table-frame .table-col-stick--body { background: #fff; }
  .table-frame tbody tr:hover .table-col-stick--body { background: #f5efe4; }

  /* ── Keyboard key hint ──────────────────────────────────────────
     Used inline and in the help modal.
  */
  .kbd {
    @apply inline-flex items-center justify-center rounded-md border border-ruforum-border-strong bg-white px-1.5 py-0.5 font-meta text-[10px] font-semibold uppercase tracking-wide text-ruforum-text-muted shadow-[0_1px_0_0_rgba(66,48,12,0.08)];
    min-width: 1.25rem;
    line-height: 1;
  }
  .kbd + .kbd { @apply ml-1; }

  /* ── Skeleton loader (HTMX placeholder) ─────────────────────────
     Apply to a div or span; animates a gentle shimmer.
  */
  @keyframes ruforum-shimmer {
    0% { background-position: -400px 0; }
    100% { background-position: 400px 0; }
  }
  .skeleton {
    background: linear-gradient(90deg, #ede5d5 0%, #f5efe4 50%, #ede5d5 100%);
    background-size: 800px 100%;
    animation: ruforum-shimmer 1.4s ease-in-out infinite;
    @apply rounded-md;
  }
  .skeleton-line { @apply skeleton h-3 w-full; }
  .skeleton-line-sm { @apply skeleton h-2.5 w-1/2; }
  .skeleton-title { @apply skeleton h-5 w-3/4; }
  .skeleton-card {
    @apply rounded-xl border border-ruforum-border bg-white p-5;
  }
  /* HTMX: only show placeholder while request in flight.
     HTMX adds .htmx-request to the *target* element for the duration of
     the request, so hiding by default and showing under .htmx-request
     gives us the correct skeleton window. */
  .skeleton-host { display: none; }
  .htmx-request .skeleton-host,
  .htmx-request.skeleton-host { display: block; }
  /* Complement to .skeleton-host: hide the live content while a request is in
     flight so the skeleton stands alone instead of stacking over stale rows. */
  .htmx-request .hx-hide-loading { display: none; }

  /* ── Global top progress bar (driven by htmx_progress.js) ───────
     A solid brand-tinted bar pinned to the viewport top; width and
     opacity are tweened by JS while any HTMX request is in flight.
     No gradient — width trickle conveys "indeterminate" instead.
  */
  .htmx-progress {
    @apply fixed left-0 top-0 z-[60] h-0.5 w-0 bg-ruforum-primary;
    opacity: 0;
    pointer-events: none;
    transition: width 0.2s ease, opacity 0.25s ease;
  }
  .htmx-progress.is-active { opacity: 1; }
  @media (prefers-reduced-motion: reduce) {
    .htmx-progress { transition: opacity 0.25s ease; }
  }

  /* ── Region loading overlay (driven by htmx_progress.js) ────────
     The HTMX swap target gets `.hx-loading` for the request window: a
     translucent warm scrim (::before) + a centered brand spinner (::after)
     sit over the region so the user sees exactly which area is updating.
     No gradient — a single solid scrim + a bordered spinner ring.
  */
  @keyframes ruforum-spin { to { transform: rotate(360deg); } }
  @keyframes ruforum-fade-in { from { opacity: 0; } to { opacity: 1; } }
  .hx-loading { position: relative; }
  .hx-loading::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 20;
    border-radius: inherit;
    background-color: rgb(245 239 228 / 0.62);
    animation: ruforum-fade-in 0.15s ease both;
  }
  .hx-loading::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 21;
    height: 1.75rem;
    width: 1.75rem;
    margin: -0.875rem 0 0 -0.875rem;
    border-radius: 9999px;
    border: 3px solid rgb(107 83 23 / 0.22);
    border-top-color: rgb(107 83 23);
    animation: ruforum-spin 0.7s linear infinite;
  }
  @media (prefers-reduced-motion: reduce) {
    .hx-loading::after { animation-duration: 1.5s; }
  }

  /* ── Full-screen navigation overlay (driven by htmx_progress.js) ─
     Shown on full-page navigation (link click / form submit) once NAV_DELAY
     elapses, until the next document paints. Scrim + centered brand spinner.
  */
  #nav-overlay {
    position: fixed;
    inset: 0;
    z-index: 70;
    background-color: rgb(245 239 228 / 0.62);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }
  #nav-overlay.is-active {
    opacity: 1;
    animation: ruforum-fade-in 0.2s ease both;
  }
  #nav-overlay::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    height: 2.25rem;
    width: 2.25rem;
    margin: -1.125rem 0 0 -1.125rem;
    border-radius: 9999px;
    border: 3px solid rgb(107 83 23 / 0.22);
    border-top-color: rgb(107 83 23);
    animation: ruforum-spin 0.7s linear infinite;
  }
  @media (prefers-reduced-motion: reduce) {
    #nav-overlay::after { animation-duration: 1.5s; }
  }

  /* ── Button "Saving…" spinner (form submit / download) ──────────
     `.btn-loading` hides the label and centers a spinner ring. The ring is
     brand-olive by default, switched to white on dark-fill buttons.
  */
  .btn-loading {
    position: relative !important;
    color: transparent !important;
    pointer-events: none;
  }
  .btn-loading::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    height: 1.05em;
    width: 1.05em;
    margin: -0.525em 0 0 -0.525em;
    border-radius: 9999px;
    border: 2px solid rgb(107 83 23 / 0.3);
    border-top-color: rgb(107 83 23);
    animation: ruforum-spin 0.6s linear infinite;
  }
  .btn-primary.btn-loading::after,
  .btn-danger.btn-loading::after {
    border-color: rgb(255 255 255 / 0.4);
    border-top-color: #fff;
  }
  @media (prefers-reduced-motion: reduce) {
    .btn-loading::after { animation-duration: 1.4s; }
  }

  /* ── Chart skeleton (driven by dashboard_charts.js) ─────────────
     A `[data-chart-host]` shows a shimmer placeholder until the chart renders
     and JS adds `.chart-ready`, covering the Chart.js CDN-load + draw gap.
  */
  [data-chart-host] { position: relative; }
  [data-chart-host] .chart-skeleton {
    position: absolute;
    inset: 0;
    z-index: 5;
    border-radius: inherit;
  }
  [data-chart-host].chart-ready .chart-skeleton { display: none; }

  /* ── Command palette (⌘K) ───────────────────────────────────────
     Mounted globally in base.html.
  */
  .cmdk-overlay {
    @apply fixed inset-0 z-[100] flex items-start justify-center px-4 pt-[8vh];
    background: rgba(28, 22, 16, 0.55);
    backdrop-filter: blur(2px);
  }
  .cmdk-panel {
    @apply w-full max-w-xl overflow-hidden rounded-2xl border border-ruforum-border bg-white shadow-dropdown;
  }
  .cmdk-search {
    @apply flex items-center gap-3 border-b border-ruforum-border px-4 py-3;
  }
  .cmdk-search input[type="text"],
  .cmdk-search input[type="search"] {
    @apply !border-0 !bg-transparent !p-0 !shadow-none !ring-0 focus:!ring-0 focus:!border-0 text-base text-ruforum-text;
  }
  .cmdk-results {
    @apply max-h-80 overflow-y-auto py-2;
  }
  .cmdk-group-label {
    @apply px-4 pt-3 pb-1 font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .cmdk-result {
    @apply flex w-full items-center gap-3 px-4 py-2 text-left text-sm text-ruforum-text transition-colors;
  }
  .cmdk-result[aria-selected="true"] {
    @apply bg-ruforum-primary/10 text-ruforum-primary;
  }
  .cmdk-result__kind {
    @apply ml-auto font-meta text-[10px] uppercase tracking-wide text-ruforum-text-muted;
  }
  .cmdk-footer {
    @apply flex items-center justify-between border-t border-ruforum-border bg-ruforum-surface-warm px-4 py-2 font-meta text-[10px] uppercase tracking-wide text-ruforum-text-muted;
  }
  .cmdk-empty {
    @apply px-4 py-6 text-center text-sm text-ruforum-text-muted;
  }

  /* ── Shortcut help modal ────────────────────────────────────────
     Opens on "?". Lists registered shortcuts.
  */
  .shk-overlay {
    @apply fixed inset-0 z-[99] flex items-center justify-center px-4;
    background: rgba(28, 22, 16, 0.55);
  }
  .shk-panel {
    @apply w-full max-w-md overflow-hidden rounded-2xl border border-ruforum-border bg-white shadow-dropdown;
  }
  .shk-row {
    @apply flex items-center justify-between gap-4 px-5 py-2.5;
  }
  .shk-row + .shk-row { @apply border-t border-ruforum-border/60; }
  .shk-desc { @apply text-sm text-ruforum-text; }
  .shk-keys { @apply flex shrink-0 items-center gap-1; }

  /* ── Skip-to-main link (WCAG) ───────────────────────────────────
     Hidden off-screen until focused.
  */
  .skip-link {
    @apply sr-only;
  }
  .skip-link:focus {
    position: fixed;
    top: 0.5rem;
    left: 0.5rem;
    width: auto;
    height: auto;
    padding: 0.5rem 0.875rem;
    clip: auto;
    white-space: nowrap;
    z-index: 200;
    @apply not-sr-only rounded-md bg-ruforum-primary text-white font-meta text-xs font-semibold uppercase tracking-wide shadow-lg;
  }

  /* ══════════════════════════════════════════════════════════════
     Wave 2 — learner surface components
  ══════════════════════════════════════════════════════════════ */

  /* ── Learner weekly plan (my_courses) ──────────────────────────
     A "today / up next / due" header above the course list.
     Replaces flat enrolment list as primary UX.
  */
  .plan-grid {
    @apply grid gap-5 lg:grid-cols-[minmax(0,1fr)_18rem];
  }
  .plan-rail {
    @apply space-y-5;
  }
  .plan-card {
    @apply rounded-xl border border-ruforum-border bg-white;
  }
  .plan-card__head {
    @apply flex items-baseline justify-between gap-4 border-b border-ruforum-border px-5 py-3;
  }
  .plan-card__title {
    @apply font-display text-base font-semibold text-ruforum-text;
  }
  .plan-card__aside {
    @apply font-meta text-[11px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .plan-card__body {
    @apply divide-y divide-ruforum-border/60;
  }
  .plan-item {
    @apply flex items-center gap-3 px-5 py-3 transition-colors hover:bg-ruforum-warm-hover;
  }
  .plan-item__kind {
    @apply flex h-8 w-8 shrink-0 flex-col items-center justify-center gap-0.5 rounded-lg font-meta text-[10px] font-bold uppercase tracking-wide leading-none;
  }
  .plan-item__kind--lesson   { @apply bg-ruforum-primary/10 text-ruforum-primary; }
  .plan-item__kind--quiz     { @apply bg-amber-100 text-amber-800; }
  .plan-item__kind--assign   { @apply bg-emerald-100 text-emerald-800; }
  .plan-item__kind--forum    { @apply bg-stone-100 text-stone-700; }
  .plan-item__kind--live     { @apply bg-red-100 text-red-800; }
  .plan-item__kind--scorm    { @apply bg-violet-100 text-violet-800; }
  .plan-item__kind-mono      { @apply text-[8px] leading-none tracking-[0.04em]; }
  .plan-item__title {
    @apply min-w-0 flex-1 truncate font-body text-sm font-medium text-ruforum-text;
  }
  .plan-item__meta {
    @apply shrink-0 font-meta text-[11px] text-ruforum-text-muted tabular-nums;
  }
  .plan-item__due--soon { @apply text-amber-800; }
  .plan-item__due--over { @apply text-red-700 font-semibold; }

  /* Continue-where-left-off hero row */
  .continue-bar {
    @apply flex items-center gap-4 rounded-xl border border-ruforum-border-strong bg-ruforum-surface-warm p-4;
  }
  .continue-bar__thumb {
    @apply h-14 w-14 shrink-0 rounded-lg overflow-hidden;
    background: linear-gradient(150deg, #f2ead8 0%, #e4d5b0 100%);
  }
  .continue-bar__body { @apply min-w-0 flex-1; }
  .continue-bar__eyebrow {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .continue-bar__title {
    @apply mt-0.5 truncate font-display text-base font-semibold text-ruforum-text;
  }
  .continue-bar__progress {
    @apply mt-1.5 flex items-center gap-2;
  }
  .continue-bar__bar {
    @apply h-1 flex-1 overflow-hidden rounded-full bg-ruforum-border;
  }
  .continue-bar__fill {
    @apply h-full rounded-full bg-ruforum-primary transition-all duration-500;
  }
  .continue-bar__pct {
    @apply font-meta text-[10px] font-semibold text-ruforum-primary tabular-nums;
  }

  /* Streak pip (seven dots, last N days active) */
  .streak {
    @apply inline-flex items-center gap-1.5 rounded-full border border-ruforum-border bg-white px-2.5 py-1;
  }
  .streak__label {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .streak__pips { @apply flex items-center gap-0.5; }
  .streak__pip { @apply h-1.5 w-1.5 rounded-full bg-ruforum-border; }
  .streak__pip--on { @apply bg-ruforum-primary; }

  /* Course strip (compact course row in my_courses under plan) */
  .course-strip {
    @apply flex items-stretch overflow-hidden rounded-xl border border-ruforum-border bg-white transition-shadow hover:shadow-card;
  }
  .course-strip__thumb {
    @apply h-auto w-16 shrink-0 sm:w-24;
    background: linear-gradient(150deg, #f2ead8 0%, #e4d5b0 100%);
  }
  .course-strip__thumb img { @apply h-full w-full object-cover; }
  .course-strip__body {
    @apply flex min-w-0 flex-1 flex-wrap items-center justify-between gap-3 px-4 py-3;
  }
  .course-strip__title {
    @apply truncate font-display text-sm font-semibold text-ruforum-text;
  }
  .course-strip__meta {
    @apply mt-0.5 font-meta text-[11px] text-ruforum-text-muted;
  }

  /* Course-thumb fallback — used when a course has no uploaded image.
     Two variants: full (catalogue tile, supplies its own warm-tone bg)
     and inline (continue-bar / course-strip thumb, inherits the parent
     thumb container's bg). */
  .course-thumb-fallback {
    @apply flex h-full w-full flex-col items-center justify-center gap-2 select-none;
    background: oklch(0.92 0.045 80);
  }
  .course-thumb-fallback__mono {
    @apply font-display text-5xl font-bold leading-none tracking-tight;
    color: color-mix(in oklch, #6b5317 28%, transparent);
  }
  .course-thumb-fallback__category {
    @apply font-meta text-[9px] uppercase tracking-[0.2em];
    color: color-mix(in oklch, #6b5317 40%, transparent);
  }
  .course-thumb-fallback--inline {
    @apply flex h-full w-full items-center justify-center font-display text-lg font-bold;
    background: transparent;
    color: color-mix(in oklch, #6b5317 30%, transparent);
  }

  /* ── Course prospectus (course_detail) ──────────────────────────
     Replaces 3x2 tile grid. Editorial syllabus.
  */
  .prospectus {
    @apply grid gap-10 lg:grid-cols-[minmax(0,1fr)_20rem];
  }
  .prospectus-outcomes {
    @apply grid gap-3 sm:grid-cols-2;
  }
  .prospectus-outcome {
    @apply flex items-start gap-3 rounded-lg border border-ruforum-border bg-white px-4 py-3;
  }
  .prospectus-outcome__num {
    @apply flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-ruforum-primary/10 font-meta text-[11px] font-bold text-ruforum-primary tabular-nums;
  }
  .prospectus-outcome__text {
    @apply font-body text-sm leading-snug text-ruforum-text;
  }

  /* Syllabus weeks — vertical arc */
  .syllabus {
    @apply relative pl-10;
  }
  .syllabus::before {
    content: "";
    @apply absolute left-[11px] top-2 bottom-2 w-px bg-ruforum-border;
  }
  .syllabus-week {
    @apply relative pb-7 last:pb-0;
  }
  .syllabus-week::before {
    content: counter(week);
    counter-increment: week;
    @apply absolute -left-10 top-0 flex h-6 w-6 items-center justify-center rounded-full border border-ruforum-border-strong bg-white font-meta text-[10px] font-bold tabular-nums text-ruforum-text-muted;
  }
  .syllabus-week--done::before {
    @apply border-ruforum-primary bg-ruforum-primary text-white;
    content: "✓";
    counter-increment: week;
  }
  .syllabus-week__title {
    @apply font-display text-base font-semibold text-ruforum-text;
  }
  .syllabus-week__meta {
    @apply mt-0.5 font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .syllabus-week__items {
    @apply mt-2 space-y-1;
  }
  .syllabus-week__item {
    @apply flex items-center gap-2 text-sm text-ruforum-text-muted;
  }
  .syllabus-week__item--done {
    @apply text-ruforum-text;
  }
  /* Nested subsection (Moodle 4.5 `subsection` → Module.parent) */
  .syllabus-week__sub {
    @apply mt-3 border-l border-ruforum-border pl-4;
  }
  .syllabus-week__sub-title {
    @apply flex flex-wrap items-center gap-x-2 gap-y-0.5 font-display text-sm font-semibold text-ruforum-text;
  }
  .syllabus-week__sub-eyebrow {
    @apply font-meta text-[10px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .syllabus-week__sub-empty {
    @apply mt-1 font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }

  /* Effort / hours-per-week meter */
  .effort-meter {
    @apply flex items-baseline gap-2;
  }
  .effort-meter__num {
    @apply font-display text-2xl font-semibold text-ruforum-text tabular-nums;
  }
  .effort-meter__unit {
    @apply font-meta text-[11px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }

  /* Enrol rail (replaces enrol card chrome) */
  .enrol-rail {
    @apply sticky top-20 space-y-4;
  }
  .enrol-rail__panel {
    @apply overflow-hidden rounded-xl border border-ruforum-border bg-white;
  }

  /* ── Immersive lesson reader (lesson_view) ──────────────────────
     Replaces boxed lesson card with editorial reading surface.

     Layout contract: when the page contains a `.reader`, the document
     itself does NOT scroll. The topbar + breadcrumb stay pinned (both
     are sticky in dashboard.html), and `.reader-main` is the single
     internal scroll container. The rail sits in a fixed-height column
     and scrolls independently when its lesson list overflows.
  */
  html.dashboard-shell:has(.reader),
  html.dashboard-shell:has(.reader) body {
    height: 100vh !important;
    min-height: 100vh !important;
    overflow: hidden !important;
  }
  /* Reader height = viewport minus sticky topbar (3.5rem) + sticky
     breadcrumb (2.25rem) + global footer (~3.25rem: py-5 + xs text +
     border). Hardcoded because the footer is plain block flow; if the
     footer markup grows, bump this value. */
  .reader {
    display: grid;
    grid-template-columns: 16rem minmax(0, 1fr);
    height: calc(100vh - 3.5rem - 2.25rem - 3.25rem);
  }
  @media (max-width: 1023px) {
    .reader { grid-template-columns: 1fr; }
  }
  /* Zen / focus mode collapses the rail track so the reading column
     can grow to the full viewport width instead of squashing into the
     first 16rem track. */
  .reader--zen {
    grid-template-columns: minmax(0, 1fr);
  }
  .reader-rail {
    @apply hidden lg:flex flex-col border-r border-ruforum-border bg-white;
    height: 100%;
    overflow-y: auto;
  }
  .reader-rail__head {
    @apply px-4 py-3 border-b border-ruforum-border;
  }
  .reader-rail__search {
    @apply block w-full !rounded-lg !border-ruforum-border !py-1.5 !text-xs !text-ruforum-text placeholder:!text-ruforum-text-muted/60;
  }
  .reader-rail__body {
    @apply flex-1 overflow-y-auto px-2 py-3;
  }
  .reader-rail__group {
    @apply mb-4;
  }
  .reader-rail__group-label {
    @apply px-2 pb-1 font-meta text-[10px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .lesson-dot {
    @apply flex h-5 w-5 shrink-0 items-center justify-center rounded-full font-meta text-[10px] font-bold tabular-nums;
  }
  .lesson-dot--done {
    background-color: #059669;
    color: #fff;
  }
  .lesson-dot--current {
    @apply bg-ruforum-primary text-white;
    box-shadow: 0 0 0 3px rgba(107,83,23,0.20);
  }
  .lesson-dot--future {
    @apply border border-ruforum-border-strong bg-white text-ruforum-text-muted;
  }
  .reader-row {
    @apply flex items-center gap-2.5 rounded-lg px-2 py-1.5 text-sm transition-colors;
  }
  .reader-row--lesson {
    @apply text-ruforum-text-muted hover:bg-ruforum-warm-hover hover:text-ruforum-text;
  }
  .reader-row--current {
    @apply bg-ruforum-primary/10 font-semibold text-ruforum-primary;
  }
  .reader-row__title {
    @apply min-w-0 flex-1 truncate leading-snug;
  }
  .reader-row__mins {
    @apply shrink-0 font-meta text-[10px] text-ruforum-text-muted tabular-nums;
  }
  /* Main reading area — the single internal scroll container. */
  .reader-main {
    @apply min-w-0 bg-ruforum-surface-warm;
    height: 100%;
    overflow-y: auto;
  }
  .reader-top {
    @apply sticky top-0 z-10 flex items-center justify-between gap-4 border-b border-ruforum-border bg-white/85 px-6 py-3 backdrop-blur;
  }
  .reader-top__progress {
    @apply flex items-center gap-3 min-w-0;
  }
  .reader-top__bar {
    @apply h-1 w-24 overflow-hidden rounded-full bg-ruforum-border;
  }
  .reader-top__fill {
    @apply h-full rounded-full bg-ruforum-primary transition-all duration-500;
  }
  .reader-top__actions { @apply flex items-center gap-2; }
  .reader-body {
    @apply mx-auto px-6 py-10 sm:px-10;
    max-width: 46rem; /* ~72ch at 16px */
  }
  /* Video lessons need room for the player; prose still wraps reasonably
     because the supporting copy uses `prose-sm` line-length defaults. */
  .reader-body--video {
    max-width: 64rem;
  }
  .reader-body--zen {
    max-width: 40rem;
  }
  .reader-eyebrow {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .reader-title {
    @apply mt-2 font-display text-3xl font-semibold leading-[1.15] text-ruforum-text sm:text-4xl;
    max-width: 22ch;
  }
  .reader-meta {
    @apply mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .reader-meta > * + *::before {
    content: "·";
    @apply mr-3 text-ruforum-text-muted/50;
  }
  .reader-prose {
    @apply prose prose-sm mt-8 max-w-none
      text-ruforum-text
      [&_h2]:font-display [&_h2]:mt-10 [&_h2]:mb-3 [&_h2]:text-xl [&_h2]:text-ruforum-text
      [&_h3]:font-display [&_h3]:mt-6 [&_h3]:mb-2 [&_h3]:text-lg [&_h3]:text-ruforum-text
      [&_p]:leading-relaxed
      [&_a]:text-ruforum-primary [&_a:hover]:text-ruforum-primary-hover
      [&_blockquote]:border-ruforum-border [&_blockquote]:text-ruforum-text-muted
      [&_ul]:my-3 [&_ol]:my-3;
  }
  .reader-video {
    @apply mt-6 overflow-hidden rounded-xl border border-ruforum-border bg-black;
  }
  .reader-pdf {
    @apply mt-6 overflow-hidden rounded-xl border border-ruforum-border bg-white;
  }
  /* Sticky prev/next footer */
  .reader-nav {
    @apply sticky bottom-0 z-10 flex items-center justify-between gap-3 border-t border-ruforum-border bg-white/90 px-6 py-3 backdrop-blur;
  }
  .reader-nav__side {
    @apply flex min-w-0 items-center gap-3;
  }
  .reader-nav__label {
    @apply font-meta text-[10px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .reader-nav__title {
    @apply truncate font-display text-sm font-semibold text-ruforum-text max-w-[14ch] sm:max-w-[20ch];
  }

  /* ── Quiz palette / focus mode (quiz_attempt) ───────────────────
     Replaces stacked-questions layout.
  */
  .quiz-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 15rem;
    gap: 2rem;
  }
  @media (max-width: 1023px) {
    .quiz-shell { grid-template-columns: 1fr; gap: 1rem; }
  }
  .quiz-main { @apply min-w-0; }
  .qp-rail {
    @apply sticky top-20 space-y-4 self-start;
  }
  .qp-rail__panel {
    @apply rounded-xl border border-ruforum-border bg-white p-4;
  }
  .qp-rail__label {
    @apply mb-2 font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .qp-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.375rem;
  }
  .qp-cell {
    @apply flex aspect-square items-center justify-center rounded-md border border-ruforum-border bg-white font-meta text-xs font-semibold tabular-nums text-ruforum-text-muted transition-colors;
  }
  .qp-cell:hover, .qp-cell:focus-visible {
    @apply border-ruforum-border-strong text-ruforum-text;
    outline: none;
  }
  .qp-cell--current {
    @apply border-ruforum-primary bg-ruforum-primary text-white;
    box-shadow: 0 0 0 3px rgba(107,83,23,0.20);
  }
  .qp-cell--answered {
    @apply border-emerald-300 bg-emerald-50 text-emerald-800;
  }
  .qp-cell--flagged {
    @apply border-amber-400 bg-amber-50 text-amber-900;
  }
  .qp-cell--flagged::after {
    content: "";
    @apply absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-amber-600;
  }
  .qp-cell { position: relative; }
  /* Timer ring */
  .qp-timer {
    @apply flex items-center gap-3 rounded-xl border border-ruforum-border bg-white px-4 py-3;
  }
  .qp-timer__ring {
    @apply relative h-10 w-10 shrink-0;
  }
  .qp-timer__num {
    @apply font-display text-sm font-semibold tabular-nums text-ruforum-text;
  }
  .qp-timer__num--warn { @apply text-amber-700; }
  .qp-timer__num--danger { @apply text-red-700; }
  .qp-legend {
    @apply space-y-1.5;
  }
  .qp-legend__row {
    @apply flex items-center gap-2 font-meta text-[11px] text-ruforum-text-muted;
  }
  .qp-legend__swatch {
    /* Bumped from h-2.5/w-2.5 to fit a colour-blind glyph alongside the fill. */
    @apply inline-flex items-center justify-center h-3.5 w-3.5 rounded-sm text-[9px] leading-none font-bold;
  }
  /* Quiz question card (focus mode) */
  .quiz-q {
    @apply rounded-2xl border border-ruforum-border bg-white;
  }
  .quiz-q__head {
    @apply flex items-center justify-between gap-3 border-b border-ruforum-border px-6 py-4;
  }
  .quiz-q__counter {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted tabular-nums;
  }
  .quiz-q__flag {
    @apply inline-flex items-center gap-1.5 rounded-full border border-ruforum-border bg-white px-2.5 py-1 font-meta text-[11px] font-medium uppercase tracking-[0.10em] text-ruforum-text-muted transition-colors hover:border-amber-400 hover:text-amber-800;
  }
  .quiz-q__flag--on {
    @apply border-amber-400 bg-amber-50 text-amber-800;
  }
  .quiz-q__body {
    @apply px-6 py-6;
  }
  .quiz-q__prompt {
    @apply font-display text-xl font-semibold leading-snug text-ruforum-text;
    max-width: 42rem;
  }
  .quiz-q__options { @apply mt-6 space-y-2; }
  .quiz-q__option {
    @apply flex cursor-pointer items-start gap-3 rounded-lg border border-ruforum-border bg-white px-4 py-3 transition-colors hover:bg-ruforum-warm-hover has-[:checked]:border-ruforum-primary has-[:checked]:bg-ruforum-primary/5;
  }
  .quiz-q__option input { @apply mt-0.5; }
  .quiz-q__option-letter {
    @apply flex h-6 w-6 shrink-0 items-center justify-center rounded-md border border-ruforum-border bg-white font-meta text-[11px] font-bold uppercase text-ruforum-text-muted;
  }
  .quiz-q__option:has(:checked) .quiz-q__option-letter {
    @apply border-ruforum-primary bg-ruforum-primary text-white;
  }
  .quiz-q__foot {
    @apply flex items-center justify-between gap-3 border-t border-ruforum-border bg-ruforum-surface-warm px-6 py-4;
  }
  .quiz-q__nav-hint {
    @apply font-meta text-[11px] text-ruforum-text-muted;
  }
  /* MATCH question (FRREP-AG001) — left prompt + right-hand select per row. */
  .quiz-q__match { @apply mt-6 max-w-2xl space-y-2.5; }
  .quiz-q__match-row {
    @apply flex flex-col gap-2 rounded-lg border border-ruforum-border bg-white px-4 py-3 sm:flex-row sm:items-center sm:gap-4;
  }
  .quiz-q__match-prompt { @apply min-w-0 flex-1 text-sm font-medium text-ruforum-text; }
  .quiz-q__match-select { @apply sm:w-64 sm:shrink-0; }
  /* ORDER question (FRREP-AG001) — shuffled list with up/down reorder controls. */
  .quiz-q__order { @apply mt-6 max-w-2xl; }
  .quiz-q__order-list { @apply space-y-2; }
  .quiz-q__order-item {
    @apply flex items-center gap-3 rounded-lg border border-ruforum-border bg-white px-4 py-3;
  }
  .quiz-q__order-pos {
    @apply flex h-6 w-6 shrink-0 items-center justify-center rounded-md border border-ruforum-border bg-ruforum-surface-warm font-meta text-[11px] font-bold text-ruforum-text-muted;
  }
  .quiz-q__order-text { @apply min-w-0 flex-1 text-sm font-medium text-ruforum-text; }
  .quiz-q__order-controls { @apply flex shrink-0 items-center gap-1; }
  .quiz-q__order-btn {
    @apply flex h-8 w-8 items-center justify-center rounded-md border border-ruforum-border bg-white text-ruforum-text-muted transition-colors hover:border-ruforum-border-strong hover:text-ruforum-text;
  }

  /* ══════════════════════════════════════════════════════════════
     Utilities used across Wave 1/2
  ══════════════════════════════════════════════════════════════ */

  /* Faceted filter group header */
  .filter-group__legend {
    @apply mb-2 flex items-center justify-between font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }

  /* Editorial section header used above card grids */
  .editorial-head {
    @apply mb-4 flex items-baseline justify-between gap-4 border-b border-ruforum-border pb-2;
  }
  .editorial-head__title {
    @apply font-display text-lg font-semibold text-ruforum-text;
  }
  .editorial-head__aside {
    @apply font-meta text-[11px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }

  /* ══════════════════════════════════════════════════════════════════
     RIMS — Tabs, Modals, Wizards (grants workflow IA)
     Used on award_detail, manager_application_detail, call_detail_manage,
     application_create, award_closeout.
  ══════════════════════════════════════════════════════════════════ */

  /* ── Tab nav ────────────────────────────────────────────────────
     Pattern: wrap a tab container in Alpine with `x-data="{ tab: 'overview' }"`.
     Buttons toggle with `:aria-selected`, `@click="tab='…'"`.
     Panels use `x-show="tab==='…'"`.
  */
  .tab-nav {
    @apply flex items-center gap-1 overflow-x-auto border-b border-ruforum-border bg-white px-3 pt-1;
    scrollbar-width: thin;
  }
  .tab-nav--contained {
    @apply rounded-t-xl border-x border-t border-ruforum-border;
  }
  .tab-btn {
    @apply relative inline-flex shrink-0 items-center gap-2 border-b-2 border-transparent px-4 py-3 font-meta text-[11px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted transition-colors duration-150;
    background: transparent;
    cursor: pointer;
  }
  .tab-btn:hover {
    @apply text-ruforum-text;
  }
  .tab-btn:focus-visible {
    outline: none;
    @apply ring-2 ring-ruforum-primary/40 rounded-sm;
  }
  .tab-btn[aria-selected="true"] {
    @apply border-ruforum-primary text-ruforum-primary;
  }
  .tab-btn__count {
    @apply inline-flex items-center justify-center rounded-full bg-ruforum-surface px-1.5 py-0.5 text-[10px] font-bold tabular-nums text-ruforum-text-muted;
  }
  .tab-btn[aria-selected="true"] .tab-btn__count {
    @apply bg-ruforum-primary/10 text-ruforum-primary;
  }
  .tab-btn__dot {
    @apply inline-block h-1.5 w-1.5 rounded-full bg-amber-500;
  }
  .tab-panel {
    @apply pt-6;
  }

  /* ── Modal shell ────────────────────────────────────────────────
     Pattern: parent element has `x-data="{ open: false }"`. Trigger sets
     `open = true`. The overlay element uses `x-show`, `@keydown.escape`,
     `x-trap.inert.noscroll`.
  */
  .modal-overlay {
    @apply fixed inset-0 z-[80] flex items-start justify-center overflow-y-auto px-4 py-[6vh];
    background: rgba(28, 22, 16, 0.52);
    backdrop-filter: blur(3px);
  }
  .modal-panel {
    @apply relative w-full max-w-lg overflow-hidden rounded-xl border border-ruforum-border bg-white shadow-dropdown;
  }
  .modal-panel--wide {
    @apply max-w-2xl;
  }
  .modal-panel--narrow {
    @apply max-w-md;
  }
  .modal-head {
    @apply flex items-start justify-between gap-4 border-b border-ruforum-border px-6 py-4;
  }
  .modal-head__title {
    @apply font-display text-lg font-semibold leading-snug text-ruforum-text;
  }
  .modal-head__eyebrow {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .modal-head__lede {
    @apply mt-1 max-w-[52ch] text-sm text-ruforum-text-muted;
  }
  .modal-close {
    @apply -m-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-ruforum-text-muted transition-colors hover:bg-ruforum-surface hover:text-ruforum-text focus:outline-none focus:ring-2 focus:ring-ruforum-primary/40;
  }
  .modal-body {
    @apply max-h-[60vh] overflow-y-auto px-6 py-5;
  }
  .modal-foot {
    @apply flex items-center justify-end gap-3 border-t border-ruforum-border bg-ruforum-surface-warm px-6 py-4;
  }
  .modal-foot--between {
    @apply justify-between;
  }
  .modal-foot__note {
    @apply font-meta text-[11px] text-ruforum-text-muted;
  }
  /* Confirm-modal variants */
  .modal-panel--danger .modal-head {
    @apply border-red-100 bg-red-50/60;
  }
  .modal-panel--danger .modal-head__title {
    @apply text-red-900;
  }
  .modal-panel--danger .modal-head__eyebrow {
    @apply text-red-700;
  }

  /* ── Wizard / stepped flow ──────────────────────────────────────
     Pattern: parent has `x-data="{ step: 1, max: 4 }"`. Step header renders
     `.wizard-rail` with one `.wizard-step` per step. Body renders
     `<div x-show="step===1">…</div>` sections. Footer renders persistent
     Back / Next / Submit buttons.
  */
  .wizard-rail {
    @apply relative flex items-start gap-0 overflow-x-auto rounded-xl border border-ruforum-border bg-white px-4 py-5 sm:px-6;
    counter-reset: wizard;
  }
  .wizard-step {
    @apply relative flex min-w-0 flex-1 items-start gap-3;
    counter-increment: wizard;
  }
  .wizard-step__marker {
    @apply relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-ruforum-border bg-white font-meta text-xs font-bold tabular-nums text-ruforum-text-muted transition-colors;
  }
  .wizard-step__marker::before {
    content: counter(wizard);
  }
  .wizard-step--done .wizard-step__marker {
    @apply border-ruforum-primary bg-ruforum-primary text-white;
  }
  .wizard-step--done .wizard-step__marker::before {
    content: "✓";
  }
  .wizard-step--active .wizard-step__marker {
    @apply border-ruforum-primary bg-ruforum-primary text-white;
    box-shadow: 0 0 0 4px rgba(107, 83, 23, 0.14);
  }
  .wizard-step__body {
    @apply min-w-0 pt-1;
  }
  .wizard-step__label {
    @apply block font-meta text-[10px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .wizard-step--active .wizard-step__label,
  .wizard-step--done .wizard-step__label {
    @apply text-ruforum-primary;
  }
  .wizard-step__title {
    @apply mt-0.5 block truncate font-body text-sm font-semibold text-ruforum-text;
  }
  .wizard-step__connector {
    @apply mx-3 mt-4 h-px flex-1 bg-ruforum-border;
  }
  .wizard-step--done ~ .wizard-step--done .wizard-step__connector,
  .wizard-step--done + .wizard-step--active .wizard-step__connector {
    @apply bg-ruforum-primary;
  }
  .wizard-step:last-child .wizard-step__connector {
    display: none;
  }
  .wizard-panel {
    @apply mt-5 overflow-hidden rounded-xl border border-ruforum-border bg-white;
  }
  .wizard-panel__body {
    @apply px-6 py-6 sm:px-8 sm:py-7;
  }
  .wizard-panel__foot {
    @apply flex flex-wrap items-center justify-between gap-3 border-t border-ruforum-border bg-ruforum-surface-warm px-6 py-4;
  }
  .wizard-panel__progress {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted tabular-nums;
  }

  /* ── Sticky decision rail (right-side action panel) ─────────────
     Used on manager_application_detail and award_detail summary panes.
  */
  .decision-rail {
    @apply space-y-4 lg:sticky lg:top-20 lg:self-start;
  }
  .decision-rail__panel {
    @apply overflow-hidden rounded-xl border border-ruforum-border bg-white;
  }
  .decision-rail__head {
    @apply border-b border-ruforum-border bg-ruforum-surface-warm px-5 py-3;
  }
  .decision-rail__title {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .decision-rail__body {
    @apply space-y-3 px-5 py-4;
  }
  /* §7 — feature panel variant lifts one rail block above the rest, used
     for the rubric on the reviewer surface so it reads as the primary
     reference for the page rather than peer to the metadata panels. */
  .decision-rail__panel--feature {
    @apply border-ruforum-primary/30 bg-ruforum-surface-warm;
  }
  .decision-rail__panel--feature .decision-rail__head {
    @apply bg-white border-ruforum-primary/20;
  }
  .decision-rail__panel--feature .decision-rail__title {
    @apply text-ruforum-primary;
  }

  /* §7 — Rubric criteria list (used inside the reviewer rail). */
  .rubric-list {
    @apply m-0 list-none divide-y divide-ruforum-border/60 p-0;
  }
  .rubric-list__row {
    @apply flex items-baseline justify-between gap-3 py-2 text-sm;
  }
  .rubric-list__label {
    @apply text-ruforum-text;
  }
  .rubric-list__pts {
    @apply text-xs font-semibold text-ruforum-text-muted;
  }
  .rubric-list__foot {
    @apply mt-3 border-t border-ruforum-border/60 pt-2 text-[11px] leading-relaxed text-ruforum-text-muted;
  }

  /* ── Empty-state card (used inside tab panels) ───────────────── */
  .empty-panel {
    @apply rounded-xl border border-dashed border-ruforum-border bg-ruforum-surface-warm px-6 py-10 text-center;
  }
  .empty-panel__title {
    @apply font-display text-base font-semibold text-ruforum-text;
  }
  .empty-panel__lede {
    @apply mx-auto mt-2 max-w-[52ch] text-sm text-ruforum-text-muted;
  }
  .empty-panel__action {
    @apply mt-5 inline-flex;
  }

  /* ── Hero stat strip (replaces the hex-heavy award_detail hero) ─ */
  .hero-strip {
    @apply grid gap-4 rounded-xl border border-ruforum-border bg-ruforum-surface-warm p-5 lg:grid-cols-[1.7fr_1fr];
  }
  .hero-strip__lead {
    @apply min-w-0;
  }
  .hero-strip__eyebrow {
    @apply font-meta text-[10px] font-semibold uppercase tracking-[0.18em] text-ruforum-primary/80;
  }
  .hero-strip__title {
    @apply mt-2 font-display text-xl font-semibold leading-snug text-ruforum-text sm:text-2xl;
    max-width: 48ch;
  }
  .hero-strip__lede {
    @apply mt-2 max-w-[68ch] text-sm leading-relaxed text-ruforum-text-muted;
  }
  .hero-strip__side {
    @apply rounded-lg border border-ruforum-border bg-white p-4;
  }

  /* ── Logo strip (list-card headers for institutions / partners / scholars) ──
     Warm cream gradient with subtle bottom border — replaces inline style attrs.
  */
  .logo-strip {
    @apply flex h-24 items-center justify-center px-6;
    background: linear-gradient(150deg, oklch(0.95 0.02 80) 0%, oklch(0.88 0.04 80) 100%);
    border-bottom: 1px solid rgb(196 180 154 / 0.25);
  }
  .logo-strip__placeholder {
    @apply flex select-none flex-col items-center gap-1;
  }
  .logo-strip__placeholder-initials {
    @apply font-display text-3xl font-bold leading-none tracking-tight text-ruforum-primary/40;
  }
  .logo-strip__placeholder-kind {
    @apply font-meta text-[9px] uppercase tracking-[0.18em] text-ruforum-primary/40;
  }

  /* ── Logo list card — reusable outer element for partner / institution / scholar grids ──
     NOTE: add `group` directly in the template (Tailwind forbids @apply group),
     e.g. <a class="logo-card group">…</a> so child :group-hover rules fire.
  */
  .logo-card {
    @apply flex flex-col overflow-hidden rounded-xl border border-ruforum-border bg-white transition-all duration-150 hover:border-ruforum-primary/30 hover:shadow-card-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-ruforum-primary;
  }
  .logo-card__body {
    @apply flex flex-1 flex-col gap-2 p-4;
  }
  .logo-card__title {
    @apply font-display text-[15px] font-semibold leading-snug text-ruforum-text transition-colors group-hover:text-ruforum-primary;
  }
  .logo-card__meta {
    @apply mt-auto font-meta text-[11px] text-ruforum-text-muted;
  }

  /* ── Quill editor overrides (shared across every rich-text form)
     Scroll fix: quill.snow.css sets .ql-editor { height:100%; overflow-y:auto }
     which traps wheel/trackpad on long manager forms. The !important here is
     required to beat the vendor stylesheet. Height can be overridden per
     instance with a local rule or inline style if a shorter editor is wanted.
  */
  .ql-container {
    font-family: inherit;
    font-size: 0.875rem;
    @apply rounded-b-lg;
  }
  .ql-toolbar.ql-snow {
    @apply rounded-t-lg border-ruforum-border bg-ruforum-surface;
  }
  .ql-container.ql-snow {
    height: auto !important;
    @apply border-ruforum-border;
  }
  .ql-snow .ql-editor {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    min-height: 140px;
    @apply text-ruforum-text;
  }
  .ql-editor.ql-blank::before {
    @apply text-ruforum-text-muted/70;
    font-style: normal;
  }
  /* Size modifiers — add to the wrapping <div id="..."> */
  .quill--sm .ql-snow .ql-editor { min-height: 100px; }
  .quill--md .ql-snow .ql-editor { min-height: 140px; }
  .quill--lg .ql-snow .ql-editor { min-height: 200px; }
  .quill--xl .ql-snow .ql-editor { min-height: 260px; }

  /* ── Search field with embedded magnifier icon ──────────────────
     Usage:
       <label class="search-field search-field--md">
         <svg class="search-field__icon" ...>…</svg>
         <input type="search" name="q" placeholder="Search…" class="search-field__input">
       </label>
     Variants: --sm (compact toolbar), --md (default), --lg (page-hero).
  */
  .search-field {
    @apply relative inline-flex items-center;
  }
  .search-field__icon {
    @apply pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-ruforum-text-muted/70;
  }
  /* Input inside .search-field — needs higher specificity to beat the
     base input[type="search"] tag selector. */
  .search-field input[type="search"].search-field__input,
  .search-field input[type="search"] {
    @apply h-10 rounded-lg border border-ruforum-border bg-white text-sm text-ruforum-text shadow-sm transition-colors;
    padding-left: 2.25rem;
    padding-right: 0.875rem;
  }
  .search-field input[type="search"]:focus {
    @apply border-ruforum-primary ring-2 ring-ruforum-primary/[0.18] outline-none;
  }
  .search-field--sm input[type="search"] { @apply h-9 text-sm; }
  .search-field--md input[type="search"] { @apply h-10 text-sm; }
  .search-field--lg input[type="search"] { @apply h-11 text-[0.9375rem]; }
  .search-field--full { @apply flex w-full; }
  .search-field--full input[type="search"] { @apply w-full; }
  /* Clearing browser-default cross/x icon so it blends */
  .search-field input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    height: 0.875rem;
    width: 0.875rem;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 18L18 6M6 6l12 12' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' stroke='black' fill='none'/></svg>") no-repeat center / contain;
    color: rgb(114 103 92 / 0.7);
    cursor: pointer;
  }
  .search-field input[type="search"]::-webkit-search-cancel-button:hover {
    color: rgb(28 22 16);
  }

  /* ── Form-field wrapper ─────────────────────────────────────────
     Pair with {% include "components/form_field.html" %}.
     .field groups label + widget + help + error into one rhythm.
  */
  .field {
    @apply block;
  }
  .field + .field {
    @apply mt-5;
  }
  /* Adjacent-sibling spacing is intended for vertically stacked fields.
     Inside a grid or flex row, each `.field` is its own column — the extra
     top margin would misalign the widgets with the first column. */
  .grid > .field + .field,
  .flex > .field + .field {
    margin-top: 0;
  }
  .field-label-row {
    @apply mb-1.5 flex items-baseline justify-between gap-3;
  }
  .field-required {
    @apply ml-0.5 align-baseline text-red-600;
  }
  .field-optional {
    @apply font-meta text-[10px] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }

  /* Checkbox / switch field with right-hand label & hint */
  .check-field {
    @apply flex items-start gap-3;
  }
  .check-field input[type="checkbox"],
  .check-field input[type="radio"] {
    @apply mt-0.5;
  }
  .check-field__body {
    @apply min-w-0 flex-1;
  }
  .check-field__label {
    @apply block cursor-pointer text-sm font-medium text-ruforum-text;
  }
  .check-field__hint {
    @apply mt-0.5 text-xs leading-relaxed text-ruforum-text-muted;
  }

  /* ══════════════════════════════════════════════════════════════════
     EDITORIAL · REP design system v2 (Spectral numerals, italic ledes,
     brand-edge cards, KPI tiles, status pills, refined chips, canvas
     forms, blueprint empty states). Used across the rep/ surface to
     give every page the same visual language.
     ═══════════════════════════════════════════════════════════════════ */

  /* — Type primitives — */
  .ed-eyebrow {
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.20em;
    color: #6b5317; font-weight: 600;
  }
  .ed-eyebrow--muted { color: #7a6f5e; }
  .ed-eyebrow--on-dark { color: rgba(255, 255, 255, 0.85); letter-spacing: 0.16em; }
  .ed-title {
    font-family: 'Spectral', Georgia, serif;
    font-weight: 600; line-height: 1.02; letter-spacing: -0.015em;
    color: #1c1610;
  }
  .ed-italic {
    font-family: 'Spectral', Georgia, serif;
    font-style: italic; color: rgba(28, 22, 16, 0.72);
    line-height: 1.45;
  }
  .ed-section-label {
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.18em;
    color: #6b5317; font-weight: 600;
    display: flex; align-items: center; gap: 0.625rem;
  }
  .ed-section-label::after {
    content: ""; flex: 1; height: 1px; background: #e7dec8;
  }
  .ed-section-label--double::before {
    content: ""; flex: 1; height: 1px; background: #e7dec8;
  }

  .ed-numeral {
    font-family: 'Spectral', Georgia, serif;
    font-weight: 600; line-height: 0.85;
    letter-spacing: -0.025em;
    font-feature-settings: "lnum"; font-variant-numeric: tabular-nums;
    color: #1c1610;
  }
  .ed-numeral--muted { color: #d6c69d; }
  .ed-numeral--accent { color: #6b5317; }
  .ed-numeral--good { color: #047857; }

  /* — Status & meta pills — */
  .status-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 12px;
    border-radius: 999px;
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.6875rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.10em;
    background: rgba(122, 111, 94, 0.12); color: #4a3f2e;
  }
  .status-pill__dot { width: 6px; height: 6px; border-radius: 999px; background: #7a6f5e; }
  .status-pill--good { background: rgba(4, 120, 87, 0.10); color: #047857; }
  .status-pill--good .status-pill__dot { background: #047857; }
  .status-pill--warn { background: rgba(180, 83, 9, 0.10); color: #b45309; }
  .status-pill--warn .status-pill__dot { background: #d97706; }
  .status-pill--bad  { background: rgba(185, 28, 28, 0.10); color: #b91c1c; }
  .status-pill--bad  .status-pill__dot { background: #b91c1c; }
  .status-pill--accent { background: rgba(107, 83, 23, 0.10); color: #6b5317; }
  .status-pill--accent .status-pill__dot { background: #6b5317; }

  /* Appeal lifecycle — assessments/appeal_queue.html row pills */
  .status-pill--appeal-open       { background: rgba(180, 83, 9, 0.10);  color: #b45309; }
  .status-pill--appeal-open       .status-pill__dot { background: #d97706; }
  .status-pill--appeal-reviewing  { background: rgba(180, 83, 9, 0.16);  color: #92400e; }
  .status-pill--appeal-reviewing  .status-pill__dot { background: #b45309; }
  .status-pill--appeal-changed    { background: rgba(4, 120, 87, 0.10);  color: #047857; }
  .status-pill--appeal-changed    .status-pill__dot { background: #047857; }
  .status-pill--appeal-upheld     { background: rgba(122, 111, 94, 0.12); color: #4a3f2e; }
  .status-pill--appeal-upheld     .status-pill__dot { background: #7a6f5e; }
  .status-pill--appeal-rejected   { background: rgba(185, 28, 28, 0.10); color: #b91c1c; }
  .status-pill--appeal-rejected   .status-pill__dot { background: #b91c1c; }

  /* Connection state — networking discovery/home cards */
  .status-pill--connected { background: rgba(4, 120, 87, 0.10);  color: #047857; }
  .status-pill--connected .status-pill__dot { background: #047857; }
  .status-pill--pending   { background: rgba(180, 83, 9, 0.10);  color: #b45309; }
  .status-pill--pending   .status-pill__dot { background: #d97706; }

  /* Live session — live/list.html "Live now" indicator (pulse on .live-now-pulse) */
  .status-pill--live { background: rgba(4, 120, 87, 0.12); color: #047857; }
  .status-pill--live .status-pill__dot { background: oklch(0.62 0.16 145); }

  .meta-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    border: 1px solid #e7dec8;
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.6875rem; font-weight: 500;
    text-transform: uppercase; letter-spacing: 0.10em;
    color: #4a3f2e; background: #ffffff;
  }
  .meta-pill--quiz   { color: #b45309; border-color: #fed7aa; }
  .meta-pill--accent { color: #6b5317; border-color: #d8c9a8; background: rgba(255, 250, 242, 0.8); }
  .meta-pill--dashed { border-style: dashed; }

  .slug-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    color: #7a6f5e;
    background: rgba(231, 222, 200, 0.45);
    padding: 2px 8px;
    border-radius: 6px;
  }

  /* — KPI band — */
  .kpi-band {
    border: 1px solid #e7dec8;
    border-radius: 18px;
    background: #ffffff;
    overflow: hidden;
    position: relative;
  }
  .kpi-band::before {
    content: ""; position: absolute; left: 0; right: 0; top: 0;
    height: 3px; background: #6b5317;
  }
  .kpi-tile { padding: 24px 22px; position: relative; }
  .kpi-tile + .kpi-tile { border-left: 1px solid #f1ead6; }
  @media (max-width: 640px) {
    .kpi-tile + .kpi-tile { border-left: 0; border-top: 1px solid #f1ead6; }
  }
  .kpi-tile__label {
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.6875rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.16em;
    color: #7a6f5e;
  }
  .kpi-tile__num {
    margin-top: 10px;
    font-family: 'Spectral', Georgia, serif;
    font-size: clamp(2.25rem, 3.4vw, 3rem);
    font-weight: 600; line-height: 0.9;
    letter-spacing: -0.02em;
    color: #1c1610;
    font-variant-numeric: tabular-nums;
  }
  .kpi-tile__num--accent { color: #6b5317; }
  .kpi-tile__num--good   { color: #047857; }
  .kpi-tile__num--muted  { color: #b09766; }
  .kpi-tile__num__suffix { font-size: 0.55em; color: #b09766; font-weight: 500; margin-left: 2px; }
  .kpi-tile__hint {
    margin-top: 8px;
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.75rem; color: #7a6f5e;
    font-variant-numeric: tabular-nums;
  }

  /* — Brand-edge card (used for module/list rows) — */
  .ed-card {
    position: relative; overflow: hidden;
    border: 1px solid #e7dec8;
    border-radius: 16px;
    background: #ffffff;
    transition: border-color 200ms ease, box-shadow 220ms ease, transform 220ms cubic-bezier(.16,1,.3,1);
  }
  .ed-card:hover { border-color: #c8b896; box-shadow: 0 8px 22px -16px rgba(66, 48, 12, 0.22); transform: translateY(-1px); }
  .ed-card__edge {
    position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
    background: #d6c69d; transition: background 180ms ease;
  }
  .ed-card[open] .ed-card__edge,
  .ed-card:hover .ed-card__edge { background: #6b5317; }
  .ed-card.is-good .ed-card__edge { background: #047857; }
  .ed-card.is-warn .ed-card__edge { background: #d97706; }
  .ed-card.is-bad  .ed-card__edge { background: #b91c1c; }

  /* — Manage rail link — */
  .nav-rail-link {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 16px;
    transition: background-color 160ms ease;
    text-decoration: none;
  }
  .nav-rail-link:hover { background: rgba(255, 250, 242, 0.75); }
  .nav-rail-link:hover .nav-rail-chip { background: #6b5317; color: #fffaf2; }
  .nav-rail-chip {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px;
    border-radius: 8px;
    background: #f1ead6;
    color: #6b5317;
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.625rem; font-weight: 700;
    letter-spacing: 0.05em;
    transition: all 180ms ease;
  }
  .nav-rail-link__title { font-size: 0.9375rem; color: #1c1610; flex: 1; min-width: 0; }
  .nav-rail-link__chev { color: rgba(122, 111, 94, 0.5); flex-shrink: 0; }

  /* — Editorial gradebook table — */
  .gb-table { width: 100%; border-collapse: collapse; }
  .gb-table th {
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.6875rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.14em;
    color: #7a6f5e;
    background: #fffaf2;
    padding: 12px 16px;
    text-align: left;
    border-bottom: 1px solid #e7dec8;
  }
  .gb-table td { padding: 14px 16px; border-bottom: 1px solid #f1ead6; vertical-align: middle; }
  .gb-table tbody tr:last-child td { border-bottom: 0; }
  .gb-table tbody tr:hover { background: rgba(255, 250, 242, 0.5); }
  .gb-score__pct { font-family: 'Spectral', Georgia, serif; font-weight: 600; font-size: 1rem; color: #1c1610; font-variant-numeric: tabular-nums; }
  .gb-score__raw { font-family: 'Archivo Narrow', sans-serif; font-size: 0.75rem; color: #7a6f5e; margin-left: 4px; font-variant-numeric: tabular-nums; }

  /* — Toggle pill (binary state) — */
  .toggle-pill {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 8px 14px;
    border: 1px solid #e7dec8;
    border-radius: 999px;
    background: #ffffff;
    cursor: pointer;
    transition: all 180ms ease;
    user-select: none;
  }
  .toggle-pill input { position: absolute; opacity: 0; pointer-events: none; }
  .toggle-pill:hover { border-color: #c8b896; }
  .toggle-pill__dot {
    width: 8px; height: 8px; border-radius: 999px;
    background: #d6c69d; transition: all 180ms ease;
  }
  .toggle-pill__label { font-size: 0.875rem; color: #4a3f2e; }
  .toggle-pill__hint  { font-family: 'Archivo Narrow', sans-serif; font-size: 0.625rem; color: #7a6f5e; text-transform: uppercase; letter-spacing: 0.10em; margin-left: 4px; }
  .toggle-pill:has(input:checked) { background: #6b5317; border-color: #6b5317; }
  .toggle-pill:has(input:checked) .toggle-pill__dot { background: #fffaf2; box-shadow: 0 0 0 4px rgba(255, 250, 242, 0.18); }
  .toggle-pill:has(input:checked) .toggle-pill__label { color: #fffaf2; font-weight: 600; }
  .toggle-pill:has(input:checked) .toggle-pill__hint  { color: #fffaf2; opacity: 0.65; }

  /* — Sticky save bar (forms) — */
  .save-bar {
    position: sticky; bottom: 16px; z-index: 5;
    margin-top: 24px;
    padding: 14px 18px;
    border-radius: 14px;
    background: rgba(28, 22, 16, 0.96);
    color: #fffaf2;
    backdrop-filter: blur(8px);
    box-shadow: 0 18px 40px -22px rgba(28, 22, 16, 0.55);
  }
  .save-bar .btn-primary { background: #fffaf2; color: #1c1610; }
  .save-bar .btn-primary:hover { background: #ffffff; }
  .save-bar__count { font-family: 'Archivo Narrow', sans-serif; font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.12em; color: rgba(255,250,242,0.6); }
  .save-bar__count strong { color: #fffaf2; font-weight: 700; font-variant-numeric: tabular-nums; }

  /* — Canvas-style inputs (forms that should feel like writing) — */
  .canvas-title {
    width: 100%;
    border: 0; outline: 0;
    padding: 0;
    background: transparent;
    font-family: 'Spectral', Georgia, serif;
    font-weight: 600;
    font-size: clamp(1.875rem, 3vw, 2.5rem);
    line-height: 1.05;
    letter-spacing: -0.015em;
    color: #1c1610;
    border-bottom: 2px solid transparent;
    transition: border-color 200ms ease;
  }
  .canvas-title:focus { border-bottom-color: #6b5317; }
  .canvas-title::placeholder { color: #b09766; font-style: italic; font-weight: 400; }
  .canvas-desc {
    width: 100%;
    border: 0; outline: 0;
    padding: 0;
    background: transparent;
    font-family: 'Spectral', Georgia, serif;
    font-style: italic;
    font-size: 1.0625rem;
    line-height: 1.5;
    color: #4a3f2e;
    resize: none;
    overflow: hidden;
  }
  .canvas-desc:focus { color: #1c1610; }
  .canvas-desc::placeholder { color: #b09766; }
  .canvas-divider {
    height: 1px; background: #e7dec8; margin: 1.75rem 0;
  }
  .canvas-section-label {
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.18em;
    color: #6b5317; font-weight: 600;
    display: flex; align-items: center; gap: 0.5rem;
  }
  .canvas-section-label::before, .canvas-section-label::after {
    content: ""; flex: 1; height: 1px; background: #e7dec8;
  }

  /* — Blueprint empty state (forms with no content yet) — */
  .blueprint {
    border: 1px dashed #d6c69d;
    border-radius: 16px;
    padding: 32px;
    background: repeating-linear-gradient(0deg, transparent, transparent 23px, rgba(107, 83, 23, 0.04) 23px, rgba(107, 83, 23, 0.04) 24px);
    text-align: center;
  }
  .blueprint__num {
    font-family: 'Spectral', Georgia, serif;
    font-size: 3rem; font-weight: 600; color: #d6c69d;
    line-height: 1;
  }
  .blueprint__title {
    font-family: 'Spectral', Georgia, serif;
    font-size: 1.125rem; font-weight: 600; color: #4a3f2e;
    margin-top: 6px;
  }
  .blueprint__hint {
    font-size: 0.875rem; color: #7a6f5e; line-height: 1.55;
    margin-top: 6px; max-width: 48ch;
    margin-left: auto; margin-right: auto;
  }
  .blueprint__chips { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }

  /* — Empty hero (full-page empty state with editorial layout) — */
  .empty-hero { padding: 2rem 0 4rem; }
  .empty-hero__grid {
    margin-top: 2rem;
    display: grid;
    grid-template-columns: minmax(200px, 280px) 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
    border-top: 1px solid #e7dec8;
    padding-top: 2.5rem;
  }
  @media (max-width: 768px) {
    .empty-hero__grid { grid-template-columns: 1fr; }
  }
  .empty-hero__visual { position: relative; padding: 1.5rem 1rem; }
  .empty-hero__numeral {
    display: block;
    font-family: 'Spectral', Georgia, serif;
    font-size: clamp(7rem, 14vw, 11rem);
    font-weight: 600; line-height: 0.85;
    color: #d6c69d; letter-spacing: -0.04em;
    font-feature-settings: "lnum"; font-variant-numeric: tabular-nums;
  }
  .empty-hero__rule { width: 64px; height: 2px; background: #6b5317; margin: 1.25rem 0; }
  .empty-hero__caption {
    font-family: 'Spectral', Georgia, serif; font-style: italic;
    font-size: 1rem; color: #7a6f5e; line-height: 1.4; max-width: 26ch;
  }
  .empty-hero__copy { padding-top: 0.5rem; max-width: 60ch; }
  .empty-hero__title {
    font-family: 'Spectral', Georgia, serif;
    font-size: clamp(1.875rem, 3.4vw, 2.875rem);
    font-weight: 600; line-height: 1.05; letter-spacing: -0.01em;
    color: #1c1610;
  }
  .empty-hero__lede { margin-top: 1rem; font-size: 1rem; line-height: 1.65; color: #4a3f2e; }
  .empty-hero__bullets {
    margin-top: 1.25rem; list-style: none; padding: 0;
    display: grid; gap: 0.5rem;
    color: #4a3f2e; font-size: 0.9375rem; line-height: 1.5;
  }
  .empty-hero__bullets li { display: grid; grid-template-columns: 1.25rem 1fr; align-items: baseline; }
  .empty-hero__bullet { color: #6b5317; font-weight: 700; line-height: 0; font-size: 1.5rem; }
  .empty-hero__actions { margin-top: 1.75rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }

  /* — Tabular pull-quote (free-text answers, learner reviews) — */
  .pull-quote {
    border-left: 2px solid #6b5317;
    padding: 6px 0 6px 16px;
    font-family: 'Spectral', Georgia, serif;
    font-size: 0.9375rem; line-height: 1.55;
    color: #2a2218; font-style: italic;
  }
  .pull-quote::before { content: "\201C"; font-size: 1.5rem; color: #b09766; vertical-align: -0.35em; line-height: 0; margin-right: 2px; }
  .pull-quote::after  { content: "\201D"; font-size: 1.5rem; color: #b09766; vertical-align: -0.35em; line-height: 0; margin-left: 2px; }

  /* — Bar visualisation row (used in survey aggregates) — */
  .bar-row { display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: baseline; padding: 8px 0; }
  .bar-row__label { font-size: 0.875rem; color: #1c1610; }
  .bar-row__count { font-family: 'Archivo Narrow', sans-serif; font-size: 0.75rem; color: #7a6f5e; font-variant-numeric: tabular-nums; }
  .bar-row__count strong { color: #1c1610; font-weight: 600; }
  .bar-track { grid-column: 1 / -1; height: 8px; border-radius: 999px; background: #efe7d3; overflow: hidden; margin-top: 6px; }
  .bar-fill  { height: 100%; background: #6b5317; border-radius: 999px; transition: width 600ms cubic-bezier(.16,1,.3,1); }
  .bar-fill--leader { background: #4a3a10; }

  /* — Progress ring (conic-gradient) — */
  .progress-ring { position: relative; width: 88px; height: 88px; }
  .progress-ring__track {
    position: absolute; inset: 0; border-radius: 999px;
    background: conic-gradient(#6b5317 calc(var(--pct, 0) * 1%), #efe7d3 0);
  }
  .progress-ring__inner {
    position: absolute; inset: 6px; border-radius: 999px;
    background: #fffaf2; display: flex; align-items: center; justify-content: center;
    flex-direction: column;
  }
  .progress-ring__value {
    font-family: 'Spectral', Georgia, serif;
    font-size: 1.5rem; font-weight: 600; line-height: 1; color: #1c1610;
    font-feature-settings: "lnum"; font-variant-numeric: tabular-nums;
  }
  .progress-ring__label {
    font-family: 'Archivo Narrow', sans-serif;
    font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.12em;
    color: #7a6f5e; margin-top: 2px;
  }
  /* Decorative mini variant — used as a small overlay on a course thumb.
     Pair with a visible numeric/bar progress source for assistive tech. */
  .progress-ring--mini { width: 28px; height: 28px; box-shadow: 0 0 0 2px #fffaf2; border-radius: 999px; }
  .progress-ring--mini .progress-ring__inner { inset: 4px; }

  /* — §9 Finance confidence: amount typography + provenance footer — */
  .rims-amount {
    display: inline-flex;
    align-items: baseline;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "lnum";
  }
  .rims-amount__int {
    @apply font-semibold text-ruforum-text;
  }
  .rims-amount__dec {
    @apply font-normal text-ruforum-text/75;
  }
  .rims-amount__ccy {
    @apply ml-1 text-[0.6875rem] font-medium uppercase tracking-[0.08em] text-ruforum-text-muted;
    align-self: center;
  }
  .rims-amount-dual {
    @apply inline-flex flex-wrap items-baseline gap-x-2 gap-y-0.5;
  }
  .rims-amount__arrow {
    @apply text-ruforum-text-muted text-sm;
  }
  .rims-amount__sep {
    @apply text-ruforum-text-muted text-sm;
  }
  .rims-amount__fx {
    @apply ml-1 text-[0.6875rem] font-normal text-ruforum-text-muted;
    font-variant-numeric: tabular-nums;
  }
  .rims-amount__fx--missing {
    @apply italic;
  }
  .rims-data-footer {
    @apply mt-10 pt-5 pb-1 border-t border-ruforum-border/70 text-[0.6875rem] uppercase tracking-[0.08em] text-ruforum-text-muted;
    font-family: 'Archivo Narrow', sans-serif;
  }

  /* — §7 Reviewer surface: progress ring caption + peer-score histogram — */
  .reviewer-progress {
    @apply inline-flex flex-col items-center gap-1 shrink-0;
  }
  .reviewer-progress__caption {
    font-family: 'Archivo Narrow', sans-serif;
    @apply text-[0.625rem] uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .score-distribution {
    @apply rounded-xl border border-ruforum-border bg-white px-5 py-4;
  }
  .score-distribution--empty {
    @apply border-dashed bg-ruforum-surface-warm;
  }
  .score-distribution__head {
    @apply mb-3;
  }
  .score-distribution__eyebrow {
    font-family: 'Archivo Narrow', sans-serif;
    @apply text-[0.625rem] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .score-distribution__title {
    @apply mt-1 font-display text-base font-semibold leading-snug text-ruforum-text;
  }
  .score-distribution__hint {
    @apply mt-1 text-xs leading-relaxed text-ruforum-text-muted;
  }
  .score-distribution__bars {
    @apply m-0 list-none space-y-1.5 p-0;
  }
  .score-distribution__row {
    @apply grid items-center gap-3;
    grid-template-columns: 5rem 1fr 2.25rem;
  }
  .score-distribution__label {
    @apply text-[0.6875rem] text-ruforum-text-muted;
  }
  .score-distribution__track {
    @apply block h-2 w-full overflow-hidden rounded-full bg-ruforum-surface;
  }
  .score-distribution__fill {
    @apply block h-full rounded-full bg-ruforum-primary/80;
    transition: width 480ms cubic-bezier(.16,1,.3,1);
  }
  .score-distribution__count {
    @apply justify-self-end text-xs font-semibold text-ruforum-text;
  }
  .score-distribution__foot {
    @apply mt-3 border-t border-ruforum-border/60 pt-2 text-[0.6875rem] uppercase tracking-[0.10em] text-ruforum-text-muted;
    font-family: 'Archivo Narrow', sans-serif;
  }

  /* — §7 Dismissible reviewer-tips callout shell — */
  .reviewer-tips {
    @apply relative;
  }
  .reviewer-tips__dismiss {
    @apply absolute right-3 top-3 rounded-full p-1 text-ruforum-text-muted transition-colors hover:bg-ruforum-surface hover:text-ruforum-text;
    line-height: 0;
  }

  /* — §8 Public call-detail recruiting surface — */
  .public-call {
    @apply mx-auto max-w-4xl;
  }
  .public-call__eyebrow {
    @apply font-display italic text-base text-ruforum-text/80;
  }
  .public-call__eyebrow-glyph {
    @apply mr-1.5 text-ruforum-primary;
  }
  .public-call__title {
    @apply display-1 mt-3 text-ruforum-text;
  }
  .public-call__lede {
    @apply mt-3 max-w-2xl text-base text-ruforum-text-muted;
  }
  .public-call__keynumbers {
    @apply mt-10 grid gap-0 border-y border-ruforum-border sm:grid-cols-2 lg:grid-cols-4;
  }
  .public-call__keycell {
    @apply px-5 py-4 sm:border-r sm:border-ruforum-border last:border-r-0;
  }
  .public-call__keylabel {
    font-family: 'Archivo Narrow', sans-serif;
    @apply text-[0.625rem] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .public-call__keyvalue {
    @apply mt-1 font-display text-lg font-semibold leading-snug text-ruforum-text tabular-nums;
  }
  .public-call__keyvalue--small {
    @apply text-sm;
  }
  .public-call__editorial {
    @apply mt-10 font-display text-lg leading-relaxed text-ruforum-text;
  }
  .public-call__editorial-eyebrow {
    @apply font-meta mb-3 text-[0.625rem] font-semibold uppercase tracking-[0.18em] text-ruforum-text-muted;
  }
  .public-call__section {
    @apply mt-10;
  }
  .public-call__section-title {
    @apply font-display text-xl font-semibold text-ruforum-text;
  }
  .public-call__bullets {
    @apply mt-4 space-y-2 text-sm text-ruforum-text;
  }
  .public-call__bullet {
    @apply flex gap-3;
  }
  .public-call__bullet-marker {
    @apply mt-2 inline-block h-1 w-3 shrink-0 bg-ruforum-primary;
  }

  .countdown-bar {
    @apply fixed inset-x-0 bottom-0 z-30 border-t border-ruforum-border bg-white/95 backdrop-blur;
    box-shadow: 0 -4px 16px -8px rgba(28, 22, 16, 0.18);
  }
  .countdown-bar__inner {
    @apply mx-auto flex max-w-5xl flex-wrap items-center justify-between gap-4 px-5 py-3;
  }
  .countdown-bar__timer {
    @apply flex items-baseline gap-3;
  }
  .countdown-bar__eyebrow {
    font-family: 'Archivo Narrow', sans-serif;
    @apply text-[0.625rem] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .countdown-bar__digits {
    @apply flex items-baseline gap-1.5 font-display text-base font-semibold text-ruforum-text;
  }
  .countdown-bar__digits--closed {
    @apply text-ruforum-text-muted italic;
  }
  .countdown-bar__cell {
    @apply inline-flex items-baseline gap-1;
  }
  .countdown-bar__num {
    @apply text-xl font-semibold leading-none text-ruforum-text;
  }
  .countdown-bar__unit {
    font-family: 'Archivo Narrow', sans-serif;
    @apply text-[0.6875rem] uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .countdown-bar__sep {
    @apply text-ruforum-text-muted/60;
  }
  .countdown-bar__cta {
    @apply flex shrink-0 items-center gap-2;
  }

  /* ══════════════════════════════════════════════════════════════════
     Repository v2 — tool-first document UI
     ──────────────────────────────────────────────────────────────────
     Replaces the editorial "monograph" rows that scattered Spectral
     italics, magazine eyebrows and bare hairline dividers across the
     repository surface. The v2 surface treats documents as records
     in a catalogue: file-type icon, coloured type badge, status pill,
     sans-serif title, scannable meta strip. Spectral is reserved for
     prose reading (abstract body, AI summary body) only.
     ════════════════════════════════════════════════════════════════ */

  /* Page head (replaces the .repo-wordmark hero on browse pages) */
  .repo-page-head { @apply mb-7; }
  .repo-page-head__kicker {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .repo-page-head__title {
    @apply mt-2 font-sans text-3xl font-semibold leading-tight tracking-tight text-ruforum-text sm:text-[2rem];
  }
  .repo-page-head__sub {
    @apply mt-2 max-w-[68ch] text-[0.9375rem] leading-relaxed text-ruforum-text-muted;
  }

  /* Working pill search input (real <input>, not a fake link) */
  .repo-search { @apply relative; }
  .repo-search__icon {
    @apply pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-ruforum-text-muted;
    z-index: 1;
  }
  input.repo-search__input,
  input[type="search"].repo-search__input {
    @apply h-12 w-full rounded-xl border border-ruforum-border-strong bg-white text-base text-ruforum-text shadow-sm transition-colors;
    padding-left: 3rem;
    padding-right: 7rem;
  }
  input.repo-search__input::placeholder,
  input[type="search"].repo-search__input::placeholder {
    @apply text-ruforum-text-muted/70;
  }
  input.repo-search__input:focus,
  input[type="search"].repo-search__input:focus {
    @apply border-ruforum-primary outline-none ring-2 ring-ruforum-primary/[0.18];
  }
  .repo-search__submit {
    @apply absolute right-1.5 top-1/2 -translate-y-1/2 inline-flex h-9 items-center gap-1.5 rounded-lg bg-ruforum-primary px-3.5 text-sm font-semibold text-white transition-colors hover:bg-ruforum-primary-hover;
  }

  /* ── Repository search typeahead (FRREP-SR002) ─────────────────── */
  .repo-typeahead {
    @apply absolute left-0 right-0 top-full z-30 mt-1.5 max-h-[22rem] overflow-y-auto rounded-xl border border-ruforum-border-strong bg-white py-1.5 shadow-lg;
  }
  .repo-typeahead__item {
    @apply flex cursor-pointer items-center px-4 py-2 transition-colors;
  }
  .repo-typeahead__item--active {
    @apply bg-ruforum-surface-warm;
  }

  /* ── Repository onboarding strip (browse landing) ──────────────── */
  .repo-welcome-strip {
    @apply flex flex-wrap items-center justify-between gap-x-6 gap-y-3 rounded-xl border border-ruforum-border bg-white px-5 py-4;
  }
  .repo-welcome-strip__body {
    @apply min-w-0 flex-1;
  }
  .repo-welcome-strip__label {
    @apply font-meta text-[10.5px] font-semibold uppercase tracking-[0.14em] text-ruforum-text-muted;
  }
  .repo-welcome-strip__sentence {
    @apply mt-1 font-display text-[15px] leading-snug text-ruforum-text;
  }
  .repo-welcome-strip__cta {
    @apply inline-flex items-center gap-1 whitespace-nowrap font-sans text-sm font-semibold text-ruforum-primary transition-colors hover:text-ruforum-primary-hover;
  }

  /* KPI strip (analytics dashboards) */
  .kpi-strip {
    @apply grid grid-cols-2 gap-x-6 gap-y-4 rounded-xl border border-ruforum-border bg-white px-5 py-4 sm:grid-cols-4;
  }
  .kpi__label {
    @apply font-meta text-[10.5px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .kpi__value {
    @apply mt-1 font-sans text-2xl font-semibold leading-none text-ruforum-text tabular-nums;
  }
  /* Display variant for analytics surfaces — Spectral, larger, measured. */
  .kpi__value--display {
    @apply font-display text-3xl font-semibold tabular-nums;
    line-height: 1.05;
    letter-spacing: -0.01em;
  }

  /* Public mast — flagship donor-facing share-link headline.
     Spectral display weight that says "institutional publication," not "admin export." */
  .public-mast {
    @apply font-display font-semibold text-ruforum-text;
    font-size: clamp(2rem, 3vw, 2.5rem);
    line-height: 1.1;
    letter-spacing: -0.005em;
  }
  .kpi__delta {
    @apply mt-1 font-meta text-[11px] text-ruforum-text-muted tabular-nums;
  }

  /* ── Filter rail ───────────────────────────────────────────────── */
  .filter-rail { @apply space-y-4; }
  .filter-rail__head {
    @apply flex items-baseline justify-between mb-1;
  }
  .filter-rail__title {
    @apply font-sans text-base font-semibold text-ruforum-text;
  }
  .filter-rail__clear {
    @apply text-xs font-medium text-ruforum-primary hover:text-ruforum-primary-hover hover:underline;
  }
  .filter-group {
    @apply rounded-xl border border-ruforum-border bg-white p-3.5;
  }
  .filter-group__label {
    @apply block font-meta text-[10.5px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted mb-2;
  }
  .filter-group__body {
    @apply space-y-0.5;
  }
  .filter-option {
    @apply flex items-center gap-2 cursor-pointer rounded-md px-1.5 py-1 transition-colors hover:bg-ruforum-warm-hover/60;
  }
  .filter-option__check {
    @apply h-3.5 w-3.5 shrink-0 rounded border-ruforum-border-strong text-ruforum-primary focus:ring-ruforum-primary/40;
  }
  .filter-option__label {
    @apply min-w-0 flex-1 break-words text-sm leading-snug text-ruforum-text;
  }
  .filter-option__count {
    @apply ml-auto rounded bg-ruforum-surface px-1.5 py-0.5 font-meta text-[10px] font-semibold tabular-nums text-ruforum-text-muted;
  }
  .filter-option input:checked + .filter-option__label {
    @apply font-semibold text-ruforum-text;
  }

  /* Active-filter chip (above results) */
  .active-filter {
    @apply inline-flex items-center gap-1.5 rounded-full border border-ruforum-primary/20 bg-ruforum-primary/10 px-2.5 py-1 font-meta text-[11px] font-medium uppercase tracking-[0.06em] text-ruforum-primary;
  }
  .active-filter__remove {
    @apply -mr-1 inline-flex h-4 w-4 items-center justify-center rounded-full text-ruforum-primary/70 transition-colors hover:bg-ruforum-primary/15 hover:text-ruforum-primary;
  }

  /* ── Results toolbar (sort, density, count) ───────────────────── */
  .results-toolbar {
    @apply flex flex-wrap items-center justify-between gap-3 mb-4 pb-3 border-b border-ruforum-border;
  }
  .results-toolbar__count {
    @apply font-sans text-sm text-ruforum-text-muted;
  }
  .results-toolbar__count strong {
    @apply font-semibold text-ruforum-text tabular-nums;
  }
  .results-toolbar__controls {
    @apply flex items-center gap-2;
  }
  .view-toggle {
    @apply inline-flex rounded-lg border border-ruforum-border bg-white p-0.5;
  }
  .view-toggle a, .view-toggle button {
    @apply inline-flex h-8 w-8 items-center justify-center rounded-md text-ruforum-text-muted transition-colors hover:text-ruforum-text;
  }
  .view-toggle .is-active {
    @apply bg-ruforum-primary text-white hover:text-white;
  }

  /* ── Document item (list row) ─────────────────────────────────── */
  .doc-item {
    @apply flex gap-4 rounded-xl border border-ruforum-border bg-white px-4 py-4 transition-all hover:border-ruforum-border-strong hover:shadow-card;
  }
  .doc-item__icon {
    @apply flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-ruforum-surface text-ruforum-text-muted ring-1 ring-ruforum-border;
  }
  .doc-item__body { @apply min-w-0 flex-1; }
  .doc-item__badges {
    @apply flex flex-wrap items-center gap-1.5 mb-1.5;
  }
  .doc-item__title {
    @apply block font-sans text-[1.0625rem] font-semibold leading-snug text-ruforum-text transition-colors hover:text-ruforum-primary;
  }
  .doc-item__authors {
    @apply mt-1 text-sm leading-snug text-ruforum-text/75;
  }
  .doc-item__authors a {
    @apply text-ruforum-text/85 hover:text-ruforum-primary transition-colors;
  }
  .doc-item__snippet {
    @apply mt-2 text-sm leading-relaxed text-ruforum-text/80;
  }
  .doc-item__snippet mark {
    background-color: #fce8b8;
    @apply rounded-sm px-0.5 text-ruforum-text;
  }
  .doc-item__meta {
    @apply mt-2.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-ruforum-text-muted;
  }
  .doc-item__meta > * + *::before {
    content: "·";
    @apply mr-3 text-ruforum-text-muted/40;
  }
  .doc-item__meta a {
    @apply text-ruforum-text-muted hover:text-ruforum-text transition-colors;
  }

  /* Grid variant: same component, tile layout. */
  .doc-grid {
    @apply grid gap-3 sm:grid-cols-2 xl:grid-cols-3;
  }
  .doc-item--grid {
    @apply flex-col gap-0 p-5;
  }
  .doc-item--grid .doc-item__icon {
    @apply mb-3 h-11 w-11;
  }
  .doc-item--grid .doc-item__title {
    @apply text-base;
  }
  .doc-item--grid .doc-item__snippet {
    @apply line-clamp-3;
  }

  /* List wrapper — gives breathing room between rows */
  .doc-list { @apply space-y-2.5; }

  /* ── Type badge (per DocumentType) ────────────────────────────── */
  .type-badge {
    @apply inline-flex items-center gap-1 rounded-md px-2 py-0.5 font-meta text-[10.5px] font-semibold uppercase tracking-[0.10em];
  }
  .type-badge--thesis              { @apply bg-violet-50 text-violet-700; }
  .type-badge--journal_article     { @apply bg-sky-50 text-sky-700; }
  .type-badge--conference_paper    { @apply bg-indigo-50 text-indigo-700; }
  .type-badge--policy_brief        { @apply bg-rose-50 text-rose-700; }
  .type-badge--technical_report    { @apply bg-stone-100 text-stone-700; }
  .type-badge--project_report      { @apply bg-amber-50 text-amber-800; }
  .type-badge--dataset             { @apply bg-teal-50 text-teal-700; }
  .type-badge--innovation_document { @apply bg-emerald-50 text-emerald-700; }
  .type-badge--publication         { @apply bg-blue-50 text-blue-700; }
  .type-badge--other               { @apply bg-stone-100 text-stone-600; }

  /* ── Status pill (Open Access / Restricted / Authenticated / …) ─ */
  .status-pill {
    @apply inline-flex items-center gap-1 rounded-md px-2 py-0.5 font-meta text-[10.5px] font-semibold uppercase tracking-[0.10em];
  }
  .status-pill--oa             { @apply bg-emerald-50 text-emerald-700; }
  .status-pill--authenticated  { @apply bg-sky-50 text-sky-700; }
  .status-pill--restricted     { @apply bg-amber-50 text-amber-800; }
  .status-pill--internal       { @apply bg-stone-100 text-stone-600; }
  .status-pill--deprecated     { @apply bg-amber-50 text-amber-800; }
  .status-pill--withdrawn      { @apply bg-rose-50 text-rose-700; }

  /* ── Document detail hero ─────────────────────────────────────── */
  .doc-hero { @apply mb-6; }
  .doc-hero__type-row {
    @apply flex flex-wrap items-center gap-2 mb-3;
  }
  .doc-hero__title {
    @apply font-sans text-3xl font-semibold leading-[1.2] tracking-tight text-ruforum-text sm:text-[2.25rem];
  }
  .doc-hero__authors {
    @apply mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 text-base text-ruforum-text/80;
  }
  .doc-hero__author {
    @apply text-ruforum-text/90 hover:text-ruforum-primary transition-colors;
  }
  .doc-hero__author + .doc-hero__author::before {
    content: "·";
    @apply mr-3 text-ruforum-text-muted/50;
  }

  /* ── Action bar on the document detail page ───────────────────── */
  .action-bar {
    @apply mt-5 flex flex-wrap items-center gap-2 rounded-xl border border-ruforum-border bg-white px-3 py-2.5 shadow-card;
  }
  .action-bar__primary {
    @apply inline-flex items-center gap-2 rounded-lg bg-ruforum-primary px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-ruforum-primary-hover;
  }
  .action-bar__secondary {
    @apply inline-flex items-center gap-2 rounded-lg border border-ruforum-border bg-white px-3.5 py-2 text-sm font-medium text-ruforum-text transition-colors hover:bg-ruforum-warm-hover;
  }
  .action-bar__icon-btn {
    @apply inline-flex h-9 w-9 items-center justify-center rounded-lg text-ruforum-text-muted transition-colors hover:bg-ruforum-warm-hover hover:text-ruforum-text;
  }
  .action-bar__divider { @apply mx-1 h-6 w-px bg-ruforum-border; }
  .action-bar__overflow { @apply ml-auto flex items-center gap-1; }
  /* Mobile sheet for the overflow group — keep Download / Read / Cite
     uncluttered on narrow screens while preserving role-gated actions. */
  .action-bar__more { @apply ml-auto; }
  .action-bar__more-sheet {
    @apply absolute right-0 top-full mt-1 w-56 rounded-xl border border-ruforum-border bg-white p-1.5 shadow-dropdown z-20;
  }
  .action-bar__more-item {
    @apply flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-sm text-ruforum-text transition-colors hover:bg-ruforum-warm-hover;
  }
  .action-bar__more-item--danger { @apply text-amber-800 hover:bg-amber-50; }
  .action-bar__more-item--success { @apply text-emerald-800 hover:bg-emerald-50; }

  /* Inline cite popover — formats shown as horizontal buttons, not nested clicks */
  .cite-pop {
    @apply absolute right-0 top-full mt-2 w-[22rem] rounded-xl border border-ruforum-border bg-white p-4 shadow-dropdown z-10;
  }
  .cite-pop__formats {
    @apply flex flex-wrap gap-1.5;
  }
  .cite-pop__format-btn {
    @apply inline-flex items-center gap-1.5 rounded-lg border border-ruforum-border bg-white px-2.5 py-1.5 font-meta text-[11px] font-semibold uppercase tracking-[0.08em] text-ruforum-text transition-colors hover:border-ruforum-primary/40 hover:bg-ruforum-warm-hover hover:text-ruforum-primary;
  }
  .cite-pop__preview {
    @apply mt-3 rounded-lg bg-ruforum-surface/60 p-3 font-display text-[12.5px] leading-snug text-ruforum-text;
  }

  /* ── Document detail body sections ────────────────────────────── */
  .detail-section { @apply mb-8; }
  .detail-section__head {
    @apply flex items-baseline justify-between gap-4 mb-3 pb-2 border-b border-ruforum-border;
  }
  .detail-section__title {
    @apply font-sans text-xl font-semibold text-ruforum-text;
  }
  .detail-section__aside {
    @apply font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .detail-section__body {
    @apply text-[0.9375rem] leading-[1.7] text-ruforum-text;
  }
  /* Prose body — Spectral is allowed here. This is the long-form
     reading column for the abstract / AI summary. */
  .detail-section__prose {
    @apply font-display text-[0.9375rem] leading-[1.75] text-ruforum-text max-w-[72ch];
  }

  /* ── Calmer AI callout (replaces .ai-bleed amber tint) ────────── */
  .ai-callout {
    @apply rounded-xl border border-ruforum-border bg-ruforum-surface-warm/70 px-5 py-4;
  }
  .ai-callout__chip {
    @apply inline-flex items-center gap-1.5 rounded-full bg-white px-2.5 py-0.5 font-meta text-[10.5px] font-semibold uppercase tracking-[0.10em] text-amber-800 ring-1 ring-amber-100;
  }
  .ai-callout__body {
    @apply mt-3 font-display text-[0.9375rem] leading-[1.7] text-ruforum-text;
  }
  .ai-callout__foot {
    @apply mt-3 font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }

  /* ── Detail sidebar (metadata, authors, versions, reach) ──────── */
  .detail-side { @apply space-y-4 lg:sticky; top: calc(3.5rem + 2.25rem + 1.25rem); }
  .detail-side__group {
    @apply rounded-xl border border-ruforum-border bg-white p-4;
  }
  .detail-side__group-title {
    @apply mb-3 pb-2 border-b border-ruforum-border font-meta text-[10.5px] font-semibold uppercase tracking-[0.12em] text-ruforum-text-muted;
  }
  .detail-side__row {
    @apply flex items-baseline justify-between gap-3 py-1.5 text-sm;
  }
  .detail-side__label {
    @apply text-ruforum-text-muted;
  }
  .detail-side__value {
    @apply font-medium text-ruforum-text text-right;
  }
  .detail-side__value--num {
    @apply font-medium text-ruforum-text text-right tabular-nums;
  }
  .detail-side__author-row {
    @apply flex items-start gap-3 py-2 border-b border-ruforum-border last:border-b-0;
  }
  .detail-side__avatar {
    @apply flex h-9 w-9 shrink-0 items-center justify-center rounded-full font-meta text-[11px] font-semibold tabular-nums text-ruforum-primary;
    background: oklch(0.92 0.04 var(--avatar-hue, 70deg));
  }
  .detail-side__author-name {
    @apply block text-sm font-semibold text-ruforum-text hover:text-ruforum-primary transition-colors leading-snug;
  }
  .detail-side__author-meta {
    @apply mt-0.5 text-xs text-ruforum-text-muted leading-snug;
  }
  .detail-side__stat-grid {
    @apply grid grid-cols-3 gap-3;
  }
  .detail-side__stat-value {
    @apply font-sans text-xl font-semibold tabular-nums text-ruforum-text leading-none;
  }
  .detail-side__stat-label {
    @apply mt-1 font-meta text-[10px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }

  /* ── Collection card (collection_list grid) ───────────────────── */
  /* NOTE: caller must also set `group` on the element to enable
     group-hover styling on .collection-card__title. */
  .collection-card {
    @apply flex h-full flex-col gap-2 rounded-xl border border-ruforum-border bg-white p-5 transition-all hover:border-ruforum-border-strong hover:shadow-card-hover;
  }
  .collection-card__badges {
    @apply flex flex-wrap items-center gap-1.5 mb-1;
  }
  .collection-card__title {
    @apply font-sans text-lg font-semibold leading-snug text-ruforum-text group-hover:text-ruforum-primary transition-colors;
  }
  .collection-card__desc {
    @apply text-sm leading-relaxed text-ruforum-text/75 line-clamp-3;
  }
  .collection-card__foot {
    @apply mt-auto flex items-center justify-between pt-3 text-xs text-ruforum-text-muted border-t border-ruforum-border;
  }
  .collection-card__count {
    @apply font-meta text-[11px] font-semibold uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .collection-card__count strong {
    @apply text-ruforum-text font-semibold normal-case tracking-normal tabular-nums;
  }

  /* ── Collection dense list (collection_list default view) ─────── */
  /* Institutional archive voice: badges + Spectral name + 1-line desc + count
     + chevron, single panel with internal dividers. Pair with .collection-row
     anchor children. */
  .collection-list {
    @apply overflow-hidden rounded-xl border border-ruforum-border bg-white shadow-card;
  }
  .collection-list > * + * {
    @apply border-t border-ruforum-border/60;
  }
  .collection-row {
    @apply grid items-center gap-x-4 gap-y-1 px-4 py-3.5 transition-colors hover:bg-ruforum-warm-hover/60;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto auto;
  }
  .collection-row__badges {
    @apply flex flex-wrap items-center gap-1.5 shrink-0;
  }
  .collection-row__body {
    @apply flex min-w-0 flex-col gap-0.5;
  }
  .collection-row__name {
    @apply truncate font-display text-base font-semibold leading-tight text-ruforum-text;
  }
  .collection-row:hover .collection-row__name {
    @apply text-ruforum-primary;
  }
  .collection-row__desc {
    @apply truncate text-sm text-ruforum-text-muted;
  }
  .collection-row__count {
    @apply shrink-0 font-meta text-[11px] uppercase tracking-[0.10em] tabular-nums text-ruforum-text-muted;
  }
  .collection-row__count strong {
    @apply text-ruforum-text font-semibold normal-case tracking-normal tabular-nums;
  }
  .collection-row__chevron {
    @apply h-4 w-4 shrink-0 text-ruforum-text-muted/60 transition-colors;
  }
  .collection-row:hover .collection-row__chevron {
    @apply text-ruforum-primary;
  }
  /* On narrow screens collapse to two-row layout: badges + body stacked
     left, count + chevron pinned right. */
  @media (max-width: 640px) {
    .collection-row {
      grid-template-columns: minmax(0, 1fr) auto;
    }
    .collection-row__badges {
      grid-column: 1 / -1;
    }
    .collection-row__chevron {
      @apply hidden;
    }
  }

  /* ── Collection view toggle (list / grid segmented control) ───── */
  .collection-view-toggle {
    @apply inline-flex items-center rounded-lg border border-ruforum-border bg-white p-0.5;
  }
  .collection-view-toggle__btn {
    @apply inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 font-meta text-[11px] font-semibold uppercase tracking-[0.10em] text-ruforum-text-muted transition-colors hover:text-ruforum-text;
  }
  .collection-view-toggle__btn--active {
    @apply bg-ruforum-surface text-ruforum-text;
  }
  .collection-list-toolbar {
    @apply mb-4 flex flex-wrap items-center justify-between gap-3 font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }
  .collection-list-toolbar__count strong {
    @apply text-ruforum-text font-semibold normal-case tracking-normal tabular-nums;
  }

  /* ── Inline section header (replaces section-head + repo-eyebrow) ─ */
  .repo-section-head {
    @apply mb-4 flex items-baseline justify-between gap-4 pb-2 border-b border-ruforum-border;
  }
  .repo-section-head__title {
    @apply font-sans text-lg font-semibold text-ruforum-text;
  }
  .repo-section-head__aside {
    @apply font-meta text-[11px] uppercase tracking-[0.10em] text-ruforum-text-muted;
  }

  /* Mobile filter drawer */
  .filter-drawer { @apply lg:hidden mb-4 rounded-xl border border-ruforum-border bg-white; }
  .filter-drawer summary {
    @apply cursor-pointer px-4 py-3 font-sans text-sm font-semibold text-ruforum-text flex items-center justify-between;
    list-style: none;
  }
  .filter-drawer summary::-webkit-details-marker { display: none; }
  .filter-drawer summary::after {
    content: "+";
    @apply font-meta font-semibold text-ruforum-text-muted;
  }
  .filter-drawer[open] summary::after { content: "−"; }
  .filter-drawer__chip {
    @apply ml-2 inline-flex items-center rounded-full bg-ruforum-primary/[0.10] px-2 py-0.5 font-meta text-[10.5px] font-semibold uppercase tracking-[0.10em] text-ruforum-primary;
  }
  .filter-drawer__form {
    @apply border-t border-ruforum-border px-4 pt-4 pb-0 space-y-4;
  }
  .filter-drawer__actions {
    @apply sticky bottom-0 z-10 -mx-4 mt-4 flex items-center justify-between gap-3 border-t border-ruforum-border bg-white/95 px-4 py-3 backdrop-blur;
  }
  .filter-drawer__clear {
    @apply font-sans text-sm font-medium text-ruforum-text-muted hover:text-ruforum-text underline-offset-2 hover:underline;
  }
  .filter-drawer__apply {
    @apply inline-flex h-10 items-center justify-center gap-1 rounded-lg bg-ruforum-primary px-5 font-sans text-sm font-semibold text-white transition-colors hover:bg-ruforum-primary-hover;
  }
  .filter-option--standalone {
    @apply rounded-lg border border-ruforum-border px-3 py-2;
  }

  /* ══════════════════════════════════════════════════════════════════
     Motion utilities (Tier A — taste-skill rewrites)
     ──────────────────────────────────────────────────────────────────
     Used on AI surfaces (recommendations, mentor-match, dropoff) and on
     mount/transition events. Every continuous animation is guarded by
     prefers-reduced-motion. The earlier @keyframes ruforum-shimmer
     (line ~1239) and live-pulse (line ~634) are re-used, not duplicated.
     ════════════════════════════════════════════════════════════════ */

  .pulse-dot {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 999px;
    background: oklch(0.62 0.16 145);
    box-shadow: 0 0 0 0 oklch(0.62 0.16 145 / 0.6);
    animation: live-pulse 1.5s ease-out infinite;
  }
  .pulse-dot--amber { background: oklch(0.68 0.15 70); box-shadow: 0 0 0 0 oklch(0.68 0.15 70 / 0.6); }
  .pulse-dot--rose  { background: oklch(0.58 0.20 18); box-shadow: 0 0 0 0 oklch(0.58 0.20 18 / 0.6); }

  @keyframes ruf-score-land {
    from { transform: scale(0.85); opacity: 0; }
    to   { transform: scale(1);    opacity: 1; }
  }
  .score-land {
    animation: ruf-score-land 380ms cubic-bezier(.16, 1, .3, 1) both;
  }

  @keyframes ruf-stagger-in {
    from { transform: translateY(6px); opacity: 0; }
    to   { transform: translateY(0);   opacity: 1; }
  }
  .stagger-in {
    animation: ruf-stagger-in 320ms cubic-bezier(.16, 1, .3, 1) both;
    animation-delay: calc(var(--index, 0) * 60ms);
  }
  @media (prefers-reduced-motion: reduce) {
    .stagger-in { animation: none; }
    /* qp-timer ring smoothness comes from an inline transition on the SVG circle;
       drop it under reduced-motion so the ring updates step-by-step instead of sweeping. */
    .qp-timer__ring circle { transition: none !important; }
  }

  @keyframes ruf-foil-pan {
    0%   { background-position:   0% 50%; }
    100% { background-position: 200% 50%; }
  }
  .foil {
    position: relative;
    overflow: hidden;
  }
  .foil::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(110deg,
      transparent 30%,
      rgba(255, 255, 255, 0.18) 50%,
      transparent 70%);
    background-size: 200% 100%;
    animation: ruf-foil-pan 5s linear infinite;
    opacity: 0;
    transition: opacity 240ms ease;
  }
  .foil:hover::after,
  .foil:focus-within::after { opacity: 1; }

  @keyframes ruf-dot-wave {
    0%, 80%, 100% { transform: translateY(0);   opacity: 0.4; }
    40%           { transform: translateY(-3px); opacity: 1; }
  }
  .dot-wave { display: inline-flex; gap: 3px; align-items: center; }
  .dot-wave > span {
    width: 4px; height: 4px; border-radius: 999px;
    background: oklch(0.50 0.04 70);
    animation: ruf-dot-wave 1.2s ease-in-out infinite;
  }
  .dot-wave > span:nth-child(2) { animation-delay: 150ms; }
  .dot-wave > span:nth-child(3) { animation-delay: 300ms; }

  @media (prefers-reduced-motion: reduce) {
    .pulse-dot, .pulse-dot--amber, .pulse-dot--rose { animation: none; box-shadow: none; }
    .score-land { animation: none; }
    .stagger-in { animation: none; animation-delay: 0ms; }
    .foil::after { animation: none; opacity: 0; }
    .dot-wave > span { animation: none; opacity: 0.7; transform: none; }
  }

  /* ── Sidebar reference-metadata block ───────────────────────────
     Editorial alternative to card-wrapped `<dl>` panels. Use for
     read-only sidebar metadata (e.g. "Grant call", "Your submission").
     Reserves the `card` chrome for interactive surfaces — forms,
     decisions, actionable data. */
  .meta-block { @apply border-t border-ruforum-border pt-4; }
  .meta-block__title {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #72675c;
    font-family: "Archivo Narrow", "Barlow", sans-serif;
    margin-bottom: 0.75rem;
  }
  /* Each item is a horizontal label→value pair with a hairline divider, so
     the eye reads "Title: E2E reviewer queue" not two stacked paragraphs. */
  .meta-block__list { @apply m-0 list-none p-0; }
  .meta-block__item {
    @apply flex items-baseline justify-between gap-4 border-b border-ruforum-border/60 py-2 last:border-0;
  }
  .meta-block__item dt {
    @apply shrink-0 text-[0.6875rem] uppercase tracking-[0.10em] text-ruforum-text-muted;
    font-family: "Archivo Narrow", "Barlow", sans-serif;
  }
  .meta-block__item dd {
    @apply min-w-0 text-right text-sm text-ruforum-text;
  }
  .meta-block__item dd.is-strong { @apply font-semibold; }
}

/* ── Leaflet map stacking-context guard ───────────────────────────────────
   Leaflet assigns internal z-indexes up to 1000 to its panes and controls
   (zoom buttons, attribution). Those would otherwise paint over the sticky
   topnav (z-40) and its mega-menu dropdowns (z-50) whenever a map card sits
   under the header — e.g. the alumni Insights map, the core dashboard map,
   and the RIMS reach/origin maps. Giving every map container its own
   stacking context via `isolation` traps those z-indexes locally, so the
   site chrome always renders above the map. Kept OUTSIDE @layer so Tailwind
   never purges it (the `.leaflet-container` class only exists at runtime and
   never appears in scanned templates). */
.leaflet-container {
  isolation: isolate;
}

