/* =========================================================
   VLE Dashboard — Stylesheet
   Design direction: "Next Orbit" — a deep-space, dark-mode feel.
   Navy background, orbit-purple as the primary accent, blue/cyan/
   light-purple carrying the same per-content-type color coding as
   before (sessions / assignments / quizzes / roster). All colours,
   spacing and type live in the CSS variables below so the whole
   theme — or the brand name and logo in config/site.php — can be
   swapped from one place.
   ========================================================= */

:root {
    /* ---- palette ---- */
    --color-bg:        #040E24;  /* deep navy — main background */
    --color-surface:   #08193B;  /* navy blue — cards / sections */
    --color-ink:       #F6F8FC;  /* soft white — main text */
    --color-muted:     #BEC7D8;  /* soft gray — secondary text */
    --color-border:    #16264D;

    --color-primary:       #6F41FF; /* orbit purple — main buttons / sessions */
    --color-primary-dark:  #5A2ED9;
    --color-primary-light: rgba(111, 65, 255, 0.22);

    --color-amber:        #269CFF; /* orbit blue — assignments */
    --color-amber-light:  rgba(38, 156, 255, 0.22);

    --color-indigo:       #29CDFF; /* electric cyan — quizzes */
    --color-indigo-light: rgba(41, 205, 255, 0.22);

    --color-clay:         #9D65FF; /* light purple — roster / students */
    --color-clay-light:   rgba(157, 101, 255, 0.22);

    --color-teal:         #14B8A6; /* teal — lesson recaps */
    --color-teal-light:   rgba(20, 184, 166, 0.22);

    --color-gold:         #D97706; /* warm gold — gentle "needs attention" cue, never red/alarming */
    --color-gold-light:   rgba(217, 119, 6, 0.18);

    --color-danger:       #FF5C6C;
    --color-danger-dark:  #E5384A;
    --color-success-bg:   rgba(46, 204, 113, 0.16);
    --color-success-text: #4ADE80;
    --color-error-bg:     rgba(255, 92, 108, 0.16);
    --color-error-text:   #FF8A96;

    /* ---- type ---- */
    --font-display: 'Fraunces', Georgia, serif;
    --font-body: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

    /* ---- layout ---- */
    --radius:    12px;
    --radius-sm: 8px;
    --spacing:   18px;
    --sidebar-width: 260px;
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
    --shadow-md: 0 10px 26px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 20px 44px rgba(0, 0, 0, 0.55);
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* Every page fades gently into view on load instead of snapping in,
   and fades out just before navigating to another page — see the
   matching click-interception in assets/js/script.js. Pure CSS, so
   the fade-in works even if JS never loads; only the fade-OUT
   depends on JS (harmless if it doesn't run — the link just
   navigates instantly instead, no broken behavior either way). */
body { animation: pageFadeIn 0.35s var(--ease, ease) both; }
@keyframes pageFadeIn { from { opacity: 0; } to { opacity: 1; } }
.page-fade-out { animation: pageFadeOut 0.18s var(--ease, ease) forwards !important; }
@keyframes pageFadeOut { from { opacity: 1; } to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    body { animation: none; }
    .page-fade-out { animation: none !important; }
}

body {
    margin: 0;
    font-family: var(--font-body);
    background-color: var(--color-bg);
    background-image:
        radial-gradient(700px circle at 12% 8%, rgba(111, 65, 255, 0.10), transparent 60%),
        radial-gradient(600px circle at 88% 22%, rgba(41, 205, 255, 0.08), transparent 60%),
        radial-gradient(800px circle at 25% 92%, rgba(38, 156, 255, 0.08), transparent 60%);
    background-repeat: no-repeat;
    background-attachment: scroll;
    color: var(--color-ink);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--color-primary); transition: color 0.15s var(--ease); }
.muted { color: var(--color-muted); }
.small { font-size: 0.85em; }

/* ---------------- Lighter theme, scoped to the student dashboard ----------------
   Same brand colors (purple/blue/cyan accents untouched) — only the
   background and text shift from dark navy toward white. Scoped to
   body.light-dashboard so nothing else on the site is affected. The
   sidebar deliberately keeps its own colored background (unchanged)
   as the one accent panel against an otherwise light page — a common,
   clean dashboard pattern. */
body.light-dashboard {
    --color-bg:     #F6F8FC;
    --color-surface: #FFFFFF;
    --color-ink:    #040E24;
    --color-muted:  #5B6472;
    --color-border: #E3E8F0;
    --color-amber: #7C5CFC;
    --color-primary-light: rgba(111, 65, 255, 0.26);
    --color-amber-light:  rgba(124, 92, 252, 0.26);
    --color-indigo-light: rgba(41, 205, 255, 0.26);
    --color-clay-light:   rgba(157, 101, 255, 0.28);
    --color-teal-light:   rgba(20, 184, 166, 0.26);
    --color-gold-light:   rgba(217, 119, 6, 0.16);
    background-image:
        radial-gradient(700px circle at 12% 8%, rgba(111, 65, 255, 0.07), transparent 60%),
        radial-gradient(600px circle at 88% 22%, rgba(157, 101, 255, 0.06), transparent 60%),
        radial-gradient(800px circle at 25% 92%, rgba(111, 65, 255, 0.05), transparent 60%);
}
body.light-dashboard .topbar { background: rgba(255, 255, 255, 0.9); }
body.light-dashboard { --font-display: 'Plus Jakarta Sans', var(--font-body); }
/* The sidebar keeps its own dark/colorful background on purpose even
   in the light theme — its text needs to stay light regardless, or
   it becomes unreadable against that background. */
body.light-dashboard .sidebar,
body.light-dashboard .sidebar h2,
body.light-dashboard .course-list a { color: #F6F8FC; }
body.light-dashboard .course-list a:hover { background: rgba(255,255,255,0.08); }
body.light-dashboard .course-list a.active { background: rgba(255,255,255,0.12); color: #fff; }
body.light-dashboard .stat-number { color: #040E24; }


h1, h2 { font-family: var(--font-display); font-weight: 600; margin: 0 0 6px; }

.typewriter { display: inline-block; }
.typewriter.is-typing::after {
    content: '';
    display: inline-block;
    width: 3px;
    height: 0.9em;
    margin-left: 3px;
    background: currentColor;
    vertical-align: -0.1em;
    animation: typewriterBlink 0.8s step-end infinite;
}
@keyframes typewriterBlink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .typewriter.is-typing::after { animation: none; }
}
h1 { font-size: 1.6rem; position: relative; display: inline-block; padding-bottom: 8px; margin-bottom: 18px; }
h1::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 46px; height: 3px;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--color-primary), var(--color-amber));
    animation: growLine 0.5s var(--ease) 0.1s both;
}
@keyframes growLine { from { width: 0; opacity: 0; } to { width: 46px; opacity: 1; } }

/* ---------------- Top bar ---------------- */
.topbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 24px;
    background: rgba(8, 25, 59, 0.9);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: 10;
    transition: box-shadow 0.25s var(--ease);
}
.topbar.is-scrolled { box-shadow: var(--shadow-md); }

.brand-lockup { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.brand-logo { width: 55px; height: 55px; display: block; transition: transform 0.3s var(--ease); }
.brand-lockup:hover .brand-logo { transform: rotate(-8deg) scale(1.08); }
.brand-name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.15rem;
    color: var(--color-primary);
    letter-spacing: 0.01em;
    transition: color 0.15s var(--ease);
}
.brand-lockup:hover .brand-name { color: var(--color-primary); }
.brand-lockup-center { flex-direction: column; gap: 8px; margin-bottom: 4px; }
.brand-logo-lg { width: 56px; height: 56px; }
.brand-name-lg { font-size: 1.4rem; }

.topbar-user { display: flex; align-items: center; gap: 14px; }
.user-chip { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; }
.user-avatar {
    width: 28px; height: 28px;
    border-radius: 50%;
    background: var(--color-primary);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.85rem;
    flex-shrink: 0;
}
.user-avatar-photo { object-fit: cover; background: none; }
.role-tag {
    font-size: 0.68rem;
    color: var(--color-muted);
    background: var(--color-bg);
    padding: 2px 7px;
    border-radius: 999px;
    margin-left: 4px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* ---------------- Layout ---------------- */
.layout { display: flex; align-items: stretch; min-height: calc(100vh - 61px); transition: opacity 0.15s ease; }

.sidebar {
    width: var(--sidebar-width);
    flex-shrink: 0;
    background-color: #040E24;
    background-image:
        radial-gradient(420px circle at 15% 8%, rgba(111, 65, 255, 0.35), transparent 62%),
        radial-gradient(380px circle at 85% 95%, rgba(41, 205, 255, 0.18), transparent 60%);
    color: var(--color-ink);
    padding: var(--spacing);
    min-height: calc(100vh - 61px);
}
.sidebar-edge-tab {
    display: none;
    align-items: center;
    justify-content: center;
    position: fixed;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 56px;
    background: var(--color-primary);
    border: none;
    border-radius: 0 12px 12px 0;
    color: #fff;
    cursor: pointer;
    z-index: 27;
    box-shadow: var(--shadow-md);
}
.sidebar-edge-tab-arrow {
    display: inline-block;
    font-size: 1.2rem;
    line-height: 1;
    transition: transform 0.3s var(--ease);
}
.sidebar-edge-tab[aria-expanded="true"] .sidebar-edge-tab-arrow { transform: rotate(180deg); }
.dashboard-sidebar-overlay {
    display: none;
    position: fixed;
    inset: var(--topbar-height, 61px) 0 0 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 24;
    opacity: 0;
    transition: opacity 0.25s var(--ease);
}
.dashboard-sidebar-overlay.is-visible { display: block; opacity: 1; }
@media (max-width: 860px) {
    .topbar { position: sticky; top: 0; z-index: 26; }
    .sidebar-edge-tab { display: flex; }
    .layout { position: relative; }
    .sidebar {
        position: fixed;
        top: var(--topbar-height, 61px);
        left: 0;
        bottom: 0;
        width: min(280px, 82vw);
        z-index: 25;
        overflow-y: auto;
        box-shadow: var(--shadow-lg);
        transform: translateX(-100%);
        transition: transform 0.3s var(--ease);
    }
    .sidebar.is-open { transform: translateX(0); }
    .content { max-width: 100%; padding: 20px 16px; }
}
@media (prefers-reduced-motion: reduce) {
    .sidebar { transition: none; }
    .dashboard-sidebar-overlay { transition: none; }
}
.sidebar h2 {
    font-family: var(--font-body);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255,255,255,0.6);
    font-weight: 600;
    margin-bottom: 10px;
}
.sidebar .muted { color: rgba(255,255,255,0.55); }

