/* ─── Reset & Base ─────────────────────────────────────────── */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* Dark is the default palette (also applies when no data-theme attribute is
   present, e.g. auth_base.html's pre-login pages). */
:root {
    --bg-base:        #0b0f17;
    --bg-surface:     #111827;
    --bg-elevated:    #1a2333;
    --bg-hover:       #1e293b;
    --border:         #27324a;
    --border-muted:   #1c2536;

    --text-primary:   #e2e8f0;
    --text-secondary: #94a3b8;
    --text-muted:     #7b8aa0;

    --accent-blue:    #38bdf8;
    --accent-cyan:    #22d3ee;
    --accent-green:   #34d399;
    --accent-yellow:  #fbbf24;
    --accent-red:     #f87171;
    --accent-purple:  #a78bfa;
    --border-subtle:  #1c2536;

    --sidebar-width:  220px;
}

/* Light theme — opted into per-user via <html data-theme="light">
   (templates/base.html). Every accent got its own darker shade rather than
   reusing the dark-theme hex values, which read too pale as text on a white
   background — see docs in migrations/105_user_theme.sql's companion plan
   for the contrast numbers behind each choice. */
:root[data-theme="light"] {
    --bg-base:        #f1f5f9;
    --bg-surface:     #ffffff;
    --bg-elevated:    #e9eef4;
    --bg-hover:       #dde6ef;
    --border:         #cbd5e1;
    --border-muted:   #e2e8f0;

    --text-primary:   #0f172a;
    --text-secondary: #334155;
    --text-muted:     #5b6b82;

    --accent-blue:    #0369a1;
    --accent-cyan:    #0e7490;
    --accent-green:   #047857;
    --accent-yellow:  #92400e;
    --accent-red:     #b91c1c;
    --accent-purple:  #7c3aed;
    --border-subtle:  #e2e8f0;
}

html, body {
    height: 100%;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: var(--bg-base);
    color: var(--text-primary);
    font-size: 16px;
    line-height: 1.6;
}

a {
    color: var(--accent-blue);
    text-decoration: none;
}

a:hover {
    color: var(--text-primary);
}

/* ─── App Shell ─────────────────────────────────────────────── */
.app-shell {
    display: flex;
    height: 100vh;
    overflow: hidden;
}

/* ─── Sidebar ───────────────────────────────────────────────── */
.sidebar {
    width: var(--sidebar-width);
    background: var(--bg-surface);
    border-right: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    overflow-y: auto;
}

.sidebar-logo {
    padding: 1.25rem 1rem 1rem;
    border-bottom: 1px solid var(--border-subtle);
}

.sidebar-logo .app-name {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-primary);
    display: block;
}

.sidebar-logo .app-tagline {
    font-size: 0.72rem;
    color: var(--accent-cyan);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.sidebar-section {
    padding: 1rem 0 0.5rem;
}

.sidebar-section-label {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 0 1rem 0.4rem;
}

.sidebar-nav {
    list-style: none;
}

.sidebar-nav li a {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.5rem 1rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
    border-left: 2px solid transparent;
    border-radius: 0 4px 4px 0;
    transition: all 0.15s;
}

.sidebar-nav li a:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
    border-left-color: var(--border);
}

.sidebar-nav li a.active {
    color: var(--accent-cyan);
    border-left-color: var(--accent-cyan);
    background: var(--bg-elevated);
    font-weight: 500;
}

.sidebar-subgroup-label {
    font-size: 0.62rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    padding: 0.5rem 1rem 0.2rem 1.6rem;
    list-style: none;
}

.sidebar-nav li a.nav-indented {
    padding-left: 1.75rem;
}

.sidebar-nav li a .nav-icon {
    font-size: 1rem;
    width: 1.1rem;
    text-align: center;
    flex-shrink: 0;
}

/* Per-item icon colors */
.sidebar-nav li a .icon-exam    { color: var(--accent-cyan); }
.sidebar-nav li a .icon-tutor   { color: var(--accent-purple); }
.sidebar-nav li a .icon-lab     { color: var(--accent-green); }
.sidebar-nav li a .icon-skills  { color: var(--accent-yellow); }
.sidebar-nav li a .icon-flash   { color: var(--accent-yellow); }
.sidebar-nav li a .icon-achieve { color: var(--accent-purple); }
.sidebar-nav li a .icon-cert    { color: var(--accent-yellow); }
.sidebar-nav li a .icon-dash    { color: var(--accent-blue); }
.sidebar-nav li a .icon-practice{ color: var(--accent-cyan); }
.sidebar-nav li a .icon-history { color: var(--accent-purple); }

/* Dimmed coming-soon items keep icon color but mute text */
.sidebar-nav li a.coming-soon {
    opacity: 1;
    cursor: not-allowed;
}
.sidebar-nav li a.coming-soon .nav-label {
    color: var(--text-muted);
    font-size: 0.82rem;
}
.sidebar-nav li a.coming-soon .soon-badge {
    margin-left: auto;
    font-size: 0.6rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--bg-elevated);
    border: 1px solid var(--border-muted);
    border-radius: 3px;
    padding: 0.1rem 0.35rem;
}

