/* ============================================================
   East Voyager Academy — Public Site Stylesheet
   Depends on: tokens.css (loaded first)
   ============================================================ */

/* ── Layout ──────────────────────────────────────────────────────────────── */

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.container-wide {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

/* ── Utility ─────────────────────────────────────────────────────────────── */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
h1,h2,h3,h4,h5,h6 { margin: 0 0 .5em; line-height: 1.2; }
ul, ol { margin: 0; padding: 0 0 0 1.2em; }
img { max-width: 100%; height: auto; }
a { color: var(--md-primary); } /* navy in light, tonal blue in dark */

/* ── Buttons ─────────────────────────────────────────────────────────────── */

/* Material pill buttons - shape from the shared token scale */
.btn {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .65rem 1.5rem;
    border-radius: var(--radius-full);
    font-family: var(--font-body);
    font-size: .88rem;
    font-weight: 600;
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: var(--transition);
    line-height: 1;
    white-space: nowrap;
}

.btn-primary {
    background: var(--eva-orange);
    color: #fff;
}
.btn-primary:hover {
    background: #d94e00;
    color: #fff;
}

.btn-secondary {
    background: transparent;
    color: #fff;
    border: 1.5px solid rgba(255, 255, 255, .5);
}
.btn-secondary:hover {
    background: rgba(255, 255, 255, .1);
    color: #fff;
}

.btn-navy {
    background: var(--eva-navy);
    color: #fff;
}
.btn-navy:hover {
    background: var(--eva-navy-dark);
    color: #fff;
}

.btn-ghost {
    background: transparent;
    color: var(--md-primary);
    border: 1.5px solid var(--border);
}
.btn-ghost:hover {
    border-color: var(--eva-navy);
    background: var(--surface-alt);
}

.btn-danger {
    background: var(--error);
    color: #fff;
}
.btn-danger:hover {
    background: #c0392b;
}

.btn-outline-white {
    background: transparent;
    color: #fff;
    border: 1.5px solid rgba(255,255,255,.5);
}
.btn-outline-white:hover {
    background: rgba(255,255,255,.1);
    color: #fff;
}

.btn-sm {
    padding: .4rem .9rem;
    font-size: .8rem;
}

/* ── Cards ───────────────────────────────────────────────────────────────── */

.card {
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    padding: 1.5rem;
    transition: box-shadow .2s, border-color .2s;
}

.card:hover {
    box-shadow: var(--shadow-lg);
    border-color: var(--border);
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.card h3 {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: .6rem;
    color: var(--text);
}

.card p {
    font-size: .88rem;
    color: var(--text-muted);
    line-height: 1.65;
    margin: 0;
}

.card-header {
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--border-light);
    font-weight: 600;
    font-family: var(--font-display);
}

.card-body {
    padding: 1.5rem;
}

/* ── Sections ────────────────────────────────────────────────────────────── */

.section {
    padding: 4.5rem 0;
}

.section-sm {
    padding: 2.5rem 0;
}

.section-alt {
    background: var(--surface-alt);
}

.section-navy {
    background: var(--eva-navy);
    color: #fff;
}

.section-header {
    text-align: center;
    margin-bottom: 3rem;
}

.section-eyebrow {
    display: block;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--eva-orange);
    margin-bottom: .75rem;
}

.section-title {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 3vw, 2.2rem);
    font-weight: 700;
    color: var(--text);
    margin-bottom: .75rem;
}

.section-title-white {
    color: #fff;
}

.section-desc {
    font-size: 1rem;
    color: var(--text-muted);
    max-width: 620px;
    margin: 0 auto;
    line-height: 1.7;
}

.section-desc-white {
    color: rgba(255, 255, 255, .75);
}

/* ── Page Hero ───────────────────────────────────────────────────────────── */

.page-hero {
    background: linear-gradient(135deg, var(--eva-navy) 0%, var(--eva-navy-light) 100%);
    color: #fff;
    padding: 3rem 0 2.5rem;
}

.page-hero h1 {
    font-family: var(--font-display);
    font-size: clamp(1.6rem, 3vw, 2.4rem);
    font-weight: 700;
    margin: 0 0 .5rem;
}

.page-hero p {
    opacity: .8;
    margin: 0;
    font-size: 1.05rem;
}

.page-hero-breadcrumb {
    font-size: .8rem;
    opacity: .6;
    margin-bottom: .75rem;
}

.page-hero-breadcrumb a {
    color: inherit;
    text-decoration: none;
    opacity: .8;
}

.page-hero-breadcrumb a:hover {
    opacity: 1;
}

/* ── Sub-navigation ──────────────────────────────────────────────────────── */

.sub-nav-wrapper {
    background: var(--surface);
    border-bottom: 2px solid var(--border);
    position: sticky;
    top: 64px;
    z-index: 50;
}

.sub-nav {
    display: flex;
    gap: 0;
    flex-wrap: wrap;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.sub-nav-link {
    color: var(--text-muted);
    text-decoration: none;
    font-size: .85rem;
    font-weight: 500;
    padding: .8rem 1rem;
    border-bottom: 2.5px solid transparent;
    margin-bottom: -2px;
    transition: var(--transition);
    white-space: nowrap;
}

.sub-nav-link:hover {
    color: var(--text);
}

.sub-nav-link.active {
    color: var(--md-primary);
    border-bottom-color: var(--eva-orange);
    font-weight: 600;
}

/* ── Hero (Homepage) ─────────────────────────────────────────────────────── */

.hero {
    background: linear-gradient(135deg, var(--eva-navy) 0%, #1a4a8a 60%, #003070 100%);
    position: relative;
    overflow: hidden;
    color: #fff;
}

.hero-bg {
    position: absolute;
    inset: 0;
    background-image: url('../img/hero-cosmic.jpg');
    background-size: cover;
    background-position: center;
    opacity: .15;
    mix-blend-mode: luminosity;
    pointer-events: none;
}

.hero-content {
    position: relative;
    z-index: 1;
    max-width: 1200px;
    margin: 0 auto;
    padding: 5.5rem 1.5rem 4.5rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3.5rem;
    align-items: center;
}

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    background: rgba(241, 98, 10, .15);
    border: 1px solid rgba(241, 98, 10, .4);
    color: #ff8343;
    padding: .35rem .85rem;
    border-radius: 100px;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    margin-bottom: 1.25rem;
}

.hero-badge svg { flex-shrink: 0; }

.hero h1 {
    font-family: var(--font-display);
    font-size: clamp(1.8rem, 3.5vw, 2.85rem);
    font-weight: 700;
    line-height: 1.13;
    margin-bottom: 1.1rem;
}

.hero h1 em {
    color: var(--eva-orange);
    font-style: normal;
}

.hero-sub {
    font-size: 1.05rem;
    opacity: .85;
    line-height: 1.75;
    margin-bottom: 2rem;
    max-width: 480px;
}

.hero-actions {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

/* Hero right: stats grid */
.hero-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
}

.hero-stat {
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: var(--radius);
    padding: 1.5rem 1.25rem;
    text-align: center;
    backdrop-filter: blur(4px);
}

.hero-stat-num {
    font-family: var(--font-display);
    font-size: 2.1rem;
    font-weight: 700;
    color: var(--eva-orange);
    line-height: 1;
}

.hero-stat-label {
    font-size: .78rem;
    opacity: .75;
    margin-top: .4rem;
    line-height: 1.35;
}

/* ── Feature Grid (Why EVA) ──────────────────────────────────────────────── */

.feature-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1.5rem;
}

.feature-card {
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    padding: 2rem 1.5rem;
    text-align: center;
    transition: var(--transition);
}

.feature-card:hover {
    box-shadow: var(--shadow-lg);
    border-color: var(--border);
    transform: translateY(-2px);
}

.feature-icon {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    margin: 0 auto 1.1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
}

.feature-icon-navy { background: rgba(0, 48, 112, .1); }
.feature-icon-orange { background: rgba(241, 98, 10, .1); }
.feature-icon-green { background: rgba(56, 161, 105, .1); }
.feature-icon-purple { background: rgba(155, 77, 202, .1); }
.feature-icon-gold { background: rgba(212, 168, 83, .15); }

.feature-card h3 {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: .5rem;
    color: var(--text);
}

.feature-card p {
    font-size: .85rem;
    color: var(--text-muted);
    line-height: 1.65;
    margin: 0;
}

/* ── Announcement Cards ──────────────────────────────────────────────────── */

.announce-card {
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    padding: 1.25rem 1.5rem;
    transition: box-shadow .2s;
}

.announce-card:hover {
    box-shadow: var(--shadow-lg);
}

.announce-date {
    font-size: .75rem;
    color: var(--text-muted);
    margin-bottom: .3rem;
    font-weight: 500;
}

.announce-title {
    font-weight: 600;
    color: var(--text);
    font-size: .95rem;
    margin-bottom: .4rem;
    font-family: var(--font-display);
}