.sidebar-back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.75);
    text-decoration: none;
    margin-bottom: 14px;
    transition: color 0.15s var(--ease);
}
.sidebar-back-link:hover { color: #fff; }
.sidebar-active-course-name {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 700;
    color: #fff;
    text-transform: none;
    letter-spacing: normal;
    margin-bottom: 14px;
    padding-bottom: 14px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

.course-list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 360px;
    overflow-y: auto;
}
.course-list.sidebar-nav-list { max-height: none; overflow-y: visible; }
.course-list li { margin-bottom: 4px; }
.course-list a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--color-ink);
    border-left: 3px solid transparent;
    transition: background 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.15s var(--ease), padding-left 0.15s var(--ease);
}
.course-list a i { font-size: 1rem; width: 18px; text-align: center; flex-shrink: 0; opacity: 0.9; }
.course-list a:hover { background: rgba(255,255,255,0.08); padding-left: 16px; }
.course-list a.active {
    background: rgba(255,255,255,0.12);
    border-left-color: var(--color-amber);
    font-weight: 600;
    color: #fff;
}
.course-badge {
    display: block;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: rgba(255,255,255,0.08);
    border-left: 3px solid var(--color-amber);
    color: var(--color-ink);
}

.sidebar-badge {
    margin-left: auto;
    background: var(--color-clay);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    padding: 1px 7px;
    border-radius: 999px;
    line-height: 1.5;
    flex-shrink: 0;
}

/* ---------------- Teacher dashboard: course Overview quick-links ---------------- */
.course-quicklink-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 14px;
}
.course-quicklink-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    padding: 20px 18px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--color-ink);
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease), border-color 0.2s var(--ease);
}
.course-quicklink-card i { font-size: 1.5rem; color: var(--color-primary); margin-bottom: 6px; }
.course-quicklink-title { font-family: var(--font-display); font-weight: 700; font-size: 1rem; }
.course-quicklink-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md), 0 0 0 1px var(--color-primary-light);
    border-color: var(--color-primary);
}

.sidebar-section-heading { margin-top: 26px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,0.14); }
.sidebar-collapsible-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    margin-top: 26px;
    padding: 10px 4px;
    border-top: 1px solid rgba(255,255,255,0.14);
    background: none;
    border-left: none;
    border-right: none;
    border-bottom: none;
    color: rgba(255,255,255,0.8);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    cursor: pointer;
}
.sidebar-collapsible-toggle:hover { color: #fff; }
.sidebar-toggle-chevron { transition: transform 0.2s var(--ease); }
.sidebar-collapsible-toggle[aria-expanded="true"] .sidebar-toggle-chevron { transform: rotate(180deg); }
.sidebar-collapsible-body { margin-top: 10px; }
.form-compact input, .form-compact textarea { font-size: 0.85rem; }
.sidebar .form label { color: rgba(255,255,255,0.8); }
.sidebar .form input,
.sidebar .form textarea {
    background: rgba(255,255,255,0.08);
    border: 1px solid rgba(255,255,255,0.2);
    color: #fff;
}
.sidebar .form input::placeholder,
.sidebar .form textarea::placeholder { color: rgba(255,255,255,0.45); }
.sidebar .form input:focus,
.sidebar .form textarea:focus {
    background: rgba(255,255,255,0.14);
    border-color: var(--color-amber);
    box-shadow: none;
}

.content {
    flex: 1;
    padding: 26px;
    max-width: 1100px;
    animation: fadeIn 0.35s ease;
    transition: opacity 0.15s ease;
}
.content.is-loading, .layout.is-loading { opacity: 0.92; }

/* ---------------- Course header (teacher) ---------------- */
.course-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }

/* ---------------- Panels (accordion cards) ---------------- */
.panel {
    position: relative;
    scroll-margin-top: 80px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin-bottom: 20px;
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    animation: fadeIn 0.4s var(--ease) both;
    transition: box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}
.panel:hover { box-shadow: var(--shadow-md), 0 0 0 1px rgba(111, 65, 255, 0.18); transform: translateY(-2px); }
.panel[data-accent="assignment"]:hover { box-shadow: var(--shadow-md), 0 0 0 1px rgba(38, 156, 255, 0.18); }
.panel[data-accent="quiz"]:hover       { box-shadow: var(--shadow-md), 0 0 0 1px rgba(41, 205, 255, 0.18); }
.panel[data-accent="students"]:hover   { box-shadow: var(--shadow-md), 0 0 0 1px rgba(157, 101, 255, 0.18); }
.content > .panel:nth-of-type(1) { animation-delay: 0.02s; }
.content > .panel:nth-of-type(2) { animation-delay: 0.07s; }
.content > .panel:nth-of-type(3) { animation-delay: 0.12s; }
.content > .panel:nth-of-type(4) { animation-delay: 0.17s; }
.content > .panel:nth-of-type(5) { animation-delay: 0.22s; }
.content > .panel:nth-of-type(6) { animation-delay: 0.27s; }
.panel::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: var(--color-primary);
}
.panel[data-accent="assignment"]::before { background: var(--color-amber); }
.panel[data-accent="quiz"]::before       { background: var(--color-indigo); }
.panel[data-accent="students"]::before  { background: var(--color-clay); }

.panel-toggle {
    all: unset;
    box-sizing: border-box;
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: center;
    padding: 20px 22px 12px;
    cursor: pointer;
    border-radius: var(--radius) var(--radius) 0 0;
    transition: background 0.15s var(--ease);
}
.panel-toggle:hover { background: var(--color-bg); }
.panel-toggle h2 { font-size: 1.1rem; }
.panel-toggle .chevron {
    font-size: 0.95rem;
    color: var(--color-muted);
    transition: transform 0.3s var(--ease);
    flex-shrink: 0;
    margin-left: 12px;
}
.panel.collapsed .chevron { transform: rotate(-90deg); }

.panel-body {
    padding: 12px 22px 22px;
    max-height: 3000px;
    overflow: hidden;
    opacity: 1;
    transition: max-height 0.35s var(--ease), opacity 0.3s var(--ease), padding 0.35s var(--ease);
}
.panel.collapsed .panel-body {
    max-height: 0;
    opacity: 0;
    padding-top: 0;
    padding-bottom: 0;
}

.panel h3 { margin: 22px 0 8px; font-size: 0.95rem; font-family: var(--font-body); font-weight: 600; }

/* No-JS fallback: if JS never runs, panels must still show everything. */
.no-js .panel-body { max-height: none !important; opacity: 1 !important; }
.no-js .join-link { display: inline-flex !important; }
.no-js .join-pending { display: none !important; }
.no-js .nav-burger { display: none !important; }
.no-js .sidebar-edge-tab { display: none !important; }
.no-js .accordion-body { max-height: none !important; opacity: 1 !important; padding: 0 20px 20px !important; }
.no-js .sidebar-collapsible-body { display: block !important; }
@media (max-width: 860px) {
    .no-js .nav-menu { display: flex !important; position: static !important; box-shadow: none !important; }
    .no-js .sidebar { transform: none !important; position: static !important; box-shadow: none !important; }
}

/* ---------------- Forms ---------------- */
.form { display: flex; flex-direction: column; gap: 4px; }
.form-grid-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
@media (max-width: 600px) {
    .form-grid-2col { grid-template-columns: 1fr; }
}
.form label { font-size: 0.82rem; font-weight: 600; margin-top: 10px; }
.form input,
.form textarea,
.form select {
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: 0.95rem;
    width: 100%;
    background: var(--color-bg);
    color: var(--color-ink);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.form input:focus,
.form textarea:focus,
.form select:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-light);
    background: var(--color-surface);
}
.form select { cursor: pointer; }
.form select option { background: var(--color-surface); color: var(--color-ink); }
.form textarea { resize: vertical; }
.form-section {
    padding: 18px 0;
    border-top: 1px solid var(--color-border);
}
.form-section:first-of-type { border-top: none; padding-top: 4px; }
.form-section-title {
    font-family: var(--font-display);
    font-size: 1rem;
    margin: 0 0 10px;
    color: var(--color-ink);
}
.form-actions { display: flex; gap: 10px; margin-top: 16px; }

.inline-form { display: inline; }