/* Sidebar stats at the bottom */
.sidebar-stats {
    margin-top: auto;
    padding: 1rem;
    border-top: 1px solid var(--border-subtle);
}

.sidebar-stat {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.3rem 0;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.sidebar-stat .stat-value {
    font-weight: 600;
    color: var(--accent-cyan);
}

/* ─── Main Content ──────────────────────────────────────────── */
.main-content {
    flex: 1;
    overflow-y: auto;
    padding: 0;
    background: var(--bg-base);
    display: flex;
    flex-direction: column;
}

.topbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.4rem 2rem;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--bg-surface);
    flex-shrink: 0;
    gap: 2rem;
}

.topbar-joke {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    overflow: hidden;
}

.topbar-joke-label {
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--accent-cyan);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    white-space: nowrap;
    flex-shrink: 0;
}

.topbar-joke-text {
    font-size: 0.75rem;
    color: var(--text-secondary);
    font-style: italic;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.joke-rate-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.75rem;
    opacity: 0.35;
    padding: 0 0.1rem;
    transition: opacity 0.15s;
    flex-shrink: 0;
}

.joke-rate-btn:hover {
    opacity: 0.8;
}

.joke-rate-btn.rated {
    opacity: 1;
}

/* Compact topbar status pill — XP | Badges count, no level name/bar (the
   level detail lives on the Achievements page; repeating it in the topbar
   on every page was redundant). */
.topbar-status-pill {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-shrink: 0;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.3rem 0.4rem 0.3rem 0.9rem;
}

.topbar-status-item {
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.topbar-status-item strong {
    color: var(--accent-yellow);
    font-weight: 700;
}

.topbar-status-badges strong { color: var(--accent-green); }

.topbar-status-sep { color: var(--border); }


.main-body {
    flex: 1;
    overflow-y: auto;
    padding: 2rem;
}

/* ─── Dashboard Header Joke ─────────────────────────────────── */
.header-joke {
    flex-shrink: 0;
    max-width: 340px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent-cyan);
    border-radius: 10px;
    padding: 0.6rem 0.85rem;
}

.joke-label {
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--accent-cyan);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    display: block;
    margin-bottom: 0.3rem;
}

.joke-text {
    font-size: 0.78rem;
    color: var(--text-secondary);
    font-style: italic;
    line-height: 1.5;
}

/* ─── Notes / Lesson Content ─────────────────────────────────── */
.notes-content {
    color: var(--text-secondary);
    font-size: 0.88rem;
    line-height: 1.8;
}

.notes-content h1,
.notes-content h2 {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--accent-cyan);
    margin: 2rem 0 0.65rem;
    padding: 0.4rem 0 0.4rem 0.75rem;
    border-left: 3px solid var(--accent-cyan);
    border-bottom: 1px solid var(--border);
}

.notes-content h2:first-child {
    margin-top: 0.25rem;
}

.notes-content h3 {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--accent-blue);
    margin: 1.35rem 0 0.45rem;
}

.notes-content h4 {
    font-size: 0.87rem;
    font-weight: 700;
    color: var(--accent-purple);
    margin: 1rem 0 0.3rem;
}

.notes-content p {
    margin-bottom: 0.85rem;
}

.notes-content ul,
.notes-content ol {
    margin: 0.5rem 0 0.85rem 1.4rem;
}

.notes-content li {
    margin-bottom: 0.3rem;
    line-height: 1.7;
}

.notes-content code {
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
    font-size: 0.82rem;
    background: var(--bg-elevated);
    color: var(--accent-cyan);
    padding: 0.1em 0.4em;
    border-radius: 4px;
    border: 1px solid var(--border);
}

.notes-content pre {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.1rem;
    overflow-x: auto;
    margin: 0.75rem 0 1rem;
}

.notes-content pre code {
    background: none;
    border: none;
    padding: 0;
    color: var(--text-primary);
    font-size: 0.84rem;
    line-height: 1.6;
}

.notes-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 0.75rem 0 1rem;
    font-size: 0.83rem;
}

/* Wide reference tables (5+ columns) get their own horizontal scroll instead of
   squeezing every column to fit — wrap the <table> in <div class="table-scroll">. */
.notes-content .table-scroll {
    overflow-x: auto;
    margin: 0.75rem 0 1rem;
}

.notes-content .table-scroll table {
    width: auto;
    min-width: 100%;
    margin: 0;
}

.notes-content th {
    background: var(--bg-elevated);
    color: var(--accent-blue);
    font-weight: 700;
    padding: 0.5rem 0.85rem;
    text-align: left;
    border: 1px solid var(--border);
}

.notes-content td {
    padding: 0.45rem 0.85rem;
    border: 1px solid var(--border);
    color: var(--text-secondary);
}

.notes-content tr:nth-child(even) td {
    background: var(--bg-elevated);
}

.notes-content hr {
    border: none;
    border-top: 1px solid var(--border);
    margin: 1.5rem 0;
}

.notes-content strong {
    color: var(--text-primary);
    font-weight: 700;
}

