/*
 * Help Room — mobile-first layout layer.
 *
 * NET-NEW, FLAGGED FOR REVIEW. The platform's shared components are
 * desktop-content oriented and there is no existing mobile-first pattern to
 * reuse, so these are NEW LAYOUT classes (a phone-first screen container, a
 * compact status strip, an action bar). They do NOT override shared components
 * — forms (.form-group), buttons (.btn), badges (.status-badge), and cards
 * (.section-card) are reused as-is. All colors and design tokens come only
 * from theme-consolidated.css (no hardcodes, no fallbacks).
 *
 * Mobile-first: base rules target the phone; min-width queries enhance upward.
 */

/* Landing hero page (body.template-helproom-landing, set by landing.html):
   the full-bleed .home-hero sits flush under the site header (zero the content
   wrapper's top padding, like the home/courses landings) and its
   ~scrollbar-width `width: 100vw` overhang is clipped.

   The clip is on the CONTENT WRAPPER, not the body: clipping the body would
   propagate to the viewport and pull the full-width sticky header in. The
   wrapper contains the hero but not the header, so the header stays full-width.
   `overflow-x: clip` (not `hidden`) clips without creating a scroll container. */
body.template-helproom-landing .background-white.padding-medium-top {
    padding-top: 0;
    overflow-x: clip;
}

/* Phone-first screen: comfortable single column, centered + capped on larger
   screens so it reads like an app screen, not a stretched desktop form. */
.hr-screen {
    width: 100%;
    max-width: 40rem;
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4);
}

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

/* Avatar chip + page title, grouped on the left of the dashboard header. */
.hr-screen__heading {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
}

.hr-screen__title {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    margin: 0;
}

.hr-screen__subtitle {
    color: var(--text-secondary);
    margin: 0;
}

/* The room location line in the landing hero — stronger than the subtitle so
   "where do I go" reads at a glance. */
.hr-screen__location {
    margin: 0;
    font-weight: var(--font-weight-semibold);
}

/* A quiet one-line hint (login note, empty states) — lighter than an alert. */
.hr-screen__hint {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

/* ── Landing top zone ─────────────────────────────────────────────────────
   Mirrors the demos landing: identity + intro text on the left, the live
   status panel (a .section-card) on the right. Mobile-first: a single
   stacked column; the two-zone split arrives with width. Theme-aware —
   everything uses semantic colors on the normal page background. */
.hr-top {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4);
}

.hr-top__intro {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
    min-width: 0;
}

/* The status panel reuses .section-card; this layer is layout only. */
.hr-top__status {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-3);
    margin-bottom: 0;
}

.hr-top__badge {
    margin: 0;
}

@media (min-width: 768px) {
    .hr-top {
        flex-direction: row;
        align-items: flex-start;
        gap: var(--spacing-8);
    }
    .hr-top__intro {
        flex: 1 1 55%;
    }
    .hr-top__status {
        flex: 1 1 45%;
        max-width: 28rem;
    }
}

/* Compact horizontal status strip — three at-a-glance numbers in one row on
   phones (vs. tall stacked stat-cards). */
.hr-statbar {
    display: flex;
    gap: var(--spacing-2);
}

.hr-statbar__item {
    flex: 1 1 0;
    background: var(--bg-secondary);
    border-radius: var(--radius-lg);
    padding: var(--spacing-3) var(--spacing-2);
    text-align: center;
}

.hr-statbar__num {
    display: block;
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    line-height: 1;
    color: var(--ucb-gold-text);
}