/* ---------------- Buttons ---------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 18px;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    text-align: center;
    position: relative;
    overflow: hidden;
    transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease), background 0.15s var(--ease);
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn:active { transform: translateY(0) scale(0.97); box-shadow: none; }
.btn-primary { background: var(--color-primary); color: #fff; }
.btn-primary:hover { background: var(--color-primary-dark); }
.btn-primary::after {
    content: '';
    position: absolute;
    top: 0; left: -60%;
    width: 40%; height: 100%;
    background: linear-gradient(120deg, transparent, rgba(255,255,255,0.25), transparent);
    transform: skewX(-20deg);
    transition: left 0.5s var(--ease);
}
.btn-primary:hover::after { left: 130%; }
.btn-secondary { background: var(--color-bg); color: var(--color-ink); border: 1px solid var(--color-border); }
.btn-danger { background: var(--color-danger); color: #fff; }
.btn-danger:hover { background: var(--color-danger-dark); }
.btn-ghost { background: transparent; border: 1px solid var(--color-border); color: var(--color-ink); }
.btn-ghost:hover { background: var(--color-bg); }
.btn-small { padding: 6px 12px; font-size: 0.8rem; }
.btn-block { width: 100%; margin-top: 8px; }

/* ---------------- Tables ---------------- */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 8px; }
.data-table { width: 100%; min-width: 480px; border-collapse: collapse; }
.data-table th, .data-table td {
    text-align: left;
    padding: 10px 10px;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.9rem;
    vertical-align: middle;
}
.data-table th { color: var(--color-muted); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
.data-table tbody tr { transition: background 0.15s ease; }
.data-table tbody tr:hover { background: var(--color-bg); }
.row-actions { display: flex; gap: 6px; white-space: nowrap; }
.data-table td input[type="checkbox"],
.data-table th input[type="checkbox"] { width: auto; accent-color: var(--color-primary); cursor: pointer; }

/* Shows roughly 10 rows, then scrolls — used for tables that can grow
   large (e.g. a 50-class recurring schedule) so the page itself stays a
   manageable length. The header row stays visible while scrolling. */
.table-scroll-tall { max-height: 190px; overflow-y: auto; }
.table-scroll-tall thead th {
    position: sticky;
    top: 0;
    background: var(--color-surface);
    z-index: 1;
    box-shadow: 0 1px 0 var(--color-border);
}

/* ---------------- Due-date badges (filled in by JS) ---------------- */
.due-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 9px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    vertical-align: middle;
    letter-spacing: 0.01em;
}
.due-badge:empty { display: none; }
.due-badge.badge-overdue  { background: var(--color-error-bg);  color: var(--color-error-text); }
.due-badge.badge-soon     { background: var(--color-amber-light); color: var(--color-amber); }
.due-badge.badge-ok       { background: var(--color-primary-light); color: var(--color-primary); }
.due-badge.badge-starting { background: var(--color-indigo-light); color: var(--color-indigo); }
.due-badge.badge-live {
    background: rgba(34, 197, 94, 0.16);
    color: #16A34A;
    animation: dueBadgeLivePulse 1.6s ease-in-out infinite;
}
@keyframes dueBadgeLivePulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.35); }
    50% { box-shadow: 0 0 0 4px rgba(34, 197, 94, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .due-badge.badge-live { animation: none; }
}

/* ---------------- Assigned-to badge (per-student assignments) ---------------- */
.assigned-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--color-clay-light);
    color: var(--color-clay);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.completed-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 10px;
    border-radius: 999px;
    background: rgba(34, 197, 94, 0.16);
    color: #16A34A;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}
/* Cancelled — neutral slate, not red. A cancelled class usually isn't
   a problem (reschedule, a day off) so it shouldn't read as an
   alarm the way overdue/danger states do; it just clearly isn't
   happening, and (via is_completed being forced to 0 when it's
   cancelled — see actions/session_action.php) never counts toward
   the lesson balance. */
.cancelled-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--color-error-bg);
    color: var(--color-danger);
    font-size: 0.75rem;
    font-weight: 700;
    white-space: nowrap;
}
.item-card.is-cancelled, .session-card.is-cancelled {
    opacity: 0.7;
    border-style: dashed;
}
.item-card.is-cancelled:hover, .session-card.is-cancelled:hover {
    opacity: 0.9;
}
.session-card-status .inline-form,
.item-card-grade .inline-form {
    /* .session-card-status doesn't actually appear on any page —
       the real class in the markup is .item-card-grade
       (session-completion-cell specifically for a session's
       Mark-Complete form). Without a matching rule, that form fell
       back to display:inline, which gives the note input's own
       width:100% an undefined containing block to size against —
       exactly the kind of thing that can silently overflow a fixed-
       width card rather than sizing to it properly. */
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
}
.session-complete-note {
    width: 100%;
    min-width: 130px;
    padding: 5px 8px;
    font-size: 0.82rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    color: var(--color-ink);
}

/* ---------------- Published Sessions: card grid ---------------- */
.session-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    align-items: start;
    gap: 10px;
}
.session-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 13px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    font-size: 0.9rem;
    overflow-wrap: break-word;
    transition: box-shadow 0.2s var(--ease), transform 0.2s var(--ease), border-color 0.2s var(--ease);
}
.session-card.session-card-hidden { display: none; }
.session-card-empty {
    display: none;
}
.session-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.session-card.is-completed { border-color: rgba(34, 197, 94, 0.4); background: rgba(34, 197, 94, 0.05); }
.session-card-date {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.94rem;
    color: var(--color-ink);
    padding-bottom: 8px;
    border-bottom: 1px solid var(--color-border);
}
.session-card-zoom-row { display: flex; align-items: center; gap: 8px; min-height: 20px; font-size: 0.92rem; }
.session-card-join { font-weight: 700; }
.session-card-lesson {
    font-size: 0.88rem;
    padding: 8px 0;
    border-top: 1px dashed var(--color-border);
    border-bottom: 1px dashed var(--color-border);
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.session-card-lesson .text-preview {
    padding: 10px 12px;
    margin: 2px 0;
    background: var(--color-primary-light);
    border-left: 3px solid var(--color-primary);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    color: var(--color-ink);
}
.session-card-status { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; font-size: 0.9rem; }
.session-card-actions { display: flex; gap: 8px; margin-top: auto; padding-top: 4px; }
.session-card .btn-small { padding: 5px 12px; font-size: 0.85rem; }
.session-show-before { margin-bottom: 12px; }
.session-show-after { margin-top: 12px; }

/* ---------------- Generic item cards (assignments, quizzes,
   grades, upcoming classes, lesson recaps — any dashboard section
   that lists several similar things) — same visual language and
   show-more/show-less behavior as the teacher's session cards
   above, but content-agnostic so any section can reuse it. Sizing
   is deliberately identical to .session-card, so every card-based
   section across every dashboard looks and feels the same. ---------------- */
.item-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    /* align-items: start (instead of the grid default, stretch) —
       without this, every card in a row is forced to match the
       height of the tallest one in that row, so a card with less
       content (e.g. a recap with no PDF attached, sitting next to
       one that has one) ends up with a chunk of empty space at the
       bottom for no reason. This lets each card just be exactly as
       tall as its own content needs. */
    align-items: start;
    gap: 10px;
}
.item-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 13px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    font-size: 0.9rem;
    overflow-wrap: break-word;
    transition: box-shadow 0.2s var(--ease), transform 0.2s var(--ease), border-color 0.2s var(--ease);
}
.item-card.item-card-hidden { display: none; }
.item-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.item-card.is-graded { border-color: rgba(34, 197, 94, 0.4); background: rgba(34, 197, 94, 0.05); }
.item-card.is-overdue { border-color: rgba(239, 68, 68, 0.35); }
.item-card-empty {
    display: none;
}
.item-card-top {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.94rem;
    color: var(--color-ink);
    padding-bottom: 8px;
    border-bottom: 1px solid var(--color-border);
}
.item-card-course { font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-primary); font-weight: 700; }
.item-card-due { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; flex-wrap: wrap; }
.item-card-body {
    font-size: 0.88rem;
    padding: 8px 0;
    border-top: 1px dashed var(--color-border);
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.item-card-lesson-text {
    font-size: 0.88rem;
    padding: 10px 12px;
    margin: 2px 0;
    background: var(--color-primary-light);
    border-left: 3px solid var(--color-primary);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    color: var(--color-ink);
}
.item-card-grade { display: flex; flex-direction: column; gap: 5px; align-items: flex-start; font-size: 0.9rem; margin-top: auto; }
.submission-link {
    /* A secondary action sitting under the grade/status line, not
       competing with it for attention — smaller and a touch muted,
       same spirit as .due-badge sitting quietly under a title. */
    font-size: 0.82rem;
    color: var(--color-muted);
}
.submission-link:hover { color: var(--color-primary); }
.item-card-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 4px; }
.item-card-link { font-weight: 700; }
.item-card .btn-small { padding: 5px 12px; font-size: 0.85rem; }

/* ---------------- Lesson Recap cards — same .item-card base as
   everything else above, plus a teal accent (top border + tinted
   notes box + a small icon by the title) scoped to .item-card-recap
   only, so assignments/quizzes/grades cards elsewhere are
   untouched. A bit more breathing room than the base card too —
   padding, internal gap, and the grid gap between cards are all
   slightly larger here, via .item-card-grid-recap. ---------------- */
.item-card-grid-recap { gap: 14px; }
.item-card-recap {
    border-top: 3px solid var(--color-teal);
    padding: 16px;
    gap: 8px;
}
.item-card-recap .item-card-top {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 10px;
}
.item-card-recap-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--color-teal-light);
    color: var(--color-teal);
    font-size: 0.85rem;
}
.item-card-recap .item-card-lesson-text {
    background: var(--color-teal-light);
    border-left: 3px solid var(--color-teal);
}
.item-card-recap .item-card-grade .btn-primary {
    background: var(--color-teal);
}
.item-card-recap .item-card-grade .btn-primary:hover {
    background: #0F9488;
}
.item-show-before { margin-bottom: 12px; }
.item-show-after { margin-top: 12px; }

/* ---------------- Session carousel — a horizontal, scrollable row
   instead of a vertical grid: 3 cards visible at a time on desktop,
   scrolling left/right (drag, trackpad, or the arrow buttons) to see
   older/later ones, rather than a "Show more" click. Every card just
   renders directly into the row — no show-more chunking, no padding
   placeholders, since scrolling handles any number of items on its
   own. Used for session lists specifically (Upcoming Classes on the
   student dashboard, and anywhere else sessions are browsed rather
   than managed) — assignments/quizzes/grades keep the existing
   vertical grid, unaffected by any of this. ---------------- */