.announce-body {
    font-size: .85rem;
    color: var(--text-muted);
    line-height: 1.65;
}

/* ── Events Timeline ─────────────────────────────────────────────────────── */

.events-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.event-item {
    display: grid;
    grid-template-columns: 72px 1fr;
    gap: 1.25rem;
    align-items: start;
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    padding: 1.25rem;
    transition: box-shadow .2s;
}

.event-item:hover {
    box-shadow: var(--shadow-lg);
}

.event-date-box {
    background: var(--eva-navy);
    color: #fff;
    border-radius: var(--radius-sm);
    text-align: center;
    padding: .6rem .5rem;
    flex-shrink: 0;
}

.event-date-month {
    font-size: .65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    opacity: .8;
}

.event-date-day {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1;
}

.event-title {
    font-weight: 600;
    font-family: var(--font-display);
    color: var(--text);
    margin-bottom: .25rem;
}

.event-meta {
    font-size: .8rem;
    color: var(--text-muted);
}

/* ── FAQ Accordion ───────────────────────────────────────────────────────── */

.faq-list {
    max-width: 760px;
    margin: 0 auto;
}

.faq-item {
    border-bottom: 1px solid var(--border);
}

.faq-item:first-child {
    border-top: 1px solid var(--border);
}

.faq-question {
    font-weight: 600;
    font-size: .95rem;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 0;
    color: var(--text);
    user-select: none;
    list-style: none;
    background: none;
    border: none;
    width: 100%;
    text-align: left;
}

.faq-question::-webkit-details-marker {
    display: none;
}

.faq-chevron {
    flex-shrink: 0;
    color: var(--eva-orange);
    transition: transform .25s ease;
}

details[open] .faq-chevron {
    transform: rotate(180deg);
}

.faq-answer {
    color: var(--text-muted);
    line-height: 1.75;
    font-size: .9rem;
    padding-bottom: 1.25rem;
}

/* ── Forms ───────────────────────────────────────────────────────────────── */

.form-group {
    margin-bottom: 1.25rem;
}

.form-label {
    display: block;
    font-size: .85rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: .4rem;
}

.form-required {
    color: var(--error);
    margin-left: .15rem;
}

.form-input,
.form-textarea,
.form-select {
    width: 100%;
    padding: .7rem .9rem;
    border: 1.5px solid var(--input-border);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: .9rem;
    color: var(--text);
    background: var(--surface);
    transition: border-color .2s, box-shadow .2s;
    appearance: none;
    -webkit-appearance: none;
}

.form-input:focus,
.form-textarea:focus,
.form-select:focus {
    outline: none;
    border-color: var(--eva-navy);
    box-shadow: 0 0 0 3px rgba(0, 48, 112, .1);
}

.form-textarea {
    min-height: 130px;
    resize: vertical;
    line-height: 1.6;
}

.form-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236B6B63' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .85rem center;
    padding-right: 2.25rem;
}

.form-error {
    color: var(--error);
    font-size: .78rem;
    margin-top: .3rem;
    display: flex;
    align-items: center;
    gap: .3rem;
}

.form-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 2rem 2.25rem;
    max-width: 640px;
    margin: 0 auto;
    box-shadow: var(--shadow);
}

.form-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 1rem;
}

/* ── Color Field (eyedropper trigger + Hex/RGB/Theme popover) ──────────────── */

.color-field {
    position: relative;
}

.color-field-control {
    position: relative;
    display: flex;
}

.color-field-input {
    width: 100%;
    padding-right: 2.6rem;
    font-family: 'SFMono-Regular', Consolas, monospace;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.color-field-input.color-field-invalid {
    border-color: var(--error);
}

.color-field-trigger {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    position: absolute;
    top: 50%;
    right: .4rem;
    transform: translateY(-50%);
    width: 2.05rem;
    height: 2.05rem;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background .15s, color .15s;
}

.color-field-trigger .swatch-dot {
    position: absolute;
    left: 6px;
    bottom: 6px;
    width: 9px;
    height: 9px;
    border-radius: 3px;
    border: 1px solid rgba(0, 0, 0, .15);
}

.color-field-trigger:hover { background: var(--surface-alt); color: var(--md-primary); }
.color-field-trigger[aria-expanded="true"] { background: var(--surface-alt); color: var(--md-primary); }
.color-field-trigger:focus-visible { outline: 2px solid var(--eva-navy); outline-offset: 2px; }

/* ── Popover ─────────────────────────────────────────────────── */

.color-popover {
    position: absolute;
    z-index: 20;
    top: calc(100% + 8px);
    left: 0;
    width: 258px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 14px;
}

.color-popover[hidden] { display: none; }

.checkerboard-base {
    background-image: conic-gradient(var(--border) 90deg, transparent 90deg 180deg, var(--border) 180deg 270deg, transparent 270deg);
    background-size: 10px 10px;
}

.sv-panel {
    position: relative;
    width: 100%;
    height: 132px;
    border-radius: 7px;
    cursor: crosshair;
    touch-action: none;
    overflow: hidden;
}

.sv-handle {
    position: absolute;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .4);
    transform: translate(-50%, -50%);
    pointer-events: none;
}

.slider-track {
    position: relative;
    height: 12px;
    border-radius: 6px;
    margin-top: 10px;
    touch-action: none;
    cursor: pointer;
}

.hue-track {
    background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
}

.slider-thumb {
    position: absolute;
    top: 50%;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    border: 1.5px solid rgba(0, 0, 0, .2);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
    transform: translate(-50%, -50%);
    pointer-events: none;
}

.preview-row {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin-top: 12px;
}

.color-preview {
    width: 30px;
    height: 30px;
    border-radius: 6px;
    border: 1px solid var(--border);
    flex-shrink: 0;
}

.preview-value {
    font-family: 'SFMono-Regular', Consolas, monospace;
    font-size: .78rem;
    color: var(--text-muted);
}

/* ── Popover tabs ────────────────────────────────────────────── */

.cp-tabs {
    display: flex;
    margin-top: 14px;
    border-bottom: 1px solid var(--border);
}

.cp-tab {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    flex: 1;
    background: none;
    border: none;
    padding: .5rem 0 .6rem;
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--text-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color .15s, border-color .15s;
}

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

.cp-tab.active {
    color: var(--md-primary);
    border-bottom-color: var(--eva-navy);
}

.cp-tab:focus-visible { outline: 2px solid var(--eva-navy); outline-offset: -2px; }

.cp-panel { display: none; padding-top: 12px; }
.cp-panel.active { display: block; }

.cp-field-row { display: flex; gap: .5rem; }

.cp-field {
    flex: 1;
    min-width: 0;
}

.cp-field label {
    display: block;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-light);
    margin-bottom: .3rem;
}

.cp-field input {
    width: 100%;
    padding: .45rem .5rem;
    border: 1.5px solid var(--input-border);
    border-radius: 5px;
    font-family: 'SFMono-Regular', Consolas, monospace;
    font-size: .82rem;
    text-align: center;
    color: var(--text);
    background: var(--surface);
}

.cp-field input:focus {
    outline: none;
    border-color: var(--eva-navy);
    box-shadow: 0 0 0 2px rgba(0, 48, 112, .12);
}

.cp-actions {
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

/* ── Theme tab ───────────────────────────────────────────────── */

.theme-group + .theme-group { margin-top: 12px; }

.theme-group-label {
    font-family: var(--font-display);
    font-style: italic;
    font-size: .78rem;
    color: var(--text-muted);
    margin: 0 0 .45rem;
}

.theme-swatch-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: .4rem;
}

.theme-swatch {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, .12);
    cursor: pointer;
    padding: 0;
    transition: transform .12s ease;
}

.theme-swatch:hover { transform: scale(1.12); }
.theme-swatch:focus-visible { outline: 2px solid var(--eva-navy); outline-offset: 2px; }

.theme-swatch.is-active::after {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: 8px;
    border: 2px solid var(--eva-navy);
}

.theme-swatch-name {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--text);
    color: var(--surface);
    font-size: .68rem;
    padding: .25rem .5rem;
    border-radius: 4px;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s ease;
    z-index: 1;
}

.theme-swatch:hover .theme-swatch-name,
.theme-swatch:focus-visible .theme-swatch-name { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
    .theme-swatch, .cp-tab { transition: none; }
}

/* ── Photo Field (file/camera picker) ──────────────────────────────────────── */

.photo-field-input {
    width: 100%;
    padding-right: 2.6rem;
}

.photo-field .color-field-trigger[disabled] {
    opacity: .5;
    cursor: default;
}

.photo-field-status {
    margin: .4rem 0 0;
    font-size: .78rem;
    color: var(--text-muted);
}

.photo-field-status.photo-field-status-error {
    color: var(--error);
}

/* ── Alerts ──────────────────────────────────────────────────────────────── */