.hr-statbar__label {
    display: block;
    margin-top: var(--spacing-1);
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Action bar: full-width, thumb-friendly primary action on phones. */
.hr-actions {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
}

.hr-actions .btn {
    width: 100%;
    padding-block: var(--spacing-3);
    font-size: var(--font-size-base);
}

/* A single big at-a-glance number (e.g. queue position) for the status screen. */
.hr-bignum {
    text-align: center;
    padding: var(--spacing-4) 0;
}

.hr-bignum__value {
    font-size: var(--font-size-6xl);
    font-weight: var(--font-weight-bold);
    line-height: 1;
    color: var(--ucb-gold-text);
}

.hr-bignum__label {
    margin-top: var(--spacing-2);
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: var(--font-size-sm);
}

/* Enhance for tablet/desktop: a touch more breathing room, side-by-side
   action buttons when there's room. */
@media (min-width: 768px) {
    .hr-actions {
        flex-direction: row;
        flex-wrap: wrap;
        /* Keep buttons at their natural height — without this, a row that also
           holds a taller item (e.g. the header's semester dropdown) stretches
           every button to match it. */
        align-items: center;
    }
    .hr-actions .btn {
        width: auto;
        flex: 1 1 auto;
    }
}

/* Compact semester dropdown in a screen header: its label is visually hidden
   (the value + the page title already say the semester), and it sizes to its
   content rather than stretching the action row. */
.hr-semester-picker {
    flex: 0 0 auto;
}

.hr-semester-picker select {
    width: auto;
}

/* Inline secondary actions inside a card (e.g. "Update location"): compact and
   right-aligned at every width so they don't compete with the screen's primary
   action. Placed after the media query above so it wins at desktop widths too. */
.hr-actions--inline {
    flex-direction: row;
    justify-content: flex-end;
}

.hr-actions--inline .btn {
    width: auto;
    flex: 0 0 auto;
    padding-block: var(--spacing-2);
    font-size: var(--font-size-sm);
}

/* Wider variant for working screens (helper dashboard, schedule builder) that
   benefit from two columns on desktop while still stacking phone-first. */
.hr-screen--wide {
    max-width: 64rem;
}

/* A small section heading inside a screen ("My active sessions", "Waiting").
   Lighter than .section-card h2, which is a heavy 3xl panel heading. */
.hr-section-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    margin: 0 0 var(--spacing-2);
    display: flex;
    align-items: center;
    gap: var(--spacing-2);
    flex-wrap: wrap;
}

/* The View-analytics button rides in the course heading row (after the section
   meta); keep it from shrinking when space is tight. Layout only. */
.hr-section-title .btn {
    flex-shrink: 0;
}

/* Faculty analytics: horizontal bar lists (category / weekly distributions)
   and a day×hour demand heatmap table. Layout + token shading only; the count
   numbers carry the precise data, so the heat tint is a visual aid (and stays
   subtle enough to keep the cell text readable in both themes). */
.hr-bars {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
}

.hr-bar {
    display: grid;
    grid-template-columns: minmax(5rem, 9rem) 1fr auto;
    align-items: center;
    gap: var(--spacing-3);
}

.hr-bar__label {
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

.hr-bar__track {
    background: var(--bg-elevated);
    border-radius: var(--radius-sm);
    height: var(--spacing-3);
    overflow: hidden;
}

.hr-bar__fill {
    display: block;
    height: 100%;
    width: var(--bar);
    min-width: var(--spacing-1);
    background: var(--ucb-gold);
    border-radius: var(--radius-sm);
}

.hr-bar__value {
    font-weight: var(--font-weight-bold);
    font-variant-numeric: tabular-nums;
}

.hr-heat-wrap {
    overflow-x: auto;
}

.hr-heat {
    border-collapse: collapse;
    width: 100%;
    font-size: var(--font-size-sm);
}

.hr-heat th,
.hr-heat td {
    border: 1px solid var(--border-color);
    padding: var(--spacing-1);
    text-align: center;
}

.hr-heat th {
    /* Inherit the accessible global th pairing (--table-header-bg/-text from
       accessibility.css) so headers stay readable in both themes; only the
       layout differs here. */
    font-weight: var(--font-weight-bold);
    white-space: nowrap;
}

.hr-heat__cell {
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    background: color-mix(in srgb, var(--ucb-gold) calc(var(--heat) * 35%), var(--bg-elevated));
}

/* Faculty portal: separate the add-helper form from the helper list above it. */
.hr-add-helper {
    margin-top: var(--spacing-5);
}

/* Faculty portal: confirm-helper modal card. Layout only — colors come from
   the shared .modal / .btn components. */
.hr-confirm__lead {
    margin: 0 0 var(--spacing-3);
}

.hr-confirm__details {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--spacing-1) var(--spacing-3);
    margin: 0 0 var(--spacing-3);
}