.session-carousel-wrap {
    display: flex;
    align-items: center;
    gap: 10px;
}
.session-carousel {
    position: relative;
    flex: 1;
    display: flex;
    /* align-items: flex-start — flex containers stretch every item
       to match the tallest one in the row by default, and since
       nowrap keeps this whole thing on a single row, that means ALL
       cards (not just the ones currently in view) get stretched to
       match whichever one has the most content — a short recap next
       to a long one, even several cards further along and not
       currently visible, would get pulled up to that height. This is
       what "sometimes big, sometimes small" actually was: every
       card's height depended on every OTHER card's content, not its
       own. Each card now sizes to exactly its own content. */
    align-items: flex-start;
    gap: 16px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    padding: 2px 2px 12px;
    -webkit-overflow-scrolling: touch;
}
.session-carousel::-webkit-scrollbar { height: 6px; }
.session-carousel::-webkit-scrollbar-track { background: transparent; }
.session-carousel::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 999px; }
.session-carousel::after {
    /* A soft fade hinting there's more content past the edge —
       .has-more-right (toggled by initSessionCarousel in script.js)
       shows it only while there's genuinely somewhere further to
       scroll, and it fades away on its own once you reach the end.
       Sits over the last card without blocking taps on it. */
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 12px;
    width: 32px;
    background: linear-gradient(to right, transparent, var(--color-surface));
    opacity: 0;
    transition: opacity 0.2s var(--ease);
    pointer-events: none;
}
.session-carousel.has-more-right::after { opacity: 1; }
.session-carousel .item-card,
.session-carousel .session-card {
    scroll-snap-align: start;
    flex: 0 0 calc((100% - 32px) / 3); /* 3 at a time (2 gaps of 16px) */
    min-width: 250px;
    /* A real, fixed height — not a minimum — so every card in a
       carousel is exactly the same size, no matter how much or how
       little its title/description/etc. actually contains. Text
       that's too long to fit gets truncated with an ellipsis (see
       the title/body rules below) instead of stretching the card —
       that's what actually makes a row read as a uniform grid rather
       than a jumble of different-sized boxes. Sized generously
       enough for the tallest realistic case (a teacher's session
       card: date + Join row + completion status + three action
       buttons, which is genuinely more content than a plain
       assignment card) — simpler cards just carry a bit of empty
       space at the bottom rather than risk clipping the busier ones.
       An earlier, shorter version of this number is exactly what was
       cutting off session dates and assignment descriptions
       mid-line. */
    height: 320px;
    overflow: hidden;
    padding: 20px 18px;
    gap: 10px;
    font-size: 1rem;
}
.session-carousel .item-card-top,
.session-carousel .session-card-date {
    font-size: 1.1rem;
    line-height: 1.3;
    padding-bottom: 10px;
    flex-shrink: 0;
    /* Clamp to 3 lines, not 2 — this block holds the course label
       (its own line) PLUS either a title or a full formatted date
       ("Tue, 08 Sep 2026 at 14:30"), and on a narrow card that date
       alone can need 2 lines to fit. Clamping the whole block to 2
       cut the date off mid-wrap on every single session card — not
       an edge case, it happened on ordinary dates on an ordinary
       phone width. 3 lines gives the date room to wrap in full,
       while still capping a truly long, freely-typed title.
       max-height is a plain, non-negotiable backup in case
       -webkit-line-clamp itself doesn't render cleanly on a given
       browser (it's normally reliable, but a mismatch between it and
       a flex parent's own sizing has been the actual cause of text
       getting cut off mid-line, without even the ellipsis showing,
       on real devices before — this guarantees a hard stop at a
       clean line boundary either way). */
    max-height: calc(1.1rem * 1.3 * 3);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.session-carousel .item-card-course {
    font-size: 0.88rem;
    margin-bottom: 2px;
}
.session-carousel .item-card-due { margin: 2px 0; flex-shrink: 0; }
.session-carousel .item-card-due .due-badge,
.session-carousel .item-card-due .cancelled-badge {
    font-size: 0.85rem;
    padding: 4px 12px;
}
.session-carousel .item-card-body,
.session-carousel .item-card-lesson-text {
    font-size: 0.92rem;
    line-height: 1.3;
    flex-shrink: 0;
    /* Same idea as the title — a long description or recap note
       clamps to 2 lines with an ellipsis rather than pushing the
       card taller than its neighbors, with the same max-height
       backup. flex-shrink: 0 matters here specifically — without it,
       this was the one card element left able to shrink (everything
       around it is pinned), so a tight fit could squeeze this box
       down below the height its own 2-line clamp needed, which is
       what caused a description to visibly cut off mid-word instead
       of showing a clean two-line "…". */
    max-height: calc(0.92rem * 1.3 * 2);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.session-carousel .item-card-body .btn {
    padding: 7px 16px;
    font-size: 0.9rem;
}
.session-carousel .item-card-grade,
.session-carousel .item-card-actions {
    /* Whichever of these is present is always the true last row
       (grade/status, or a teacher's action buttons) — pins it to the
       bottom of the fixed-height card so it lands in the same place
       regardless of how much (or how little) content sits above it. */
    margin-top: auto;
    flex-shrink: 0;
}
.session-carousel .item-card-grade + .item-card-actions {
    /* A teacher's session card has BOTH of the above, back to back —
       grade/completion status, then Edit/Cancel/Delete. Two
       consecutive auto top-margins split the leftover space between
       them instead of just pushing the pair down as one group, which
       opened up an unintended gap between the completion status and
       the buttons under it. Grade's own auto-margin already pushes
       this whole pair to the bottom; actions just needs to sit
       directly under it. */
    margin-top: 0;
}
.session-carousel-btn {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 1.35rem;
    line-height: 1;
    color: var(--color-ink);
    transition: background 0.15s var(--ease), opacity 0.15s var(--ease);
}
.session-carousel-btn:hover:not(:disabled) { background: var(--color-bg); }
.session-carousel-btn:disabled { opacity: 0.3; cursor: not-allowed; }
@media (max-width: 1000px) {
    .session-carousel .item-card,
    .session-carousel .session-card { flex: 0 0 calc((100% - 16px) / 2); } /* 2 at a time */
}
@media (max-width: 640px) {
    .session-carousel .item-card,
    .session-carousel .session-card {
        flex: 0 0 88%; /* ~1 at a time, with a peek of the next to hint it scrolls */
        /* Same fixed-height, truncate-instead-of-stretch approach as
           the desktop rule above — just a smaller number to match
           the narrower column and reduced padding here. */
        min-width: unset;
        height: 290px;
        padding: 14px;
        gap: 8px;
        font-size: 0.9rem;
    }
    .session-carousel .item-card-top,
    .session-carousel .session-card-date {
        font-size: 1rem;
        padding-bottom: 8px;
    }
    .session-carousel-btn { width: 32px; height: 32px; font-size: 1.15rem; }
}

/* ---------------- Copy-link button ---------------- */
.copy-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--color-muted);
    font-size: 0.85rem;
    padding: 3px 6px;
    border-radius: 4px;
    margin-left: 2px;
    vertical-align: middle;
    transition: color 0.15s ease, background 0.15s ease;
}
.copy-btn:hover { color: var(--color-primary); background: var(--color-primary-light); }
.copy-btn.copied { color: var(--color-primary); animation: popIn 0.3s var(--ease); }

/* ---------------- Checkbox list (Manage Students) ---------------- */
.checkbox-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 280px;
    overflow-y: auto;
    padding: 4px 0;
}
.checkbox-row {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: normal;
    font-size: 0.9rem;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    transition: background 0.15s ease;
}
.checkbox-row:hover { background: var(--color-bg); }
.checkbox-row input { width: auto; accent-color: var(--color-clay); }

.radio-row { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 4px 0 10px; }
.radio-inline {
    display: flex;
    align-items: center;
    gap: 7px;
    font-weight: normal;
    font-size: 0.88rem;
    color: var(--color-ink);
}
.radio-inline input { width: auto; accent-color: var(--color-clay); }

.roster-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}
.roster-avatar-placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-clay-light);
    color: var(--color-clay);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.75rem;
}

.checkbox-list-row {
    flex-direction: row;
    flex-wrap: wrap;
    max-height: none;
    overflow: visible;
    gap: 6px;
}
.checkbox-row-compact {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    padding: 6px 12px;
    gap: 6px;
}
.checkbox-row-compact:hover { background: var(--color-primary-light); }
.checkbox-row-compact input { accent-color: var(--color-primary); }

/* ---------------- Next Up cards (student dashboard) ---------------- */
.next-up-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
    margin-top: 6px;
}
.next-up-card {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-primary);
    border-radius: var(--radius-sm);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.next-up-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.next-up-course { font-family: var(--font-display); font-weight: 600; font-size: 1rem; color: var(--color-primary); }
.progress-bar-track {
    width: 100%;
    height: 8px;
    border-radius: 999px;
    background: var(--color-surface);
    overflow: hidden;
}
.progress-bar-fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--color-primary), var(--color-indigo));
    width: 0;
    animation: progressFill 1s var(--ease) 0.15s forwards;
}
@keyframes progressFill {
    to { width: var(--target-width, 0%); }
}
@media (prefers-reduced-motion: reduce) {
    .progress-bar-fill { animation: none; width: var(--target-width, 0%); }
}

/* ---------------- Dashboard home two-column row + Achievements ---------------- */
.dashboard-home-row { display: flex; gap: 20px; align-items: stretch; margin-bottom: 20px; }
.dashboard-home-row .panel { display: flex; flex-direction: column; }
.dashboard-home-row .panel-body { flex: 1; display: flex; flex-direction: column; }
.dashboard-home-col-wide { flex: 1 1 65%; margin-bottom: 0; }
.dashboard-home-col-narrow { flex: 1 1 35%; margin-bottom: 0; }
@media (max-width: 860px) {
    /* Without this, two panels side by side (65%/35%) never had
       anywhere to go on a narrow screen — they'd just keep
       squeezing into a row that's wider than the phone itself,
       forcing the ENTIRE PAGE to scroll sideways to see the second
       one (Announcements, in the screenshot) rather than it simply
       sitting underneath the first, which is what actually happens
       everywhere else on a phone. Stacked as full-width, one above
       the other, same order as the row had them in. */
    .dashboard-home-row { flex-direction: column; }
    .dashboard-home-col-wide,
    .dashboard-home-col-narrow { flex: 1 1 auto; }
}

/* ---------------- Parent dashboard: child summary cards ---------------- */
.child-summary-card {
    margin-bottom: 20px;
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.child-summary-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md), 0 0 0 1px rgba(157, 101, 255, 0.18);
}
.child-summary-card .panel-body { padding: 26px 28px 28px; }
.child-summary-header { display: flex; align-items: center; gap: 22px; margin-bottom: 26px; }
.child-summary-photo {
    width: 76px;
    height: 76px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    border: 3px solid var(--color-primary-light);
}
.child-summary-photo-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--color-primary), var(--color-indigo));
    color: #fff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.6rem;
    border-color: transparent;
}
.child-summary-name { font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; color: var(--color-ink); margin-bottom: 10px; line-height: 1.3; }
.child-summary-course-tag {
    display: inline-block;
    padding: 5px 14px;
    border-radius: 999px;
    background: var(--color-primary-light);
    color: var(--color-primary);
    font-size: 0.84rem;
    font-weight: 600;
}
.child-summary-cta { width: 100%; justify-content: center; gap: 8px; margin-top: 4px; }