.alert {
    padding: 1rem 1.25rem;
    border-radius: var(--radius-sm);
    margin-bottom: 1.25rem;
    font-size: .9rem;
    line-height: 1.55;
}

/* Tonal container pairs - theme-aware in light and dark. Pure tonal
   fill, no accent border - see /styles.htm (Feedback > Alerts). */
.alert-success {
    background: var(--success-c);
    color: var(--success);
}

.alert-error {
    background: var(--error-c);
    color: var(--error);
}

.alert-warning {
    background: var(--warning-c);
    color: var(--warning);
}

.alert-info {
    background: var(--info-c);
    color: var(--info);
}

.alert ul {
    margin: .5rem 0 0 1.2rem;
    padding: 0;
}

/*
 * Same visual as .alert-info but a distinct class on purpose: the student
 * "Trusted Adults" / Need Help strip (partials/student-safety-strip.php) is
 * meant to stay on screen permanently, unlike .alert-success/.alert-info
 * flash messages, which public/assets/js/app.js's autoDismissAlerts()
 * fades out and removes ~5.5s after page load. Reusing .alert-info made
 * the strip get caught by that same selector and vanish.
 */
.safety-note {
    padding: 1rem 1.25rem;
    border-radius: var(--radius-sm);
    margin-bottom: 1.25rem;
    background: var(--info-c);
    color: var(--info);
    font-size: .9rem;
    line-height: 1.55;
}

/* ── Badges ──────────────────────────────────────────────────────────────── */

.badge {
    display: inline-flex;
    align-items: center;
    padding: .2rem .65rem;
    border-radius: 100px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .03em;
}

/* Tonal container/on-container pairs - theme-aware in light and dark.
   dashboard.css re-declares the role badges with the same pattern. */
.badge-admin      { background: var(--md-primary-container); color: var(--md-on-primary-container); }
.badge-teacher    { background: var(--science-c); color: var(--science); }
.badge-parent     { background: var(--warning-c); color: var(--warning); }
.badge-student    { background: var(--ela-c); color: var(--ela); }
.badge-leadership,
.badge-school_leadership { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }
.badge-new      { background: var(--info-c); color: var(--info); }
.badge-reviewing{ background: var(--warning-c); color: var(--warning); }
.badge-offered  { background: var(--success-c); color: var(--success); }
.badge-declined { background: var(--error-c); color: var(--error); }
.badge-orange   { background: var(--md-tertiary-container); color: var(--md-on-tertiary-container); }
.badge-navy     { background: var(--md-primary-container); color: var(--md-on-primary-container); }

/* ── Tables ──────────────────────────────────────────────────────────────── */

.table-responsive {
    overflow-x: auto;
    border-radius: var(--radius);
    border: 1px solid var(--border);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .875rem;
}

.data-table th {
    background: var(--surface-alt);
    padding: .75rem 1rem;
    font-weight: 600;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
    text-align: left;
    border-bottom: 1px solid var(--border);
}

.data-table td {
    padding: .85rem 1rem;
    border-bottom: 1px solid var(--border-light);
    color: var(--text);
    vertical-align: middle;
}

.data-table tr:last-child td {
    border-bottom: none;
}

.data-table tr:hover td {
    background: var(--surface-alt);
}

/* ── Stat Cards ──────────────────────────────────────────────────────────── */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 1rem;
}

.stat-card {
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    padding: 1.5rem;
    text-align: center;
}

.stat-value {
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: 700;
    color: var(--md-primary);
    line-height: 1;
}

.stat-label {
    font-size: .78rem;
    color: var(--text-muted);
    margin-top: .35rem;
    line-height: 1.35;
}

/* ── Dashboard shared (minimal, full in dashboard.css) ───────────────────── */

.page-header {
    margin-bottom: 1.75rem;
}

.page-header h1 {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text);
    margin-bottom: .35rem;
}

.empty-state {
    text-align: center;
    padding: 3rem 2rem;
    color: var(--text-muted);
}

.empty-state-icon {
    font-size: 2.5rem;
    margin-bottom: 1rem;
    opacity: .4;
}

.empty-state p {
    margin: 0;
    font-size: .9rem;
}

/* ── Lang Toggle ─────────────────────────────────────────────────────────── */

.lang-toggle {
    display: flex;
    gap: .25rem;
}

.lang-toggle a {
    font-size: .75rem;
    font-weight: 600;
    color: var(--text-muted);
    text-decoration: none;
    padding: .2rem .45rem;
    border-radius: 3px;
    transition: var(--transition);
}

.lang-toggle a:hover {
    color: var(--text);
}

.lang-toggle a.active {
    background: var(--eva-orange);
    color: #fff;
    border-radius: 3px;
}

/* ── Process Steps ───────────────────────────────────────────────────────── */

.steps-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0;
    counter-reset: step;
    position: relative;
}

.step-item {
    text-align: center;
    padding: 2rem 1.25rem;
    position: relative;
}

.step-num {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: var(--eva-navy);
    color: #fff;
    font-family: var(--font-display);
    font-size: 1.2rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1rem;
    position: relative;
    z-index: 1;
}

.step-item h3 {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: .4rem;
}

.step-item p {
    font-size: .85rem;
    color: var(--text-muted);
    line-height: 1.6;
}

/* ── Info Cards (two-column layout) ─────────────────────────────────────── */

.info-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    align-items: start;
}

.info-block h2 {
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--text);
    margin-bottom: .75rem;
}

.info-block p {
    color: var(--text-muted);
    line-height: 1.75;
    font-size: .95rem;
}

/* ── Team / Profile Cards ────────────────────────────────────────────────── */

.team-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1.5rem;
}

.team-card {
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    overflow: hidden;
    transition: box-shadow .2s, transform .2s;
    text-align: center;
}

.team-card:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-3px);
}

.team-photo {
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    object-position: 50% 50%;
    background: var(--surface-alt);
    display: block;
}

.team-photo-placeholder {
    width: 100%;
    aspect-ratio: 4 / 5;
    background: linear-gradient(135deg, var(--eva-navy) 0%, #1a4a8a 100%);
    display: flex;
    align-items: center;
    justify-content: center;
}

.team-photo-placeholder span {
    font-size: 3.5rem;
    color: rgba(255,255,255,.25);
}

.team-info {
    padding: 1.25rem;
}

.team-name {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: .25rem;
}

.team-role {
    font-size: .78rem;
    color: var(--text-muted);
    margin-bottom: .75rem;
}

.team-bio-toggle {
    background: none;
    border: none;
    padding: 0;
    font-size: .78rem;
    font-weight: 600;
    color: var(--md-primary);
    cursor: pointer;
    font-family: var(--font-body);
}

.team-bio-toggle:hover {
    text-decoration: underline;
}

.team-bio {
    text-align: left;
}

/* ── CTA Strip ───────────────────────────────────────────────────────────── */

.cta-strip {
    background: linear-gradient(135deg, var(--eva-orange) 0%, #d94e00 100%);
    color: #fff;
    padding: 3.5rem 0;
    text-align: center;
}

.cta-strip h2 {
    font-family: var(--font-display);
    font-size: clamp(1.4rem, 2.5vw, 2rem);
    font-weight: 700;
    margin-bottom: .5rem;
}

.cta-strip p {
    opacity: .85;
    font-size: 1rem;
    margin-bottom: 1.75rem;
}

/* ── Testimonials ────────────────────────────────────────────────────────── */

.testimonial-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1.5rem;
}

.testimonial-card {
    background: var(--surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    padding: 1.75rem;
    position: relative;
}

.testimonial-quote {
    font-size: .95rem;
    line-height: 1.75;
    color: var(--text-muted);
    font-style: italic;
    margin-bottom: 1.25rem;
}

.testimonial-quote::before {
    content: '\201C';
    font-family: var(--font-display);
    font-size: 3rem;
    color: var(--eva-orange);
    opacity: .4;
    position: absolute;
    top: .5rem;
    left: 1.25rem;
    line-height: 1;
}

.testimonial-author {
    font-weight: 600;
    font-size: .85rem;
    color: var(--text);
}

.testimonial-role {
    font-size: .78rem;
    color: var(--text-muted);
    margin-top: .15rem;
}

/* ── Schedule / Day-in-Life ──────────────────────────────────────────────── */

.schedule-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
}

.schedule-col h3 {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 1rem;
    padding-bottom: .5rem;
    border-bottom: 2px solid var(--border);
}

.schedule-item {
    display: flex;
    gap: 1rem;
    padding: .65rem 0;
    border-bottom: 1px solid var(--border-light);
    font-size: .88rem;
}

.schedule-item:last-child {
    border-bottom: none;
}

.schedule-time {
    font-weight: 600;
    color: var(--md-primary);
    white-space: nowrap;
    min-width: 80px;
    font-size: .82rem;
}

.schedule-activity {
    color: var(--text-muted);
}

.schedule-lang-tag {
    display: inline-block;
    font-size: .65rem;
    font-weight: 700;
    padding: .1rem .4rem;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-left: .4rem;
}

.tag-mandarin {
    background: rgba(192,57,43,.1);
    color: var(--chinese);
}

.tag-english {
    background: rgba(0,48,112,.1);
    color: var(--md-primary);
}

/* ── Subject Pillars ─────────────────────────────────────────────────────── */

.subject-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1rem;
}

