/* ==========================================================================
   Components — buttons, cards, badges, alerts, tables, forms, modals,
   pagination, toolbars, empty states, skeletons.
   All colours come from tokens.css so Light/Dark stay in sync automatically.
   ========================================================================== */

/* ==========================================================================
   1. Buttons
   ========================================================================== */
.btn {
    --btn-bg: var(--surface);
    --btn-fg: var(--text-2);
    --btn-border: var(--border);
    --btn-shadow: var(--shadow-xs);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    min-height: var(--control-h);
    padding: 0 var(--sp-4);
    border: 1px solid var(--btn-border);
    border-radius: var(--radius-sm);
    background: var(--btn-bg);
    color: var(--btn-fg);
    box-shadow: var(--btn-shadow);
    font-family: inherit;
    font-size: var(--fs-base);
    font-weight: var(--fw-semibold);
    line-height: 1;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
        border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease),
        transform var(--dur-fast) var(--ease);
}

.btn svg {
    width: 17px;
    height: 17px;
    flex: 0 0 auto;
}

.btn:hover {
    text-decoration: none;
    transform: translateY(-1px);
}

.btn:active {
    transform: translateY(0);
}

.btn:disabled,
.btn.is-disabled,
.btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* Primary */
.btn--primary {
    --btn-bg: var(--primary);
    --btn-fg: var(--primary-contrast);
    --btn-border: var(--primary);
}

.btn--primary:hover {
    --btn-bg: var(--primary-hover);
    --btn-border: var(--primary-hover);
}

/* Secondary (default neutral) */
.btn--secondary {
    --btn-bg: var(--surface);
    --btn-fg: var(--text-2);
}

.btn--secondary:hover {
    --btn-bg: var(--surface-muted);
    --btn-fg: var(--text);
    --btn-border: var(--border-strong);
}

/* Soft / tinted */
.btn--soft {
    --btn-bg: var(--primary-soft);
    --btn-fg: var(--primary);
    --btn-border: var(--primary-soft-border);
    --btn-shadow: none;
}

.btn--soft:hover {
    --btn-bg: var(--brand-100);
}

[data-theme="dark"] .btn--soft:hover {
    --btn-bg: rgba(76, 141, 255, 0.24);
}

/* Ghost */
.btn--ghost {
    --btn-bg: transparent;
    --btn-fg: var(--text-2);
    --btn-border: transparent;
    --btn-shadow: none;
}

.btn--ghost:hover {
    --btn-bg: var(--surface-muted);
    --btn-fg: var(--text);
}

/* Semantic variants */
.btn--success {
    --btn-bg: var(--success);
    --btn-fg: #fff;
    --btn-border: var(--success);
}

[data-theme="dark"] .btn--success {
    --btn-fg: #04231a;
}

.btn--success:hover {
    --btn-bg: var(--success-hover);
}

.btn--danger {
    --btn-bg: var(--danger);
    --btn-fg: #fff;
    --btn-border: var(--danger);
}

[data-theme="dark"] .btn--danger {
    --btn-fg: #2b0808;
}

.btn--danger:hover {
    --btn-bg: var(--danger-hover);
}

.btn--warning {
    --btn-bg: var(--warning);
    --btn-fg: #fff;
    --btn-border: var(--warning);
}

.btn--warning:hover {
    --btn-bg: var(--warning-hover);
}

/* Sizes */
.btn--sm {
    min-height: var(--control-h-sm);
    padding: 0 var(--sp-3);
    font-size: var(--fs-sm);
    gap: var(--sp-1);
}

.btn--sm svg {
    width: 15px;
    height: 15px;
}

.btn--lg {
    min-height: var(--control-h-lg);
    padding: 0 var(--sp-5);
    font-size: var(--fs-md);
}

.btn--block {
    width: 100%;
}

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

.btn--icon.btn--sm {
    width: var(--control-h-sm);
}

/* Loading state toggled by static/js/app.js on submit */
.btn.is-loading {
    pointer-events: none;
    opacity: 0.85;
}

.btn.is-loading::before {
    content: "";
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: spin 700ms linear infinite;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

.btn-group {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.btn-group--attached {
    gap: 0;
}

.btn-group--attached .btn {
    border-radius: 0;
    margin-inline-start: -1px;
}

.btn-group--attached .btn:first-child {
    border-start-start-radius: var(--radius-sm);
    border-end-start-radius: var(--radius-sm);
    margin-inline-start: 0;
}

.btn-group--attached .btn:last-child {
    border-start-end-radius: var(--radius-sm);
    border-end-end-radius: var(--radius-sm);
}
/* ==========================================================================
   2. Cards, sections and dashboard stat cards
   ========================================================================== */
.card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.card--flush {
    overflow: visible;
}

.card--interactive {
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
        border-color var(--dur) var(--ease);
}

.card--interactive:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: var(--border-strong);
}

.card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
    padding: var(--sp-4) var(--sp-5);
    border-block-end: 1px solid var(--border-subtle);
    background: var(--surface);
}

.card__title {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
    color: var(--text);
}

.card__title svg {
    width: 19px;
    height: 19px;
    color: var(--primary);
}

.card__subtitle {
    margin-block-start: 2px;
    font-size: var(--fs-sm);
    color: var(--text-muted);
    font-weight: var(--fw-regular);
}