.lesson-status-list { display: flex; flex-direction: column; gap: 4px; }
.lesson-status-item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 6px;
    border-bottom: 1px solid var(--color-border);
}
.lesson-status-item:last-child { border-bottom: none; }
.lesson-status-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--color-primary-light);
    color: var(--color-primary);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
}
.lesson-status-info { flex: 1; min-width: 0; }
.lesson-status-course { font-weight: 600; color: var(--color-ink); }
.lesson-status-count {
    flex-shrink: 0;
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--color-primary-light);
    color: var(--color-primary);
    font-size: 0.85rem;
    font-weight: 700;
    white-space: nowrap;
}
/* Three states, distinguished by color and wording alone — never a
   dollar figure. "Ahead" (paid for more than has happened yet) and
   "caught up" (nothing pending) both read as good news, in green;
   "pending" (more has happened than has been paid for) gets a warm
   gold, deliberately not red — a nudge, not a warning. The item's
   left border repeats the same color so the state is scannable
   without reading the text at all. */
.lesson-status-item.lesson-status-pending { border-left: 3px solid var(--color-gold); padding-left: 10px; }
.lesson-status-item.lesson-status-ahead   { border-left: 3px solid var(--color-success-text); padding-left: 10px; }
.lesson-status-item.lesson-status-caughtup { border-left: 3px solid var(--color-success-text); padding-left: 10px; }
.lesson-status-count.lesson-status-pending { background: var(--color-gold-light); color: var(--color-gold); }
.lesson-status-count.lesson-status-ahead,
.lesson-status-count.lesson-status-caughtup { background: var(--color-success-bg); color: var(--color-success-text); }
/* The one place in the whole parent dashboard a dollar figure ever
   shows (Payments page only) — deliberately small and quiet, a
   supporting detail under the lesson count rather than a headline
   number, and only ever rendered for the "pending" state. */
.lesson-status-estimate {
    font-size: 0.8rem;
    color: var(--color-gold);
    margin-top: 2px;
}
.back-link { display: inline-flex; align-items: center; gap: 6px; font-size: 0.88rem; font-weight: 600; margin-bottom: 12px; }
@media (max-width: 860px) {
    .dashboard-home-row { flex-direction: column; }
}

.achievement-list { display: flex; flex-direction: column; gap: 14px; margin: 4px 0 12px; }
.achievement-row { display: flex; align-items: flex-start; gap: 12px; }
.achievement-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--color-clay-light);
    font-size: 1.1rem;
    animation: achievementIconPulse 2.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .achievement-icon { animation: none; }
}
.achievement-title { font-weight: 600; font-size: 0.9rem; color: var(--color-ink); }
.achievement-view-all { display: inline-block; font-size: 0.85rem; font-weight: 600; }

/* ---------------- Teacher Announcements ---------------- */
.announcement-list { display: flex; flex-direction: column; gap: 14px; margin: 6px 0 4px; }
.announcement-item { padding-bottom: 14px; border-bottom: 1px solid var(--color-border); }
.announcement-item:last-child { border-bottom: none; padding-bottom: 0; }
.announcement-item-accented {
    border-bottom: none !important;
    padding: 14px 16px !important;
    margin-bottom: 10px;
    background: var(--color-clay-light);
    border-left: 3px solid var(--color-clay);
    border-radius: var(--radius-sm);
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.announcement-item-accented:last-child { margin-bottom: 0; }
.announcement-item-accented:hover { transform: translateX(3px); box-shadow: var(--shadow-sm); }
.announcement-header { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.announcement-title { font-weight: 700; font-size: 0.92rem; color: var(--color-ink); }
.announcement-message { margin: 6px 0 0; font-size: 0.9rem; }


.achievement-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; }
.achievement-card {
    text-align: center;
    padding: 22px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.achievement-card.is-earned {
    border-color: var(--color-clay);
    background: linear-gradient(150deg, var(--color-surface), var(--color-clay-light) 130%);
    animation: achievementGlow 3.2s ease-in-out infinite;
}
@keyframes achievementGlow {
    0%, 100% { box-shadow: var(--shadow-sm), 0 0 0 0 rgba(157, 101, 255, 0); }
    50% { box-shadow: var(--shadow-sm), 0 0 18px 3px rgba(157, 101, 255, 0.28); }
}
.achievement-card.is-earned .achievement-card-icon { animation: achievementIconPulse 2.6s ease-in-out infinite; }
@keyframes achievementIconPulse {
    0%, 100% { transform: scale(1) rotate(0deg); }
    50% { transform: scale(1.12) rotate(-4deg); }
}
.panel-header-icon-animated {
    display: inline-block;
    color: var(--color-primary);
    animation: achievementIconPulse 2.8s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .panel-header-icon-animated { animation: none; }
}
.achievement-card.is-earned:hover {
    transform: translateY(-4px) scale(1.02);
    box-shadow: var(--shadow-md), 0 0 24px 5px rgba(157, 101, 255, 0.4);
}
@media (prefers-reduced-motion: reduce) {
    .achievement-card.is-earned { animation: none; }
    .achievement-card.is-earned .achievement-card-icon { animation: none; }
}
.achievement-card.is-locked { opacity: 0.5; }
.achievement-card-icon { display: block; font-size: 2rem; margin-bottom: 10px; }
.achievement-card-title { font-family: var(--font-display); font-weight: 600; font-size: 0.95rem; margin-bottom: 4px; color: var(--color-ink); }

/* ---------------- Certificates ---------------- */
.certificate-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 18px; }
.certificate-card {
    position: relative;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    overflow: hidden;
    text-align: center;
    padding: 26px 16px;
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.certificate-card.is-unlocked {
    border-color: #D4AF37;
    background: linear-gradient(160deg, var(--color-surface), var(--color-primary-light));
}
.certificate-card.is-unlocked:hover { transform: translateY(-4px); box-shadow: var(--shadow-md), 0 0 0 1px rgba(212, 175, 55, 0.45); }
.certificate-card-icon { display: block; font-size: 2.4rem; margin-bottom: 10px; }
.certificate-card-title { font-family: var(--font-display); font-weight: 600; font-size: 0.98rem; margin-bottom: 4px; color: var(--color-ink); }
.certificate-unlocked-date { margin: 10px 0 0; font-size: 0.78rem; font-weight: 700; color: #B8860B; }
.certificate-card.is-locked .certificate-card-inner {
    filter: blur(4px);
    opacity: 0.65;
    user-select: none;
    pointer-events: none;
}
.certificate-lock-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.04);
}
.certificate-lock-icon {
    font-size: 1.6rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 50%;
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow-md);
}

.next-up-date { font-size: 0.85rem; color: var(--color-muted); }
.next-up-join { margin-top: 6px; align-self: flex-start; }

/* ---------------- PDF lesson-plan link ---------------- */
.pdf-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-weight: 600;
    text-decoration: none;
    transition: transform 0.15s var(--ease);
}
.pdf-link:hover { transform: translateX(2px); text-decoration: underline; }
.current-file-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 8px 12px;
    margin-top: 6px;
}

/* ---------------- My Profile (teacher: photo + bio editor) ---------------- */
.profile-editor {
    display: flex;
    gap: 20px;
    align-items: flex-start;
    flex-wrap: wrap;
}
.profile-picture-preview {
    width: 110px;
    height: 110px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    border: 3px solid var(--color-border);
    box-shadow: var(--shadow-sm);
}
.profile-picture-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-picture-placeholder {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    background: var(--color-primary-light);
    color: var(--color-primary);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 2.2rem;
}
.profile-form { flex: 1; min-width: 220px; }

/* ---------------- Your Teachers (student: photo + bio cards) ---------------- */
.teacher-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
    margin-top: 6px;
}
.teacher-card {
    display: flex;
    gap: 16px;
    text-align: left;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-clay);
    border-radius: var(--radius-sm);
    padding: 16px;
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.teacher-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.teacher-photo {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    border: 3px solid var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.teacher-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.teacher-photo-placeholder {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    background: var(--color-clay-light);
    color: var(--color-clay);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.9rem;
}
.teacher-info { flex: 1; min-width: 0; }
.teacher-name { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--color-ink); }
.teacher-courses { margin-top: 2px; }
.teacher-bio { margin: 8px 0 0; font-size: 0.88rem; line-height: 1.5; color: var(--color-ink); }

/* ---------------- Lesson Plans (student: titled notes + PDFs) ---------------- */


/* ---------------- Course accordion (Lesson Recaps) ---------------- */
.course-accordion { display: flex; flex-direction: column; gap: 12px; }
.accordion-item {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-indigo);
    border-radius: var(--radius);
    overflow: hidden;
}
.accordion-header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--color-ink);
    text-align: left;
    scroll-margin-top: calc(var(--topbar-height, 61px) + 16px);
}
.accordion-meta { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.accordion-count { font-family: var(--font-body); font-weight: 500; font-size: 0.8rem; color: var(--color-muted); }
.accordion-header .chevron { transition: transform 0.25s var(--ease); color: var(--color-muted); }
.accordion-item.is-open .accordion-header .chevron { transform: rotate(180deg); }
.accordion-body {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    padding: 0 20px;
    transition: max-height 0.35s var(--ease), opacity 0.3s var(--ease), padding 0.35s var(--ease);
}
.accordion-item.is-open .accordion-body {
    max-height: 12000px;
    opacity: 1;
    padding: 0 20px 20px;
}

.workspace-subheading {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-muted);
    margin: 18px 0 8px;
}
.workspace-subheading:first-child { margin-top: 4px; }
.workspace-item-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.workspace-item-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: 0.9rem;
    padding: 8px 10px;
    background: var(--color-bg);
    border-radius: var(--radius-sm);
}

/* A general-purpose cap for any free-form teacher-written text shown in
   a compact spot (table cells, list rows) — assignment descriptions,
   quiz instructions, session notes. Without this, one long paragraph
   can blow a single row/card out to an awkward height, especially once
   there are many of them stacked in a list. */
.text-preview {
    max-height: 90px;
    overflow-y: auto;
    padding: 6px 8px;
    margin-top: 4px;
    background: var(--color-bg);
    border-radius: 6px;
    line-height: 1.5;
}

/* ---------------- Join gating (5 minutes before start) ---------------- */
.join-pending { display: none; font-variant-numeric: tabular-nums; }

/* ---------------- Roster list (Manage Students — one compact row per
   student: enroll checkbox + avatar + name + email + Reset/Delete) ---------------- */