.notes-content blockquote {
    border-left: 3px solid var(--accent-yellow);
    padding: 0.5rem 1rem;
    margin: 0.75rem 0;
    background: var(--bg-elevated);
    border-radius: 0 6px 6px 0;
    color: var(--text-muted);
    font-style: italic;
}

.page-header {
    margin-bottom: 1.75rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--border);
}

.page-header h1 {
    font-size: 1.4rem;
    font-weight: 600;
    color: var(--text-primary);
}

.page-header p {
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin-top: 0.25rem;
}

/* ─── Future Learning ───────────────────────────────────────── */
.future-learning-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.75rem 0 0;
}

.future-toggle {
    font-size: 0.68rem;
    color: var(--text-muted);
    letter-spacing: 0.04em;
}

.future-group {
    margin-bottom: 0.85rem;
}

.future-group:last-child {
    margin-bottom: 0;
}

.future-group-label {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 0.4rem;
}

.future-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.future-tag {
    font-size: 0.75rem;
    color: var(--text-secondary);
    background: var(--bg-elevated);
    border: 1px solid var(--border-muted);
    border-radius: 20px;
    padding: 0.2rem 0.65rem;
}

/* ─── Cards ─────────────────────────────────────────────────── */
.card {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.25rem;
}

.card-hover-blue:hover { border-color: var(--accent-blue); }
.trivia-label:hover { border-color: var(--accent-purple) !important; }

.card-grid {
    display: grid;
    gap: 1rem;
}

.card-grid-2 { grid-template-columns: repeat(2, 1fr); }
.card-grid-3 { grid-template-columns: repeat(3, 1fr); }
.card-grid-4 { grid-template-columns: repeat(4, 1fr); }

.stat-card {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.1rem 1.25rem;
}

.stat-card .stat-label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.4rem;
}

.stat-card .stat-value {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.2;
}

.stat-card .stat-sub {
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin-top: 0.25rem;
}

.stat-card.green  { border-left: 3px solid var(--accent-green); }
.stat-card.blue   { border-left: 3px solid var(--accent-blue); }
.stat-card.cyan   { border-left: 3px solid var(--accent-cyan); }
.stat-card.yellow { border-left: 3px solid var(--accent-yellow); }
.stat-card.red    { border-left: 3px solid var(--accent-red); }
.stat-card.purple { border-left: 3px solid var(--accent-purple); }

/* Section header inside content */
.section-header {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin: 1.75rem 0 0.75rem;
}

/* Phase/status badge */
.badge {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 600;
    padding: 0.15rem 0.5rem;
    border-radius: 20px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.badge-active  { background: rgba(63,185,80,0.15);  color: var(--accent-green); }
.badge-soon    { background: rgba(56,139,253,0.15);  color: var(--accent-blue); }
.badge-planned { background: rgba(72,79,88,0.3);     color: var(--text-muted); }

/* Progress bar */
.progress-bar {
    height: 5px;
    background: var(--bg-elevated);
    border-radius: 3px;
    overflow: hidden;
    margin-top: 0.5rem;
}

.progress-bar-fill {
    height: 100%;
    border-radius: 3px;
    background: var(--accent-cyan);
    transition: width 0.4s ease;
}

/* ─── Forms ─────────────────────────────────────────────────── */
.form-group {
    margin-bottom: 1rem;
}

.form-group label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.4rem;
}

select, textarea, input[type="text"] {
    width: 100%;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    color: var(--text-primary);
    border-radius: 10px;
    padding: 0.55rem 0.8rem;
    font-size: 0.9rem;
    outline: none;
    transition: border-color 0.15s;
}

select:focus, textarea:focus, input:focus {
    border-color: var(--accent-blue);
}

/* Password field with a show/hide toggle button overlaid inside it */
.password-field-wrapper {
    position: relative;
}

.password-toggle-btn {
    position: absolute;
    right: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--text-muted);
    display: flex;
    align-items: center;
}

.password-toggle-btn:hover {
    color: var(--text-primary);
}

/* ─── Buttons ───────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 1.1rem;
    border-radius: 10px;
    font-size: 0.85rem;
    font-weight: 500;
    cursor: pointer;
    border: 1px solid transparent;
    transition: all 0.15s;
}

.btn-primary {
    background: var(--accent-blue);
    color: #fff;
    border-color: var(--accent-blue);
}

.btn-primary:hover {
    background: #0ea5e9;
    border-color: #0ea5e9;
}

.btn-secondary {
    background: var(--bg-elevated);
    color: var(--text-primary);
    border-color: var(--border);
}

.btn-secondary:hover {
    background: var(--bg-hover);
    border-color: var(--text-muted);
}

.btn-success {
    background: rgba(63,185,80,0.15);
    color: var(--accent-green);
    border-color: rgba(63,185,80,0.3);
}

/* ─── Difficulty Badge ──────────────────────────────────────── */
.difficulty-badge {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.15rem 0.5rem;
    border-radius: 3px;
}
.difficulty-beginner     { background: rgba(63,185,80,0.15);  color: var(--accent-green); }
.difficulty-intermediate { background: rgba(210,153,34,0.15); color: var(--accent-yellow); }
.difficulty-advanced     { background: rgba(248,81,73,0.15);  color: var(--accent-red); }