.hr-confirm__details dt {
    font-weight: var(--font-weight-semibold);
}

.hr-confirm__details dd {
    margin: 0;
}

.hr-confirm__note {
    margin: 0 0 var(--spacing-3);
    font-size: var(--font-size-sm);
}

/* Compact presence control in the dashboard header: the availability toggle +
   its live label + the check-out button, replacing the old full-width button
   stack so the queue gets more room. Layout only; the switch itself reuses the
   shared .toggle-switch component. */
.hr-presence {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    flex-wrap: wrap;
}

.hr-presence__toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-2);
}

.hr-presence__status {
    font-weight: var(--font-weight-semibold);
}

.hr-presence__hint {
    margin: 0;
}

/* Claim-button group in the queue header: the course-scoped primaries +
   "any course" overflow, wrapping onto their own row on narrow screens. */
.hr-claim-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-2);
}

/* Phone-first columns: stacked on phones, side by side on desktop. The first
   child stays narrower (controls / forms), the second grows (the live list). */
.hr-cols {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4);
}

/* Each column is its own vertical stack, so a gap separates the section
   heading (and the "Claim next" buttons) from the card list beneath it. */
.hr-cols__aside,
.hr-cols__main {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-3);
    min-width: 0;
}

@media (min-width: 768px) {
    .hr-cols {
        flex-direction: row;
        align-items: flex-start;
    }
    .hr-cols__aside {
        flex: 1 1 38%;
    }
    .hr-cols__main {
        flex: 1 1 62%;
    }
}

/* Landing manager tooling: a labeled cluster of admin links below the shared
   page list. The "Manager tools" heading + extra top space (no divider rule)
   separate manager-only tools from the public navigation; each task group
   stacks its own compact card list so a manager scans by group instead of
   reading one flat list. Layout/token only. */
.hr-manager-tools {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4);
    padding-top: var(--spacing-4);
}

.hr-tool-group {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
}

/* Group label heading each cluster of links. Base size (matches the card
   titles, so it never reads smaller than the cards) and the secondary color +
   lighter weight keep it clearly subordinate to the bold "Manager tools" h2. */
.hr-tool-group__title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    margin: 0;
}

/* Compact card list (queue entries, active sessions, schedule slots). Tighter
   than .section-card, which is a heavy full-width panel — this mirrors the
   scheduling app's per-item card pattern. Token-only; no component overrides. */
.hr-list {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
}

.hr-item {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--spacing-3);
    display: flex;
    flex-direction: column;
    gap: var(--spacing-1);
}

/* Accent a card that needs attention (e.g. a student who requested this helper). */
.hr-item--accent {
    border-color: var(--color-success);
    border-width: 2px;
}

/* Location card with a ready-to-post join QR: details on the left, the
   scannable code on the right. Stacks on narrow screens. */
.hr-item--location {
    flex-direction: row;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: var(--spacing-3);
}

.hr-item__body {
    flex: 1 1 16rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--spacing-2);
}

.hr-location-qr {
    flex: none;
    background: var(--ucb-white);
    border-radius: var(--radius-md);
    padding: var(--spacing-2);
    line-height: 0;
}

.hr-location-qr img {
    display: block;
    width: 7rem;
    height: auto;
    image-rendering: pixelated;
}

/* A card that is itself a link (landing navigation): the whole card is the
   tap target, so suppress the global anchor underline/color and signal
   clickability with a chevron + hover/focus affordance instead. */
a.hr-item--link {
    color: var(--text-primary);
    text-decoration: none;
    position: relative;
    padding-right: var(--spacing-8);
    transition: var(--transition-fast);
    transform: translateZ(0);
    backface-visibility: hidden;
}

a.hr-item--link::after {
    content: "›";
    position: absolute;
    right: var(--spacing-3);
    top: 50%;
    transform: translateY(-50%);
    font-size: var(--font-size-xl);
    color: var(--text-secondary);
}

a.hr-item--link:hover,
a.hr-item--link:focus-visible {
    color: var(--text-primary);
    text-decoration: none;
    border-color: var(--ucb-gold);
    box-shadow: var(--shadow-sm);
}