.card__body {
    padding: var(--sp-5);
    flex: 1 1 auto;
}

.card__body--tight {
    padding: var(--sp-4);
}

.card__body--none {
    padding: 0;
}

.card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    padding: var(--sp-4) var(--sp-5);
    border-block-start: 1px solid var(--border-subtle);
    background: var(--surface-2);
}

.card__section + .card__section {
    margin-block-start: var(--sp-5);
    padding-block-start: var(--sp-5);
    border-block-start: 1px dashed var(--border);
}

/* ---------- Stat cards (dashboard / finance KPIs) ---------- */
.stat {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    padding: var(--sp-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
        border-color var(--dur) var(--ease);
}

.stat::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    height: 3px;
    background: var(--stat-accent, var(--primary));
    opacity: 0.9;
}

.stat:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: var(--border-strong);
}

.stat__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-3);
}

.stat__label {
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    color: var(--text-muted);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
}

.stat__icon {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    background: var(--stat-soft, var(--primary-soft));
    color: var(--stat-accent, var(--primary));
    flex: 0 0 auto;
}

.stat__icon svg {
    width: 20px;
    height: 20px;
}

.stat__value {
    font-size: var(--fs-4xl);
    font-weight: var(--fw-bold);
    line-height: 1.1;
    letter-spacing: var(--ls-tight);
    color: var(--text);
}

.stat__value--sm {
    font-size: var(--fs-2xl);
}

.stat__hint {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.stat__trend {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: 2px var(--sp-2);
    border-radius: var(--radius-pill);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
}

.stat__trend svg {
    width: 13px;
    height: 13px;
}

.stat__trend--up {
    background: var(--success-soft);
    color: var(--success-text);
}

.stat__trend--down {
    background: var(--danger-soft);
    color: var(--danger-text);
}

.stat__trend--flat {
    background: var(--surface-muted);
    color: var(--text-muted);
}

/* Tones: drive --stat-accent / --stat-soft from the token palette. */
.stat--primary { --stat-accent: var(--primary); --stat-soft: var(--primary-soft); }
.stat--success { --stat-accent: var(--success); --stat-soft: var(--success-soft); }
.stat--warning { --stat-accent: var(--warning); --stat-soft: var(--warning-soft); }
.stat--danger  { --stat-accent: var(--danger);  --stat-soft: var(--danger-soft); }
.stat--info    { --stat-accent: var(--info);    --stat-soft: var(--info-soft); }
.stat--accent  { --stat-accent: var(--accent);  --stat-soft: var(--accent-soft); }
.stat--neutral { --stat-accent: var(--text-muted); --stat-soft: var(--surface-muted); }

.stat--warning::before {
    background: var(--warning);
}
/* ==========================================================================
   3. Badges, chips, alerts, toasts, avatars, progress, empty & loading states
   ========================================================================== */

/* ---------- Badges: semantic AND described by text (never colour alone) ---------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: 3px var(--sp-2);
    border: 1px solid var(--neutral-border);
    border-radius: var(--radius-pill);
    background: var(--neutral-soft);
    color: var(--neutral-text);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
    line-height: 1.5;
    white-space: nowrap;
}

.badge svg {
    width: 13px;
    height: 13px;
    flex: 0 0 auto;
}

.badge--success { background: var(--success-soft); border-color: var(--success-border); color: var(--success-text); }
.badge--warning { background: var(--warning-soft); border-color: var(--warning-border); color: var(--warning-text); }
.badge--danger  { background: var(--danger-soft);  border-color: var(--danger-border);  color: var(--danger-text); }
.badge--info    { background: var(--info-soft);    border-color: var(--info-border);    color: var(--info-text); }
.badge--accent  { background: var(--accent-soft);  border-color: var(--accent-border);  color: var(--accent-text); }
.badge--brand   { background: var(--primary-soft); border-color: var(--primary-soft-border); color: var(--primary); }
.badge--neutral { background: var(--neutral-soft); border-color: var(--neutral-border);  color: var(--neutral-text); }

.badge--solid {
    border-color: transparent;
}

.badge--solid.badge--success { background: var(--success); color: #fff; }
.badge--solid.badge--danger  { background: var(--danger);  color: #fff; }
.badge--solid.badge--warning { background: var(--warning); color: #fff; }
.badge--solid.badge--brand   { background: var(--primary); color: var(--primary-contrast); }

[data-theme="dark"] .badge--solid { color: #0b1220; }

.badge--dot::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

/* ---------- Chips / pills for filters and meta information ---------- */
.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-1) var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--text-2);
    font-size: var(--fs-sm);
    text-decoration: none;
}

.chip svg {
    width: 14px;
    height: 14px;
}

.chip--active {
    background: var(--primary-soft);
    border-color: var(--primary-soft-border);
    color: var(--primary);
    font-weight: var(--fw-semibold);
}

/* ---------- Alerts ---------- */
.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-4);
    border: 1px solid var(--neutral-border);
    border-radius: var(--radius-md);
    background: var(--neutral-soft);
    color: var(--neutral-text);
    font-size: var(--fs-base);
}

.alert svg {
    width: 19px;
    height: 19px;
    flex: 0 0 auto;
    margin-block-start: 1px;
}