/* ─── Practice Page ─────────────────────────────────────────── */
.question-card {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.5rem;
    margin-bottom: 1rem;
    line-height: 1.8;
    font-size: 0.95rem;
}

.question-topic {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--accent-cyan);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.75rem;
}

.answer-options {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-bottom: 1.25rem;
}

.answer-option {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.15s;
    font-size: 0.9rem;
}

.answer-option:hover {
    border-color: var(--accent-blue);
    background: var(--bg-hover);
}

.answer-option input[type="radio"] {
    margin-top: 0.15rem;
    accent-color: var(--accent-cyan);
    flex-shrink: 0;
}

.answer-option.selected {
    border-color: var(--accent-cyan);
    background: rgba(57,208,216,0.05);
}

.answer-letter {
    font-weight: 700;
    color: var(--text-secondary);
    flex-shrink: 0;
    width: 1rem;
}

/* ─── Result Feedback ───────────────────────────────────────── */
.result-card {
    border-radius: 10px;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1rem;
}

.result-card.correct {
    background: rgba(63,185,80,0.08);
    border: 1px solid rgba(63,185,80,0.3);
}

.result-card.incorrect {
    background: rgba(248,81,73,0.08);
    border: 1px solid rgba(248,81,73,0.3);
}

.result-title {
    font-size: 1rem;
    font-weight: 700;
    margin-bottom: 0.4rem;
}

.result-card.correct  .result-title { color: var(--accent-green); }
.result-card.incorrect .result-title { color: var(--accent-red); }

.result-answers {
    font-size: 0.82rem;
    color: var(--text-secondary);
    margin-bottom: 1rem;
}

.explanation-box {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1rem;
    font-size: 0.88rem;
    color: var(--text-secondary);
    line-height: 1.75;
}

/* ─── Loading ───────────────────────────────────────────────── */
.htmx-indicator {
    display: none;
    font-size: 0.8rem;
    color: var(--text-secondary);
    margin-left: 0.75rem;
}

.htmx-request .htmx-indicator { display: inline; }

/* ─── Badges ────────────────────────────────────────────────── */
.badge-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    width: 88px;
    cursor: default;
}

.badge-shape-wrap {
    width: 72px;
    height: 72px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.badge-shape {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    font-weight: 700;
    color: #fff;
    transition: transform 0.2s ease;
}

.badge-card:hover .badge-shape { transform: scale(1.08); }

.badge-hex  { width: 72px; height: 72px; clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%); }
.badge-shield { width: 64px; height: 72px; clip-path: polygon(0% 0%, 100% 0%, 100% 65%, 50% 100%, 0% 65%); }
.badge-circle { width: 68px; height: 68px; border-radius: 50%; }

/* Locked */
/* filter (not just color) so emoji glyphs like the Coffee Benefactor's ☕
   also gray out — emoji render from the font's own embedded color data and
   ignore the CSS `color` property, but a grayscale filter still affects the
   rendered pixels. No visible effect on the plain-text ▲/◆/● glyphs, which
   were already grayed out via `color` alone. */