.subject-card {
    border-radius: var(--radius);
    padding: 1.25rem;
    border: 1px solid;
    transition: var(--transition);
}

.subject-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
}

.subject-card h3 {
    font-family: var(--font-display);
    font-size: .95rem;
    font-weight: 600;
    margin-bottom: .35rem;
}

.subject-card p {
    font-size: .8rem;
    line-height: 1.55;
    margin: 0;
}

.subject-chinese  { background: rgba(192,57,43,.06); border-color: rgba(192,57,43,.2); color: #7b1b12; }
.subject-math     { background: rgba(45,91,169,.06); border-color: rgba(45,91,169,.2); color: #1a3d7c; }
.subject-science  { background: rgba(29,131,72,.06); border-color: rgba(29,131,72,.2); color: #0f5c33; }
.subject-ela      { background: rgba(155,77,202,.06); border-color: rgba(155,77,202,.2); color: #6b2fa0; }
.subject-social   { background: rgba(192,121,42,.06); border-color: rgba(192,121,42,.2); color: #7b4c15; }
.subject-arts     { background: rgba(142,68,173,.06); border-color: rgba(142,68,173,.2); color: #5c2080; }
.subject-pe       { background: rgba(56,161,105,.06); border-color: rgba(56,161,105,.2); color: #1a6b44; }
.subject-stem     { background: rgba(52,152,219,.06); border-color: rgba(52,152,219,.2); color: #1a6090; }

/* ── Contact Info Block ──────────────────────────────────────────────────── */

.contact-info-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2.5rem;
    align-items: start;
}

.contact-detail {
    display: flex;
    gap: .85rem;
    margin-bottom: 1.25rem;
    align-items: flex-start;
}

.contact-detail-icon {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(0, 48, 112, .08);
    color: var(--md-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.contact-detail-text h4 {
    font-size: .85rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: .15rem;
}

.contact-detail-text p,
.contact-detail-text a {
    font-size: .88rem;
    color: var(--text-muted);
    margin: 0;
    text-decoration: none;
}

.contact-detail-text a:hover {
    color: var(--md-primary);
}

.map-placeholder {
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    height: 260px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: .9rem;
    gap: .75rem;
    margin-top: 1.5rem;
}

/* ── Auth Wrapper ────────────────────────────────────────────────────────── */

.auth-body {
    background: var(--eva-navy);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.auth-wrapper {
    width: 100%;
    max-width: 440px;
    padding: 1.5rem;
}

.auth-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 2rem;
    box-shadow: var(--shadow-xl);
}

.auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .65rem;
    padding-bottom: 1.25rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--border);
}

.auth-brand img {
    height: 40px;
    width: 40px;
    flex-shrink: 0;
}

.auth-brand-name {
    display: flex;
    flex-direction: column;
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--md-primary);
    letter-spacing: .01em;
}

.auth-brand-sub {
    font-size: .74rem;
    font-weight: 400;
    letter-spacing: .06em;
    color: var(--eva-orange);
}

.auth-brand-sub em {
    font-style: italic;
    font-family: var(--font-display);
}

.auth-theme-toggle {
    display: flex;
    justify-content: flex-end;
    margin-bottom: .5rem;
}

/* Auth page body is constant navy - toggle needs light-on-dark colors */
.auth-theme-toggle .theme-toggle {
    color: rgba(255, 255, 255, .75);
}

.auth-theme-toggle .theme-toggle:hover {
    background: rgba(255, 255, 255, .12);
    color: #fff;
}

.auth-card h1 {
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 700;
    text-align: center;
    margin: 0 0 1.25rem;
    color: var(--text);
}

.auth-footer-link {
    display: block;
    text-align: center;
    margin-top: 1.25rem;
    font-size: .82rem;
    color: rgba(255, 255, 255, .55);
    text-decoration: none;
}

.auth-footer-link:hover {
    color: rgba(255, 255, 255, .85);
}

/* ── Dividers ────────────────────────────────────────────────────────────── */

.divider {
    border: none;
    border-top: 1px solid var(--border);
    margin: 2rem 0;
}

/* ── Flash message wrapper ───────────────────────────────────────────────── */

.flash-container {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    pointer-events: none;
}

/* ── Checkbox / Radio (native, brand-accented) ───────────────────────────── */

input[type="checkbox"],
input[type="radio"] {
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--eva-navy);
    cursor: pointer;
    flex-shrink: 0;
}

.form-check {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-size: .88rem;
    color: var(--text);
    cursor: pointer;
    user-select: none;
}

/* ── Date / Time inputs ───────────────────────────────────────────────────── */
/* Native controls - the OS/browser supplies the calendar/clock popover, not
   a custom widget. Just harmonize the picker-indicator icon on hover. */

input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: .6;
    transition: opacity .2s;
}

input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:hover::-webkit-calendar-picker-indicator {
    opacity: 1;
}

/* ── Toggle Switch ────────────────────────────────────────────────────────── */

.toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    cursor: pointer;
    user-select: none;
    font-size: .88rem;
    color: var(--text);
}

.toggle input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.toggle-track {
    position: relative;
    width: 2.4rem;
    height: 1.4rem;
    background: var(--input-border);
    border-radius: 999px;
    transition: var(--transition);
    flex-shrink: 0;
}

.toggle-track::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
    transition: transform .18s ease;
}

.toggle input:checked + .toggle-track {
    background: var(--eva-navy);
}

.toggle input:checked + .toggle-track::before {
    transform: translateX(1rem);
}

.toggle input:focus-visible + .toggle-track {
    outline: 2px solid var(--eva-navy);
    outline-offset: 2px;
}

.toggle input:disabled + .toggle-track {
    opacity: .5;
    cursor: not-allowed;
}

/* ── Tooltip ──────────────────────────────────────────────────────────────── */
/* Attribute-driven: add data-tooltip="label text" to any element. */

[data-tooltip] {
    position: relative;
}

[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--text);
    color: var(--surface);
    font-size: .72rem;
    font-weight: 500;
    white-space: nowrap;
    padding: .35rem .6rem;
    border-radius: 5px;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s ease;
    z-index: 20;
}

[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::after {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    [data-tooltip]::after { transition: none; }
}

/* ── Pagination ───────────────────────────────────────────────────────────── */

.pagination {
    display: flex;
    align-items: center;
    gap: .3rem;
    list-style: none;
    margin: 1.5rem 0 0;
    padding: 0;
}

.pagination a,
.pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.1rem;
    height: 2.1rem;
    padding: 0 .5rem;
    border-radius: var(--radius-sm);
    font-size: .85rem;
    font-weight: 600;
    color: var(--text-muted);
    text-decoration: none;
    transition: var(--transition);
}

.pagination a:hover {
    background: var(--surface-alt);
    color: var(--text);
}

.pagination .is-current span,
.pagination .is-current a {
    background: var(--eva-navy);
    color: #fff;
}

.pagination .is-disabled {
    opacity: .4;
    pointer-events: none;
}

/* ── Modal (native <dialog>) ──────────────────────────────────────────────── */

.modal {
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--shadow-xl);
    padding: 0;
    width: min(480px, calc(100vw - 2rem));
    color: var(--text);
}

.modal::backdrop {
    background: rgba(26, 26, 24, .5);
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--border);
}

.modal-header h3 {
    font-family: var(--font-display);
    font-size: 1.1rem;
    font-weight: 600;
    margin: 0;
}

.modal-close {
    appearance: none;
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: .25rem;
    border-radius: 5px;
    display: flex;
}

.modal-close:hover {
    background: var(--surface-alt);
    color: var(--text);
}

.modal-body {
    padding: 1.5rem;
    font-size: .9rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: .6rem;
    padding: 1rem 1.5rem 1.5rem;
}

/* ── Dark-mode remaps ─────────────────────────────────────────────────────── */
/* Navy is EVA's identity and stays constant as a FILL (sidebar, buttons,
   heroes), but navy TEXT is unreadable on dark surfaces - remap the known
   text usages to the tonal primary. */

[data-theme="dark"] .btn-ghost,
[data-theme="dark"] .sub-nav-link.active,
[data-theme="dark"] .auth-brand-name,
[data-theme="dark"] .nav-brand-text {
    color: var(--md-primary);
}

/* .cta-strip's background is a fixed orange gradient in both themes
   (not a surface token), so btn-ghost's navy-on-neutral treatment -
   and the dark-mode remap right above - both leave it low-contrast
   there. CMS authors can pick btn-ghost for any cta_strip button
   (it's one of the two styles the admin CMS editor documents), so
   fix the variant for this context rather than the content. Placed
   after the dark-mode remap so it wins in both themes despite equal
   selector specificity. */