.alert__body {
    flex: 1 1 auto;
    min-width: 0;
}

.alert__title {
    font-weight: var(--fw-semibold);
    margin-block-end: 2px;
}

.alert__list {
    margin: var(--sp-2) 0 0;
    padding-inline-start: var(--sp-5);
}

.alert__close {
    border: 0;
    background: transparent;
    color: inherit;
    opacity: 0.65;
    cursor: pointer;
    padding: 2px;
    border-radius: var(--radius-xs);
}

.alert__close:hover {
    opacity: 1;
}

.alert--success { background: var(--success-soft); border-color: var(--success-border); color: var(--success-text); }
.alert--warning { background: var(--warning-soft); border-color: var(--warning-border); color: var(--warning-text); }
.alert--danger  { background: var(--danger-soft);  border-color: var(--danger-border);  color: var(--danger-text); }
.alert--info    { background: var(--info-soft);    border-color: var(--info-border);    color: var(--info-text); }
/* ---------- Toast region (rendered from Django messages) ---------- */
.toast-region {
    position: fixed;
    z-index: var(--z-toast);
    inset-block-start: calc(var(--appbar-h) + var(--sp-3));
    inset-inline-end: var(--sp-5);
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    width: min(400px, calc(100vw - var(--sp-8)));
    pointer-events: none;
}

.toast-region .alert {
    pointer-events: auto;
    box-shadow: var(--shadow-lg);
    background: var(--surface);
    color: var(--text);
    animation: toast-in var(--dur-slow) var(--ease);
}

.toast-region .alert--success { border-inline-start: 4px solid var(--success); }
.toast-region .alert--danger  { border-inline-start: 4px solid var(--danger); }
.toast-region .alert--warning { border-inline-start: 4px solid var(--warning); }
.toast-region .alert--info    { border-inline-start: 4px solid var(--info); }

.toast-region .alert--success svg { color: var(--success); }
.toast-region .alert--danger svg  { color: var(--danger); }
.toast-region .alert--warning svg { color: var(--warning); }
.toast-region .alert--info svg    { color: var(--info); }

.toast-region .alert.is-hiding {
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translateY(-10px) scale(0.98);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@media (max-width: 640px) {
    .toast-region {
        inset-inline: var(--sp-4);
        width: auto;
    }
}

/* ---------- Avatar ---------- */
.avatar {
    display: inline-grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: var(--radius-pill);
    background: var(--primary-soft);
    color: var(--primary);
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    overflow: hidden;
    flex: 0 0 auto;
    border: 1px solid var(--primary-soft-border);
}

.avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar--lg {
    width: 64px;
    height: 64px;
    font-size: var(--fs-xl);
}

.avatar--xl {
    width: 84px;
    height: 84px;
    font-size: var(--fs-2xl);
}

.avatar--sm {
    width: 30px;
    height: 30px;
    font-size: var(--fs-2xs);
}

.avatar--success { background: var(--success-soft); color: var(--success-text); border-color: var(--success-border); }
.avatar--accent  { background: var(--accent-soft);  color: var(--accent-text);  border-color: var(--accent-border); }

.person {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    min-width: 0;
}

.person__name {
    display: block;
    font-weight: var(--fw-semibold);
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.person__meta {
    display: block;
    font-size: var(--fs-xs);
    color: var(--text-muted);
}

/* ---------- Progress ---------- */
.progress {
    position: relative;
    height: 8px;
    width: 100%;
    border-radius: var(--radius-pill);
    background: var(--surface-muted);
    overflow: hidden;
}

.progress__bar {
    height: 100%;
    border-radius: inherit;
    background: var(--primary);
    transition: width var(--dur-slow) var(--ease);
}

.progress__bar--success { background: var(--success); }
.progress__bar--warning { background: var(--warning); }
.progress__bar--danger  { background: var(--danger); }

.progress-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    margin-block-end: var(--sp-2);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

/* ---------- Empty state ---------- */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--sp-3);
    padding: var(--sp-9) var(--sp-5);
    color: var(--text-muted);
}

.empty-state__icon {
    display: grid;
    place-items: center;
    width: 60px;
    height: 60px;
    border-radius: var(--radius-pill);
    background: var(--primary-soft);
    color: var(--primary);
    margin-block-end: var(--sp-1);
}

.empty-state__icon svg {
    width: 28px;
    height: 28px;
}

.empty-state__title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
    color: var(--text);
}

.empty-state__text {
    max-width: 46ch;
    font-size: var(--fs-base);
    line-height: var(--lh-normal);
}

.empty-state--compact {
    padding: var(--sp-7) var(--sp-4);
}

.empty-state--inline {
    padding: var(--sp-6) var(--sp-4);
    border: 1px dashed var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

/* ---------- Skeleton loading ---------- */
.skeleton {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-sm);
    background: var(--surface-muted);
    min-height: 14px;
}

.skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
    animation: shimmer 1.4s infinite;
}

[data-theme="dark"] .skeleton::after {
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.07), transparent);
}

@keyframes shimmer {
    100% {
        transform: translateX(100%);
    }
}

.skeleton--text { height: 12px; }
.skeleton--title { height: 20px; width: 40%; }
.skeleton--block { height: 120px; }
/* ==========================================================================
   4. Tables — readable, scannable, and usable on small screens
   ========================================================================== */