.roster-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
    max-height: 160px;
    overflow-y: auto;
    margin-top: 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 4px;
}
.roster-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: 6px;
    transition: background 0.15s var(--ease);
}
.roster-row:hover { background: var(--color-bg); }
.roster-contact-email-form {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 8px 12px 44px;
    flex-wrap: wrap;
}
.roster-contact-email-input {
    flex: 1;
    min-width: 180px;
    padding: 5px 8px;
    font-size: 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    color: var(--color-ink);
}
.roster-row input[type="checkbox"] { flex-shrink: 0; accent-color: var(--color-clay); cursor: pointer; }
.roster-name {
    font-weight: 600;
    font-size: 0.86rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 160px;
}
.roster-email {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.roster-actions { display: flex; gap: 6px; flex-shrink: 0; margin-left: auto; align-items: center; flex-wrap: wrap; }
.roster-cert-form { display: flex; gap: 6px; align-items: center; }
.roster-cert-select {
    padding: 6px 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    color: var(--color-ink);
    font-size: 0.82rem;
    max-width: 160px;
}

/* ---------------- Alerts ---------------- */
.alert {
    padding: 11px 16px;
    border-radius: var(--radius-sm);
    margin-bottom: 16px;
    font-size: 0.9rem;
    border-left: 3px solid transparent;
    animation: slideDown 0.3s var(--ease);
}
.alert-success { background: var(--color-success-bg); color: var(--color-success-text); border-left-color: var(--color-success-text); }
.alert-error   { background: var(--color-error-bg);   color: var(--color-error-text); border-left-color: var(--color-error-text); }

/* ---------------- "New updates" live-check banner ---------------- */
.update-banner {
    position: sticky;
    top: var(--topbar-height, 61px); /* sits right below the topbar */
    z-index: 15;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 10px 16px;
    background: var(--color-amber-light);
    color: var(--color-amber);
    font-size: 0.9rem;
    font-weight: 600;
    border-bottom: 1px solid var(--color-amber);
    animation: slideDown 0.3s var(--ease);
}

/* ---------------- Auth / login page ---------------- */
.auth-body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(circle at 15% 20%, rgba(255,255,255,0.12), transparent 45%),
        radial-gradient(circle at 85% 80%, rgba(255,255,255,0.10), transparent 45%),
        linear-gradient(150deg, var(--color-primary-dark), var(--color-primary) 55%, var(--color-amber));
    padding: 20px;
}
.auth-card {
    background: var(--color-surface);
    padding: 36px;
    border-radius: 16px;
    width: 100%;
    max-width: 380px;
    box-shadow: var(--shadow-lg);
    text-align: center;
    animation: fadeIn 0.4s var(--ease);
}
.auth-card .brand-logo-lg { transition: transform 0.4s var(--ease); }
.auth-card:hover .brand-logo-lg { transform: rotate(-6deg) scale(1.05); }
.auth-card .form { text-align: left; }
.auth-card .subtitle { color: var(--color-muted); margin-top: 0; margin-bottom: 20px; }
.hint { margin-top: 22px; font-size: 0.8rem; color: var(--color-muted); line-height: 1.6; text-align: left; }

/* ---------------- Trial booking page ---------------- */
.trial-page { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 20px; }
.trial-card { max-width: 460px; }
.trial-detail-row { text-align: left; margin: 10px 0; font-size: 0.92rem; }

/* ---------------- Trial booking: brief "Your teacher is X" reveal ---------------- */
.teacher-reveal {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 4px 0 16px;
    padding: 10px 16px;
    background: var(--color-clay-light);
    border-radius: 999px;
    font-size: 0.9rem;
    color: var(--color-clay);
    animation: fadeIn 0.5s var(--ease) both;
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.teacher-reveal.teacher-reveal-hidden { opacity: 0; transform: translateY(-4px); pointer-events: none; }
.teacher-reveal-photo {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}
.teacher-reveal-placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-clay);
    color: #fff;
    font-weight: 700;
    font-size: 0.8rem;
}

/* ---------------- Teacher: inline Zoom-link form in Trial Bookings ---------------- */
.trial-zoom-form { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; }
.trial-zoom-input { width: 170px; flex-shrink: 0; }

/* ---------------- Teacher: My Availability week grid ---------------- */
.availability-week-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin: 8px 0 14px;
    font-size: 0.9rem;
}
.availability-grid-scroll { max-height: 420px; }
.availability-grid th, .availability-grid td { text-align: center; white-space: nowrap; }
.availability-grid th:first-child, .availability-grid td:first-child { text-align: left; white-space: nowrap; }
.availability-grid input[type="checkbox"] { accent-color: var(--color-clay); cursor: pointer; width: 16px; height: 16px; }

/* ---------------- Grading panel (assignments & quizzes) ---------------- */
.grading-panel {
    margin-top: 20px;
    padding: 16px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-indigo);
    border-radius: var(--radius-sm);
}
.grading-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0;
    border-bottom: 1px solid var(--color-border);
    flex-wrap: wrap;
}
.grading-row:last-of-type { border-bottom: none; }
.grading-student-name { width: 140px; flex-shrink: 0; font-weight: 600; font-size: 0.88rem; }
.grading-grade-input { width: 120px; flex: 0 0 auto; }
.grading-note-input { flex: 1; min-width: 160px; }

/* ---------------- Assignment submissions — a student's attached
   photos/files of paper homework, and the teacher's compact preview
   of them alongside each grading row. ---------------- */
.submission-file-list {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin: 10px 0 16px;
}
.submission-file-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 104px;
}
.submission-thumb-link,
.submission-file-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 88px;
    height: 88px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    overflow: hidden;
    flex-shrink: 0;
}
.submission-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.submission-file-icon {
    font-size: 2.1rem;
    text-decoration: none;
}
.submission-file-name {
    max-width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: center;
}
.submission-file-item .btn { padding: 3px 10px; font-size: 0.78rem; }

/* The teacher's compact version, inline within a .grading-row —
   small thumbnails in a row rather than the student's bigger,
   labeled tiles, since this just needs to be a quick visual
   reference while grading, not the primary view. */
.grading-row-submissions { display: flex; flex-wrap: wrap; gap: 6px; }
.submission-file-icon-small {
    width: 36px;
    height: 36px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--color-bg);
    font-size: 1rem;
    text-decoration: none;
}
.submission-thumb-link-small {
    /* Sizes the wrapping <a> itself for the teacher's compact grading
       view — the .submission-thumb img inside it already fills
       whatever container it's in (width/height: 100% from the base
       rule below), so it only needs this on the link, not a second,
       separately-sized class on the image too. */
    width: 36px;
    height: 36px;
}

/* ---------------- Password confirmation modal ---------------- */
.pw-confirm-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.pw-confirm-overlay.pw-confirm-visible { display: flex; }
.pw-confirm-box {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 24px;
    max-width: 360px;
    width: 100%;
    box-shadow: var(--shadow-md);
    animation: fadeIn 0.2s var(--ease) both;
}
.pw-confirm-title { margin: 0 0 6px; font-size: 1.1rem; }
.pw-confirm-message { margin: 0 0 14px; }
.pw-confirm-input { width: 100%; margin-bottom: 6px; }
.pw-confirm-error { color: var(--color-danger); font-size: 0.82rem; margin: 4px 0 0; }
.pw-confirm-actions { display: flex; gap: 10px; margin-top: 16px; justify-content: flex-end; }

/* ================================================================
   Landing page (index.php) — public homepage shown before login
   ================================================================ */
.landing-body { overflow-x: hidden; }

.landing-topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    width: 100%;
    background: rgba(4, 14, 36, 0.85);
    backdrop-filter: blur(8px);
    transition: box-shadow 0.25s var(--ease);
}
.landing-topbar-inner {
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    padding: 16px 24px;
    max-width: 1400px;
    margin: 0 auto;
}
.landing-topbar.is-scrolled { box-shadow: var(--shadow-md); }

.nav-menu { display: flex; align-items: center; gap: 32px; }
.main-nav { display: flex; align-items: center; gap: 26px; }
.main-nav a {
    color: var(--color-ink);
    text-decoration: none;
    font-weight: 500;
    font-size: 0.94rem;
    transition: color 0.15s ease;
}
.main-nav a:hover { color: var(--color-primary); }
.nav-actions { display: flex; align-items: center; gap: 10px; }

.nav-burger {
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 36px;
    height: 36px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    flex-shrink: 0;
}
.nav-burger span {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--color-ink);
    border-radius: 2px;
    transition: transform 0.25s var(--ease), opacity 0.25s var(--ease);
}
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }


@media (max-width: 860px) {
    .nav-burger { display: flex; }
    .nav-menu {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: flex-start;
        gap: 22px;
        background: var(--color-surface);
        padding: 24px;
        border-top: 1px solid var(--color-border);
        border-bottom: 1px solid var(--color-border);
        box-shadow: var(--shadow-md);
    }
    .nav-menu.is-open { display: flex; }
    .main-nav { flex-direction: column; align-items: flex-start; gap: 18px; width: 100%; }
    .main-nav a { font-size: 1rem; }
    .nav-actions { flex-direction: column; align-items: stretch; gap: 10px; width: 100%; }
    .nav-actions .btn { width: 100%; text-align: center; }
}