.cta-strip .btn-ghost {
    color: #fff;
    border-color: rgba(255, 255, 255, .5);
}
.cta-strip .btn-ghost:hover {
    background: rgba(255, 255, 255, .1);
    border-color: #fff;
}

/* ── Theme Toggle (dark mode, sitewide header control) ───────────────────── */

.theme-toggle {
    appearance: none;
    -webkit-appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border: none;
    border-radius: var(--radius-full, 999px);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    transition: background .15s, color .15s;
}

.theme-toggle:hover {
    background: var(--surface-alt);
    color: var(--text);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--eva-navy);
    outline-offset: 2px;
}

/* Icon swap: moon in light mode (action = go dark), sun in dark mode */
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* On dark chrome (navy topbars/sidebars), invert the resting color */
.theme-toggle.on-dark {
    color: rgba(255, 255, 255, .75);
}

.theme-toggle.on-dark:hover {
    background: rgba(255, 255, 255, .12);
    color: #fff;
}

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

@media (max-width: 900px) {
    .hero-content {
        grid-template-columns: 1fr;
        padding: 3.5rem 1.5rem 3rem;
    }

    .hero-stats {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: .75rem;
    }

    .info-grid {
        grid-template-columns: 1fr;
    }

    .schedule-grid {
        grid-template-columns: 1fr;
    }

    .contact-info-grid {
        grid-template-columns: 1fr;
    }

    .form-grid-2 {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 640px) {
    .section {
        padding: 3rem 0;
    }

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

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

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

    .steps-grid {
        grid-template-columns: 1fr 1fr;
    }

    .cta-strip {
        padding: 2.5rem 0;
    }

    .form-card {
        padding: 1.5rem;
    }
}

@media (max-width: 480px) {
    .hero-stats {
        grid-template-columns: repeat(2, 1fr);
    }

    .team-grid {
        grid-template-columns: 1fr 1fr;
    }

    .feature-grid {
        grid-template-columns: 1fr;
    }

    .steps-grid {
        grid-template-columns: 1fr;
    }
}

/* ============================================================
   MATERIAL EXPRESSIVE FORM COMPONENTS
   Ported from public/styles.htm (the EVA Design System
   prototype) as part of the site-wide forms migration off the
   older .form-group/.btn pattern. Legacy .btn and .form- rules
   above are left untouched — they still back every unmigrated
   view — this block is purely additive. See
   specifications/style_guide.md for the full component index.
   Tokens referenced here (--md-*, --shape-*, --elev-*,
   --dur-*) live in tokens.css.
   ============================================================ */

.msr {
    font-family: 'Material Symbols Rounded';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    display: inline-block;
    letter-spacing: normal;
    white-space: nowrap;
    direction: ltr;
    font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
    user-select: none;
}
.msr.fill { font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24; }
.msr.sm { font-size: 20px; }
.msr.lg { font-size: 32px; }

/* ── Ripple (Material's signature interaction) ──────────────── */
.rip { position: relative; overflow: hidden; -webkit-tap-highlight-color: transparent; }

.ripple-ink {
    position: absolute;
    border-radius: 50%;
    transform: scale(0);
    animation: eva-ripple 480ms var(--ease-emphasized);
    background: currentColor;
    opacity: .18;
    pointer-events: none;
}

@keyframes eva-ripple { to { transform: scale(2.6); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
    .ripple-ink { animation: none; opacity: 0; }
}

/* ── Buttons (pill, Material emphasis levels) ────────────────── */
.m-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    height: 40px;
    padding: 0 1.5rem;
    border: none;
    border-radius: var(--shape-full);
    font-family: var(--font-body);
    font-size: .875rem;
    font-weight: 600;
    letter-spacing: .006em;
    cursor: pointer;
    text-decoration: none;
    transition: box-shadow var(--dur-short), background var(--dur-short);
}
.m-btn .msr { font-size: 18px; margin-left: -.35rem; }
.m-btn:disabled { opacity: .38; cursor: not-allowed; box-shadow: none !important; }
.m-btn.sm { height: 32px; padding: 0 1rem; font-size: .8rem; }
.m-btn.block { width: 100%; }

.m-filled { background: var(--md-primary); color: var(--md-on-primary); }
.m-filled:hover:not(:disabled) { box-shadow: var(--elev-1); background: color-mix(in srgb, var(--md-on-primary) 8%, var(--md-primary)); }

.m-tonal { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }
.m-tonal:hover:not(:disabled) { box-shadow: var(--elev-1); background: color-mix(in srgb, var(--md-on-secondary-container) 8%, var(--md-secondary-container)); }

.m-elevated { background: var(--md-surface-container-low); color: var(--md-primary); box-shadow: var(--elev-1); }
.m-elevated:hover:not(:disabled) { box-shadow: var(--elev-2); }

.m-outlined { background: transparent; color: var(--md-primary); border: 1px solid var(--md-outline); }
.m-outlined:hover:not(:disabled) { background: color-mix(in srgb, var(--md-primary) 8%, transparent); }

.m-text { background: transparent; color: var(--md-primary); padding: 0 .75rem; }
.m-text:hover:not(:disabled) { background: color-mix(in srgb, var(--md-primary) 8%, transparent); }

.m-brand { background: var(--eva-orange); color: #fff; }
.m-brand:hover:not(:disabled) { box-shadow: var(--elev-1); background: color-mix(in srgb, #000 8%, var(--eva-orange)); }

.m-error { background: var(--md-error); color: var(--md-on-error); }
.m-error:hover:not(:disabled) { box-shadow: var(--elev-1); background: color-mix(in srgb, #000 8%, var(--md-error)); }

/* Icon buttons */
.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: var(--shape-full);
    background: transparent;
    color: var(--md-on-surface-variant);
    cursor: pointer;
    transition: background var(--dur-short);
}
.icon-btn:hover { background: color-mix(in srgb, var(--md-on-surface) 8%, transparent); }
.icon-btn.filled { background: var(--md-primary); color: var(--md-on-primary); }
.icon-btn.tonal { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }
.icon-btn.outlined { border: 1px solid var(--md-outline); }

/* ── Chips & status badges ───────────────────────────────────── */
.chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    height: 32px;
    padding: 0 1rem;
    border: 1px solid var(--md-outline);
    border-radius: var(--shape-sm);
    background: transparent;
    color: var(--md-on-surface);
    font-family: var(--font-body);
    font-size: .82rem;
    font-weight: 500;
    cursor: pointer;
    transition: background var(--dur-short), border-color var(--dur-short);
    user-select: none;
}
.chip .msr { font-size: 18px; color: var(--md-primary); }
.chip:hover { background: color-mix(in srgb, var(--md-on-surface) 6%, transparent); }
.chip.selected { background: var(--md-secondary-container); color: var(--md-on-secondary-container); border-color: transparent; }
.chip.selected .msr { color: var(--md-on-secondary-container); }
.chip-subj { border-color: transparent; font-weight: 600; cursor: default; }

.status {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    height: 26px;
    padding: 0 .75rem;
    border-radius: var(--shape-full);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .03em;
}
.status .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status.success { background: var(--md-success-container); color: var(--md-success); }
.status.warning { background: var(--md-warning-container); color: var(--md-warning); }
.status.error   { background: var(--md-error-container);   color: var(--md-error); }
.status.info    { background: var(--md-info-container);    color: var(--md-info); }

/* ── Text fields (floating label, pure CSS) ──────────────────── */
.field { position: relative; margin-bottom: 1.4rem; }

.field input, .field select, .field textarea {
    width: 100%;
    font-family: var(--font-body);
    font-size: .95rem;
    color: var(--md-on-surface);
    background: transparent;
    border: 1px solid var(--md-outline);
    border-radius: var(--shape-xs);
    padding: 1rem .95rem .55rem;
    height: 56px;
    outline: none;
    transition: border-color var(--dur-short), box-shadow var(--dur-short);
    appearance: none;
}
.field textarea { height: auto; min-height: 110px; resize: vertical; padding-top: 1.35rem; }

/* Native <option> popups aren't styled by the transparent .field
   background above (they render as an opaque OS-level list), so
   without this Chrome/Edge fall back to a white popup - unreadable
   against the light text color inherited from dark mode. */
.field select option {
    background: var(--md-surface-container-lowest);
    color: var(--md-on-surface);
}

.field label {
    position: absolute;
    left: .8rem;
    top: 1.05rem;
    padding: 0 .3rem;
    font-size: .95rem;
    color: var(--md-on-surface-variant);
    background: var(--surface);
    pointer-events: none;
    transition: all var(--dur-short) var(--ease-emphasized);
}

.field input:focus, .field select:focus, .field textarea:focus {
    border-color: var(--md-primary);
    box-shadow: inset 0 0 0 1px var(--md-primary);
}

.field input:focus ~ label,
.field input:not(:placeholder-shown) ~ label,
.field textarea:focus ~ label,
.field textarea:not(:placeholder-shown) ~ label,
.field select:valid ~ label,
.field select:focus ~ label {
    top: -.55rem;
    font-size: .74rem;
    color: var(--md-primary);
}

.field input:not(:focus):not(:placeholder-shown) ~ label,
.field textarea:not(:focus):not(:placeholder-shown) ~ label,
.field select:valid:not(:focus) ~ label { color: var(--md-on-surface-variant); }

.field .supporting { position: absolute; left: .95rem; top: calc(100% + 3px); font-size: .72rem; color: var(--md-on-surface-variant); }

.field.error input, .field.error select, .field.error textarea { border-color: var(--md-error); box-shadow: inset 0 0 0 1px var(--md-error); }
.field.error label, .field.error .supporting { color: var(--md-error); }

.field .trail {
    position: absolute;
    right: .5rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--md-on-surface-variant);
    pointer-events: none;
}

/* Filled variant */
.field.filled input, .field.filled select, .field.filled textarea {
    background: var(--md-surface-container-highest);
    border: none;
    border-bottom: 1px solid var(--md-on-surface-variant);
    border-radius: var(--shape-xs) var(--shape-xs) 0 0;
    box-shadow: none;
}
.field.filled input:focus, .field.filled select:focus, .field.filled textarea:focus { border-bottom: 2px solid var(--md-primary); box-shadow: none; }
.field.filled label { background: transparent; }

/* Native picker inputs share the shell */
.field input[type="date"], .field input[type="time"], .field input[type="color"] { padding-top: 1.15rem; cursor: pointer; }
.field input[type="color"] { padding: 1.35rem .6rem .5rem; }
.field input[type="date"] ~ label, .field input[type="time"] ~ label, .field input[type="color"] ~ label { top: -.55rem; font-size: .74rem; }

.form-cols { display: flex; flex-direction: column; }
@media (min-width: 600px) {
    .form-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
}

/* ── Selection controls ───────────────────────────────────────── */
.ctl { display: inline-flex; align-items: center; gap: .7rem; font-size: .9rem; cursor: pointer; user-select: none; }

.m-switch { position: relative; display: inline-block; width: 52px; height: 32px; flex-shrink: 0; }
.m-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; z-index: 1; }

.m-switch .track {
    position: absolute;
    inset: 0;
    border-radius: var(--shape-full);
    /* Transparent, not filled - a filled-gray + gray-outline + gray-
       thumb combination reads as one muted blob, indistinguishable at
       a glance from the .38-opacity disabled state below. An empty
       pill with a defined outline reads as "off but interactive". */
    background: transparent;
    border: 2px solid var(--md-outline);
    transition: background var(--dur-short), border-color var(--dur-short);
}

.m-switch .thumb {
    position: absolute;
    top: 50%;
    left: 8px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--md-on-surface-variant);
    transform: translateY(-50%);
    transition: all var(--dur-short) var(--ease-emphasized);
    display: grid;
    place-items: center;
    color: transparent;
    font-family: 'Material Symbols Rounded';
    font-size: 14px;
}

.m-switch input:checked ~ .track { background: var(--md-primary); border-color: var(--md-primary); }
.m-switch input:checked ~ .thumb { left: 24px; width: 24px; height: 24px; background: var(--md-on-primary); color: var(--md-primary); }
.m-switch input:checked ~ .thumb::after { content: 'check'; }
.m-switch input:focus-visible ~ .track { outline: 2px solid var(--md-primary); outline-offset: 2px; }
.m-switch input:disabled ~ .track, .m-switch input:disabled ~ .thumb { opacity: .38; }

input[type="radio"].m-radio {
    width: 20px;
    height: 20px;
    accent-color: var(--md-primary);
    cursor: pointer;
    flex-shrink: 0;
}

/* Checkboxes are fully custom (appearance:none), not native + accent-
   color like radios. A native unchecked box renders as whatever pale/
   transparent default the OS gives it, which against this site's
   custom-styled controls reads as flat/inert regardless of any
   outline layered on top. Owning both states outright - container-
   lowest fill and a real outline when unchecked, solid primary + a
   drawn checkmark when checked - matches .m-switch's approach. */
input[type="checkbox"].m-check {
    appearance: none;
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    border-radius: 4px;
    border: 2px solid var(--md-outline);
    background: var(--md-surface-container-lowest);
    display: inline-grid;
    place-items: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: background var(--dur-short), border-color var(--dur-short);
}
input[type="checkbox"].m-check::before {
    content: 'check';
    font-family: 'Material Symbols Rounded';
    font-size: 15px;
    font-variation-settings: 'FILL' 0, 'wght' 700, 'GRAD' 0, 'opsz' 20;
    color: transparent;
    line-height: 1;
}
input[type="checkbox"].m-check:checked {
    background: var(--md-primary);
    border-color: var(--md-primary);
}
input[type="checkbox"].m-check:checked::before { color: var(--md-on-primary); }
input[type="checkbox"].m-check:focus-visible { outline: 2px solid var(--md-primary); outline-offset: 2px; }
input[type="checkbox"].m-check:disabled { opacity: .38; cursor: not-allowed; }

.m-slider { -webkit-appearance: none; appearance: none; width: 100%; max-width: 340px; height: 16px; background: transparent; cursor: pointer; }
.m-slider::-webkit-slider-runnable-track {
    height: 6px;
    border-radius: var(--shape-full);
    background: linear-gradient(to right, var(--md-primary) var(--fill, 50%), var(--md-surface-container-highest) var(--fill, 50%));
}
.m-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    margin-top: -7px;
    border-radius: 50%;
    background: var(--md-primary);
    box-shadow: var(--elev-1);
}
.m-slider::-moz-range-track { height: 6px; border-radius: var(--shape-full); background: var(--md-surface-container-highest); }
.m-slider::-moz-range-progress { height: 6px; border-radius: var(--shape-full); background: var(--md-primary); }
.m-slider::-moz-range-thumb { width: 20px; height: 20px; border: none; border-radius: 50%; background: var(--md-primary); box-shadow: var(--elev-1); }

