/**
 * Student attendance + rank panels (profile.html).
 *
 * DESIGN CONSTRAINTS BAKED INTO THIS FILE — read before editing:
 *
 * 1. NO `opacity` on any ancestor of text. Rendered contrast is
 *    (opacity x source) + ((1 - opacity) x background), which cannot clear
 *    WCAG 4.5:1 below roughly 0.85 on these surfaces. De-emphasis uses the
 *    theme-aware `--text-secondary` / `--text-tertiary` tokens instead.
 *
 * 2. Only BASE `--accent-*` tokens. `--accent-success-bright` (#22c55e) has NO
 *    `[data-theme="light"]` override and measures about 2:1 on white — invisible
 *    in a dark-only screenshot, a 1.4.3/1.4.11 failure the moment anyone toggles
 *    light theme. `--accent-success` flips (#10b981 dark, #0F7B3F light).
 *
 * 3. Everything sizes in `rem` so a 200% browser text zoom scales the rings and
 *    the numerals together. A fixed-px ring around a rem numeral tears apart at
 *    zoom; an SVG <text> would not scale at all (SC 1.4.4).
 *
 * 4. Every flex/grid child that holds text carries `min-width: 0`. A flex item's
 *    initial `min-width: auto` is a hard floor that refuses to shrink, which is
 *    what pushes a control off a 320px viewport.
 */

.sa-panels {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 20px 0;
}

.sa-panel {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    padding: 16px;
    min-width: 0;
}

.sa-panel__title {
    margin: 0 0 12px;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.sa-panel p {
    margin: 0;
}

/* ── Panel 1 — Rank ─────────────────────────────────────────────────────── */

.sa-rank__belt {
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 8px;
}

.sa-stripes {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}

/* A stripe slot is a physical thing on a belt, so it stays a fixed-ish bar —
   but it is `aria-hidden` decoration; the awarded/pending COUNTS are stated in
   text below it, so nothing is conveyed by shape or colour alone (SC 1.4.1). */
.sa-stripe {
    width: 14px;
    height: 26px;
    border-radius: 3px;
    background: transparent;
    border: 1px solid var(--border-medium);
}

.sa-stripe--awarded {
    background: var(--accent-success);
    border-color: var(--accent-success);
}

/* Earned-but-not-yet-awarded: deliberately a DIFFERENT treatment (dashed
   outline, unfilled), never a lighter fill — a student must not read "pending"
   as "you have this". */
.sa-stripe--pending {
    background: transparent;
    border: 2px dashed var(--accent-warning);
}

.sa-rank__awarded {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.sa-rank__pending {
    margin-top: 4px;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--accent-warning);
}

.sa-rank__track {
    position: relative;
    margin: 12px 0 8px;
    height: 10px;
    border-radius: 999px;
    background: var(--bg-hover);
    overflow: hidden;
}

.sa-rank__fill {
    height: 100%;
    max-width: 100%;
    border-radius: 999px;
    background: var(--accent);
}

.sa-rank__count {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.sa-rank__caption,
.sa-rank__review {
    margin-top: 4px;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

/* THE READY STATE IS COMMON, NOT AN EDGE CASE. `classes_required` is the total
   for the WHOLE belt (classes_per_stripe x stripes_required), so a long-tenured
   student sits here routinely — it gets the same design care as the counting-up
   state. `--accent-success-light` is used for the tint because it, unlike
   `--accent-success-bright`, DOES carry a [data-theme="light"] override. */
.sa-rank--ready {
    border-color: var(--accent-success);
    background:
        linear-gradient(var(--accent-success-light), var(--accent-success-light)),
        var(--bg-elevated);
}

.sa-rank__fill--ready {
    background: var(--accent-success);
}

.sa-rank__ready {
    font-size: 1rem;
    font-weight: 700;
    color: var(--accent-success);
}

.sa-rank__prompt {
    font-size: 0.9375rem;
    color: var(--text-secondary);
    margin-bottom: 10px;
}

.sa-rank__prompt-action {
    min-height: 44px;
    padding: 10px 16px;
    border: 1px solid var(--accent);
    border-radius: 8px;
    background: var(--accent);
    color: var(--text-on-accent);
    font-size: 0.9375rem;
    font-weight: 600;
    cursor: pointer;
}

/* ── Panel 2 — Check-in rings ───────────────────────────────────────────── */

.sa-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
}

.sa-tile {
    position: relative;
    flex: 1 1 8rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}

.sa-tile__ring {
    display: block;
    width: 5rem;
    height: 5rem;
    transform: rotate(-90deg);
}

.sa-tile__ring-track {
    fill: none;
    stroke: var(--border-medium);
    stroke-width: 6;
}

.sa-tile__ring-arc {
    fill: none;
    stroke: var(--accent-success);
    stroke-width: 6;
    stroke-linecap: round;
}

/* The numeral is HTML text layered OVER the svg, not <text> inside it — SVG
   text scales with the viewBox, not with the user's font size, so it would stay
   put at 200% zoom and fail SC 1.4.4. Positioned over the ring's own box. */
.sa-tile .stat-tile__value {
    position: absolute;
    top: 2.5rem;
    left: 0;
    right: 0;
    transform: translateY(-50%);
    text-align: center;
    pointer-events: none;
}

.sa-tile__number {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-primary);
}

.sa-tile__caption {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 0;
    text-align: center;
}

.sa-tile__label {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-primary);
}

.sa-tile__compare {
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

/* ── Panel 3 — Recent check-ins ─────────────────────────────────────────── */

.sa-recent__list,
.sa-recent__rows {
    list-style: none;
    margin: 0;
    padding: 0;
}

.sa-recent__day + .sa-recent__day {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border-subtle);
}

.sa-recent__date {
    margin: 0 0 6px;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.sa-recent__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    padding: 4px 0;
    min-width: 0;
}

.sa-recent__name {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.9375rem;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

/* `time: null` renders an EMPTY span — never "00:00", which would claim a class
   ran at midnight. An empty slot is honest about not knowing. */
.sa-recent__time {
    flex: 0 0 auto;
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

/* ── Empty / loading / error ────────────────────────────────────────────── */

.sa-empty__headline {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--text-primary);
}

.sa-empty__detail {
    margin-top: 6px;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.sa-loading p,
.sa-error p {
    font-size: 0.9375rem;
    color: var(--text-secondary);
}

.sa-error p:first-child {
    font-weight: 600;
    color: var(--text-primary);
}

.sa-refresh-error {
    margin-top: 12px;
    padding: 12px;
    border: 1px solid var(--border-medium);
    border-radius: 10px;
    background: var(--bg-elevated);
}

.sa-refresh-error p {
    margin: 0 0 8px;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.sa-retry {
    min-height: 44px;
    margin-top: 12px;
    padding: 10px 16px;
    border: 1px solid var(--accent);
    border-radius: 8px;
    background: var(--accent);
    color: var(--text-on-accent);
    font-size: 0.9375rem;
    font-weight: 600;
    cursor: pointer;
}

.sa-refresh-error .sa-retry {
    margin-top: 0;
}

/* Guarded — an unguarded :hover paints on tap and sticks until the next tap. */
@media (hover: hover) and (pointer: fine) {
    .sa-retry:hover {
        background: var(--accent-hover);
        border-color: var(--accent-hover);
        color: var(--bg-base);
    }
}

.sa-retry:focus-visible,
.sa-rank__prompt-action:focus-visible {
    outline: 2px solid var(--accent-text);
    outline-offset: 2px;
}

@media (max-width: 400px) {
    .sa-panel {
        padding: 14px 12px;
    }

    .sa-tiles {
        gap: 12px;
    }
}