.table-wrap {
    width: 100%;
    overflow-x: auto;
    border-radius: inherit;
    -webkit-overflow-scrolling: touch;
}

.table-wrap--bordered {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
}

.table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--fs-base);
}

.table caption {
    caption-side: top;
    padding: var(--sp-3) var(--sp-5);
    text-align: start;
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.table th,
.table td {
    padding: var(--sp-3) var(--sp-4);
    text-align: start;
    vertical-align: middle;
}

.table thead th {
    position: relative;
    padding-block: var(--sp-3);
    border-block-end: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
    white-space: nowrap;
}

.table thead th:first-child {
    border-start-start-radius: var(--radius-lg);
}

.table thead th:last-child {
    border-start-end-radius: var(--radius-lg);
}

.table tbody tr {
    transition: background var(--dur-fast) var(--ease);
}

.table tbody tr + tr td {
    border-block-start: 1px solid var(--border-subtle);
}

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

.table tbody tr.is-selected {
    background: var(--primary-soft);
}

.table tbody td {
    height: var(--row-h);
    color: var(--text-2);
}

.table tbody td strong,
.table tbody td .cell-strong {
    color: var(--text);
    font-weight: var(--fw-semibold);
}

/* Row modifiers */
.table tr.is-muted td {
    color: var(--text-muted);
}

.table tr.is-danger td {
    background: color-mix(in srgb, var(--danger-soft) 55%, transparent);
}

.table tr.is-warning td {
    background: color-mix(in srgb, var(--warning-soft) 55%, transparent);
}

/* Cell helpers */
.table .col-index {
    width: 72px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.table .col-actions {
    width: 1%;
    white-space: nowrap;
    text-align: end;
}

.table .num,
.table .money {
    text-align: end;
    font-variant-numeric: tabular-nums;
}

.table__empty td {
    padding: 0;
    height: auto;
}

/* Sticky header for long tables inside a scrolling viewport */
.table--sticky thead th {
    position: sticky;
    inset-block-start: 0;
    z-index: 2;
}

/* Dense variant for high row counts */
.table--dense tbody td {
    height: var(--row-h-dense);
    padding-block: var(--sp-2);
}

/* Totals / summary row */
.table tfoot td {
    padding: var(--sp-3) var(--sp-4);
    border-block-start: 2px solid var(--border);
    background: var(--surface-2);
    font-weight: var(--fw-semibold);
    color: var(--text);
}

/* Row actions */
.row-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    justify-content: flex-end;
}

.action-link {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-1) var(--sp-2);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    color: var(--primary);
    text-decoration: none;
    transition: background var(--dur-fast) var(--ease);
}

.action-link svg {
    width: 15px;
    height: 15px;
}

.action-link:hover {
    background: var(--primary-soft);
    text-decoration: none;
}

.action-link--muted {
    color: var(--text-muted);
}

.action-link--muted:hover {
    background: var(--surface-muted);
    color: var(--text);
}

.action-link--danger {
    color: var(--danger);
}

.action-link--danger:hover {
    background: var(--danger-soft);
    color: var(--danger-text);
}

/* ---------- Mobile: turn wide tables into readable cards ---------- */
@media (max-width: 720px) {
    .table-responsive thead {
        display: none;
    }

    .table-responsive,
    .table-responsive tbody,
    .table-responsive tr,
    .table-responsive td {
        display: block;
        width: 100%;
    }

    .table-responsive tbody tr {
        padding: var(--sp-3) var(--sp-4);
        border-block-start: 1px solid var(--border-subtle);
    }

    .table-responsive tbody tr:first-child {
        border-block-start: 0;
    }

    .table-responsive tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--sp-4);
        height: auto;
        padding: var(--sp-2) 0;
        border: 0 !important;
        text-align: end;
    }

    .table-responsive tbody td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: var(--fs-xs);
        font-weight: var(--fw-semibold);
        letter-spacing: var(--ls-wide);
        text-transform: uppercase;
        color: var(--text-muted);
        text-align: start;
    }

    .table-responsive .col-actions {
        width: auto;
    }

    .table-responsive .table__empty td {
        display: block;
        text-align: center;
    }

    .table-responsive .table__empty td::before {
        content: none;
    }
}
/* ==========================================================================
   5. Toolbar, filter bar, search, tabs, pagination
   ========================================================================== */
.toolbar {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-block-end: var(--sp-5);
}

.toolbar--end {
    justify-content: flex-end;
}

.toolbar__spacer {
    flex: 1 1 auto;
}

/* Student card: printable, lamination-friendly */
.student-card {
    max-width: 420px;
    padding: var(--sp-4);
}
.student-card__brand {
    display: flex;
    flex-direction: column;
    border-block-end: 1px solid var(--border);
    padding-block-end: var(--sp-2);
    margin-block-end: var(--sp-3);
}
.student-card__body {
    display: flex;
    gap: var(--sp-3);
    align-items: center;
}
.student-card__photo {
    width: 84px;
    height: 84px;
    object-fit: cover;
    border-radius: var(--radius-lg);
}
.student-card__name {
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
    margin: 0;
}
.student-card__code {
    font-weight: var(--fw-semibold);
    margin: 0;
}
.student-card__barcode {
    margin-block-start: var(--sp-3);
    text-align: center;
}
.student-card__barcode img {
    max-width: 100%;
    height: 72px;
}
@media print {
    .app-bar, .page-header__actions, .form-actions, .breadcrumbs {
        display: none !important;
    }
    .receipt, .student-card {
        box-shadow: none;
        border: 1px solid #000;
    }
}
.filter-bar {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-3);
    flex-wrap: wrap;
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    margin-block-end: var(--sp-3);
}