.hero {
    position: relative;
    min-height: 615px;
    display: flex;
    align-items: center;
    background-image:
        linear-gradient(90deg, var(--color-bg) 0%, rgba(4,14,36,0.86) 30%, rgba(4,14,36,0.35) 60%, rgba(4,14,36,0.05) 85%),
        url('../img/hero-bg.jpg');
    background-size: cover;
    background-position: center 17%;
    background-repeat: no-repeat;
    background-attachment: scroll;
    padding-top: clamp(40px, 8vh, 60px);
    padding-bottom: clamp(40px, 8vh, 60px);
    padding-left: max(24px, calc((100% - 1400px) / 2 + 24px));
    padding-right: max(24px, calc((100% - 1400px) / 2 + 24px));
    margin: 0 0 60px;
}
.hero-copy {
    max-width: 560px;
    text-align: left;
    position: relative;
    z-index: 1;
}
.hero-title {
    font-size: clamp(1.7rem, 1.15rem + 2.2vw, 2.6rem);
    display: block;
    padding-bottom: 0;
    text-align: left;
    animation: fadeIn 0.6s var(--ease) both;
}
.hero-title::after { left: 0; transform: none; }
.hero-subtitle {
    font-size: clamp(0.94rem, 0.85rem + 0.4vw, 1.08rem);
    color: var(--color-muted);
    line-height: 1.6;
    margin: 18px 0 30px;
    animation: fadeIn 0.6s var(--ease) 0.1s both;
}
.hero-cta {
    display: inline-flex;
    width: auto;
    padding: clamp(12px, 1.2vw + 8px, 14px) clamp(26px, 3vw + 14px, 36px);
    font-size: clamp(0.92rem, 0.85rem + 0.3vw, 1rem);
    box-shadow: 0 10px 28px rgba(111, 65, 255, 0.35);
    animation: fadeIn 0.6s var(--ease) 0.2s both;
}
.hero-cta:hover { box-shadow: 0 14px 34px rgba(111, 65, 255, 0.5); }
@media (max-width: 860px) {
    .hero {
        min-height: 460px;
        background-position: center 15%;
        background-size: cover;
        background-repeat: no-repeat;
        padding-top: 40px;
        padding-bottom: 40px;
        padding-left: 24px;
        padding-right: 24px;
    }
    .hero-copy { text-align: center; max-width: 100%; margin: 0 auto; }
    .hero-title { text-align: center; }
    .hero-title::after { left: 50%; transform: translateX(-50%); }
}
@media (max-width: 400px) {
    .hero { min-height: 420px; }
}

.stats-row {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 16px;
    max-width: 1400px;
    margin: 0 auto 60px;
    padding: 0 24px;
}
.stats-row.dashboard-stats-row {
    max-width: none;
    padding: 0;
    justify-content: flex-start;
}
.stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-primary);
    border-radius: var(--radius);
    padding: 24px 32px;
    text-align: center;
    min-width: 160px;
    flex: 1;
    box-shadow: var(--shadow-sm);
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.stat-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md), 0 0 0 1px var(--color-primary-light); }
.stat-card:nth-child(2) { border-top-color: var(--color-amber); }
.stat-card:nth-child(3) { border-top-color: var(--color-clay); }
.stat-number { font-family: var(--font-display); font-size: clamp(1.7rem, 1.3rem + 1.2vw, 2.2rem); font-weight: 700; color: white; }
.stat-label { margin-top: 4px; font-size: 0.85rem; color: var(--color-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }

.landing-section {
    max-width: 1400px;
    margin: 0 auto 60px;
    padding: 0 24px;
}
.landing-section-title {
    font-size: 1.6rem;
    text-align: center;
    position: relative;
    display: inline-block;
    padding-bottom: 8px;
    margin-bottom: 28px;
}
.landing-section-title::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    width: 46px; height: 3px;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--color-primary), var(--color-amber));
    animation: growLine 0.5s var(--ease) 0.1s both;
}
/* .landing-section wraps this in a centered block, so we need the
   title itself centered as a block rather than inline-block here. */
.landing-section { text-align: center; }

.quick-info-panel {
    max-width: 1400px;
    margin: 40px auto 60px;
    padding: 32px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    position: relative;
    z-index: 2;
}
.quick-info-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 28px 24px;
}
.quick-info-row-secondary {
    margin-top: 28px;
    padding-top: 28px;
    border-top: 1px solid var(--color-border);
}
.quick-info-item {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    text-align: left;
    padding: 8px;
    border-radius: var(--radius-sm);
    transition: transform 0.2s var(--ease), background 0.2s var(--ease);
}
.quick-info-item:hover { transform: translateY(-3px); background: rgba(255, 255, 255, 0.05); }
.quick-info-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    font-size: 1.3rem;
    line-height: 1;
    flex-shrink: 0;
    transition: transform 0.2s var(--ease);
}
.quick-info-item:hover .quick-info-icon { transform: scale(1.1); }
.quick-info-row > .quick-info-item:nth-child(1) .quick-info-icon { background: var(--color-primary-light); }
.quick-info-row > .quick-info-item:nth-child(2) .quick-info-icon { background: var(--color-amber-light); }
.quick-info-row > .quick-info-item:nth-child(3) .quick-info-icon { background: var(--color-indigo-light); }
.quick-info-row > .quick-info-item:nth-child(4) .quick-info-icon { background: var(--color-clay-light); }
.quick-info-item h4 {
    margin: 0 0 4px;
    color: var(--color-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
}
.quick-info-item p {
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--color-muted);
}
@media (max-width: 760px) {
    .quick-info-panel { margin-top: 30px; padding: 24px 20px; }
    .quick-info-row { grid-template-columns: repeat(2, 1fr); gap: 24px 16px; }
}
@media (max-width: 480px) {
    .quick-info-row { grid-template-columns: 1fr; }
}

.our-story-section { text-align: left; }
.our-story-inner {
    display: flex;
    align-items: center;
    gap: 60px;
}
.our-story-eyebrow {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-primary);
}
.our-story-text p {
    color: var(--color-muted);
    font-size: 0.98rem;
    line-height: 1.7;
    margin: 14px 0 0;
}
.our-story-visual { position: relative; width: 180px; height: 180px; flex-shrink: 0; }
.our-story-ring {
    position: absolute;
    inset: 0;
    border: 1.5px dashed var(--color-primary);
    border-radius: 50%;
    opacity: 0.35;
    animation: orbitSpin 25s linear infinite;
}
.our-story-badge {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 140px;
    height: 140px;
    border-radius: 50%;
    background: var(--color-primary-light);
    border: 2px solid var(--color-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.4rem;
}
.our-story-badge img {
    width: 140px;
    height: 140px;
    border-radius: 50%;
}
.our-story-dot {
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    animation: orbitPulse 2.4s var(--ease) infinite;
}
.our-story-dot-1 { top: 4px; left: 50%; margin-left: -5px; background: var(--color-indigo); box-shadow: 0 0 8px var(--color-indigo); animation-delay: 0s; }
.our-story-dot-2 { bottom: 22px; right: 8px; background: var(--color-clay); box-shadow: 0 0 8px var(--color-clay); animation-delay: 0.8s; }
.our-story-dot-3 { bottom: 22px; left: 8px; background: var(--color-amber); box-shadow: 0 0 8px var(--color-amber); animation-delay: 1.6s; }
@keyframes orbitSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes orbitPulse {
    0%, 100% { opacity: 0.45; transform: scale(0.85); }
    50% { opacity: 1; transform: scale(1.15); }
}
@media (max-width: 760px) {
    .our-story-inner { flex-direction: column; text-align: center; gap: 32px; }
    .our-story-text { text-align: center; }
}
@media (prefers-reduced-motion: reduce) {
    .our-story-ring, .our-story-dot { animation: none !important; }
}

.landing-cta {
    position: relative;
    text-align: center;
    overflow: hidden;
    padding: 56px 24px;
    border-radius: var(--radius);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
}
.landing-cta .btn { margin-top: 8px; }
.landing-cta-content { position: relative; z-index: 1; }
.starfield { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.star {
    position: absolute;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--color-ink);
    animation: starTwinkle 3.2s ease-in-out infinite;
}
.cta-glow {
    position: absolute;
    width: 260px;
    height: 260px;
    border-radius: 50%;
    filter: blur(60px);
    opacity: 0.28;
    animation: ctaGlowDrift 14s ease-in-out infinite;
}
.cta-glow-1 { top: -80px; left: -60px; background: var(--color-primary); }
.cta-glow-2 { bottom: -90px; right: -60px; background: var(--color-indigo); animation-delay: 3s; animation-direction: reverse; }
@keyframes starTwinkle {
    0%, 100% { opacity: 0.15; }
    50% { opacity: 0.9; }
}
@keyframes ctaGlowDrift {
    0%, 100% { transform: translate(0, 0); }
    50% { transform: translate(24px, 16px); }
}
@media (prefers-reduced-motion: reduce) {
    .star, .cta-glow { animation: none !important; }
}

/* ================================================================
   Programs page (programs.php)
   ================================================================ */
.page-header {
    max-width: 1400px;
    margin: 50px auto 30px;
    padding: 0 24px;
    text-align: left;
}
.page-header-center { text-align: center; }
.page-header-title {
    font-family: var(--font-display);
    font-size: clamp(1.6rem, 1.1rem + 1.8vw, 2.2rem);
    color: var(--color-ink);
    margin: 0 0 8px;
}
.page-header-subtitle { color: var(--color-muted); font-size: clamp(0.9rem, 0.85rem + 0.2vw, 1rem); margin: 0; }

.program-filters-wrap { max-width: 1400px; margin: 0 auto 40px; padding: 0 24px; }
.program-filters { display: flex; flex-wrap: wrap; gap: 10px; }
.filter-tab {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-muted);
    padding: 10px 20px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.88rem;
    cursor: pointer;
    transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.filter-tab:hover { border-color: var(--color-primary); color: var(--color-ink); }
.filter-tab.is-active { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }

.programs-grid-wrap { max-width: 1400px; margin: 0 auto 80px; padding: 0 24px; }
.programs-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.program-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.program-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.program-card-banner { height: 110px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.program-card-icon { font-size: 2.8rem; line-height: 1; }
.program-card-photo { width: 100%; height: 100%; object-fit: cover; }
.program-banner-languages { background: var(--color-primary-light); }
.program-banner-science   { background: var(--color-indigo-light); }
.program-banner-coding    { background: var(--color-amber-light); }
.program-banner-kids      { background: var(--color-clay-light); }
.program-card-body { padding: 20px; flex: 1; display: flex; flex-direction: column; }
.program-card-body h3 { font-family: var(--font-display); font-size: 1.1rem; margin: 0 0 4px; color: var(--color-ink); }
.program-card-age { font-size: 0.78rem; color: var(--color-muted); margin: 0 0 10px; font-weight: 600; }
.program-card-desc { font-size: 0.85rem; color: var(--color-muted); margin: 0 0 18px; line-height: 1.45; flex: 1; }

@media (max-width: 960px) {
    .programs-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .programs-grid { grid-template-columns: 1fr; }
    .page-header-title { font-size: 1.8rem; }
}

/* ================================================================
   How It Works page (how-it-works.php)
   ================================================================ */
.steps-wrap { max-width: 1400px; margin: 0 auto 70px; padding: 0 24px; }
.steps-timeline { position: relative; max-width: 700px; margin: 0 auto; }
.steps-timeline::before {
    content: '';
    position: absolute;
    top: 42px;
    bottom: 42px;
    left: 41px;
    width: 2px;
    background: linear-gradient(180deg, var(--color-primary), var(--color-amber), var(--color-indigo), var(--color-clay), var(--color-primary));
    opacity: 0.4;
}
.step-row {
    display: flex;
    align-items: flex-start;
    gap: 28px;
    margin-bottom: 40px;
    position: relative;
}
.step-row:last-child { margin-bottom: 0; }
.step-line-col { position: relative; z-index: 1; flex-shrink: 0; width: 84px; }
.step-icon-ring {
    width: 84px;
    height: 84px;
    border-radius: 50%;
    background: var(--color-surface);
    border: 2px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.9rem;
    transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.step-row[data-accent="primary"] .step-icon-ring { border-color: var(--color-primary); }
.step-row[data-accent="amber"]   .step-icon-ring { border-color: var(--color-amber); }
.step-row[data-accent="indigo"]  .step-icon-ring { border-color: var(--color-indigo); }
.step-row[data-accent="clay"]    .step-icon-ring { border-color: var(--color-clay); }
.step-row:hover .step-icon-ring { transform: scale(1.08) rotate(-6deg); }
.step-row[data-accent="primary"]:hover .step-icon-ring { box-shadow: 0 0 0 8px var(--color-primary-light); }
.step-row[data-accent="amber"]:hover   .step-icon-ring { box-shadow: 0 0 0 8px var(--color-amber-light); }
.step-row[data-accent="indigo"]:hover  .step-icon-ring { box-shadow: 0 0 0 8px var(--color-indigo-light); }
.step-row[data-accent="clay"]:hover    .step-icon-ring { box-shadow: 0 0 0 8px var(--color-clay-light); }

.step-content { padding-top: 18px; transition: transform 0.3s var(--ease); }
.step-row:hover .step-content { transform: translateX(4px); }
.step-number {
    display: inline-block;
    font-family: var(--font-display);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    padding: 4px 12px;
    border-radius: 999px;
    margin-bottom: 10px;
}
.step-row[data-accent="primary"] .step-number { background: var(--color-primary-light); color: var(--color-primary); }
.step-row[data-accent="amber"]   .step-number { background: var(--color-amber-light); color: var(--color-amber); }
.step-row[data-accent="indigo"]  .step-number { background: var(--color-indigo-light); color: var(--color-indigo); }
.step-row[data-accent="clay"]    .step-number { background: var(--color-clay-light); color: var(--color-clay); }

.step-title { font-family: var(--font-display); font-size: 1.2rem; margin: 0 0 8px; color: var(--color-ink); }
.step-desc { color: var(--color-muted); font-size: 0.92rem; line-height: 1.6; margin: 0; }

.step-icon-ring-finish {
    font-size: 1.6rem;
    border: 2px solid transparent;
    background:
        linear-gradient(var(--color-surface), var(--color-surface)) padding-box,
        linear-gradient(135deg, var(--color-primary), var(--color-indigo), var(--color-amber)) border-box;
    animation: finishPulse 2.4s var(--ease) infinite;
}
.step-row-finish .step-number { background: var(--color-primary-light); color: var(--color-primary); }
@keyframes finishPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(111, 65, 255, 0.35); }
    50% { box-shadow: 0 0 0 12px rgba(111, 65, 255, 0); }
}

@media (min-width: 861px) {
    .steps-timeline { max-width: 1100px; }
    .steps-timeline::before { left: 50%; transform: translateX(-50%); }
    .step-row {
        display: grid;
        grid-template-columns: 1fr 84px 1fr;
        align-items: center;
        gap: 0 40px;
        margin-bottom: 54px;
    }
    .step-line-col { grid-column: 2; justify-self: center; }
    .step-content { grid-column: 1; text-align: right; padding-top: 0; max-width: 420px; margin-left: auto; }
    .step-row:nth-child(even) .step-content { grid-column: 3; text-align: left; margin-left: 0; margin-right: auto; }
    .step-row:hover .step-content { transform: none; }

    .step-row.step-row-finish {
        display: flex !important;
        flex-direction: column !important;
        align-items: center !important;
        text-align: center !important;
    }
    .step-row.step-row-finish .step-content {
        grid-column: unset !important;
        max-width: none !important;
        margin: 0 !important;
        text-align: center !important;
        padding-top: 18px !important;
    }
}

@media (max-width: 560px) {
    .step-row { gap: 18px; }
    .step-line-col { width: 64px; }
    .step-icon-ring { width: 64px; height: 64px; font-size: 1.4rem; }
    .steps-timeline::before { left: 31px; }
    .step-content { padding-top: 10px; }
    .step-title { font-size: 1.05rem; }
}
@media (prefers-reduced-motion: reduce) {
    .step-icon-ring-finish { animation: none !important; }
}

/* ================================================================
   Individual program page (program.php)
   ================================================================ */
.program-detail-wrap { max-width: 1100px; margin: 40px auto 80px; padding: 0 24px; }
.program-detail-back {
    display: inline-block;
    color: var(--color-muted);
    text-decoration: none;
    font-size: 0.88rem;
    margin-bottom: 20px;
    transition: color 0.15s var(--ease);
}
.program-detail-back:hover { color: var(--color-primary); }

.program-detail-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 48px; align-items: start; }