/* ── Search bar ───────────────────────────────────────────────── */
/* container-high read too close to a muted/disabled tone. Container-
   lowest (the "paper" surface) plus a hairline border and elev-1
   gives it the crisp, clearly-interactive look a search field needs. */
.searchbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    height: 56px;
    padding: 0 .6rem 0 1.1rem;
    border-radius: var(--shape-full);
    background: var(--md-surface-container-lowest);
    border: 1px solid var(--md-outline-variant);
    box-shadow: var(--elev-1);
    max-width: 480px;
}
.searchbar input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: var(--font-body); font-size: .95rem; color: var(--md-on-surface); }

/* ════════════════════════════════════════════════════════════════
   DESIGN SYSTEM v2 — new component library, ported from /styles.htm.
   Tickets replace the left-accent-border card pattern retired above
   (.announce-card, .alert, .safety-note, .stat-card, .sidebar-link).
   ════════════════════════════════════════════════════════════════ */

/* ── Tickets - stub, punched-hole divider, main content. No left
   border anywhere. No outer box-shadow: it traces the ticket's plain
   rectangular silhouette regardless of the notch cut into it - fine
   on a dark surface, but on light surfaces it reads as an unbroken
   line running straight across the "hole," undoing the illusion.
   Definition instead comes from the container-low/surface tone
   difference plus each notch's own inset shadow. ─────────────────── */
.ticket {
    position: relative;
    display: flex;
    background: var(--md-surface-container-low);
    border-radius: var(--shape-lg);
    overflow: hidden;
}

.ticket-stub {
    flex: 0 0 92px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    padding: 1rem .4rem;
    background: var(--md-primary-container);
    color: var(--md-on-primary-container);
    text-align: center;
}

.ticket-stub .msr { font-size: 24px; }
.ticket-stub b { font-family: var(--font-mono); font-size: 1.4rem; font-weight: 600; line-height: 1; }
.ticket-stub span { font-size: .6rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; opacity: .85; }

.ticket-perf {
    flex: 0 0 0;
    position: relative;
    border-left: 2px dashed color-mix(in srgb, var(--md-on-primary-container) 35%, transparent);
}

.ticket-perf::before, .ticket-perf::after {
    content: '';
    position: absolute;
    left: -9px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--md-surface);
    box-shadow: inset 0 1px 3px rgba(0,0,0,.3), inset 0 -1px 1px rgba(255,255,255,.12);
}

.ticket-perf::before { top: -9px; }
.ticket-perf::after { bottom: -9px; }