.filter-bar__group {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 150px;
}

.filter-bar__group--grow {
    flex: 1 1 260px;
}

.filter-bar__label {
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--text-muted);
}

.filter-bar__actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin-inline-start: auto;
}

.filter-summary {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-block-end: var(--sp-4);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

/* Segmented control (Day / Week / Month, task views) */
.segmented {
    display: inline-flex;
    align-items: center;
    padding: 3px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    gap: 2px;
}

.segmented__item {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radius-sm);
    color: var(--text-2);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.segmented__item:hover {
    background: var(--surface-muted);
    color: var(--text);
    text-decoration: none;
}

.segmented__item.is-active {
    background: var(--surface);
    color: var(--primary);
    font-weight: var(--fw-semibold);
    box-shadow: var(--shadow-xs);
}

/* Tabs */
.tabs {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    border-block-end: 1px solid var(--border);
    overflow-x: auto;
}

.tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4);
    color: var(--text-muted);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    text-decoration: none;
    white-space: nowrap;
}

.tab:hover {
    color: var(--text);
    text-decoration: none;
}

.tab.is-active {
    color: var(--primary);
    font-weight: var(--fw-semibold);
}

.tab.is-active::after {
    content: "";
    position: absolute;
    inset-block-end: -1px;
    inset-inline: var(--sp-2);
    height: 2px;
    border-radius: var(--radius-pill);
    background: var(--primary);
}

.tab__count {
    padding: 0 var(--sp-2);
    border-radius: var(--radius-pill);
    background: var(--surface-muted);
    color: var(--text-muted);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
}

.tab.is-active .tab__count {
    background: var(--primary-soft);
    color: var(--primary);
}

/* ---------- Pagination ---------- */
.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
    padding: var(--sp-4) var(--sp-5);
    border-block-start: 1px solid var(--border-subtle);
    background: var(--surface-2);
}

.pagination__info {
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.pagination__list {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    list-style: none;
    margin: 0;
    padding: 0;
}

.pagination__link {
    display: inline-grid;
    place-items: center;
    min-width: 36px;
    height: 36px;
    padding-inline: var(--sp-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-2);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    text-decoration: none;
    transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
        border-color var(--dur-fast) var(--ease);
}

.pagination__link svg {
    width: 16px;
    height: 16px;
}

/* Directional arrows must follow the reading direction. */
html[dir="rtl"] .pagination__link svg {
    transform: scaleX(-1);
}

.pagination__link:hover {
    background: var(--surface-muted);
    border-color: var(--border-strong);
    color: var(--text);
    text-decoration: none;
}

.pagination__link.is-current {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--primary-contrast);
    font-weight: var(--fw-semibold);
}

.pagination__link.is-disabled {
    opacity: 0.45;
    pointer-events: none;
}

.pagination__ellipsis {
    padding-inline: var(--sp-2);
    color: var(--text-faint);
}

/* In RTL the "previous"/"next" chevrons must point the other way. */
html[dir="rtl"] .icon-flip {
    transform: scaleX(-1);
}
/* ==========================================================================
   6. Forms — labels, controls, validation, grouped layouts
   ========================================================================== */
.field {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 0;
}

.field__label {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    color: var(--text-2);
}

.field__required {
    color: var(--danger);
    font-weight: var(--fw-bold);
}

.field__help {
    font-size: var(--fs-xs);
    color: var(--text-muted);
    line-height: var(--lh-snug);
}

.field__error {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-1);
    font-size: var(--fs-xs);
    font-weight: var(--fw-medium);
    color: var(--danger-text);
}

.field__error svg {
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
    margin-block-start: 1px;
}

.field--invalid .form-control,
.field--invalid .form-select {
    border-color: var(--danger);
}

.field--invalid .form-control:focus,
.field--invalid .form-select:focus {
    box-shadow: var(--focus-ring-danger);
}

/* ---------- Controls ---------- */
.form-control,
.form-select,
textarea.form-control {
    width: 100%;
    min-height: var(--control-h);
    padding: var(--sp-2) var(--control-px);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs-base);
    line-height: 1.5;
    transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease),
        background var(--dur-fast) var(--ease);
    appearance: none;
}

.form-control::placeholder {
    color: var(--text-faint);
}

.form-control:hover:not(:disabled),
.form-select:hover:not(:disabled) {
    border-color: var(--text-faint);
}

.form-control:focus,
.form-select:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: var(--focus-ring);
}

.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
    background: var(--surface-muted);
    color: var(--text-muted);
    cursor: not-allowed;
}

textarea.form-control {
    min-height: 104px;
    padding-block: var(--sp-3);
    resize: vertical;
}

.form-select {
    padding-inline-end: var(--sp-7);
    background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
        linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
    background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    cursor: pointer;
}

html[dir="rtl"] .form-select {
    background-position: 13px 50%, 18px 50%;
}