.badge-shape-locked { background: #21262d; color: #30363d; filter: grayscale(1) brightness(0.55); opacity: 0.6; }

/* Streak — red */
.badge-shape-streak { background: linear-gradient(145deg, #c0392b, #e74c3c); box-shadow: 0 0 10px rgba(231,76,60,0.35); }

/* Knowledge — blue */
.badge-shape-knowledge { background: linear-gradient(145deg, #1a56db, #388bfd); box-shadow: 0 0 10px rgba(56,139,253,0.35); }

/* Milestone — green */
.badge-shape-milestone { background: linear-gradient(145deg, #196f3d, #3fb950); box-shadow: 0 0 10px rgba(63,185,80,0.35); border: 2px solid rgba(63,185,80,0.4); }

/* Elite — gold */
.badge-shape-elite { background: linear-gradient(145deg, #b8860b, #ffd700); box-shadow: 0 0 18px rgba(255,215,0,0.45); animation: badge-pulse 2.5s infinite; }

/* Supporter — amber (manually granted, never auto-awarded — see Coffee Benefactor) */
.badge-shape-supporter { background: linear-gradient(145deg, #92400e, #d97706); box-shadow: 0 0 10px rgba(217,119,6,0.4); }
.badge-supporter .badge-card-name { color: var(--accent-yellow); }

@keyframes badge-pulse {
    0%, 100% { box-shadow: 0 0 18px rgba(255,215,0,0.45); }
    50%       { box-shadow: 0 0 28px rgba(255,215,0,0.7); }
}

/* SVG badge icons — the art already bakes in its own frame/gradient, so
   locked state is a filter over the same image rather than a separate shape. */
.badge-icon-img {
    width: 72px;
    height: 72px;
    transition: transform 0.2s ease;
}

.badge-card:hover .badge-icon-img { transform: scale(1.08); }

.badge-icon-locked {
    filter: grayscale(1) brightness(0.55);
    opacity: 0.6;
}

.badge-card-name {
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-align: center;
    line-height: 1.3;
}

.badge-locked .badge-card-name { color: #484f58; }
.badge-elite  .badge-card-name { color: #ffd700; }
.badge-streak .badge-card-name { color: #e74c3c; }
.badge-knowledge .badge-card-name { color: #388bfd; }
.badge-milestone .badge-card-name { color: #3fb950; }

.badge-card-date {
    font-size: 0.58rem;
    color: var(--text-muted);
    text-align: center;
}

.badge-card-locked {
    font-size: 0.58rem;
    color: #30363d;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* ─── Admin Collapsible Cards (exam/class accordions, /admin & /admin/classes) ─── */
.admin-collapsible-summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.admin-collapsible-summary::-webkit-details-marker { display: none; }
.admin-collapsible-summary .disclosure-arrow {
    display: inline-block;
    color: var(--text-muted);
    font-size: 0.7rem;
    transition: transform 0.15s ease;
}
.admin-collapsible[open] > .admin-collapsible-summary .disclosure-arrow {
    transform: rotate(90deg);
}
.admin-collapsible-body {
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border);
}

/* ─── Flash Messages (one-time success/error banner, see utils/flash.py) ─── */
.flash-message {
    border-radius: 10px;
    padding: 0.65rem 1.1rem;
    margin-bottom: 1.25rem;
    font-size: 0.85rem;
    border: 1px solid var(--border);
}
.flash-message.flash-success {
    border-left: 3px solid var(--accent-green);
    color: var(--accent-green);
    background: rgba(74,222,128,0.08);
}
.flash-message.flash-error {
    border-left: 3px solid var(--accent-red);
    color: var(--accent-red);
    background: rgba(248,81,73,0.08);
}

/* ─── Today I Learned Banner ────────────────────────────────── */
.til-banner {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent-purple);
    border-radius: 10px;
    padding: 0.75rem 1.1rem;
    margin-bottom: 1rem;
}

.til-label {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--accent-purple);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 0.35rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.til-category {
    font-size: 0.65rem;
    color: var(--text-muted);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--bg-elevated);
    border-radius: 3px;
    padding: 0.1rem 0.4rem;
}

.til-fact {
    font-size: 0.85rem;
    color: var(--text-secondary);
    line-height: 1.6;
}

/* ─── Flashcard Flip ────────────────────────────────────────── */
.fc-scene {
    width: 100%;
    max-width: 680px;
    margin: 0 auto;
    height: 220px;
    perspective: 1000px;
    cursor: pointer;
}

.fc-card {
    width: 100%;
    height: 100%;
    position: relative;
    transform-style: preserve-3d;
    transition: transform 0.5s ease;
}

.fc-card.flipped {
    transform: rotateY(180deg);
}

.fc-face {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    justify-content: safe center;
    align-items: center;
    padding: 1.5rem 2rem;
    text-align: center;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-top: 2px solid var(--accent-cyan);
    overflow-y: auto;
}

.fc-back {
    transform: rotateY(180deg);
    border-top-color: var(--accent-green);
}

.fc-hint {
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 0.75rem;
}

.fc-text {
    font-size: 1rem;
    color: var(--text-primary);
    line-height: 1.6;
}

/* Rating buttons */
.fc-btn-again { background: rgba(248,81,73,0.12);  color: var(--accent-red);    border-color: rgba(248,81,73,0.3); }
.fc-btn-hard  { background: rgba(210,153,34,0.12); color: var(--accent-yellow); border-color: rgba(210,153,34,0.3); }
.fc-btn-good  { background: rgba(56,139,253,0.12); color: var(--accent-blue);   border-color: rgba(56,139,253,0.3); }
.fc-btn-easy  { background: rgba(63,185,80,0.12);  color: var(--accent-green);  border-color: rgba(63,185,80,0.3); }

.fc-btn-again:hover { background: rgba(248,81,73,0.25);  color: var(--accent-red); }
.fc-btn-hard:hover  { background: rgba(210,153,34,0.25); color: var(--accent-yellow); }
.fc-btn-good:hover  { background: rgba(56,139,253,0.25); color: var(--accent-blue); }
.fc-btn-easy:hover  { background: rgba(63,185,80,0.25);  color: var(--accent-green); }

.fc-interval {
    font-size: 0.68rem;
    opacity: 0.7;
    margin-left: 0.3rem;
}

/* ─── Scrollbars (thin on Windows/Chrome) ───────────────────── */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--text-muted) transparent;
}

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--text-muted); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }

/* ─── Responsive ────────────────────────────────────────────── */

/* Laptop / Surface Pro (≤1280px) */
@media (max-width: 1280px) {
    :root { --sidebar-width: 190px; }

    .main-body { padding: 1.25rem 1.5rem; }

    .topbar { padding: 0.4rem 1.25rem; gap: 1rem; }

    .card-grid-4 { grid-template-columns: repeat(2, 1fr); }
}

/* Small laptop (≤1024px) */
@media (max-width: 1024px) {
    :root { --sidebar-width: 170px; }

    .main-body { padding: 1rem 1.25rem; }

    .topbar { padding: 0.4rem 1rem; }

    .card-grid-3 { grid-template-columns: repeat(2, 1fr); }
}

/* Tablet / mobile (≤768px) */
@media (max-width: 768px) {
    :root { --sidebar-width: 0px; }

    .sidebar { display: none; }

    .card-grid-2,
    .card-grid-3,
    .card-grid-4 { grid-template-columns: 1fr; }

    .main-body { padding: 1rem; }

    .topbar { padding: 0.4rem 1rem; }

    /* Hide the XP/badge counts but keep the avatar button reachable. */
    .topbar-status-item, .topbar-status-sep { display: none; }
    .topbar-status-pill { padding: 0.3rem; border: none; background: none; }
}

/* ─── Pygments Monokai Syntax Highlighting ───────────────────── */
pre { line-height: 125%; }
.highlight { background: #272822; color: #F8F8F2; border-radius:8px; padding:1rem 1.1rem; overflow-x:auto; margin:0.75rem 0 1rem; }
.highlight pre { background:none; border:none; padding:0; margin:0; border-radius:0; }
.highlight .c { color: #959077 }
.highlight .err { color: #ED007E; background-color: #1E0010 }
.highlight .k { color: #66D9EF }
.highlight .l { color: #AE81FF }
.highlight .n { color: #F8F8F2 }
.highlight .o { color: #FF4689 }
.highlight .p { color: #F8F8F2 }
.highlight .ch { color: #959077 }
.highlight .cm { color: #959077 }
.highlight .cp { color: #959077 }
.highlight .c1 { color: #959077 }
.highlight .cs { color: #959077 }
.highlight .gd { color: #FF4689 }
.highlight .ge { color: #F8F8F2; font-style: italic }
.highlight .gi { color: #A6E22E }
.highlight .go { color: #66D9EF }
.highlight .gp { color: #FF4689; font-weight: bold }
.highlight .gs { color: #F8F8F2; font-weight: bold }
.highlight .kc { color: #66D9EF }
.highlight .kd { color: #66D9EF }
.highlight .kn { color: #FF4689 }
.highlight .kp { color: #66D9EF }
.highlight .kr { color: #66D9EF }
.highlight .kt { color: #66D9EF }
.highlight .m  { color: #AE81FF }
.highlight .s  { color: #E6DB74 }
.highlight .na { color: #A6E22E }
.highlight .nb { color: #F8F8F2 }
.highlight .nc { color: #A6E22E }
.highlight .no { color: #66D9EF }
.highlight .nd { color: #A6E22E }
.highlight .nf { color: #A6E22E }
.highlight .nt { color: #FF4689 }
.highlight .nv { color: #F8F8F2 }
.highlight .ow { color: #FF4689 }
.highlight .mf { color: #AE81FF }
.highlight .mh { color: #AE81FF }
.highlight .mi { color: #AE81FF }
.highlight .mo { color: #AE81FF }
.highlight .s2 { color: #E6DB74 }
.highlight .se { color: #AE81FF }
.highlight .sh { color: #E6DB74 }
.highlight .si { color: #E6DB74 }
.highlight .s1 { color: #E6DB74 }
.highlight .ss { color: #E6DB74 }
.highlight .fm { color: #A6E22E }
.highlight .il { color: #AE81FF }

/* ─── Avatars ───────────────────────────────────────────────── */

/* Avatars are SVGs (static/avatars/) authored circular from the start —
   gradient ring frame + dark core + icon, same technique as the badge SVGs —
   so no cropping is needed; the same file works in the compact topbar/
   sidebar circle and the picker modal grid. */
.avatar-circle {
    display: block;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
}

.avatar-circle img {
    width: 100%;
    height: 100%;
    display: block;
}

.avatar-btn {
    all: unset;
    cursor: pointer;
    display: flex;
    align-items: center;
    border-radius: 50%;
    transition: transform 0.15s ease;
}

.avatar-btn:hover { transform: scale(1.07); }

.theme-toggle-btn {
    all: unset;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    padding: 0.3rem;
    border-radius: 50%;
    transition: color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.theme-toggle-btn:hover {
    color: var(--accent-yellow);
    background: var(--bg-hover);
    transform: scale(1.07);
}

/* Sidebar footer profile card — one bordered pill holding avatar/name/level
   plus a small gear-icon logout button, instead of a separate full-width
   "Log Out (email)" nav row competing visually with it. */
.sidebar-profile-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.45rem 0.5rem;
    transition: background 0.15s ease;
}

.sidebar-profile-card:hover { background: var(--bg-hover); }

.sidebar-profile-main {
    all: unset;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
    flex: 1;
}

.sidebar-profile-main .avatar-circle {
    width: 34px;
    height: 34px;
    border: 1px solid var(--border);
    flex-shrink: 0;
}

.sidebar-profile-text {
    min-width: 0;
    overflow: hidden;
}

.sidebar-profile-name {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.15s ease;
}

.sidebar-profile-main:hover .sidebar-profile-name { color: var(--accent-cyan); }

.sidebar-profile-role {
    display: block;
    font-size: 0.65rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-logout-btn {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    padding: 0.5rem 1rem;
    color: var(--text-secondary);
    font-size: 0.8rem;
    border-left: 2px solid transparent;
    border-radius: 0 4px 4px 0;
    transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.nav-logout-btn:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
    border-left-color: var(--border);
}

.nav-logout-btn .nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.1rem;
    flex-shrink: 0;
}

/* Avatar picker modal */
.avatar-modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.65);
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.avatar-modal-overlay.open { display: flex; }

.avatar-modal {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-top: 2px solid var(--accent-cyan);
    border-radius: 8px;
    width: 100%;
    max-width: 440px;
    max-height: 85vh;
    overflow-y: auto;
    padding: 1.25rem;
}

.avatar-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--border-muted);
    padding-bottom: 0.75rem;
}

.avatar-modal-header h3 {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-primary);
}

.avatar-modal-close {
    all: unset;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 1rem;
    padding: 0.1rem 0.3rem;
}

.avatar-modal-close:hover { color: var(--text-primary); }

.avatar-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.75rem;
}

.avatar-option {
    all: unset;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    padding: 0.6rem 0.4rem;
    border-radius: 10px;
    border: 2px solid transparent;
    background: var(--bg-elevated);
    text-align: center;
    transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}

.avatar-option:hover { transform: scale(1.03); background: var(--bg-hover); }
.avatar-option.selected { border-color: var(--accent-cyan); }

.avatar-option img {
    display: block;
    width: 64px;
    height: 64px;
}

.avatar-option-name {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-primary);
}

.avatar-option-title {
    font-size: 0.62rem;
    color: var(--text-muted);
}

/* ─── Print (Study Notes → PDF) ───────────────────────────────
   Scoped to body.printing-notes so it only takes effect when the
   Print / Save as PDF button on the notes page triggers window.print().
   Everything outside .notes-print-area is hidden; the notes content
   is re-rendered on a white background since the dark theme's page
   background doesn't print, but keeps darkened versions of the same
   accent hues (not grayscale) so headings/tables/gotchas stay
   visually distinct on paper. print-color-adjust forces browsers to
   actually render the tinted backgrounds instead of silently
   dropping them (the "Background graphics" print-dialog checkbox). */
@media print {
    body.printing-notes .sidebar,
    body.printing-notes .topbar,
    body.printing-notes .page-header > div:last-child,
    body.printing-notes .no-print {
        display: none !important;
    }

    body.printing-notes,
    body.printing-notes html {
        height: auto !important;
    }

    body.printing-notes .app-shell {
        height: auto !important;
        overflow: visible !important;
    }

    body.printing-notes .main-content {
        height: auto !important;
        overflow: visible !important;
        margin-left: 0 !important;
        padding: 0 !important;
        background: #fff !important;
    }

    body.printing-notes .main-body {
        height: auto !important;
        overflow: visible !important;
    }

    /* The 3-tier course engine's phase page is a two-column grid (phases
       sidebar + content). Hiding the sidebar via .no-print leaves its 200px
       track behind and the content indented, so collapse the grid outright
       for print — otherwise a printed Learn tier sits in a narrow right-hand
       strip. */
    body.printing-notes .phase-layout {
        display: block !important;
        max-width: none !important;
    }

    body.printing-notes,
    body.printing-notes .card,
    body.printing-notes .notes-content,
    body.printing-notes .notes-content * {
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
        color-adjust: exact !important;
    }

    body.printing-notes,
    body.printing-notes .card {
        background: #fff !important;
        color: #1a1a1a !important;
        box-shadow: none !important;
        border: none !important;
    }

    body.printing-notes .notes-content {
        color: #1a1a1a !important;
    }

    body.printing-notes .notes-content h1,
    body.printing-notes .notes-content h2 {
        color: #0e7c86 !important;
        border-color: #c9e6e8 !important;
    }

    body.printing-notes .notes-content h3 {
        color: #1f5fc4 !important;
    }

    body.printing-notes .notes-content h4 {
        color: #7c3aed !important;
    }

    body.printing-notes .notes-content code,
    body.printing-notes .notes-content pre {
        background: #f2f2f2 !important;
        color: #0e7c86 !important;
        border-color: #ccc !important;
    }

    body.printing-notes .notes-content pre code {
        color: #1a1a1a !important;
    }

    body.printing-notes .notes-content th,
    body.printing-notes .notes-content td {
        border-color: #ccc !important;
        color: #1a1a1a !important;
    }

    body.printing-notes .notes-content th {
        background: #eaf2fe !important;
        color: #1f5fc4 !important;
    }

    body.printing-notes .notes-content tr:nth-child(even) td {
        background: #f7f7f7 !important;
    }

    body.printing-notes .notes-content strong {
        color: #000 !important;
    }

    body.printing-notes .notes-content blockquote {
        background: #fff8e6 !important;
        border-color: #d29922 !important;
        color: #8a6d1a !important;
    }
}

/* ── Familiarize exercise cards (3-tier course engine) ─────────────────────
   Tier 2 is goal-driven exercises, not a command checklist (decided
   2026-08-15, ops/decisions-log.md). The hint sits in a native <details> so
   it stays hidden by default — revealing it up front would defeat a prompt
   written to make the learner work out the tool themselves — and needs no
   JS, so there's no CSP inline-handler problem. */

.exercise {
    border-left: 3px solid var(--border);
}

/* Header is deliberately just "Exercise N" — never the command. The prompt
   withholds the tool on purpose, so naming it here would answer the exercise
   before the learner reads it; that's what the hint is for.
   It doubles as the card's <summary>, so it carries the same custom
   disclosure arrow as .admin-collapsible-summary rather than a second
   convention. */
.exercise-header {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
}

.exercise-header::-webkit-details-marker { display: none; }

.exercise-header .disclosure-arrow {
    display: inline-block;
    font-size: 0.6rem;
    transition: transform 0.15s ease;
}

.exercise[open] > .exercise-header .disclosure-arrow {
    transform: rotate(90deg);
}

/* A collapsed card is a single header line, so its bottom margin would leave a
   dead gap under the summary. */
.exercise:not([open]) > .exercise-header {
    margin-bottom: 0;
}

.exercise-prompt {
    font-size: 0.85rem;
    color: var(--text-secondary);
    line-height: 1.6;
    margin-bottom: 0.6rem;
}

.exercise-hint {
    font-size: 0.78rem;
    margin-bottom: 0.6rem;
}

.exercise-hint summary {
    cursor: pointer;
    color: var(--accent-blue);
    font-weight: 600;
}

.exercise-hint p {
    margin: 0.4rem 0 0;
    color: var(--text-secondary);
}

/* ── Learn tab: generated table of contents ─────────────────────────── */
/* Lives inside the phases rail, which is already position:sticky, so this
   needs no positioning of its own — only a rule separating it from the phase
   list above it. Capped in height so a long contents list can scroll rather
   than pushing the sticky rail past the bottom of the viewport. */
.learn-toc {
    margin-top: 1.25rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border);
    font-size: 0.72rem;
    max-height: 55vh;
    overflow-y: auto;
}

.learn-toc-title {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
}

.learn-toc ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.learn-toc ul ul {
    padding-left: 0.6rem;
}

.learn-toc li {
    margin: 0.15rem 0;
}

.learn-toc a {
    color: var(--text-muted);
    text-decoration: none;
    display: block;
    line-height: 1.3;
    padding: 0.2rem 0.5rem;
    border-radius: 5px;
    border-left: 2px solid transparent;
}

.learn-toc a:hover {
    color: var(--text-primary);
    background: var(--bg-elevated);
}

/* Set by app.js as the reader scrolls — which section you're in is the one
   thing a static list of links can't tell you. Matches how the phase list
   above marks the current phase. */
.learn-toc a.toc-active {
    color: var(--text-primary);
    background: var(--bg-elevated);
    border-left-color: var(--accent-blue);
    font-weight: 600;
}

/* Where this exercise can be run (migration 202's runs_on). A quiet chip, not
   a warning: "Snapshot first" is information the learner acts on before
   starting, not an alert competing with the prompt for attention. */
.exercise-runs-on {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 0.05rem 0.3rem;
}

.exercise-solution {
    margin: 0.55rem 0 0;
    padding: 0.5rem 0.65rem;
    border-left: 2px solid var(--accent-yellow);
    background: var(--bg-elevated);
    border-radius: 0 4px 4px 0;
}

/* Deliberately not styled like the hint: revealing the worked answer is a
   different act from taking a nudge, and should look like one. */
.exercise-solution summary {
    cursor: pointer;
    color: var(--accent-yellow);
    font-weight: 600;
}

.exercise-solution p {
    margin: 0.4rem 0 0;
    color: var(--text-secondary);
}

.exercise-solution-noted {
    font-size: 0.72rem;
    color: var(--text-muted) !important;
    font-style: italic;
}

.exercise-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    border-top: 1px solid var(--border);
    padding-top: 0.6rem;
}

.exercise-criteria {
    font-size: 0.75rem;
    color: var(--text-muted);
    line-height: 1.5;
}

/* Completion is shown on the marker and the left edge only — recolouring the
   whole card would wash out the prompt text the learner still needs to read. */
.exercise.exercise-done {
    border-left-color: var(--accent-green);
}

.exercise.exercise-done .exercise-header {
    color: var(--accent-green);
}

/* ── Phase page layout (3-tier course engine) ──────────────────────────────
   Phases sidebar + content, one reading-width column. It was a two-column
   split on Familiarize while the tab hosted a browser terminal beside the
   exercise list; that sandbox was removed 2026-08-20 (Tier 2 is now done on
   the learner's own machine), so there is no second column to make room for
   and the page stays at reading width on every tab. */

.phase-layout {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 1.5rem;
    max-width: 1000px;
    align-items: start;
}