a.hr-item--link:focus-visible {
    outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);
    outline-offset: var(--focus-outline-offset);
}

.hr-item__top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-2);
}

.hr-item__name {
    font-weight: var(--font-weight-semibold);
}

/* Wait time / time range sits at the far right of the row. */
.hr-item__meta {
    margin-left: auto;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    white-space: nowrap;
}

.hr-item__badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-1);
}

/* Per-display font-size tuner (manager displays page). */
.hr-scale-form {
    margin-block: var(--spacing-3);
}

.hr-scale-form__row {
    display: flex;
    align-items: center;
    gap: var(--spacing-2);
    margin-block: var(--spacing-1);
}

.hr-scale-form__row .form-control {
    width: auto;
    max-width: 6rem;
    flex: 0 0 auto;
}

.hr-scale-form__row .btn {
    flex: 0 0 auto;
}

.hr-item__topic {
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    margin: 0;
}

/* Student table/location — wayfinding for the helper, so it reads as primary
 * text (not muted like topic/meta). */
.hr-item__loc {
    display: flex;
    align-items: center;
    gap: var(--spacing-1);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0;
}

/* Weekly schedule grid: one day per row on phones, widening to a multi-day
   grid on larger screens. */
.hr-week {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--spacing-3);
}

@media (min-width: 600px) {
    .hr-week {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 1100px) {
    .hr-week {
        grid-template-columns: repeat(5, 1fr);
    }
}

/* A single day's coverage list inside the week grid. */
.hr-day__title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-bold);
    margin: 0 0 var(--spacing-2);
    padding-bottom: var(--spacing-1);
    border-bottom: 1px solid var(--border-color);
}

.hr-slot {
    margin-bottom: var(--spacing-2);
}

.hr-slot:last-child {
    margin-bottom: 0;
}

.hr-slot__time {
    font-weight: var(--font-weight-semibold);
}

.hr-slot__notes {
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

/* ── Calendar schedule (Tier D) ───────────────────────────────────────────
   A help-room calendar: weekday columns (Mon–Fri) × time rows on desktop, a
   stacked per-day agenda on phones. Adapts the scheduling app's cal-grid
   technique (CSS-grid time×day, grid-row positioning) but Mon–Fri, non-HTMX,
   and mobile-first — the agenda replaces the desktop grid below md instead of
   horizontally scrolling it. Layout + the established calendar color tokens
   only (mirrors .cal-event in scheduling.css). */

/* Mobile-first: the agenda is the default view; the grid is hidden until md. */
.hr-cal {
    display: none;
}

.hr-agenda {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4);
}

@media (min-width: 768px) {
    .hr-agenda {
        display: none;
    }

    .hr-cal {
        --hr-cal-slot-height: var(--spacing-3);
        display: grid;
        grid-template-columns: auto repeat(5, 1fr);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        overflow: hidden;
    }
}

/* Header row: the time-gutter corner + sticky day names. */
.hr-cal__corner,
.hr-cal__day-header {
    grid-row: 1;
    background: var(--bg-secondary);
    padding: var(--spacing-2);
    text-align: center;
    font-weight: var(--font-weight-bold);
    border-bottom: 1px solid var(--border-color);
}

.hr-cal__corner {
    grid-column: 1;
}

/* Hour labels down the gutter. Top-aligned just below their hour line (no
   upward nudge — that pushed the first label into the day-header row); with
   no drawn gridlines this reads the same and matches slot tops exactly. */
.hr-cal__time-label {
    grid-column: 1;
    padding: var(--spacing-1) var(--spacing-2) 0;
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
    text-align: right;
}

/* A day column: its own lane grid spanning the time rows, so overlapping
   coverage lays out side-by-side (lane positions come from the service).
   Inline styles supply the row/lane templates; rows reuse the same
   slot-height var as the outer grid so times stay aligned with the gutter. */
.hr-cal__day {
    display: grid;
    grid-row: 2 / -1;
}

/* A positioned coverage block. grid-row/grid-column come from
   row_start/row_span and lane_start/lane_span. */