.form-select option {
    background: var(--surface);
    color: var(--text);
}

.form-control--sm,
.form-select--sm {
    min-height: var(--control-h-sm);
    font-size: var(--fs-sm);
}

.form-control--invalid {
    border-color: var(--danger);
}

/* Date/time inputs: keep the native picker legible in dark mode. */
[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator {
    filter: invert(1) opacity(0.7);
}

input[type="file"].form-control {
    padding-block: var(--sp-2);
    font-size: var(--fs-sm);
}

input[type="file"].form-control::file-selector-button {
    margin-inline-end: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-2);
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    cursor: pointer;
}
/* ---------- Search input with icon ---------- */
.search {
    position: relative;
    flex: 1 1 240px;
    min-width: 0;
}

/* The flex-basis above is written for a ROW parent, where it sets the width.
   Inside .filter-bar__group -- a column -- the same basis set the HEIGHT, so
   the search box stretched to 240px and blew the filter bar open. The group
   already stretches children across the full width, so resetting the basis to
   auto is enough: the box becomes as tall as its input, in both directions. */
.filter-bar__group > .search {
    flex: 1 1 auto;
    min-width: 0;
}

.search svg {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: var(--sp-3);
    width: 17px;
    height: 17px;
    transform: translateY(-50%);
    color: var(--text-faint);
    pointer-events: none;
}

.search .form-control {
    padding-inline-start: calc(var(--sp-3) * 2 + 17px);
}

/* ---------- Checkbox & radio ---------- */
.check {
    display: inline-flex;
    align-items: flex-start;
    gap: var(--sp-2);
    font-size: var(--fs-base);
    color: var(--text-2);
    cursor: pointer;
}

.check input[type="checkbox"],
.check input[type="radio"] {
    width: 17px;
    height: 17px;
    margin: 2px 0 0;
    accent-color: var(--primary);
    cursor: pointer;
    flex: 0 0 auto;
}

/* ---------- Switch ---------- */
.switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-3);
    cursor: pointer;
}

.switch input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.switch__track {
    position: relative;
    width: 40px;
    height: 22px;
    border-radius: var(--radius-pill);
    background: var(--border-strong);
    transition: background var(--dur) var(--ease);
    flex: 0 0 auto;
}

.switch__track::after {
    content: "";
    position: absolute;
    inset-block-start: 3px;
    inset-inline-start: 3px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: var(--shadow-xs);
    transition: transform var(--dur) var(--ease);
}

.switch input:checked + .switch__track {
    background: var(--primary);
}

.switch input:checked + .switch__track::after {
    transform: translateX(18px);
}

html[dir="rtl"] .switch input:checked + .switch__track::after {
    transform: translateX(-18px);
}

.switch input:focus-visible + .switch__track {
    box-shadow: var(--focus-ring);
}

/* ---------- Form layout: sections, grid, actions ---------- */
.form-grid {
    display: grid;
    gap: var(--sp-5);
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.form-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.form-grid .span-2 {
    grid-column: span 2;
}

@media (max-width: 860px) {
    .form-grid,
    .form-grid--3 {
        grid-template-columns: minmax(0, 1fr);
    }

    .form-grid .span-2 {
        grid-column: auto;
    }
}

.form-section {
    padding: var(--sp-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
}

.form-section__header {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    margin-block-end: var(--sp-5);
    padding-block-end: var(--sp-4);
    border-block-end: 1px solid var(--border-subtle);
}

.form-section__icon {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    background: var(--primary-soft);
    color: var(--primary);
    flex: 0 0 auto;
}

.form-section__icon svg {
    width: 18px;
    height: 18px;
}

.form-section__title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
}

.form-section__hint {
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.form-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    padding: var(--sp-4) 0;
}

.form-actions--sticky {
    position: sticky;
    inset-block-end: 0;
    z-index: 5;
    margin-block-start: var(--sp-6);
    padding: var(--sp-4) var(--sp-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-md);
}

.form-actions__hint {
    margin-inline-start: auto;
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

@media (max-width: 640px) {
    .form-actions,
    .form-actions--sticky {
        flex-direction: column-reverse;
        align-items: stretch;
    }

    .form-actions .btn {
        width: 100%;
    }

    .form-actions__hint {
        margin-inline-start: 0;
        text-align: center;
    }
}

/* ---------- Validation summary ---------- */
.form-summary {
    display: flex;
    gap: var(--sp-3);
    padding: var(--sp-4);
    border: 1px solid var(--danger-border);
    border-radius: var(--radius-md);
    background: var(--danger-soft);
    color: var(--danger-text);
    margin-block-end: var(--sp-5);
}

.form-summary svg {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
}

.form-summary ul {
    margin: var(--sp-2) 0 0;
    padding-inline-start: var(--sp-5);
}

.form-summary a {
    color: inherit;
    text-decoration: underline;
}
/* ==========================================================================
   7. Modal, descriptions, timeline, list items
   ========================================================================== */

/* ---------- Modal (<dialog>) ---------- */
.modal {
    width: min(560px, calc(100vw - var(--sp-6)));
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-lg);
}

.modal::backdrop {
    background: var(--surface-overlay);
}

.modal[open] {
    animation: modal-in var(--dur-slow) var(--ease);
}

@keyframes modal-in {
    from {
        opacity: 0;
        transform: translateY(12px) scale(0.98);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.modal__header {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-5);
    border-block-end: 1px solid var(--border-subtle);
}

.modal__title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
}

.modal__body {
    padding: var(--sp-5);
    color: var(--text-2);
}

.modal__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--sp-3);
    padding: var(--sp-4) var(--sp-5);
    border-block-start: 1px solid var(--border-subtle);
    background: var(--surface-2);
}