.program-detail-banner {
    height: 200px;
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    margin-bottom: 24px;
}
.program-detail-icon { font-size: 4rem; line-height: 1; }
.program-detail-photo { width: 100%; height: 100%; object-fit: cover; }

.program-detail-title { font-family: var(--font-display); font-size: clamp(1.7rem, 1.2rem + 1.8vw, 2.1rem); margin: 0 0 4px; color: var(--color-ink); }
.program-detail-age { color: var(--color-primary); font-weight: 600; font-size: 0.92rem; margin: 0 0 16px; }
.program-detail-intro { color: var(--color-muted); font-size: 1rem; line-height: 1.65; margin: 0 0 22px; }

.check-list { list-style: none; padding: 0; margin: 0 0 26px; display: flex; flex-direction: column; gap: 11px; }
.check-list li { color: var(--color-ink); font-size: 0.92rem; line-height: 1.5; display: flex; align-items: flex-start; gap: 9px; }
.check-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin-top: 1px;
    border-radius: 50%;
    background: var(--color-success-bg);
    color: var(--color-success-text);
    font-size: 0.7rem;
    font-weight: 700;
}

.program-detail-facts {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 22px;
}
.program-detail-fact { display: flex; flex-direction: column; gap: 3px; text-align: center; }
.program-detail-fact-label { font-size: 0.72rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.program-detail-fact-value { font-weight: 600; font-size: 0.88rem; color: var(--color-ink); }

.program-detail-cta { font-size: 1rem; padding: 14px; }

.program-detail-side { display: flex; flex-direction: column; gap: 20px; }
.program-detail-panel {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
}
.program-detail-panel h3 { font-family: var(--font-display); font-size: 1.05rem; margin: 0 0 16px; color: var(--color-ink); }
.program-detail-panel .check-list { margin-bottom: 0; }

@media (max-width: 860px) {
    .program-detail-grid { grid-template-columns: 1fr; }
}

.site-footer {
    border-top: 1px solid var(--color-border);
    background: var(--color-surface);
    padding: 32px 24px;
    text-align: center;
}
.site-footer .brand-lockup { justify-content: center; margin-bottom: 14px; }
.site-footer-contact { display: flex; justify-content: center; gap: 24px; flex-wrap: wrap; margin-bottom: 12px; }
.site-footer-contact a { color: var(--color-ink); text-decoration: none; font-size: 0.9rem; font-weight: 600; }
.site-footer-contact a:hover { color: var(--color-primary); }
.site-footer-copyright { font-size: 0.8rem; color: var(--color-muted); margin: 0; }

/* Scroll-reveal: sections fade + slide up into view as the visitor
   scrolls to them (assets/js/script.js adds .revealed via
   IntersectionObserver). Without JS, .no-js forces everything visible
   immediately — nothing on the page ever depends on JS to be seen. */
.reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.reveal.revealed { opacity: 1; transform: translateY(0); }
.no-js .reveal { opacity: 1 !important; transform: none !important; }

/* ---------------- Animations ---------------- */
@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes slideDown { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes popIn { 0% { transform: scale(1); } 40% { transform: scale(1.35); } 100% { transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

/* ---------------- Responsive ---------------- */
@media (max-width: 720px) {
    /* Sidebar/layout stacking used to be handled here, before the
       slide-in drawer (.sidebar-edge-tab / .dashboard-sidebar-overlay,
       @media max-width:860px above) existed — that block already
       covers every width from 860px down to 0, so it was silently
       fighting this one below 720px: identical specificity, this
       block came later in the file, so its `.sidebar { width: 100%;
       }` was winning and stretching the drawer edge-to-edge instead
       of the intended ~280px overlay every time someone opened it on
       a narrower phone. Removed the two conflicting lines; the rest
       of this block (padding, type sizes, stacking a couple of
       specific rows) is independent of that and still applies. */
    .content { max-width: 100%; padding: 18px; }
    .topbar { flex-wrap: wrap; gap: 10px; padding: 10px 16px; }
    h1 { font-size: 1.35rem; }
    .course-header { flex-direction: column; align-items: stretch; }
    .panel-toggle { padding: 16px 16px 4px; }
    .panel-body { padding: 6px 16px 18px; }
    .hero-title { font-size: 1.9rem; }
    .stat-card { min-width: 130px; padding: 18px 20px; }
    .landing-section-title { font-size: 1.35rem; }
}

@media (max-width: 460px) {
    .role-tag { display: none; }
    .form-actions { flex-direction: column; }
    .form-actions .btn { width: 100%; }
    .row-actions { flex-wrap: wrap; }
    .auth-card { padding: 26px 22px; }
    .roster-email { display: none; }
    .roster-row { flex-wrap: wrap; }
    .roster-actions { width: 100%; justify-content: flex-end; margin-left: 34px; }
    .teacher-card { flex-direction: column; align-items: center; text-align: center; }
    .profile-editor { justify-content: center; text-align: center; }
    .profile-picture-preview { margin: 0 auto; }
}