.hr-cal__slot {
    margin: var(--border-1) var(--spacing-1);
    padding: var(--spacing-1) var(--spacing-2);
    border-left: var(--border-3) solid var(--color-info-border);
    border-radius: var(--radius-sm);
    background-color: color-mix(in srgb, var(--color-info-border) 10%, var(--color-bg-secondary));
    font-size: var(--font-size-xs);
    line-height: 1.25;
    overflow: hidden;
}

/* Closure / blackout block: danger accent so it reads as "room unavailable". */
.hr-cal__slot--closure {
    border-left-color: var(--color-danger-border);
    background-color: color-mix(in srgb, var(--color-danger-border) 12%, var(--color-bg-secondary));
}

.hr-cal__slot-name {
    font-weight: var(--font-weight-semibold);
}

.hr-cal__slot-time {
    color: var(--text-secondary);
}

.hr-cal__slot-link {
    display: inline-block;
    margin-top: var(--spacing-1);
}

/* ── Block schedule grid (sheet-style) ─────────────────────────────────────
   A period × weekday table with helpers stacked in each cell — the readable
   replacement for the lane grid when many helpers cover one block (mirrors the
   legacy Google Sheet). Desktop table; the .hr-agenda stack takes over below
   md. Course colors cycle a small palette of existing hue tokens, mixed into
   the card background so each chip reads in both themes. */

.hr-block-wrap {
    display: none;
}

@media (min-width: 768px) {
    .hr-block-wrap {
        display: block;
        overflow-x: auto;
    }
}

.hr-block {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.hr-block th,
.hr-block td {
    border: 1px solid var(--border-color);
    vertical-align: top;
    padding: var(--spacing-1);
}

/* Header cells set their own color: the global `th { color: table-header-text }`
   in accessibility.css pairs with table-header-bg, but this grid uses a
   bg-secondary header, so the text must be re-paired or it vanishes in light
   mode. */
.hr-block thead th {
    background: var(--bg-secondary);
    color: var(--text-primary);
    text-align: center;
    padding: var(--spacing-2);
}

.hr-block__time-head {
    width: 9%;
}

.hr-block__period {
    background: var(--bg-secondary);
    white-space: nowrap;
    text-align: center;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

/* This grid is laid out as a table but isn't a scannable data table, so the
   global zebra striping + full-row hover (set on `tr` in accessibility.css and
   re-applied for dark mode in dark-mode-components.css) fight the course
   colors. Rather than out-specify those theme-specific `tr` rules, give the
   data cells an opaque page-background so any row-level background never shows
   through — then cue the hovered cell instead, identically in both themes. */
.hr-block tbody td {
    background: var(--bg-primary);
}

/* A stacked helper chip inside a cell. The hover cues the individual helper
   session (the chip), not the whole cell/row. */
.hr-chip {
    margin-bottom: var(--spacing-1);
    padding: var(--spacing-1) var(--spacing-2);
    border-left: var(--border-3) solid var(--border-color);
    border-radius: var(--radius-sm);
    background-color: var(--bg-secondary);
    font-size: var(--font-size-xs);
    line-height: 1.3;
    text-align: center;
    overflow-wrap: anywhere;
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.hr-chip:last-child {
    margin-bottom: 0;
}

/* Lift the hovered session above its dense neighbors so the cue is obvious. */
.hr-chip:hover {
    transform: translateY(-2px) scale(1.02);
    box-shadow: var(--shadow-lg);
    position: relative;
    z-index: 1;
}

.hr-chip__name {
    display: block;
    font-weight: var(--font-weight-semibold);
}

.hr-chip__course {
    color: var(--text-secondary);
}

.hr-chip__time {
    display: block;
    color: var(--text-secondary);
}

.hr-chip__link {
    display: inline-block;
    margin-top: var(--spacing-1);
}

/* Course color — one stable hue per course (ScheduleService.course_hue),
   supplied inline as --course-hue; saturation/lightness come from theme tokens
   so it adapts to light/dark. Both the schedule chip accent and the course
   badge key off the same hue, so a course reads the same color at every
   help-room touchpoint. */
.hr-course-accent {
    border-left-color: hsl(var(--course-hue) var(--course-sat) var(--course-border-l));
    background-color: hsl(var(--course-hue) var(--course-sat) var(--course-tint-l));
}

/* A course pill (helper dashboard, status page, mobile agenda) — sized like
   .status-badge but colored by --course-hue. */
.hr-course-badge {
    display: inline-block;
    padding: var(--spacing-1) var(--spacing-2_5);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-primary);
    background-color: hsl(var(--course-hue) var(--course-sat) var(--course-tint-l));
    border: 1px solid hsl(var(--course-hue) var(--course-sat) var(--course-border-l));
}

/* Closure / blackout: danger accent, "room unavailable". */
.hr-chip--closure {
    border-left-color: var(--color-danger-border);
    background-color: color-mix(in srgb, var(--color-danger-border) 12%, var(--bg-secondary));
}

/* Editable chip (manager builder): the read-only chip rendered as a <button>
   that opens the slot editor modal. Reset the native button chrome (borders,
   font) so it still reads as a chip; the lift on hover comes from the base
   .hr-chip:hover rule, and we add the keyboard-focus mirror + outline here. */
.hr-chip--editable {
    display: block;
    width: 100%;
    border-top: 0;
    border-right: 0;
    border-bottom: 0;
    font-family: inherit;
    color: var(--text-primary);
    cursor: pointer;
}

.hr-chip--editable:focus-visible {
    transform: translateY(-2px) scale(1.02);
    box-shadow: var(--shadow-lg);
    position: relative;
    z-index: 1;
    outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);
    outline-offset: var(--focus-outline-offset);
}

/* Editable agenda item (mobile builder): the coverage card rendered as a
   full-width <button> that opens the slot editor. */
.hr-item--editable {
    width: 100%;
    font-family: inherit;
    font-size: inherit;
    text-align: left;
    color: var(--text-primary);
    cursor: pointer;
}

.hr-item--editable:hover,
.hr-item--editable:focus-visible {
    border-color: var(--ucb-gold);
}

.hr-item--editable:focus-visible {
    outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);
    outline-offset: var(--focus-outline-offset);
}