/* ---------- Description / key-value lists ---------- */
.kv {
    display: grid;
    gap: var(--sp-4) var(--sp-6);
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    margin: 0;
}

.kv__item {
    min-width: 0;
}

.kv__label {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    margin-block-end: var(--sp-1);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--text-muted);
}

.kv__label svg {
    width: 14px;
    height: 14px;
}

.kv__value {
    font-size: var(--fs-md);
    color: var(--text);
    word-break: break-word;
}

.kv--stacked {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-4);
}

/* ---------- Timeline (level history, audit trails) ---------- */
.timeline {
    position: relative;
    list-style: none;
    margin: 0;
    padding-inline-start: var(--sp-6);
}

.timeline::before {
    content: "";
    position: absolute;
    inset-block: 6px;
    inset-inline-start: 7px;
    width: 2px;
    background: var(--border);
}

.timeline__item {
    position: relative;
    padding-block-end: var(--sp-5);
}

.timeline__item:last-child {
    padding-block-end: 0;
}

.timeline__dot {
    position: absolute;
    inset-block-start: 3px;
    inset-inline-start: calc(var(--sp-6) * -1);
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 3px solid var(--surface);
    background: var(--primary);
    box-shadow: 0 0 0 1px var(--border);
}

.timeline__dot--success { background: var(--success); }
.timeline__dot--warning { background: var(--warning); }
.timeline__dot--muted   { background: var(--text-faint); }

.timeline__title {
    font-weight: var(--fw-semibold);
    color: var(--text);
}

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

.timeline__body {
    margin-block-start: var(--sp-1);
    font-size: var(--fs-base);
    color: var(--text-2);
}

/* ---------- List items (notifications, tasks, upcoming lessons) ---------- */
.list {
    display: flex;
    flex-direction: column;
    list-style: none;
    margin: 0;
    padding: 0;
}

.list__item {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-4);
    padding: var(--sp-4) var(--sp-5);
    border-block-start: 1px solid var(--border-subtle);
    transition: background var(--dur-fast) var(--ease);
}

.list__item:first-child {
    border-block-start: 0;
}

.list__item:hover {
    background: var(--surface-2);
}

.list__item--unread {
    background: var(--primary-soft);
    box-shadow: inset 3px 0 0 var(--primary);
}

html[dir="rtl"] .list__item--unread {
    box-shadow: inset -3px 0 0 var(--primary);
}

.list__icon {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    background: var(--surface-muted);
    color: var(--text-2);
    flex: 0 0 auto;
}

.list__icon svg {
    width: 18px;
    height: 18px;
}

.list__icon--primary { background: var(--primary-soft); color: var(--primary); }
.list__icon--success { background: var(--success-soft); color: var(--success-text); }
.list__icon--warning { background: var(--warning-soft); color: var(--warning-text); }
.list__icon--danger  { background: var(--danger-soft);  color: var(--danger-text); }
.list__icon--accent  { background: var(--accent-soft);  color: var(--accent-text); }

.list__main {
    flex: 1 1 auto;
    min-width: 0;
}

.list__title {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    font-weight: var(--fw-semibold);
    color: var(--text);
}

.list__text {
    margin-block-start: 2px;
    font-size: var(--fs-base);
    color: var(--text-2);
}

.list__meta {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-block-start: var(--sp-2);
    font-size: var(--fs-xs);
    color: var(--text-muted);
}

.list__meta svg {
    width: 14px;
    height: 14px;
}
/* ==========================================================================
   8. Charts (SVG rendered by static/js/charts.js) and the schedule calendar
   ========================================================================== */
.chart {
    position: relative;
    width: 100%;
}

.chart svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

.chart__grid line {
    stroke: var(--chart-grid);
    stroke-width: 1;
}

.chart__axis text {
    fill: var(--chart-axis);
    font-size: 11px;
    font-family: var(--font-sans);
}

.chart__bar {
    transition: opacity var(--dur-fast) var(--ease);
}

.chart__bar:hover {
    opacity: 0.82;
}

.chart__line {
    fill: none;
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.chart__area {
    opacity: 0.14;
}

.chart__legend {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-block-start: var(--sp-4);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.chart__legend-item {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
}

.chart__swatch {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--primary);
    flex: 0 0 auto;
}

.chart__empty {
    display: grid;
    place-items: center;
    min-height: 200px;
    padding: var(--sp-5);
    border: 1px dashed var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: var(--fs-sm);
    text-align: center;
}

.chart--donut {
    display: flex;
    align-items: center;
    gap: var(--sp-6);
    flex-wrap: wrap;
}

.chart--donut svg {
    width: 180px;
    height: 180px;
    flex: 0 0 auto;
}

/* Accessible data table that stays available behind every chart. */
.chart__data {
    width: 100%;
    border-collapse: collapse;
    margin-block-start: var(--sp-3);
    font-size: var(--fs-sm);
}

.chart__data th,
.chart__data td {
    padding: var(--sp-2) var(--sp-3);
    text-align: start;
    border-block-end: 1px solid var(--border-subtle);
}

.chart__data th {
    color: var(--text-muted);
    font-weight: var(--fw-semibold);
}

/* ---------- Calendar (month grid + day/week lists) ---------- */
.calendar {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.calendar__head {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    background: var(--surface-2);
    border-block-end: 1px solid var(--border);
}

.calendar__weekday {
    padding: var(--sp-3) var(--sp-2);
    text-align: center;
    font-size: var(--fs-xs);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--text-muted);
}

.calendar__grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
}