.ticket-main { flex: 1; min-width: 0; padding: 1rem 1.2rem; }
.ticket-main h4 { margin: 0 0 .6rem; font-family: var(--font-display); font-size: 1.1rem; font-weight: 600; }
.ticket-main .chart-box { margin-top: .6rem; }

.ticket.hi .ticket-stub { background: var(--eva-orange); color: #fff; }
.ticket.hi .ticket-perf { border-left-color: rgba(255,255,255,.4); }
.ticket.tonal .ticket-stub { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }
.ticket.tonal .ticket-perf { border-left-color: color-mix(in srgb, var(--md-on-secondary-container) 35%, transparent); }

.ticket-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }

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

/* Manifest rows: dot-leader label/value pairs used inside tickets */
.manifest-row { display: flex; align-items: baseline; gap: .4rem; font-size: .82rem; padding: .3rem 0; }
.manifest-row .label { color: var(--text-muted); white-space: nowrap; }
.manifest-row .leader { flex: 1; border-bottom: 1px dotted var(--border); margin-bottom: .25rem; }
.manifest-row .value { font-family: var(--font-mono); font-weight: 600; white-space: nowrap; }

/* ── Ring stamps - verification marks, reusing the EVA seal's own
   ring-of-text idea. currentColor drives the SVG so a wrapper class
   tints it like any icon. Requires the eva-emblem <symbol> sprite
   (partials/eva-emblem.php) to be present once on the page. ──────── */
.stamp-row { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start; }
.stamp-badge { display: inline-flex; flex-direction: column; align-items: center; gap: .6rem; width: clamp(132px, 9vw + 4rem, 168px); text-align: center; }
.stamp-badge svg { display: block; width: 100%; height: auto; }
.stamp-badge span { font-size: .78rem; color: var(--text-muted); }
.stamp-badge.success { color: var(--success); }
.stamp-badge.info { color: var(--info); }
.stamp-badge.primary { color: var(--md-primary); }

/* Small collectible milestone stamps - distinct from ring stamps
   (those verify a record; these celebrate a milestone). */
.passport-stamps { display: flex; gap: .9rem; flex-wrap: wrap; margin-top: .85rem; }
.p-stamp { display: flex; flex-direction: column; align-items: center; gap: .35rem; width: 64px; text-align: center; }
.p-stamp .ring { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; border: 2px solid currentColor; }
.p-stamp .ring .msr { font-size: 20px; }
.p-stamp span { font-size: .68rem; line-height: 1.25; color: var(--text-muted); }
.p-stamp.earned { color: var(--md-primary); }
.p-stamp.earned .ring { background: var(--md-primary-container); }
.p-stamp.locked { color: var(--md-outline); opacity: .6; }
.p-stamp.locked .ring { border-style: dashed; }

/* ── Language-of-instruction day strip ────────────────────────────── */
.lang-flag {
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    font-size: .66rem;
    font-weight: 800;
    letter-spacing: .01em;
    flex-shrink: 0;
}
.lang-flag.zh { background: var(--chinese-c); color: var(--chinese); }
.lang-flag.en { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }

.day-strip { display: flex; flex-direction: column; gap: .5rem; }
.day-strip .period {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .55rem .8rem;
    border-radius: var(--shape-md);
    background: var(--md-surface-container-low);
}
.day-strip .period .time { font-family: var(--font-mono); font-size: .82rem; color: var(--text-muted); width: 3.4em; flex-shrink: 0; }
.day-strip .period .subj { flex: 1; font-weight: 600; font-size: .92rem; }

/* ── Word-of-the-day card ──────────────────────────────────────────── */
.word-card { display: flex; flex-direction: column; gap: .5rem; align-items: flex-start; }
.word-card .hanzi-row { display: flex; align-items: center; gap: 1rem; }
.word-card .hanzi { font-family: var(--font-display); font-size: clamp(3rem, 2rem + 4vw, 4.75rem); line-height: 1; }
.word-card .pinyin { font-family: var(--font-mono); font-size: 1.1rem; color: var(--text-muted); }
.word-card .gloss { font-size: 1.02rem; font-weight: 600; }
.word-card .example { font-size: .88rem; color: var(--text-muted); font-style: italic; }
.word-card .example span { font-style: normal; }
.word-card .also-row { display: flex; align-items: center; gap: .5rem; padding-top: .35rem; margin-top: .1rem; border-top: 1px solid var(--border-light); width: 100%; }
.word-card .also-row .also-lang { font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.word-card .also-row strong { font-size: .95rem; flex: 1; }

/* Visual feedback while the Web Speech API is actually speaking a
   word - see partials/word-of-day.php and app.js's data-speak handler. */
.icon-btn.speaking .msr { animation: speak-pulse 900ms ease-in-out infinite; }
@keyframes speak-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .5; transform: scale(1.18); } }

/* ── Proficiency route tracker ───────────────────────────────────── */
.route-track { display: flex; position: relative; padding-top: 2.4rem; }
.route-track::before {
    content: '';
    position: absolute;
    left: 6%;
    right: 6%;
    top: calc(2.4rem + 7px);
    border-top: 2px dashed var(--border);
    z-index: 0;
}
.route-wp { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: .55rem; position: relative; z-index: 1; text-align: center; }
.route-wp .dot { width: 16px; height: 16px; border-radius: 50%; background: var(--surface); border: 2px solid var(--md-outline); }
.route-wp.done .dot { background: var(--md-primary); border-color: var(--md-primary); }
.route-wp.current .dot { width: 20px; height: 20px; background: var(--eva-orange); border-color: var(--eva-orange); box-shadow: 0 0 0 5px color-mix(in srgb, var(--eva-orange) 22%, transparent); }
.route-wp .marker { position: absolute; top: -1.9rem; font-size: 19px; color: var(--eva-orange); }
.route-wp span { font-size: clamp(.62rem, 2vw, .8rem); font-weight: 600; color: var(--text-muted); overflow-wrap: break-word; word-break: break-word; max-width: 100%; }
.route-wp.current span, .route-wp.done span { color: var(--text); }

/* Route divider - a dashed break used sparingly between dense
   content sections, not on every heading. */
.route-divider { display: flex; align-items: center; gap: .75rem; margin: 2.25rem 0; color: var(--md-outline); }
.route-divider::before, .route-divider::after { content: ''; flex: 1; height: 0; border-top: 1.5px dashed var(--border); }
.route-divider .msr { font-size: 19px; color: var(--md-primary); }

/* ── Dashboard gauge ring (CSS conic-gradient, not Chart.js - a
   single static KPI doesn't need canvas overhead). Hole must match
   whatever surface the ring sits on - same background-matching
   gotcha as the ticket perforation above. ────────────────────────── */
.goal-ring {
    --pct: 50;
    position: relative;
    width: 84px;
    height: 84px;
    border-radius: 50%;
    flex-shrink: 0;
    background: conic-gradient(var(--md-primary) calc(var(--pct) * 1%), var(--md-surface-container-highest) 0);
    display: grid;
    place-items: center;
}
.goal-ring .hole {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: var(--surface);
    display: grid;
    place-items: center;
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--text);
}

/* ── Chart containers (Chart.js canvases) ─────────────────────────── */
.chart-box { position: relative; height: 260px; }
.chart-box.sm { height: 130px; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .75rem; }
.chart-legend span { display: inline-flex; align-items: center; gap: .4rem; font-size: .78rem; color: var(--text-muted); }
.chart-legend i { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }

/* ── Photo Frame (single random promotional photo) ──────────────────────── */

.photo-frame {
    margin: 0;
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    background: var(--surface-alt);
}

.photo-frame picture {
    display: block;
    width: 100%;
    height: 100%;
}

.photo-frame img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.photo-frame-4x3 { aspect-ratio: 4 / 3; }
.photo-frame-16x9 { aspect-ratio: 16 / 9; }
.photo-frame-1x1 { aspect-ratio: 1 / 1; }
.photo-frame-3x4 { aspect-ratio: 3 / 4; }

.photo-frame figcaption {
    padding: .6rem .9rem;
    font-size: .78rem;
    color: var(--text-muted);
    background: var(--surface);
    border-top: 1px solid var(--border-light);
}

/* ── Photo Carousel (rotating set of random promotional photos) ─────────── */

.photo-carousel {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    background: var(--surface-alt);
}

.photo-carousel-4x3 { aspect-ratio: 4 / 3; }
.photo-carousel-16x9 { aspect-ratio: 16 / 9; }
.photo-carousel-1x1 { aspect-ratio: 1 / 1; }

.photo-carousel-track {
    position: relative;
    width: 100%;
    height: 100%;
}

.photo-carousel-slide {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    transition: opacity var(--dur-medium) var(--ease-emphasized);
}

.photo-carousel-slide.is-active {
    opacity: 1;
}

.photo-carousel-slide picture {
    display: block;
    width: 100%;
    height: 100%;
}

.photo-carousel-slide img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.photo-carousel-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, .38);
    color: #fff;
    cursor: pointer;
    transition: background .2s;
}