/* Per-cell "+ Add" affordance in the editable grid — subtle until hovered or
   focused so the filled chips stay the visual focus. */
.hr-cell-add {
    display: block;
    width: 100%;
    margin-top: var(--spacing-1);
    padding: var(--spacing-1);
    border: var(--border-1) dashed var(--border-color);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
    cursor: pointer;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.hr-cell-add:hover {
    background-color: var(--bg-secondary);
    color: var(--text-primary);
}

.hr-cell-add:focus-visible {
    outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);
    outline-offset: var(--focus-outline-offset);
}

/* Course legend above the grid — a row of course badges. */
.hr-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-2);
    margin: 0 0 var(--spacing-3);
    padding: 0;
    list-style: none;
}

/* Course-color picker (manager portal): a hue slider + live preview swatch and
   named preset swatches. The hue is unconstrained (0–359), so there's no cap on
   how many courses can have a distinct color. */
.hr-hue-row {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
}

.hr-hue-slider {
    flex: 1 1 auto;
    min-width: 0;
}

.hr-hue-presets {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-2);
    margin-top: var(--spacing-2);
}

/* A preset swatch is a mini course badge — the same tint fill + accent border
   the real badge uses, so the preview matches in both light and dark mode. */
.hr-hue-swatch {
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 1px solid hsl(var(--course-hue) var(--course-sat) var(--course-border-l));
    border-radius: var(--radius-sm);
    cursor: pointer;
    background-color: hsl(var(--course-hue) var(--course-sat) var(--course-tint-l));
}

/* Public schedule filter bar — a wrapping row of dropdowns + actions. */
.hr-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-3);
    align-items: flex-end;
    margin-bottom: var(--spacing-4);
}

.hr-filters .form-group {
    margin-bottom: 0;
}

.hr-filters__actions {
    display: flex;
    gap: var(--spacing-2);
    align-items: flex-end;
}

/* "Add a profile photo" helper nudge (dashboard). Layout only — the alert
 * component supplies the colors. */
.hr-photo-nudge {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-3);
}

.hr-photo-nudge__text {
    margin: 0;
}

.hr-photo-nudge__actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-2);
}