.calendar__day {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 0;
    min-height: 118px;
    padding: var(--sp-2);
    border-block-start: 1px solid var(--border-subtle);
    border-inline-start: 1px solid var(--border-subtle);
}

.calendar__grid > .calendar__day:nth-child(7n + 1) {
    border-inline-start: 0;
}

.calendar__day--muted {
    background: var(--surface-2);
}

.calendar__day--muted .calendar__date {
    color: var(--text-faint);
}

.calendar__day--today {
    background: var(--primary-soft);
}

.calendar__date {
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
}

.calendar__day--today .calendar__date {
    display: inline-grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--primary);
    color: var(--primary-contrast);
}

.calendar__events {
    display: flex;
    flex-direction: column;
    gap: 3px;
    list-style: none;
    margin: 0;
    padding: 0;
    min-width: 0;
}

.calendar__event {
    display: block;
    padding: 3px var(--sp-2);
    border-inline-start: 3px solid var(--chart-1);
    border-radius: var(--radius-sm);
    background: var(--surface-muted);
    color: var(--text-2);
    font-size: var(--fs-xs);
    line-height: 1.35;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.calendar__event:hover {
    background: var(--primary-soft);
    color: var(--text);
    text-decoration: none;
}

.calendar__event-time {
    font-weight: var(--fw-semibold);
    font-variant-numeric: tabular-nums;
}

.calendar__event--group { border-inline-start-color: var(--chart-1); }
.calendar__event--private { border-inline-start-color: var(--chart-2); }
.calendar__event--workshop { border-inline-start-color: var(--chart-6); }
.calendar__event--exam { border-inline-start-color: var(--chart-4); }
.calendar__event--assessment { border-inline-start-color: var(--chart-5); }
.calendar__event--cancelled {
    opacity: 0.65;
    text-decoration: line-through;
}

.calendar__more {
    font-size: var(--fs-2xs);
    color: var(--text-muted);
    padding-inline: var(--sp-2);
}

.calendar-scroll {
    overflow-x: auto;
}

.calendar-scroll .calendar {
    min-width: 780px;
}

/* Reading paragraph shown on placement recording and review screens. The
   English text is explicitly LTR in the markup, so this keeps the accent on
   the block's leading edge in either interface direction. */
.placement-text {
    margin: 0;
    padding: var(--sp-4) var(--sp-5);
    border-inline-start: 4px solid var(--primary-soft-border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-md);
    line-height: var(--lh-normal);
}

.placement-text p {
    margin: 0;
}

.placement-text p + p {
    margin-block-start: var(--sp-3);
}

/* ---------- Misc ---------- */
/* Icon sizing for {% icon %}. The SVG inherits colour from currentColor, so a
   tone change on the parent recolours the glyph without touching markup. */
svg.icon {
    width: 1.25rem;
    height: 1.25rem;
    fill: currentColor;
    vertical-align: middle;
    flex: 0 0 auto;
}

svg.icon-md { width: 1.5rem; height: 1.5rem; }
svg.icon-lg { width: 2rem; height: 2rem; }
svg.icon-sm { width: 1rem; height: 1rem; }
svg.icon-xs { width: 0.875rem; height: 0.875rem; }

.divider {
    height: 1px;
    margin: var(--sp-5) 0;
    border: 0;
    background: var(--border-subtle);
}

.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
}

/* ==========================================================================
   RTL
   The whole stylesheet is written with logical properties, so these are the
   only physical-direction exceptions left. They are listed in one place with
   a reason, rather than sprinkled through each component.
   ========================================================================== */

/* Directional arrows (pagination, breadcrumbs, back links) must follow the
   reading direction, so the same glyph is mirrored. */
html[dir="rtl"] .pagination__link svg,
html[dir="rtl"] .breadcrumbs li + li::before,
html[dir="rtl"] .stat__hint svg,
html[dir="rtl"] .action-link .icon-flip {
    transform: scaleX(-1);
}

/* The unread marker is a leading edge stripe; it belongs on the right in RTL. */
html[dir="rtl"] .list__item--unread {
    border-inline-start: 0;
    border-inline-end: 3px solid var(--primary);
}

/* A native <select> draws its arrow on the physical left. */
html[dir="rtl"] .form-select {
    background-position: left 0.75rem center;
    padding-inline-start: var(--sp-3);
    padding-inline-end: 2rem;
}

/* A switch is a physical track, so the knob has to travel the other way. */
html[dir="rtl"] .switch input:checked + .switch__track::after {
    transform: translateX(-100%);
}