.photo-carousel-arrow:hover { background: rgba(0, 0, 0, .58); }
.photo-carousel-prev { left: .75rem; }
.photo-carousel-next { right: .75rem; }

.photo-carousel-dots {
    position: absolute;
    left: 50%;
    bottom: .85rem;
    transform: translateX(-50%);
    display: flex;
    gap: .4rem;
}

.photo-carousel-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, .5);
    cursor: pointer;
    transition: background .2s, transform .2s;
}

.photo-carousel-dot.is-active {
    background: #fff;
    transform: scale(1.25);
}

@media (prefers-reduced-motion: reduce) {
    .photo-carousel-slide { transition: none; }
}
.searchbar .msr { color: var(--md-on-surface-variant); }

/* ════════════════════════════════════════════════════════════════
   CLASS TICKETS — full-width row variant of the .ticket pattern,
   built for the teacher "My Classes" view (one ticket per class:
   aggregate stub, columned body, action rail, native details/
   summary quick view). Spec: specifications/mockups/
   teacher-class-tickets.html. Purely additive to the base .ticket
   component above.
   ════════════════════════════════════════════════════════════════ */
.class-ticket-list { display: grid; grid-template-columns: 1fr; gap: 1rem; }

/* Wider stub than the base 92px: it carries two figures (count +
   attendance rate) instead of one. */
.ticket.row .ticket-stub { flex-basis: 118px; }
.ticket.row .ticket-stub .msr { font-size: 26px; }
.ticket.row .ticket-stub b { font-size: 1.55rem; }
.ticket.row .ticket-main { padding: 1rem 1.2rem 1.1rem; }

.ticket-stub .stub-att {
    margin-top: .45rem;
    padding-top: .5rem;
    border-top: 1px dashed color-mix(in srgb, currentColor 35%, transparent);
    width: 72%;
    font-family: var(--font-mono);
    font-style: normal;
    font-size: .72rem;
    font-weight: 600;
}
.ticket-stub .stub-att small {
    display: block;
    font-family: var(--font-body);
    font-size: .56rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    opacity: .8;
}

/* Subject-tonal stub variants (container fill + solid text, same
   pairing as .lang-flag.zh; tokens from tokens.css). */
.ticket.subj-chinese .ticket-stub { background: var(--chinese-c); color: var(--chinese); }
.ticket.subj-chinese .ticket-perf { border-left-color: color-mix(in srgb, var(--chinese) 40%, transparent); }
.ticket.subj-math .ticket-stub { background: var(--math-c); color: var(--math); }
.ticket.subj-math .ticket-perf { border-left-color: color-mix(in srgb, var(--math) 40%, transparent); }
.ticket.subj-science .ticket-stub { background: var(--science-c); color: var(--science); }
.ticket.subj-science .ticket-perf { border-left-color: color-mix(in srgb, var(--science) 40%, transparent); }
.ticket.subj-ela .ticket-stub { background: var(--ela-c); color: var(--ela); }
.ticket.subj-ela .ticket-perf { border-left-color: color-mix(in srgb, var(--ela) 40%, transparent); }
.ticket.subj-social .ticket-stub { background: var(--social-c); color: var(--social); }
.ticket.subj-social .ticket-perf { border-left-color: color-mix(in srgb, var(--social) 40%, transparent); }
.ticket.subj-arts .ticket-stub { background: var(--arts-c); color: var(--arts); }
.ticket.subj-arts .ticket-perf { border-left-color: color-mix(in srgb, var(--arts) 40%, transparent); }

/* ── Ticket header row ──────────────────────────────────────────── */
.ticket-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.ticket-head .titles { min-width: 0; }
.ticket-head h4 { margin: 0; font-family: var(--font-display); font-size: 1.2rem; font-weight: 600; line-height: 1.2; }
.ticket-head .meta { margin-top: .25rem; font-size: .78rem; color: var(--text-muted); display: flex; align-items: center; gap: .35rem .6rem; flex-wrap: wrap; }
.ticket-head .meta .msr { font-size: 15px; vertical-align: -2px; }
.ticket-head .meta b { font-family: var(--font-mono); font-weight: 500; }

/* ── Ticket body columns ────────────────────────────────────────── */
.ticket-cols {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: .4rem 2rem;
    margin: .8rem 0 .9rem;
}
.ticket-cols .col-h { font-size: .64rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 .2rem; }

.manifest-row .value.good { color: var(--md-success); }
.manifest-row .value.bad  { color: var(--md-error); }
.manifest-row .value.warn { color: var(--md-warning); }

.spark { display: block; width: 100%; max-width: 210px; height: 26px; margin-top: .3rem; color: var(--md-success); opacity: .9; }

/* Flag chips (roster alerts) */
.flags { display: flex; flex-wrap: wrap; gap: .4rem; padding-top: .15rem; }
.flag {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    height: 27px;
    padding: 0 .65rem;
    border-radius: var(--shape-full);
    font-size: .7rem;
    font-weight: 700;
    white-space: nowrap;
}
.flag .msr { font-size: 15px; }
.flag.navy    { background: var(--md-primary-container);      color: var(--md-on-primary-container); }
.flag.warning { background: var(--md-warning-container);      color: var(--md-warning); }
.flag.error   { background: var(--md-error-container);        color: var(--md-on-error-container); }
.flag.muted   { background: var(--md-surface-container-high); color: var(--text-muted); }

/* ── Action rail ────────────────────────────────────────────────── */
.ticket-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding-top: .9rem;
    border-top: 1.5px dashed var(--border);
}
.ticket-actions .m-btn { height: 36px; padding: 0 1.05rem; font-size: .8rem; }
.ticket-actions .m-btn .msr { font-size: 17px; margin-left: -.3rem; }
.ticket-actions .m-text { padding: 0 .7rem; }

.m-btn .count {
    font-family: var(--font-mono);
    font-size: .68rem;
    font-weight: 600;
    background: color-mix(in srgb, currentColor 14%, transparent);
    border-radius: var(--shape-full);
    padding: .05rem .4rem;
    margin-right: -.3rem;
}

/* ── Quick view (native details/summary) ────────────────────────── */
.ticket-more { margin-top: .75rem; }
.ticket-more > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .3rem .8rem .3rem .55rem;
    border-radius: var(--shape-full);
    font-size: .76rem;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    user-select: none;
    transition: background var(--dur-short), color var(--dur-short);
}
.ticket-more > summary::-webkit-details-marker { display: none; }
.ticket-more > summary:hover { background: color-mix(in srgb, var(--md-on-surface) 7%, transparent); color: var(--text); }
.ticket-more > summary .msr { font-size: 19px; transition: transform var(--dur-short) var(--ease-emphasized); }
.ticket-more[open] > summary .msr { transform: rotate(180deg); }

.more-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1rem;
    margin-top: .75rem;
}
.more-col {
    background: var(--md-surface-container);
    border-radius: var(--shape-md);
    padding: .8rem .9rem;
    min-width: 0;
}
.more-col .col-h { font-size: .64rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 .45rem; }
.more-col .col-foot { margin-top: .5rem; }
.more-col .col-foot a { font-size: .76rem; font-weight: 600; color: var(--md-primary); text-decoration: none; }
.more-col .col-foot a:hover { text-decoration: underline; }

/* Mini roster rows inside the quick view */
.mini-item { display: flex; align-items: center; gap: .6rem; padding: .32rem 0; min-width: 0; }
.mini-item .avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    font-size: .66rem;
    font-weight: 700;
    color: #fff;
}
.mini-item .who { flex: 1; min-width: 0; font-size: .8rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-item .who small { display: block; font-weight: 400; font-size: .68rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-item .tags { display: flex; gap: .25rem; flex-shrink: 0; }
.mini-tag {
    font-size: .58rem;
    font-weight: 700;
    letter-spacing: .04em;
    padding: .1rem .4rem;
    border-radius: var(--shape-full);
}
.mini-tag.navy    { background: var(--md-primary-container); color: var(--md-on-primary-container); }
.mini-tag.warning { background: var(--md-warning-container); color: var(--md-warning); }
.mini-tag.error   { background: var(--md-error-container);   color: var(--md-on-error-container); }

/* Upcoming-assignment rows inside the quick view */
.plan-row { display: flex; align-items: center; gap: .55rem; padding: .3rem 0; font-size: .8rem; min-width: 0; }
.plan-row .day { font-family: var(--font-mono); font-size: .68rem; font-weight: 600; color: var(--text-muted); width: 3.4em; flex-shrink: 0; }
.plan-row .what { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 540px) {
    .ticket.row .ticket-stub { flex-basis: 92px; }
    .ticket.row .ticket-stub b { font-size: 1.3rem; }
    .ticket.row .ticket-main { padding: .9rem 1rem 1rem; }
    .ticket-cols { grid-template-columns: 1fr; gap: .5rem; }
}
