/* ==========================================================================
   Supplementary styles for page types template_file.php doesn't itself
   contain (dashboards, tables, stat cards) — built entirely on the same
   CSS custom properties (--brand-*, --surface, --text, --line, --r-*,
   --shadow-card) defined in template-exact.css's :root, so these blend
   into the same visual system rather than introducing a second one.
   ========================================================================== */

/* The template's own nav elements are <button>s, so they never needed an
   anchor reset. This app also links real hrefs (<a class="vertical-tab">,
   rail icons, etc.), which must not show the browser's default underline —
   and must not depend on an external CSS reset loading successfully. */
a.vertical-tab, a.vertical-tab:hover,
.vertical-icons-right a, .vertical-icons-right a:hover,
.fd-rail-link, a.rail-profile,
a.btn-sm-add, a.btn-sm-add:hover {
    text-decoration: none !important;
}

/* ==========================================================================
   In-page section tabs ("sub-tabs" — Aug 2026 "each major menu should be
   broken down into tabs so that one sub menu is only shown alone and not
   mixed" request). See subtabs.js for the show/hide behavior; this is
   purely the visual style. Deliberately flat, not the gradient-capsule
   look of the main app nav or the auth-page pill switcher (this same
   round's "no gradient stuff" ask) — a plain rounded strip with a solid
   fill on the active tab, closer to a segmented control than a floating
   dock, since this sits INSIDE a page's own white card/section rather
   than floating over it. */
.fd-subtabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    background: var(--brand-15);
    border: 1px solid var(--line);
    border-radius: var(--r-md, 16px);
    padding: 5px;
    margin-bottom: 22px;
}
.fd-subtabs button[data-subtab-target] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: 12px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
    white-space: nowrap;
}
.fd-subtabs button[data-subtab-target] i { font-size: 13px; color: inherit; }
.fd-subtabs button[data-subtab-target]:hover { background: var(--brand-50); color: var(--brand-600); }
.fd-subtabs button[data-subtab-target].active { background: var(--brand-600); color: #fff; }
@media (max-width: 700px) {
    .fd-subtabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
    .fd-subtabs::-webkit-scrollbar { height: 0; }
}
.fd-subtab-panel[hidden] { display: none !important; }

.fd-topbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }
.fd-topbar h2 { margin: 0; font-size: 22px; color: var(--brand-600); font-family: 'Poppins', sans-serif; }
.fd-context { font-size: 13px; color: var(--text-muted); }

.fd-section { margin-bottom: 28px; }
.fd-section h3 { font-size: 17px; margin-bottom: 14px; color: var(--brand-600); font-family: 'Poppins', sans-serif; }

.fd-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 24px; }
.fd-stat {
    background: var(--brand-25); border: 1px solid var(--brand-100); border-radius: var(--r-md);
    padding: 16px 18px;
}
.fd-stat .num { font-family: 'Poppins', sans-serif; font-size: 24px; font-weight: 700; color: var(--brand-600); }
.fd-stat .label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .4px; }

/* 2026-09-14, quoted directly: "seeing assessment results should be
   opened on same page via a pop up will designed and not on a new page."
   The result popup's own score display, replacing the old plain
   "score / max_score" text stat with a proper LMS-style progress ring -
   a pure-CSS conic-gradient (no chart library), the sweep driven by the
   --fd-pct custom property assessment_result.php sets inline per result
   (0-100), colored via the same --ok/--warn tokens .fd-badge.ok/.warn
   already use elsewhere so this reads as consistent with the rest of the
   platform's pass/attention language, not a one-off new color scheme. */
.fd-result-score-card {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 20px;
    border-radius: var(--r-lg, 18px);
    background: var(--ok-bg);
    border: 1px solid var(--ok);
}
.fd-result-score-card.warn { background: var(--warn-bg); border-color: var(--warn); }
.fd-result-score-ring {
    position: relative;
    flex: 0 0 auto;
    width: 88px;
    height: 88px;
    border-radius: 50%;
    background: conic-gradient(var(--ok) calc(var(--fd-pct) * 1%), rgba(0,0,0,0.08) 0);
    display: flex;
    align-items: center;
    justify-content: center;
}
.fd-result-score-card.warn .fd-result-score-ring {
    background: conic-gradient(var(--warn) calc(var(--fd-pct) * 1%), rgba(0,0,0,0.08) 0);
}
.fd-result-score-ring::before {
    content: '';
    position: absolute;
    inset: 8px;
    border-radius: 50%;
    background: var(--surface);
}
.fd-result-score-pct {
    position: relative;
    font-family: 'Poppins', sans-serif;
    font-size: 18px;
    font-weight: 700;
    color: var(--ok);
}
.fd-result-score-card.warn .fd-result-score-pct { color: var(--warn); }
.fd-result-score-meta { min-width: 0; }
.fd-result-score-num { font-family: 'Poppins', sans-serif; font-size: 22px; font-weight: 700; color: var(--text); }
.fd-result-score-num span { font-size: 14px; font-weight: 500; color: var(--text-muted); }
.fd-result-score-label { font-size: 13px; color: var(--text-muted); margin-top: 2px; }

/* ==========================================================================
   Table redesign, take two (Sep 2026 "change all tables on the entire
   platform into clean light gray cards, one row = one card, a bit of
   space, then the next, all stacked vertically" request). Every data
   table across the app already shares this one .fd-table/.fd-table-wrap
   class pair (confirmed - 119 <table> occurrences across 56 files, every
   single one using this class, nothing else), so - same as the previous
   redesign - the fix lives here, once, rather than per-page, and no
   PHP/markup changed anywhere: the real <table>/<thead>/<tbody>/<tr>/<td>
   structure server-side is untouched, only how it's PAINTED changes.
   fd-app-shell.js copies each <thead> th's text onto its column's td's
   as a `data-label` attribute once per page (any table missing a thead,
   e.g. a header-less list, just prints no label - still a clean value-
   only card). The thead itself is hidden - its job is now just supplying
   those labels. No JS anywhere depends on the real table DOM shape (also
   confirmed - no sort/filter/paginate/row-click code touches table rows
   directly), so this is purely visual. */
.fd-table-wrap {
    overflow-x: visible;
    border-radius: 0;
    border: none;
    box-shadow: none;
    background: transparent;
}
table.fd-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: transparent;
    display: block;
}
table.fd-table thead { display: none; }
table.fd-table tbody { display: block; }
table.fd-table tbody tr {
    display: block;
    background: var(--fd-card-bg);
    border-radius: 12px;
    padding: 12px 16px;
    margin-bottom: 10px;
    transition: background .12s ease;
}
table.fd-table tbody tr:last-child { margin-bottom: 0; }
table.fd-table tbody tr:hover { background: var(--fd-card-bg-hover); }
table.fd-table th, table.fd-table td {
    display: block;
    text-align: left;
    padding: 8px 0;
    font-size: 13.5px;
    border-bottom: 1px solid var(--line);
}
table.fd-table tbody tr td:last-child { border-bottom: none; padding-bottom: 0; }
table.fd-table tbody tr td:first-child { padding-top: 0; }
/* Sep 2026 (same-day follow-up): "can we make each item inside one
   section of the card be in a straight line like a row rather than
   having them each on their own line?" - label to the left, the cell's
   real value to the right, on one line, instead of the label stacked
   above it. The earlier version deliberately avoided plain flex here
   because a cell can hold several separate elements (a badge plus two
   action buttons) which `justify-content:space-between` would spread
   apart individually instead of keeping grouped - fd-app-shell.js's
   FIX 3 now wraps a labeled cell's real content in one `.fd-td-value`
   span first (see its own comment), so a flex row here only ever has
   at most two items - the label and that one wrapper - and whatever's
   inside the wrapper stays together and simply wraps as a group if the
   row gets too narrow. */
table.fd-table td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
table.fd-table td::before {
    content: attr(data-label);
    display: block;
    flex: 0 0 auto;
    color: var(--text-muted);
    text-transform: uppercase;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .3px;
}
table.fd-table td:not([data-label])::before,
table.fd-table td[data-label=""]::before { content: none; }
table.fd-table td .fd-td-value {
    flex: 1 1 auto;
    min-width: 0;
    text-align: right;
}
table.fd-table td:not([data-label]) .fd-td-value,
table.fd-table td[data-label=""] .fd-td-value {
    text-align: left;
}

.fd-badge { display: inline-block; padding: 3px 11px; border-radius: var(--r-pill); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; }
.fd-badge.ok { background: var(--ok-bg); color: var(--ok); }
.fd-badge.warn { background: var(--warn-bg); color: var(--warn); }
.fd-badge.err { background: var(--err-bg); color: var(--err); }

/* Sep 2026 follow-up, quoted directly: "also a little dot on the class tab
   on the nav bar to indicate that something is up." An unobtrusive unread
   dot on a subject's own nav icon (header.php's .vertical-tab loop, both the
   mobile bottom dock and the desktop side-nav pill share this one element) -
   same red as #fdNotifBadgeRail's own numeric bell badge just below, but a
   plain dot rather than a count since this is per-subject, not one global
   number. .vertical-tab is already `position: relative`, so this positions
   against the icon/button itself with no extra wrapper markup needed. */
.fd-nav-unread-dot { position: absolute; top: 4px; right: 10px; width: 9px; height: 9px; border-radius: 50%; background: var(--err); box-shadow: 0 0 0 2px var(--brand-600); }
@media (max-width: 768px) {
    .fd-nav-unread-dot { top: 2px; right: 14px; }
}

/* ==========================================================================
   Teacher dashboard home (public/teacher/index.php) — greeting hero, 4-stat
   grid, "My Classes" card grid, "Recent Activity" list. Visual reference:
   the user-supplied teacher-dashboard HTML template (Sep 2026) — same
   layout/proportions, but rebuilt entirely on this app's own CSS custom
   properties (--brand-*, --surface, --line, --text-muted, --r-*, --ok/
   --warn/--err + their -bg pairs) instead of the template's own hardcoded
   hex colors, so dark mode (already globally wired via toggleDarkMode()/
   [data-theme]) works with zero extra JS, and so nothing here leaks into
   any other page — every selector is scoped under .fd-teacher-home.
   House-style spacing rule (Sep 2026, "rows must never look joined on
   mobile" — the recurring fix applied to the arc/faculty-list/quick-menu
   elsewhere in this file): every grid/list below carries a real gap and
   per-item padding, checked at a 390px viewport. ========================== */
.fd-teacher-home { display: block; }

.fd-dash-hero {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 22px;
}
.fd-dash-greeting { font-size: 21px; font-weight: 700; margin: 0 0 4px 0; color: var(--text); font-family: 'Poppins', sans-serif; }
.fd-dash-sub { margin: 0; font-size: 13.5px; color: var(--text-muted); }
.fd-dash-date {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: var(--brand-50);
    color: var(--brand-600);
    border-radius: var(--r-pill);
    padding: 7px 16px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.fd-dash-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 14px;
    margin-bottom: 26px;
}
.fd-dash-stat {
    background: var(--brand-25);
    border: 1px solid var(--brand-100);
    border-radius: var(--r-md);
    padding: 16px 16px 14px 16px;
    position: relative;
    transition: transform .2s ease, box-shadow .2s ease;
}
.fd-dash-stat:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); }
.fd-dash-stat-icon {
    position: absolute;
    top: 14px;
    right: 14px;
    font-size: 19px;
    color: var(--brand-200);
}
.fd-dash-stat-num { font-family: 'Poppins', sans-serif; font-size: 26px; font-weight: 700; color: var(--brand-600); line-height: 1.2; }
.fd-dash-stat-label { font-size: 12.5px; color: var(--text-muted); font-weight: 500; margin-top: 2px; }

.fd-dash-section-title {
    font-size: 16.5px;
    font-weight: 700;
    margin: 26px 0 14px 0;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 9px;
    font-family: 'Poppins', sans-serif;
}
.fd-dash-section-title i { color: var(--brand-600); }

.fd-dash-class-grid {
    display: grid;
    /* Sep 2026 class-grid rework: a fixed 4-column layout ("the grid can
       make 4 classes in a row") rather than the previous auto-fit, which
       used to stretch a single card to fill the whole row - each class now
       always occupies exactly one of the 4 columns, however many classes
       there are, and a lone class sits in the first column instead of
       spanning the row. Responsive breakpoints below step this down as the
       viewport narrows, never back to a single stretched card. */
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 8px;
}
.fd-dash-class-card {
    display: block;
    background: var(--brand-25);
    border: 1px solid var(--brand-100);
    border-radius: var(--r-lg);
    padding: 20px 14px;
    text-align: center;
    text-decoration: none !important;
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.fd-dash-class-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); border-color: var(--brand-200); }
.fd-dash-class-icon {
    position: relative;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    margin: 0 auto 10px auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    color: #fff;
    background: var(--grad-brand, linear-gradient(135deg, var(--brand-500), var(--brand-600)));
}

/* Sep 2026 fourth follow-up: "when there is an evaluation or online
   classes created the class grid box should have an additional icon to
   indicate the respective activitiy" - a small pair of badge dots pinned
   to the bottom-right corner of the class icon circle, one per activity
   type present (video camera = has an online class, pen-on-paper = has
   an evaluation) - both can show at once. White ring around each dot so
   it reads clearly against the icon's own gradient background instead of
   blending into it. */
.fd-dash-class-badges {
    position: absolute;
    bottom: -3px;
    right: -3px;
    display: flex;
    gap: 2px;
}
.fd-dash-class-badge {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    color: #fff;
    background: var(--brand-600);
    border: 2px solid #fff;
}
.fd-dash-class-name { display: block; font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 3px; }
.fd-dash-class-meta { display: block; font-size: 11.5px; color: var(--text-muted); line-height: 1.4; }

/* Sep 2026 class-card rework - one card per CLASS (not per subject),
   showing the class name first, its subject count under it, and a small
   row of action icons (Edit, Assignments) pinned to the top-right corner.
   Keeps the same brand-tinted card look as .fd-dash-class-card (which
   stays in place, still used by anything that renders the older per-
   subject shape) rather than introducing a visually different component. */
.fd-dash-class-card2 {
    position: relative;
    background: var(--brand-25);
    border: 1px solid var(--brand-100);
    border-radius: var(--r-lg);
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.fd-dash-class-card2:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); border-color: var(--brand-200); }
.fd-dash-class-actions {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    z-index: 2;
}
.fd-dash-class-action-btn {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: none;
    background: var(--surface);
    color: var(--brand-600);
    font-size: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(0,0,0,0.12);
    transition: background .15s ease, transform .15s ease;
}
.fd-dash-class-action-btn:hover { background: var(--brand-600); color: #fff; transform: scale(1.08); }
.fd-dash-class-body {
    display: block;
    padding: 20px 14px;
    text-align: center;
    text-decoration: none !important;
    cursor: pointer;
    background: none;
    border: none;
    width: 100%;
    font: inherit;
}
.fd-dash-class-subcount {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 11.5px;
    color: var(--text-muted);
    line-height: 1.4;
}

/* Sep 2026: ".fd-dash-activity-*" (the Recent Activity list) removed
   outright - "Created class Form 2 - remove all this recent activities."
   See teacher/index.php's own removal note near where
   fd_dash_activity_block() used to be defined. */

/* Sep 2026 dashboard unification - the "My Private Classes" / "School
   Classes" tab switcher on teacher/index.php. Same pill-capsule idea as
   .fd-auth-tabs (pre-login page switcher) but a lighter-weight, inline
   variant matching this page's own .fd-dash-* look (brand-50 background,
   brand-600 active state) rather than that switcher's opaque brand-600
   capsule - this one sits among ordinary dashboard content, not alone on
   a bare login page. */
.fd-dash-tabs {
    display: flex;
    gap: 6px;
    width: fit-content;
    max-width: 100%;
    flex-wrap: wrap;
    background: var(--brand-50);
    border-radius: 14px;
    padding: 5px;
    margin-bottom: 22px;
}
.fd-dash-tab-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 18px;
    border-radius: 10px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s ease, color .15s ease;
}
.fd-dash-tab-btn i { color: inherit; }
.fd-dash-tab-btn:hover { color: var(--text); }
.fd-dash-tab-btn.active { background: var(--surface); color: var(--brand-600); box-shadow: var(--shadow-card); }
.fd-dash-tab-count {
    background: var(--brand-100);
    color: var(--brand-700);
    border-radius: var(--r-pill);
    padding: 1px 8px;
    font-size: 11px;
    font-weight: 700;
}
.fd-dash-tab-btn.active .fd-dash-tab-count { background: var(--brand-50); }

/*
 * 2026-09-26 (forty-seventh follow-up), quoted: "an empty study tab or task
 * tab should not have that rectangle gray box also make the icon abit bigger
 * but make sure to remove the rectangle gray box background."
 *
 * The tinted panel drew a hard box around a state that is, by definition,
 * nothing - so an empty tab looked like a broken component rather than a
 * calm "nothing here yet". No background, no border; the icon carries it
 * instead, and it is larger for that.
 */
.fd-dash-empty-state {
    text-align: center;
    padding: 40px 20px;
    background: transparent;
    border: 0;
    border-radius: var(--r-lg);
}
.fd-dash-empty-state i { font-size: 46px; color: var(--brand-200); margin-bottom: 14px; }
.fd-dash-empty-state p { margin: 0 0 6px 0; font-size: 14px; font-weight: 600; color: var(--text); }
.fd-dash-empty-state p.fd-context { font-weight: 400; max-width: 440px; margin: 0 auto 18px auto; }
.fd-dash-empty-state .btn-sm-add { display: inline-flex; }

/* Sep 2026: "the classes section can be 4 per row and col-6 on mobile" -
   desktop/tablet now stay at the base 4-per-row all the way down to the
   768px mobile breakpoint (the old 992px 3-per-row step-down is gone,
   unifying desktop+tablet at 4); mobile switches to col-6 (2 per row,
   Bootstrap's own naming for "half width") instead of the previous
   "still 4 across, just shrunk to fit" approach - with only 2 per row
   now there's no need to shrink the card nearly as aggressively, so
   icon/text sizes here are close to their desktop size again. */
/* Sep 2026 follow-up, quoted directly: "on mobile the teacher index page
   should have the pie chart and the classes in a row horizontally and
   scrollable just like the tabs in the class_tools sections." Converts
   the grid to the exact same flex/overflow-x pattern .fd-tool-tab-grid
   already uses (class_tools.php's own tab strip) instead of a 2-per-row
   grid - class-card2 becomes a fixed-width flex item so the row scrolls
   instead of wrapping. */
@media (max-width: 768px) {
    .fd-dash-class-grid {
        display: flex;
        grid-template-columns: none;
        gap: 10px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 2px;
    }
    .fd-dash-class-grid::-webkit-scrollbar { display: none; }
    .fd-dash-class-card2 { flex: 0 0 auto; width: 132px; }
    .fd-dash-class-card { padding: 14px 10px; }
    .fd-dash-class-body { padding: 14px 10px; }
    .fd-dash-class-icon { width: 44px; height: 44px; font-size: 18px; margin-bottom: 8px; }
    .fd-dash-hero { margin-bottom: 18px; }
    .fd-dash-tab-btn { flex: 1 1 auto; justify-content: center; padding: 9px 12px; }
}
@media (max-width: 480px) {
    .fd-dash-stat-num { font-size: 22px; }
    .fd-dash-class-card2 { width: 118px; }
    .fd-dash-class-card { padding: 12px 8px; }
    .fd-dash-class-body { padding: 12px 8px; }
    .fd-dash-class-icon { width: 38px; height: 38px; font-size: 16px; margin-bottom: 6px; }
    .fd-dash-empty-state { padding: 28px 16px; }
}

/* ==========================================================================
   Sep 2026 student-dashboard rework, quoted directly: "the dashboard for
   student rather than having the class it should be replace by the
   subjects in a horizontal row which slides to show all the subjects."
   Unlike .fd-dash-class-grid (a real grid on desktop, only switching to a
   horizontal scroll strip under the 768px breakpoint above), this carousel
   is ALWAYS a horizontal-scrolling flex row, at every width - reuses the
   exact same .fd-dash-class-card2/-body/-icon/-name/-subcount visuals
   (subjects.php's own subject-card look) rather than a new component, just
   in a different wrapper. Cards are real <button> elements (not the usual
   div-wrapping-a-button - there's no separate "leave" affordance to make
   room for on a subject card), given .fd-dash-class-body's own
   display:block/padding/cursor reset alongside .fd-dash-class-card2's
   background/border/radius so both apply from the one element.
   ========================================================================== */
.fd-subject-carousel {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    padding-bottom: 4px;
    margin-bottom: 8px;
}
.fd-subject-carousel::-webkit-scrollbar { display: none; }
.fd-subject-carousel-card {
    flex: 0 0 auto;
    width: 150px;
    scroll-snap-align: start;
}
@media (max-width: 480px) {
    .fd-subject-carousel-card { width: 128px; }
}

/* Sep 2026 follow-up, quoted directly: "on the teacher's account where we
   have my classes: it should show the subject then the class name under
   for example chemistry then other form 5 for all the subjects. which
   should also be in a row that scroll for mobile then for desktop it can
   be in a grid." teacher/classes.php's own "My classes" cards (one per
   teacher_assignment/subject+class combo - see that loop's own comment)
   move into this grid. A real CSS grid on desktop, switching to the exact
   same horizontal-scroll flex row at the exact same 768px breakpoint
   .fd-dash-class-grid already uses - but a SIBLING class, not a reuse of
   .fd-dash-class-grid/-card2 outright: those cards are a fixed 132px/118px
   width tuned for a small icon-only tile (teacher/index.php's own compact
   "My Classes" grid), while this page's cards carry more per-class detail
   (join code, a QR code, a price/plan badge, an inline add-student form)
   that a tile that narrow would clip - same mechanism, wider card. */
.fd-teacher-subject-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 14px;
    margin-bottom: 8px;
}
.fd-teacher-subject-card {
    position: relative;
    background: var(--brand-25);
    border: 1px solid var(--brand-100);
    border-radius: var(--r-lg);
    padding: 18px 16px;
}
.fd-teacher-subject-link { display: block; text-decoration: none !important; color: inherit; }
.fd-teacher-subject-name {
    font-family: 'Poppins', sans-serif;
    font-size: 17px;
    font-weight: 700;
    color: var(--text);
    margin: 0 4px 2px 0;
    padding-right: 30px;
}
.fd-teacher-subject-class { font-size: 13px; color: var(--text-muted); margin: 0 0 10px 0; }
.fd-teacher-subject-edit {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--surface);
    color: var(--brand-600);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    box-shadow: 0 2px 6px rgba(0,0,0,0.12);
    text-decoration: none !important;
    transition: background .15s ease, color .15s ease, transform .15s ease;
}
.fd-teacher-subject-edit:hover { background: var(--brand-600); color: #fff; transform: scale(1.08); }
@media (max-width: 768px) {
    .fd-teacher-subject-grid {
        display: flex;
        grid-template-columns: none;
        gap: 12px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 2px;
    }
    .fd-teacher-subject-grid::-webkit-scrollbar { display: none; }
    .fd-teacher-subject-card { flex: 0 0 auto; width: 260px; }
}
html[data-theme="dark"] .fd-teacher-subject-card { background: var(--surface); border-color: var(--line); }
html[data-theme="dark"] .fd-teacher-subject-edit { background: var(--surface); box-shadow: 0 2px 6px rgba(0,0,0,0.4); }

/* Sep 2026 UI-bug follow-up, quoted directly: "on mobile, the pie/donut
   chart should be col-12 while 'My Classes' sits on a new line below (not
   side-by-side)." Reverses the previous "chart rides along as the leading
   item of the class grid's own horizontal scroll row" behavior (see
   fd_dash_class_grid()'s $leadingHtml docblock, teacher/index.php, and
   .fd-dash-summary-row's own 768px rule further down which this pairs
   with) - the chart no longer duplicates into that scroll row at all, so
   it never shares a row with the class cards; it now shows once, full
   width, via .fd-dash-summary-row itself (see that rule) with "My
   Classes" as its own line below. $leadingHtml is still passed/rendered
   server-side (cheap, harmless) but this slot itself stays hidden at
   every width so nothing doubles up. */
.fd-dash-chart-mobile-slot { display: none; }

html[data-theme="dark"] .fd-dash-stat,
html[data-theme="dark"] .fd-dash-class-card,
html[data-theme="dark"] .fd-dash-class-card2,
html[data-theme="dark"] .fd-dash-empty-state {
    background: var(--surface);
    border-color: var(--line);
}
html[data-theme="dark"] .fd-dash-stat:hover,
html[data-theme="dark"] .fd-dash-class-card:hover,
html[data-theme="dark"] .fd-dash-class-card2:hover { border-color: var(--brand-200); }
html[data-theme="dark"] .fd-dash-class-action-btn { background: var(--surface); box-shadow: 0 2px 6px rgba(0,0,0,0.4); }
html[data-theme="dark"] .fd-dash-date { background: var(--brand-50); color: var(--brand-600); }
html[data-theme="dark"] .fd-dash-tabs { background: var(--surface); }
html[data-theme="dark"] .fd-dash-tab-btn.active { background: var(--brand-50); }

/* ==========================================================================
   Sep 2026 class-tools feature: the sheet-injected "Edit class" form (JS-
   built markup inside #fdcSheetViewport, since it isn't a server-rendered
   <form> - see fdOpenClassEdit() in teacher/index.php) and its bottom
   action row - "a long width save on the middle and cancel buttons on the
   left both on a row at the bottom", per the product ask.
   ========================================================================== */
.fd-sheet-form label { font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.fd-sheet-actions-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
}
.fd-sheet-btn-cancel {
    flex: 0 0 auto;
    padding: 12px 20px;
    border-radius: 12px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--text-muted);
    font-weight: 600;
    cursor: pointer;
}
.fd-sheet-btn-cancel:hover { color: var(--text); border-color: var(--brand-200); }
.fd-sheet-btn-save {
    flex: 1 1 auto;
    padding: 12px 20px;
    border-radius: 12px;
    border: none;
    background: var(--grad-brand, linear-gradient(135deg, var(--brand-500), var(--brand-600)));
    color: #fff;
    font-weight: 700;
    text-align: center;
    cursor: pointer;
}
.fd-sheet-btn-save:hover { opacity: .92; }

/* class_tools.php - the row of 4 big tool tiles (Online Classes /
   Assignment / Attendance / Extra) a teacher lands on after picking a
   class+subject. Deliberately similar in spirit to .fd-dash-class-grid
   (4 columns, brand-tinted cards) but taller/centered, since these are the
   whole point of the page rather than one item among many.
   Sep 2026 follow-up: these are now used as a static callout row that
   links out is no longer the interaction (see .fd-tool-tab-* below, which
   replaced link-tiles with real switching tabs) - kept in the stylesheet
   since nothing in this codebase references it as dead weight to remove,
   but class_tools.php itself no longer renders .fd-tool-grid/.fd-tool-tile
   markup after this pass. */
.fd-tool-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin: 8px 0 24px 0;
}
.fd-tool-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 28px 12px;
    border-radius: var(--r-lg);
    text-decoration: none !important;
    color: #fff;
    text-align: center;
    font-weight: 700;
    font-size: 14px;
    transition: transform .2s ease, box-shadow .2s ease;
    min-height: 130px;
}
.fd-tool-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); }
.fd-tool-tile i { font-size: 26px; }
.fd-tool-tile.tone-online { background: linear-gradient(135deg, #6C63FF, #5849D6); }
.fd-tool-tile.tone-assignment { background: linear-gradient(135deg, #FF9F43, #E8590C); }
.fd-tool-tile.tone-attendance { background: linear-gradient(135deg, #20C997, #1C8A4C); }
.fd-tool-tile.tone-extra {
    background: var(--brand-25);
    color: var(--text-muted);
    border: 1px dashed var(--brand-150);
    cursor: default;
}
.fd-tool-tile.tone-extra:hover { transform: none; box-shadow: none; }
@media (max-width: 768px) { .fd-tool-grid { grid-template-columns: repeat(2, 1fr); } }

/* ==========================================================================
   Sep 2026 class-tools tabs rework: "the tab icons should be same like the
   account type selection on the auth page exactly the same like that."
   Deliberate near-exact copy of login.php's .account-type-grid/
   .account-type-card (same padding/radius/icon-medallion/selected-state/
   checkmark shape) under new class names - NOT the same classes, so a
   change here can never affect the auth page's own picker.

   Sep 2026, second follow-up (class_tools 5-tab rework): superseded the
   old "forced 4-across grid, never collapses" layout below. New ask:
   "these tabs you can make it slide horizontally if they are many on
   mobile, while on desktop you can put even 6 per row so that it stays
   all on a straight line." Switched from a fixed grid to a single-row
   flex strip: desktop divides the row evenly across however many tabs
   exist (flex:1 1 0, no wrap - stays on one straight line up to ~6-8
   before cards would need to keep shrinking rather than wrap, fine for
   today's fixed 5-tab set); mobile switches each card to a fixed
   min-width and lets the strip itself scroll horizontally
   (overflow-x:auto) instead of shrinking further, which is what actually
   produces "slide horizontally if they are many" on a real phone
   viewport. fdShowToolTab() (class_tools.php) is untouched - it only
   toggles by data-tab/.active, agnostic to grid vs. flex.
   ========================================================================== */
/* Sep 2026, FOURTH nav-rework pass: "add some space between the tools and
   the start of the title for evaluation or my session or attendance etc
   for all the tools and class pages" - this strip sits directly above
   every one of class_tools.php's 5 tab panels (Online/Evaluation/
   Attendance/Notifications/Rewards), so bumping its own bottom margin is
   one change that adds the gap uniformly in front of every panel's own
   title ("My sessions", "Evaluations", "Summary", ...) without touching
   each panel's markup individually. Was 22px. */
.fd-tool-tab-grid { display: flex; gap: 12px; margin: 4px 0 36px 0; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.fd-tool-tab-grid::-webkit-scrollbar { display: none; }
.fd-tool-tab-card {
    flex: 1 1 0;
    min-width: 0;
    background: var(--brand-20);
    border: 2px solid transparent;
    border-radius: 20px;
    padding: 20px 8px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
}
.fd-tool-tab-card:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(88, 73, 214, 0.12); border-color: var(--brand-150); }
.fd-tool-tab-card.active { border-color: var(--brand-500); background: var(--brand-50); box-shadow: 0 8px 25px rgba(88, 73, 214, 0.15); }
.fd-tool-tab-card.disabled { opacity: 0.5; cursor: not-allowed; }
.fd-tool-tab-card.disabled:hover { transform: none; box-shadow: none; border-color: transparent; }
.fd-tool-tab-icon {
    width: 52px; height: 52px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    margin: 0 auto 10px auto; font-size: 22px; color: #fff; transition: all 0.3s ease;
}
.fd-tool-tab-icon.online { background: linear-gradient(135deg, #6C63FF, #5849D6); }
.fd-tool-tab-icon.evaluation { background: linear-gradient(135deg, #FF9F43, #E8590C); }
.fd-tool-tab-icon.attendance { background: linear-gradient(135deg, #20C997, #1C8A4C); }
.fd-tool-tab-icon.extra { background: linear-gradient(135deg, #BA68C8, #7B3FA0); }
.fd-tool-tab-name { font-size: 13px; font-weight: 700; color: var(--text); display: block; margin-bottom: 2px; }
.fd-tool-tab-desc { font-size: 10.5px; color: var(--text-muted); display: block; line-height: 1.35; }
/* Sep 2026: "remove the check icon on the selected tool tab" - the
   .fd-tool-tab-check badge (a checkmark pinned to the corner of the
   active card) and its markup are both gone; .fd-tool-tab-card.active's
   own border/background/shadow above is what now shows selection. */
@media (max-width: 768px) {
    .fd-tool-tab-grid { gap: 8px; }
    .fd-tool-tab-card { flex: 0 0 auto; width: 104px; padding: 14px 4px; }
    .fd-tool-tab-icon { width: 40px; height: 40px; font-size: 16px; margin-bottom: 6px; }
    .fd-tool-tab-name { font-size: 10.5px; }
    .fd-tool-tab-desc { display: none; }
}

/* Sep 2026 follow-up, quoted directly: "the classes on step 2 should
   inherit something similar to the class_tools tab design." The Create
   Class wizard's Class step (footer.php's fdCreateClassStepClass()) used
   to pick an existing class from the same small .chip-select-grid pills
   used elsewhere in this wizard; now it borrows class_tools.php's own tab
   card look (icon-in-a-gradient-circle, name, selected = colored border +
   tinted background) instead - .fd-tool-tab-card itself isn't reused
   directly because that class assumes a FIXED small set sharing one row
   evenly (flex: 1 1 0, exactly 5 tool tabs); a teacher's own class list is
   open-ended, so this variant wraps onto as many rows as needed at a
   fixed card width instead of dividing one row. */
/* Sep 2026 follow-up, quoted directly: "lets arrange then in a one line
   horizontal manner which is scrollable horizontally and also differernt
   colors to make it beautiful." Was flex-wrap:wrap + a vertical scrollbox
   (max-height/overflow-y) - now a single row that scrolls sideways
   instead, same horizontal-strip pattern already established by
   .fd-tool-tab-grid (app-extra.css, above) - and each card's icon now
   carries its own inline gradient (footer.php's fdWizardClassTones,
   cycled per card - same 6-color palette index.php's own class-grid
   cards already use) instead of every card sharing one fixed purple. */
.fd-wizard-class-grid {
    display: flex; flex-wrap: nowrap; gap: 10px; margin: 4px 0 14px 0;
    overflow-x: auto; overflow-y: hidden; padding-bottom: 6px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.fd-wizard-class-grid::-webkit-scrollbar { display: none; }
.fd-wizard-class-card {
    flex: 0 0 auto; width: 118px;
    background: var(--brand-20); border: 2px solid transparent; border-radius: 18px;
    padding: 16px 6px; text-align: center; cursor: pointer; transition: all 0.2s ease;
}
.fd-wizard-class-card:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(88, 73, 214, 0.12); border-color: var(--brand-150); }
.fd-wizard-class-card.selected { border-color: var(--brand-500); background: var(--brand-50); box-shadow: 0 8px 22px rgba(88, 73, 214, 0.15); }
.fd-wizard-class-card-icon {
    width: 46px; height: 46px; border-radius: 50%; margin: 0 auto 8px auto;
    background: linear-gradient(135deg, #6C63FF, #5849D6); color: #fff;
    display: flex; align-items: center; justify-content: center; font-size: 18px;
}
.fd-wizard-class-card-name {
    font-size: 12px; font-weight: 700; color: var(--text);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (max-width: 480px) {
    .fd-wizard-class-card { width: 100px; padding: 12px 4px; }
    .fd-wizard-class-card-icon { width: 38px; height: 38px; font-size: 15px; }
    .fd-wizard-class-card-name { font-size: 11px; }
}
@media (max-width: 420px) {
    .fd-tool-tab-card { width: 92px; padding: 10px 2px; }
    .fd-tool-tab-icon { width: 34px; height: 34px; font-size: 14px; }
    .fd-tool-tab-name { font-size: 9.5px; }
}
.fd-tool-panel { animation: wizardSlideIn 0.28s cubic-bezier(0.32, 0.72, 0, 1); }

/* Attendance redesign - period summary charts (self-hosted inline SVG, no
   charting library exists anywhere in this codebase - see README) and the
   two big colorful square "Take attendance" / "Search previous attendance"
   tiles. */
.fd-att-summary {
    display: grid;
    grid-template-columns: 1fr 1.4fr;
    gap: 24px;
    align-items: center;
    margin-bottom: 8px;
}
.fd-att-pie-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.fd-att-pie-legend { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; font-size: 12px; }
.fd-att-pie-legend span { display: inline-flex; align-items: center; gap: 5px; color: var(--text-muted); }
.fd-att-pie-legend i { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.fd-att-bar-chart { display: flex; align-items: flex-end; gap: 8px; height: 140px; padding-top: 10px; }
.fd-att-bar-col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 4px; }
.fd-att-bar-stack { width: 100%; max-width: 26px; display: flex; flex-direction: column-reverse; border-radius: 4px 4px 0 0; overflow: hidden; }
.fd-att-bar-label { font-size: 10px; color: var(--text-faint); white-space: nowrap; }
@media (max-width: 768px) { .fd-att-summary { grid-template-columns: 1fr; } }

.fd-att-tile-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin: 8px 0 24px 0; }
.fd-att-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    aspect-ratio: 1.4 / 1;
    border-radius: var(--r-lg);
    border: none;
    color: #fff;
    font-weight: 700;
    font-size: 15px;
    cursor: pointer;
    text-align: center;
    padding: 16px;
    transition: transform .2s ease, box-shadow .2s ease;
}
.fd-att-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); }
.fd-att-tile i { font-size: 30px; }
.fd-att-tile.tone-take { background: linear-gradient(135deg, #6C63FF, #5849D6); }
.fd-att-tile.tone-search { background: linear-gradient(135deg, #FF9F43, #E8590C); }
@media (max-width: 480px) { .fd-att-tile-grid { grid-template-columns: 1fr; } }

/* The take-attendance sheet's per-student Present/Absent toggle row -
   simplified from the full 5-status dropdown per the product ask
   ("present absent icon to be clicked"); the underlying mark_session
   handler still accepts any of the 5 statuses, so LATE/EXCUSED entries set
   from elsewhere are preserved and simply shown as their own badge here
   rather than offered as a third toggle choice. */
/* Sep 2026 follow-up, quoted directly: "when clicking take attendance...
   list of students and A(absent)/P(present)/N(unknown) radio toggles
   around each student's name, all in line in a row, all in a card... same
   design as the attendance list, with photo next to each name." A third
   "N" (unknown/not-yet-recorded - the existing NOT_RECORDED status) toggle
   joins Present/Absent, and each row gets a photo/initials avatar (see
   fdAttAvatarHtml(), class_tools.php) - the roster now reuses
   .fd-item-card-list as its card background (same "very light gray"
   backdrop the Online Class/Evaluation lists already use), each row still
   its own .fd-att-roster-row. */
.fd-att-roster-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 4px;
    border-bottom: 1px solid var(--line);
}
.fd-att-roster-row:last-child { border-bottom: none; }
.fd-att-roster-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--grad-brand, linear-gradient(135deg, var(--brand-500), var(--brand-600)));
    color: #fff;
    font-size: 12px;
    font-weight: 700;
}
.fd-att-roster-avatar img { width: 100%; height: 100%; object-fit: cover; }
.fd-att-roster-name {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fd-att-toggle-group { display: flex; gap: 6px; flex-shrink: 0; }
.fd-att-toggle-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--text-faint);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all .15s ease;
    font-size: 12px;
    font-weight: 800;
}
.fd-att-toggle-btn.present.active { background: var(--ok); border-color: var(--ok); color: #fff; }
.fd-att-toggle-btn.absent.active { background: var(--err); border-color: var(--err); color: #fff; }
.fd-att-toggle-btn.unknown.active { background: var(--text-muted); border-color: var(--text-muted); color: #fff; }
.fd-att-toggle-btn:hover { border-color: var(--brand-300); }

/* Sep 2026 follow-up: the in-popup previous/next-day nav strip that
   replaces the removed "Search Previous" tile/popup - see
   fdAttDayNavHtml(), class_tools.php. */
.fd-att-day-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-bottom: 14px;
}
.fd-att-day-nav .fd-att-day-btn { width: 34px; height: 34px; }
.fd-att-day-label { font-size: 13.5px; font-weight: 700; color: var(--text); display: inline-flex; align-items: center; gap: 8px; }

/* Sep 2026 follow-up: down to one tile (Take Attendance / Students) now
   that browsing other days / adding+inviting lives inside each popup - a
   single .fd-pick-tile in what used to be a 2-column grid would otherwise
   stretch full width and look oversized, so this caps it back to a
   normal tile's width. Reused by both the Attendance and Students tabs. */
.fd-att-actions-grid-single { grid-template-columns: minmax(0, 160px); }

/* Sep 2026 follow-up, quoted directly: "another button for 'Students'
   which opens a popup that lists all students with a button that slides
   to a new section where students can be added/invited via WhatsApp,
   link, phone, etc." Two full-width screens side by side inside an
   overflow-hidden track; fdStudentsSlideTo() (class_tools.php) toggles
   `.slid` to translate the track by exactly one screen-width. */
.fd-slide-track {
    display: flex;
    width: 200%;
    transition: transform .3s ease;
}
.fd-slide-track.slid { transform: translateX(-50%); }
.fd-slide-screen { width: 50%; flex-shrink: 0; min-width: 0; }
.fd-slide-screen:first-child { padding-right: 4px; }
.fd-slide-screen:last-child { padding-left: 4px; }

html[data-theme="dark"] .fd-tool-tile.tone-extra { background: var(--surface); }
html[data-theme="dark"] .fd-att-toggle-btn { background: var(--surface); }

.fd-alert { border-radius: var(--r-md); padding: 12px 18px; margin-bottom: 16px; font-size: 14px; }
.fd-alert.err { background: var(--err-bg); color: var(--err); }
.fd-alert.ok { background: var(--ok-bg); color: var(--ok); }
/* Sep 2026 fix: .fd-alert.warn was used across the app (get_started.php's
   own pending-join-request banner among ~9 call sites) but never actually
   defined - it rendered as unstyled plain text with no background/color,
   easy to miss entirely on a busy page. .fd-badge.warn already defines
   the same --warn/--warn-bg pairing; mirrored here for consistency. */
.fd-alert.warn { background: var(--warn-bg); color: var(--warn); }
/* 2026-09-26 (forty-third follow-up): the calm variant. The quiz screen uses
   it for an expected state - "you have used all your attempts", "not open
   yet" - which is information, not a failure, and was rendering unstyled
   because only err/ok/warn existed. Same pairing convention as the three
   above, on the brand tint rather than a status colour. */
.fd-alert.info { background: rgba(88, 73, 214, .09); color: var(--brand-700, #4C3FCC); }
html[data-theme="dark"] .fd-alert.info { background: rgba(124, 115, 255, .16); color: #CFC9FF; }

/* Login card - the one page with no left/right rails since there is no
   account/context to navigate yet. */
.fd-login-shell { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 24px; gap: 8px; }
.fd-login-card { width: 100%; max-width: 400px; }

/* ==========================================================================
   Auth entry-point switcher (Aug 2026, restyled to match the app's real
   "pill" nav design). Originally a boxed vertical list of white cards with
   a border - visually a different component from the floating gradient
   capsule (.vertical-tabs-wrapper/.vertical-tab in template-exact.css)
   used everywhere else once logged in. This now reuses that exact visual
   language (rounded-26px brand-gradient capsule, transparent tab buttons,
   white text, small underline-dash active indicator instead of a
   background chip) so the pre-login pages read as the same product -
   still its own component (not literally .vertical-tabs-wrapper) since
   this is a horizontal 2-tab switcher with labels beside the icons, not
   a full app nav rail. ========================== */
.fd-auth-tabs {
    display: flex;
    flex-direction: row;
    gap: 6px;
    width: fit-content;
    max-width: 100%;
    flex-shrink: 0;
    background: var(--brand-600);
    border-radius: 26px;
    padding: 6px;
    box-shadow: 0 14px 32px rgba(88, 73, 214, 0.35);
    margin-bottom: 20px;
}
.fd-auth-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 11px 22px;
    border-radius: 20px;
    color: rgba(255, 255, 255, 0.65);
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    background: transparent;
    border: none;
    position: relative;
    transition: background .2s ease, color .2s ease;
    white-space: nowrap;
}
.fd-auth-tab i { width: 16px; text-align: center; color: inherit; }
.fd-auth-tab:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
.fd-auth-tab.active { background: transparent; color: #fff; }
.fd-auth-tab.active i { color: #fff; }
.fd-auth-tab.active::after {
    content: '';
    position: absolute;
    bottom: 6px;
    left: 50%;
    transform: translateX(-50%);
    width: 18px;
    height: 3px;
    border-radius: 3px;
    background: #fff;
}
@media (max-width: 860px) {
    .fd-login-shell { padding: 16px; gap: 16px; }
    .fd-auth-tabs { width: 100%; max-width: 400px; }
    .fd-auth-tab { flex: 1 1 0; padding: 10px 12px; }
}

/* Sign-up wizard step 1 (Aug 2026) - account-type picker cards, and the
   freelance-vs-institution radio pair on the teacher step. */
.fd-role-pick {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border-radius: var(--r-md, 12px);
    border: 1px solid var(--border, rgba(0,0,0,0.08));
    background: var(--surface);
    color: var(--text-1, #333);
    text-decoration: none;
    transition: border-color .15s ease, background .15s ease;
}
.fd-role-pick i { font-size: 22px; color: var(--brand-600); width: 28px; text-align: center; flex-shrink: 0; }
.fd-role-pick:hover { border-color: var(--brand-600); background: var(--brand-50, rgba(88,73,214,0.06)); color: var(--text-1, #333); }
.fd-radio-pick { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 500; cursor: pointer; }
.fd-radio-pick input { accent-color: var(--brand-600); }

/* ==========================================================================
   Mobile top bar (Aug 2026 correction): reverted back to template_file.php's
   OWN default arc — the light lavender/blur tint defined in
   template-exact.css's .mobile-top-nav::before — after user feedback that
   an earlier pass here had swapped it for an opaque brand-color gradient.
   That override is gone; only the layout fixes below (which the template
   never needed, since its own header only ever shows a short admission-step
   title, not a full institution name) remain.
   ========================================================================== */
@media (max-width: 768px) {
    /* .logo-text already has min-width:0 in template-exact.css, but its
       parent .logo-section doesn't — a flex item's default min-width is
       "auto" (its content size), so without this a long institution name/
       abbreviation could refuse to shrink and push the right-side controls
       off the edge of the screen instead of eliding with "...". */
    .mobile-top-nav .logo-section { min-width: 0; flex: 1 1 auto; overflow: hidden; }
    .mobile-top-nav .nav-icons { flex-shrink: 0; gap: 10px; }

    /* Bottom dock cap (Aug 2026 correction): a page with 8-10 nav items
       was cramming every one of them into the mobile bottom dock — reads
       as visual clutter, and each icon shrinks to stay in one row. Only
       the first 4 (or, if the current page isn't among those 4, the first
       3 plus the current page — see header.php) render here; the rest are
       hidden and reachable via the "More" tab, which opens the same
       account sheet that already lists every nav item. */
    .vertical-tabs-wrapper .fd-mobile-extra { display: none !important; }
}
.fd-mobile-more-tab {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
}
@media (max-width: 768px) {
    .fd-mobile-more-tab { display: flex; }
}

/* Sep 2026 follow-up, quoted directly: "the curent experimental tab nav is
   great but we will prefer that all the items on that menu be added on the
   menu no need for a 'more' button instead let it scroll horizontally to
   reveal everything." Scoped to body[data-tab-shell] (header.php's
   $fdTabShellMode flag - the beta teacher tab-nav only) so the ordinary
   capped-dock-plus-More behavior above is completely unchanged for every
   other role/page, including a teacher who has opted back out via
   ?tabnav=0. Three things undo the cap for this mode specifically:
   1) un-hide every .fd-mobile-extra item (the ones the base rule above
      hides beyond the first 4), 2) switch each .vertical-tab from
      `flex: 1 1 0` (template-exact.css's mobile rule - shrinks every tab to
      fit however many are shown, which is what made a cap necessary in the
      first place) to a fixed `flex: 0 0 auto` width so tabs stay a
      consistent, readable size no matter the class count, and 3) let the
      wrapper actually scroll horizontally instead of the base rule's
      `overflow-x: visible` (which only ever crams everything into one
      squeezed row, never scrolls). The "More" tab itself is hidden in this
      mode - #fdMobileSheet's own class list/menu is still reachable via the
      corner profile button, so nothing becomes unreachable. */
@media (max-width: 768px) {
    body.fd-dock-scroll .vertical-tabs-wrapper .fd-mobile-extra {
        display: flex !important;
    }
    /* Sep 2026 follow-up, quoted directly (first pass): "lets get just 5
       items on the bottom nav bar before the scroll inorder to make it less
       crowded." Then, quoted directly (this pass, correcting that first
       one): "there is a little problem with the bottom nav it should always
       be full width and lets put just 4 items on it before the scrolling."
       The first pass capped the count by giving the dock a fixed
       device-independent WIDTH (max-width: 350px, no longer stretching to
       both edges) - which reliably showed 5, but at the cost of the dock no
       longer spanning the screen edge-to-edge like the base rule/every
       other page's dock does, which is exactly what this pass flagged as
       "a little problem." Fixed by keeping the base rule's own edge-to-edge
       `left: 14px; right: 14px;` anchoring completely untouched (removed
       the max-width/left:50%/transform overrides entirely - back to full
       width) and instead sizing each TAB as a share of the wrapper's own
       width - `flex-basis: calc((100% - 12px) / 4)` (12px = 3 inter-tab
       gaps at the base rule's own `gap: 4px`, between 4 items) - so, on any
       device, exactly 4 tabs' worth of width fills the full-width dock
       exactly, and a 5th+ tab (same calculated width, not a shrinking
       fraction) overflows into the horizontal scroll instead of being
       squeezed to fit. This is device-independent in the way that matters
       (always exactly 4 before scroll) while ALSO being full width on every
       device (the thing the fixed-pixel-width approach gave up). */
    body.fd-dock-scroll .vertical-tabs-wrapper {
        overflow-x: auto;
        overflow-y: hidden;
        justify-content: flex-start;
        -webkit-overflow-scrolling: touch;
    }
    body.fd-dock-scroll .vertical-tabs-wrapper .vertical-tab {
        /* 2026-09-19: grow 1 so a page with fewer than 4 items still fills
           the full-width dock (no dead space where "More" used to sit);
           with 5+ items there is no free space to grow into, so each keeps
           its quarter width and the row scrolls exactly as before. */
        flex: 1 0 calc((100% - 12px) / 4);
        width: auto;
    }
    body.fd-dock-scroll .fd-mobile-more-tab {
        display: none !important;
    }
}

/* Actual school logo image in the mobile top-nav (falls back to the
   graduation-cap glyph when the institution hasn't uploaded one). Sized to
   match the template's own .logo-section img rule but circular, since a
   school logo is usually a badge/crest rather than the wide wordmark the
   template's own img rule (object-fit:contain, no radius) was written for. */
.mobile-top-nav .logo-section .fd-logo-img {
    height: 34px;
    width: 34px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--brand-25);
    flex-shrink: 0;
}
.mobile-top-nav .logo-section .fd-logo-fallback {
    height: 34px;
    width: 34px;
    border-radius: 50%;
    background: var(--brand-600);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    flex-shrink: 0;
}

/* "4 separated squares" app-launcher icon that opens the account bottom
   sheet — sits alongside the avatar rather than replacing it, so a signed-
   in user always sees both who they are (avatar) and where to find
   everything else (grid). Built as 4 explicit spans rather than an icon
   font glyph so its corner radius/gap match the rest of the UI exactly. */
.fd-mobile-grid-btn {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: none;
    background: var(--brand-50);
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
    gap: 3px;
    padding: 10px;
    cursor: pointer;
    flex-shrink: 0;
    transition: all 0.2s ease;
}
.fd-mobile-grid-btn span {
    background: var(--brand-600);
    border-radius: 2px;
}
.fd-mobile-grid-btn:active { transform: scale(0.92); background: var(--brand-100); }
html[data-theme="dark"] .fd-mobile-grid-btn { background: var(--brand-100); }

/* Sep 2026 follow-up: "there should be only the menu and it should have no
   background" (mobile top nav, now that the avatar button beside it is
   gone - see header.php) - a plain icon, not a filled circle button. Only
   overrides background/border; the grid layout/spacing/dot color above is
   untouched so the icon itself still looks identical, just without its
   filled backdrop. */
.fd-mobile-grid-btn-bare { background: transparent !important; }
.fd-mobile-grid-btn-bare:active { background: transparent !important; }
html[data-theme="dark"] .fd-mobile-grid-btn-bare { background: transparent !important; }

/* Contextual admission-flow progress pill — a compact linear readout for
   the mobile top-nav (the template's own segmented .nav-progress-ring is
   part of the admission-wizard's own inline markup/JS; this is a simpler,
   reusable version for "which step is this account in" elsewhere). */
.fd-mobile-progress {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 84px;
}
.fd-mobile-progress-track {
    flex: 1 1 auto;
    height: 6px;
    border-radius: 3px;
    background: var(--brand-100);
    overflow: hidden;
}
.fd-mobile-progress-fill {
    height: 100%;
    border-radius: 3px;
    background: var(--brand-600);
    transition: width 0.3s ease;
}
.fd-mobile-progress-label {
    font-size: 10.5px;
    font-weight: 700;
    color: var(--brand-600);
    white-space: nowrap;
}

/* ==========================================================================
   Bottom sheet height cap (Aug 2026 correction, Sep 2026 follow-up). template-
   exact.css's own .bottom-sheet has no max-height — fine for the admission
   wizard's short, fixed action list, but this app's account menu (profile +
   every nav item + notifications + dark mode + logout + cancel) is longer
   and was opening almost edge-to-edge. Capped with internal scroll so the
   handle/profile stay reachable and the sheet never covers the whole screen
   the way a full-screen takeover would.
   Sep 2026 follow-up, quoted directly: "increase the height of the pop up
   to [90] percent" (90 picked directly out of a 85/90/100 clarifying
   question) - raised from 75vh to 90vh here, and matched below by every
   other sheet-height rule in this file that used to read 75vh/80vh (the
   fd-sheet-scroll inner cap just below, and .bottom-sheet.fd-wizard-sheet's
   own fixed height further down) so every popup on the platform - the
   account/tools menu, Profile & Settings, Wallet, the new Class-info sheet,
   the Create Class wizard - opens to the same, now-taller height.
   ========================================================================== */
.bottom-sheet {
    max-height: 90vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* Avatar button that replaces the plain hamburger top-right on mobile —
   shows the signed-in account's initials and opens the account menu
   (the template's own .bottom-sheet component, see header.php). */
.fd-mobile-avatar-btn {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.85);
    background: var(--brand-100);
    color: var(--brand-700);
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
    font-size: 14px;
    cursor: pointer;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
}
.fd-mobile-avatar-btn:active { transform: scale(0.92); }

/* Sep 2026: a "pop up out of the top bar" avatar badge + always-visible
   dark-mode toggle briefly lived here (position:relative;top:-12px on
   .fd-mobile-avatar-btn, plus a .fd-mobile-dark-toggle button) - reverted.
   That placement was a misread of the original ask; the person clarified
   directly ("the user photo I said should show on the pop up when the
   user opens the menu pop up on mobile"), so both moved to the account
   bottom-sheet's own top-right corner instead - see .fd-sheet-corner /
   .fd-sheet-dark-toggle below, and header.php's bottom-sheet markup.
   .fd-mobile-avatar-btn is back to its original flush-in-the-bar look
   (the plain rule two rules up, untouched by this revert).

   ==========================================================================
   Sep 2026 (corrected placement): the account-sheet corner badge - photo/
   initials + dark-mode toggle overflowing slightly above the popup's own
   top edge, same "badge escaping its container" visual idea as the
   top-bar version above, just anchored to this panel instead. Confirmed
   .bottom-sheet itself carries no `overflow` in template-exact.css, but
   THIS app's own "Bottom sheet height cap" rule just above does
   (`overflow-y: auto`) - which would clip anything positioned to overflow
   past the sheet's top edge. Solved by moving that scroll/height-cap onto
   a new inner wrapper, .fd-sheet-scroll, scoped to #fdMobileSheet only -
   the shared .bottom-sheet rule above (still used by login.php's own
   sheet) and the onboarding wizard's .fd-wizard-sheet variant (which
   already manages its own scrolling via .sheet-viewport, unaffected by
   this) are both left exactly as they were.
   ========================================================================== */
#fdMobileSheet { overflow: visible; }
#fdMobileSheet .fd-sheet-scroll {
    /* ~62px less than the sheet's own 90vh cap above - roughly the space
       the handle + corner badge row now takes outside this wrapper, so
       the sheet's total on-screen height stays about the same as before. */
    max-height: calc(90vh - 62px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    /* Sep 2026 follow-up, quoted directly: "the user photo is sitting too
       close to the other icons below it. add mb-5 or pt-5 especially the
       desktop." The corner avatar (.fd-sheet-corner, just below) sits
       position:absolute/top:-22px, entirely out of flow - so with no
       clearance here, .fd-menu-grid (the first thing actually IN this
       flow) started right at this wrapper's own top edge, directly under
       the overflowing badge. A flat top padding (~pt-3) covers mobile;
       the wider ~pt-5 gap asked for "especially on desktop" is added by
       the >=769px rule further down, where the sheet is a centered dialog
       with more room to spare. */
    padding-top: 14px;
}
@media (min-width: 769px) {
    #fdMobileSheet .fd-sheet-scroll { padding-top: 48px; }
}

.fd-sheet-corner {
    position: absolute;
    top: -22px;
    right: 20px;
    z-index: 2;
    display: flex;
    align-items: flex-end;
    gap: 10px;
}
/* .menu-profile is template-exact.css's full-width tinted bar (icon +
   name/sub text) - this corner badge only needs the circle, so its own
   chrome is stripped down to a bare positioning box. */
.fd-sheet-corner .menu-profile.fd-sheet-avatar {
    display: block;
    background: transparent;
    padding: 0;
    margin: 0;
    border-radius: 50%;
}
.fd-sheet-corner .menu-avatar {
    width: 52px;
    height: 52px;
    border: 3px solid var(--surface);
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
}
.fd-sheet-avatar-initials { color: #fff; font-weight: 700; font-size: 16px; }
html[data-theme="dark"] .fd-sheet-corner .menu-avatar { box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45); }

/* Same 38px-circle / surface-background / soft-shadow / fa-moon treatment
   the reverted top-bar toggle used, styled like the desktop
   .rail-dark-toggle so the control reads as the same thing everywhere.
   Calls the SAME global toggleDarkMode() already defined once in
   footer.php - nothing duplicated here. */
.fd-sheet-dark-toggle {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: none;
    background: var(--surface);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    cursor: pointer;
    flex-shrink: 0;
    transition: all 0.2s ease;
}
.fd-sheet-dark-toggle i { font-size: 15px; }
.fd-sheet-dark-toggle:active { transform: scale(0.92); }
html[data-theme="dark"] .fd-sheet-dark-toggle { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); }

/* template-exact.css only defines .sheet-action-icon.help/.support (the
   two actions its own admission-wizard sheet needs) — this app's account
   menu also needs a "profile/section link" tint, built the same way. */
.sheet-action-icon.profile { background: var(--brand-600); }

/* ==========================================================================
   Skeleton loading (Aug 2026 UI request): "since we are building a PWA it
   should feel like a real native app — no page loading, use skeleton
   loading rather than a blank page". This is server-rendered PHP, not an
   SPA, so there's no client-side moment where content is "still loading"
   on the SAME page — the two real gaps are (1) the brief blank-white flash
   between clicking a link and the next full page arriving, and (2) any
   block that fetches its own data after first paint. #1 is covered by the
   top progress bar in footer.php; .fd-skeleton below is the reusable
   placeholder for #2, and is also available to any page that wants an
   explicit loading state instead of a spinner. ========================== */
.fd-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--brand-50);
    border-radius: var(--r-md, 12px);
}
.fd-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent);
    animation: fdSkeletonShimmer 1.4s ease-in-out infinite;
}
html[data-theme="dark"] .fd-skeleton { background: var(--brand-25); }
html[data-theme="dark"] .fd-skeleton::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.08), transparent); }
@keyframes fdSkeletonShimmer { 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
    .fd-skeleton::after { animation: none; }
}
.fd-skeleton-text { height: 12px; margin-bottom: 8px; width: 100%; }
.fd-skeleton-text.short { width: 55%; }
.fd-skeleton-line { height: 14px; margin-bottom: 10px; }
.fd-skeleton-title { height: 20px; width: 45%; margin-bottom: 14px; }
.fd-skeleton-avatar { height: 44px; width: 44px; border-radius: 50%; }
.fd-skeleton-card { height: 90px; border-radius: var(--r-md, 12px); }
.fd-skeleton-row { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; }

/* Sep 2026: #fdTopLoadBar (the slim top-of-page loading bar) removed
   outright, per "remove the loading line on the top of the page when
   clicking a link... on the entire app" - its markup (header.php) and
   control JS (footer.php) are gone too. */

/* ==========================================================================
   Subtle section tinting (Aug 2026 UI request: "some pages are just too
   white especially on mobile — add a subtle background like the parental
   information section"). That section is template-exact.css's own
   .field-group: var(--brand-25) fill, var(--brand-150) border, rounded
   corners. `.fd-section.tinted` reuses those exact tokens on this app's
   own .fd-section blocks, opt-in per section so the effect stays "subtle
   accent here and there", not applied wholesale over every panel. */
.fd-section.tinted {
    background: var(--brand-25);
    border: 1px solid var(--brand-150);
    border-radius: 16px;
    padding: 16px 16px 4px 16px;
}
.fd-section.tinted h3 { margin-top: 0; }

/* ===== BARE PAGES (login/register/institution sign-up) =====
   template-exact.css's own `body { padding: 20px 80px !important }`
   (and the mobile `70px 0 80px 0` variant) reserve space for the shared
   header/footer's own mobile-top-nav + bottom dock - correct for every
   page that includes header.php/footer.php, wrong for a bare
   pre-login page with no nav at all. Without this override, that
   padding pushed .fd-login-shell's own 100vh box past the actual
   viewport height, producing a vertical scrollbar with nothing real to
   scroll to, on both desktop and mobile. */
body.fd-bare-page {
    padding: 0 !important;
}
/* Aug 2026 auth/onboarding rebuild: login.php/onboarding_student.php/
   onboarding_tutor.php reuse `fd-bare-page` (for the dark-mode link
   color + background tweaks above) but, unlike the plain centered-card
   pages that rule was written for, DO use the shared mobile-top-nav
   (fixed, 66px tall) and vertical-tabs-wrapper bottom dock - so they
   need the padding the rule above just zeroed out, or the fixed nav
   bar overlaps the page heading and the fixed bottom bar overlaps
   whatever content is last on the page. Marked with a second class,
   `fd-app-shell-page`, so this only ever applies to a bare page that
   opted into the nav shell - two classes beats the single-class rule
   above regardless of source order. Confirmed by direct measurement
   (Playwright, mobile viewport) that body padding was computed as 0px
   before this fix - this is what "heading cut off" / "fixed button
   sits on top of the content" actually were. */
body.fd-bare-page.fd-app-shell-page {
    padding: 20px 80px !important;
}
@media (max-width: 992px) {
    body.fd-bare-page.fd-app-shell-page { padding: 20px 70px !important; }
}
@media (max-width: 768px) {
    body.fd-bare-page.fd-app-shell-page {
        padding-top: calc(76px + env(safe-area-inset-top, 0px)) !important;
        /* The fixed Save/Continue bar itself sits `calc(78px + 16px +
           safe-area)` up from the viewport bottom (nav-action-bar's own
           rule) AND is itself ~80px tall - so clearing it needs that
           whole stack (~174px), not just the offset. Confirmed by
           screenshot: 96px looked right on paper but the button visibly
           covered the radio option below it in practice. */
        padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)) !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
}

/* Onboarding wizard pages only: the bottom tab dock (Academics/Profile)
   competes for the same thumb-reach space as each step's own fixed
   Save/Continue bar - hidden on mobile so only one fixed bottom bar is
   ever competing for that space at a time. */
@media (max-width: 768px) {
    .fd-onboarding-page .vertical-tabs-wrapper { display: none; }
}
/* Aug 2026 dark-mode contrast fix: these bare pages' plain sign-up/log-in
   links ("New here? Create an account", "Already have an account? Log
   in", etc.) never had an explicit color, so they fell back to
   Bootstrap's un-themed default link blue (#0d6efd) - borderline-legible
   on the dark-mode background and not on-brand either. Give them the same
   brand color already used for tabs/nav links elsewhere, which resolves
   to a light lavender in dark mode with plenty of contrast against the
   dark background (see template-exact.css's --brand-600 redefinition
   under [data-theme="dark"]). */
/* Sep 2026 follow-up: scoped to :not(.btn) - found while building
   signup_institution.php's confirmation screen (an <a class="btn
   btn-primary">, the same pattern reset_password.php's own "Go to log
   in"/"Request a new link" buttons use). This rule's specificity
   (0,1,2 - a class plus two elements) beats template-exact.css's own
   `.btn-primary { color: white; }` (0,1,0), so any CTA button on a bare
   page that happens to be an <a> instead of a <button> silently got
   brand-purple text on its own purple background - readable nowhere,
   not just a contrast nit. Plain <button class="btn-primary"> elements
   were never affected (this selector only ever matched <a> tags), which
   is exactly why the bug went unnoticed elsewhere. */
body.fd-bare-page a:not(.btn) { color: var(--brand-600); font-weight: 600; }
body.fd-bare-page a:not(.btn):hover { text-decoration: underline; }
@media (max-width: 768px) {
    /* On mobile specifically, plain (non-card) stat/table sections read as
       "all white" against the page background — nudge the page background
       itself very slightly off pure white so cards/sections keep contrast
       without needing every single one tinted. Uses the same --bg tint the
       desktop body already carries (Aug 2026 "too whitish" pass), rather
       than the paler --brand-15, so mobile and desktop read at the same
       depth instead of mobile looking washed out by comparison. */
    body { background: var(--bg); }
    html[data-theme="dark"] body { background: var(--bg); }
}

/* ==========================================================================
   Sync conflict review (completeness pass C7 - offline Category B action
   types, 3.29.23). offline-sync.js renders cards into #fdSyncConflicts
   when a queued offline action comes back CONFLICT instead of SUCCESS -
   fixed near the top of the viewport so it's visible on whichever page
   the person happens to be on when reconnecting, since the conflict was
   never a server-side record to begin with (the write was refused), only
   ever a browser-local one. */
#fdSyncConflicts {
    position: fixed;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2001;
    width: min(92vw, 480px);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.fd-sync-conflict-card {
    background: var(--surface, #fff);
    border: 1px solid #e5533d;
    border-left: 4px solid #e5533d;
    border-radius: 12px;
    padding: 12px 14px;
    box-shadow: 0 6px 18px rgba(0,0,0,0.14);
    font-size: 13px;
}
html[data-theme="dark"] .fd-sync-conflict-card { background: var(--surface-alt, #201d3a); }
.fd-sync-conflict-card .fd-sync-conflict-title { font-weight: 600; margin-bottom: 4px; }
.fd-sync-conflict-card .fd-sync-conflict-actions { margin-top: 8px; display: flex; gap: 8px; }
.fd-sync-conflict-card button {
    border: none;
    background: var(--brand-500);
    color: #fff;
    border-radius: 8px;
    padding: 4px 10px;
    font-size: 12px;
    cursor: pointer;
}
.fd-sync-conflict-card button.fd-sync-conflict-discard {
    background: transparent;
    color: inherit;
    border: 1px solid var(--brand-150);
}

/* =====================================================================
   Auth pages + onboarding wizard rebuild (Aug 2026 follow-up)
   Ported verbatim from the user-supplied template mockups
   (authentication1.html, student_creation_step_26.html,
   tutor_creation_step_26.html) — same tokens/radii/shadows already
   defined in template-exact.css, just the component shapes those three
   pages introduced that the rest of the app didn't need yet.
   ===================================================================== */

/* ---- Sheet loading state (spinner shown while a step's data is being
   fetched, so a wizard transition never looks frozen) ---- */
.fd-sheet-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 48px 20px; color: var(--text-muted); }
.fd-sheet-loading i { font-size: 30px; color: var(--brand-600); }
.fd-sheet-loading span { font-size: 13px; font-weight: 600; }
/* Sep 2026: "the spinner color should be same as the icon color on the
   entire app" - .fd-icon-spin is the rotating fa-circle-notch/fa-spinner
   used for every inline loading state (wizard step loads, search-results
   "Searching…", demo-data seeding). It previously set no color of its
   own, so it just inherited whatever text color its container happened
   to have (var(--brand-600) inside .fd-sheet-loading, but var(--text-
   muted) inside .search-results .result-empty) - two different spinner
   colors in the same app. var(--brand-600) here is the same color used
   for icons app-wide (.fd-toast-icon, .fd-sheet-loading i, fd_chip_tone()
   slot 0's border), so this makes every spinner match by default; a
   container that still wants a different spinner color can override it
   the same way .fd-sheet-loading i already does (a more specific
   selector wins over this class-level default). */
.fd-icon-spin { animation: fdSpin 0.8s linear infinite; color: var(--brand-600); }
@keyframes fdSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* ---- Mobile background should be plain white on these bare pages ----
   body's shared background is the tinted `--bg` (#E6E8F5), which barely
   shows on desktop (the centered white form-container covers almost the
   whole viewport) but is clearly visible on mobile, where body has no
   left/right padding and the tint shows as a visible strip behind the
   fixed top nav and bottom tab dock. */
@media (max-width: 768px) {
    .fd-bare-page { background: #ffffff; }
}

.fd-bare-page .main-wrapper { max-width: 900px; }

/* ---- Onboarding wizard sheet: 80% viewport height, fixed footer,
   sticky search bar, single-column scrollable list (Aug 2026 follow-up
   round of fixes) ---- */
.fd-onboarding-page .bottom-sheet.fd-wizard-sheet {
    height: auto;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    padding-bottom: 0;
}
.fd-onboarding-page .bottom-sheet.fd-wizard-sheet .sheet-header,
.fd-onboarding-page .bottom-sheet.fd-wizard-sheet .sheet-handle {
    flex-shrink: 0;
}
.fd-onboarding-page .bottom-sheet.fd-wizard-sheet .sheet-viewport {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-right: 2px;
    /* BUG FIX (Sep 2026): no bottom padding at all here meant that
       whenever a sheet's footer is hidden (setSheetFooter({showBack:
       false, showSave:false}) - the faculty/category list steps, and the
       quick-action menu), the last row sat flush against the sheet's own
       bottom edge with zero breathing room. #sheetFooter already reserves
       its own space when visible, so this only shows up on the
       footerless views - which is exactly the "no gap at the bottom"
       report. */
    padding-bottom: 14px;
}
.fd-sheet-search-wrap {
    flex-shrink: 0;
    padding-bottom: 10px;
}
.fd-sheet-search-wrap .form-control { height: 44px !important; }
.fd-sheet-footer {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 0 calc(12px + env(safe-area-inset-bottom, 0px)) 0;
    border-top: 1px solid var(--line);
    background: var(--surface, #fff);
}
.fd-sheet-footer-back {
    width: 48px;
    height: 48px;
    flex: 0 0 48px;
    border-radius: 50%;
    border: 1.5px solid var(--line);
    background: transparent;
    color: var(--text);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 15px;
    transition: all 0.2s ease;
}
/* Sep 2026: "the back arrow can we make it red?" - .fd-sheet-footer-back
   is the wizard's own back/close button (a plain X on step 1, a back
   arrow on later steps - both share this class, see fdSheetFooter()'s
   own comment in class_tools.php), so this recolors both to var(--err)
   rather than adding a separate arrow-only class. */
.fd-sheet-footer-back { border-color: var(--err); color: var(--err); }
.fd-sheet-footer-back:hover { background: rgba(201, 42, 42, 0.08); border-color: var(--err); color: var(--err); }
/* Sep 2026, FOURTH nav-rework pass: "the next button on the pop up should
   be on the right end" - was `margin: 0 auto`, which centers the button
   in the footer row (the back button's fixed 48px width means centering
   the remaining space is NOT the same as flush-right). `margin-left:auto`
   absorbs only the leftover space on the left, pushing this button flush
   against the footer's right edge instead - back stays put on the left
   (fdSheetFooter()'s own function comment, class_tools.php). */
.fd-sheet-footer-save {
    flex: 0 1 auto; min-width: 220px; margin-left: auto;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.fd-sheet-footer-save i { font-size: 14px; line-height: 1; }

/* Small extra safety margin for icon-in-input positioning inside narrow
   nested fields (repeat-row's half-width columns) - not a confirmed
   overflow, but cheap defensive polish. */
.fd-onboarding-page .input-icon-wrap .input-icon { left: 18px; }
.fd-onboarding-page .form-control.has-icon { padding-left: 46px !important; }

/* ---- Robust two/four-field row layout (Aug 2026 follow-up) ----
   Bootstrap's .row/.col-sm-* combo computes column widths as fixed
   percentages of the row's own width, with gutter applied via padding
   on each column. That's fragile the moment you want the row's OUTER
   edges to align exactly with a full-width field above it: zeroing the
   gutter (g-0) removes the misalignment but also removes the visual
   gap between the two side-by-side fields, and adding a manual gap back
   without accounting for it in the percentage math makes the row
   overflow its container. CSS Grid with fr units sidesteps all of this -
   it always subtracts an explicit `gap` from the available width before
   dividing by the fr proportions, so the outer edges land exactly where
   a plain full-width sibling's edges do, with a clean gap between the
   two fields and no per-column padding fighting to be zeroed. */
.fd-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.fd-row-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.fd-row-2-wide-narrow { display: grid; grid-template-columns: 1.4fr 1fr; gap: 10px; }
.fd-row-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
@media (max-width: 575.98px) {
    .fd-row-2, .fd-row-3, .fd-row-2-wide-narrow, .fd-row-4 { grid-template-columns: 1fr; }
}
@media (min-width: 576px) and (max-width: 767.98px) {
    .fd-row-4 { grid-template-columns: repeat(2, 1fr); }
}
.fd-row-2 > *, .fd-row-3 > *, .fd-row-2-wide-narrow > *, .fd-row-4 > * {
    width: 100% !important; max-width: 100% !important; padding-left: 0 !important; padding-right: 0 !important; margin-bottom: 0 !important;
}

/* ---- Textarea auto-grow (Aug 2026 follow-up) ----
   .form-control's own `height: 50px !important` (template-exact.css)
   applies to every form-control including textareas, and a plain
   inline style="height:auto" cannot override an !important external
   rule - this is why the bio textarea never visibly grew no matter how
   much was typed. auto-resize.js does the actual growing (recalculating
   height from scrollHeight on input); this override just lets that
   height take effect instead of being clamped back to 50px. */
textarea.form-control {
    height: auto !important;
    min-height: 100px;
    overflow-y: hidden;
}

/* ---- Desktop: let the sheet actually use the available width instead
   of staying narrow with a tall, heavily-scrolled single column ---- */
@media (min-width: 992px) {
    .fd-onboarding-page .bottom-sheet.fd-wizard-sheet { max-width: 760px; }
    .fd-onboarding-page .sheet-action-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
    /* BUG FIX (Sep 2026): this `margin-bottom: 0` was living OUTSIDE this
       media query, so it zeroed every .sheet-action's normal 10px
       margin-bottom (template-exact.css) at EVERY width, not just here on
       desktop where CSS grid's own `gap: 8px` above takes over spacing
       duty instead. .sheet-action-grid is used on mobile for two real
       things - the higher-ed faculty/department list, and the 4-item
       quick-action menu (Add/Save/Theme/Logout) - and on mobile it stays
       a plain single-column block (the `display:grid` above only applies
       at >=992px), so with no grid gap AND no margin, every row was
       rendering flush against the next one with zero space between them,
       looking "joined". Moved inside this block so mobile gets its normal
       margin-bottom spacing back, matching every other stacked list of
       .sheet-action rows in the app - confirmed via a real 390px
       screenshot before and after. */
    .sheet-action-grid .sheet-action { margin-bottom: 0; }
}

/* ---- Breadcrumb inline with the sheet title, instead of taking a
   whole line inside the scrolling content - so what's already been
   picked (e.g. "Faculty of Science") stays visible the whole time a
   step is on screen, not just briefly while scrolled into view. ---- */
.sheet-crumb-inline {
    display: inline-block; font-size: 11px; font-weight: 700; color: var(--brand-600);
    background: var(--brand-50); border-radius: 999px; padding: 2px 10px; margin-top: 3px;
}

/* ---- Alternate design: 3-per-row subject/course card grid (Aug 2026
   "give me another version" request) - only used by onboarding_
   student_grid.php / onboarding_tutor_grid.php, side-by-side design
   comparison against the default full-width stacked list. ---- */
.subject-grid-3col { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 900px) { .subject-grid-3col { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 575.98px) { .subject-grid-3col { grid-template-columns: 1fr; } }
.subject-card-grid {
    position: relative; background: var(--brand-20); border-radius: 18px; padding: 16px 14px;
    text-align: center; transition: all 0.25s ease; min-height: 150px;
    display: flex; flex-direction: column; align-items: center;
}
.subject-card-grid:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(88, 73, 214, 0.1); }
.subject-avatar-grid {
    width: 40px; height: 40px; border-radius: 12px; color: #fff; display: flex; align-items: center;
    justify-content: center; font-size: 16px; margin-bottom: 8px;
}
.subject-name-grid { font-weight: 700; font-size: 13.5px; color: var(--text); line-height: 1.3; }
.subject-meta-grid { font-size: 11px; color: var(--text-muted); margin-top: 4px; line-height: 1.4; }
/* BUG FIX (Sep 2026 verification pass): the tag-pill styling below
   (background/padding/border-radius/gap) was only ever scoped to
   `.subject-card .class-tag[-row]` (see the default stacked-list rules
   further down this file). The grid variant's cards use a different
   class, `.subject-card-grid`, which never matched that rule - so on
   onboarding_student_grid.php/onboarding_tutor_grid.php the subject tags
   rendered as plain unstyled inline text with no wrapping or spacing at
   all ("MathematicsEnglish LanguageScience" running together with zero
   separation), confirmed via a real headless-browser screenshot. Mirrors
   the same declarations `.subject-card .class-tag-row`/`.class-tag`
   already use correctly for the default list. */
.subject-card-grid .class-tag-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 5px; margin-top: 8px; }
.subject-card-grid .class-tag { font-size: 10.5px; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: var(--brand-100); color: var(--brand-600); }
.subject-card-grid.is-program .class-tag,
.subject-card-grid.is-course .class-tag { background: #EFE0F7; color: #7B3FA0; }
.subject-actions-mini {
    position: absolute; top: 8px; right: 8px; display: flex; gap: 4px; opacity: 0; transition: opacity 0.2s ease;
}
.subject-card-grid:hover .subject-actions-mini { opacity: 1; }
.subject-actions-mini button {
    width: 24px; height: 24px; border-radius: 50%; border: none; background: #fff; color: #5a6c7d;
    font-size: 10px; cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}
.subject-actions-mini button.delete:hover { background: #e74c3c; color: #fff; }

/* ---- Skeleton loading (Aug 2026 follow-up) ----
   Shown by default in place of the subject/course list until the page's
   own JS has actually built the real content, instead of an empty gap
   or a jarring pop-in once it appears. */
.fd-skeleton-list { display: flex; flex-direction: column; gap: 12px; }
.fd-skeleton-card {
    height: 76px; border-radius: 18px; background: var(--brand-20);
    background-image: linear-gradient(90deg, var(--brand-20) 0%, var(--brand-50) 50%, var(--brand-20) 100%);
    background-size: 200% 100%; animation: fdSkeletonShimmer 1.4s ease-in-out infinite;
}
@keyframes fdSkeletonShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ---- Frosted glass behind the fixed bottom Save/Continue + Back +
   Logout row (Aug 2026 follow-up) ---- */
@media (max-width: 768px) {
    .fd-onboarding-page .nav-action-bar {
        padding-top: 14px !important;
        /* Sep 2026 flush-to-bottom fix: template-exact.css's shared
           `.nav-action-bar` rule positions the whole bar (including this
           frosted background) at `bottom: calc(10px + env(safe-area-inset-
           bottom))` - correct spacing when the bar needs to float above
           the bottom tab dock (.vertical-tabs-wrapper), but on
           .fd-onboarding-page specifically that dock is already
           `display:none` on mobile (see the rule right above this one),
           so there was nothing left for the bar to float above - just a
           visible unblurred gap between the bottom of the frosted panel
           and the true bottom edge of the screen ("the blur ... floats
           above the screen edge instead of sitting flush", per the bug
           report). `!important` here to win over template-exact.css's
           own `bottom` (never edit that file - it's the shared
           byte-for-byte template extraction). The old 10px offset is
           absorbed into this padding-bottom instead (14px -> 24px) so the
           button itself keeps roughly the same visual distance from the
           true edge - only the frosted panel now touches bottom:0, not
           the button crammed against it. Net offset from the true
           viewport bottom to the top of the button's own content is
           unchanged (old: 10px bottom-offset + 14px padding = 24px; new:
           0px bottom-offset + 24px padding = 24px), so
           `body.fd-bare-page.fd-app-shell-page`'s mobile
           `padding-bottom` (reserved so this fixed bar never covers page
           content, tuned separately just above) needed no change -
           confirmed by Playwright measurement, see verify script. */
        bottom: 0 !important;
        padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)) !important;
        background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.72) 28%, rgba(255,255,255,0.92) 100%);
        -webkit-backdrop-filter: blur(14px);
        backdrop-filter: blur(14px);
    }
    html[data-theme="dark"] .fd-onboarding-page .nav-action-bar {
        background: linear-gradient(180deg, rgba(21,19,43,0) 0%, rgba(21,19,43,0.72) 28%, rgba(21,19,43,0.92) 100%);
    }
}

/* ---- Icon-only circular nav buttons (Back / Logout) ----
   Bootstrap's btn-outline-secondary is transparent by default, which on
   mobile (against the tinted/gradient background) made these icon-only
   buttons hard to see or looked "invisible". Solid opaque background
   instead, so they're always clearly visible regardless of what's
   behind them. */
.fd-icon-btn {
    width: 48px; height: 48px; flex: 0 0 48px; border-radius: 50%; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: #ffffff !important; border: 1.5px solid var(--line) !important; color: var(--text) !important;
}
.fd-icon-btn:hover { background: var(--brand-25) !important; border-color: var(--brand-200) !important; color: var(--brand-600) !important; }
html[data-theme="dark"] .fd-icon-btn { background: var(--surface) !important; }

/* ---- Sep 2026 follow-up: "remove the same buttons at the top of the pop
   up and put them at the bottm fixed" (Evaluation's submissions popup) ----
   fdcOpenSheet()'s 4th argument replaces #fdcSheetFooter's innerHTML
   wholesale (footer.php), and that element already carries the fixed,
   bottom-pinned .fd-sheet-footer base rule above (flex row, border-top,
   safe-area padding). This wrapper is what evActionsTpl{id} (class_tools.
   php) and its identical visible-card row both render into - a plain flex
   row of .fd-icon-btn circles that scrolls horizontally instead of
   wrapping/overflowing when a status has many actions at once (e.g. Edit +
   Copy link + Activate + Mark + Publish + Lock all at once on a freshly
   DRAFTed evaluation). flex:1 so it fills the footer the same way the
   single .fd-sheet-footer-save button used to. */
.fd-sheet-footer-actions {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 2px 2px;
}
.fd-sheet-footer-actions .fd-icon-btn,
.fd-sheet-footer-actions form { flex: 0 0 auto; }

/* ---- Sep 2026 follow-up: Mark button's ungraded-count corner badge ----
   The old text button read "Mark (N)"; icon-only needs the count to stay
   visible some other way, so it's pinned to the icon's corner instead -
   same small-circle-with-count idea as the header's own notification bell
   badge, just scoped to a single .fd-icon-btn instead of the top bar.
   .fd-icon-btn-badged only adds `position:relative` (so the badge's
   `absolute` below anchors to THIS button, not an ancestor) - every other
   .fd-icon-btn rule above still applies unchanged. */
.fd-icon-btn-badged { position: relative; overflow: visible; }
.fd-icon-btn-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--warn, #E8590C);
    color: #fff !important;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--surface, #fff);
}

/* ---- Mobile top-right "Add Subjects/Classes/Courses" shortcut ----
   Lets a mobile user jump straight into the add-subject sheet from
   anywhere on Step 2 without scrolling down to find the trigger card.
   Desktop already has plenty of room for the full trigger card, so this
   is mobile-only. */
.fd-mobile-add-shortcut {
    display: flex; align-items: center; gap: 6px; background: var(--brand-600); color: #fff;
    border: none; border-radius: 999px; padding: 7px 14px; font-size: 12.5px; font-weight: 700;
    white-space: nowrap; flex-shrink: 0;
}
.fd-mobile-add-shortcut:active { background: var(--brand-700); }
@media (min-width: 769px) { .fd-mobile-add-shortcut { display: none !important; } }

/* ---- Bare-page (login/signup/onboarding) template-fidelity overrides ----
   These three pages share classes (.sheet-action-icon, .field-group-icon,
   .btn-primary, .rail-dark-toggle, .vertical-icons-right a, .app-hero-
   avatar) with the rest of the already-built app via template-exact.css.
   template-exact.css's OWN versions of several of these were already
   flattened to solid colors / made circular-with-tooltip by an earlier
   session in this app's history, before this rebuild ever started - but
   the user's three template files want gradients and a pill-with-label
   rail (not a circle-with-tooltip one) for these same classes. Changing
   the shared template-exact.css rules would regress every other already-
   built page that also uses them (school-admin/teacher/student
   dashboards, etc.), so these overrides are scoped to `.fd-bare-page`
   only - the body class login.php/onboarding_student.php/onboarding_
   tutor.php use and nothing else does. */
.fd-bare-page .sheet-action-icon.help { background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.fd-bare-page .sheet-action-icon.support { background: linear-gradient(135deg, #00B894, #55EFC4); }
.fd-bare-page .field-group-icon { background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.fd-bare-page .btn-primary:hover { background: linear-gradient(135deg, var(--brand-550), var(--brand-700)); }
/* "Semi-circle" arc behind the mobile header - restored per follow-up
   (moving the glass onto just the header text instead wasn't liked),
   sized down from the shared template's original (bottom -34px / ±12%
   horizontal overflow / 34px corner radius) to a smaller, tighter arc,
   recolored gray/transparent instead of brand-lavender.
   Sep 2026: sized down again per explicit feedback that the gap between
   the header text/logo row and the curved bottom edge of the arc was
   still too large - bottom -26px / 28px corner radius shrunk further to
   -14px / 16px, keeping the same ±6% horizontal overflow (that controls
   how far the curve reaches sideways past the bar, not the vertical gap
   being asked about here). This is now the house style for the mobile
   header arc going forward.
   Sep 2026 (later): broadened from `.fd-bare-page`-only to the base
   `.mobile-top-nav` selector - reported live as "apply onboarding_
   tutor.php's look everywhere". Every page besides the 7 `.fd-bare-page`
   ones (login/onboarding x4/reset_password/index) shares the exact same
   `.mobile-top-nav` markup via header.php, so they were still rendering
   template-exact.css's own larger/brand-lavender arc untouched - this was
   the literal example given, not a hypothetical drift. Un-scoping this
   rule (rather than duplicating it under `.fd-bare-page .mobile-top-nav`
   too) makes it apply once, everywhere, with nothing left to keep in
   sync between two selectors going forward. */
/* 2026-09-18, quoted directly: "its remove that semi circle and make it
   straight". The arc described at length above is gone - this block used
   to set `border-radius: 0 0 50% 50% / 0 0 16px 16px` (the smaller,
   house-style version of template-exact.css's original dome). The header
   now ends on a straight edge. The horizontal overflow is dropped back to
   0 at the same time: it only ever existed so the curve could reach
   sideways past the bar, and with a straight edge it would just bleed the
   tint off both sides of the screen. */
.mobile-top-nav::before {
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 0;
    background: linear-gradient(160deg, rgba(120,122,130,0.14) 0%, rgba(150,152,158,0.09) 60%, rgba(255,255,255,0.05) 100%);
}
.mobile-top-nav.scrolled::before {
    background: linear-gradient(160deg, rgba(120,122,130,0.22) 0%, rgba(150,152,158,0.14) 60%, rgba(255,255,255,0.08) 100%);
    -webkit-backdrop-filter: saturate(120%) blur(24px);
    backdrop-filter: saturate(120%) blur(24px);
}
.fd-bare-page .app-hero-avatar-fallback { background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.fd-bare-page .app-hero-avatar,
.fd-bare-page .app-hero-avatar-fallback { width: 110px; height: 110px; }

/* Right icon rail: template wants a pill with a visible text label next
   to each icon (Help/Support/Theme); the shared rail is currently a bare
   44px circle that reveals its label only as a hover tooltip. */
.fd-bare-page .vertical-icons-right a,
.fd-bare-page .rail-dark-toggle {
    width: auto; min-width: 44px; border-radius: 50px;
    justify-content: flex-start; gap: 8px; padding: 0 14px; white-space: nowrap;
}
.fd-bare-page .vertical-icons-right a i,
.fd-bare-page .rail-dark-toggle i { font-size: 18px; }
.fd-bare-page .icon-label { font-size: 11px; font-weight: 500; color: #5a6c7d; letter-spacing: 0.2px; }
.fd-bare-page .vertical-icons-right a:hover .icon-label,
.fd-bare-page .rail-dark-toggle:hover .icon-label { color: var(--brand-600); }
.fd-bare-page .vertical-icons-right a:hover,
.fd-bare-page .rail-dark-toggle:hover { transform: scale(1.05) translateY(-2px); }

/* ---- Tab visibility (BUG FIX, Aug 2026 follow-up) ----
   template-exact.css defines `.tabcontent { display: none; }` (copied
   verbatim from template_file.php's admission wizard) but that page
   never actually uses the .active-class toggle pattern to reveal one -
   it has its own separate reveal mechanism. login.php/onboarding_
   student.php/onboarding_tutor.php DO use the classic add/remove
   `.active` pattern (matching the raw template mockups' own self-
   contained <style> block, which had this exact rule and was
   mistakenly not carried over here) - without this override every
   single tab is permanently hidden regardless of which one the server
   marks active. This was reported live: page shell rendered, form area
   was empty on every tab. */
.tabcontent.active { display: block; }

/* ---- Auth link + centered field column (login/signup/forgot forms) ---- */
.auth-link { color: var(--brand-600); text-decoration: none; font-weight: 600; transition: color 0.2s ease; }
.auth-link:hover { color: var(--brand-700); text-decoration: underline; }
.field-centered { max-width: 420px; margin-left: auto; margin-right: auto; }
@media (max-width: 768px) { .field-centered { max-width: 100%; } }

/* ---- Account type picker (Institution / Educator / Student / Parent) ---- */
.account-type-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 20px 0; }
.account-type-card {
    background: var(--brand-20);
    border: 2px solid transparent;
    border-radius: 20px;
    padding: 24px 12px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
}
.account-type-card:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(88, 73, 214, 0.12); border-color: var(--brand-150); }
.account-type-card.selected { border-color: var(--brand-500); background: var(--brand-50); box-shadow: 0 8px 25px rgba(88, 73, 214, 0.15); }
.account-type-card.selected .account-type-check { opacity: 1; transform: scale(1); }
.account-type-card.disabled { opacity: 0.5; cursor: not-allowed; }
.account-type-card.disabled:hover { transform: none; box-shadow: none; border-color: transparent; }
.account-type-card .account-type-icon {
    width: 56px; height: 56px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    margin: 0 auto 12px auto; font-size: 24px; color: #fff; transition: all 0.3s ease;
}
.account-type-card .account-type-icon.inst { background: linear-gradient(135deg, #6C63FF, #5849D6); }
.account-type-card .account-type-icon.edu { background: linear-gradient(135deg, #00B894, #1C8A4C); }
.account-type-card .account-type-icon.student { background: linear-gradient(135deg, #FF8A65, #E8590C); }
.account-type-card .account-type-icon.parent { background: linear-gradient(135deg, #BA68C8, #7B3FA0); }
.account-type-card .account-type-name { font-size: 14px; font-weight: 700; color: var(--text); display: block; margin-bottom: 2px; }
.account-type-card .account-type-desc { font-size: 11px; color: var(--text-muted); display: block; line-height: 1.4; }
.account-type-card .account-type-check {
    position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; border-radius: 50%;
    background: var(--brand-500); color: #fff; display: flex; align-items: center; justify-content: center;
    font-size: 12px; opacity: 0; transform: scale(0.5); transition: all 0.3s ease;
}
@media (max-width: 768px) {
    .account-type-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .account-type-card { padding: 18px 10px; }
    .account-type-card .account-type-icon { width: 44px; height: 44px; font-size: 18px; }
    .account-type-card .account-type-name { font-size: 12px; }
    .account-type-card .account-type-desc { font-size: 10px; }
}

/* ---- Teacher account/user menu grid (Sep 2026, THIRD nav-rework pass,
   trimmed in the FOURTH): "the user menu should now be grid icons..." then
   "remove everything else except settings; profile, question bank, clear
   cache and logout" - #fdMobileSheet's fixed tool list on teacher pages
   (header.php's $fdMenuTools), a smaller plain-tile variant of
   .account-type-grid/.account-type-card above (no selected state - these
   are just links/actions, not a picker). A tile with no href (Clear
   Cache) renders as a real <button> instead of an <a> - this reset makes
   it look identical to its sibling link-tiles rather than a native
   browser button. ---- */
.fd-menu-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 4px 0 14px 0; }
.fd-menu-tile {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 8px; background: var(--brand-20); border-radius: 16px; padding: 14px 6px;
    text-align: center; transition: all 0.2s ease;
    border: none; width: 100%; cursor: pointer; font-family: inherit;
}
.fd-menu-tile:hover { background: var(--brand-50); transform: translateY(-2px); }
.fd-menu-tile-icon {
    width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--brand-500), var(--brand-600));
    color: #fff; font-size: 15px;
}
.fd-menu-tile-label { font-size: 11px; font-weight: 700; color: var(--text); line-height: 1.25; }
@media (max-width: 480px) {
    .fd-menu-grid { grid-template-columns: repeat(3, 1fr); gap: 8px; }
    .fd-menu-tile { padding: 12px 4px; }
    .fd-menu-tile-icon { width: 36px; height: 36px; font-size: 13px; }
    .fd-menu-tile-label { font-size: 10px; }
}

/* ---- Toggle switch rows (enrolled? / teaching now? / open to contact?) ---- */
.toggle-row {
    display: flex; align-items: center; flex-wrap: wrap; gap: 14px 16px;
    background: var(--brand-20); border-radius: 18px; padding: 16px 18px; margin-bottom: 12px;
    transition: all 0.25s ease;
}
.toggle-row.is-on { background: var(--brand-50); }
.toggle-row .toggle-copy { flex: 1 1 220px; min-width: 0; }
.toggle-row .toggle-title { font-weight: 700; font-size: 13.5px; color: var(--text); display: flex; align-items: center; gap: 8px; }
.toggle-row .toggle-title i { color: var(--brand-600); font-size: 14px; }
.toggle-row .toggle-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.toggle-row .toggle-reveal {
    flex: 1 1 100%; max-height: 0; overflow: hidden; opacity: 0;
    transition: max-height 0.3s ease, opacity 0.25s ease, margin 0.3s ease; margin-top: 0;
}
.toggle-row.is-on .toggle-reveal { max-height: 90px; opacity: 1; margin-top: 4px; }

.switch { position: relative; display: inline-block; width: 48px; height: 28px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; position: absolute; }
.switch-slider { position: absolute; cursor: pointer; inset: 0; background: #DDDBEC; border-radius: 999px; transition: all 0.25s ease; }
.switch-slider::before {
    content: ''; position: absolute; height: 22px; width: 22px; left: 3px; top: 3px;
    background: #ffffff; border-radius: 50%; transition: all 0.25s cubic-bezier(0.4,0,0.2,1);
    box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}
.switch input:checked + .switch-slider { background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.switch input:checked + .switch-slider::before { transform: translateX(20px); }
.switch input:focus-visible + .switch-slider { outline: 2px solid var(--brand-600); outline-offset: 2px; }

/* ---- Live school-search dropdown ---- */
.search-results { max-height: 180px; overflow-y: auto; background: #fff; border-radius: 12px; border: 1px solid var(--brand-150); display: none; }
.search-results.is-open { display: block; }
.search-results .result-item { padding: 10px 14px; cursor: pointer; transition: background 0.2s ease; border-bottom: 1px solid var(--brand-50); }
.search-results .result-item:hover { background: var(--brand-25); }
.search-results .result-item:last-child { border-bottom: none; }
.search-results .result-item .result-name { font-weight: 600; font-size: 13px; color: var(--text); }
.search-results .result-item .result-meta { font-size: 11px; color: var(--text-muted); }
.search-results .result-empty { padding: 12px 14px; font-size: 12.5px; color: var(--text-muted); }
.selected-chip {
    display: inline-flex; align-items: center; gap: 8px; background: var(--brand-50); border: 1px solid var(--brand-150);
    border-radius: 999px; padding: 6px 8px 6px 12px; font-size: 12.5px; font-weight: 600; color: var(--brand-700); margin-top: 8px;
}
.selected-chip button { border: none; background: transparent; color: var(--text-muted); cursor: pointer; width: 20px; height: 20px; border-radius: 50%; }
.selected-chip button:hover { background: var(--brand-150); color: var(--err); }

/* ---- Empty state (no subjects/qualifications added yet) ---- */
.empty-state { text-align: center; padding: 40px 20px; color: var(--text-muted); }
.empty-state i { font-size: 48px; color: var(--brand-200); margin-bottom: 12px; }
.empty-state h5 { color: var(--text); font-weight: 600; }
.empty-state p { font-size: 13px; }

/* ---- Subject / course summary card (Step 2 list) ---- */
.subject-card {
    background: var(--brand-20); border-radius: 18px; padding: 16px 18px; margin-bottom: 12px;
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
    transition: all 0.3s ease; border: 1px solid transparent;
}
.subject-card:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(88, 73, 214, 0.08); border-color: var(--brand-150); }
.subject-card .subject-info { display: flex; align-items: flex-start; gap: 14px; min-width: 0; }
.subject-card .subject-avatar {
    width: 44px; height: 44px; border-radius: 12px; background: linear-gradient(135deg, var(--brand-500), var(--brand-600));
    color: #fff; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0;
}
.subject-card.is-course .subject-avatar { background: linear-gradient(135deg, #BA68C8, #7B3FA0); }
.subject-card .subject-name { font-weight: 700; font-size: 15px; color: var(--text); }
.subject-card .subject-meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; line-height: 1.5; }
.subject-card .subject-meta .meta-line { display: block; }
.subject-card .subject-actions { display: flex; gap: 8px; flex-shrink: 0; }
.subject-card .subject-actions button {
    width: 32px; height: 32px; border-radius: 50%; border: none; background: #eef2f5; color: #5a6c7d;
    font-size: 13px; cursor: pointer; transition: all 0.2s ease;
}
.subject-card .subject-actions button:hover { background: var(--brand-600); color: #fff; }
.subject-card .subject-actions button.delete:hover { background: #e74c3c; color: #fff; }
.subject-card .class-tag-row { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.subject-card .class-tag { font-size: 10.5px; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: var(--brand-100); color: var(--brand-600); }
.subject-card.is-course .class-tag { background: #EFE0F7; color: #7B3FA0; }
.section-count-note { font-size: 12px; color: var(--text-muted); }
.section-count-note strong { color: var(--brand-600); }

/* ---- Chip-select grid (subjects/classes/series inside the add sheet) ---- */
.chip-select-grid { display: grid; grid-template-columns: 1fr; gap: 8px; }
.chip-select {
    border: 1.5px solid var(--line); background: var(--brand-15, var(--brand-20)); color: var(--text); border-radius: 14px;
    padding: 11px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all 0.2s ease;
    display: flex; align-items: center; gap: 8px; text-align: left;
}
.chip-select i.chip-check { margin-left: auto; opacity: 0; color: var(--brand-600); font-size: 12px; transition: opacity .2s ease; }
.chip-select:hover { border-color: var(--brand-200); }
.chip-select.selected { background: var(--brand-50); border-color: var(--brand-500); color: var(--brand-600); }
.chip-select.selected i.chip-check { opacity: 1; }
.chip-icon { width: 24px; height: 24px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 11px; flex-shrink: 0; }

/* ---- Sheet slide wizard (Faculty > Department > Course / Category > Class > Series) ---- */
@keyframes wizardSlideIn { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: translateX(0); } }
.wizard-slide-in { animation: wizardSlideIn 0.28s cubic-bezier(0.32, 0.72, 0, 1); }
.sheet-step-dots { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 16px; }
.sheet-step-dots .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand-150); transition: all 0.25s ease; }
.sheet-step-dots .dot.active { width: 20px; border-radius: 4px; background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.sheet-step-dots .dot.done { background: var(--brand-300, var(--brand-200)); }
.sheet-crumb { font-size: 11.5px; color: var(--text-muted); text-align: center; margin-bottom: 14px; }
.sheet-crumb strong { color: var(--brand-600); }
.sheet-slide-title { font-size: 14px; font-weight: 700; color: var(--text); margin-top: 4px; margin-bottom: 10px; }
.wizard-nav-row {
    display: flex; gap: 10px; margin-top: 16px; position: sticky; bottom: -1px; background: #ffffff;
    padding: 12px 0 2px 0; border-top: 1px solid var(--line); z-index: 5;
}
.wizard-nav-row .btn-primary { flex: 2; }
.wizard-nav-row .btn-outline-secondary { flex: 1; }

/* Sep 2026 UI-bug follow-up, quoted directly: "the 'use this' buttons are
   not even styled" - the Create Class wizard's two custom-name/custom-
   subject "Use this" buttons (footer.php) were plain, unmodified Bootstrap
   `.btn-outline-secondary` (thin grey border/text) sitting right next to
   the brand-colored `.fd-subject-picker-row`/`.chip-select` rows above
   them, so they read as unfinished. This gives that same pair of buttons
   the app's own brand look instead of overriding Bootstrap's class
   globally (which .wizard-nav-row's own `.btn-outline-secondary` rule,
   just above, still relies on elsewhere in this same wizard). */
.fd-use-this-btn.btn-outline-secondary {
    border: 1.5px solid var(--brand-300, var(--brand-150));
    color: var(--brand-600);
    background: var(--brand-15);
    font-weight: 600;
    border-radius: var(--r-md, 10px);
}
.fd-use-this-btn.btn-outline-secondary:hover {
    background: var(--brand-600);
    border-color: var(--brand-600);
    color: #fff;
}

/* ---- Repeatable rows (professional history / qualifications) ---- */
.repeat-row { background: var(--brand-25); border: 1px solid var(--brand-150); border-radius: 16px; padding: 14px 14px 4px 14px; margin-bottom: 12px; position: relative; }
.repeat-row .repeat-remove {
    position: absolute; top: 10px; right: 10px; z-index: 5; width: 28px; height: 28px; border-radius: 50%; border: none;
    background: #FFD9D6; color: #d6336c; font-size: 12px; cursor: pointer; transition: all 0.2s ease;
}
.repeat-row .repeat-remove:hover { background: #e74c3c; color: #fff; }
.repeat-row > .input-icon-wrap:first-of-type input.form-control { padding-right: 40px; }
.add-row-btn {
    width: 100%; background: transparent; border: 1.5px dashed var(--brand-200); border-radius: 12px; padding: 12px;
    color: var(--brand-600); font-weight: 700; font-size: 13px; display: flex; align-items: center; justify-content: center;
    gap: 8px; cursor: pointer; transition: all 0.25s ease;
}
.add-row-btn:hover { background: var(--brand-25); border-color: var(--brand-500); }

/* ---- Round profile photo upload (tutor Step 3) ---- */
.photo-upload-container { width: 100%; max-width: 150px; margin: 0 auto; position: relative; }
.photo-preview {
    width: 140px; height: 140px; border-radius: 50%; border: 4px solid var(--brand-100); overflow: hidden;
    background: var(--brand-25); display: flex; align-items: center; justify-content: center;
    transition: all 0.3s ease; margin: 0 auto; position: relative; cursor: pointer;
}
.photo-preview:hover { border-color: var(--brand-600); box-shadow: 0 8px 30px rgba(88, 73, 214, 0.15); }
.photo-preview img { width: 100%; height: 100%; object-fit: cover; }
.photo-preview i.ph-placeholder { font-size: 46px; color: var(--brand-200); }
.photo-preview .upload-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; opacity: 0; transition: all 0.3s ease; border-radius: 50%; }
.photo-preview:hover .upload-overlay { opacity: 1; }
.photo-preview .upload-overlay i { color: #fff; font-size: 24px; }
.photo-upload-input { display: none; }
.photo-upload-caption { text-align: center; font-size: 11.5px; color: var(--text-muted); margin-top: 10px; }

/* ---- Add-subjects trigger card sits inside a 1-col account-type-grid on
   the onboarding pages, unlike the 4-col one on the auth page ---- */
.fd-add-subject-grid.account-type-grid { grid-template-columns: 1fr; margin: 0; }

/* ---- Self-hosted toast (fd-toast.js) ---- */
.fd-toast-stack { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 4000; display: flex; flex-direction: column; gap: 8px; width: min(360px, calc(100vw - 24px)); pointer-events: none; }
.fd-toast {
    pointer-events: auto; display: flex; align-items: flex-start; gap: 10px; background: var(--surface); color: var(--text);
    border-radius: 14px; padding: 12px 14px; box-shadow: 0 10px 30px rgba(0,0,0,0.14);
    border-left: 4px solid var(--brand-500); opacity: 0; transform: translateY(-10px); transition: all 0.22s ease; cursor: pointer;
}
.fd-toast.is-in { opacity: 1; transform: translateY(0); }
.fd-toast-success { border-left-color: var(--ok); }
.fd-toast-error { border-left-color: var(--err); }
.fd-toast-icon { font-size: 18px; margin-top: 1px; color: var(--brand-600); }
.fd-toast-success .fd-toast-icon { color: var(--ok); }
.fd-toast-error .fd-toast-icon { color: var(--err); }
.fd-toast-title { font-weight: 700; font-size: 13.5px; }
.fd-toast-text { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }

/* ---- Sep 2026: backend-request spinner (fd-app-shell.js applies this
   class automatically to whichever button/link/submit control triggered
   a fetch()/XHR/form submit - see that file's own comments). Fades the
   control's own text/icons out via color:transparent (works no matter
   what markup is inside it - font-icons included - without touching
   innerHTML, so no onclick handler or nested element is ever disturbed)
   and draws a small spinner ring centered on top of it instead.

   Sep 2026 (second follow-up): a fixed --brand-600 ring all but
   disappeared on the many buttons that ARE brand-600 (a solid purple
   ring on a solid purple button). `mix-blend-mode: difference` fixes
   this without needing to know the button's own color at all - the ring
   is rendered as the mathematical color-difference between white and
   whatever is directly behind it, which is never equal to that
   background (difference against white -> black, against the brand
   purple -> a contrasting yellow-green, against black -> white),
   so it reads clearly on light buttons, dark buttons, and brand-colored
   buttons alike. ---- */
.fd-busy {
    position: relative;
    color: transparent !important;
    pointer-events: none;
    cursor: default;
}
.fd-busy img { visibility: hidden; }
.fd-busy::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 16px;
    height: 16px;
    margin: -8px 0 0 -8px;
    border-radius: 50%;
    border: 2px solid #fff;
    border-right-color: transparent;
    mix-blend-mode: difference;
    animation: fdBusySpin 0.6s linear infinite;
}
@keyframes fdBusySpin {
    to { transform: rotate(360deg); }
}
@media (max-width: 768px) { .fd-toast-stack { top: 70px; } }

/* ---- Dark-mode form input text (Sep 2026, found verifying the new Get
   Started admin form below) ----
   template-exact.css's `.form-control` rule never set an explicit `color`,
   so Bootstrap's own un-themed default (#212529, near-black) won every
   text/textarea/select input in dark mode - illegible against the dark-
   mode input background (confirmed via computed style: color rgb(33,37,41)
   on a rgb(21,19,43) background, effectively invisible). This is
   sitewide - every form on every page, not just the one added this round
   - template-exact.css's OWN comment already fixed the identical gap for
   plain <body> text ("Aug 2026 dark-mode contrast fix"); this is that
   same fix for form fields, added here since template-exact.css itself is
   the untouched verbatim template extraction and must not be edited. */
html[data-theme="dark"] .form-control { color: var(--text); }

/* ---- Get Started intro cards (Sep 2026 "first introduction" rework) ----
   Reuses .fd-section.tinted (same brand-25 fill / brand-150 border tokens
   as everywhere else) for each card so dark mode needs zero extra rules;
   this just adds the icon/title/body layout + equal-height columns. Also
   used, read-only preview aside, by the admin edit rows on
   super-admin/settings.php's "Get Started" tab. */
.fd-intro-card {
    height: 100%;
    padding: 20px 18px 18px 18px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.fd-intro-card > i { font-size: 26px; color: var(--brand-600); }
.fd-intro-card h4 { margin: 2px 0 0 0; font-size: 15px; font-family: 'Poppins', sans-serif; color: var(--text); }
.fd-intro-card p { margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.5; }

/* ---- Super Admin > Settings > Get Started: repeating card-edit rows ---- */
.fd-intro-edit-row {
    display: grid;
    grid-template-columns: 140px 1fr auto;
    gap: 10px;
    align-items: start;
    padding: 12px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-sm, 10px);
    margin-bottom: 10px;
}
.fd-intro-edit-row .fd-intro-edit-remove {
    background: none; border: 1px solid var(--line); color: var(--err);
    border-radius: 8px; width: 36px; height: 36px; cursor: pointer;
}
.fd-intro-edit-row .fd-intro-edit-remove:hover { background: var(--err); color: #fff; }
@media (max-width: 640px) {
    .fd-intro-edit-row { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Sep 2026 class-tools SECOND follow-up round. Everything below is new -
   nothing here replaces the Sep 2026 class-tools rework block above (the
   .fd-tool-tab-*, .fd-att-tile-* and .fd-dash-* rules stay exactly as they
   were for whatever still uses them) except where a comment says so
   explicitly.
   ========================================================================== */

/* ---- Icon-tile picker grid: a real multi-column grid of square icon
   tiles, reused for the Online Classes platform picker, the Evaluation
   type picker, AND (2-up) the Attendance tab's Take/Search actions -
   quoted directly: "put this platform in grid rather than list... to
   reduce scrolling" and "the take attendance and see previous attendance
   icons are soo big they should be like same design like the evaluation
   type icons and also sit next to each other same row." Distinct from the
   existing .chip-select-grid (a single-column list-with-icon row, kept
   as-is and still used by the Billing gateway picker) and from
   .fd-onboarding-page .sheet-action-grid (page-scoped, not reachable
   here) - this is its own small multi-column component so it can be
   reused on any page without pulling in unrelated onboarding styling. */
.fd-pick-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 10px;
    margin-bottom: 6px;
}
.fd-pick-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    background: var(--surface);
    border: 2px solid var(--line);
    border-radius: var(--r-md, 14px);
    padding: 12px 6px 10px 6px;
    cursor: pointer;
    text-align: center;
    transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.fd-pick-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-card); }
.fd-pick-tile.selected { border-color: var(--brand-500); background: var(--brand-25); }
/* Sep 2026: "create evaluation step 2: on desktop put the icons vertically
   centered" - a CSS grid row stretches every tile in it to match its
   tallest neighbor (default align-items:stretch), so once one type's
   label wraps to two lines, shorter-label tiles in that row are taller
   than their own content and (being flex-column with no justify-content)
   top-align, leaving their icon sitting higher than the wrapped tile's
   icon. Scoped to the evaluation type grid specifically, desktop only -
   mobile's narrower columns rarely produce uneven row heights and the
   other .fd-pick-grid users (Online Class provider/payment tiles,
   Attendance actions) keep their existing top-aligned look. */
@media (min-width: 769px) {
    #evTypeGrid.fd-pick-grid { align-items: stretch; }
    #evTypeGrid .fd-pick-tile { justify-content: center; }
}
.fd-pick-tile-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    color: #fff;
    flex-shrink: 0;
}
.fd-pick-tile-label { font-size: 11.5px; font-weight: 700; color: var(--text); line-height: 1.25; }
.fd-pick-tile-check {
    position: absolute;
    top: 6px;
    right: 8px;
    color: var(--brand-500);
    font-size: 12px;
    opacity: 0;
    transform: scale(.5);
    transition: all .2s ease;
}
.fd-pick-tile { position: relative; }
.fd-pick-tile.selected .fd-pick-tile-check { opacity: 1; transform: scale(1); }
/* .multi tiles (the payment-method toggle) use a checkbox-square instead
   of a single-select ring, since more than one can be active at once. */
.fd-pick-tile.multi.selected { border-color: var(--ok); background: rgba(28,138,76,0.08); }
.fd-pick-tile.multi.selected .fd-pick-tile-check { color: var(--ok); }
/* The Attendance tab's 2-tile row specifically - bigger label, no wrap,
   sits directly under .fd-pick-grid's default sizing (already "sit next
   to each other same row" since 2 tiles never wrap in an auto-fill grid
   with a 480px+ container) but a little roomier since there are only 2. */
.fd-att-actions-grid.fd-pick-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
.fd-att-actions-grid .fd-pick-tile-icon { width: 46px; height: 46px; font-size: 19px; }
.fd-att-actions-grid .fd-pick-tile-label { font-size: 13px; }

/* ---- Item card list (Online Classes sessions / Evaluations) - replaces
   the previous plain <table> with a colorful, icon-led card per row,
   quoted directly: "list all created online classes in a card list
   format with icons and course or subject name dates and etc use icons
   too and colorful too." */
/* Sep 2026, FOURTH nav-rework pass: "add a very light gray background on
   the evaluation lists and online class lists" - .fd-item-card-list is
   only ever used by those two lists in class_tools.php (confirmed - no
   other page reuses this class), so this backdrop is safely scoped to
   exactly what was asked without a new class. var(--line) is this app's
   own existing "very light gray" token (already used the same way for
   .sheet-btn.ghost's background) rather than a hardcoded hex, so it still
   makes sense against the dark theme's own tokens. */
.fd-item-card-list { display: flex; flex-direction: column; gap: 10px; background: var(--line); border-radius: 16px; padding: 12px; }
/* Sep 2026 follow-up, quoted directly: "on mobile view the items should not
   take more than 3 row... keep the class sesion title and price on same
   row but the price should be on the extreme right end. the time and
   platfrom in the middle then the third row can be the clickable icons" -
   plus "thesame should go for the evaluations created." Both the Online
   Class and Evaluation cards (class_tools.php) now render three explicit
   row children (row1/row2/row3, evaluation adds one extra badges row for
   its longer guest-link/draft text) instead of the old icon+body+actions
   flex-wrap layout, so .fd-item-card itself is now a plain column stack -
   this reads identically on desktop (three tidy rows) and mobile (the
   same three rows, just the only thing at this width), rather than having
   a separate mobile-only layout to keep in sync. */
.fd-item-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md, 14px);
    padding: 14px 16px;
    transition: box-shadow .15s ease, transform .15s ease;
}
.fd-item-card:hover { box-shadow: var(--shadow-card); transform: translateY(-2px); }
.fd-item-card-icon-sm {
    width: 32px;
    height: 32px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    color: #fff;
    flex-shrink: 0;
}
.fd-item-card-row1 {
    display: flex;
    align-items: center;
    gap: 10px;
}
.fd-item-card-title {
    font-weight: 700;
    font-size: 14px;
    color: var(--text);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fd-item-card-status { flex-shrink: 0; }
.fd-item-card-price {
    margin-left: auto;
    flex-shrink: 0;
    font-weight: 700;
    font-size: 13px;
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}
.fd-item-card-row2 {
    display: flex;
    align-items: center;
    gap: 14px;
    font-size: 12px;
    color: var(--text-muted);
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.fd-item-card-row2::-webkit-scrollbar { display: none; }
.fd-item-card-row2 span { display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0; white-space: nowrap; }
.fd-item-card-badges-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fd-item-card-row3.fd-item-card-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Old per-subject icon+body layout classes, kept only where still
   referenced elsewhere in the app (none currently under public/, confirmed
   by grep, but left defined rather than deleted - cheap to keep, zero
   risk if a future page reuses the shape). */
.fd-item-card-icon {
    width: 46px;
    height: 46px;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    color: #fff;
    flex-shrink: 0;
}
.fd-item-card-body { flex: 1; min-width: 160px; }
.fd-item-card-meta { display: flex; flex-wrap: wrap; gap: 10px; font-size: 12px; color: var(--text-muted); }
.fd-item-card-meta span { display: inline-flex; align-items: center; gap: 5px; }
.fd-item-card-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Sep 2026 follow-up, quoted directly: "the icons should not be a button
   but just clickable icons only i dont want to see border lines around
   them." Scoped to the card's own action row (not .fd-icon-btn globally -
   the sheet-footer/top-bar uses of that class elsewhere are unaffected)
   since that's specifically what was asked about here. */
.fd-item-card-row3.fd-item-card-actions .fd-icon-btn {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    width: 38px;
    height: 38px;
}
.fd-item-card-row3.fd-item-card-actions .fd-icon-btn:hover,
.fd-item-card-row3.fd-item-card-actions .fd-icon-btn:active {
    background: var(--brand-25) !important;
}
html[data-theme="dark"] .fd-item-card-row3.fd-item-card-actions .fd-icon-btn:hover,
html[data-theme="dark"] .fd-item-card-row3.fd-item-card-actions .fd-icon-btn:active {
    background: var(--brand-50) !important;
}
.fd-item-card-top-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 12px;
}
.fd-item-card-top-row h3 { margin: 0; }

/* ---- Evaluation wizard's Question-Bank browsing step: Topic > Subtopic >
   Lesson breadcrumb, a question row with a "+" add button (instead of the
   existing .sheet-action's chevron - reused as-is for the topic/subtopic/
   lesson tiles themselves), the running "selected questions" strip, and
   the compact inline add-topic/subtopic/lesson + manual quick-add-question
   forms. Quoted directly: "the user will see a list of topics for that
   subjects then subtopics then lessons then the various questions and a
   plus add button for them to add the questions they want and also an
   input field for them to manually type a question." */
.fd-qb-crumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-muted);
    margin-bottom: 12px;
}
.fd-qb-crumb button {
    background: none;
    border: none;
    color: var(--brand-600);
    font-weight: 600;
    cursor: pointer;
    padding: 2px 4px;
    font-size: 12.5px;
}
.fd-qb-crumb button:hover { text-decoration: underline; }
.fd-qb-crumb .sep { color: var(--text-faint); }
.fd-qb-question-row {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--brand-20);
    border-radius: 14px;
    padding: 12px 14px;
    margin-bottom: 8px;
}
.fd-qb-question-row .fd-qb-q-text { flex: 1; font-size: 13px; color: var(--text); min-width: 0; }
.fd-qb-add-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: var(--brand-500);
    color: #fff;
    font-size: 13px;
    flex-shrink: 0;
    cursor: pointer;
    transition: background .15s ease, transform .15s ease;
}
.fd-qb-add-btn:hover { background: var(--brand-600); transform: scale(1.08); }
.fd-qb-add-btn.added { background: var(--ok); }
/* Sep 2026 third follow-up: "an option for the user to manually type or
   edit or add questions but under the given topic sub topic lesson" - a
   second small round button per question row, neutral-toned (distinct
   from the brand-colored add/added button next to it) so the two read as
   different actions at a glance. */
.fd-qb-edit-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1.5px solid var(--line);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 12px;
    flex-shrink: 0;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, transform .15s ease;
}
.fd-qb-edit-btn:hover { background: var(--brand-25); color: var(--brand-600); border-color: var(--brand-200); transform: scale(1.08); }
.fd-qb-selected-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px;
    background: var(--brand-25);
    border: 1px dashed var(--brand-150);
    border-radius: 14px;
    margin-bottom: 14px;
    min-height: 44px;
}
.fd-qb-selected-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--surface);
    border-radius: var(--r-pill);
    padding: 5px 6px 5px 12px;
    font-size: 12px;
    color: var(--text);
    box-shadow: 0 1px 4px rgba(0,0,0,0.08);
}
.fd-qb-selected-chip button {
    background: var(--err-bg, rgba(220,53,69,0.12));
    color: var(--err);
    border: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 10px;
}
.fd-qb-inline-add {
    display: flex;
    gap: 8px;
    margin: 10px 0 16px 0;
}
.fd-qb-inline-add input {
    flex: 1;
    border: 1.5px dashed var(--line);
    border-radius: 10px;
    padding: 9px 12px;
    font-size: 13px;
    background: transparent;
    color: var(--text);
}
.fd-qb-inline-add button {
    background: var(--brand-50);
    color: var(--brand-600);
    border: 1.5px dashed var(--brand-200);
    border-radius: 10px;
    padding: 0 14px;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}
.fd-qb-quickadd {
    background: var(--brand-15, var(--brand-25));
    border: 1px solid var(--line);
    border-radius: var(--r-md, 14px);
    padding: 14px;
    margin-top: 6px;
}
.fd-qb-toggle-quickadd {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: 1.5px dashed var(--brand-200);
    color: var(--brand-600);
    border-radius: 12px;
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    width: 100%;
    justify-content: center;
    margin-top: 8px;
}

/* "for the title input field remove that background color as it makes the
   input not visible" - .form-control's own background is a hard
   !important fill (template-exact.css) that can end up too close to the
   page/section color behind it to read as a distinct field; dropping the
   fill entirely and relying on a visible border instead sidesteps that in
   both themes without touching the shared .form-control rule everywhere
   else still depends on. */
.fd-ev-title-input {
    background: transparent !important;
    border: 1.5px solid var(--line) !important;
    color: var(--text) !important;
}
.fd-ev-title-input:focus {
    background: transparent !important;
    border-color: var(--brand-500) !important;
}

/* Sep 2026 fourth follow-up: "the icons concerning the input field the
   icons should be inside the input field not on the label." Every field
   that had an <i> sitting inside its <label> (Title, Meeting link,
   Start/End, Instructions, Price, Number of questions, Question type,
   Question, Opens/Due/Duration/Term, New status/Reason) now wraps its
   real <input>/<select>/<textarea> in `.fd-input-icon` instead - the icon
   moves inside the field itself as a left-inset glyph and the label
   above it goes back to plain text. Left deliberately UNUSED on labels
   that sit above a custom picker/grid rather than a genuine input (e.g.
   "Accepted methods", "Payment gateway", "Who takes it") - those aren't
   "input fields" in the sense the instruction meant, and their icon
   stays on the label. `.fd-input-icon-top` is the textarea variant -
   pins the icon to the first line instead of vertically centering it,
   since a centered icon on a multi-row box reads oddly. */
.fd-input-icon {
    position: relative;
}
.fd-input-icon > i {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-faint);
    font-size: 14px;
    pointer-events: none;
    z-index: 1;
}
.fd-input-icon > input,
.fd-input-icon > select,
.fd-input-icon > textarea {
    padding-left: 36px !important;
}
.fd-input-icon.fd-input-icon-top > i {
    top: 14px;
    transform: none;
}
.fd-input-icon > select {
    /* Bootstrap's default select already reserves room on the right for
       its own dropdown caret - only the left side needs the icon gap. */
    padding-right: 28px;
}

/* ---- Evaluation wizard step 1's guest-access toggle switch ---- */
.fd-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--brand-20);
    border-radius: 14px;
    padding: 12px 14px;
    margin-top: 4px;
}
.fd-toggle-row-text { font-size: 12.5px; color: var(--text); }
.fd-toggle-row-text strong { display: block; font-size: 13.5px; margin-bottom: 2px; }
.fd-toggle-switch {
    position: relative;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
    background: var(--line);
    border-radius: var(--r-pill);
    border: none;
    cursor: pointer;
    transition: background .2s ease;
}
.fd-toggle-switch::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    transition: transform .2s ease;
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.fd-toggle-switch.on { background: var(--ok); }
.fd-toggle-switch.on::after { transform: translateX(20px); }

/* ==========================================================================
   Sep 2026 second follow-up: teacher dashboard (teacher/index.php) fixes -
   analytics bar chart + summary side-by-side, a fresher stat-card look
   with NO colored border-accent lines, a heading above the class grid,
   and distinct-per-icon action-button coloring (light circle / strong
   icon, the inverse of the previous solid-circle/white-icon look).
   ========================================================================== */
.fd-dash-summary-row {
    /* Sep 2026 follow-up, quoted directly: "on desktop view we should have
       the tutor's photo after the pie chart then his other profile
       information on the right. so its pie chart, photo, then other
       profile info." Widened from 2 to 3 columns (chart / photo / profile)
       to fit the new middle photo card - see fd_dash_photo_card(),
       teacher/index.php. */
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.65fr) minmax(0, 1.15fr);
    gap: 18px;
    margin-bottom: 26px;
    align-items: stretch;
}
.fd-dash-chart-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 18px);
    padding: 18px;
    display: flex;
    flex-direction: column;
}
.fd-dash-chart-card h4 {
    margin: 0 0 14px 0;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
}
.fd-dash-chart-card h4 i { color: var(--brand-600); }

/* Sep 2026 third follow-up, quoted directly: "can we use a pir chart
   insted with multiple inner rings nicely styled" - a set of concentric
   SVG progress rings (one per stat, drawn via stroke-dasharray on a
   circle - see fd_dash_summary_block() in index.php) replaces the
   .fd-dash-bar-* chart above, which is left in place, unused, rather
   than deleted (cheap to keep, zero risk). */
.fd-dash-ring-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    flex: 1;
    padding-top: 4px;
}
.fd-dash-ring-svg {
    width: 168px;
    height: 168px;
    flex-shrink: 0;
}
.fd-dash-ring-svg circle {
    transition: stroke-dasharray .6s cubic-bezier(0.32, 0.72, 0, 1);
}
.fd-dash-ring-legend {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px 18px;
    width: 100%;
}
.fd-dash-ring-legend-item {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--text-muted);
    min-width: 0;
}
.fd-dash-ring-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.fd-dash-ring-legend-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-dash-ring-legend-num { font-weight: 700; color: var(--text); flex-shrink: 0; }

html[data-theme="dark"] .fd-dash-ring-legend-item { color: var(--text-muted); }

.fd-dash-bar-chart {
    display: flex;
    align-items: flex-end;
    gap: 14px;
    flex: 1;
    min-height: 120px;
    padding-top: 6px;
}
.fd-dash-bar-col { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.fd-dash-bar-track {
    width: 100%;
    max-width: 34px;
    height: 110px;
    display: flex;
    align-items: flex-end;
    background: var(--brand-15, var(--brand-25));
    border-radius: 10px 10px 4px 4px;
    overflow: hidden;
}
.fd-dash-bar-fill { width: 100%; border-radius: 10px 10px 0 0; min-height: 4px; transition: height .4s ease; }
.fd-dash-bar-num { font-size: 13px; font-weight: 700; color: var(--text); }
.fd-dash-bar-label { font-size: 10.5px; color: var(--text-muted); text-align: center; }

/* Sep 2026: "the grids at the left of the pie chart should be replaced
   with the teacher profile information" - .fd-dash-stats-fresh/.fd-dash-
   stat-fresh (the old stat-card grid alongside the pie chart) are gone,
   replaced by .fd-dash-profile-panel below (fd_dash_profile_panel(),
   teacher/index.php). Sits in the exact same grid slot inside
   .fd-dash-summary-row, so no layout-container changes were needed. */
.fd-dash-profile-panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 18px);
    padding: 18px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.fd-dash-profile-panel h4 {
    margin: 0 0 10px 0;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
}
.fd-dash-profile-panel h4 i { color: var(--brand-600); }
.fd-dash-profile-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--line);
}
.fd-dash-profile-row:last-of-type { border-bottom: none; }
.fd-dash-profile-icon {
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: var(--brand-25);
    color: var(--brand-600);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    flex-shrink: 0;
}
.fd-dash-profile-text { min-width: 0; }
.fd-dash-profile-label { font-size: 10.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; }
.fd-dash-profile-value { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-dash-profile-edit-link {
    margin-top: 12px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--brand-600);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.fd-dash-profile-edit-link:hover { text-decoration: underline; }
/* "on mobile this part should be completely hidden" - .fd-dash-summary-
   row already stacks to one column at <=900px (rule below), which is
   what would otherwise put this panel between the chart and the class
   grid on mobile; hidden outright there instead. */
@media (max-width: 900px) {
    .fd-dash-profile-panel { display: none; }
}

/* Sep 2026 follow-up, quoted directly: "on desktop view we should have the
   tutor's photo after the pie chart then his other profile information on
   the right." A real photo (accounts.photo) or initials fallback, same
   convention as header.php's corner avatar / profile.php's photo upload -
   see fd_dash_photo_card(), teacher/index.php. Hidden on mobile/tablet for
   the same reason .fd-dash-profile-panel is above (this ask was explicitly
   "that is for desktop" - mobile gets the chart+classes scroll row instead,
   see .fd-dash-chart-mobile-slot further down). */
.fd-dash-photo-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 18px);
    padding: 18px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    text-align: center;
}
.fd-dash-photo-circle {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--grad-brand, linear-gradient(135deg, var(--brand-500), var(--brand-600)));
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.fd-dash-photo-circle img { width: 100%; height: 100%; object-fit: cover; }
.fd-dash-photo-initials { color: #fff; font-weight: 700; font-size: 30px; }
.fd-dash-photo-name {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
@media (max-width: 900px) {
    .fd-dash-photo-card { display: none; }
}

/* Class-card action icons: distinct color per action (Edit vs
   Assignments), and inverted from the previous look - a LIGHT tint circle
   with a STRONG-colored icon, rather than a solid-colored circle with a
   white icon. */
.fd-dash-class-action-btn.tone-edit { background: rgba(232,89,12,0.14); color: #E8590C; }
.fd-dash-class-action-btn.tone-edit:hover { background: #E8590C; color: #fff; }
.fd-dash-class-action-btn.tone-assign { background: rgba(28,138,76,0.14); color: #1C8A4C; }
.fd-dash-class-action-btn.tone-assign:hover { background: #1C8A4C; color: #fff; }
/* Sep 2026 "2 more icons for editing and delete class" - Delete's own
   tone, same light-tint-to-solid hover pattern as Edit/Assign above. */
.fd-dash-class-action-btn.tone-delete { background: rgba(194,37,92,0.14); color: #C2255C; }
.fd-dash-class-action-btn.tone-delete:hover { background: #C2255C; color: #fff; }

@media (max-width: 900px) {
    .fd-dash-summary-row { grid-template-columns: 1fr; }
}
/* Sep 2026 UI-bug follow-up, quoted directly: "on mobile, the pie/donut
   chart should be col-12 while 'My Classes' sits on a new line below (not
   side-by-side)." Was `display:none` at this breakpoint (the chart used
   to reappear inside the class grid's own scroll row instead, see
   .fd-dash-chart-mobile-slot above) - now the row stays visible so the
   chart still shows on mobile, just on its own: photo/profile are already
   hidden at the 900px rule above, so the chart card is the only grid item
   left, and with .fd-dash-summary-row's `grid-template-columns: 1fr`
   (also from the 900px rule) it fills the full row width (col-12) with
   "My Classes"'s own heading/grid, further down the page, forming the
   next line - never side-by-side with the chart. */
@media (max-width: 480px) {
    .fd-dash-bar-chart { gap: 8px; }
}

html[data-theme="dark"] .fd-dash-chart-card,
html[data-theme="dark"] .fd-dash-profile-panel,
html[data-theme="dark"] .fd-dash-photo-card,
html[data-theme="dark"] .fd-item-card,
html[data-theme="dark"] .fd-pick-tile {
    background: var(--surface);
    border-color: var(--line);
}

/* "on mobile the entire patform background should be white" - guarded to
   light theme only (html:not([data-theme="dark"]), the same mutually-
   exclusive pairing as the existing html[data-theme="dark"] body rule in
   template-exact.css) so dark mode is completely unaffected; this app
   never uses prefers-color-scheme (confirmed by grep - dark mode is only
   ever the explicit data-theme="dark" toggle), so no OS-dark-mode case is
   missed by that guard. */
@media (max-width: 768px) {
    html:not([data-theme="dark"]) body { background: #FFFFFF; }
}

/* Dashboard hero greeting: "the time should always stay on same line or
   row with the name but on the far right side" even on mobile - the
   .fd-dash-hero row already used justify-content:space-between, it just
   also allowed flex-wrap, which is what let the date badge drop to its
   own line on a narrow phone. Locking flex-wrap off on mobile and letting
   the greeting itself truncate instead keeps the two on one row exactly
   like the desktop layout already looks. */
@media (max-width: 480px) {
    .fd-dash-hero { flex-wrap: nowrap; align-items: center; }
    .fd-dash-hero > div:first-child { min-width: 0; }
    .fd-dash-greeting { font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 2px; }
    .fd-dash-sub { display: none; }
    .fd-dash-date { flex-shrink: 0; padding: 6px 12px; font-size: 11.5px; }
}

/* ---- class_tools.php topbar: class name then subject name, with icons
   ("i think it should show the class and then the subject... add some
   nice icons too") ---- */
.fd-topbar-crumb { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fd-topbar-crumb .seg { display: inline-flex; align-items: center; gap: 7px; }
.fd-topbar-crumb .seg i { color: var(--brand-600); font-size: 15px; }
.fd-topbar-crumb .chev { color: var(--text-faint); font-size: 13px; }

/* ==========================================================================
   Sep 2026 third follow-up: "the pop ups we have a problem with scolling
   they dont scroll and some options or fields are just stucked hidden."
   Root cause: template-exact.css's base .sheet-viewport is a FIXED height
   (62vh/460px max) with overflow:hidden - fine for the onboarding wizard,
   which always injects a .sheet-pane (its own overflow-y:auto child) into
   it, but our class_tools.php/index.php sheets inject raw HTML straight
   into #fdcSheetViewport with no such wrapper, so anything taller than
   that fixed height was being silently CLIPPED, not scrolled.
   The onboarding pages already solved this exact problem for their own
   wizard sheet with a `.fd-onboarding-page .bottom-sheet.fd-wizard-sheet`
   variant (flex column, header/handle pinned, only .sheet-viewport
   scrolls) further up this file - this generalizes that SAME pattern so
   any `.bottom-sheet.fd-wizard-sheet` gets it, not only onboarding's,
   rather than inventing a second version of the same fix. Marking our
   sheet with the `fd-wizard-sheet` class (class_tools.php/index.php) is
   the only markup change needed to opt in. Specificity note: this 3-class
   selector loses to the onboarding page's 4-class one where both could
   apply (harmless - the values are identical), and beats the unscoped
   1-class base .sheet-viewport rule everywhere else.

   Sep 2026 fourth follow-up: "it should have a fixed height about 80
   percent of the entire screen even on desktop there should be a fixed
   height" - was `height:auto; max-height:80vh`, which only reached 80vh
   when a step's content happened to be that tall; short steps left the
   sheet visibly shrinking/growing between clicks. A real `height` (not
   just a ceiling) keeps every step of every sheet on this page -
   Attendance included - the same physical size. Unscoped by any media
   query here on purpose, so mobile (bottom-anchored) and desktop
   (centred dialog, template-exact.css's >=769px override) both inherit
   the same fixed height with no separate breakpoint rule needed.
   Sep 2026 follow-up, quoted directly: "increase the height of the pop up
   to [90] percent" - raised from 80vh to 90vh here to match the base
   .bottom-sheet cap above (this rule is what actually governs #fdProfileSheet/
   #fdWalletSheet/#fdClassSheet/#fdcSheet - every one of them carries
   .fd-wizard-sheet - so it, not the base rule, is the real profile-popup
   height fix).
   ========================================================================== */
.bottom-sheet.fd-wizard-sheet {
    height: 90vh;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    padding-bottom: 0;
}
.bottom-sheet.fd-wizard-sheet .sheet-header,
.bottom-sheet.fd-wizard-sheet .sheet-handle {
    flex-shrink: 0;
}
.bottom-sheet.fd-wizard-sheet .sheet-viewport {
    flex: 1;
    min-height: 0;
    height: auto;
    max-height: none;
    overflow-y: auto;
    /* Sep 2026 follow-up: explicit, rather than left to the CSS spec's own
       "overflow-x computes to auto when overflow-y isn't visible" rule -
       needed so the Students popup's .fd-slide-track (200% width, two
       screens side by side) is actually clipped/hidden horizontally and
       slides via transform instead of just being horizontally scrollable,
       which would defeat the slide illusion. Nothing else in this sheet
       viewport has ever relied on horizontal scrolling of the viewport
       itself (every horizontal-scroll strip on this page - tab strips,
       class grids - scrolls itself, not this container). */
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding-right: 2px;
    padding-bottom: 4px;
}

/* The wizard's own Back/Next (or Cancel/Save) row, now a PERMANENT sibling
   of #fdcSheetViewport rather than the last thing inside the scrolling
   HTML - "the back and next buttons on the pop ups should be fixed at
   the bottom again in same row with the back button just an icon."
   Reuses the SAME .fd-sheet-footer/.fd-sheet-footer-back/
   .fd-sheet-footer-save classes the onboarding wizard already built for
   exactly this (both are already unscoped/global, confirmed by grep - no
   new classes needed here, just new markup using them on this page). */
#fdcSheetFooter { display: none; }
#fdcSheetFooter.open { display: flex; }

/* Round, icon-only Back/Cancel button, small addition to the existing
   .fd-sheet-footer-back look: a plain X (cancel, step 1 of a wizard) vs
   an arrow (back, any later step) both fit the same 48px circle without
   a new class - the icon itself (passed as HTML) decides which it reads
   as. */
.fd-sheet-footer-back i { font-size: 16px; }

/* Sep 2026 third follow-up asked for the sheet to float clear above the
   mobile nav pill (`bottom: calc(84px + ...)` below the pill's own
   footprint). Sep 2026 fourth follow-up reversed that explicitly: "the
   pop up should not be placed above the nav but rather over the nav on
   mobile" - i.e. go back to the sheet covering the pill, not floating
   above it with a visible gap. The sheet's z-index (3001) already sits
   above the pill (.vertical-tabs-wrapper, z-index 1000) and
   template-exact.css's base `.bottom-sheet` is already `position:fixed;
   bottom:0`, so reverting is simply *not* overriding `bottom` here -
   no rule needed, this comment is left as a marker of the reversal so a
   future pass doesn't reintroduce the calc(84px...) offset thinking it
   was never tried. */

/* ==========================================================================
   Sep 2026 evaluation-submissions follow-up - icon-only action buttons,
   the desktop popup width bump, and the per-question grading display.
   ========================================================================== */

/* "the copy button remove the color padding round the icon let it be
   just the icon" - a modifier on .btn-sm-add (not a replacement - every
   text-label button on this app, Activate/Close/Publish/Lock/etc., keeps
   its existing solid-pill look unchanged) that strips the background/
   padding down to a bare icon, for buttons whose entire content is one
   <i> and nothing else (Copy link, the new DRAFT-state Edit icon below,
   Online Classes' Copy guest link). Sized to sit comfortably next to the
   pill buttons it shares a row with, not shrunk to the point of being a
   hard tap target on mobile. */
.btn-sm-add.fd-icon-btn {
    background: transparent;
    color: var(--text-muted);
    padding: 8px;
    width: 36px;
    height: 36px;
    justify-content: center;
    border-radius: 10px;
}
.btn-sm-add.fd-icon-btn:hover {
    background: var(--line);
    color: var(--brand-600);
    transform: none;
    box-shadow: none;
}

/* Sep 2026, quoted directly: "on desktop view make the pop up width a
   bit more wider while on mobile u maintain the current width." Only the
   desktop centered-dialog rule (template-exact.css's own
   @media (min-width:769px) block) changes - the mobile bottom-sheet's own
   max-width:520px is untouched, exactly as asked. Widened from 560px to
   720px - comfortably fits the new submissions/grading popup's student
   list and per-question option rows without needing horizontal scroll,
   while still leaving real margin on a typical laptop screen. */
@media (min-width: 769px) {
    .bottom-sheet { width: min(720px, calc(100vw - 64px)); }
    /* 2026-09-12, quoted directly: "please increase the width of the popup
       on desktop it should be quite wide" (the Students-tab class/student
       browsing popup, school-admin people.php - built on the shared
       #fdcSheet, see footer.php's fdcOpenSheet()'s own comment for why
       this is a toggleable class rather than a change to the rule right
       above). Deliberately scoped to ONLY the popup that opts in via
       fdcOpenSheet(..., true) - genuinely spacious next to the 720px
       default (mobile's own bottom-sheet width is untouched either way,
       this whole block only applies at >=769px), not a blanket app-wide
       widening of every other .bottom-sheet popup (the Finance per-class
       popup and the Create Class wizard included), which never asked for
       this and stay at 720px exactly as before. */
    .bottom-sheet.bottom-sheet-wide { width: min(1100px, calc(100vw - 64px)); }
    /* Sep 2026 GCE exam feature, quoted directly: "if its past GCE question
       then a pop up should come up full width dont forget" - the user's own
       "dont forget" flagged that the 1100px .bottom-sheet-wide rule just
       above (added for the Students-tab popup) undershot what "full width"
       should mean for this wizard specifically, so a separate, wider
       modifier was added here at calc(100vw - 32px) - genuinely edge-to-
       edge on most screens.
       Sep 2026 immediate follow-up, quoted directly: "the pop up should be
       wide but not full screen" - calc(100vw - 32px) read as literally
       full-screen on a normal laptop, which wasn't the ask either time.
       Settled between the two: noticeably wider than the shared 1100px
       .bottom-sheet-wide rule (so this wizard still reads as roomier than
       every other popup, per the original request), but capped well short
       of the viewport edge so real page margin is always visible, even on
       a large desktop monitor. Scoped to ONLY the GCE authoring wizard
       (#fdcSheet gets this class instead of .bottom-sheet-wide when
       fdcOpenSheet()'s `wide` argument is the string 'full', not a boolean
       - see footer.php's own comment) - every other popup on the platform
       is completely untouched. */
    .bottom-sheet.bottom-sheet-full { width: min(1320px, calc(100vw - 120px)); }
}

/* Whole-card click target for the new "click an evaluation to see its
   submissions" behavior (evOpenSubmissions() in class_tools.php) - only
   applied via a small inline style on the icon/body of the evaluation
   card itself (not the whole .fd-item-card, so the existing action-row
   buttons underneath keep working as independent clicks, no
   event.stopPropagation() needed anywhere), so this is just the visual
   affordance (pointer cursor + a faint hover tint) rather than new
   layout. */
.fd-item-card-clickable { cursor: pointer; border-radius: 12px; transition: background 0.15s ease; }
.fd-item-card-clickable:hover { background: var(--line); }

/* The submissions popup's own student list row and per-question grading
   block - deliberately its own small set of classes rather than
   overloading .fd-item-card (that component's fixed icon+body+actions
   layout doesn't fit a question's stem + option list + score control). */
.fd-grade-student {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 12px 14px; border: 1px solid var(--line); border-radius: 14px;
    margin-bottom: 8px; cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease;
}
.fd-grade-student:hover { background: var(--line); border-color: var(--brand-600); }
.fd-grade-student-name { font-weight: 600; }
.fd-grade-student-meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.fd-grade-student-chev { color: var(--text-muted); }

.fd-grade-q { padding: 14px; border: 1px solid var(--line); border-radius: 14px; margin-bottom: 12px; }
.fd-grade-q-stem { font-weight: 600; margin-bottom: 10px; }
.fd-grade-opt {
    display: flex; align-items: center; gap: 8px; padding: 8px 10px;
    border: 1px solid var(--line); border-radius: 10px; margin-bottom: 6px; font-size: 13px;
}
.fd-grade-opt i { color: var(--line); }
.fd-grade-opt.selected { border-color: var(--text-muted); }
.fd-grade-opt.correct { background: var(--ok-bg); border-color: var(--ok); }
.fd-grade-opt.correct i, .fd-grade-opt.selected.correct i { color: var(--ok); }
.fd-grade-opt.selected:not(.correct) { background: var(--err-bg); border-color: var(--err); }
.fd-grade-opt.selected:not(.correct) i { color: var(--err); }
.fd-grade-answer-text { background: var(--line); border-radius: 10px; padding: 10px 12px; font-size: 13px; margin-bottom: 10px; white-space: pre-wrap; }

/* =====================================================================
   Sep 2026 follow-up: merged Profile & Settings popup, Wallet popup,
   the bottom-center icon-only Log Out button, and the desktop
   photo-left "My profile" layout. See footer.php (#fdProfileSheet,
   #fdWalletSheet, fdOpenProfileSheet()/fdOpenWalletSheet()/fdLogOut())
   and public/profile.php for the markup these rules style.
   ===================================================================== */

.fd-sheet-loading { text-align: center; padding: 40px 0; color: var(--text-muted); font-size: 14px; }
.fd-sheet-loading i { margin-right: 8px; }

/* "the log out button on the user profile pop up should be placed at the
   center at the very button [bottom]... just an icon - red." Sits below
   the tool grid, inside the same scrollable sheet body - not part of the
   grid itself, so it reads as a distinct, deliberate "leave" action.

   Sep 2026 follow-up, quoted directly: "the user profile popup no longer
   shows the logout icon, which is supposed to be at the center bottom
   with pt-5." The button itself was never removed (see profile.php) -
   what was actually missing was the "pt-5" gap asked for here: at
   `padding: 4px 0 10px 0` this row sat almost flush against the red
   "Delete account" box right above it in the scrollable sheet body, with
   no divider, so it read as part of that box rather than its own
   distinct control and was easy to miss/mistake for "gone". Bootstrap's
   `pt-5` is 3rem (48px); reproduced here directly since this project has
   no Bootstrap spacing classes to reuse, plus a top border so the
   separation is visible even before the extra whitespace registers. */
.fd-sheet-logout-row { display: flex; justify-content: center; padding: 48px 0 16px 0; margin-top: 8px; border-top: 1px solid var(--border-color, #e5e7eb); }
.fd-sheet-logout-btn {
    width: 52px; height: 52px; border-radius: 50%; border: none; cursor: pointer;
    background: linear-gradient(135deg, #e74c3c, #c0392b); color: #fff; font-size: 18px;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 6px 16px rgba(231, 76, 60, 0.35); transition: transform 0.15s ease;
}
.fd-sheet-logout-btn:hover { transform: translateY(-2px); }
.fd-sheet-logout-btn:disabled { opacity: 0.85; cursor: default; transform: none; }

/* ---- "My profile" desktop photo-left layout ---- */
.fd-profile-layout { display: flex; flex-direction: column; gap: 20px; align-items: stretch; }
.fd-profile-photo-col {
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px;
    background: var(--brand-20); border-radius: 20px; padding: 24px 16px; flex-shrink: 0;
}
.fd-profile-photo {
    position: relative; width: 140px; height: 140px; border-radius: 50%; overflow: hidden;
    background: var(--brand-600); display: flex; align-items: center; justify-content: center;
    cursor: pointer; flex-shrink: 0;
}
.fd-profile-photo img { width: 100%; height: 100%; object-fit: cover; }
.fd-profile-photo-initials { color: #fff; font-weight: 700; font-size: 44px; }
.fd-profile-photo-edit {
    position: absolute; left: 0; right: 0; bottom: 0; padding: 6px 4px; font-size: 10px; font-weight: 600;
    background: rgba(0,0,0,0.55); color: #fff; opacity: 0; transition: opacity 0.15s ease;
}
.fd-profile-photo:hover .fd-profile-photo-edit, .fd-profile-photo:focus-within .fd-profile-photo-edit { opacity: 1; }
.fd-profile-photo-name { font-weight: 700; font-size: 16px; }
.fd-profile-photo-email { font-size: 12px; color: var(--text-muted); word-break: break-word; }
.fd-profile-info-col { flex: 1; min-width: 0; }

/* Desktop (>=769px, matching the app's own bottom-sheet/desktop-dialog
   breakpoint): photo column becomes a fixed-width left rail that
   stretches to the full height of the info column beside it - the
   literal "photo should take the entire height" ask. */
@media (min-width: 769px) {
    .fd-profile-layout { flex-direction: row; align-items: stretch; }
    .fd-profile-photo-col { width: 220px; justify-content: center; }
    .fd-profile-photo { width: 160px; height: 160px; }
}

/* ---- Wallet popup ---- */
.fd-wallet-tabs { display: flex; overflow-x: auto; gap: 6px; padding-bottom: 8px; margin-bottom: 14px; border-bottom: 1px solid var(--line); }
.fd-wallet-tab {
    flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 8px 14px; border: none; background: transparent; color: var(--text-muted);
    font-size: 11px; font-weight: 600; border-radius: 12px; cursor: pointer; font-family: inherit;
}
.fd-wallet-tab i { font-size: 16px; }
.fd-wallet-tab.active { background: var(--brand-20); color: var(--brand-600); }
.fd-wallet-panel { padding-bottom: 8px; }
.fd-wallet-qr-wrap { display: flex; justify-content: center; padding: 12px; background: #fff; border-radius: 16px; margin-bottom: 12px; }
.fd-wallet-qr-wrap svg { width: 180px; height: 180px; }
.fd-wallet-receive-code {
    text-align: center; font-family: monospace; font-size: 13px; background: var(--line);
    border-radius: 10px; padding: 10px; margin-bottom: 12px; word-break: break-all;
}
.fd-wallet-history { display: flex; flex-direction: column; gap: 4px; }
.fd-wallet-history-row { display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 12px; }
.fd-wallet-history-row:hover { background: var(--line); }
.fd-wallet-history-icon {
    width: 34px; height: 34px; border-radius: 50%; background: var(--brand-20); color: var(--brand-600);
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.fd-wallet-history-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fd-wallet-history-title { font-weight: 600; font-size: 13px; }
.fd-wallet-history-sub { font-size: 11px; color: var(--text-muted); }
.fd-wallet-history-amt { font-weight: 700; font-size: 13px; white-space: nowrap; }

/* Sep 2026 "while on mobile lets put the subjects in a horizonal row
   which is scrollable horizontally and should fit 6 that is col-2." A
   modifier on .chip-select-grid (opt-in via .fd-chip-grid-scroll, applied
   only to the Create Class wizard's subject grid - see footer.php's
   fdCreateClassStep2()) so the class/series pickers and the Billing
   gateway picker elsewhere, which also reuse the bare .chip-select-grid,
   are completely unaffected. Mobile only, per the ask - desktop keeps the
   existing vertical list. 16.6667% = Bootstrap's own col-2 width, so
   exactly 6 tiles fill one screen-width before the 7th peeks in from the
   edge as the scroll affordance. */
@media (max-width: 768px) {
    .chip-select-grid.fd-chip-grid-scroll {
        display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 8px;
        -webkit-overflow-scrolling: touch; padding-bottom: 6px;
    }
    .chip-select-grid.fd-chip-grid-scroll .chip-select {
        flex: 0 0 16.6667%; min-width: 0;
        flex-direction: column; justify-content: center; text-align: center;
        padding: 8px 2px; font-size: 10px; gap: 4px; border-radius: 12px;
    }
    .chip-select-grid.fd-chip-grid-scroll .chip-select .chip-icon { margin: 0 auto; }
    .chip-select-grid.fd-chip-grid-scroll .chip-select span { white-space: normal; line-height: 1.15; }
    /* No room for the trailing checkmark in a col-2 tile - selection is
       still clearly shown via the existing .selected background/border. */
    .chip-select-grid.fd-chip-grid-scroll .chip-select i.chip-check { display: none; }
}

/* =====================================================================
   E-LEARNING STYLE EVALUATION-TAKING UI
   Sep 2026, quoted directly: "redesign the student evaluation-taking...
   pages in an e-learning style." One question at a time (progressively
   enhanced - see core_system_files/js/fd-quiz.js's own top comment for
   the no-JS fallback: every .fd-quiz-question renders visible in the
   markup with no `hidden` attribute at all), a progress bar, a clickable
   question-navigator strip (mirrors the .fd-tool-tab-grid horizontal-
   scroll-on-mobile pattern already used elsewhere in this file), and a
   countdown timer for timed assessments. Shared by public/student/
   assessment_attempt.php and public/student/attempt.php via
   core_system_files/partials/quiz_ui.php's fd_render_quiz_questions();
   public/share/assessment.php (the unauthenticated guest page, which has
   no header.php/footer.php and so never loads this stylesheet) carries
   its own copy of these rules inline instead.
   ===================================================================== */
.fd-quiz-wrap { max-width: 720px; margin: 0 auto; }
.fd-quiz-progress-track { height: 8px; border-radius: var(--r-pill); background: var(--brand-100); overflow: hidden; margin-bottom: 14px; }
.fd-quiz-progress-fill { height: 100%; background: linear-gradient(90deg, #6C63FF, #5849D6); border-radius: var(--r-pill); transition: width .25s ease; }
.fd-quiz-meta-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; flex-wrap: wrap; gap: 8px; }
.fd-quiz-counter { font-size: 13px; font-weight: 700; color: var(--brand-600); }
.fd-quiz-timer { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; padding: 5px 12px; border-radius: var(--r-pill); background: var(--ok-bg); color: var(--ok); }
.fd-quiz-timer.fd-quiz-timer-warn { background: var(--err-bg); color: var(--err); }
.fd-quiz-nav { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 6px; margin-bottom: 18px; scrollbar-width: none; }
.fd-quiz-nav::-webkit-scrollbar { display: none; }
.fd-quiz-nav-dot {
    flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
    border: 1.5px solid var(--brand-150); background: var(--surface, #fff);
    color: var(--brand-600); font-size: 12.5px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.fd-quiz-nav-dot.answered { background: var(--brand-100); border-color: var(--brand-500); }
.fd-quiz-nav-dot.current { background: linear-gradient(135deg, #6C63FF, #5849D6); border-color: transparent; color: #fff; }
.fd-quiz-qcard {
    background: var(--surface, #fff); border-radius: var(--r-md); padding: 22px;
    box-shadow: 0 2px 12px rgba(88,73,214,0.07); margin-bottom: 20px;
}
.fd-quiz-qnum { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--brand-500); margin-bottom: 6px; }
.fd-quiz-stem { font-size: 16px; margin: 0 0 16px; }
.fd-quiz-opts { display: flex; flex-direction: column; gap: 10px; }
.fd-quiz-opt {
    display: flex; align-items: center; gap: 10px; padding: 12px 14px;
    border-radius: 12px; border: 1.5px solid var(--brand-150); cursor: pointer;
    font-size: 14px; transition: border-color .15s, background .15s;
}
.fd-quiz-opt:hover { border-color: var(--brand-500); }
.fd-quiz-opt input { accent-color: #5849D6; width: 17px; height: 17px; flex: 0 0 auto; }
.fd-quiz-opt:has(input:checked) { border-color: var(--brand-500); background: var(--brand-25); }
.fd-quiz-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
.fd-quiz-actions .btn-sm-add.ghost { background: var(--surface, #fff); color: var(--brand-600); border: 1.5px solid var(--brand-150); }
@media (max-width: 640px) {
    .fd-quiz-qcard { padding: 16px; }
    .fd-quiz-nav-dot { width: 30px; height: 30px; font-size: 11.5px; }
}

/* =====================================================================
   E-LEARNING STYLE JOIN-A-CLASS (DISCOVER) CATALOG
   Sep 2026, quoted directly: "redesign the... join-a-class page in an
   e-learning style." public/discover.php's plain data table of public
   classes is now a searchable grid of course-style cards - same tone-
   gradient header/tint palette public/teacher/index.php's own dashboard
   class cards use (fd-dash-class-card2), so a class reads consistently
   whether a teacher sees it on their dashboard or a student browses to
   join it, without inventing a second palette.
   ===================================================================== */
.fd-discover-hero {
    display: flex; align-items: flex-start; gap: 16px;
    background: var(--brand-25); border: 1px solid var(--brand-150);
    border-radius: var(--r-md); padding: 20px; margin-bottom: 24px;
}
.fd-discover-hero-icon {
    flex: 0 0 auto; width: 48px; height: 48px; border-radius: 14px;
    background: linear-gradient(135deg, #6C63FF, #5849D6); color: #fff;
    display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.fd-discover-hero-body { flex: 1 1 auto; min-width: 0; }
.fd-discover-hero-body h3 { margin-top: 0; }
.fd-discover-code-form { display: flex; gap: 10px; max-width: 420px; flex-wrap: wrap; }
.fd-discover-code-form .form-control { flex: 1 1 220px; }
.fd-discover-catalog-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.fd-discover-catalog-head h3 { margin: 0; }
.fd-discover-search { max-width: 320px; }
.fd-discover-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 18px; }
.fd-discover-card {
    border-radius: var(--r-md); overflow: hidden; display: flex; flex-direction: column;
    box-shadow: var(--shadow-card); transition: transform .15s, box-shadow .15s;
}
.fd-discover-card:hover { transform: translateY(-3px); }
.fd-discover-card-top {
    position: relative; height: 74px; display: flex; align-items: center; justify-content: center;
    color: rgba(255,255,255,0.85); font-size: 28px;
}
.fd-discover-price { position: absolute; top: 10px; right: 10px; }
.fd-discover-price-free { background: rgba(255,255,255,0.25); color: #fff; }
.fd-discover-card-body { background: var(--surface, #fff); padding: 16px; flex: 1 1 auto; display: flex; flex-direction: column; gap: 8px; }
.fd-discover-card-title { margin: 0; font-size: 15px; }
.fd-discover-card-desc { margin: 0; font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.fd-discover-card-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.fd-discover-card-teacher { font-size: 12.5px; color: var(--text-muted); display: flex; align-items: center; gap: 6px; }
.fd-discover-card-cta { margin-top: auto; padding-top: 6px; }
@media (max-width: 640px) {
    .fd-discover-hero { flex-direction: column; }
    .fd-discover-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
}

/* =====================================================================
   CREATE CLASS WIZARD - SUBJECT PICKER RESTYLE + SHARE STEP
   Sep 2026, quoted directly: "restyle the subject picker - one per line,
   full width, icons, light colors." Replaces the compact .chip-select-grid
   this step used for the Create Class wizard's Subject step only (the
   Class step's existing-class picker keeps its own compact grid unchanged
   - only the subject list was called out) with a plain full-width list of
   rows, so a long subject name is never truncated in a small tile.
   ===================================================================== */
.fd-subject-picker-list { display: flex; flex-direction: column; gap: 8px; max-height: 320px; overflow-y: auto; margin-bottom: 4px; }
.fd-subject-picker-row {
    display: flex; align-items: center; gap: 12px; width: 100%;
    background: var(--brand-25); border: 1.5px solid transparent; border-radius: 12px;
    padding: 12px 14px; font-size: 14px; font-weight: 600; color: var(--text, #2B2A3D);
    text-align: left; cursor: pointer; transition: border-color .15s, background .15s;
}
.fd-subject-picker-row:hover { border-color: var(--brand-200); }
.fd-subject-picker-row.selected { background: var(--brand-100); border-color: var(--brand-500); }
.fd-subject-picker-icon {
    flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px;
    background: var(--brand-100); color: var(--brand-600);
    display: flex; align-items: center; justify-content: center; font-size: 14px;
}
.fd-subject-picker-row.selected .fd-subject-picker-icon { background: var(--brand-500); color: #fff; }
.fd-subject-picker-name { flex: 1 1 auto; min-width: 0; }
.fd-subject-picker-check { flex: 0 0 auto; opacity: 0; color: var(--brand-500); font-size: 16px; transition: opacity .15s; }
.fd-subject-picker-row.selected .fd-subject-picker-check { opacity: 1; }

/* Sep 2026 UI-bug follow-up: "the tutor should be able to select multiple
   subjects" - the small removable chip row (footer.php's
   fdCreateClassRenderPickedSubjects()) under the Create Class wizard's
   Subject step, listing every subject picked so far (catalog rows and
   typed custom names alike) with its own "x" to undo one pick. */
.fd-picked-subject-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 10px 0; }
.fd-picked-subject-chip {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--brand-100); color: var(--brand-600);
    border-radius: 999px; padding: 5px 6px 5px 12px; font-size: 12.5px; font-weight: 600;
}
.fd-picked-subject-chip button {
    border: none; background: var(--brand-500); color: #fff; width: 18px; height: 18px;
    border-radius: 50%; display: flex; align-items: center; justify-content: center;
    font-size: 9px; cursor: pointer; flex: 0 0 auto;
}
.fd-picked-subject-chip button:hover { background: var(--brand-600); }

/* Sep 2026 follow-up, quoted directly: "the user profile pop up can not
   be openned on desktop so that means people on desktop can not logout."
   #fdDesktopProfileGap (header.php) bridges the real gap between the two
   existing, working profile-access systems: .vertical-icons-right (the
   desktop rail) only renders at min-width 1481px (template-exact.css),
   and .mobile-top-nav only renders at max-width 768px - leaving every
   ordinary laptop/desktop width in between (769px-1480px) with no way to
   reach the profile popup/Logout at all. Hidden outside that exact range
   so neither existing system's own behavior changes even slightly. Reuses
   .rail-dark-toggle's own circle-button look (see template-exact.css) -
   positioned top-right instead of mid-right so it can't collide with
   page content the way the wider desktop rail used to (the very overlap
   .vertical-icons-right's own 1480px cutoff exists to avoid). */
#fdDesktopProfileGap {
    display: none;
    position: fixed;
    top: 14px;
    right: 14px;
    z-index: 1001;
}
@media (min-width: 769px) and (max-width: 1260px) {
    #fdDesktopProfileGap {
        display: flex;
    }
}

/* ==========================================================================
   Sep 2026 Education Catalog reorganize round, quoted directly: "to reduce
   scrolling can we use two items per row to display the classes or subjects
   or options." A plain, always-2-column grid - deliberately NOT a reuse of
   .fd-dash-class-grid/.fd-teacher-subject-grid (both auto-fill/horizontal-
   scroll shapes elsewhere in this file, "as many as fit" rather than a
   literal "two per row") - collapsing to a single column only on genuinely
   narrow/mobile widths so a card (name + description + Edit/Delete) never
   gets too cramped to read. Used by education_catalog.php's Secondary
   Classes/Series/Subjects panels. ========================================================================== */
.fd-catalog-grid2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    margin-bottom: 8px;
}
@media (max-width: 560px) {
    .fd-catalog-grid2 { grid-template-columns: 1fr; }
}
.fd-catalog-card {
    position: relative;
    background: var(--brand-25);
    border: 1px solid var(--brand-100);
    border-radius: var(--r-lg);
    padding: 16px 16px 14px 16px;
}
html[data-theme="dark"] .fd-catalog-card { background: var(--surface); border-color: var(--line); }
.fd-catalog-card-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 6px; }
.fd-catalog-card-icon {
    width: 38px; height: 38px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 15px; color: #fff; flex: 0 0 auto;
    background: var(--grad-brand, linear-gradient(135deg, var(--brand-500), var(--brand-600)));
}
.fd-catalog-card-name { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 15px; color: var(--text); word-break: break-word; }
.fd-catalog-card-meta { font-size: 11.5px; color: var(--text-muted); }
.fd-catalog-card-desc { font-size: 12.5px; color: var(--text-muted); margin: 0 0 10px 0; line-height: 1.4; }
.fd-catalog-card-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.fd-catalog-empty { padding: 20px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* Small in-popup "Manual vs Bulk upload" pill toggle - the "Add" popups on
   the Secondary Classes/Series/Subjects panels each hold both add methods
   inside the SAME sheet (quoted directly: "there should always be a pop up
   for the upload"), switched here rather than a full class_tools-style
   tab-card set (too heavy for a two-way in-form choice this small). */
.fd-mini-toggle { display: flex; gap: 8px; margin-bottom: 16px; }
.fd-mini-toggle button {
    flex: 1 1 0;
    padding: 9px 10px;
    border-radius: var(--r-md, 10px);
    border: 1px solid var(--brand-150, var(--brand-100));
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.fd-mini-toggle button.active { background: var(--brand-500); border-color: var(--brand-500); color: #fff; }

/* Sep 2026 Education Catalog reorganize round - "each class should also
   have an edit and a delete button" - a red-tinted modifier on .btn-sm-add
   (same shape, not a replacement, matching the .fd-icon-btn modifier
   precedent above) for the new grid cards' Delete action specifically, so
   it visually reads as destructive without a whole separate button style. */
.btn-sm-add.btn-sm-danger { background: #E03131; }
.btn-sm-add.btn-sm-danger:hover { background: #C92A2A; }

/* ==========================================================================
   Sep 2026 (2026-09-13), quoted directly: "lets try a new ui layout. lets
   move all the tabs in each menu to be place vertically few pixels from
   the menu itself so for example if i click finance i should have a
   beautiful menu vertically between the nav menu pill and the main
   warpper for desktops view then for mobile view this tabs will open
   loading above the bottom nav." Applies only on the 7 pages that wrap
   their existing .fd-tool-tab-grid + .fd-tool-panel siblings in two
   wrappers (finance.php, academics.php, engagement.php, assessment.php,
   people.php, class_tools.php, subject_tools.php - see each file's own
   wrap comment): <div class="fd-tab-layout"> around the grid AND all the
   panels, <div class="fd-tool-panel-stack"> around just the panels. Every
   selector below is scoped under .fd-tab-layout (or is a brand-new class)
   so .fd-tool-tab-grid/.fd-tool-tab-card's EXISTING rules above keep
   working unchanged anywhere else they're already reused (GCE exam wizard
   step-pickers, education-catalog grids, etc.). fdShowToolTab() (each
   page's own copy) is completely untouched throughout everything below.

   Sep 2026 (2026-09-13) SAME-DAY FOLLOW-UP, quoted directly: "ok the tabs
   are great on desktop but make sure it stays in place while the page
   scroll also increase the width of the main wrapper abit and also give
   an other one where the tabs are outside of the main wrapper card. then
   for mobile the tabs should be horizontally diretclly ontop the bottom
   nav pill and scrollable horizontally." This follow-up rewrote most of
   the block below - see the three dated sub-comments further down for
   each specific change (manual sticky fix, inside/outside toggle, mobile
   strip). The old mobile drawer (#fdTabDrawer + its trigger button) this
   block used to also define is gone outright, not just unused - the
   drawer's markup was removed from footer.php and its JS
   (fdOpenTabDrawer/fdCloseTabDrawer/fdTabLayoutSyncTrigger) replaced
   there; mobile no longer needs a popup, see the new mobile section at
   the bottom of this block. */
.fd-tab-layout {
    display: flex;
    align-items: flex-start;
    gap: 24px;
}
.fd-tool-panel-stack { flex: 1 1 auto; min-width: 0; width: 100%; }

/* ---------------------------------------------------------------------
   DESKTOP (>=769px) - sidebar list + manual sticky-replacement.
   Desktop: .fd-tool-tab-grid turns into a vertical sidebar list sitting
   in the content column, right after the app's own nav rail
   (.vertical-tabs-wrapper - the "nav menu pill", template-exact.css) and
   before .fd-tool-panel-stack's content - i.e. exactly "vertically
   between the nav menu pill and the main wrapper" since .fd-tab-layout is
   simply the existing content column laid out as two flex columns
   instead of one. Each card becomes a list-item row via CSS grid
   placement alone (icon spans both rows on the left, name+desc stacked to
   its right) - no markup change to the cards' own icon/name/desc spans.
--------------------------------------------------------------------- */
@media (min-width: 769px) {
    .fd-tab-layout .fd-tool-tab-grid {
        flex: 0 0 232px;
        width: 232px;
        flex-direction: column;
        gap: 8px;
        margin: 4px 0 0 0;
        overflow: visible;
        /* Sep 2026 (2026-09-13) follow-up, quoted directly: "make sure it
           stays in place while the page scroll." This position:sticky
           never actually worked - .form-container (template-exact.css)
           sets `overflow: hidden`, a well-known CSS gotcha that silently
           breaks position:sticky on any descendant, and widening that
           rule is out of scope (it's shared by ~50 other pages that rely
           on it to clip rounded-corner content). Left here as an inert,
           harmless fallback only; footer.php's fdStickyApply() (guarded
           to no-op without #fdToolTabGrid) does the REAL work below by
           manually toggling .fd-tool-tab-grid-fixed once the page has
           scrolled past the grid's natural top - see that class below
           and footer.php's own comment for the full mechanism. top:20px
           here is also the exact value fdStickyApply() itself uses
           (FD_STICKY_TOP_GAP) so both agree. */
        position: sticky;
        top: 20px;
        align-self: flex-start;
    }
    /* JS-driven sticky replacement (footer.php: fdStickyApplyInside()).
       Higher specificity than the (inert) rule above via the extra class,
       so this wins the instant footer.php adds it. left/width/top are all
       set inline by footer.php, re-measured every scroll/resize tick from
       a placeholder element (.fd-tool-tab-grid-placeholder, inserted at
       the same moment) rather than cached once, so a browser resize or a
       taller/shorter panel after switching tabs can never leave it
       misaligned. */
    .fd-tab-layout .fd-tool-tab-grid.fd-tool-tab-grid-fixed {
        position: fixed;
        z-index: 5;
    }
    .fd-tool-tab-grid-placeholder {
        flex: 0 0 auto;
    }
    .fd-tab-layout .fd-tool-tab-card {
        display: grid;
        grid-template-columns: auto 1fr;
        grid-template-rows: auto auto;
        align-items: center;
        column-gap: 14px;
        row-gap: 1px;
        width: 100%;
        text-align: left;
        padding: 12px 14px;
        border-radius: 16px;
    }
    .fd-tab-layout .fd-tool-tab-card:hover { transform: translateX(3px); }
    .fd-tab-layout .fd-tool-tab-icon {
        grid-column: 1;
        grid-row: 1 / 3;
        width: 42px;
        height: 42px;
        font-size: 17px;
        margin: 0;
    }
    .fd-tab-layout .fd-tool-tab-name { grid-column: 2; grid-row: 1; margin-bottom: 0; }
    .fd-tab-layout .fd-tool-tab-desc { grid-column: 2; grid-row: 2; }

    /* 2026-09-14, quoted directly: "also on the desktop view this part
       '<div class="fd-tool-panel-stack ">' add p-5 or p-6." Desktop-only -
       the mobile block further down sets its own `padding-bottom` on this
       same class for a completely different reason (clearing the fixed
       tab strip above the dock), so this is scoped to this file's own
       existing `@media (min-width:769px)` block rather than touching that
       mobile rule. 24px is the p-6 end of the two options given (a
       Tailwind-style scale: p-5=20px, p-6=24px), applied on every side so
       panel content also gets breathing room from the tab sidebar beside
       it, not just the wrapper's own edges.
       2026-09-14 follow-up, quoted directly: "add p-5 to this on desktop
       view." The earlier round used p-6 (24px, the larger of the two
       options originally offered); this round asks specifically for p-5 -
       24px -> 20px, same scale, same scoping, nothing else changed. */
    .fd-tab-layout .fd-tool-panel-stack { padding: 20px; }

    /* 2026-09-13 FIFTH same-day follow-up, quoted directly: "we will go
       with inner card." The inside/outside toggle pill
       (.fd-tab-layout-style-toggle) and the entire "outside card"
       variant (.fd-tab-layout--outside .fd-tool-tab-grid/
       .fd-tool-panel-stack) that used to live here are deleted outright,
       not just disabled - the experiment is settled, matching this
       file's own established practice of removing a superseded
       mechanism rather than leaving unused CSS behind (the old mobile
       drawer rules got the same treatment a few rounds back). Only the
       "inside" sidebar above survives; #fdToolTabGrid never gets an
       --outside modifier applied to anything any more. */
}

/* ---------------------------------------------------------------------
   2026-09-13 FIFTH same-day follow-up, quoted directly: "also update
   this on the tempate-exact: .main-wrapper { max-width: 1500px; ...}."
   template-exact.css's own `.main-wrapper` is now 1500px platform-wide
   (see that file's own dated comment on the rule itself, and its own
   nav-rail/right-icon formula update right below it - both edited
   directly this round, by explicit instruction, for the first time since
   this feature began).
   That single change makes the entire `.fd-wide-wrapper` opt-in
   mechanism this block used to hold (a special, JS/PHP-flagged 1300px ->
   1400px override for just 13 pages, invented specifically so the other
   ~50 pages' shared `.main-wrapper` rule in template-exact.css could stay
   untouched) obsolete: the platform default is now EQUAL TO OR WIDER
   than what this override used to provide, so keeping it would have
   actively SHRUNK these 13 pages back down below the new platform-wide
   width - the opposite of the intent. Deleted outright (not left inert)
   along with the outside-mode `:has()` twin that used to sit here, per
   this codebase's standing practice of removing a superseded mechanism
   rather than leaving unused code behind. `$fdWideWrapper`/
   `.fd-wide-wrapper` are likewise removed from header.php and all 13
   pages that used to set the flag (see those files' own history) -
   there is nothing left for the class to do. */

/* ---------------------------------------------------------------------
   2026-09-13 FIFTH same-day follow-up: the `body:has(.fd-wide-wrapper)`/
   `body:has(.fd-tab-layout--outside)` nav-rail/right-icon override rules
   that used to live here (added SAME-DAY FOLLOW-UP #2, to compensate for
   just 13 pages having a wider `.main-wrapper` than the platform-wide
   template default) are deleted for the same reason as the block above:
   template-exact.css's own `.vertical-tabs-wrapper`/`.vertical-icons-
   right` formulas were updated directly, in lockstep with its new
   1500px `.main-wrapper`, so EVERY page platform-wide now gets correct,
   non-overlapping rail/icon positioning straight from the vendor
   stylesheet itself - no per-page override needed, and no `.fd-wide-
   wrapper`/`.fd-tab-layout--outside` class left to key one off anyway. */

/* ---------------------------------------------------------------------
   MOBILE (<=768px), quoted directly: "for mobile the tabs should be
   horizontally diretclly ontop the bottom nav pill and scrollable
   horizontally." Replaces last round's drawer+trigger entirely - no JS
   needed any more (simpler than last round, not more complex): the SAME
   #fdToolTabGrid/.fd-tool-tab-card elements are just repositioned fixed
   above the bottom nav by CSS alone, still driven only by each page's own
   unmodified fdShowToolTab(). .fd-tab-layout itself stays a simple
   full-width block (no sidebar column) exactly as before. Because
   nothing more specific than the base (unscoped) .fd-tool-tab-grid/
   .fd-tool-tab-card rules near the top of this file apply below 769px
   any more (the desktop-only overrides above are now confined inside
   their own @media (min-width:769px) block), the cards automatically
   fall back to that base horizontal-scroll-strip look/sizing (~line
   750-789 above) unchanged - exactly "adapting the ORIGINAL horizontal
   design" rather than inventing new card styling.
   bottom: 74px matches .vertical-tabs-wrapper's own mobile dock
   (template-exact.css: fixed bottom:14px, ~48-60px tall including its
   own padding at this width, so 14+60=~74px total) - same math the old
   drawer comment already used. z-index: 1500 is comfortably above the
   dock's 1000 but well below the existing sheet stack's 9000/9001
   (template-exact.css .sheet-backdrop/.bottom-sheet), matching that same
   layering precedent instead of inventing new numbers from scratch. */
@media (max-width: 768px) {
    .fd-tab-layout { display: block; }
    /* 2026-09-13 FIFTH same-day follow-up - mobile stacking-context bug,
       quoted directly: "when i click on a menu the nav tabs does not
       show exactly just above the menu it shows under like z-index
       issues." Root cause: .main-wrapper (template-exact.css) carries
       `position: relative; z-index: 1;`, which creates a stacking
       context that traps every descendant - including this position:
       fixed grid, no matter how high ITS OWN z-index is set - below the
       bottom-nav dock's real top-level z-index:1000, since the dock is a
       true top-level sibling of .main-wrapper while this grid used to be
       nested (.fd-tab-layout > #fdToolTabGrid) inside .main-wrapper's
       own, much lower (1) top-level stacking position. No z-index value
       set on a trapped descendant can ever out-rank a separate sibling's
       own top-level order.
       Fix: footer.php's fdTabGridSyncPortal() now reparents
       #fdToolTabGrid to be a direct child of <body> the instant mobile
       width is detected - a true top-level sibling of the dock, outside
       .main-wrapper's stacking context entirely - so the selector below
       targets the ID directly rather than ".fd-tab-layout .fd-tool-tab-
       grid": once portaled, the grid is no longer a descendant of
       .fd-tab-layout at all, so that old descendant selector would
       silently stop matching. `#fdToolTabGrid` matches wherever the
       element currently lives, before or after the JS moves it, and
       stays exactly as scoped to these 13 pages as before (nothing else
       platform-wide uses this id). `.fd-tool-panel-stack` is NOT
       reparented (only the grid/tab-card row needs to escape - the
       panels themselves never needed to rise above the dock), so its own
       selector below is untouched. */
    /* 2026-09-13 SIXTH/SEVENTH same-day follow-ups (superseded below,
       2026-09-14): two rounds tried to make the closed sheet exactly
       match the bottom-nav dock's own inset-pill shape (so a slide-up
       animation would blend into it) via a live-measured
       `--fd-tab-sheet-dock-h` CSS custom property, then fixed a horizontal-
       scroll regression the first attempt introduced. Both fixed real bugs
       at the time; both are moot now that the closed state is simply
       `display:none` (see the 2026-09-14 comment immediately below) -
       nothing is left to shape-match against, and there's no CSS var/
       measurement left to regress. Kept only as a pointer for anyone
       reading README.md's own dated history of this feature. */
    /* 2026-09-14 (prior same-day round, superseded immediately below):
       "lets remove the slide effect for now... currently the tabs are
       just visible and this makes the main menu on mobile unaccessible."
       Dropped the animation for a plain `display:none` <-> `display:flex`
       toggle on tap. Fixed that round's own bug, but the very next
       message asked to go further still - see the 2026-09-14 FOLLOW-UP
       comment right below. */
    /* 2026-09-14 FOLLOW-UP, quoted directly: "lets make sure that if a
       menu has tabs it should be visible at once when the menu is clicked
       and no need to hide again, then we can bring the tabs alittle
       closer to the menu and let the tabs and active menu have same
       background that is linked for example the background of the active
       menu flows and joins the tabs."
       1. "visible at once ... no need to hide again": there is no more
          open/closed STATE at all - #fdToolTabGrid is simply always
          `display:flex` on any of these 13 pages, on every mobile visit,
          the instant the page (or tab-shell panel) loads. footer.php's
          click-to-toggle handler (`fdTabSheetInit()` - intercepted a tap
          on the already-active dock icon and flipped a `.fd-tab-sheet-
          open` class) is removed outright along with that class: tapping
          the active icon is now just what it always was on every OTHER
          page - a harmless, redundant self-navigation - since there is no
          hidden state left for it to reveal.
       2. "bring the tabs a little closer to the menu": `bottom` tightened
          from 96px to 80px - the dock's own top edge sits at ~82px from
          the viewport bottom (14px inset + ~68px content height), so this
          leaves only a couple of px of breathing room instead of a
          visible 14px gap, without the two boxes actually touching/
          overlapping.
       3. "same background that is linked ... flows and joins": FIRST
          attempt made this strip match the dock's own purple
          (`var(--brand-600)`, was `var(--surface)`). Follow-up clarified
          the actual ask: "the light gray color of the active menu should
          be the background color of the tabs" - i.e. not the whole purple
          dock, but a NEW light-gray highlight chip added to the
          currently-ACTIVE dock icon specifically (template-exact.css's
          `.vertical-tab.gactive`, mobile only - see the dated comment
          there), reused here as this strip's background. THIRD follow-up,
          quoted directly: "there should be no purple separation between
          the active menu and its tabs" - even with matching colors, a
          sliver of the dock's own purple top padding was still visible
          between this strip's bottom edge and the active icon's chip
          underneath it (the strip stopped 2px short of the dock's outer
          top edge, and the icon itself sits inset a further 6-8px inside
          the dock's own padding - see `bottom`/`z-index` below for the
          fix). Reuses the existing `--fd-card-bg` token throughout (a
          genuinely neutral light gray - #F4F4F6 light theme / #24213D
          dark theme - already used elsewhere in this file for table row
          striping) rather than inventing a new color. The individual
          tab-cards keep their own existing `var(--brand-20)` background
          (near-white #F8F8FF light / dark-purple #221F3F dark, unchanged)
          - close in value to the new gray strip background in light theme
          (a subtle white-card-on-gray-surface look) and clearly distinct
          from it in dark theme. */
    #fdToolTabGrid {
        display: flex;
        position: fixed;
        left: 14px;
        right: 14px;
        /* "no purple separation" fix: this used to stop at 80px (a couple
           px short of the dock's own top OUTER edge at ~82px), leaving the
           dock's own 6-8px of inner top padding - solid purple, above the
           active icon's chip but below this strip - fully visible in
           between. 68px reaches all the way up to the active icon's own
           TOP edge (i.e. past the dock's padding entirely) for the default
           mobile range (481-768px wide: 14px dock inset + 6px dock padding
           + 48px icon height = the icon's top sits 68px above the
           viewport bottom) - see the two breakpoint overrides right after
           this block's closing brace for the two narrower ranges, where
           the dock's own padding/icon-height numbers differ and so does
           this value. */
        bottom: 68px;
        /* Raised above the dock's own z-index:1000 (was 950, i.e. BELOW
           the dock) specifically so this strip's now-deeper overlap
           renders ON TOP of the dock's purple padding instead of being
           clipped behind it - the mechanism that actually erases the
           purple sliver, not just the repositioning above. Both elements
           are true top-level children of <body> (fdTabGridSyncPortal()'s
           reparenting), so this is a simple, safe reordering with nothing
           else at this z-index for it to conflict with. */
        z-index: 1001;
        margin: 0;
        padding: 8px 10px;
        background: var(--fd-card-bg);
        /* FOLLOW-UP, quoted directly: "the bottom right border radius of
           the tab shows a purple underneath making it feel like two
           different blocks... all the borders... should be connected and
           as one block continuous not two blocks trying to join." This
           strip's own bottom-left/bottom-right corners were still rounded
           (18px, same as the top), so whichever tool-tab happens to sit
           near either end of the row got a curved edge above it instead
           of the flat one the active icon's own now-flattened top corners
           (template-exact.css, .vertical-tab.gactive) were built to
           continue - the mismatch is exactly what revealed a sliver of
           the dock's purple there, breaking the "one block" illusion for
           any active tab close to either edge (last round's screenshot
           happened to test the FIRST icon, where the strip's rounded
           corner sits well clear of it, so this didn't show up then).
           Squaring off just the bottom two corners makes the strip's
           entire bottom edge one flat line, full width, with no curve
           anywhere along it - so it continues flush into the flattened
           active-icon chip no matter which tab is active, left, middle,
           or right, without needing to know or track its position. */
        /* FOLLOW-UP, quoted directly: "can we make the edging alittle
           round on these edges: the 90 degrees edges to be alittle
           rounded rather than 90 degrees direct." The hard 0 above was
           more literal than needed - softened to a small 6px on just
           these two corners (matching the same 6px now used on the active
           icon's own top corners, template-exact.css), kept well below
           the 18px this strip's TOP corners (and the old bottom corners,
           before the "one block" fix) used - small enough that it still
           reads as one continuous surface rather than reintroducing the
           two-blobs pinch, re-verified via pixel-sampling with the active
           tab in first/middle/last position (same method/positions as the
           original corner-radius bug this whole area came from). */
        border-radius: 18px 18px 6px 6px;
        /* FOLLOW-UP, quoted directly (twice): "it still does not flow...
           i can immediately tell those are two different pieces." Color
           and shape now genuinely match at the seam (verified pixel-by-
           pixel, see the two comments above) - what was still giving this
           away is a drop shadow, which is a universal visual cue for "this
           thing floats above, and is separate from, whatever is behind
           it." A floating-card shadow made sense when there was a real gap
           between this strip and the dock; now that they deliberately
           touch/overlap as one surface, keeping that shadow actively works
           against the "one continuous body" goal - it's the shadow, not
           the color, that was still saying "these are two things." Removed
           outright rather than softened, since any residual shadow at all
           re-introduces the same cue. The dock's own `box-shadow: var(
           --shadow-dock)` (template-exact.css, mobile) is a downward
           shadow (positive y-offset) cast BELOW the dock, away from this
           strip, so it was never part of this problem and is untouched. */
        box-shadow: none;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
    }
    /* FOLLOW-UP, continued: the individual active tab-card inside this
       strip (`.fd-tool-tab-card.active`, a platform-wide rule reused on
       ~13 other pages' own inline tool-tab grids, NOT mobile-specific) has
       its own long-standing `box-shadow: 0 8px 25px rgba(88, 73, 214,
       0.15)` - a purple-tinted glow meant to lift the selected card off an
       ordinary page background. Pixel-sampled and confirmed: that glow
       bleeds a visible purple-tinted gradient onto this strip's flat gray
       floor for ~15-18px below the card, which is exactly the kind of
       "these are different pieces" cue the color/shape fixes above don't
       touch. Overridden to `none` ONLY for the reparented mobile instance
       (via the `#fdToolTabGrid` ID prefix, the same scoping trick already
       used for `#fdToolTabGrid .fd-tool-tab-icon` above) - the other ~13
       pages' own inline (non-mobile-dock) tool-tab grids keep the glow
       unchanged, since it's a legitimate "this one's selected" cue there,
       not a floating-vs-flat mismatch. */
    #fdToolTabGrid .fd-tool-tab-card.active { box-shadow: none; }
    /* Always occupies the same fixed screen space now (no more open/closed
       size difference), sitting just above the dock rather than inline in
       the page's normal scroll flow - panel content needs enough bottom
       clearance to never render underneath it. 195px was sized for the
       strip's older, higher resting spot (bottom:80px); now that the
       strip sits lower still (68-74px depending on breakpoint, see
       above), 195px is still comfortably more than enough, just with a
       little extra unused buffer - left as-is rather than trimmed, since
       over-provisioning here is harmless and under-provisioning would let
       panel content render underneath the strip. */
    .fd-tab-layout .fd-tool-panel-stack { padding-bottom: 195px; }

    /* 2026-09-13 SAME-DAY FOLLOW-UP #2, quoted directly: "on mobile its
       perfect just make the tab icons abit smaller." Then SAME-DAY
       FOLLOW-UP #3, quoted directly (again): "make the icons smaller" -
       shrunk to 26px/12px. FIFTH same-day follow-up, quoted directly yet
       again: "just make the icons smaller." Shrunk once more, to
       22px/11px - still comfortably above typical minimum touch-target
       guidance once the whole tappable card (icon + padding, not just
       the icon glyph itself) is counted, which is the actual tap target
       here (fdShowToolTab() binds to the card, not the icon alone -
       untouched, see this whole block's own top comment). Selector
       updated from ".fd-tab-layout .fd-tool-tab-grid .fd-tool-tab-icon"
       to "#fdToolTabGrid .fd-tool-tab-icon" for the same reparenting
       reason as the grid's own rule above - still MORE specific than the
       base (unscoped) ".fd-tool-tab-icon" mobile rule these 13 pages
       would otherwise fall back to (app-extra.css ~line 786), which
       stays untouched for its other reuses (e.g. the GCE wizard
       step-pickers). */
    #fdToolTabGrid .fd-tool-tab-icon {
        width: 22px;
        height: 22px;
        font-size: 11px;
        margin-bottom: 3px;
    }
}

/* "no purple separation" fix, continued: the dock's own top padding and
   icon height both change at the 480px and 380px breakpoints
   (template-exact.css's .vertical-tabs-wrapper/.vertical-tab), so the
   exact `bottom` value that lands this strip precisely on the active
   icon's own top edge (see the long comment on the base #fdToolTabGrid
   rule above) changes too. 481-768px range: dock padding-top 6px + icon
   height 48px + 14px dock inset = icon top at 68px (the base rule's
   value, no override needed there). 381-480px range: dock padding-top
   jumps to 8px and icon height to 52px = icon top at 74px. ≤380px range:
   icon height drops to 46px (padding-top stays 8px, unchanged since
   .vertical-tabs-wrapper itself isn't redefined at this breakpoint) =
   icon top back down at 68px, same number as the base rule but a
   coincidence of the arithmetic, not inherited from it - restated
   explicitly here so it survives if either number changes independently
   later. */
@media (max-width: 480px) {
    /* 2026-09-18: was `bottom: 74px`, derived from the dock being a pill
       floating 14px above the bottom edge (14 + ~60 tall). The dock is now
       flush at bottom:0; its height was MEASURED in a real browser at
       390x844 as 68px (8px padding + 52px tab + 8px padding), not
       estimated. The env() term is the part the old hardcoded number
       always got wrong: on a notched phone the dock grows by the safe-area
       inset, so a fixed value slides underneath it. Same expression used
       for .fd-offline-banner above. */
    #fdToolTabGrid { bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 380px) {
    #fdToolTabGrid { bottom: 68px; }
}

/* 2026-09-14, quoted directly: "also try to check this mode 'Testing the
   experimental tab nav...' its buggy when clicking through especially
   with bad internet connection it becomes buggy and stuck." Root cause
   (see fd-tab-shell.js's own dated comment for the full story): a slow
   fetch gave literally no visual feedback at all - the page-wide loading
   bar every other page used to show was removed platform-wide a few
   rounds back - so a slow tab genuinely looked identical to a stuck one,
   which is exactly what encouraged repeat-tapping the same link (which
   used to fire a second, overlapping fetch for the same destination - a
   real bug, also fixed in that file). This small pulsing dot on whichever
   dock icon has a fetch in flight is the fix for the "no feedback at all"
   half of the problem; fd-tab-shell.js's own comment covers the
   overlapping-fetch and stale-response half. `.vertical-tab` already
   carries `position: relative` (template-exact.css), so this positions
   cleanly in its top-right corner on both the desktop rail and the mobile
   dock without needing any markup change. */
.vertical-tab.fd-tab-shell-loading::after {
    content: '';
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #ffffff;
    animation: fdTabShellPulse 0.9s ease-in-out infinite;
    pointer-events: none;
}
@keyframes fdTabShellPulse {
    0%, 100% { opacity: 0.3; transform: scale(0.85); }
    50% { opacity: 1; transform: scale(1.15); }
}

/* =====================================================================
   OFFLINE BANNER - 2026-09-18
   "you are seeing a saved copy" strip, shown by spa-nav.js's
   setOfflineBanner() when a navigation failed and the page was restored
   from the IndexedDB page store (fd-offline-pages.js) instead.

   This rule used to live in mobile-v2.css and was scoped to that
   layer's `body.fd-m2`. mobile-v2.css is gone (the UI was reverted to
   its pre-redesign design on request) but offline browsing was kept, so
   the banner needs a home that is not tied to any one design: it now
   lives here, unscoped, and works on desktop and mobile alike.

   Positioned clear of the old UI's fixed bottom nav on mobile (body
   carries `padding-bottom: 80px` there - see template-exact.css) so it
   can never be mistaken for page content or sit under the nav.
   ===================================================================== */
.fd-offline-banner {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 16px;
    z-index: 1001;
    border-radius: 14px;
    padding: 9px 14px;
    background: #2B2A4E;
    color: #fff;
    font-family: 'Poppins', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .2px;
    text-align: center;
    box-shadow: 0 10px 22px rgba(43, 42, 78, .32);
}
.fd-offline-banner i {
    color: #F4A183;
    margin-right: 6px;
}
@media (max-width: 768px) {
    /* Above the fixed bottom nav rather than behind it. 2026-09-18: was
       88px, when the nav was a pill floating 14px off the bottom edge. The
       nav is now flush at bottom:0 and measures 68px tall, so this is that
       height plus 10px of clearance - and plus the safe-area inset, which
       the dock itself also grows by on a notched phone. */
    .fd-offline-banner { bottom: calc(78px + env(safe-area-inset-bottom, 0px)); }
}
@media (min-width: 769px) {
    /* Desktop has no bottom nav - anchor it bottom-right instead of
       stretching a full-width strip across a wide screen. */
    .fd-offline-banner { left: auto; right: 20px; bottom: 20px; max-width: 360px; }
}

/* =====================================================================
   QUESTION BANK - "Add manually" level cards + wizard cards, 2026-09-18
   Quoted: "lets have 3 options to select from that is for the 3
   educational types primary secondary or higher education."

   Two related card families:
     .fd-qb-level-card  the three education-level cards in the panel
     .fd-qb-wiz-card    the choice cards INSIDE the popup wizard
                        (kind, paper, add-vs-bulk, question type)
   They share a look on purpose - the wizard should read as a
   continuation of the card you tapped, not a different screen.

   Deliberately their own classes rather than a reuse of
   .fd-tool-tab-card: those are TABS (they toggle a panel and carry an
   .active state driven by subtabs.js). These are actions. Overloading
   the tab class would have meant fighting that active-state styling on
   every one of these.
   ===================================================================== */
.fd-qb-level-grid,
.fd-qb-wiz-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px;
    margin-top: 6px;
}
.fd-qb-level-card,
.fd-qb-wiz-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 7px;
    width: 100%;
    text-align: left;
    padding: 18px 16px;
    border: 1px solid var(--line, #E6E4F0);
    border-radius: var(--r-md, 14px);
    background: var(--fd-card-bg, #fff);
    cursor: pointer;
    transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.fd-qb-level-card:hover:not(.disabled),
.fd-qb-wiz-card:hover {
    border-color: var(--brand-500, #6C5CE7);
    box-shadow: 0 10px 24px rgba(88, 73, 214, .14);
    transform: translateY(-2px);
}
.fd-qb-level-card:focus-visible,
.fd-qb-wiz-card:focus-visible {
    outline: 2px solid var(--brand-500, #6C5CE7);
    outline-offset: 2px;
}
.fd-qb-level-icon,
.fd-qb-wiz-card-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    background: linear-gradient(135deg, var(--brand-500, #6C5CE7), var(--brand-600, #5849D6));
    color: #fff;
    font-size: 16px;
    flex: 0 0 auto;
}
.fd-qb-level-name,
.fd-qb-wiz-card-title {
    display: block;
    font-weight: 700;
    font-size: 14px;
    color: var(--text, #1A1928);
}
.fd-qb-level-blurb,
.fd-qb-wiz-card-hint {
    display: block;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--muted, #6E6A80);
}
.fd-qb-level-go {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
    font-size: 11.5px;
    font-weight: 700;
    color: var(--brand-600, #5849D6);
}

/* "Coming soon" / unreachable-database levels. Rendered as a plain div
   (not a button) by the PHP, so there is nothing to click in the first
   place - this only has to LOOK unavailable and say why. */
.fd-qb-level-card.disabled {
    cursor: not-allowed;
    opacity: .62;
    background: var(--brand-25, #F7F6FD);
    border-style: dashed;
}
.fd-qb-level-card.disabled .fd-qb-level-icon {
    background: var(--muted, #6E6A80);
}
.fd-qb-level-badge {
    display: inline-block;
    margin-top: 2px;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(110, 106, 128, .14);
    color: var(--muted, #6E6A80);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
}

/* The breadcrumb strip on the repeating add-a-question screen, so the
   admin can always see which paper/section/type they are adding into
   without leaving the form. */
.fd-qb-wiz-crumb {
    margin-bottom: 14px;
    padding: 9px 13px;
    border-radius: 10px;
    background: var(--brand-25, #F7F6FD);
    color: var(--muted, #6E6A80);
    font-size: 11.5px;
    font-weight: 600;
}
.fd-qb-wiz-crumb strong { color: var(--brand-600, #5849D6); }

html[data-theme="dark"] .fd-qb-level-card,
html[data-theme="dark"] .fd-qb-wiz-card { background: var(--fd-card-bg); }
html[data-theme="dark"] .fd-qb-wiz-crumb,
html[data-theme="dark"] .fd-qb-level-card.disabled { background: rgba(255, 255, 255, .04); }

/* ==========================================================================
   2026-09-18 (twenty-fifth follow-up) - mobile chrome pass
   --------------------------------------------------------------------------
   Quoted directly: "i dont want scroll bars inside pop ups please. also the
   section under the nav bar under where u swipe up on andriod i would like
   that to be colored too same color as the nav bar ... the tab bar on each
   subject for a teacher or class for a student should slide up from under
   and also slide back down under the bottom nav when the user clicks away
   or clicks on it. and should be full length of the mobile view ... for the
   bottom nav bar on mobile lets reduce the height and make the fonts more
   sharp then the color and the andriod mobile nav should have same color
   and feel like one panel."

   Everything for this round lives in this one block, at the END of the
   file, so it wins the cascade over the older rules it supersedes without
   those rules (and their long dated comments) having to be rewritten.
   ========================================================================== */

/* ---- 1. No visible scrollbars inside any popup -------------------------
   Every popup family this app has: the shared bottom sheets (#fdMobileSheet,
   #fdcSheet, #fdProfileSheet, #fdWalletSheet, #fdClassSheet, #fdQuizSheet,
   #fdResultSheet - all .bottom-sheet), the school-admin .fd-modal-* dialogs,
   and anything else that declares role="dialog". The content still scrolls
   (touch, wheel, keyboard) - only the scrollbar chrome is hidden, on the
   popup itself AND on every scroller nested inside it (option lists,
   tables, the sheet viewport). */
.bottom-sheet, .bottom-sheet *,
.fd-modal-overlay, .fd-modal-overlay *,
[role="dialog"], [role="dialog"] *,
.sheet-viewport, .sheet-viewport * {
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;       /* old Edge */
}
.bottom-sheet::-webkit-scrollbar, .bottom-sheet *::-webkit-scrollbar,
.fd-modal-overlay::-webkit-scrollbar, .fd-modal-overlay *::-webkit-scrollbar,
[role="dialog"]::-webkit-scrollbar, [role="dialog"] *::-webkit-scrollbar,
.sheet-viewport::-webkit-scrollbar, .sheet-viewport *::-webkit-scrollbar {
    width: 0 !important;
    height: 0 !important;
    display: none;
    background: transparent;
}

/* ---- 2. Bottom nav: one panel with the Android system bar --------------
   header.php now sets viewport-fit=cover, so on Android (Chrome 135+
   edge-to-edge) and iOS the page is drawn underneath the gesture/nav bar
   and env(safe-area-inset-bottom) reports its height. The dock's own
   background runs through that inset (padding-bottom), so the system bar
   area is literally the dock's colour - one continuous panel, no second
   strip. The same colour is published as the theme-color meta / manifest
   theme_color so the status bar at the top matches too.

   --fd-dock-core is the dock's height ABOVE the safe area. Everything that
   has to sit on top of the dock (the tab drawer, the offline banner, the
   connection badge) positions off --fd-dock-h, so none of it is a
   hard-coded pixel guess any more. */
:root {
    --fd-dock-core: 56px;
    --fd-dock-h: calc(var(--fd-dock-core) + env(safe-area-inset-bottom, 0px));
    --fd-dock-bg: var(--brand-600);
}
html[data-theme="dark"] { --fd-dock-bg: #15132B; }

@media (max-width: 768px) {
    .vertical-tabs-wrapper {
        box-sizing: border-box;
        height: var(--fd-dock-h);
        padding: 5px 6px calc(5px + env(safe-area-inset-bottom, 0px)) 6px;
        gap: 2px;
        align-items: stretch;
        background: var(--fd-dock-bg);
        /* No shadow and no top border: a shadow is exactly what makes a
           bar read as "floating over" the system bar instead of being
           the same surface. */
        box-shadow: none;
        z-index: 1000;
    }
    .vertical-tab {
        height: calc(var(--fd-dock-core) - 10px);
        min-height: 0;
        padding: 3px 2px 2px;
        gap: 3px;
        border-radius: 12px;
        color: rgba(255, 255, 255, 0.74);
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-rendering: geometricPrecision;
    }
    .vertical-tab i {
        font-size: 18px;
        line-height: 1;
    }
    /* "make the fonts more sharp": the old label was 9-10px, UPPERCASE,
       at 0.95 opacity on top of an already-translucent colour - small
       caps at partial alpha is what reads as blurry on a phone. Now
       sentence case, Inter 600, full-opacity text on a stronger base
       colour, with a hair of positive tracking. */
    .vertical-tab .tab-label {
        font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
        font-size: 10.5px;
        font-weight: 600;
        letter-spacing: 0.15px;
        text-transform: none;
        opacity: 1;
        line-height: 1.1;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .vertical-tab.gactive {
        background: var(--fd-card-bg);
        color: var(--brand-600);
        border-radius: 12px;
    }
    html[data-theme="dark"] .vertical-tab.gactive { color: #fff; }
    html[data-theme="dark"] .vertical-tab.gactive i { color: #fff; }
    /* The two corner masks (template-exact.css) only exist to blend the
       active chip into a tab strip sitting directly above it. With the
       strip now a drawer that is usually tucked away, they are only drawn
       while it is actually open - see section 3. */
    .vertical-tab.gactive::before,
    .vertical-tab.gactive::after { display: none; }

    /* Things that sit above the dock follow its real height. */
    .fd-offline-banner { bottom: calc(var(--fd-dock-h) + 10px); }
    #fdConnStatus { bottom: calc(var(--fd-dock-h) + 10px) !important; }
}
@media (max-width: 380px) {
    .vertical-tab .tab-label { font-size: 9.5px; letter-spacing: 0; }
    .vertical-tab i { font-size: 17px; }
}

/* ---- 3. The subject/class tab drawer -----------------------------------
   Mobile only. #fdToolTabGrid is portaled to <body> by footer.php (see
   fdTabGridSyncPortal()), and now lives BEHIND the dock (z-index 999 < the
   dock's 1000) so it can genuinely slide up out from under it and back
   down beneath it. Closed = translated down by its own height, which parks
   its top edge exactly at the dock's top edge: fully hidden behind the
   dock, never peeking. footer.php's fdTabDrawer* functions own the state
   (body.fd-tabgrid-open); this is only the look and the motion. */
@media (max-width: 768px) {
    #fdToolTabGrid {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: var(--fd-dock-h);
        z-index: 999;
        margin: 0;
        padding: 16px 12px 10px;
        gap: 8px;
        background: var(--fd-card-bg);
        border-radius: 22px 22px 0 0;
        box-shadow: 0 -10px 30px rgba(30, 22, 90, 0.16);
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        transform: translateY(100%);
        transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease;
        will-change: transform;
        visibility: hidden;
    }
    #fdToolTabGrid::-webkit-scrollbar { display: none; }
    /* Grab handle, so the drawer reads as something you can put away. */
    #fdToolTabGrid::before {
        content: '';
        position: absolute;
        top: 6px;
        left: 50%;
        width: 38px;
        height: 4px;
        margin-left: -19px;
        border-radius: 4px;
        background: rgba(88, 73, 214, 0.22);
    }
    body.fd-tabgrid-ready #fdToolTabGrid { visibility: visible; }
    body.fd-tabgrid-open #fdToolTabGrid { transform: translateY(0); }
    body:not(.fd-tabgrid-open) #fdToolTabGrid { box-shadow: none; }

    /* "full length of the mobile view": the cards share the whole width
       when they fit, and scroll sideways when they don't. */
    #fdToolTabGrid .fd-tool-tab-card {
        flex: 1 0 76px;
        width: auto;
        min-width: 76px;
        padding: 10px 4px 9px;
        border-radius: 16px;
        border-width: 1.5px;
        background: var(--surface, #fff);
        box-shadow: none;
    }
    #fdToolTabGrid .fd-tool-tab-card:hover { transform: none; box-shadow: none; }
    #fdToolTabGrid .fd-tool-tab-card.active {
        background: var(--brand-50);
        border-color: var(--brand-500);
        box-shadow: none;
    }
    #fdToolTabGrid .fd-tool-tab-icon {
        width: 30px;
        height: 30px;
        font-size: 13px;
        margin-bottom: 5px;
    }
    #fdToolTabGrid .fd-tool-tab-name {
        font-size: 10.5px;
        font-weight: 700;
        line-height: 1.2;
        -webkit-font-smoothing: antialiased;
    }

    /* While the drawer is open, the active dock chip goes back to being
       the drawer's "stem": flat top, same colour, corner masks on. */
    body.fd-tabgrid-open .vertical-tab.gactive { border-radius: 0 0 12px 12px; }
    body.fd-tabgrid-open .vertical-tab.gactive::before,
    body.fd-tabgrid-open .vertical-tab.gactive::after { display: block; }

    /* A small chevron on the active dock icon while the drawer is tucked
       away - the only hint that this page has tabs to pull up. */
    body.fd-has-tabgrid .vertical-tab.gactive .fd-tabgrid-hint {
        position: absolute;
        top: 3px;
        left: 7px;
        font-size: 9px;
        color: var(--brand-500);
        transition: transform 0.3s ease, opacity 0.3s ease;
    }
    body.fd-tabgrid-open .vertical-tab.gactive .fd-tabgrid-hint { transform: rotate(180deg); opacity: 0.55; }

    /* Panel content keeps enough bottom room for the drawer when open. */
    .fd-tab-layout .fd-tool-panel-stack { padding-bottom: 150px; }
}
@media (prefers-reduced-motion: reduce) {
    #fdToolTabGrid { transition: none !important; }
}
/* The hint chevron is injected by footer.php on every width; it is only
   meaningful on the mobile dock. */
.fd-tabgrid-hint { display: none; }
@media (max-width: 768px) {
    body.fd-has-tabgrid .vertical-tab.gactive .fd-tabgrid-hint { display: block; }
}

/* ---- 4. The week calendar (WeekSchedule::render()) ----------------------
   Student and teacher dashboards. Mobile: a 7-day strip, tap (or swipe the
   list) to change day, the chosen day's activities as cards underneath.
   Wide screens (>= 992px): the strip gives way to seven real columns, each
   day with its own card list under it - literally "the week days lined up
   horizontally then under each day a card list". */
.fd-week {
    --fd-ev-lesson: #1971C2;
    --fd-ev-online: #5849D6;
    --fd-ev-assignment: #E8590C;
    --fd-ev-assessment: #C2255C;
    background: var(--surface, #fff);
    border: 1px solid var(--line, #ECEAF6);
    border-radius: 22px;
    padding: 16px 16px 14px;
    margin: 0 0 22px 0;
    box-shadow: 0 10px 30px rgba(88, 73, 214, 0.06);
}
.fd-week-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.fd-week-heading { display: flex; align-items: center; gap: 12px; min-width: 0; }
.fd-week-heading-icon {
    flex: 0 0 auto;
    width: 40px; height: 40px; border-radius: 13px;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 17px;
    background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6));
    box-shadow: 0 8px 18px rgba(88, 73, 214, 0.28);
}
.fd-week-title { margin: 0; font-family: 'Poppins', sans-serif; font-size: 16px; font-weight: 700; color: var(--text); line-height: 1.2; }
.fd-week-range { display: block; font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.fd-week-nav { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.fd-week-nav-btn {
    width: 32px; height: 32px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-50); color: var(--brand-600) !important; font-size: 12px;
    text-decoration: none !important; transition: background .15s ease, transform .15s ease;
}
.fd-week-nav-btn:hover { background: var(--brand-100); transform: scale(1.06); }
.fd-week-nav-today {
    padding: 6px 12px; border-radius: 999px; font-size: 12px; font-weight: 700;
    background: var(--brand-600); color: #fff !important; text-decoration: none !important;
}

.fd-week-filter { display: flex; gap: 6px; margin: -2px 0 12px; flex-wrap: wrap; }
.fd-week-chip {
    display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid var(--line, #ECEAF6); background: transparent; color: var(--text-muted);
    border-radius: 999px; padding: 5px 11px; font-size: 12px; font-weight: 600; cursor: pointer;
    transition: all .15s ease;
}
.fd-week-chip span {
    min-width: 18px; padding: 0 5px; border-radius: 999px; font-size: 10.5px; line-height: 17px; text-align: center;
    background: var(--brand-50); color: var(--brand-700, #4A3DC0);
}
.fd-week-chip.active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.fd-week-chip.active span { background: rgba(255, 255, 255, 0.22); color: #fff; }

.fd-week-strip {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 6px;
    margin-bottom: 14px;
}
.fd-week-day {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 9px 0 8px; border: none; border-radius: 16px;
    background: var(--brand-25, #F7F6FD); color: var(--text);
    cursor: pointer; transition: background .2s ease, color .2s ease, transform .2s ease, box-shadow .2s ease;
    -webkit-tap-highlight-color: transparent;
}
.fd-week-day:active { transform: scale(0.96); }
.fd-week-dow { font-size: 10.5px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; color: var(--text-muted); }
.fd-week-num { font-family: 'Poppins', sans-serif; font-size: 17px; font-weight: 700; line-height: 1.1; }
.fd-week-dots { display: flex; gap: 3px; height: 5px; }
.fd-week-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--brand-500, #6C63FF); }
/* 2026-10-02: a real count on a day with more than one activity. Three dots
   could not distinguish three activities from eight, so a busy day looked
   like a quiet one and people never scrolled. */
.fd-week-count {
    display: inline-grid;
    place-items: center;
    min-width: 17px; height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--brand-500, #6C63FF);
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1;
}
.fd-week-day.is-selected .fd-week-count { background: #fff; color: var(--brand-700, #4A3BC4); }
.fd-week-day.is-today:not(.is-selected) { box-shadow: inset 0 0 0 1.5px var(--brand-500, #6C63FF); }
.fd-week-day.is-today:not(.is-selected) .fd-week-num { color: var(--brand-600); }
.fd-week-day.is-selected {
    background: linear-gradient(160deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6));
    color: #fff;
    box-shadow: 0 10px 22px rgba(88, 73, 214, 0.32);
}
.fd-week-day.is-selected .fd-week-dow { color: rgba(255, 255, 255, 0.82); }
.fd-week-day.is-selected .fd-week-dots i { background: #fff; }

.fd-week-lists { position: relative; }
.fd-week-list { display: none; flex-direction: column; gap: 8px; }
.fd-week-list.is-selected { display: flex; }
.fd-week-list.fd-week-anim { animation: fdWeekIn .32s cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes fdWeekIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.fd-week-list-head { display: none; }
.fd-week-list-mobile-title { font-size: 12.5px; font-weight: 700; color: var(--text); margin: 0 2px 2px; display: flex; align-items: center; gap: 8px; }
/* 2026-09-26: the "See all" button exists only on desktop columns - a phone
   already shows the whole day as a swipeable strip. Declared here, BEFORE the
   min-width: 992px block that turns it on, so the cascade runs the right way
   round. */
/* 2026-10-02: the overflow behaviour used to start at 992px, so on a phone -
   where this app actually lives - a day with six activities stacked all six
   and pushed everything below the fold. Reported as "THE CALENDAR SEEMS TO BE
   TAKING LOTS OF SPACE ON THE APP". Now a day shows its first TWO activities
   on a phone and collapses the rest behind the same "See all" pop-up the
   desktop already used. Two rather than one, because on a phone the list IS
   the day view, and showing a single card would hide the common case of a
   morning and an afternoon class. */
@media (max-width: 991.98px) {
    .fd-week-list > .fd-ev.fd-ev-over-m { display: none; }
    .fd-week-more[hidden] { display: none; }
    .fd-week-more:not([hidden]) {
        display: flex; align-items: center; gap: 7px; width: 100%;
        padding: 9px 11px; margin-top: 2px;
        border: 1px dashed var(--brand-300, #BAB4F5);
        border-radius: 12px; background: transparent;
        color: var(--brand-700, #4A3BC4);
        font-size: 12.5px; font-weight: 600; cursor: pointer;
    }
    .fd-week-more:active { background: var(--brand-50, #F0EEFF); }
    .fd-week-more-n {
        flex: 0 0 auto; min-width: 24px; padding: 2px 6px; border-radius: 999px;
        background: var(--brand-500, #6C63FF); color: #fff; font-size: 10.5px; text-align: center;
    }
    .fd-week-more-lbl { flex: 1 1 auto; text-align: left; }
    .fd-week-more > i { flex: 0 0 auto; font-size: 9px; opacity: .75; }
}
.fd-week-more { display: none; }
.fd-week-today-pill { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); }
.fd-week-empty {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 18px 10px; border-radius: 16px; border: 1.5px dashed var(--line, #E4E1F2);
    color: var(--text-muted); font-size: 12.5px; font-weight: 600;
}
.fd-week-empty[hidden] { display: none; }
.fd-week-empty i { color: #F59F00; }

/* One activity card. The coloured rail on the left is the type; the
   small chip at the bottom is where it comes from (school or tutor). */
.fd-ev {
    --fd-ev-c: var(--fd-ev-lesson);
    position: relative;
    display: flex; align-items: stretch; gap: 12px;
    padding: 12px 12px 12px 16px;
    border-radius: 16px;
    background: var(--surface, #fff);
    border: 1px solid var(--line, #ECEAF6);
    color: var(--text) !important;
    text-decoration: none !important;
    overflow: hidden;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.fd-ev[hidden] { display: none; }
.fd-ev::before {
    content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
    background: var(--fd-ev-c);
}
.fd-ev::after {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(90deg, color-mix(in srgb, var(--fd-ev-c) 7%, transparent), transparent 55%);
}
a.fd-ev:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(30, 22, 90, 0.08); border-color: color-mix(in srgb, var(--fd-ev-c) 35%, var(--line, #ECEAF6)); }
.fd-ev--online { --fd-ev-c: var(--fd-ev-online); }
.fd-ev--assignment { --fd-ev-c: var(--fd-ev-assignment); }
.fd-ev--assessment { --fd-ev-c: var(--fd-ev-assessment); }
.fd-ev-time {
    flex: 0 0 44px; display: flex; flex-direction: column; justify-content: center;
    position: relative; z-index: 1;
}
.fd-ev-time b { font-family: 'Poppins', sans-serif; font-size: 13px; font-weight: 700; color: var(--text); line-height: 1.2; }
.fd-ev-time small { font-size: 11px; color: var(--text-muted); }
.fd-ev-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; position: relative; z-index: 1; }
.fd-ev-type {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-size: 10.5px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; color: var(--fd-ev-c);
}
.fd-ev-status {
    text-transform: none; letter-spacing: 0; font-weight: 700; font-size: 10.5px;
    padding: 1px 7px; border-radius: 999px;
    background: color-mix(in srgb, var(--fd-ev-c) 12%, transparent); color: var(--fd-ev-c);
}
.fd-ev.is-overdue .fd-ev-status { background: rgba(224, 49, 49, .12); color: #E03131; }
.fd-ev-live {
    display: inline-flex; align-items: center; gap: 5px;
    text-transform: none; letter-spacing: 0; font-size: 10.5px;
    padding: 1px 8px 1px 6px; border-radius: 999px; background: rgba(18, 184, 134, .14); color: #0CA678;
}
.fd-ev-live span { width: 7px; height: 7px; border-radius: 50%; background: #12B886; animation: fdEvPulse 1.4s ease-in-out infinite; }
@keyframes fdEvPulse { 0% { box-shadow: 0 0 0 0 rgba(18, 184, 134, .55); } 70% { box-shadow: 0 0 0 7px rgba(18, 184, 134, 0); } 100% { box-shadow: 0 0 0 0 rgba(18, 184, 134, 0); } }
.fd-ev-title {
    font-size: 14px; font-weight: 700; color: var(--text); line-height: 1.3;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fd-ev-meta { font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-ev-src {
    align-self: flex-start; margin-top: 4px;
    display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
    font-size: 10.5px; font-weight: 600; padding: 2px 8px; border-radius: 999px;
    background: var(--brand-25, #F7F6FD); color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fd-ev-src--private { background: #FFF4E0; color: #B8790A; }
.fd-ev-go { align-self: center; font-size: 11px; color: var(--text-muted); opacity: .6; position: relative; z-index: 1; }

@media (min-width: 992px) {
    .fd-week { padding: 20px; }
    .fd-week-strip { display: none; }
    .fd-week-lists { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; }
    .fd-week-list, .fd-week-list.is-selected {
        display: flex; gap: 8px; padding: 10px 8px; border-radius: 18px;
        background: var(--brand-25, #F7F6FD); min-height: 190px; align-content: flex-start;
    }
    .fd-week-list.fd-week-anim { animation: none; }
    .fd-week-list.is-today { background: color-mix(in srgb, var(--brand-500, #6C63FF) 9%, var(--surface, #fff)); box-shadow: inset 0 0 0 1.5px var(--brand-500, #6C63FF); }
    .fd-week-list-mobile-title { display: none; }
    .fd-week-list-head { display: flex; align-items: baseline; justify-content: space-between; padding: 2px 4px 6px; }
    .fd-week-list-dow { font-size: 11px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; color: var(--text-muted); }
    .fd-week-list-num { font-family: 'Poppins', sans-serif; font-size: 18px; font-weight: 700; color: var(--text); }
    .fd-week-list.is-today .fd-week-list-num { color: var(--brand-600); }
    /*
     * 2026-09-26 (forty-sixth follow-up), quoted: "the calandar on desktop if
     * there are more than 1 item on a day instead of stacking them just add a
     * beautiful see more button which will bring up a pop up with a beautiful
     * list of all activities of that day. becase stacking them up like that
     * increases scrolling alot and breaks the design ui style."
     *
     * A column shows its first card and nothing else, so all seven columns keep
     * the same height whether a day holds one activity or nine. Two things are
     * deliberate here:
     *
     *  - the child selector. Cloned cards inside the pop-up are NOT direct
     *    children of a column, so they are never hidden by this rule even
     *    though the clone may still carry the class.
     *  - this whole block is inside min-width: 992px. On a phone the day is
     *    already a horizontal scroll-snapping strip, which is the right answer
     *    on that screen, so nothing here applies there.
     */
    .fd-week-list > .fd-ev.fd-ev-over { display: none; }
    /* reflow() hides this with the `hidden` attribute when a filter leaves a
       single activity on the day - and `display: flex` below would otherwise
       beat the browser's own [hidden] rule, so it is spelled out. */
    .fd-week-more[hidden] { display: none; }
    .fd-week-more:not([hidden]) { display: flex; align-items: center; gap: 6px; width: 100%; padding: 8px 10px; border: 1px dashed var(--brand-300, #BAB4F5);
        border-radius: 13px; background: transparent; color: var(--brand-600, #5849D6); font-size: 11.5px; font-weight: 700;
        font-family: inherit; cursor: pointer; transition: background .2s ease, border-color .2s ease, transform .2s ease; text-align: left; }
    .fd-week-more:hover { background: var(--brand-50, #F0EEFF); border-style: solid; border-color: var(--brand-500, #6C63FF); transform: translateY(-1px); }
    .fd-week-more-n { flex: 0 0 auto; min-width: 26px; padding: 2px 6px; border-radius: 999px; background: var(--brand-500, #6C63FF); color: #fff; font-size: 10.5px; text-align: center; }
    .fd-week-more-lbl { flex: 1 1 auto; }
    .fd-week-more > i { flex: 0 0 auto; font-size: 9px; opacity: .75; }
    .fd-ev { flex-direction: column; gap: 4px; padding: 10px 10px 10px 13px; border-radius: 13px; }
    .fd-ev-time { flex: 0 0 auto; flex-direction: row; align-items: baseline; justify-content: flex-start; gap: 4px; }
    .fd-ev-time b { font-size: 12px; }
    .fd-ev-time small::before { content: '– '; }
    .fd-ev-title { font-size: 12.5px; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
    .fd-ev-meta { font-size: 11px; }
    .fd-ev-type { font-size: 9.5px; }
    .fd-ev-go { display: none; }
    .fd-week-empty { padding: 14px 6px; font-size: 11.5px; flex-direction: column; gap: 4px; border-width: 1px; }
}
@media (max-width: 380px) {
    .fd-week { padding: 14px 12px 12px; border-radius: 18px; }
    .fd-week-strip { gap: 4px; }
    .fd-week-num { font-size: 15px; }
    .fd-week-dow { font-size: 9.5px; }
}
html[data-theme="dark"] .fd-week { background: var(--surface); border-color: var(--line); box-shadow: none; }
html[data-theme="dark"] .fd-week-day { background: rgba(255, 255, 255, .04); }
html[data-theme="dark"] .fd-ev { background: var(--fd-card-bg); border-color: var(--line); }
html[data-theme="dark"] .fd-ev-src { background: rgba(255, 255, 255, .06); }
html[data-theme="dark"] .fd-ev-src--private { background: rgba(245, 159, 0, .14); color: #FFC078; }

/* ---- 5. Dashboards on mobile: no pie chart, subjects/classes 3 per row --
   "on mobile instead of having that pie chart ... we maintain the my
   subjects but 3 per row on mobile." The summary row (chart, and the
   photo/profile cards that were already hidden under 900px) goes away on
   mobile - the week calendar above the tabs takes its place. The subject
   carousel (student) and the class grid (teacher) become a 3-column grid
   instead of a sideways scroller. Desktop is untouched. */
@media (max-width: 768px) {
    .fd-dash-summary-row { display: none; }
    .fd-subject-carousel,
    .fd-dash-class-grid {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
        overflow: visible;
        scroll-snap-type: none;
        padding-bottom: 0;
    }
    .fd-subject-carousel-card,
    .fd-dash-class-card2 { width: auto; min-width: 0; flex: none; }
    .fd-subject-carousel .fd-dash-class-body,
    .fd-dash-class-grid .fd-dash-class-body { padding: 14px 6px 12px; }
    .fd-subject-carousel .fd-dash-class-icon,
    .fd-dash-class-grid .fd-dash-class-icon { width: 38px; height: 38px; font-size: 15px; margin-bottom: 7px; }
    .fd-subject-carousel .fd-dash-class-name,
    .fd-dash-class-grid .fd-dash-class-name {
        font-size: 12px; line-height: 1.25;
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
        word-break: break-word;
    }
    .fd-subject-carousel .fd-dash-class-subcount,
    .fd-dash-class-grid .fd-dash-class-subcount { font-size: 10.5px; }
    .fd-dash-class-grid .fd-dash-class-actions { top: 5px; right: 5px; gap: 4px; }
    .fd-dash-class-grid .fd-dash-class-action-btn { width: 22px; height: 22px; font-size: 10px; }
    .fd-dash-class-grid .fd-dash-class-badge { width: 16px; height: 16px; font-size: 8px; }
    .fd-dash-chart-mobile-slot { display: none !important; }
}

/* ---- 6. Catalog-first inputs (fd-catalog-picker.js) -------------------- */
.fd-pick-menu {
    position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 60;
    max-height: 240px; overflow-y: auto; scrollbar-width: none;
    background: var(--surface, #fff); border: 1px solid var(--line, #E6E4F0);
    border-radius: 14px; box-shadow: 0 16px 34px rgba(30, 22, 90, 0.14);
    padding: 6px;
}
.fd-pick-menu::-webkit-scrollbar { display: none; }
.fd-pick-menu[hidden] { display: none; }
.fd-pick-opt {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 8px 10px; border: none; border-radius: 10px; background: transparent;
    font-size: 13px; color: var(--text); text-align: left; cursor: pointer;
}
.fd-pick-opt i { color: var(--brand-500); font-size: 11px; }
.fd-pick-opt:hover { background: var(--brand-50); }
.fd-pick-opt mark { padding: 0; background: transparent; color: var(--brand-600); font-weight: 700; }
.fd-pick-miss {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    padding: 8px 10px; margin-top: 2px; border-radius: 10px;
    background: #FFF6E0; color: #8A5A00; font-size: 12px;
}
.fd-pick-hint { color: #8A5A00; opacity: .85; }
.fd-pick-accept {
    margin-left: auto; border: none; border-radius: 999px; padding: 4px 10px;
    background: #F59F00; color: #fff; font-size: 11.5px; font-weight: 700; cursor: pointer;
}
input.fd-pick-invalid { border-color: #E03131 !important; box-shadow: 0 0 0 3px rgba(224, 49, 49, .12) !important; }

/* ---- 7. Academic structure wizard (academic-structure-wizard.js) -------- */
.fd-as-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 12px; font-size: 12px; }
.fd-as-crumbs button { border: none; background: var(--brand-50); color: var(--brand-600); padding: 4px 10px; border-radius: 999px; font-weight: 700; cursor: pointer; font-size: 12px; }
.fd-as-crumbs i { font-size: 9px; color: var(--text-muted); }
.fd-as-crumbs .current { padding: 4px 10px; border-radius: 999px; background: var(--brand-600); color: #fff; font-weight: 700; }
.fd-as-loading { padding: 40px 10px; text-align: center; color: var(--text-muted); font-weight: 600; }
.fd-as-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.fd-as-chip { border: 1px solid var(--line, #E6E4F0); background: transparent; color: var(--text-muted); border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600; cursor: pointer; }
.fd-as-chip.active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.fd-as-search { position: relative; margin-bottom: 12px; }
.fd-as-search > i { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-muted); font-size: 13px; }
.fd-as-search .form-control { padding-left: 38px; }
.fd-as-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.fd-as-card {
    position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
    padding: 14px; border: 1px solid var(--line, #E6E4F0); border-radius: 16px;
    background: var(--fd-card-bg, #fff); text-align: left; cursor: pointer;
    transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.fd-as-card[hidden] { display: none; }
.fd-as-card:hover { border-color: var(--brand-500); box-shadow: 0 10px 22px rgba(88, 73, 214, .12); transform: translateY(-2px); }
.fd-as-card-wrap { padding: 0; cursor: default; }
.fd-as-card-body { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; width: 100%; padding: 14px; border: none; background: transparent; text-align: left; cursor: pointer; }
.fd-as-card-x { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 50%; border: none; background: rgba(224, 49, 49, .1); color: #E03131; font-size: 11px; cursor: pointer; z-index: 1; }
.fd-as-card-ico { width: 36px; height: 36px; border-radius: 11px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 15px; background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.fd-as-card-ico.tone-subject { background: linear-gradient(135deg, #20C997, #1C8A4C); }
.fd-as-card-title { font-weight: 700; font-size: 13.5px; color: var(--text); line-height: 1.25; }
.fd-as-card-sub { font-size: 11.5px; color: var(--text-muted); }
.fd-as-card-add { border-style: dashed; background: transparent; }
.fd-as-card-add .fd-as-card-ico { background: var(--brand-50); color: var(--brand-600); }
.fd-as-group { margin-bottom: 14px; }
.fd-as-group-head { font-weight: 700; font-size: 13px; margin-bottom: 8px; color: var(--text); }
.fd-as-group-head span { font-weight: 500; color: var(--text-muted); font-size: 12px; }
.fd-as-form { max-width: 560px; }
.fd-as-matches { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.fd-as-matches-label { width: 100%; font-size: 11.5px; color: #8A5A00; font-weight: 600; }
.fd-as-matches-label.ok { color: #0CA678; }
.fd-as-match { border: 1px solid var(--line, #E6E4F0); background: var(--surface, #fff); border-radius: 999px; padding: 5px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer; color: var(--text); }
.fd-as-match i { color: #12B886; }
.fd-as-match small { color: var(--text-muted); }
.fd-as-msg { min-height: 18px; margin: 8px 0; font-size: 12.5px; color: var(--text-muted); font-weight: 600; }
.fd-as-msg.err { color: #E03131; }
.fd-as-msg.ok { color: #0CA678; }
.fd-as-checklist { display: flex; flex-direction: column; gap: 6px; }
.fd-as-check {
    display: flex; align-items: center; gap: 10px; margin: 0; padding: 10px 12px; border-radius: 14px;
    border: 1px solid var(--line, #E6E4F0); background: var(--fd-card-bg, #fff); cursor: pointer;
}
.fd-as-check[hidden] { display: none; }
.fd-as-check:has(input:checked) { border-color: var(--brand-500); background: var(--brand-50); }
.fd-as-check input { width: 18px; height: 18px; accent-color: var(--brand-600); }
.fd-as-check-ico { width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; background: rgba(32, 201, 151, .14); color: #1C8A4C; font-size: 13px; }
.fd-as-check-name { font-weight: 600; font-size: 13.5px; color: var(--text); flex: 1; }
.fd-as-check-tag { font-size: 10.5px; padding: 2px 8px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); font-weight: 700; }
.fd-as-notfound { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; padding: 12px 14px; border-radius: 14px; background: #FFF6E0; color: #8A5A00; font-size: 12.5px; }
.fd-as-notfound[hidden] { display: none; }
.fd-as-add { display: grid; grid-template-columns: 1fr auto; gap: 8px; margin-bottom: 4px; }
.fd-as-add-2 { grid-template-columns: 1fr 1fr auto; }
.fd-as-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.fd-as-row { display: flex; align-items: stretch; gap: 6px; border: 1px solid var(--line, #E6E4F0); border-radius: 14px; background: var(--fd-card-bg, #fff); overflow: hidden; }
.fd-as-row[hidden] { display: none; }
.fd-as-row-main { flex: 1; display: flex; align-items: center; gap: 12px; padding: 11px 12px; border: none; background: transparent; text-align: left; cursor: pointer; min-width: 0; }
div.fd-as-row-main { cursor: default; }
.fd-as-row-ico { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; background: var(--brand-50); color: var(--brand-600); font-size: 14px; }
.fd-as-row-ico.tone-lesson { background: rgba(232, 89, 12, .12); color: #E8590C; }
.fd-as-row-text { display: flex; flex-direction: column; min-width: 0; }
.fd-as-row-title { font-weight: 700; font-size: 13.5px; color: var(--text); }
.fd-as-row-sub { font-size: 11.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-as-row-go { margin-left: auto; color: var(--text-muted); font-size: 11px; }
.fd-as-row-x { flex: 0 0 44px; border: none; border-left: 1px solid var(--line, #E6E4F0); background: transparent; color: var(--text-muted); cursor: pointer; }
.fd-as-row-x:hover { color: #E03131; background: rgba(224, 49, 49, .06); }
.fd-as-empty { padding: 22px 10px; text-align: center; color: var(--text-muted); font-size: 13px; font-weight: 600; border: 1.5px dashed var(--line, #E6E4F0); border-radius: 14px; }
.fd-as-bulk-link { display: inline-flex; align-items: center; gap: 8px; margin: 4px 0 6px; border: none; background: transparent; color: var(--brand-600); font-weight: 700; font-size: 12.5px; cursor: pointer; padding: 0; }
.fd-as-upload { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 18px; border-radius: 18px; border: 1.5px dashed var(--brand-200, #C9C3F5); background: var(--brand-25, #F7F6FD); }
.fd-as-upload p { margin: 0; }
.fd-as-upload-ico { width: 44px; height: 44px; border-radius: 13px; display: inline-flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #20C997, #1C8A4C); color: #fff; font-size: 18px; }
.fd-as-done { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 26px 10px; text-align: center; }
.fd-as-done i { font-size: 38px; color: #12B886; }
.fd-as-done span { color: var(--text-muted); font-size: 13px; }
.fd-table td small { display: block; color: var(--text-muted); }
@media (max-width: 576px) {
    .fd-as-add, .fd-as-add-2 { grid-template-columns: 1fr; }
    .fd-as-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Academic structure overview cards (question_bank_moderation.php) */
.fd-as-level-stats { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.fd-as-level-stats span { font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); }
html[data-theme="dark"] .fd-pick-menu { background: var(--surface); }
html[data-theme="dark"] .fd-pick-miss, html[data-theme="dark"] .fd-as-notfound { background: rgba(245, 159, 0, .12); color: #FFC078; }

/* ==========================================================================
   2026-09-18 (twenty-sixth follow-up) - Academic structure managers, the
   "All submissions" browser, add-questions hand-off.
   ========================================================================== */
.fd-as-manage-bar { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin: 4px 0 18px; }
.fd-as-manage-btn {
    position: relative; display: flex; align-items: center; gap: 14px; text-align: left;
    padding: 16px 18px; border: none; border-radius: 18px; cursor: pointer; color: #fff; overflow: hidden;
    background: linear-gradient(135deg, #6C63FF, #4A3DC0);
    box-shadow: 0 12px 26px rgba(88, 73, 214, .28);
    transition: transform .18s ease, box-shadow .18s ease;
}
.fd-as-manage-btn.tone-b { background: linear-gradient(135deg, #20C997, #0B7A57); box-shadow: 0 12px 26px rgba(12, 166, 120, .26); }
.fd-as-manage-btn::after { content: ''; position: absolute; right: -30px; top: -30px; width: 120px; height: 120px; border-radius: 50%; background: rgba(255, 255, 255, .10); }
.fd-as-manage-btn:hover { transform: translateY(-2px); box-shadow: 0 16px 30px rgba(30, 22, 90, .28); }
.fd-as-manage-ico { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .18); font-size: 19px; }
.fd-as-manage-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; position: relative; z-index: 1; }
.fd-as-manage-text strong { font-size: 15px; font-weight: 700; }
.fd-as-manage-text span { font-size: 12px; opacity: .88; }
.fd-as-manage-plus { margin-left: auto; width: 30px; height: 30px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .22); font-size: 12px; position: relative; z-index: 1; }

.fd-as-mhero { display: flex; gap: 14px; align-items: flex-start; padding: 16px; border-radius: 16px; background: linear-gradient(135deg, rgba(108, 99, 255, .12), rgba(88, 73, 214, .04)); margin-bottom: 14px; }
.fd-as-mhero.tone-b { background: linear-gradient(135deg, rgba(32, 201, 151, .14), rgba(12, 166, 120, .04)); }
.fd-as-mhero-ico { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 13px; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, #6C63FF, #4A3DC0); font-size: 17px; }
.fd-as-mhero.tone-b .fd-as-mhero-ico { background: linear-gradient(135deg, #20C997, #0B7A57); }
.fd-as-mhero strong { display: block; font-size: 14.5px; color: var(--text); margin-bottom: 2px; }
.fd-as-mhero span { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.fd-as-mh { font-size: 13px; font-weight: 700; margin: 18px 0 8px; color: var(--text); }
.fd-as-madd { padding: 12px; border: 1.5px dashed var(--brand-200, #C9C3F5); border-radius: 16px; background: var(--brand-25, #F7F6FD); margin-bottom: 4px; }
.fd-as-madd-row { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.fd-as-iconpick { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.fd-as-iconpick button { width: 36px; height: 36px; border-radius: 10px; border: 1.5px solid var(--line, #E6E4F0); background: var(--surface, #fff); color: var(--text-muted); cursor: pointer; }
.fd-as-iconpick button.on { border-color: var(--brand-500); background: var(--brand-50); color: var(--brand-600); }
.fd-as-mlist { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.fd-as-mrow { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 14px; border: 1px solid var(--line, #E6E4F0); background: var(--fd-card-bg, #fff); }
.fd-as-mrow.hidden-row { opacity: .6; border-style: dashed; }
.fd-as-mrow.editing { flex-direction: column; align-items: stretch; border-color: var(--brand-500); }
.fd-as-mrow-edit .form-control { max-width: 420px; }
.fd-as-mrow-ico { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 11px; display: inline-flex; align-items: center; justify-content: center; background: var(--brand-50); color: var(--brand-600); font-size: 15px; }
.fd-as-mrow-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.fd-as-mrow-title { font-weight: 700; font-size: 14px; color: var(--text); }
.fd-as-mrow-sub { font-size: 11.5px; color: var(--text-muted); display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 2px; }
.fd-as-mrow-actions { display: flex; gap: 6px; margin-left: auto; }
.fd-as-pill { font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); }
.fd-as-pill.muted { background: rgba(110, 106, 128, .14); color: var(--text-muted); }
.fd-as-iconbtn { width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--line, #E6E4F0); background: var(--surface, #fff); color: var(--text-muted); cursor: pointer; }
.fd-as-iconbtn:hover { color: var(--brand-600); border-color: var(--brand-500); }
.fd-as-iconbtn.danger:hover { color: #E03131; border-color: #E03131; background: rgba(224, 49, 49, .06); }
.fd-as-restore { border: none; border-radius: 999px; padding: 6px 12px; background: var(--brand-50); color: var(--brand-600); font-weight: 700; font-size: 12px; cursor: pointer; }

/* Lessons step: per-lesson "add questions" */
.fd-as-row-q { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; padding: 0 12px; border: none; border-left: 1px solid var(--line, #E6E4F0); background: transparent; color: var(--brand-600); font-weight: 700; font-size: 12px; cursor: pointer; }
.fd-as-row-q:hover { background: var(--brand-50); }
@media (max-width: 576px) { .fd-as-row-q span { display: none; } .fd-as-madd-row { grid-template-columns: 1fr; } }

/* Browser (All submissions) */
.fd-as-qcount { display: inline-block; margin-top: 2px; font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px; background: rgba(12, 166, 120, .12); color: #0B7A57; }
.fd-as-row-main .fd-as-qcount { margin: 0 4px 0 auto; flex: 0 0 auto; }
.fd-as-row-main .fd-as-qcount + .fd-as-row-go { margin-left: 4px; }
.fd-as-card-alt { background: linear-gradient(135deg, rgba(108, 99, 255, .06), transparent); }
.fd-as-card-ico.tone-warn, .fd-as-row-ico.tone-warn { background: rgba(245, 159, 0, .16); color: #B8790A; }
.fd-as-row-ico.tone-all { background: rgba(12, 166, 120, .14); color: #0B7A57; }
.fd-as-stats { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.fd-as-stat { font-size: 12px; padding: 6px 12px; border-radius: 12px; background: var(--brand-25, #F7F6FD); color: var(--text-muted); }
.fd-as-stat b { font-size: 14px; color: var(--text); margin-right: 2px; }
.fd-as-stat.ok b { color: #0CA678; } .fd-as-stat.warn b { color: #E8590C; } .fd-as-stat.err b { color: #E03131; }
.fd-as-qhead { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.fd-as-qhead h4 { margin: 0; font-size: 16px; font-weight: 700; color: var(--text); }
.fd-as-qhead h4 span { font-size: 12px; font-weight: 600; color: var(--text-muted); margin-left: 6px; }
.fd-as-qlist { display: flex; flex-direction: column; gap: 10px; }
.fd-as-q { padding: 14px 16px; border: 1px solid var(--line, #E6E4F0); border-radius: 16px; background: var(--fd-card-bg, #fff); }
.fd-as-q-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
.fd-as-q-num { width: 24px; height: 24px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; background: var(--brand-600); color: #fff; }
.fd-as-q-tag { font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); }
.fd-as-q-head .fd-badge { text-transform: capitalize; }
.fd-as-q-stem { font-size: 14px; color: var(--text); font-weight: 600; line-height: 1.5; white-space: pre-wrap; }
.fd-as-q-opts { list-style: none; padding: 0; margin: 10px 0 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 6px; }
.fd-as-q-opts li { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 10px; background: var(--brand-25, #F7F6FD); font-size: 13px; color: var(--text); }
.fd-as-q-opts li span { width: 22px; height: 22px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; background: var(--surface, #fff); color: var(--text-muted); flex: 0 0 auto; }
.fd-as-q-opts li.correct { background: rgba(18, 184, 134, .12); color: #087F5B; font-weight: 600; }
.fd-as-q-opts li.correct span { background: #12B886; color: #fff; }
.fd-as-q-opts li i { margin-left: auto; color: #12B886; }
.fd-as-q-expl { margin-top: 8px; font-size: 12.5px; color: var(--text-muted); }
.fd-as-q-expl summary { cursor: pointer; font-weight: 700; color: var(--brand-600); }
.fd-as-level-stats .st-approved { background: rgba(18, 184, 134, .12); color: #087F5B; }
.fd-as-level-stats .st-pending_review { background: rgba(232, 89, 12, .12); color: #C24E0A; }
.fd-as-level-stats .st-rejected { background: rgba(224, 49, 49, .12); color: #C92A2A; }
.fd-as-flat summary { cursor: pointer; font-weight: 700; color: var(--brand-600); font-size: 13px; margin-bottom: 10px; }
html[data-theme="dark"] .fd-as-q, html[data-theme="dark"] .fd-as-mrow { background: var(--fd-card-bg); }

/* ======================================================================
   2026-09-19 - Series & options manager (Super Admin > Academic structure)
   ====================================================================== */
.fd-as-manage-btn.tone-c { background: linear-gradient(135deg, #FF9F43, #D9480F); box-shadow: 0 12px 26px rgba(217, 72, 15, .24); }
.fd-as-mhero.tone-c { background: linear-gradient(135deg, rgba(255, 159, 67, .16), rgba(217, 72, 15, .04)); }
.fd-as-mhero.tone-c .fd-as-mhero-ico { background: linear-gradient(135deg, #FF9F43, #D9480F); }
.fd-as-series-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.fd-as-series-card { border-radius: 18px; padding: 14px; background: var(--surface, #fff); border: 1px solid var(--brand-100); box-shadow: 0 6px 18px rgba(30, 22, 90, .05); }
.fd-as-series-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.fd-as-series-head strong { display: block; font-size: 14.5px; color: var(--text); }
.fd-as-series-head span { font-size: 12px; color: var(--text-muted); }
.fd-as-series-ico { width: 40px; height: 40px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; background: linear-gradient(135deg, #6C63FF, #4A3DC0); flex: 0 0 auto; }
.fd-as-series-card.tone-1 .fd-as-series-ico { background: linear-gradient(135deg, #FF9F43, #D9480F); }
.fd-as-series-card.tone-2 .fd-as-series-ico { background: linear-gradient(135deg, #20C997, #0B7A57); }
.fd-as-series-card.tone-3 .fd-as-series-ico { background: linear-gradient(135deg, #4DABF7, #1971C2); }
.fd-as-series-card .fd-as-mlist { margin-top: 10px; }
.fd-as-series-link { display: flex; align-items: center; gap: 10px; width: 100%; margin-top: 12px; padding: 12px 14px; border-radius: 14px; border: 1.5px dashed #F2A65A; background: rgba(255, 159, 67, .08); color: #B8520A; font-weight: 600; font-size: 13px; text-align: left; cursor: pointer; }
.fd-as-series-link .fa-arrow-right { margin-left: auto; }
html[data-theme="dark"] .fd-as-series-card { background: var(--fd-card-bg); border-color: rgba(255, 255, 255, .06); }

/* ======================================================================
   2026-09-19 - Student self-study: topics -> lessons -> options -> MCQ
   ====================================================================== */
.fd-study-hero { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 20px; border-radius: 22px; margin-bottom: 14px; color: #fff;
    background: radial-gradient(120% 140% at 100% 0%, rgba(255, 255, 255, .18) 0%, rgba(255, 255, 255, 0) 45%), linear-gradient(135deg, var(--brand-500), var(--brand-600)); box-shadow: 0 14px 30px rgba(88, 73, 214, .25); }
.fd-study-hero-icon { width: 58px; height: 58px; border-radius: 18px; background: rgba(255, 255, 255, .18); display: inline-flex; align-items: center; justify-content: center; font-size: 24px; flex: 0 0 auto; }
.fd-study-hero-text { flex: 1 1 260px; min-width: 0; }
.fd-study-hero-text h2 { margin: 2px 0 4px; font-size: 22px; font-weight: 700; font-family: 'Poppins', sans-serif; color: #fff; }
.fd-study-hero-text p { margin: 0; font-size: 13px; opacity: .9; }
.fd-study-hero-kicker { font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; font-weight: 700; opacity: .85; }
.fd-study-hero-stats { display: flex; gap: 8px; }
.fd-study-hero-stats > div { min-width: 74px; padding: 10px 12px; border-radius: 14px; background: rgba(255, 255, 255, .16); text-align: center; }
.fd-study-hero-stats strong { display: block; font-size: 18px; line-height: 1.1; }
.fd-study-hero-stats span { font-size: 11px; opacity: .88; }

.fd-study-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.fd-study-head h3 { margin: 0; }
.fd-study-head .fd-context { margin: 4px 0 0; }
.fd-study-search { width: 260px; max-width: 100%; }
.fd-study-topic-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.fd-study-topic { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-align: left; padding: 16px 16px 14px; border-radius: 18px; border: 1px solid transparent; cursor: pointer; overflow: hidden;
    background: var(--fd-st-tint, var(--brand-25)); color: var(--text); transition: transform .18s ease, box-shadow .18s ease; min-height: 138px; }
.fd-study-topic::before { content: ''; position: absolute; right: -26px; top: -26px; width: 90px; height: 90px; border-radius: 50%; background: linear-gradient(135deg, var(--fd-st-a), var(--fd-st-b)); opacity: .14; }
.fd-study-topic:hover { transform: translateY(-3px); box-shadow: 0 12px 24px rgba(30, 22, 90, .10); }
.fd-study-topic-num { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 13px; color: #fff; padding: 5px 10px; border-radius: 10px; background: linear-gradient(135deg, var(--fd-st-a), var(--fd-st-b)); }
.fd-study-topic-name { font-weight: 700; font-size: 15px; line-height: 1.3; }
.fd-study-topic-meta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: auto; font-size: 12px; color: var(--text-muted); }
.fd-study-topic-meta i { color: var(--fd-st-b); margin-right: 3px; }
.fd-study-topic-go { position: absolute; right: 14px; bottom: 12px; width: 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; color: #fff; background: linear-gradient(135deg, var(--fd-st-a), var(--fd-st-b)); }

.fd-study-sheet .sheet-slide-title { margin-bottom: 10px; }
.fd-study-lesson-list { display: flex; flex-direction: column; gap: 8px; }
.fd-study-lesson { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border-radius: 16px; border: 1px solid var(--brand-100); background: var(--surface, #fff); text-align: left; cursor: pointer; color: var(--text); transition: border-color .15s, transform .15s; }
.fd-study-lesson:hover { border-color: var(--brand-300, #A9A2F2); transform: translateX(2px); }
.fd-study-lesson > .fa-chevron-right { margin-left: auto; color: var(--text-muted); font-size: 12px; }
.fd-study-lesson-num { width: 34px; height: 34px; border-radius: 11px; color: #fff; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); }
.fd-study-lesson-text { display: flex; flex-direction: column; min-width: 0; }
.fd-study-lesson-name { font-weight: 600; font-size: 14px; }
.fd-study-lesson-meta { font-size: 12px; color: var(--text-muted); }
.fd-study-lesson-all { border-style: dashed; background: var(--brand-25); }
.fd-study-lesson-all .fd-study-lesson-num { background: var(--brand-100); color: var(--brand-600); }
.fd-study-empty { text-align: center; padding: 18px 10px; color: var(--text-muted); }
.fd-study-empty > i { font-size: 30px; color: var(--brand-400, #8C84F6); margin-bottom: 8px; }
.fd-study-empty p { margin: 4px 0; }

.fd-study-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.fd-study-option { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 18px 16px 16px; border-radius: 20px; text-decoration: none; color: var(--text);
    background: var(--surface, #fff); border: 1px solid var(--brand-100); box-shadow: 0 8px 20px rgba(30, 22, 90, .06); transition: transform .18s ease, box-shadow .18s ease; min-height: 150px; }
.fd-study-option:hover { transform: translateY(-3px); box-shadow: 0 14px 28px rgba(30, 22, 90, .12); color: var(--text); }
.fd-study-option-icon { width: 48px; height: 48px; border-radius: 15px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 20px; margin-bottom: 4px; }
.fd-study-option-label { font-weight: 700; font-size: 15px; }
.fd-study-option-desc { font-size: 12px; color: var(--text-muted); }
.fd-study-option-badge { margin-top: auto; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); }

.fd-study-tool-head { display: flex; align-items: center; gap: 12px; margin: 4px 0 14px; }
.fd-study-back { width: 38px; height: 38px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; background: var(--brand-50); color: var(--brand-600); text-decoration: none; flex: 0 0 auto; }
.fd-study-tool-icon { width: 46px; height: 46px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 19px; flex: 0 0 auto; background: linear-gradient(135deg, #6C63FF, #5849D6); }
.fd-study-tool-icon.tool-video { background: linear-gradient(135deg, #FF9F43, #E8590C); }
.fd-study-tool-icon.tool-notes { background: linear-gradient(135deg, #20C997, #1C8A4C); }
.fd-study-tool-icon.tool-past { background: linear-gradient(135deg, #4DABF7, #1971C2); }
.fd-study-tool-titles { min-width: 0; }
.fd-study-tool-titles h2 { margin: 0; font-size: 20px; font-weight: 700; font-family: 'Poppins', sans-serif; }
.fd-study-tool-titles .fd-study-hero-kicker { color: var(--brand-600); }
.fd-study-notes-body { font-size: 14.5px; line-height: 1.7; white-space: normal; }

.fd-practice { max-width: 760px; margin: 0 auto; }
.fd-practice-top { display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 600; color: var(--text-muted); margin-bottom: 8px; }
.fd-practice-score { color: #B8790A; background: #FFF6E0; padding: 4px 10px; border-radius: 999px; }
.fd-practice-bar { height: 8px; border-radius: 999px; background: var(--brand-50); overflow: hidden; margin-bottom: 14px; }
.fd-practice-bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--brand-500), var(--brand-600)); transition: width .35s ease; }
.fd-practice-card { padding: 20px; border-radius: 22px; background: var(--surface, #fff); border: 1px solid var(--brand-100); box-shadow: 0 10px 26px rgba(30, 22, 90, .07); }
.fd-practice-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.fd-practice-tag { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); }
.fd-practice-tag.diff-easy { background: rgba(18, 184, 134, .12); color: #087F5B; }
.fd-practice-tag.diff-medium { background: rgba(232, 89, 12, .10); color: #C24E0A; }
.fd-practice-tag.diff-hard { background: rgba(224, 49, 49, .10); color: #C92A2A; }
.fd-practice-stem { font-size: 17px; font-weight: 600; line-height: 1.5; margin-bottom: 14px; color: var(--text); }
.fd-practice-photo { max-width: 100%; border-radius: 14px; margin-bottom: 14px; }
.fd-practice-options { display: flex; flex-direction: column; gap: 10px; }
.fd-practice-opt { display: flex; align-items: center; gap: 12px; width: 100%; padding: 13px 14px; border-radius: 16px; border: 1.5px solid var(--brand-100); background: var(--surface, #fff); text-align: left; cursor: pointer; color: var(--text); font-size: 14.5px; transition: border-color .15s, background .15s, transform .12s; }
.fd-practice-opt:hover:not(:disabled) { border-color: var(--brand-300, #A9A2F2); transform: translateX(2px); }
.fd-practice-letter { width: 32px; height: 32px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; background: var(--brand-50); color: var(--brand-600); flex: 0 0 auto; }
.fd-practice-opt-text { flex: 1 1 auto; }
.fd-practice-mark { font-size: 18px; }
.fd-practice-opt.selected { border-color: var(--brand-500); background: var(--brand-25); }
.fd-practice-opt.selected .fd-practice-letter { background: var(--brand-500); color: #fff; }
.fd-practice-opt.correct { border-color: #12B886; background: rgba(18, 184, 134, .10); }
.fd-practice-opt.correct .fd-practice-letter { background: #12B886; color: #fff; }
.fd-practice-opt.correct .fd-practice-mark { color: #0CA678; }
.fd-practice-opt.wrong { border-color: #FA5252; background: rgba(250, 82, 82, .08); }
.fd-practice-opt.wrong .fd-practice-letter { background: #FA5252; color: #fff; }
.fd-practice-opt.wrong .fd-practice-mark { color: #E03131; }
.fd-practice-opt:disabled { cursor: default; }
.fd-practice-feedback { margin-top: 14px; padding: 12px 14px; border-radius: 14px; font-size: 13.5px; }
.fd-practice-feedback.ok { background: rgba(18, 184, 134, .10); color: #087F5B; }
.fd-practice-feedback.bad { background: rgba(255, 159, 67, .12); color: #A04A08; }
.fd-practice-feedback-head { font-weight: 700; }
.fd-practice-feedback-body { margin-top: 6px; color: var(--text); line-height: 1.55; }
.fd-practice-actions { display: flex; justify-content: space-between; gap: 10px; margin-top: 14px; }
.fd-practice-actions .btn-primary { min-width: 160px; border-radius: 14px; }
.fd-practice-actions .btn-outline-secondary { border-radius: 14px; }
.fd-practice-result { text-align: center; padding: 26px 18px; border-radius: 24px; background: var(--surface, #fff); border: 1px solid var(--brand-100); box-shadow: 0 10px 26px rgba(30, 22, 90, .07); }
.fd-practice-ring { width: 150px; height: 150px; }
.fd-practice-ring-text { font-size: 24px; font-weight: 700; fill: var(--text); font-family: 'Poppins', sans-serif; }
.fd-practice-result h3 { margin: 10px 0 4px; }
.fd-practice-result-actions { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin: 16px 0 8px; }
.fd-practice-review { text-align: left; margin-top: 12px; }
.fd-practice-review summary { cursor: pointer; font-weight: 700; color: var(--brand-600); }
.fd-practice-review-row { display: flex; gap: 10px; padding: 10px 4px; border-bottom: 1px solid var(--brand-50); font-size: 13.5px; }
.fd-practice-review-icon { width: 24px; height: 24px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; color: #fff; flex: 0 0 auto; background: #FA5252; }
.fd-practice-review-row.ok .fd-practice-review-icon { background: #12B886; }
.fd-practice-review-ans { display: block; font-size: 12px; color: var(--text-muted); margin-top: 2px; }
html[data-theme="dark"] .fd-practice-card, html[data-theme="dark"] .fd-practice-opt, html[data-theme="dark"] .fd-practice-result,
html[data-theme="dark"] .fd-study-option, html[data-theme="dark"] .fd-study-lesson { background: var(--fd-card-bg); border-color: rgba(255, 255, 255, .07); }

/* Dashboard: self-study subjects + pending join banner (no school yet) */
.fd-selfstudy .fd-item-card-top-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.fd-selfstudy-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-top: 8px; }
.fd-selfstudy-card { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 16px 10px; text-decoration: none; color: var(--text); }
.fd-selfstudy-card:hover { color: var(--text); }
.fd-pending-join { display: flex; gap: 14px; align-items: flex-start; padding: 14px 16px; margin-bottom: 14px; border-radius: 18px; background: linear-gradient(135deg, rgba(255, 159, 67, .16), rgba(255, 159, 67, .05)); border: 1px solid rgba(232, 89, 12, .22); }
.fd-pending-join-icon { width: 40px; height: 40px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, #FF9F43, #E8590C); flex: 0 0 auto; }
.fd-pending-join strong { color: #A04A08; }
.fd-pending-join p { margin: 3px 0 0; font-size: 13px; color: var(--text); }
.fd-gs-continue { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 20px 22px; }
.fd-gs-continue h4 { margin: 0 0 4px; color: var(--brand-600); }
.fd-gs-continue .btn-primary { border-radius: 14px; padding: 10px 20px; font-weight: 600; }

/* "Join a school or class" popup (fd-join.js) */
.fd-join-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.fd-join-choice { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 18px; border-radius: 20px; border: 1px solid var(--brand-100); background: var(--surface, #fff); text-align: left; cursor: pointer; color: var(--text); transition: transform .18s, box-shadow .18s; }
.fd-join-choice:hover { transform: translateY(-3px); box-shadow: 0 12px 24px rgba(30, 22, 90, .10); }
.fd-join-choice-icon { width: 48px; height: 48px; border-radius: 15px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 20px; margin-bottom: 4px; }
.fd-join-choice-title { font-weight: 700; font-size: 15px; }
.fd-join-choice-desc { font-size: 12.5px; color: var(--text-muted); }
.fd-join-results { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.fd-join-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border-radius: 16px; border: 1px solid var(--brand-100); background: var(--surface, #fff); text-align: left; color: var(--text); cursor: pointer; margin: 0; }
.fd-join-row:disabled { opacity: .6; cursor: default; }
.fd-join-row > .fa-chevron-right { margin-left: auto; color: var(--text-muted); font-size: 12px; }
.fd-join-row-form .btn-sm-add { margin-left: auto; white-space: nowrap; }
.fd-join-row-icon { width: 38px; height: 38px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, #6C63FF, #5849D6); flex: 0 0 auto; }
.fd-join-row-icon.off { background: #ADB5BD; }
.fd-join-row-text { display: flex; flex-direction: column; min-width: 0; }
.fd-join-row-title { font-weight: 600; font-size: 14px; }
.fd-join-row-sub { font-size: 12px; color: var(--text-muted); }
.fd-join-class-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
.fd-join-class { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 14px 10px; border-radius: 16px; border: 1.5px solid var(--brand-100); background: var(--brand-25); cursor: pointer; color: var(--text); font-weight: 600; }
.fd-join-class i { font-size: 20px; color: var(--brand-600); }
.fd-join-class small { font-weight: 400; color: var(--text-muted); font-size: 11.5px; }
.fd-join-class.selected { border-color: var(--brand-500); background: var(--brand-50); box-shadow: 0 0 0 3px rgba(108, 99, 255, .18); }
.fd-join-code-row { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.fd-join-code-row .btn-primary { border-radius: 12px; }
html[data-theme="dark"] .fd-join-choice, html[data-theme="dark"] .fd-join-row { background: var(--fd-card-bg); border-color: rgba(255, 255, 255, .07); }

@media (max-width: 768px) {
    .fd-study-hero { padding: 16px; border-radius: 18px; }
    .fd-study-hero-stats { width: 100%; }
    .fd-study-hero-stats > div { flex: 1 1 0; }
    .fd-study-topic-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .fd-study-topic { min-height: 128px; padding: 14px 12px 12px; }
    .fd-study-topic-name { font-size: 14px; }
    .fd-study-options { gap: 10px; }
    .fd-study-option { min-height: 140px; padding: 14px 12px; }
    .fd-selfstudy-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
    .fd-selfstudy-card { padding: 12px 6px; }
    .fd-selfstudy-card .fd-dash-class-name { font-size: 12.5px; }
    .fd-practice-card { padding: 16px; border-radius: 18px; }
    .fd-practice-stem { font-size: 16px; }
    .fd-practice-actions .btn-primary { flex: 1 1 auto; }
    .fd-as-series-grid { grid-template-columns: 1fr; }
}

/* ======================================================================
   2026-09-19 (twenty-eighth follow-up) - one student layout, full-width
   topic rows, today's lesson, offline study, the new quiz screen
   ====================================================================== */
/* "add a little light gray on the calendar this week" */
.fd-week { background: #F4F5F9; border-color: #E9EAF1; }
html[data-theme="dark"] .fd-week { background: rgba(255, 255, 255, .04); border-color: rgba(255, 255, 255, .06); }

/* Student dashboard: no greeting block on mobile (name + class are in the top bar) */
@media (max-width: 768px) {
    .fd-student-hero { display: none; }
    .fd-student-home { padding-top: 0; }
    .fd-student-home > :first-child { margin-top: 0; }
}

/* Topics: one full-width numbered row each */
.fd-study-topic-list { display: flex; flex-direction: column; gap: 10px; }
.fd-study-topic-list .fd-study-topic {
    display: flex; flex-direction: row; align-items: center; gap: 14px; width: 100%; min-height: 0;
    padding: 14px 16px; border-radius: 18px; border: 1px solid var(--line, #ECEAF6); background: var(--surface, #fff);
    text-align: left; cursor: pointer; color: var(--text); overflow: hidden; position: relative;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.fd-study-topic-list .fd-study-topic::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; border-radius: 4px; background: var(--fd-tp, #6C63FF); opacity: 1; right: auto; width: 4px; height: auto; }
.fd-study-topic-list .fd-study-topic:hover { transform: translateY(-1px); box-shadow: 0 10px 22px rgba(30, 22, 90, .08); border-color: var(--brand-200, #C9C3F5); }
.fd-study-topic-list .fd-study-topic-num {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center;
    font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 15px; color: #fff; padding: 0; background: var(--fd-tp-g, linear-gradient(135deg, #6C63FF, #5849D6));
}
.fd-study-topic-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 auto; }
.fd-study-topic-list .fd-study-topic-name { font-weight: 700; font-size: 15px; line-height: 1.3; }
.fd-study-topic-list .fd-study-topic-meta { margin: 0; display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; color: var(--text-muted); }
.fd-study-topic-list .fd-study-topic-meta i { color: var(--fd-tp, #6C63FF); margin-right: 3px; }
.fd-study-topic-list .fd-study-topic-go { position: static; flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; color: var(--fd-tp, #6C63FF); background: var(--brand-50); }
.fd-study-topic.tone-0 { --fd-tp: #6C63FF; --fd-tp-g: linear-gradient(135deg, #6C63FF, #5849D6); }
.fd-study-topic.tone-1 { --fd-tp: #E8590C; --fd-tp-g: linear-gradient(135deg, #FF9F43, #E8590C); }
.fd-study-topic.tone-2 { --fd-tp: #1C8A4C; --fd-tp-g: linear-gradient(135deg, #20C997, #1C8A4C); }
.fd-study-topic.tone-3 { --fd-tp: #1971C2; --fd-tp-g: linear-gradient(135deg, #4DABF7, #1971C2); }
.fd-study-topic.tone-4 { --fd-tp: #C2255C; --fd-tp-g: linear-gradient(135deg, #F783AC, #C2255C); }
.fd-study-topic.tone-5 { --fd-tp: #087F5B; --fd-tp-g: linear-gradient(135deg, #38D9A9, #087F5B); }
html[data-theme="dark"] .fd-study-topic-list .fd-study-topic { background: var(--fd-card-bg); border-color: rgba(255, 255, 255, .06); }

/* Save for offline */
.fd-study-offline { display: flex; align-items: center; gap: 12px; padding: 12px 14px; margin: 0 0 12px; border-radius: 16px; background: var(--brand-25); border: 1px dashed var(--brand-200, #C9C3F5); }
.fd-study-offline-icon { width: 38px; height: 38px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, #4DABF7, #1971C2); flex: 0 0 auto; }
.fd-study-offline-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.fd-study-offline-text strong { font-size: 13.5px; }
.fd-study-offline-text span { font-size: 12px; color: var(--text-muted); }
.fd-study-offline .btn-sm-add { white-space: nowrap; }
.fd-study-offline.saved { background: rgba(18, 184, 134, .08); border-color: rgba(18, 184, 134, .35); border-style: solid; }
.fd-study-offline.saved .fd-study-offline-icon { background: linear-gradient(135deg, #20C997, #0CA678); }

/* Tasks / Online Classes for a student with no school yet */
.fd-study-locked { text-align: center; padding: 26px 14px; }
.fd-study-locked-icon { position: relative; display: inline-flex; width: 64px; height: 64px; border-radius: 20px; align-items: center; justify-content: center; font-size: 26px; color: var(--brand-600); background: var(--brand-50); margin-bottom: 10px; }
.fd-study-locked-badge { position: absolute; right: -6px; bottom: -6px; width: 26px; height: 26px; border-radius: 50%; font-size: 11px; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: #868E96; border: 3px solid var(--surface, #fff); }
.fd-study-locked h4 { margin: 4px 0; font-size: 16px; }
.fd-study-locked p { color: var(--text-muted); font-size: 13px; max-width: 420px; margin: 0 auto 12px; }

/* Today's lesson (subject Study tab) */
.fd-today-lessons { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.fd-today-lesson { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-radius: 18px; text-decoration: none; color: #fff;
    background: linear-gradient(135deg, var(--brand-500), var(--brand-600)); box-shadow: 0 12px 24px rgba(88, 73, 214, .22); }
.fd-today-lesson:hover { color: #fff; transform: translateY(-1px); }
.fd-today-lesson-icon { width: 44px; height: 44px; border-radius: 14px; background: rgba(255, 255, 255, .18); display: inline-flex; align-items: center; justify-content: center; font-size: 18px; flex: 0 0 auto; }
.fd-today-lesson-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.fd-today-lesson-kicker { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; opacity: .85; }
.fd-today-lesson-title { font-weight: 700; font-size: 15.5px; }
.fd-today-lesson-sub { font-size: 12px; opacity: .85; }
.fd-today-lesson-go { font-size: 12.5px; font-weight: 700; background: rgba(255, 255, 255, .2); padding: 6px 12px; border-radius: 999px; white-space: nowrap; }
.fd-today-none { margin: 2px 4px 12px; }

/* Profile popup: leave the active school */
.fd-menu-leave { margin: 2px 0 8px; text-align: right; }
.fd-menu-leave button { border: none; background: none; color: #E03131; font-size: 12px; font-weight: 600; padding: 4px 8px; cursor: pointer; }

/* ----------------------------------------------------------------------
   The quiz screen (fd-study.js .fdq) - full screen over the page, or
   inline on study_tool.php deep links
   ---------------------------------------------------------------------- */
body.fdq-open { overflow: hidden; }
.fdq { position: fixed; inset: 0; z-index: 3000; display: flex; flex-direction: column; background: #F5F4FB; color: var(--text);
    transform: translateY(24px); opacity: 0; transition: transform .26s cubic-bezier(.32, .72, 0, 1), opacity .2s ease; }
.fdq.in { transform: none; opacity: 1; }
.fdq.fdq-inline { position: relative; inset: auto; z-index: auto; min-height: 70vh; border-radius: 24px; overflow: hidden; transform: none; opacity: 1; box-shadow: 0 14px 34px rgba(30, 22, 90, .10); }
.fdq-top { display: flex; align-items: center; gap: 12px; padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 12px; color: #fff;
    background: radial-gradient(120% 160% at 100% 0%, rgba(255, 255, 255, .20) 0%, rgba(255, 255, 255, 0) 50%), linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6)); }
.fdq-close { width: 40px; height: 40px; border-radius: 12px; border: none; background: rgba(255, 255, 255, .18); color: #fff; font-size: 17px; flex: 0 0 auto; cursor: pointer; }
.fdq-titles { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.fdq-titles strong { font-size: 16px; font-family: 'Poppins', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fdq-kicker { font-size: 11.5px; font-weight: 600; opacity: .88; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fdq-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px; background: var(--brand-50); color: var(--brand-600); white-space: nowrap; }
.fdq-top .fdq-chip { background: rgba(255, 255, 255, .2); color: #fff; }
.fdq-steps { display: flex; gap: 5px; padding: 12px 16px 0; background: transparent; }
.fdq-steps span { flex: 1 1 0; height: 7px; border-radius: 999px; background: #E3E1F2; transition: background .25s ease, transform .25s ease; }
.fdq-steps span.cur { background: var(--brand-300, #A9A2F2); transform: scaleY(1.25); }
.fdq-steps span.ok { background: #12B886; }
.fdq-steps span.bad { background: #FA5252; }
.fdq-steps span.skip { background: #ADB5BD; }
.fdq-body { flex: 1 1 auto; overflow-y: auto; padding: 16px 16px 24px; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.fdq-body::-webkit-scrollbar { display: none; }
.fdq-body > * { max-width: 720px; margin-left: auto; margin-right: auto; }
@keyframes fdqIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.fdq-in { animation: fdqIn .32s cubic-bezier(.32, .72, 0, 1) both; }
.fdq-loading { text-align: center; padding: 60px 10px; color: var(--text-muted); }
.fdq-spinner { display: inline-block; width: 38px; height: 38px; border-radius: 50%; border: 4px solid #E3E1F2; border-top-color: var(--brand-500, #6C63FF); animation: fdSpin .8s linear infinite; }
.fdq-card { background: var(--surface, #fff); border-radius: 26px; padding: 20px 18px 18px; box-shadow: 0 16px 36px rgba(30, 22, 90, .08); }
.fdq-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }
.fdq-count { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 15px; color: var(--brand-600); margin-right: auto; }
.fdq-count small { font-size: 12px; color: var(--text-muted); font-weight: 600; }
.fdq-chip.diff-easy { background: rgba(18, 184, 134, .12); color: #087F5B; }
.fdq-chip.diff-medium { background: rgba(232, 89, 12, .12); color: #C24E0A; }
.fdq-chip.diff-hard { background: rgba(224, 49, 49, .12); color: #C92A2A; }
.fdq-streak { background: #FFF3E0 !important; color: #D9480F !important; }
.fdq-stem { font-size: 19px; line-height: 1.45; font-weight: 700; margin: 4px 0 8px; font-family: 'Poppins', sans-serif; color: var(--text); }
.fdq-hint { font-size: 12.5px; color: var(--text-muted); margin: 0 0 8px; }
.fdq-photo { display: block; max-width: 100%; border-radius: 16px; margin: 6px 0 10px; }
.fdq-opts { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
@keyframes fdqOpt { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }
.fdq-opt { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 14px; border-radius: 18px; border: 2px solid #E7E5F4; background: var(--surface, #fff);
    border-bottom-width: 4px; text-align: left; font-size: 15px; color: var(--text); cursor: pointer; animation: fdqOpt .3s ease both;
    transition: border-color .15s ease, background .15s ease, transform .1s ease; }
.fdq-opt:active:not(:disabled) { transform: translateY(2px); border-bottom-width: 2px; }
.fdq-letter { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 11px; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; background: #F0EFFA; color: var(--brand-600); transition: all .15s ease; }
.fdq-opt-text { flex: 1 1 auto; line-height: 1.4; }
.fdq-mark { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 13px; color: #fff; }
.fdq-opt.sel { border-color: var(--brand-500, #6C63FF); background: #F4F2FF; }
.fdq-opt.sel .fdq-letter { background: var(--brand-500, #6C63FF); color: #fff; }
.fdq-opt.right { border-color: #12B886; background: #E6FCF5; }
.fdq-opt.right .fdq-letter, .fdq-opt.right .fdq-mark { background: #12B886; color: #fff; }
.fdq-opt.wrong { border-color: #FA5252; background: #FFF0F0; animation: fdqShake .35s ease; }
.fdq-opt.wrong .fdq-letter, .fdq-opt.wrong .fdq-mark { background: #FA5252; color: #fff; }
.fdq-opt.dim { opacity: .55; }
.fdq-opt:disabled { cursor: default; }
@keyframes fdqShake { 0%, 100% { transform: none; } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
.fdq-bar { display: flex; gap: 10px; padding: 12px 16px calc(14px + env(safe-area-inset-bottom, 0px)); background: var(--surface, #fff); border-top: 1px solid #ECEBF5; }
.fdq-bar > * { max-width: 720px; }
.fdq-btn { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 52px; padding: 0 18px; border-radius: 16px; border: none; font-weight: 800; font-size: 15px; letter-spacing: .01em; cursor: pointer; text-decoration: none; transition: transform .1s ease, filter .15s ease; }
.fdq-btn:active:not(:disabled) { transform: translateY(2px); }
.fdq-btn:disabled { opacity: .45; cursor: default; }
.fdq-btn-primary { color: #fff; background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6)); box-shadow: 0 5px 0 #4336B8; }
.fdq-btn-primary:disabled { box-shadow: none; background: #CFCBEF; }
.fdq-btn-ghost { flex: 0 0 auto; color: var(--text-muted); background: #F0EFFA; }
.fdq-btn-ok { color: #fff; background: #12B886; box-shadow: 0 5px 0 #0B8A63; }
.fdq-btn-bad { color: #fff; background: #FA5252; box-shadow: 0 5px 0 #C92A2A; }
.fdq-wide { flex: 1 1 100%; }
.fdq-sheet { padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px)); transform: translateY(100%); transition: transform .28s cubic-bezier(.32, .72, 0, 1); }
.fdq-sheet.up { transform: none; }
.fdq-sheet.ok { background: #D3F9D8; }
.fdq-sheet.bad { background: #FFE3E3; }
.fdq-sheet-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.fdq-sheet-head strong { display: block; font-size: 18px; font-family: 'Poppins', sans-serif; }
.fdq-sheet-head span { font-size: 13px; }
.fdq-sheet.ok .fdq-sheet-head { color: #087F5B; }
.fdq-sheet.bad .fdq-sheet-head { color: #C92A2A; }
.fdq-sheet-icon { width: 42px; height: 42px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 18px; flex: 0 0 auto; }
.fdq-sheet.ok .fdq-sheet-icon { background: #12B886; }
.fdq-sheet.bad .fdq-sheet-icon { background: #FA5252; }
.fdq-sheet-body { font-size: 13.5px; line-height: 1.55; color: #343A40; margin-bottom: 12px; max-height: 26vh; overflow-y: auto; }
.fdq-empty { text-align: center; padding: 50px 14px; }
.fdq-empty-icon { display: inline-flex; width: 76px; height: 76px; border-radius: 24px; align-items: center; justify-content: center; font-size: 30px; color: var(--brand-600); background: #ECEAFF; margin-bottom: 12px; }
.fdq-empty h3 { font-size: 19px; margin: 6px 0; }
.fdq-empty p { color: var(--text-muted); font-size: 14px; max-width: 420px; margin: 0 auto; }
.fdq-notes { background: var(--surface, #fff); border-radius: 24px; padding: 22px 20px; box-shadow: 0 16px 36px rgba(30, 22, 90, .08); }
.fdq-notes-tag { display: inline-flex; gap: 6px; align-items: center; font-size: 12px; font-weight: 700; color: #1C8A4C; background: #E6FCF5; padding: 4px 10px; border-radius: 999px; margin-bottom: 12px; }
.fdq-notes-body { font-size: 15.5px; line-height: 1.75; }
.fdq-result { text-align: center; padding: 10px 0 6px; }
.fdq-ring-wrap { position: relative; width: 168px; height: 168px; margin: 6px auto 8px; }
.fdq-ring { width: 100%; height: 100%; }
.fdq-ring circle { fill: none; stroke-width: 12; }
.fdq-ring-track { stroke: #E7E5F4; }
.fdq-ring-fill { stroke-linecap: round; transition: stroke-dasharray 1s cubic-bezier(.32, .72, 0, 1); }
.fdq-ring-fill.tone-ok { stroke: #12B886; }
.fdq-ring-fill.tone-mid { stroke: #FD7E14; }
.fdq-ring-fill.tone-low { stroke: #FA5252; }
.fdq-ring-text { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.fdq-ring-text strong { font-size: 36px; font-family: 'Poppins', sans-serif; line-height: 1; }
.fdq-ring-text span { font-size: 12px; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.fdq-result h2 { font-size: 22px; margin: 6px 0 2px; font-family: 'Poppins', sans-serif; }
.fdq-result-sub { color: var(--text-muted); margin: 0 0 16px; }
.fdq-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.fdq-stats > div { background: var(--surface, #fff); border-radius: 16px; padding: 12px 6px; box-shadow: 0 6px 16px rgba(30, 22, 90, .06); }
.fdq-stats strong { display: block; font-size: 20px; font-family: 'Poppins', sans-serif; }
.fdq-stats span { font-size: 11.5px; color: var(--text-muted); font-weight: 600; }
.fdq-stats .ok strong { color: #0CA678; }
.fdq-stats .bad strong { color: #E03131; }
.fdq-best { margin: 14px 0 0; color: #D9480F; font-weight: 700; font-size: 13.5px; }
.fdq-review { text-align: left; margin-top: 16px; background: var(--surface, #fff); border-radius: 18px; padding: 12px 14px; }
.fdq-review summary { cursor: pointer; font-weight: 700; color: var(--brand-600); }
.fdq-review-row { padding: 10px 0; border-bottom: 1px solid #F0EFFA; font-size: 13.5px; }
.fdq-review-row p { margin: 0 0 4px; font-weight: 600; }
.fdq-review-row span { color: #0CA678; font-size: 12.5px; }
html[data-theme="dark"] .fdq { background: #15132B; }
html[data-theme="dark"] .fdq-card, html[data-theme="dark"] .fdq-opt, html[data-theme="dark"] .fdq-bar, html[data-theme="dark"] .fdq-notes,
html[data-theme="dark"] .fdq-stats > div, html[data-theme="dark"] .fdq-review { background: var(--fd-card-bg); border-color: rgba(255, 255, 255, .08); }
html[data-theme="dark"] .fdq-opt.sel { background: rgba(108, 99, 255, .18); }
html[data-theme="dark"] .fdq-opt.right { background: rgba(18, 184, 134, .18); }
html[data-theme="dark"] .fdq-opt.wrong { background: rgba(250, 82, 82, .16); }
html[data-theme="dark"] .fdq-sheet.ok { background: #123D2E; }
html[data-theme="dark"] .fdq-sheet.bad { background: #43191C; }
html[data-theme="dark"] .fdq-sheet-body { color: #E9ECEF; }
@media (min-width: 769px) {
    .fdq-bar { justify-content: center; }
    .fdq-sheet { display: flex; flex-direction: column; align-items: center; }
    .fdq-sheet > * { width: 100%; max-width: 720px; }
    .fdq-stem { font-size: 21px; }
}
@media (max-width: 420px) {
    .fdq-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.fdq [hidden] { display: none !important; }
.fdq-sheet .fdq-btn { width: 100%; }
@media (max-width: 768px) { .fd-student-home { margin-top: -14px; } }

/* ======================================================================
   2026-09-19 (twenty-ninth follow-up) - colourful study screens, the
   account-type card look, quiz settings/timer/pause, trophy + share
   ====================================================================== */
.input-icon-wrap.is-textarea .input-icon { top: 16px; transform: none; }

/* Name capitalisation on display ("even for words that where not capitalized") */
.fd-study-topic-name, .fd-study-lesson-name, .fd-subj-name, .fd-dash-class-name, .fdq-titles strong,
.fd-dash-greeting, .fd-tool-tab-name, #fdcSheetTitle { text-transform: capitalize; }

/* Shared tone palette: --t (strong), --tg (gradient), --tl (light tint) */
.tone-0 { --t: #5849D6; --tg: linear-gradient(135deg, #7C73FF, #5849D6); --tl: #F0EEFF; }
.tone-1 { --t: #E8590C; --tg: linear-gradient(135deg, #FFA94D, #E8590C); --tl: #FFF1E6; }
.tone-2 { --t: #1C8A4C; --tg: linear-gradient(135deg, #38D9A9, #1C8A4C); --tl: #E6F9F0; }
.tone-3 { --t: #1971C2; --tg: linear-gradient(135deg, #74C0FC, #1971C2); --tl: #E7F3FF; }
.tone-4 { --t: #C2255C; --tg: linear-gradient(135deg, #FAA2C1, #C2255C); --tl: #FFEEF4; }
.tone-5 { --t: #7B3FA0; --tg: linear-gradient(135deg, #CC8BEA, #7B3FA0); --tl: #F6ECFB; }
.tone-all { --t: #495057; --tg: linear-gradient(135deg, #868E96, #495057); --tl: #F1F3F5; }
html[data-theme="dark"] .tone-0, html[data-theme="dark"] .tone-1, html[data-theme="dark"] .tone-2, html[data-theme="dark"] .tone-3,
html[data-theme="dark"] .tone-4, html[data-theme="dark"] .tone-5, html[data-theme="dark"] .tone-all { --tl: rgba(255, 255, 255, .05); }

/* Topic rows: icon medallion, light tint of its own colour, progress ring - no border */
.fd-study-topic-list .fd-study-topic { background: var(--tl, #F0EEFF); border: none; box-shadow: none; padding: 14px; }
.fd-study-topic-list .fd-study-topic::before { display: none; }
.fd-study-topic-list .fd-study-topic:hover { box-shadow: 0 10px 22px rgba(30, 22, 90, .08); }
.fd-st-icon { flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 19px; color: #fff; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); box-shadow: 0 6px 14px rgba(30, 22, 90, .12); }
.fd-study-topic-list .fd-study-topic-meta i { color: var(--t, #5849D6); }
.fd-st-ring { position: relative; flex: 0 0 auto; width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center; }
.fd-st-ring svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.fd-st-ring circle { fill: none; stroke-width: 3.6; }
.fd-st-ring .trk { stroke: rgba(0, 0, 0, .08); }
.fd-st-ring .bar { stroke: var(--t, #5849D6); stroke-linecap: round; transition: stroke-dasharray .6s ease; }
.fd-st-ring b { position: relative; font-size: 10.5px; font-weight: 800; color: var(--t, #5849D6); }
.fd-st-ring b::after { content: '%'; font-size: 8px; }
.fd-st-ring.done { border-radius: 50%; background: #12B886; color: #fff; font-size: 17px; box-shadow: 0 6px 14px rgba(18, 184, 134, .35); }
.fd-st-go { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: var(--tg); font-size: 13px; }
html[data-theme="dark"] .fd-st-ring .trk { stroke: rgba(255, 255, 255, .12); }

/* Lessons popup: same look */
.fd-study-lesson-list .fd-study-lesson { background: var(--tl, #F0EEFF); border: none; border-radius: 18px; padding: 12px 14px; gap: 12px; }
.fd-study-lesson-list .fd-study-lesson:hover { transform: translateY(-1px); box-shadow: 0 8px 18px rgba(30, 22, 90, .08); }
.fd-sl-icon { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); }
.fd-sl-best { margin-left: auto; flex: 0 0 auto; font-size: 11.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px; background: rgba(255, 255, 255, .8); color: var(--t, #5849D6); white-space: nowrap; }
.fd-sl-best.ok { background: #12B886; color: #fff; }
.fd-study-lesson-all { border: none !important; }

/* "How do you want to study?" - the sign-up account-type card look */
.fd-study-options { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.fd-study-options .fd-study-option { align-items: center; text-align: center; border: 2px solid transparent; border-radius: 20px; padding: 22px 12px 18px; box-shadow: none; min-height: 0; background: var(--ol, #F0EEFF); }
.fd-study-options .fd-study-option:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(88, 73, 214, .12); border-color: var(--oc, #5849D6); }
.fd-study-options .fd-study-option-icon { width: 56px; height: 56px; border-radius: 50%; margin: 0 auto 10px; font-size: 22px; background: var(--og, linear-gradient(135deg, #7C73FF, #5849D6)); }
.fd-study-options .fd-study-option-label { font-size: 14px; }
.fd-study-options .fd-study-option-desc { font-size: 11.5px; }
.fd-study-options .fd-study-option-badge { margin: 8px auto 0; background: rgba(255, 255, 255, .85); color: var(--oc, #5849D6); }
.fd-study-option.opt-mcq { --ol: #F0EEFF; --oc: #5849D6; --og: linear-gradient(135deg, #7C73FF, #5849D6); }
.fd-study-option.opt-video { --ol: #FFF1E6; --oc: #E8590C; --og: linear-gradient(135deg, #FFA94D, #E8590C); }
.fd-study-option.opt-notes { --ol: #E6F9F0; --oc: #1C8A4C; --og: linear-gradient(135deg, #38D9A9, #1C8A4C); }
.fd-study-option.opt-past { --ol: #E7F3FF; --oc: #1971C2; --og: linear-gradient(135deg, #74C0FC, #1971C2); }
html[data-theme="dark"] .fd-study-options .fd-study-option { --ol: rgba(255, 255, 255, .05); }

/* Desktop: topics and lessons as the account-type card grid */
@media (min-width: 769px) {
    .fd-study-topic-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 16px; }
    .fd-study-topic-list .fd-study-topic { flex-direction: column; text-align: center; padding: 26px 14px 20px; border-radius: 20px; border: 2px solid transparent; transition: all .3s ease; }
    .fd-study-topic-list .fd-study-topic:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(88, 73, 214, .12); border-color: var(--t); }
    .fd-study-topic-list .fd-st-icon { width: 56px; height: 56px; font-size: 22px; margin: 0 auto 4px; }
    .fd-study-topic-list .fd-study-topic-text { align-items: center; }
    .fd-study-topic-list .fd-study-topic-meta { justify-content: center; font-size: 11px; }
    .fd-study-topic-list .fd-st-ring, .fd-study-topic-list .fd-st-go { position: absolute; top: 10px; right: 10px; width: 34px; height: 34px; }
    .fd-study-topic-list .fd-st-ring b { font-size: 9px; }
    .fd-study-lesson-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
    .fd-study-lesson-list .fd-study-lesson { flex-direction: column; text-align: center; padding: 22px 12px 16px; border-radius: 20px; position: relative; }
    .fd-study-lesson-list .fd-sl-icon { width: 52px; height: 52px; font-size: 20px; margin: 0 auto 4px; }
    .fd-study-lesson-list .fd-study-lesson-text { align-items: center; }
    .fd-study-lesson-list .fd-sl-best { margin: 6px auto 0; }
    .fd-study-options { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Dashboard "My Subjects" - account-type cards */
.fd-subj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; margin-bottom: 18px; }
.fd-subj-card { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px; padding: 22px 10px 18px; border-radius: 20px; border: 2px solid transparent;
    background: var(--tl); color: var(--text); text-decoration: none; cursor: pointer; transition: all .3s ease; }
.fd-subj-card:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(88, 73, 214, .12); border-color: var(--t); color: var(--text); }
.fd-subj-icon { width: 56px; height: 56px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-size: 22px; color: #fff; background: var(--tg); }
.fd-subj-name { font-size: 14px; font-weight: 700; line-height: 1.25; }
.fd-subj-sub { font-size: 11px; color: var(--text-muted); }
/*
 * 2026-09-26 (forty-sixth follow-up), quoted: "on mobile screen lets have the
 * my subjects slide horizontally. while it stays same way on desktop."
 *
 * One row that scrolls sideways instead of a wrapping grid. Notes on the
 * details, because each one is load-bearing:
 *
 *  - scoped to .fd-subj-strip, which only the dashboard section carries. The
 *    same cards are used by student/catalog.php, which is a searchable browse
 *    list of the whole catalog - dozens of results in one sideways row would
 *    be worse, not better, so that page keeps the wrapping grid.
 *  - grid-auto-flow: column keeps the same .fd-subj-grid element and the same
 *    cards; only the flow direction changes, so nothing above needs a second
 *    version of the markup.
 *  - scroll-snap-type on the strip plus scroll-snap-align on the card means a
 *    flick lands on a card rather than halfway through one.
 *  - the negative margin + matching padding let the strip bleed to both screen
 *    edges (so it reads as a scroller) while the first and last cards still sit
 *    on the page's own gutter.
 *  - -webkit-overflow-scrolling for momentum on iOS; scrollbar-width: none
 *    because a visible bar under a 3-card strip looks broken.
 *  - the hover lift is dropped here: on a touch screen it fires on tap and
 *    fights the scroll.
 */
@media (max-width: 768px) {
    .fd-subj-grid.fd-subj-strip {
        grid-template-columns: none;
        grid-auto-flow: column;
        grid-auto-columns: 40%;
        gap: 10px;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
        margin-left: -16px;
        margin-right: -16px;
        padding: 2px 16px 6px;
    }
    .fd-subj-grid.fd-subj-strip::-webkit-scrollbar { display: none; }
    .fd-subj-grid:not(.fd-subj-strip) { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
    .fd-subj-card { padding: 16px 6px 14px; scroll-snap-align: start; }
    .fd-subj-card:hover { transform: none; box-shadow: none; }
    .fd-subj-icon { width: 44px; height: 44px; font-size: 18px; margin-bottom: 8px; }
    .fd-subj-name { font-size: 12px; }
    .fd-subj-sub { font-size: 10px; }
}
@media (max-width: 420px) {
    /* Narrower phones: the third card should still peek in, so the strip
       reads as scrollable without anyone having to try. */
    .fd-subj-grid.fd-subj-strip { grid-auto-columns: 45%; }
}

/* Bottom nav labels: two words per line on the mobile dock */
.tab-label .fd-tl-line { display: inline; }
@media (max-width: 768px) {
    body.fd-dock-scroll .vertical-tabs-wrapper .tab-label { white-space: normal; line-height: 1.12; text-align: center; overflow: hidden; }
    body.fd-dock-scroll .vertical-tabs-wrapper .tab-label .fd-tl-line { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
}

/* ---------------- Quiz screen additions ---------------- */
.fdq-top-right { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.fdq-titles { padding-left: 2px; }
.fdq-timer b { font-variant-numeric: tabular-nums; }
.fdq-timer.warn { background: #FFE3E3 !important; color: #C92A2A !important; animation: fdqPulse 1s ease infinite; }
@keyframes fdqPulse { 50% { transform: scale(1.06); } }
.fdq-prog { position: relative; width: 46px; height: 46px; display: inline-flex; align-items: center; justify-content: center; }
.fdq-prog svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.fdq-prog circle { fill: none; stroke-width: 4.5; }
.fdq-prog .trk { stroke: rgba(255, 255, 255, .25); }
.fdq-prog .bar { stroke: #fff; stroke-linecap: round; stroke-dasharray: 0 200; transition: stroke-dasharray .45s cubic-bezier(.32, .72, 0, 1); }
.fdq-prog b { position: relative; font-size: 11px; font-weight: 800; color: #fff; }
.fdq-prog.full .bar { stroke: #8CE99A; }
.fdq-steps { display: none; }

.fdq-body { display: flex; flex-direction: column; }
.fdq-body > .fdq-q { flex: 1 0 auto; width: 100%; display: flex; flex-direction: column; }
.fdq-q-top { background: var(--surface, #fff); border-radius: 24px; padding: 18px 18px 16px; box-shadow: 0 12px 30px rgba(30, 22, 90, .07); }
.fdq-count i { margin-right: 4px; }
.fdq-q .fdq-opts { margin-top: auto; padding-top: 18px; }
.fdq-opt { border-width: 2px; border-bottom-width: 4px; border-color: transparent; background: var(--ob, #F0EEFF); }
.fdq-opt.t0 { --ob: #F0EEFF; --oc: #5849D6; }
.fdq-opt.t1 { --ob: #FFF1E6; --oc: #E8590C; }
.fdq-opt.t2 { --ob: #E6F9F0; --oc: #1C8A4C; }
.fdq-opt.t3 { --ob: #E7F3FF; --oc: #1971C2; }
.fdq-opt.t4 { --ob: #FFEEF4; --oc: #C2255C; }
.fdq-opt.t5 { --ob: #F6ECFB; --oc: #7B3FA0; }
.fdq-opt { border-bottom-color: rgba(0, 0, 0, .06); }
.fdq-opt .fdq-letter { background: #fff; color: var(--oc, #5849D6); }
.fdq-opt.sel { border-color: var(--oc); background: var(--ob); }
.fdq-opt.sel .fdq-letter { background: var(--oc); color: #fff; }
.fdq-opts.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.fdq-opts.grid .fdq-opt { flex-direction: column; justify-content: center; text-align: center; min-height: 96px; padding: 14px 10px; gap: 8px; }
.fdq-opts.grid .fdq-mark { position: absolute; top: 8px; right: 8px; }
.fdq-opts.grid .fdq-opt { position: relative; }
.fdq-submit { margin-top: 12px; width: 100%; }
.fdq-toast { align-self: center; margin-top: 12px; padding: 8px 16px; border-radius: 999px; font-weight: 800; font-size: 14px; animation: fdqIn .25s ease both; }
.fdq-toast.ok { background: #D3F9D8; color: #087F5B; }
.fdq-toast span { font-weight: 600; font-size: 12px; margin-left: 4px; opacity: .8; }
html[data-theme="dark"] .fdq-q-top { background: var(--fd-card-bg); }
html[data-theme="dark"] .fdq-opt { --ob: rgba(255, 255, 255, .06); }

.fdq-bar.fdq-controls { justify-content: space-around; gap: 6px; padding-top: 8px; padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
.fdq-icon-btn { flex: 0 0 auto; display: inline-flex; flex-direction: column; align-items: center; gap: 3px; min-width: 64px; padding: 6px 10px; border: none; background: none; color: var(--text-muted); font-size: 11px; font-weight: 700; cursor: pointer; border-radius: 14px; }
.fdq-icon-btn i { width: 42px; height: 42px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 16px; background: #F0EFFA; color: var(--brand-600, #5849D6); }
.fdq-icon-btn.danger i { background: #FFF0F0; color: #E03131; }
.fdq-icon-btn:disabled { opacity: .4; }
.fdq-bar .fdq-icon-btn span { line-height: 1; }
.fdq-result-bar { flex-wrap: wrap; align-items: center; }
.fdq-result-bar .fdq-btn { flex: 1 1 0; min-width: 0; padding: 0 12px; }
.fdq-btn-share { color: #fff; background: linear-gradient(135deg, #20C997, #0CA678); box-shadow: 0 5px 0 #087F5B; }
@media (max-width: 480px) {
    .fdq-result-bar .fdq-icon-btn { min-width: 48px; padding: 4px; }
    .fdq-result-bar .fdq-icon-btn span { display: none; }
    .fdq-result-bar .fdq-btn { font-size: 13.5px; padding: 0 8px; min-height: 48px; }
}

/* Pause + settings modals */
.fdq-modal { position: absolute; inset: 0; z-index: 5; display: flex; align-items: flex-end; justify-content: center; background: rgba(21, 19, 43, .45); backdrop-filter: blur(3px); }
.fdq-modal-card { width: 100%; max-width: 560px; max-height: 88%; overflow-y: auto; scrollbar-width: none; background: var(--surface, #fff); border-radius: 26px 26px 0 0; padding: 20px 18px calc(18px + env(safe-area-inset-bottom, 0px)); }
.fdq-modal-card::-webkit-scrollbar { display: none; }
@media (min-width: 769px) { .fdq-modal { align-items: center; } .fdq-modal-card { border-radius: 26px; } }
.fdq-paused { text-align: center; }
.fdq-paused-icon { display: inline-flex; width: 72px; height: 72px; border-radius: 50%; align-items: center; justify-content: center; font-size: 28px; color: #fff; background: linear-gradient(135deg, #FFA94D, #E8590C); margin-bottom: 8px; }
.fdq-paused h3 { margin: 4px 0; font-family: 'Poppins', sans-serif; }
.fdq-paused p { color: var(--text-muted); margin: 0 0 16px; }
.fdq-set-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.fdq-set-head h3 { margin: 0; font-size: 18px; font-family: 'Poppins', sans-serif; }
.fdq-set-head span { font-size: 12px; color: var(--text-muted); }
.fdq-set-head-ico { width: 44px; height: 44px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6)); }
.fdq-set-group { margin-bottom: 14px; }
.fdq-set-label { display: block; font-size: 12.5px; font-weight: 700; color: var(--text); margin-bottom: 8px; }
.fdq-set-label i { color: var(--brand-600); margin-right: 4px; }
.fdq-seg { display: flex; gap: 6px; flex-wrap: wrap; }
.fdq-seg button { flex: 1 1 auto; min-width: 54px; padding: 9px 10px; border-radius: 12px; border: 2px solid #ECEBF5; background: #F7F6FD; color: var(--text); font-weight: 700; font-size: 13px; cursor: pointer; }
.fdq-seg button.on { border-color: var(--brand-500, #6C63FF); background: #F0EEFF; color: var(--brand-600, #5849D6); }
.fdq-set-sub { margin-top: 8px; }
.fdq-set-note { font-size: 11.5px; color: var(--text-muted); margin: 6px 2px 0; }
.fdq-set-row { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 16px; background: #F7F6FD; margin-bottom: 8px; cursor: pointer; }
.fdq-set-ico { width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: #fff; color: var(--brand-600); flex: 0 0 auto; }
.fdq-set-text { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.fdq-set-text strong { font-size: 13.5px; }
.fdq-set-text span { font-size: 11.5px; color: var(--text-muted); }
.fdq-set-actions { display: flex; gap: 10px; margin-top: 14px; }
.fdq-set-actions .fdq-btn-ghost { flex: 1 1 0; }
html[data-theme="dark"] .fdq-modal-card { background: var(--fd-card-bg); }
html[data-theme="dark"] .fdq-seg button, html[data-theme="dark"] .fdq-set-row { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .08); }

/* Results: trophy, icon stats */
.fdq-trophy { position: relative; width: 96px; height: 96px; margin: 0 auto -6px; display: flex; align-items: center; justify-content: center; font-size: 52px; color: #FAB005; animation: fdqTrophy .7s cubic-bezier(.34, 1.56, .64, 1) both; }
.fdq-trophy > i { position: relative; filter: drop-shadow(0 6px 10px rgba(250, 176, 5, .45)); }
.fdq-trophy-glow { position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle, rgba(255, 212, 59, .55), rgba(255, 212, 59, 0) 70%); animation: fdqGlow 2s ease-in-out infinite; }
.fdq-sparkle { position: absolute; color: #FFD43B; font-size: 13px; animation: fdqTwinkle 1.6s ease-in-out infinite; }
.fdq-sparkle.s1 { top: 4px; left: 6px; }
.fdq-sparkle.s2 { top: 14px; right: 0; animation-delay: .5s; font-size: 10px; }
.fdq-sparkle.s3 { bottom: 10px; left: -2px; animation-delay: 1s; font-size: 9px; }
@keyframes fdqTrophy { from { opacity: 0; transform: scale(.3) rotate(-12deg); } to { opacity: 1; transform: none; } }
@keyframes fdqGlow { 50% { transform: scale(1.15); opacity: .7; } }
@keyframes fdqTwinkle { 50% { opacity: .2; transform: scale(.6); } }
.fdq-result.tier-gold .fdq-ring-wrap { width: 150px; height: 150px; }
.fdq-result.tier-gold h2 { color: #E67700; }
.fdq-stats > div i { display: block; font-size: 16px; margin-bottom: 4px; color: var(--text-muted); }
.fdq-stats .ok i { color: #12B886; }
.fdq-stats .bad i { color: #FA5252; }
.fdq-stats .skip i { color: #868E96; }
.fdq-stats .time i { color: #1971C2; }
.fdq-review summary i { margin-right: 4px; }

/* =====================================================================
   2026-09-19 (thirtieth follow-up) - school catalog in the evaluation
   wizard (.fd-sc-*) and the school admin Topics & Lessons wizard (.fd-ss-*).
   Same tinted rows + round icon medallions as the student study screens.
   ===================================================================== */
.fd-sc-list { display: flex; flex-direction: column; gap: 8px; }
.fd-sc-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border: none; border-radius: 18px; background: var(--tl, #F0EEFF); color: var(--text); text-align: left; cursor: pointer; transition: transform .15s, box-shadow .15s; }
.fd-sc-row:hover { transform: translateY(-1px); box-shadow: 0 8px 18px rgba(30, 22, 90, .08); }
.fd-sc-icon { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); }
.fd-sc-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.fd-sc-title { font-weight: 600; font-size: 14px; text-transform: capitalize; }
.fd-sc-sub { font-size: 12px; color: var(--text-muted); }
.fd-sc-chev { margin-left: auto; color: var(--t, #5849D6); font-size: 12px; }
.fd-sc-qhead { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin: 4px 0 10px; font-weight: 600; font-size: 13px; }
.fd-sc-vis { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 12px 0; }
.fd-sc-vis-label { grid-column: 1 / -1; font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.fd-sc-vis-opt { position: relative; margin: 0; cursor: pointer; }
.fd-sc-vis-opt input { position: absolute; opacity: 0; pointer-events: none; }
.fd-sc-vis-opt span { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 14px; border: 1.5px solid var(--brand-100, #E4E0FB); font-weight: 600; font-size: 13.5px; height: 100%; }
.fd-sc-vis-opt span i { color: var(--brand-600, #5849D6); margin-right: 4px; }
.fd-sc-vis-opt small { font-weight: 400; font-size: 11.5px; color: var(--text-muted); }
.fd-sc-vis-opt input:checked + span { border-color: var(--brand-500, #6C63FF); background: var(--brand-25, #F7F6FD); box-shadow: 0 0 0 3px rgba(108, 99, 255, .12); }

.fd-ss .fd-qb-crumb { margin-bottom: 12px; }
.fd-ss-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
.fd-ss-card { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 20px 12px 16px; border: none; border-radius: 20px; background: var(--tl, #F0EEFF); color: var(--text); text-align: center; cursor: pointer; transition: transform .15s, box-shadow .15s; }
.fd-ss-card:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(30, 22, 90, .1); }
.fd-ss-card-icon { width: 52px; height: 52px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 20px; background: var(--tg); box-shadow: 0 6px 14px rgba(30, 22, 90, .12); }
.fd-ss-card-name { font-weight: 700; font-size: 14.5px; text-transform: capitalize; }
.fd-ss-card-sub { font-size: 12px; color: var(--text-muted); }
.fd-ss-card-sub i { font-size: 10px; color: var(--t); }
.fd-ss-hero { display: flex; gap: 12px; align-items: flex-start; padding: 14px; border-radius: 18px; background: var(--brand-25, #F7F6FD); margin-bottom: 12px; }
.fd-ss-hero-icon { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6)); }
.fd-ss-hero strong { display: block; font-size: 14.5px; }
.fd-ss-hero span { display: block; font-size: 12.5px; line-height: 1.45; color: var(--text-muted); margin-top: 2px; }
.fd-ss-only { display: flex; align-items: center; gap: 8px; margin: 8px 0 0; font-size: 12.5px; color: var(--text-muted); cursor: pointer; }
.fd-ss-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.fd-ss-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 6px; border-radius: 18px; background: var(--tl, #F0EEFF); }
.fd-ss-row.hidden-row { opacity: .6; background: var(--surface-2, #F1F3F5); }
.fd-ss-row.editing { padding: 8px 10px; }
.fd-ss-row.editing .form-control { flex: 1 1 auto; min-width: 0; }
.fd-ss-row-main { display: flex; align-items: center; gap: 12px; flex: 1 1 auto; min-width: 0; padding: 6px; border: none; background: transparent; color: var(--text); text-align: left; cursor: pointer; }
.fd-ss-row-main[disabled] { cursor: default; }
.fd-ss-row-icon { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); }
.fd-ss-row-text { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.fd-ss-row-name { font-weight: 600; font-size: 14px; text-transform: capitalize; }
.fd-ss-row-sub { font-size: 12px; color: var(--text-muted); }
.fd-ss-row-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.fd-ss-row-actions { display: flex; gap: 6px; flex: 0 0 auto; }
.fd-ss-pill { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 600; background: rgba(255, 255, 255, .85); color: var(--t, #5849D6); }
.fd-ss-pill.cat { color: #1971C2; }
.fd-ss-pill.own { color: #1C8A4C; }
.fd-ss-pill.muted { color: var(--text-muted); }
.fd-ss-iconbtn { width: 34px; height: 34px; border-radius: 50%; border: none; display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .9); color: var(--t, #5849D6); cursor: pointer; }
.fd-ss-iconbtn.danger { color: #C92A2A; }
.fd-ss-iconbtn:hover { box-shadow: 0 4px 10px rgba(30, 22, 90, .12); }
.fd-ss-restore { border: none; border-radius: 999px; padding: 6px 12px; font-size: 12px; font-weight: 600; background: #fff; color: var(--brand-600, #5849D6); cursor: pointer; }
html[data-theme="dark"] .fd-ss-pill, html[data-theme="dark"] .fd-ss-iconbtn, html[data-theme="dark"] .fd-ss-restore { background: rgba(255, 255, 255, .08); }
html[data-theme="dark"] .fd-ss-hero, html[data-theme="dark"] .fd-sc-vis-opt input:checked + span { background: rgba(255, 255, 255, .05); }
@media (max-width: 576px) {
    .fd-ss-grid { grid-template-columns: 1fr 1fr; }
    .fd-ss-row { flex-wrap: wrap; }
    .fd-ss-row-actions { margin-left: auto; }
    .fd-sc-vis { grid-template-columns: 1fr; }
}

/* =====================================================================
   Mobile bottom nav + tab drawer.
   2026-09-19 (thirtieth follow-up): quiz-bar anatomy - a round icon
   medallion with the label underneath.
   2026-09-19 (thirty-first follow-up), quoted directly: "for the mobile
   bottom nav lets use light gray as the color then the icons light circle
   color can be the platfrom color. also the slide up tab tools should
   maintain thier colorful options and also have a light gray background
   and style should be same like on the /auth/login.php?tab=AccountType
   style exact. also make sure the text warp for the mobile nav having two
   words."
   - Dock: light gray surface, platform-colour medallions, white icons,
     dark labels wrapped two words per line (header.php's .fd-tl-line).
   - Drawer: the same light gray, growing out of the dock, holding
     .account-type-card look-alike cards (tinted card, 2px border, round
     gradient icon, name + description, check badge when active) - each
     tab keeps its own colour (rotated when a page gives them all one).
   Mobile only - the desktop rail is untouched.
   ===================================================================== */
:root { --fd-dock-gray: #F1F2F6; --fd-dock-ink: #4A4F5E; }
html[data-theme="dark"] { --fd-dock-gray: #1B1A2E; --fd-dock-ink: rgba(255, 255, 255, .78); }
@media (max-width: 768px) {
    :root { --fd-dock-core: 80px; --fd-dock-bg: var(--fd-dock-gray); }
    html[data-theme="dark"] { --fd-dock-bg: var(--fd-dock-gray); }
    body .vertical-tabs-wrapper {
        padding: 11px 6px calc(4px + env(safe-area-inset-bottom, 0px));
        gap: 0;
        background: var(--fd-dock-gray);
        border-radius: 0;
        border-top: 1px solid rgba(20, 20, 60, .06);
    }
    body .vertical-tabs-wrapper .vertical-tab,
    body .vertical-tabs-wrapper .vertical-tab.gactive {
        position: relative;
        height: calc(var(--fd-dock-core) - 10px);
        padding: 0 2px;
        gap: 4px;
        justify-content: flex-start;
        align-items: center;
        background: transparent;
        border-radius: 14px;
        color: var(--fd-dock-ink);
        box-shadow: none;
    }
    body .vertical-tabs-wrapper .vertical-tab::before,
    body .vertical-tabs-wrapper .vertical-tab::after,
    body.fd-tabgrid-open .vertical-tabs-wrapper .vertical-tab.gactive::before,
    body.fd-tabgrid-open .vertical-tabs-wrapper .vertical-tab.gactive::after { display: none; }
    body .vertical-tabs-wrapper .vertical-tab > i:first-child {
        flex: 0 0 40px;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 16px;
        line-height: 1;
        /* 2026-09-19 (thirty-second follow-up): "make the color around the
           icon the light version then the icon itself gets the actual color" */
        background: var(--brand-50, #EFEDFF);
        color: var(--brand-600);
        transition: box-shadow .2s ease, transform .2s ease, background .2s ease;
    }
    body .vertical-tabs-wrapper .vertical-tab:active > i:first-child { transform: scale(.94); }
    body .vertical-tabs-wrapper .vertical-tab.gactive > i:first-child {
        background: var(--brand-100, #DEDAFF);
        color: var(--brand-600);
        box-shadow: 0 0 0 3px var(--fd-dock-gray), 0 0 0 5px var(--brand-300, #A9A2F2), 0 6px 14px rgba(88, 73, 214, .2);
    }
    html[data-theme="dark"] body .vertical-tabs-wrapper .vertical-tab > i:first-child { background: rgba(167, 156, 255, .14); color: #C9C2FF; }
    body .vertical-tabs-wrapper .vertical-tab.completed:not(.gactive) > i:first-child { background: #E6F9F0; color: #12B886; }
    /* Labels: two words per line, never cut to an ellipsis mid-name. */
    body .vertical-tabs-wrapper .vertical-tab .tab-label {
        font-size: 10px;
        font-weight: 700;
        color: var(--fd-dock-ink);
        white-space: normal;
        line-height: 1.15;
        text-align: center;
        overflow: hidden;
        max-width: 100%;
    }
    body .vertical-tabs-wrapper .vertical-tab .tab-label .fd-tl-line {
        display: block;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 100%;
    }
    body .vertical-tabs-wrapper .vertical-tab.gactive .tab-label { color: var(--brand-600); }
    html[data-theme="dark"] body .vertical-tabs-wrapper .vertical-tab.gactive .tab-label { color: #fff; }
    /* The "pull up the tabs" hint: a small badge on the active medallion. */
    body.fd-has-tabgrid .vertical-tabs-wrapper .vertical-tab.gactive .fd-tabgrid-hint {
        position: absolute;
        top: -3px;
        left: calc(50% + 11px);
        width: 16px;
        height: 16px;
        border-radius: 50%;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 8px;
        background: #fff;
        color: var(--brand-600);
        box-shadow: 0 2px 6px rgba(20, 12, 70, .2);
        opacity: 1;
    }
    body.fd-tabgrid-open .vertical-tabs-wrapper .vertical-tab.gactive .fd-tabgrid-hint { transform: rotate(180deg); opacity: 1; }
    body .vertical-tabs-wrapper .fd-nav-unread-dot { top: 0; right: calc(50% - 24px); left: auto; box-shadow: 0 0 0 2px var(--fd-dock-gray); }

    /* The drawer: the same light gray surface, growing out of the dock. */
    #fdToolTabGrid {
        background: var(--fd-dock-gray);
        border-radius: 22px 22px 0 0;
        padding: 16px 6px 6px;
        gap: 8px;
        align-items: stretch;
        box-shadow: none;
    }
    #fdToolTabGrid::before { background: rgba(20, 20, 60, .16); }
    body:not(.fd-tabgrid-open) #fdToolTabGrid { box-shadow: none; }
    /* Cards: login.php?tab=AccountType's .account-type-card, exactly. */
    /* 2026-09-19 (thirty-second follow-up): "reduce the side abit so it
       matches the same size as the nav bar itself and also there should
       be 4 visble with possibility of scrolling horizontally" - compact
       cards, exactly a quarter of the strip each (the 5th+ scrolls). */
    #fdToolTabGrid .fd-tool-tab-card,
    #fdToolTabGrid .fd-tool-tab-card:hover {
        position: relative;
        flex: 0 0 calc((100% - 24px) / 4);
        min-width: 0;
        width: calc((100% - 24px) / 4);
        padding: 8px 4px 7px;
        border: 2px solid transparent;
        border-radius: 20px;
        background: var(--surface, #fff);
        box-shadow: none;
        transform: none;
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 0;
        transition: all .3s ease;
    }
    #fdToolTabGrid .fd-tool-tab-card.active {
        border-color: var(--brand-500);
        background: var(--brand-50);
        box-shadow: none;
    }
    #fdToolTabGrid .fd-tool-tab-card.active::after {
        content: '\f00c';
        font-family: 'Font Awesome 6 Free';
        font-weight: 900;
        position: absolute;
        top: 4px;
        right: 4px;
        width: 16px;
        height: 16px;
        border-radius: 50%;
        background: var(--brand-500);
        color: #fff;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 8px;
    }
    #fdToolTabGrid .fd-tool-tab-card .fd-tool-tab-icon {
        width: 34px;
        height: 34px;
        border-radius: 50%;
        font-size: 14px;
        margin: 0 auto 5px;
        color: #fff !important;
        box-shadow: none;
        background: var(--fd-tt, linear-gradient(135deg, #6C63FF, #5849D6)) !important;
    }
    #fdToolTabGrid .fd-tool-tab-card .fd-tool-tab-icon i { color: #fff !important; }
    /* Keep every tab colourful: the four page colours in account-type order,
       rotated so a page that marks every tab the same still gets variety. */
    #fdToolTabGrid .fd-tool-tab-card:nth-child(6n+1) { --fd-tt: linear-gradient(135deg, #6C63FF, #5849D6); }
    #fdToolTabGrid .fd-tool-tab-card:nth-child(6n+2) { --fd-tt: linear-gradient(135deg, #FF9F43, #E8590C); }
    #fdToolTabGrid .fd-tool-tab-card:nth-child(6n+3) { --fd-tt: linear-gradient(135deg, #20C997, #1C8A4C); }
    #fdToolTabGrid .fd-tool-tab-card:nth-child(6n+4) { --fd-tt: linear-gradient(135deg, #BA68C8, #7B3FA0); }
    #fdToolTabGrid .fd-tool-tab-card:nth-child(6n+5) { --fd-tt: linear-gradient(135deg, #74C0FC, #1971C2); }
    #fdToolTabGrid .fd-tool-tab-card:nth-child(6n+6) { --fd-tt: linear-gradient(135deg, #FAA2C1, #C2255C); }
    #fdToolTabGrid .fd-tool-tab-card .fd-tool-tab-name { color: var(--text) !important; font-size: 10.5px; font-weight: 700; line-height: 1.2; display: block; margin: 0; overflow-wrap: anywhere; }
    #fdToolTabGrid .fd-tool-tab-card .fd-tool-tab-desc { display: none !important; }
    #fdToolTabGrid .fd-tool-tab-card, #fdToolTabGrid .fd-tool-tab-card:hover { border-radius: 16px; }
    html[data-theme="dark"] #fdToolTabGrid .fd-tool-tab-card { background: var(--fd-card-bg); }
    html[data-theme="dark"] #fdToolTabGrid .fd-tool-tab-card.active { background: rgba(108, 99, 255, .16); }
    .fd-tab-layout .fd-tool-panel-stack { padding-bottom: 180px; }
}

/* Quiz question card: ~2.5x taller, question centred both ways. */
.fdq-q-top { display: flex; flex-direction: column; min-height: clamp(260px, 40vh, 380px); padding: 18px 20px 22px; position: relative; overflow: hidden; }
.fdq-q-top::before { content: ''; position: absolute; right: -60px; top: -60px; width: 180px; height: 180px; border-radius: 50%; background: radial-gradient(circle, rgba(108, 99, 255, .10), rgba(108, 99, 255, 0) 70%); pointer-events: none; }
.fdq-q-top::after { content: ''; position: absolute; left: -50px; bottom: -70px; width: 170px; height: 170px; border-radius: 50%; background: radial-gradient(circle, rgba(56, 217, 169, .10), rgba(56, 217, 169, 0) 70%); pointer-events: none; }
.fdq-stem-wrap { position: relative; z-index: 1; flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 10px 4px 0; }
.fdq-stem-wrap .fdq-stem { font-size: 23px; line-height: 1.4; margin: 0; }
.fdq-stem-wrap .fdq-hint { margin: 10px 0 0; }
.fdq-stem-wrap .fdq-photo { margin: 12px auto 0; }
.fdq-q-top .fdq-meta { position: relative; z-index: 1; }
@media (min-width: 769px) { .fdq-stem-wrap .fdq-stem { font-size: 26px; } }

/* 2026-09-19 (thirty-first follow-up), quoted directly: "the evaluations
   list on the teacher and the student side can we redo the cards to look
   like the topic or subject style with those beautiful light colors and
   icons ?" - the same tinted row + round gradient medallion as the study
   topics (.tone-N gives --t / --tg / --tl). */
.fd-item-card-list:has(> .fd-ev-card) { background: transparent; padding: 0; gap: 12px; }
.fd-item-card.fd-ev-card { background: var(--tl, #F0EEFF); border: none; border-radius: 20px; padding: 14px 14px 12px; gap: 6px; box-shadow: none; }
.fd-item-card.fd-ev-card:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(30, 22, 90, .08); }
.fd-ev-card .fd-item-card-row1 { gap: 12px; }
.fd-ev-card .fd-ev-icon { width: 46px; height: 46px; border-radius: 50%; font-size: 18px; color: #fff; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); box-shadow: 0 6px 14px rgba(30, 22, 90, .12); }
.fd-ev-card .fd-item-card-title { font-size: 15px; text-transform: capitalize; }
.fd-ev-card .fd-item-card-row2, .fd-ev-card .fd-item-card-row3 { padding-left: 58px; }
.fd-ev-card .fd-item-card-row2 i { color: var(--t, #5849D6); }
.fd-ev-card .fd-item-card-status { background: rgba(255, 255, 255, .85); }
.fd-ev-card .fd-badge:not(.fd-item-card-status) { background: rgba(255, 255, 255, .85); color: var(--t, #5849D6); }
.fd-ev-card .fd-item-card-actions .fd-icon-btn { background: rgba(255, 255, 255, .9) !important; color: var(--t, #5849D6) !important; border-radius: 50%; width: 36px; height: 36px; }
.fd-ev-card .fd-item-card-actions .btn-sm-add:not(.fd-icon-btn) { background: var(--tg); border: none; color: #fff; }
html[data-theme="dark"] .fd-ev-card .fd-item-card-status, html[data-theme="dark"] .fd-ev-card .fd-badge, html[data-theme="dark"] .fd-ev-card .fd-item-card-actions .fd-icon-btn { background: rgba(255, 255, 255, .08) !important; }

/* 2026-09-19 (thirty-second follow-up): "remove the bottom nav from the
   login signup page please" - the in-form links switch Login / Sign up /
   Reset instead. */
.fd-auth-page .vertical-tabs-wrapper { display: none !important; }
@media (max-width: 768px) { .fd-auth-page .content-body1, .fd-auth-page .main-wrapper { padding-bottom: 24px !important; } }
/* 2026-09-19 (thirty-third follow-up): "the tab_tools please it seems they
   have some shadow please remove that" - no shadow anywhere in the drawer. */
@media (max-width: 768px) {
    #fdToolTabGrid, #fdToolTabGrid *, #fdToolTabGrid *::before, body.fd-tabgrid-open #fdToolTabGrid { box-shadow: none !important; }
}

/* 2026-09-19 (thirty-third follow-up): notices, GCE exams and tasks as the
   same tinted rows with a round icon medallion as the study topics. */
.fd-note-list { display: flex; flex-direction: column; gap: 10px; }
.fd-note-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border: none; border-radius: 20px; background: var(--tl, #F0EEFF); color: var(--text); text-decoration: none; text-align: left; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; font: inherit; }
.fd-note-row:hover { transform: translateY(-1px); box-shadow: 0 10px 22px rgba(30, 22, 90, .08); color: var(--text); }
.fd-note-icon { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 17px; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); box-shadow: 0 6px 14px rgba(30, 22, 90, .12); }
.fd-note-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; gap: 2px; }
.fd-note-text strong { font-size: 14.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fd-note-text small { font-size: 12px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fd-note-time { flex: 0 0 auto; font-size: 11.5px; font-weight: 700; color: var(--t, #5849D6); }
.fd-note-pill { flex: 0 0 auto; font-size: 11px; font-weight: 800; padding: 5px 10px; border-radius: 999px; background: rgba(255, 255, 255, .85); color: var(--t, #5849D6); white-space: nowrap; }
.fd-note-pill.ok { background: #12B886; color: #fff; }
.fd-note-pill.live { background: var(--tg); color: #fff; }
.fd-note-pill.err { background: #FA5252; color: #fff; }
.fd-note-go { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: var(--tg); font-size: 12px; }
html[data-theme="dark"] .fd-note-pill { background: rgba(255, 255, 255, .08); }
/* Task details popup: the row look on top, everything else at the bottom. */
.fd-task-sheet { display: flex; flex-direction: column; min-height: 46vh; }
.fd-task-hero { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 18px 10px 10px; border-radius: 22px; background: var(--tl, #F0EEFF); }
.fd-task-hero .fd-note-icon { width: 64px; height: 64px; font-size: 24px; }
.fd-task-hero h3 { margin: 0; font-size: 18px; font-family: 'Poppins', sans-serif; }
.fd-task-facts { margin-top: auto; padding-top: 18px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.fd-task-facts div { background: var(--surface-2, #F7F6FD); border-radius: 14px; padding: 10px 12px; font-size: 13px; }
.fd-task-facts div small { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.fd-task-facts div strong { font-size: 13.5px; }
html[data-theme="dark"] .fd-task-facts div { background: rgba(255, 255, 255, .05); }

/* 2026-09-19 (thirty-third follow-up): toasts stay visible above the studio / builder pop-ups and the full-screen sheets. */
.fd-toast-stack { z-index: 9800; }

/* 2026-09-20 (thirty-fourth follow-up), quoted directly: "all pop up on
   desktop should have a wide width so its really presentable." Every
   desktop popup (the shared bottom sheet, the builder/studio modals and
   the other sheets) now opens wide; mobile keeps its bottom-sheet. */
@media (min-width: 769px) {
    .bottom-sheet { width: min(1040px, calc(100vw - 64px)); }
    .bottom-sheet.bottom-sheet-wide { width: min(1120px, calc(100vw - 64px)); }
    .gceb-modal-box { max-width: 1000px; }
    .gceb-modal-box.wide { max-width: 1060px; }
}

/* 2026-09-20 (thirty-fourth follow-up): Accounts - rows like the study
   topics, the account pop-up, roles and invites. */
.fd-acc-search { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 16px; }
.fd-acc-search-box { flex: 1 1 260px; display: flex; align-items: center; gap: 10px; background: var(--surface, #fff); border: 1.5px solid #E6E4F3; border-radius: 16px; padding: 0 14px; }
.fd-acc-search-box i { color: var(--text-muted); }
.fd-acc-search-box input { border: none; outline: none; background: transparent; flex: 1; padding: 12px 0; font: inherit; color: var(--text); }
.fd-acc-search select { border: 1.5px solid #E6E4F3; border-radius: 16px; padding: 0 14px; background: var(--surface, #fff); color: var(--text); font: inherit; min-height: 46px; }
.fd-acc-search .btn { border-radius: 16px; }
.fd-acc-h { display: flex; align-items: center; gap: 8px; font-size: 16px; margin: 0 0 12px; }
.fd-acc-h small { font-size: 12px; font-weight: 800; color: var(--brand-600, #5849D6); background: #F0EEFF; padding: 3px 9px; border-radius: 999px; }
.fd-acc-h-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.fd-acc-initials { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 15px; letter-spacing: .5px; }
.fd-acc-touched { outline: 2px dashed var(--t, #7C73FF); outline-offset: 2px; }
.fd-acc-pages { display: flex; gap: 8px; margin-top: 14px; font-size: 13px; flex-wrap: wrap; }
.fd-acc-pages a, .fd-acc-pages strong { min-width: 34px; height: 34px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; background: #F0EEFF; text-decoration: none; }
.fd-acc-pages strong { background: var(--brand-600, #5849D6); color: #fff; }
.fd-acc-hero { display: flex; align-items: center; gap: 14px; padding: 16px; border-radius: 22px; background: var(--tl, #F0EEFF); margin-bottom: 14px; }
.fd-acc-hero .fd-note-icon { width: 62px; height: 62px; font-size: 20px; }
.fd-acc-hero h3 { margin: 0 0 6px; font-size: 18px; font-family: 'Poppins', sans-serif; }
.fd-acc-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.fd-acc-fact { background: #fff; border-radius: 16px; padding: 10px 12px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.fd-acc-fact span { font-size: 11px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; color: var(--text-muted); }
.fd-acc-fact b { font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.fd-acc-fact small { color: var(--text-muted); font-weight: 500; }
.fd-acc-sub { display: flex; align-items: center; gap: 8px; font-size: 14px; margin: 18px 0 8px; color: var(--text); }
.fd-acc-sub i { color: var(--brand-600, #5849D6); }
.fd-acc-mships { display: flex; flex-direction: column; gap: 6px; }
.fd-acc-mship { display: flex; gap: 10px; align-items: center; background: #fff; border-radius: 14px; padding: 9px 12px; font-size: 13px; }
.fd-acc-mship b { min-width: 120px; }
.fd-acc-mship span { flex: 1; color: var(--text-muted); }
.fd-acc-mship em { font-style: normal; font-size: 11px; font-weight: 800; padding: 3px 9px; border-radius: 999px; background: #F1F3F5; }
.fd-acc-mship em.ok { background: #E6FCF5; color: #087F5B; }
.fd-acc-roles { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
.fd-acc-role { display: flex; gap: 10px; align-items: flex-start; background: #fff; border: 2px solid transparent; border-radius: 16px; padding: 10px 12px; cursor: pointer; margin: 0; }
.fd-acc-role.on { border-color: var(--brand-500, #7C73FF); background: #F5F3FF; }
.fd-acc-role input { margin-top: 3px; accent-color: #5849D6; }
.fd-acc-role span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fd-acc-role small { font-size: 11.5px; color: var(--text-muted); }
.fd-acc-actions { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px; }
.fd-acc-act { display: flex; align-items: center; gap: 10px; border: 2px solid transparent; background: #fff; border-radius: 16px; padding: 12px 14px; font: inherit; font-size: 13.5px; font-weight: 700; color: var(--text); cursor: pointer; text-align: left; }
.fd-acc-act i { width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: #F0EEFF; color: #5849D6; flex: 0 0 auto; }
.fd-acc-act.on { border-color: var(--brand-500, #7C73FF); }
.fd-acc-act.ok i { background: #E6FCF5; color: #0CA678; }
.fd-acc-act.warn i { background: #FFF4E6; color: #E8590C; }
.fd-acc-act.danger { color: #C92A2A; }
.fd-acc-act.danger i { background: #FFF0F0; color: #E03131; }
.fd-acc-panel { margin-top: 12px; background: #fff; border-radius: 18px; padding: 14px 16px; border: 2px solid #ECEBF5; }
.fd-acc-panel.ok { border-color: #96F2D7; background: #F3FFFA; }
.fd-acc-panel.danger { border-color: #FFC9C9; background: #FFF8F8; }
.fd-acc-panel p { margin: 0 0 10px; font-size: 13.5px; }
.fd-acc-secret { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: #F7F6FD; border-radius: 12px; padding: 10px 12px; margin-bottom: 8px; }
.fd-acc-secret code { flex: 1; font-size: 15px; font-weight: 700; color: #3B2FB8; background: none; }
.fd-role-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.fd-role-card { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; border: none; border-radius: 22px; padding: 16px; background: var(--tl, #F0EEFF); text-align: left; font: inherit; color: var(--text); cursor: pointer; transition: transform .15s ease; }
.fd-role-card:hover { transform: translateY(-2px); }
.fd-role-card b { font-size: 15px; }
.fd-role-card small { font-size: 12px; color: var(--text-muted); }
.fd-role-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.fd-role-chips em { font-style: normal; font-size: 11px; font-weight: 700; background: rgba(255, 255, 255, .85); color: var(--t, #5849D6); padding: 3px 8px; border-radius: 999px; }
.fd-sec-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.fd-sec-card { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 16px 10px 12px; border-radius: 20px; background: #fff; border: 2px solid transparent; cursor: pointer; margin: 0; }
.fd-sec-card input { position: absolute; opacity: 0; pointer-events: none; }
.fd-sec-card .fd-note-icon { width: 44px; height: 44px; }
.fd-sec-card b { font-size: 14px; }
.fd-sec-card small { font-size: 11.5px; color: var(--text-muted); line-height: 1.35; }
.fd-sec-card .fd-sec-tick { position: absolute; top: 10px; right: 10px; color: #D0CEE6; font-size: 18px; }
.fd-sec-card.on { border-color: var(--t, #7C73FF); background: var(--tl, #F5F3FF); }
.fd-sec-card.on .fd-sec-tick { color: var(--t, #5849D6); }
html[data-theme="dark"] .fd-acc-fact, html[data-theme="dark"] .fd-acc-mship, html[data-theme="dark"] .fd-acc-role, html[data-theme="dark"] .fd-acc-act, html[data-theme="dark"] .fd-acc-panel, html[data-theme="dark"] .fd-sec-card { background: rgba(255, 255, 255, .05); }

/* 2026-09-20 (thirty-fourth follow-up): Super Admin > Academic structure. */
.acs-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.acs-head h3 { margin: 0 0 2px; font-size: 18px; font-family: 'Poppins', sans-serif; }
.acs-head p { margin: 0; max-width: 640px; }
.acs-sub { display: flex; align-items: center; gap: 8px; font-size: 15px; margin: 18px 0 10px; }
.acs-sub i { color: var(--brand-600, #5849D6); }
.acs-sub small { font-size: 11.5px; font-weight: 800; background: #F0EEFF; color: #5849D6; padding: 2px 8px; border-radius: 999px; }
.acs-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.acs-tile { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 16px; border-radius: 22px; background: var(--tl, #F0EEFF); min-width: 0; }
.acs-tile.off { opacity: .55; }
.acs-tile .fd-note-icon { width: 48px; height: 48px; font-size: 18px; }
.acs-tile b { font-size: 15.5px; font-family: 'Poppins', sans-serif; }
.acs-tile small { font-size: 12.5px; color: var(--text-muted); line-height: 1.45; }
.acs-tile-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 6px; }
.acs-tile-actions .gce-btn { text-decoration: none; }
.acs-empty { text-align: center; padding: 34px 16px; border-radius: 22px; background: #F7F6FD; color: var(--text-muted); }
.acs-empty i { font-size: 28px; color: #B8B3E6; }
.acs-empty p { margin: 8px 0 0; }
.acs-icons { display: flex; flex-wrap: wrap; gap: 8px; }
.acs-icons button { width: 44px; height: 44px; border-radius: 14px; border: 2px solid transparent; background: #F0EEFF; color: #5849D6; font-size: 16px; cursor: pointer; }
.acs-icons button.on { border-color: #5849D6; background: #fff; }
.fdqs-launch { margin-bottom: 16px; }
html[data-theme="dark"] .acs-empty { background: rgba(255, 255, 255, .04); }
@media (min-width: 769px) {
    /* 2026-09-20: the older .fd-modal-box pop-ups open wide on desktop too. */
    .fd-modal-box { width: 100%; max-width: min(960px, calc(100vw - 64px)) !important; }
}
/* 2026-09-20: a new student's one-time sign-in details (People). */
.fd-cred-card { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 16px 18px; border-radius: 22px; background: #E6FCF5; margin-bottom: 16px; }
.fd-cred-card .fd-note-icon { background: linear-gradient(135deg, #38D9A9, #0CA678); }
.fd-cred-text { flex: 1 1 280px; display: flex; flex-direction: column; gap: 4px; }
.fd-cred-text small { color: var(--text-muted); }
.fd-cred-rows { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.fd-cred-rows span { background: #fff; border-radius: 12px; padding: 8px 12px; font-size: 13px; }
.fd-cred-rows b { color: #087F5B; font-size: 14.5px; margin-left: 4px; }
html[data-theme="dark"] .fd-cred-card { background: rgba(18, 184, 134, .12); }
html[data-theme="dark"] .fd-cred-rows span { background: rgba(255, 255, 255, .06); }
.fd-as-q-decide { display: flex; gap: 8px; margin-top: 10px; }
.fd-as-card-pending { border: 2px solid #FFD8A8 !important; }

/* 2026-09-20 audit A3/C14 - a checkbox drawn as a toggle switch: add class="fd-tg" */
input[type=checkbox].fd-tg { -webkit-appearance: none; appearance: none; position: relative; width: 44px; height: 24px; flex-shrink: 0; margin: 0; border-radius: 999px; background: #DDDBEC; cursor: pointer; transition: background .2s ease; vertical-align: middle; }
input[type=checkbox].fd-tg::before { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2); transition: transform .2s ease; }
input[type=checkbox].fd-tg:checked { background: linear-gradient(135deg, var(--brand-500, #7C5CFC), var(--brand-600, #6741F5)); }
input[type=checkbox].fd-tg:checked::before { transform: translateX(20px); }
input[type=checkbox].fd-tg:disabled { opacity: .45; cursor: not-allowed; }
input[type=checkbox].fd-tg:focus-visible { outline: 2px solid var(--brand-600, #6741F5); outline-offset: 2px; }
input[type=checkbox].fd-tg-sm { width: 34px; height: 19px; }
input[type=checkbox].fd-tg-sm::before { width: 13px; height: 13px; }
input[type=checkbox].fd-tg-sm:checked::before { transform: translateX(15px); }

/* Billing plan cards (audit A3) */
.fd-bplan-list { display: grid; gap: 12px; }
.fd-bplan { border: 1px solid var(--fd-border, #E7E5F2); border-radius: 16px; background: var(--fd-card, #fff); overflow: hidden; }
.fd-bplan.off { opacity: .6; }
.fd-bplan-main { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 16px; background: none; border: 0; text-align: left; cursor: pointer; color: inherit; font: inherit; }
.fd-bplan-main:hover { background: rgba(124,92,252,.05); }
.fd-bplan-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fd-bplan-text b { font-size: 15px; }
.fd-bplan-text small { color: var(--fd-muted, #6B6880); font-size: 12.5px; }
.fd-bplan-off { background: #FFE3E3; color: #C92A2A; border-radius: 999px; padding: 1px 8px; font-size: 11px; font-weight: 600; }
.fd-bplan-groups { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 16px 14px; border-top: 1px dashed var(--fd-border, #E7E5F2); }
.fd-bplan-group { display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px 6px 8px; border-radius: 999px; background: #F4F3FA; font-size: 12.5px; font-weight: 600; cursor: pointer; margin: 0; color: #5B5870; }
.fd-bplan-group.on { background: rgba(124,92,252,.12); color: var(--brand-600, #6741F5); }
.fd-bplan-inst { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; margin-bottom: 14px; }
.fd-bplan-inst button { padding: 10px 8px; border-radius: 12px; border: 1.5px solid var(--fd-border, #E7E5F2); background: var(--fd-card, #fff); cursor: pointer; font: inherit; text-align: center; color: inherit; }
.fd-bplan-inst button b { display: block; font-size: 14px; }
.fd-bplan-inst button small { color: var(--fd-muted, #6B6880); font-size: 11.5px; }
.fd-bplan-inst button.on { border-color: var(--brand-600, #6741F5); background: rgba(124,92,252,.08); }
.fd-bplan-inst button:disabled { opacity: .35; cursor: not-allowed; }

/* Audit A5: names always show with capitals, even rows typed before saving was title-cased. */
.fd-people-card-name, .fd-study-topic-name, .fd-dash-photo-name, .fd-dash-class-name, .fd-profile-photo-name, .fd-pick-tile-label,
.fd-att-roster-name, .fd-bplan-text b, .fd-grade-student-name, .fd-wizard-class-card-name, .fd-study-lesson-name, .fd-chosen-chip-name, .fd-teacher-subject-name, .fd-taxo-topic-name, .fd-taxo-subtopic-name, .fd-subject-picker-name, .fd-subj-name, .fd-catalog-card-name, .fd-as-check-name, .fd-acc-name, .fd-inst-name, .fd-school-name, .fd-sb-name, .fd-app-school-name { text-transform: capitalize; }

/* Audit A6 - series & options: classes offered as removable chips */
.sb-tie-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.sb-tie-label { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--fd-muted, #6B6880); min-width: 70px; }
.sb-tie-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 5px 5px 12px; border-radius: 999px; background: rgba(124,92,252,.12); color: var(--brand-600, #6741F5); font-size: 13px; font-weight: 600; }
.sb-tie-chip button { width: 22px; height: 22px; border-radius: 50%; border: 0; background: #fff; color: #C92A2A; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; }
.sb-tie-chip button:hover { background: #FA5252; color: #fff; }
.sb-tie-add { padding: 5px 12px; border-radius: 999px; border: 1.5px dashed var(--fd-border, #D5D2E6); background: transparent; color: var(--fd-muted, #6B6880); font: inherit; font-size: 13px; cursor: pointer; }
.sb-tie-add:hover { border-color: var(--brand-600, #6741F5); color: var(--brand-600, #6741F5); }
.sb-bulk-row { display: flex; justify-content: flex-end; margin-top: 8px; }

/* Audit A8 - GCE hub: open toggle and section-by-section marking */
.fd-gh-open { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; margin: 0; cursor: pointer; }
.fd-gh-secs { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin-bottom: 14px; }
.fd-gh-sec { text-align: left; padding: 10px 12px; border-radius: 14px; border: 1.5px solid transparent; background: #F4F3FA; cursor: pointer; font: inherit; color: inherit; }
.fd-gh-sec b { display: block; font-size: 13.5px; }
.fd-gh-sec small { color: var(--fd-muted, #6B6880); font-size: 12px; }
.fd-gh-sec.on { border-color: var(--brand-600, #6741F5); background: rgba(124,92,252,.1); }
.fd-gh-qs { display: grid; gap: 10px; }
.fd-gh-q { border: 1px solid var(--fd-border, #E7E5F2); border-radius: 14px; padding: 12px 14px; background: var(--fd-card, #fff); }
.fd-gh-q.todo { border-color: #FAB005; background: #FFFBEB; }
.fd-gh-qhead { display: flex; align-items: flex-start; gap: 10px; }
.fd-gh-qhead > b { flex-shrink: 0; color: var(--brand-600, #6741F5); }
.fd-gh-qhead > span { flex: 1; min-width: 0; font-size: 14px; }
.fd-gh-mark { display: inline-flex; align-items: center; gap: 6px; margin: 0; flex-shrink: 0; }
.fd-gh-mark span { font-size: 12px; color: var(--fd-muted, #6B6880); }
.fd-gh-mark input { width: 74px; padding: 6px 8px; border-radius: 10px; border: 1.5px solid var(--fd-border, #D5D2E6); font: inherit; }
.fd-gh-mark em { font-style: normal; font-size: 12.5px; color: var(--fd-muted, #6B6880); }
.fd-gh-auto { flex-shrink: 0; font-weight: 700; font-size: 13px; }
.fd-gh-auto small { font-weight: 500; color: var(--fd-muted, #6B6880); }
.fd-gh-answer { margin-top: 8px; padding: 10px 12px; border-radius: 10px; background: #F4F3FA; font-size: 14px; white-space: normal; }
.fd-gh-none { margin: 8px 0 0; color: var(--fd-muted, #6B6880); font-size: 13px; font-style: italic; }
.fd-gh-opts { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; font-size: 13.5px; }
.fd-gh-opts li { padding: 5px 10px; border-radius: 8px; }
.fd-gh-opts li.right { background: #EBFBEE; color: #2B8A3E; }
.fd-gh-opts li.chosen:not(.right) { background: #FFF5F5; color: #C92A2A; }
@media (max-width: 640px) { .fd-gh-qhead { flex-wrap: wrap; } }

/* Audit C3 - Academics > School setup: spaced list under the studio card */
.fd-acs-quick { display: grid; gap: 10px; margin-top: 16px; }
.fd-acs-quick .fd-note-row { margin: 0; }
@media (min-width: 900px) { .fd-acs-quick { grid-template-columns: 1fr 1fr; } }

/* Audit C16 - the school's logo in the page header */
.app-hero-avatar-img { background: #fff; overflow: hidden; padding: 0; }
.app-hero-avatar-img img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }

/* Audit B1-B5 - institution onboarding: builder cards, class tiles, staff rows */
.fd-onboarding-page .fd-ob-top { background: linear-gradient(135deg, var(--brand-500, #7C5CFC), var(--brand-600, #5849D6)); }
.fd-ob-logout { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 999px; background: rgba(255,255,255,.18); color: #fff; font-weight: 600; font-size: 13px; text-decoration: none; }
.fd-ob-logout:hover { background: rgba(255,255,255,.3); color: #fff; }
.fd-ob-card { margin-bottom: 16px; }
.fd-ob-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; margin-top: 12px; }
.fd-ob-tile { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 12px; border-radius: 16px; border: 2px solid transparent; background: #fff; cursor: pointer; text-align: left; font: inherit; color: inherit; box-shadow: 0 2px 8px rgba(30,22,90,.06); }
.fd-ob-tile b { font-size: 14px; text-transform: capitalize; }
.fd-ob-tile small { font-size: 11.5px; color: var(--fd-muted, #6B6880); }
.fd-ob-tile .fd-sec-tick { position: absolute; top: 10px; right: 10px; opacity: 0; color: var(--brand-600, #6741F5); }
.fd-ob-tile.on { border-color: var(--brand-600, #6741F5); background: rgba(124,92,252,.07); }
.fd-ob-tile.on .fd-sec-tick { opacity: 1; }
.fd-ob-series { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed rgba(0,0,0,.08); }
.fd-ob-series-label { font-weight: 700; font-size: 12.5px; min-width: 80px; }
.fd-ob-addbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-top: 14px; padding: 14px; border-radius: 16px; background: #F4F3FA; }
.fd-ob-x { width: 30px; height: 30px; border-radius: 50%; border: 0; background: #fff; color: #C92A2A; cursor: pointer; flex-shrink: 0; }
.fd-ob-x:hover { background: #FA5252; color: #fff; }
.fd-ob-subjrow { padding: 10px 12px; border-radius: 14px; background: #F7F6FC; margin-bottom: 8px; }
.fd-ob-subjrow > b { display: block; font-size: 13px; margin-bottom: 6px; }
.fd-ob-nav { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin: 22px 0 40px; }
.fd-ob-back { display: inline-flex; align-items: center; gap: 8px; padding: 12px 20px; border-radius: 14px; border: 0; background: #F0EFFA; color: var(--brand-600, #5849D6); font-weight: 700; cursor: pointer; }
.fd-ob-back:hover { background: #E3E1FF; }
.fd-ob-next { border-radius: 14px; padding: 12px 24px; font-weight: 700; }

/* Audit B4/B6 - staff join link pop-up */
.fd-join-link { display: flex; gap: 8px; }
.fd-join-link input { flex: 1; min-width: 0; padding: 10px 12px; border-radius: 12px; border: 1.5px solid var(--fd-border, #D5D2E6); font: inherit; font-size: 13px; background: #F7F6FC; }
.fd-join-actions { display: grid; gap: 8px; }
.fd-join-btn { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; border-radius: 14px; border: 0; font-weight: 700; color: #fff; text-decoration: none; cursor: pointer; font: inherit; font-weight: 700; }
.fd-join-btn.wa { background: linear-gradient(135deg, #40C057, #25A244); }
.fd-join-btn.mail { background: linear-gradient(135deg, #7C73FF, #5849D6); }
.fd-join-btn.share { background: linear-gradient(135deg, #FFA94D, #E8590C); }
.fd-join-btn:hover { color: #fff; filter: brightness(1.05); }
.fd-oc-num { display: inline-flex; align-items: center; gap: 8px; }
.fd-oc-num input { width: 72px; padding: 6px 8px; border-radius: 10px; border: 1.5px solid var(--fd-border, #D5D2E6); font: inherit; text-align: center; }

/* Audit C14 - every settings checkbox is a toggle switch platform-wide
   (Bootstrap .form-check-input checkboxes included). */
input[type=checkbox].form-check-input { -webkit-appearance: none; appearance: none; position: relative; width: 44px !important; height: 24px !important; flex-shrink: 0; margin: 0 8px 0 0 !important; float: none !important; border-radius: 999px !important; border: 0 !important; background: #DDDBEC !important; background-image: none !important; cursor: pointer; transition: background .2s ease; vertical-align: middle; box-shadow: none !important; }
input[type=checkbox].form-check-input::before { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2); transition: transform .2s ease; }
input[type=checkbox].form-check-input:checked { background: linear-gradient(135deg, var(--brand-500, #7C5CFC), var(--brand-600, #6741F5)) !important; }
input[type=checkbox].form-check-input:checked::before { transform: translateX(20px); }
.form-check:has(> input[type=checkbox].form-check-input) { display: flex; align-items: center; padding-left: 0; }
.fd-pm-row .fd-note-text { gap: 6px; }
.fd-pm-ins { width: 100%; padding: 7px 10px; border-radius: 10px; border: 1.5px solid rgba(0,0,0,.08); background: rgba(255,255,255,.8); font: inherit; font-size: 13px; }

/* Audit C17 - school admin home */
.fd-home-hero { position: relative; overflow: hidden; display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 22px 24px; border-radius: 22px; margin-bottom: 18px; color: #fff; background: linear-gradient(135deg, var(--brand-500, #7C5CFC), var(--brand-600, #5849D6)); box-shadow: 0 10px 30px rgba(88,73,214,.25); }
.fd-home-hero h2 { color: #fff; margin: 6px 0 4px; font-size: 24px; }
.fd-home-hero p { margin: 0; opacity: .9; }
.fd-home-kicker { font-size: 12.5px; opacity: .85; font-weight: 600; }
.fd-home-hero-art { font-size: 84px; opacity: .15; position: absolute; right: 18px; bottom: -8px; }
.fd-home-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; }
.fd-home-stat { display: flex; flex-direction: column; gap: 4px; padding: 16px; border-radius: 18px; text-decoration: none; color: inherit; background: var(--fd-card, #fff); box-shadow: 0 2px 10px rgba(30,22,90,.06); transition: transform .15s ease; }
.fd-home-stat:hover { transform: translateY(-2px); color: inherit; }
.fd-home-stat b { font-size: 24px; line-height: 1.1; margin-top: 6px; }
.fd-home-stat small { color: var(--fd-muted, #6B6880); font-weight: 600; }
.fd-home-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 992px) { .fd-home-grid { grid-template-columns: 1fr 1fr; } }
.fd-home-actions { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
.fd-home-action { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 14px; border-radius: 16px; background: #F7F6FC; text-decoration: none; color: inherit; font-weight: 700; font-size: 13.5px; }
.fd-home-action:hover { background: rgba(124,92,252,.1); color: inherit; }
.fd-home-clear { padding: 16px; border-radius: 14px; background: #EBFBEE; color: #2B8A3E; font-weight: 600; }

/* Audit D11/D12 - teacher home: classes right after the calendar, grouped per school */
.fd-myclasses-title { margin-top: 22px; }
.fd-dash-group { margin-bottom: 18px; scroll-margin-top: 80px; }
.fd-dash-group-head { display: flex; align-items: center; gap: 10px; margin: 6px 0 10px; }
.fd-dash-group-head .fd-note-icon { width: 32px; height: 32px; font-size: 14px; }
.fd-dash-group-head b { font-size: 15px; }
.fd-dash-group-head small { color: var(--fd-muted, #6B6880); font-size: 12px; }

/* Audit D3 - on phones a day's activities slide sideways (swipe) instead of
   stacking into a long column; the day title stays pinned above them. */
@media (max-width: 991.98px) {
    .fd-week-list.is-selected { display: grid; grid-auto-flow: column; grid-template-rows: auto auto; grid-auto-columns: 84%; column-gap: 10px; row-gap: 8px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 6px; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
    .fd-week-list.is-selected::-webkit-scrollbar { display: none; }
    .fd-week-list.is-selected > .fd-week-list-mobile-title { grid-row: 1; grid-column: 1; position: sticky; left: 0; white-space: nowrap; }
    .fd-week-list.is-selected > .fd-ev, .fd-week-list.is-selected > .fd-week-empty { grid-row: 2; scroll-snap-align: start; }
    .fd-week-list.is-selected > .fd-week-empty:not([hidden]) { grid-column: 1 / span 1; }
}
.fd-week-list.is-selected:has(> .fd-ev:only-of-type) { grid-auto-columns: 100%; }

/* Audit D4 - class tools subject switch: icon inside, wider */
.fd-subject-switch { position: relative; display: inline-flex; align-items: center; min-width: 240px; max-width: 100%; margin: 0; }
.fd-subject-switch > .fa-book-open { position: absolute; left: 14px; color: var(--brand-600, #5849D6); pointer-events: none; }
.fd-subject-switch select { -webkit-appearance: none; appearance: none; width: 100%; padding: 10px 38px 10px 40px; border-radius: 14px; border: 1.5px solid var(--brand-150, #DCD8FF); background: var(--brand-25, #F7F6FD); font: inherit; font-size: 14px; font-weight: 700; color: var(--text, #1F1B3A); cursor: pointer; }
.fd-subject-switch select:focus { outline: none; border-color: var(--brand-500, #7C5CFC); box-shadow: 0 0 0 3px rgba(124,92,252,.15); }
.fd-subject-switch-caret { position: absolute; right: 14px; font-size: 12px; color: var(--text-muted, #6B6880); pointer-events: none; }
@media (max-width: 575.98px) { .fd-subject-switch { width: 100%; min-width: 0; } }

/* Audit E2 - the left icon rail: support, notifications, account, and the
   page's own "+" (WhatsApp-style, always reachable on any screen width). */
.fd-util-rail { position: fixed; left: 12px; bottom: 96px; z-index: 1200; display: flex; flex-direction: column-reverse; gap: 10px; }
.fd-util-btn { position: relative; width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--fd-card, #fff); color: var(--brand-600, #5849D6); box-shadow: 0 6px 18px rgba(30,22,90,.16); display: inline-flex; align-items: center; justify-content: center; font-size: 16px; cursor: pointer; text-decoration: none; }
.fd-util-btn:hover { color: #fff; background: var(--brand-600, #5849D6); }
.fd-util-add { width: 54px; height: 54px; font-size: 20px; color: #fff; background: linear-gradient(135deg, var(--brand-500, #7C5CFC), var(--brand-600, #5849D6)); }
.fd-util-add:hover { filter: brightness(1.07); color: #fff; }
.fd-util-badge { position: absolute; top: -2px; right: -2px; font-size: 9px; padding: 1px 5px; }
.fd-util-tip { position: absolute; left: 54px; white-space: nowrap; background: #1F1B3A; color: #fff; font-size: 11.5px; font-weight: 600; padding: 4px 9px; border-radius: 8px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.fd-util-btn:hover .fd-util-tip { opacity: .95; }
/* 2026-09-20 follow-up, quoted directly: "the floating notification,
   support and user profile should actually replace the icons on the right
   side of the screen on desktop and on mobile it should be just
   notification and support since the user profile pop up button is already
   on the top right."

   So: on a wide desktop this rail moves into the right gutter where the old
   .vertical-icons-right strip used to sit (and that strip, plus the
   stop-gap top-right profile button, are switched off - this rail is now
   the one place those icons live); on narrower desktops, where there was
   never room for a right-hand strip, it floats bottom-right; and on phones
   and tablets it keeps only Notifications and Support, because the account
   pop-up already has its own button in the top bar. */
@media (min-width: 992px) {
    .fd-util-rail { left: auto; right: 14px; bottom: auto; top: 50%; transform: translateY(-50%); flex-direction: column; gap: 14px; }
    .fd-util-tip { left: auto; right: 54px; }
    #fdDesktopProfileGap { display: none !important; }
}
@media (min-width: 992px) and (max-width: 1260.98px) {
    /* No gutter beside the content at these widths (the very overlap the
       old strip's 1480px cut-off existed to avoid), so the rail stacks in
       the bottom-right corner instead of across the middle of the page. */
    .fd-util-rail { top: auto; bottom: 26px; transform: none; }
}
@media (min-width: 1261px) {
    /* The same gutter formula .vertical-icons-right itself used, so the
       rail lands exactly where those icons were. 2026-09-22: 1600 -> 1380px
       and the 1481px floor -> 1261px, tracking .main-wrapper's 1500 ->
       1280px narrowing in template-exact.css. */
    .fd-util-rail { right: max(12px, calc((100vw - 1380px) / 2 - 64px)); }
    .vertical-icons-right { display: none !important; }
}
@media (max-width: 991.98px) {
    .fd-util-rail { left: auto; right: 14px; bottom: 104px; }
    .fd-util-tip { display: none; }
    .fd-util-account { display: none; }
}
@media print { .fd-util-rail { display: none; } }

/* Audit E5 - the self-study catalog browser */
.fd-cat-search { position: relative; display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.fd-cat-search > i { position: absolute; left: 14px; color: var(--fd-muted, #6B6880); }
.fd-cat-search input { flex: 1; padding: 10px 12px 10px 38px; border-radius: 12px; border: 1.5px solid var(--fd-border, #D5D2E6); font: inherit; }

/* Audit E6 - "I still learn here" switch in the student profile pop-up */
.fd-menu-stay { margin: 4px 0 10px; }
.fd-menu-stay-row { display: flex; align-items: center; gap: 12px; margin: 0; padding: 10px 12px; border-radius: 14px; background: var(--brand-25, #F7F6FD); cursor: pointer; }
.fd-menu-stay-text { flex: 1; display: flex; flex-direction: column; }
.fd-menu-stay-text strong { font-size: 13.5px; }
.fd-menu-stay-text small { font-size: 11.5px; color: var(--text-muted, #6B6880); }

/* Audit C5/C7 - class blocks and the class pop-up */
.fd-class-blocks { display: grid; gap: 12px; margin-top: 14px; }
.fd-class-block { border-radius: 18px; padding: 14px 16px; background: var(--fd-card, #fff); box-shadow: 0 2px 10px rgba(30,22,90,.06); }
.fd-class-block-head { display: flex; align-items: center; gap: 12px; }
.fd-class-block-titles { display: flex; flex-direction: column; }
.fd-class-block-titles strong { font-size: 15.5px; text-transform: capitalize; }
.fd-class-block-titles small { font-size: 12px; color: var(--fd-muted, #6B6880); }
.fd-class-block-opts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.fd-class-opt { display: inline-flex; align-items: stretch; border-radius: 14px; overflow: hidden; background: #F4F3FA; }
.fd-class-opt.off { opacity: .55; }
.fd-class-opt-main { border: 0; background: none; padding: 8px 12px; text-align: left; cursor: pointer; font: inherit; color: inherit; }
.fd-class-opt-main b { display: block; font-size: 13.5px; }
.fd-class-opt-main small { font-size: 11.5px; color: var(--fd-muted, #6B6880); }
.fd-class-opt form { display: flex; }
.fd-class-opt form button { border: 0; background: none; color: #C92A2A; padding: 0 12px; cursor: pointer; }
.fd-class-opt form button:hover { background: #FA5252; color: #fff; }
.fd-class-opt-add { border: 1.5px dashed var(--fd-border, #D5D2E6); background: transparent; border-radius: 14px; padding: 8px 14px; color: var(--fd-muted, #6B6880); font: inherit; font-weight: 600; cursor: pointer; }
.fd-class-opt-add:hover { border-color: var(--brand-600, #6741F5); color: var(--brand-600, #6741F5); }
.fd-cd-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.fd-cd-head strong { display: block; font-size: 17px; text-transform: capitalize; }
.fd-cd-head small { color: var(--fd-muted, #6B6880); font-size: 12.5px; }
.fd-cd-max { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; border-radius: 14px; background: #F7F6FC; margin-bottom: 14px; }
.fd-cd-max span { font-weight: 600; font-size: 13px; }
.fd-cd-max input { width: 120px; padding: 8px 10px; border-radius: 10px; border: 1.5px solid var(--fd-border, #D5D2E6); font: inherit; }
.fd-cd-h { margin: 18px 0 8px; font-size: 14px; }
.fd-cd-add { margin-top: 10px; }
.fd-cd-add-row { display: flex; flex-wrap: wrap; gap: 8px; }
.fd-cd-add-row input, .fd-cd-add-row select { flex: 1 1 150px; min-width: 0; padding: 9px 11px; border-radius: 11px; border: 1.5px solid var(--fd-border, #D5D2E6); font: inherit; font-size: 13.5px; }
.fd-cd-foot { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--fd-border, #E7E5F2); }
.fd-subjgrp-h { margin: 18px 0 8px; font-size: 14.5px; display: flex; align-items: center; gap: 8px; text-transform: capitalize; }
.fd-subjgrp-h small { font-size: 11.5px; color: var(--fd-muted, #6B6880); background: #F0EFFA; border-radius: 999px; padding: 1px 8px; }

/* ---------------------------------------------------------------------
   2026-09-20 audit C4 - School setup studio: adding / editing the
   school's own catalog items, and the badge on the ones it owns.
   --------------------------------------------------------------------- */
.ss-itembar { margin: 2px 0 4px; }
.ss-chip-add { border-style: dashed !important; font-weight: 700; }
.gceb-chipbtn .ss-own,
.gceb-option .ss-own {
    display: inline-block;
    margin-left: 5px;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(88, 73, 214, .12);
    color: var(--brand, #5849D6);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .2px;
    text-transform: uppercase;
    vertical-align: middle;
}
.gceb-option .ss-own { margin: 4px 0 0; }
.acs-prop-row .fd-note-pill { white-space: nowrap; }

/* ---------------------------------------------------------------------
   2026-09-20 audit C2 - the school admin's teacher profile pop-up:
   tabs, the per-class subject list, and the teaching log against the
   curriculum.
   --------------------------------------------------------------------- */
.fd-tp-tabs {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin: 14px 0 12px;
    border-bottom: 1px solid var(--line-soft);
    padding-bottom: 10px;
}
.fd-tp-tab {
    border: 1px solid var(--line-soft);
    background: var(--surface-2, #F6F7FB);
    color: var(--text-muted);
    border-radius: 999px;
    padding: 8px 14px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 7px;
}
.fd-tp-tab.on {
    background: var(--brand, #5849D6);
    border-color: var(--brand, #5849D6);
    color: #fff;
}
.fd-tp-h {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 16px 0 8px;
    font-size: 14px;
    font-weight: 800;
}
.fd-tp-h small { color: var(--text-muted); font-weight: 600; font-size: 12px; }
.fd-tp-switch { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13.5px; }
.fd-tp-foot { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.fd-tp-classchips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.fd-tp-assign { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.fd-tp-assign select { flex: 1 1 150px; max-width: 220px; }
.fd-tp-log {
    border-radius: 14px;
    padding: 12px 14px;
    margin-bottom: 10px;
    background: var(--brand-20, #F2F0FF);
}
.fd-tp-log-h { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 14px; }
.fd-tp-bar { height: 7px; border-radius: 999px; background: rgba(0, 0, 0, .08); margin: 9px 0; overflow: hidden; }
.fd-tp-bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #6C63FF, #38D9A9); }
.fd-tp-stats { display: flex; flex-wrap: wrap; gap: 10px 16px; font-size: 12px; color: var(--text-muted); font-weight: 600; }
.fd-tp-stats i { margin-right: 4px; }
.fd-tp-topics { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.fd-tp-topic {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--surface, #fff);
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
}
.fd-tp-topic.done { color: #12B886; }
.fd-tp-topic i { font-size: 10px; }
@media (max-width: 560px) {
    .fd-tp-tab { flex: 1 1 auto; justify-content: center; }
    .fd-tp-assign select { max-width: none; }
}

/* ---------------------------------------------------------------------
   2026-09-20 audit D5 - the teacher's online-class and evaluation lists
   in topic style, and the pop-up they open (fd-teacher-lists.js).
   --------------------------------------------------------------------- */
.fd-tl-facts { display: flex; flex-wrap: wrap; gap: 10px; }
.fd-tl-fact {
    flex: 1 1 130px;
    background: var(--surface-2, #F6F7FB);
    border-radius: 12px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.fd-tl-fact i { color: var(--brand, #5849D6); font-size: 13px; }
.fd-tl-fact small { color: var(--text-muted); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; }
.fd-tl-fact strong { font-size: 13.5px; }
.fd-tl-form { display: inline-flex; gap: 6px; align-items: center; }
.fd-tl-form input[type="url"] { min-width: 170px; }
#fdTlModal .gceb-modal-foot { flex-wrap: wrap; gap: 8px; }

/* ---------------------------------------------------------------------
   2026-09-20 audit D9 - the students pop-up and the per-student slide-in
   on the teacher's attendance page (fd-att-students.js).
   --------------------------------------------------------------------- */
.fd-att-tile.tone-students { background: linear-gradient(135deg, #38D9A9, #1C8A4C); }
.fd-stu-slide {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(420px, 100%);
    z-index: 9600; /* above the students pop-up (.gceb-modal.fdm) it opens from */
    transform: translateX(100%);
    /* 2026-09-25 (forty-first follow-up): `visibility` is what actually
       stops a parked panel painting. translateX(100%) moves the BOX off
       screen but its inner card's box-shadow points left (-18px 0 50px),
       so the shadow still bled back into the viewport as a soft dark strip
       down the right edge - the reported band, once per stacked copy. Same
       treatment .bottom-sheet already uses for the same reason (see
       template-exact.css): hidden while closed, with the visibility change
       delayed until the slide-out finishes so it does not pop. */
    visibility: hidden;
    transition: transform .28s cubic-bezier(.22, .61, .36, 1), visibility 0s linear .28s;
    pointer-events: none;
}
.fd-stu-slide.open { transform: none; pointer-events: auto; visibility: visible; transition: transform .28s cubic-bezier(.22, .61, .36, 1), visibility 0s; }
.fd-stu-slide-inner {
    height: 100%;
    background: var(--surface, #fff);
    box-shadow: -18px 0 50px rgba(20, 20, 60, .22);
    display: flex;
    flex-direction: column;
    border-radius: 20px 0 0 20px;
    overflow: hidden;
}
.fd-stu-slide-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--line-soft);
    font-size: 16px;
}
.fd-stu-slide-body { padding: 16px 18px 26px; overflow-y: auto; flex: 1; }
.fd-stu-h { display: flex; align-items: center; gap: 8px; margin: 18px 0 8px; font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); }
.fd-stu-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.fd-stu-rate { display: flex; align-items: center; gap: 14px; }
.fd-stu-rate small { display: block; color: var(--text-muted); font-size: 12px; margin-top: 2px; }
.fd-stu-ring {
    width: 68px;
    height: 68px;
    border-radius: 50%;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    background: conic-gradient(var(--brand, #5849D6) calc(var(--p) * 1%), rgba(0, 0, 0, .08) 0);
}
.fd-stu-ring b {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background: var(--surface, #fff);
    display: grid;
    place-items: center;
    font-size: 14px;
}
@media (max-width: 560px) {
    .fd-stu-slide { width: 100%; }
    .fd-stu-slide-inner { border-radius: 18px 18px 0 0; }
}

/* ---------------------------------------------------------------------
   2026-09-20 audit D13 - an empty calendar day is a button that opens the
   "add an activity" pop-up (fd-week-add.js).
   --------------------------------------------------------------------- */
.fd-week-empty-add {
    width: 100%;
    border: 1px dashed var(--line-soft);
    background: transparent;
    cursor: pointer;
    border-radius: 14px;
    transition: background .15s, border-color .15s;
}
.fd-week-empty-add:hover { background: var(--brand-20, #F2F0FF); border-color: var(--brand, #5849D6); }
.fd-week-addbtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding: 7px 12px;
    border-radius: 999px;
    border: 1px dashed var(--line-soft);
    background: transparent;
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
}
.fd-week-addbtn:hover { color: var(--brand, #5849D6); border-color: var(--brand, #5849D6); }
.fd-wa-two { display: flex; gap: 10px; }
.fd-wa-two > * { flex: 1; }

/* ---------------------------------------------------------------------
   2026-09-20 audit E1 - the signed-in evaluation/assignment quiz now uses
   the study quiz's own .fdq screen (quiz_ui.php + fd-quiz-eval.js). Only
   the few bits that screen never needed before live here: the inline
   header's right side, the short-answer box and the review card.
   --------------------------------------------------------------------- */
.fdq-eval .fdq-top-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.fdq-eval .fdq-short {
    width: 100%;
    box-sizing: border-box;
    min-height: 120px;
    border: 2px solid #E7E5F4;
    border-radius: 18px;
    padding: 14px;
    font: inherit;
    font-size: 15px;
    background: var(--surface, #fff);
    resize: vertical;
    margin-top: 14px;
}
.fdq-eval .fdq-short:focus { outline: none; border-color: var(--brand-500, #6C63FF); }
.fdq-eval .fdq-opt { position: relative; margin: 0; cursor: pointer; }
.fdq-eval .fdq-opt input { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; }
.fdq-eval .fdq-q[hidden] { display: none !important; }
.fdq-eval .fdq-save-note { font-size: 12px; color: rgba(255, 255, 255, .9); font-weight: 700; }
.fdq-bar .fdq-save-note { color: var(--text-muted); }
.fdq-review-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.fdq-review-dot {
    min-width: 62px;
    border-radius: 14px;
    border: 2px solid #E7E5F4;
    background: var(--surface, #fff);
    padding: 8px 10px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.fdq-review-dot b { font-size: 15px; font-weight: 800; }
.fdq-review-dot small { font-size: 10.5px; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .2px; }
.fdq-review-dot.ok { border-color: #12B886; background: #E6FCF5; }
.fdq-review-dot.ok small { color: #087F5B; }

/* ---------------------------------------------------------------------
   2026-09-20 audit E4 - the wallet sheet: the big balance with its eye,
   the MTN/Orange picker, the QR scanner box, the bigger receive QR and
   the action bar along the bottom (footer.php's fdWallet* functions).
   --------------------------------------------------------------------- */
.fd-wal-line {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 2px 2px 12px;
    border-bottom: 1px solid var(--line-soft);
}
.fd-wal-line-text { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.fd-wal-line-text small { font-size: 11.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; color: var(--text-muted); }
.fd-wal-line-text b { font-family: 'Poppins', sans-serif; font-size: 24px; font-weight: 800; letter-spacing: -.4px; }
.fd-wal-eye {
    width: 38px;
    height: 38px;
    border-radius: 12px;
    border: none;
    background: var(--brand-20, #F2F0FF);
    color: var(--brand, #5849D6);
    font-size: 15px;
    cursor: pointer;
    flex: 0 0 auto;
}
.fd-wal-back {
    margin: 12px 0 0;
    border: none;
    background: transparent;
    color: var(--brand, #5849D6);
    font-weight: 700;
    font-size: 13.5px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0;
}
.fd-wal-h { display: flex; align-items: center; gap: 8px; margin: 14px 0 10px; font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); }
.fd-wal-bar {
    position: sticky;
    bottom: 0;
    display: flex;
    gap: 6px;
    padding: 10px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    margin-top: 14px;
    background: var(--surface, #fff);
    border-top: 1px solid var(--line-soft);
}
.fd-wal-act {
    flex: 1 1 0;
    border: none;
    background: transparent;
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 700;
    cursor: pointer;
    padding: 6px 2px;
    border-radius: 14px;
}
.fd-wal-act i {
    width: 40px;
    height: 40px;
    border-radius: 14px;
    display: grid;
    place-items: center;
    font-size: 15px;
    background: var(--brand-20, #F2F0FF);
    color: var(--brand, #5849D6);
}
.fd-wal-act.active { color: var(--brand, #5849D6); }
.fd-wal-act.active i { background: linear-gradient(135deg, #6C63FF, #5849D6); color: #fff; }
.fd-wal-scanrow { display: flex; gap: 8px; align-items: center; }
.fd-wal-scanrow .form-control { flex: 1 1 auto; }
.fd-wal-scanbtn {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    border-radius: 14px;
    border: none;
    background: linear-gradient(135deg, #6C63FF, #5849D6);
    color: #fff;
    font-size: 17px;
    cursor: pointer;
}
#fdWalletScanBox { margin-top: 10px; }
#fdWalletVideo { width: 100%; border-radius: 16px; background: #000; max-height: 260px; object-fit: cover; }
.fd-wal-pickfile {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 6px 0 10px;
    padding: 9px 14px;
    border-radius: 999px;
    border: 1px dashed var(--line-soft);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}
.fd-wal-prov { display: flex; gap: 8px; margin-bottom: 14px; }
.fd-wal-prov-btn {
    flex: 1 1 0;
    border: 2px solid var(--line-soft);
    background: var(--surface, #fff);
    border-radius: 16px;
    padding: 12px 8px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
}
.fd-wal-prov-btn.active { border-color: var(--brand, #5849D6); background: var(--brand-20, #F2F0FF); color: var(--brand, #5849D6); }
.fd-wal-qr-big { padding: 18px; }
/* 2026-09-26: "reduce the size of the qr code alittle bit." */
.fd-wal-qr-big svg { width: min(210px, 56vw); height: auto; display: block; margin: 0 auto; }

/* ---------------------------------------------------------------------
   2026-09-21 audit C11 - the school picks its grading system (Assessment
   > Results). Grading.php holds what each one means in Cameroon.
   --------------------------------------------------------------------- */
.fd-grade-systems {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
    margin: 14px 0 18px;
}
.fd-grade-sys { margin: 0; }
.fd-grade-sys button {
    width: 100%;
    height: 100%;
    text-align: left;
    border: 2px solid var(--line-soft);
    background: var(--surface, #fff);
    border-radius: 18px;
    padding: 14px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font: inherit;
}
.fd-grade-sys button:hover { border-color: var(--brand, #5849D6); }
.fd-grade-sys.on button { border-color: var(--brand, #5849D6); background: var(--brand-20, #F2F0FF); }
.fd-grade-sys-icon {
    width: 40px;
    height: 40px;
    border-radius: 13px;
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, #6C63FF, #5849D6);
    color: #fff;
    font-size: 16px;
}
.fd-grade-sys strong { font-size: 14.5px; }
.fd-grade-sys small { font-size: 12px; color: var(--text-muted); line-height: 1.4; }
.fd-grade-sys .fd-note-pill { align-self: flex-start; }
.fd-grade-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 12px;
    margin-bottom: 10px;
}
.fd-grade-grid label { display: flex; flex-direction: column; gap: 5px; }
.fd-grade-grid span { font-size: 12.5px; font-weight: 700; color: var(--text-muted); }
.fd-grade-num { width: 92px; flex: 0 0 auto; }
.fd-grade-shape { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.fd-grade-shape > strong { display: block; margin-bottom: 8px; font-size: 13.5px; }

/* ---------------------------------------------------------------------
   2026-09-21 audit C12 - the report card / result sheet designer, with
   the real document previewed beside it (ReportCardDesign.php).
   --------------------------------------------------------------------- */
.fd-rcd { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.fd-rcd-templates { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
.fd-rcd-tpl {
    border: 2px solid var(--line-soft);
    border-radius: 16px;
    padding: 12px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin: 0;
}
.fd-rcd-tpl.on { border-color: var(--brand, #5849D6); background: var(--brand-20, #F2F0FF); }
.fd-rcd-tpl-icon {
    width: 34px;
    height: 34px;
    border-radius: 11px;
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, #6C63FF, #5849D6);
    color: #fff;
    font-size: 14px;
}
.fd-rcd-tpl strong { font-size: 13.5px; }
.fd-rcd-tpl small { font-size: 11.5px; color: var(--text-muted); line-height: 1.35; }
.fd-rcd-color { padding: 4px; height: 42px; }
.fd-rcd-flags { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 8px 14px; margin-top: 12px; }
.fd-rcd-preview { border: 1px solid var(--line-soft); border-radius: 18px; padding: 12px; background: var(--surface-2, #F6F7FB); }
.fd-rcd-preview-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; font-size: 13.5px; }
.fd-rcd-frame { width: 100%; height: 620px; border: 0; border-radius: 12px; background: #fff; }
@media (max-width: 991.98px) {
    .fd-rcd { grid-template-columns: minmax(0, 1fr); }
    .fd-rcd-frame { height: 460px; }
}
.fd-rsub-nav { margin: 8px 0 14px; }
.fd-rsub-nav .gceb-chipbtn small { background: #FA5252; color: #fff; border-radius: 999px; padding: 0 6px; margin-left: 4px; font-size: 10.5px; }
/* audit C12 - the grade scale as a compact row grid (it used to be a
   full-width table the responsive styling stacked into a tall column). */
.fd-band-grid { display: flex; flex-direction: column; gap: 6px; }
.fd-band-head, .fd-band-row { display: grid; grid-template-columns: 110px 90px 90px 90px minmax(0, 1fr); gap: 8px; align-items: center; }
.fd-band-head span { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); }
.fd-band-row .form-control { padding: 8px 10px; }
@media (max-width: 720px) {
    .fd-band-head { display: none; }
    .fd-band-row { grid-template-columns: 1fr 1fr; padding: 10px; border: 1px solid var(--line-soft); border-radius: 14px; }
    .fd-band-row .form-control:last-child { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------------
   2026-09-21 audit C8 - Academics > Timetable (fd-timetable.js): the
   week as a grid, days across and periods down, with the breaks.
   --------------------------------------------------------------------- */
.fd-tt-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.fd-tt-class { max-width: 240px; }
.fd-tt-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 16px; }
.fd-tt-grid { width: 100%; min-width: 640px; border-collapse: separate; border-spacing: 5px; }
.fd-tt-grid thead th { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); text-align: center; padding: 4px; }
.fd-tt-grid td { padding: 0; vertical-align: stretch; }
.fd-tt-time { width: 64px; text-align: right; padding-right: 6px !important; font-size: 12px; white-space: nowrap; }
.fd-tt-time b { display: block; font-size: 12.5px; }
.fd-tt-time small { color: var(--text-muted); }
.fd-tt-cell, .fd-tt-empty {
    width: 100%;
    min-height: 62px;
    height: 100%;
    border-radius: 12px;
    border: 0;
    cursor: pointer;
    text-align: left;
    padding: 7px 9px;
    font: inherit;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.fd-tt-cell { background: var(--brand-20, #F2F0FF); }
.fd-tt-cell strong { font-size: 12.5px; line-height: 1.25; }
.fd-tt-cell small { font-size: 11px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fd-tt-cell.tone-0 { background: #EEEBFF; } .fd-tt-cell.tone-1 { background: #FFF1E6; } .fd-tt-cell.tone-2 { background: #E6FAF3; }
.fd-tt-cell.tone-3 { background: #E7F3FF; } .fd-tt-cell.tone-4 { background: #FFEAF0; } .fd-tt-cell.tone-5 { background: #F3ECFA; }
.fd-tt-empty { background: transparent; border: 1.5px dashed var(--line-soft); color: var(--text-muted); align-items: center; justify-content: center; }
.fd-tt-empty:hover { border-color: var(--brand, #5849D6); color: var(--brand, #5849D6); background: var(--brand-20, #F2F0FF); }
.fd-tt-break td { text-align: center; font-size: 11.5px; font-weight: 700; color: #C24E0A; background: #FFF4E6; border-radius: 10px; padding: 5px !important; }

/* ---------------------------------------------------------------------
   2026-09-21 audit C15 - leaderboard pop-up (fd-leaderboard.js) and the
   trophy button in the profile pop-up's corner.
   --------------------------------------------------------------------- */
.fd-sheet-lb { color: #F59F00; }
.fd-lb-modal .gceb-modal-box { max-width: 620px; }
.fd-lb-loading { padding: 30px; text-align: center; color: var(--text-muted); }
.fd-lb-scopes { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin: 2px 0 16px; }
.fd-lb-scope { border: none; border-radius: 999px; padding: 7px 16px; font-weight: 700; font-size: 13px; background: var(--surface-2, #F1F0FA); color: var(--text); cursor: pointer; }
.fd-lb-scope.active { background: linear-gradient(135deg, #7C73FF, #5849D6); color: #fff; }
.fd-lb-podium { display: grid; grid-template-columns: repeat(3, 1fr); align-items: end; gap: 10px; margin: 8px 0 16px; }
.fd-lb-step { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 3px; position: relative; min-width: 0; }
.fd-lb-step strong { font-size: 12.5px; max-width: 100%; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.fd-lb-step strong em { font-style: normal; color: var(--brand, #5849D6); }
.fd-lb-step small { font-size: 12px; color: var(--text-muted); font-weight: 700; }
.fd-lb-av { width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 17px; background: linear-gradient(135deg, #ADB5BD, #868E96); box-shadow: 0 6px 16px rgba(30, 22, 90, .15); }
.fd-lb-step.p1 .fd-lb-av { width: 66px; height: 66px; font-size: 20px; background: linear-gradient(135deg, #FFD43B, #F59F00); }
.fd-lb-step.p2 .fd-lb-av { background: linear-gradient(135deg, #CED4DA, #868E96); }
.fd-lb-step.p3 .fd-lb-av { background: linear-gradient(135deg, #FFA94D, #D9480F); }
.fd-lb-step.me .fd-lb-av { outline: 3px solid var(--brand, #5849D6); outline-offset: 2px; }
.fd-lb-crown { color: #F59F00; font-size: 20px; margin-bottom: -2px; }
.fd-lb-block { width: 100%; border-radius: 14px 14px 6px 6px; display: grid; place-items: center; color: #fff; margin-top: 6px; }
.fd-lb-block b { font-size: 22px; font-family: 'Poppins', sans-serif; }
.fd-lb-step.p1 .fd-lb-block { height: 92px; background: linear-gradient(180deg, #FFD43B, #F59F00); }
.fd-lb-step.p2 .fd-lb-block { height: 66px; background: linear-gradient(180deg, #CED4DA, #868E96); }
.fd-lb-step.p3 .fd-lb-block { height: 48px; background: linear-gradient(180deg, #FFA94D, #D9480F); }
.fd-lb-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 26px 10px; text-align: center; color: var(--text-muted); }
.fd-lb-empty i { font-size: 28px; color: #12B886; }
.fd-lb-empty strong { color: var(--text); }
.fd-lb-mine { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 20px; background: linear-gradient(135deg, #7C73FF, #5849D6); color: #fff; margin-bottom: 8px; }
.fd-lb-mine-rank { width: 50px; height: 50px; border-radius: 50%; background: rgba(255, 255, 255, .2); display: grid; place-items: center; font-weight: 800; font-size: 15px; flex: 0 0 auto; }
.fd-lb-mine-text { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.fd-lb-mine-text small, .fd-lb-mine-pts small { opacity: .8; font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; }
.fd-lb-mine-pts { display: flex; flex-direction: column; align-items: flex-end; }
.fd-lb-mine-pts b { font-size: 20px; line-height: 1.1; }
.fd-lb-h { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--text-muted); margin: 18px 0 8px; }
.fd-lb-rank { font-weight: 800; font-size: 15px; font-style: normal; }
.fd-lb-me-row { outline: 2px solid var(--brand, #5849D6); }
.fd-lb-ways { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.fd-lb-way, .fd-lb-recent > div { display: flex; align-items: center; gap: 10px; background: var(--surface-2, #F6F7FB); border-radius: 14px; padding: 9px 12px; font-size: 13px; }
.fd-lb-way i, .fd-lb-recent i { color: var(--brand, #5849D6); width: 18px; text-align: center; }
.fd-lb-way span, .fd-lb-recent span { flex: 1 1 auto; min-width: 0; }
.fd-lb-way b { color: #0CA678; white-space: nowrap; }
.fd-lb-way b small { color: var(--text-muted); font-weight: 600; }
.fd-lb-recent { display: flex; flex-direction: column; gap: 6px; }
.fd-lb-recent small { color: var(--text-muted); font-size: 11.5px; }
.fd-lb-recent b { color: #0CA678; min-width: 34px; text-align: right; }
.fd-lb-recent b.neg { color: #E03131; }
.fd-pts-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.fd-pts-card { display: grid; grid-template-columns: 40px 1fr auto; grid-template-rows: auto auto; gap: 8px 10px; align-items: center; padding: 12px; border-radius: 18px; background: var(--surface-2, #F6F7FB); }
.fd-pts-card .fd-pts-ic { grid-row: 1; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; color: #fff; background: linear-gradient(135deg, #7C73FF, #5849D6); }
.fd-pts-card strong { font-size: 13.5px; }
.fd-pts-card label { grid-column: span 1; display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; color: var(--text-muted); margin: 0; }
.fd-pts-card label:first-of-type { grid-column: 1 / span 2; }
.fd-pts-card input[type="number"] { width: 72px; }

/* ---------------------------------------------------------------------
   2026-09-21 audit D8 - teacher tools as pop-ups: FDModal.page() and the
   chrome-less page it frames (?fd_frame=1 -> body.fd-framed).
   --------------------------------------------------------------------- */
.fd-page-modal .gceb-modal-box { max-width: min(1180px, 96vw); width: 100%; }
.fd-page-modal .gceb-modal-body { padding: 0 !important; overflow: hidden; }
/* 2026-10-02 (foundation rebuild): the pop-up no longer holds an <iframe>.
   Its content is injected into this document (fd-modal.js injectPage), so the
   wrapper scrolls its own content instead of handing scrolling to a nested
   document - which is why pop-ups used to get their own scrollbar and feel
   detached from the page behind them. */
.fd-page-frame-wrap { position: relative; max-height: min(78vh, calc(100vh - 150px)); overflow: auto; -webkit-overflow-scrolling: touch; background: var(--bg, #F6F7FB); }
.fd-page-host { display: block; min-height: 40px; }
.fd-page-host > .form-container { padding: 14px 16px 20px; }
.fd-page-frame-load { display: flex; flex-direction: column; gap: 10px; align-items: center; justify-content: center; min-height: 220px; color: var(--text-muted); font-size: 22px; }
.fd-page-frame-load span { font-size: 13.5px; letter-spacing: .01em; }
/* A pop-up that cannot show what was asked for says so properly, rather than
   rendering the login page or a bare "Access denied" string. */
.fd-page-fail { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; padding: 42px 26px; }
.fd-page-fail i { font-size: 30px; color: var(--brand-600, #5849D6); opacity: .85; }
.fd-page-fail strong { font-size: 16.5px; font-weight: 700; }
.fd-page-fail p { margin: 0; font-size: 13.5px; color: var(--text-muted); max-width: 42ch; line-height: 1.55; }
.fd-page-fail .gce-btn { margin-top: 6px; }
@media (max-width: 768px) { .fd-page-frame-wrap { max-height: calc(100vh - 120px); } }

/* 403 / stop page (bootstrap.php fd_deny_forbidden) - replaces die('Access denied'). */
.fd-stop-page { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; padding: 32px 22px; background: var(--bg, #F6F7FB); }
.fd-stop-icon { width: 62px; height: 62px; border-radius: 20px; display: grid; place-items: center; font-size: 24px; color: #fff; background: linear-gradient(135deg, var(--brand-500, #6C5CE7), var(--brand-700, #4A3BC4)); box-shadow: 0 10px 26px rgba(88,73,214,.28); }
.fd-stop-page h1 { font-size: 20px; font-weight: 700; margin: 8px 0 0; }
.fd-stop-page p { margin: 0; font-size: 14px; color: var(--text-muted); max-width: 46ch; line-height: 1.6; }
.fd-stop-detail { font-size: 12px !important; opacity: .7; }
.fd-stop-actions { display: flex; flex-direction: column; gap: 10px; align-items: center; margin-top: 14px; }
.fd-stop-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 0 24px; border-radius: 14px; background: var(--brand-600, #5849D6); color: #fff; font-weight: 600; font-size: 14.5px; text-decoration: none; }
.fd-stop-btn:hover { color: #fff; opacity: .93; }
.fd-stop-link { font-size: 13px; color: var(--text-muted); text-decoration: underline; }
body.fd-framed .mobile-top-nav, body.fd-framed #verticalTabs, body.fd-framed .vertical-tabs-wrapper,
body.fd-framed .vertical-icons-right, body.fd-framed #fdUtilRail, body.fd-framed .app-hero,
body.fd-framed #fdMobileSheet, body.fd-framed #fdSheetBackdrop, body.fd-framed .fd-topbar .fd-back,
body.fd-framed .fd-mobile-progress, body.fd-framed #fdDesktopProfileGap { display: none !important; }
body.fd-framed .content-body1, body.fd-framed .main-wrapper { padding: 0 !important; margin: 0 !important; min-height: 0 !important; }
body.fd-framed .form-container { padding: 14px 16px 30px !important; margin: 0 !important; max-width: none !important; transform: none !important; }
body.fd-framed .fd-topbar h2 { font-size: 18px; }

/* ---------------------------------------------------------------------
   2026-09-21 audit D6 - the evaluation builder pop-up (fd-eval-builder.js).
   --------------------------------------------------------------------- */
.fd-evb .gceb-modal-box { max-width: min(1120px, 96vw); width: 100%; }
.fd-evb .gceb-modal-foot { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.fd-evb-load { padding: 40px; text-align: center; color: var(--text-muted); font-size: 22px; }
.fd-evb-steps { display: flex; gap: 8px; margin: 0 0 16px; flex-wrap: wrap; }
.fd-evb-step { border: none; background: var(--surface-2, #F1F0FA); color: var(--text); border-radius: 999px; padding: 7px 14px 7px 7px; font-weight: 700; font-size: 13px; display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.fd-evb-step b { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: #fff; color: var(--brand, #5849D6); font-size: 12px; }
.fd-evb-step em { font-style: normal; background: #12B886; color: #fff; border-radius: 999px; padding: 1px 8px; font-size: 11px; }
.fd-evb-step.on { background: linear-gradient(135deg, #7C73FF, #5849D6); color: #fff; }
.fd-evb-h { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--text-muted); margin: 16px 0 8px; }
.fd-evb-types { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.fd-evb-type { border: 2px solid transparent; border-radius: 16px; padding: 12px 10px; background: var(--tl, #F0EEFF); display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; cursor: pointer; font-weight: 700; font-size: 13px; color: var(--text); text-decoration: none; }
.fd-evb-type i { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; color: #fff; background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6)); font-size: 15px; }
.fd-evb-type small { font-weight: 600; color: var(--text-muted); font-size: 11px; }
.fd-evb-type.on { border-color: var(--brand, #5849D6); box-shadow: 0 8px 20px rgba(88, 73, 214, .18); }
.fd-evb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px 12px; margin-top: 14px; }
.fd-evb-f { display: flex; flex-direction: column; gap: 5px; margin: 0; }
.fd-evb-f.wide { grid-column: 1 / -1; }
.fd-evb-f > span { font-size: 12px; font-weight: 700; color: var(--text-muted); }
.fd-evb-f > span i { color: var(--brand, #5849D6); margin-right: 4px; }
.fd-evb-who { display: flex; gap: 10px; flex-wrap: wrap; }
.fd-evb-radio { display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px; border-radius: 14px; background: var(--surface-2, #F6F7FB); font-weight: 600; font-size: 13.5px; cursor: pointer; margin: 0; }
.fd-evb-stu { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 6px; margin-top: 10px; max-height: 190px; overflow: auto; }
.fd-evb-stu label { display: flex; gap: 8px; align-items: center; font-size: 13px; margin: 0; }
.fd-evb-switch { display: flex; gap: 12px; align-items: center; margin-top: 14px; padding: 12px 14px; border-radius: 16px; background: var(--surface-2, #F6F7FB); cursor: pointer; }
.fd-evb-switch span { display: flex; flex-direction: column; }
.fd-evb-switch small { color: var(--text-muted); font-size: 12px; }
.fd-evb-tray { padding: 10px 12px; border-radius: 16px; background: var(--surface-2, #F6F7FB); margin-bottom: 12px; font-size: 13px; }
.fd-evb-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; max-height: 88px; overflow: auto; }
.fd-evb-chip { display: inline-flex; align-items: center; gap: 6px; background: #fff; border-radius: 999px; padding: 4px 6px 4px 10px; font-size: 12px; box-shadow: 0 1px 3px rgba(0, 0, 0, .06); }
.fd-evb-chip button { border: none; background: #FFE3E3; color: #E03131; width: 20px; height: 20px; border-radius: 50%; font-size: 10px; cursor: pointer; }
html[data-theme="dark"] .fd-evb-chip, html[data-theme="dark"] .fd-evb-step b { background: rgba(255, 255, 255, .08); }
.fd-evb-split { display: grid; grid-template-columns: minmax(240px, 330px) 1fr; gap: 14px; align-items: start; }
.fd-evb-colh { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 13.5px; margin-bottom: 8px; min-height: 32px; flex-wrap: wrap; }
.fd-evb-colh i { color: var(--brand, #5849D6); }
.fd-evb-tree { max-height: 52vh; overflow: auto; padding-right: 4px; }
.fd-evb-topic { margin-bottom: 6px; }
.fd-evb-trow, .fd-evb-lrow { width: 100%; border: 2px solid transparent; display: flex; align-items: center; gap: 8px; text-align: left; cursor: pointer; font: inherit; color: var(--text); }
.fd-evb-trow { padding: 9px 10px; border-radius: 14px; background: var(--tl, #F0EEFF); font-weight: 700; font-size: 13.5px; }
.fd-evb-trow small, .fd-evb-lrow small { margin-left: auto; color: var(--text-muted); font-weight: 700; font-size: 11px; white-space: nowrap; }
.fd-evb-tname { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.fd-evb-chev { font-size: 11px; color: var(--t, #5849D6); width: 12px; }
.fd-evb-trow.on, .fd-evb-lrow.on { border-color: var(--brand, #5849D6); }
.fd-evb-lessons { padding: 6px 0 4px 18px; display: flex; flex-direction: column; gap: 4px; }
.fd-evb-lrow { padding: 7px 10px; border-radius: 12px; background: var(--surface-2, #F6F7FB); font-size: 13px; }
.fd-evb-lrow i { color: var(--brand, #5849D6); font-size: 12px; }
.fd-evb-now, .fd-evb-next { font-size: 10px; font-weight: 800; padding: 2px 7px; border-radius: 999px; color: #fff; background: #12B886; text-transform: uppercase; }
.fd-evb-next { background: #F59F00; }
.fd-evb-add { display: flex; gap: 6px; margin-top: 6px; }
.fd-evb-add input { flex: 1; min-width: 0; }
.fd-evb-empty { color: var(--text-muted); font-size: 13px; padding: 8px 2px; }
.fd-evb-empty.big { text-align: center; padding: 34px 12px; }
.fd-evb-empty.big i { font-size: 26px; color: var(--brand, #5849D6); display: block; margin-bottom: 8px; }
.fd-evb-qs { display: flex; flex-direction: column; gap: 6px; max-height: 52vh; overflow: auto; padding-right: 4px; }
.fd-evb-q { display: flex; gap: 10px; align-items: flex-start; text-align: left; border: 2px solid transparent; border-radius: 14px; padding: 10px 12px; background: var(--surface-2, #F6F7FB); cursor: pointer; font: inherit; color: var(--text); }
.fd-evb-q.on { border-color: #12B886; background: #EBFBF3; }
html[data-theme="dark"] .fd-evb-q.on { background: rgba(18, 184, 134, .12); }
.fd-evb-qtick { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: #fff; color: var(--brand, #5849D6); font-size: 11px; }
.fd-evb-q.on .fd-evb-qtick { background: #12B886; color: #fff; }
.fd-evb-qtext { font-size: 13.5px; display: flex; flex-direction: column; gap: 3px; }
.fd-evb-qtext small { color: var(--text-muted); font-size: 11.5px; }
.fd-evb-warn { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.fd-evb-warn div { background: #FFF4E6; color: #D9480F; border-radius: 12px; padding: 8px 12px; font-size: 13px; }
.fd-evb-olist { margin: 0; padding-left: 20px; font-size: 13.5px; display: flex; flex-direction: column; gap: 4px; }
@media (max-width: 760px) {
    .fd-evb-split { grid-template-columns: 1fr; }
    .fd-evb-tree, .fd-evb-qs { max-height: none; }
}

/* ---------------------------------------------------------------------
   2026-09-21 audit D10 - the syllabus (teacher: fd-syllabus.js; student:
   subject_tools.php Study tab).
   --------------------------------------------------------------------- */
.fd-syl-head { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-radius: 20px; background: var(--surface-2, #F6F7FB); margin-bottom: 12px; }
.fd-syl-ring { width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto; display: grid; place-items: center; background: conic-gradient(#12B886 calc(var(--p) * 1%), rgba(0, 0, 0, .08) 0); }
.fd-syl-ring b { width: 50px; height: 50px; border-radius: 50%; background: var(--surface, #fff); display: grid; place-items: center; font-size: 13px; }
.fd-syl-headtext { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fd-syl-headtext small { color: var(--text-muted); font-size: 12.5px; }
.fd-syl-hint { font-size: 11.5px !important; }
.fd-syl-list { display: flex; flex-direction: column; gap: 10px; }
.fd-syl-topic { border-radius: 20px; background: var(--tl, #F0EEFF); overflow: hidden; }
.fd-syl-topic.is-now { box-shadow: 0 0 0 2px #12B886 inset; }
.fd-syl-trow { width: 100%; display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: none; background: none; text-align: left; font: inherit; color: var(--text); cursor: pointer; }
.fd-syl-trow .fd-note-text small { white-space: normal; }
.fd-syl-num { font-weight: 800; font-size: 15px; }
.fd-syl-bar { display: block; height: 5px; border-radius: 99px; background: rgba(0, 0, 0, .07); overflow: hidden; margin-top: 4px; max-width: 260px; }
.fd-syl-bar i { display: block; height: 100%; background: #12B886; border-radius: 99px; }
.fd-syl-done { font-size: 10.5px; font-weight: 800; padding: 3px 8px; border-radius: 999px; background: #12B886; color: #fff; white-space: nowrap; }
.fd-syl-chev { color: var(--t, #5849D6); font-size: 12px; margin-left: 4px; }
.fd-syl-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 14px 10px; }
.fd-syl-lessons { background: var(--surface, #fff); margin: 0 10px 10px; border-radius: 16px; padding: 8px 10px; display: flex; flex-direction: column; gap: 4px; }
.fd-syl-lesson { display: flex; align-items: center; gap: 8px; padding: 6px 4px; border-bottom: 1px solid var(--line-soft, #EEE); }
.fd-syl-lesson:last-of-type { border-bottom: none; }
.fd-syl-lname { flex: 1 1 auto; min-width: 0; font-size: 13.5px; display: flex; flex-direction: column; }
.fd-syl-lname small { color: var(--text-muted); font-size: 11px; }
.fd-syl-lesson.done .fd-syl-lname { color: var(--text-muted); text-decoration: line-through; text-decoration-color: rgba(0, 0, 0, .25); }
.fd-syl-tick { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; border: 2px solid #CED4DA; background: none; color: transparent; display: grid; place-items: center; cursor: pointer; font-size: 12px; }
.fd-syl-lesson.done .fd-syl-tick { background: #12B886; border-color: #12B886; color: #fff; }
.fd-syl-addrow { display: flex; gap: 8px; margin-top: 12px; }
.fd-syl-addrow.sm { margin-top: 6px; }
.fd-syl-addrow input { flex: 1; min-width: 0; }
.fd-syl-notes { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.fd-syl-note { background: var(--surface-2, #F6F7FB); border-radius: 16px; padding: 10px 12px; }
.fd-syl-note-h { display: flex; align-items: center; gap: 8px; }
.fd-syl-note-h i { color: var(--brand, #5849D6); }
.fd-syl-note-body { font-size: 14px; line-height: 1.6; margin-top: 6px; }
.fd-syl-video { position: relative; padding-top: 56.25%; border-radius: 12px; overflow: hidden; margin-top: 8px; background: #000; }
.fd-syl-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.fd-syl-kinds { display: flex; gap: 8px; margin-bottom: 10px; }
.fd-syl-noteform { border-top: 1px dashed var(--line-soft, #E5E5EF); padding-top: 10px; }
/* student view */
.fd-ssyl { margin-bottom: 16px; }
.fd-ssyl-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.fd-ssyl-top h4 { margin: 0; font-size: 16px; font-family: 'Poppins', sans-serif; }
.fd-ssyl-top small { color: var(--text-muted); }
.fd-ssyl .fd-note-row.is-now { box-shadow: 0 0 0 2px #12B886 inset; }
.fd-ssyl .fd-note-row.is-done .fd-note-icon { background: linear-gradient(135deg, #38D9A9, #0CA678); }
.fd-ssyl-lesson { border-radius: 14px; background: var(--surface-2, #F6F7FB); padding: 10px 12px; margin-bottom: 8px; }
.fd-ssyl-lesson > strong { display: flex; gap: 8px; align-items: center; }
.fd-ssyl-lesson > strong .fa-circle-check { color: #12B886; }
.fd-tp-topic.part i { color: #F59F00; }
.fd-tp-topic .fd-evb-now, .fd-tp-topic .fd-evb-next { font-size: 9.5px; padding: 1px 6px; }
.fd-tp-recent { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; font-size: 12.5px; }
.fd-tp-recent small { font-weight: 800; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); font-size: 10.5px; }
.fd-tp-recent i { color: #12B886; }
.fd-tp-recent em { color: var(--text-muted); font-style: normal; font-size: 11.5px; }

/* ==========================================================================
   2026-09-22 (thirty-ninth follow-up) - the student Study tab: one topic
   list with two rings, and "Save for offline" as a switch on the heading row.

   Quoted directly: "in the study tab remove the class syllabus rather just
   use the tittle topics since its samething then on the progress rings on
   eqch topic we will add a second ring which is the progress of how the
   teqcher is covering that topic while the other is the student progress.
   make the save for offline a toggle which should be played on same
   horizontal line as the "topics" name".

   The single-ring `.fd-st-ring` rules above are untouched - a self-study
   subject with no class syllabus behind it still renders exactly that.
   `.dual` is additive: a slightly larger badge, a second (inner) arc, and
   the completed state moved off the whole ring onto the small centre disc
   so a finished topic no longer hides the class's own arc behind green.
   ========================================================================== */
.fd-st-ring.dual { width: 46px; height: 46px; }
.fd-st-ring.dual circle { stroke-width: 3.2; }
.fd-st-ring .trk2 { stroke: rgba(0, 0, 0, .07); }
.fd-st-ring .bar2 { stroke: var(--fd-st-class, #F59F00); stroke-linecap: round; transition: stroke-dasharray .6s ease; }
.fd-st-core {
    position: relative;
    width: 17px; height: 17px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    font-size: 9.5px; font-weight: 800; line-height: 1;
    color: var(--t, #5849D6);
}
.fd-st-core em { font-style: normal; font-size: 7px; }
.fd-st-ring.dual.done .fd-st-core {
    background: #12B886; color: #fff; font-size: 9px;
    width: 19px; height: 19px;
    box-shadow: 0 4px 10px rgba(18, 184, 134, .35);
}
/* Without this key the two arcs are just two colours with no meaning. */
.fd-st-legend { display: inline-flex; align-items: center; gap: 5px; margin-left: 8px; font-size: 11.5px; color: var(--text-muted); white-space: nowrap; }
.fd-st-key { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.fd-st-key.you { background: #5849D6; }
.fd-st-key.cls { background: #F59F00; margin-left: 6px; }
html[data-theme="dark"] .fd-st-ring .trk2 { stroke: rgba(255, 255, 255, .1); }

/* The heading row now carries the offline switch beside the "Topics" name
   at every width - the caption and the search box wrap under it. */
.fd-study-head { align-items: center; row-gap: 6px; }
.fd-study-head-h { flex: 1 1 auto; margin: 0; min-width: 0; }
.fd-study-head-sub { flex: 1 0 100%; margin: 0 !important; order: 3; }
.fd-study-head .fd-study-search { flex: 0 0 260px; max-width: 100%; order: 4; margin-left: auto; }
.fd-study-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.fd-study-offline {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 7px 12px; margin: 0;
    border-radius: 999px;
    background: var(--brand-25); border: 1px solid var(--brand-200, #C9C3F5);
    cursor: pointer;
}
.fd-study-offline .fd-study-offline-icon { width: 28px; height: 28px; border-radius: 50%; font-size: 12px; }
.fd-study-offline .fd-study-offline-text { gap: 0; }
.fd-study-offline .fd-study-offline-text strong { font-size: 12.5px; line-height: 1.2; }
.fd-study-offline .fd-study-offline-state { font-size: 11px; color: var(--text-muted); }
.fd-study-offline.saved { background: rgba(18, 184, 134, .08); border-color: rgba(18, 184, 134, .35); }
.fd-study-offline.saved .fd-study-offline-icon { background: linear-gradient(135deg, #20C997, #0CA678); }
@media (max-width: 768px) {
    /* The switch stays beside the heading; only the search box goes
       full-width under it. */
    .fd-study-head .fd-study-search { flex: 1 0 100%; margin-left: 0; }
    .fd-study-offline { padding: 6px 10px; gap: 8px; }
    .fd-study-offline .fd-study-offline-icon { display: none; }
}
@media (max-width: 400px) {
    /* No room for the state line next to a heading on the narrowest
       phones - the switch position already says whether it is on. */
    .fd-study-offline .fd-study-offline-state { display: none; }
}

/* The dual ring needs a few more pixels than the single one it replaces, in
   both of the layouts the topic list has: the desktop card grid and the
   mobile full-width row, each of which pins the ring to 34px. */
.fd-study-topic-list .fd-st-ring.dual { width: 40px; height: 40px; }
.fd-study-topic-list .fd-st-ring.dual .fd-st-core { width: 15px; height: 15px; font-size: 8.5px; }
.fd-study-topic-list .fd-st-ring.dual em { font-size: 6.5px; }
.fd-study-topic-list .fd-st-ring.dual.done .fd-st-core { width: 17px; height: 17px; font-size: 8px; }

/* The teacher's notes, carried into the topic / lesson pop-up from the
   syllabus list this round removed. */
.fd-study-cover { margin: 0 0 10px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fd-study-tnotes { margin: 0 0 12px; }
.fd-study-tnotes > small { display: block; margin-bottom: 6px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: 10.5px; }
.fd-study-lesson-list .fd-syl-done { margin-left: auto; flex: 0 0 auto; }

/* 2026-09-22 (thirty-ninth follow-up) - the student's own calendar entries
   (StudentPlanner) and the one card type they can remove. Quoted directly:
   "on the student index page clicking on an e,pty calendar day does not let
   us add schedule." */
.fd-ev--plan { border-left: 3px solid #7C5CFC; }
.fd-ev--plan .fd-ev-type i { color: #7C5CFC; }
.fd-ev-remove {
    flex: 0 0 auto; align-self: flex-start;
    width: 26px; height: 26px; padding: 0;
    border: none; border-radius: 50%;
    background: rgba(0, 0, 0, .05); color: var(--text-muted, #6B6880);
    font-size: 11px; cursor: pointer; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
}
.fd-ev-remove:hover { background: rgba(250, 82, 82, .14); color: #E03131; }
html[data-theme="dark"] .fd-ev-remove { background: rgba(255, 255, 255, .08); }

/* ==========================================================================
   2026-09-22 (thirty-ninth follow-up) - the teacher profile pop-up, now the
   shared bottom sheet rather than its own overlay.

   Quoted directly: "for the teqcher profile under the profile tab give
   spaces and possible hr/ for eqch section assessment permissions, roles,
   and profile", "to avoid much scrolling can we show on the teacher prfile
   pop up the subjects he is assigned to in grid form instead?", and "it
   should be a pop up not modal please and the pop up should look like the
   user profile pop up fully flushed at the bottom and coners" - which the
   sheet component (.bottom-sheet, footer.php) already is, so the only thing
   needed here is the content's own spacing.
   ========================================================================== */
.fd-tp-wrap { position: relative; }
.fd-tp-wrap.is-busy { opacity: .55; pointer-events: none; }
.fd-tp-sec { display: block; }
.fd-tp-sec + .fd-tp-sec { margin-top: 18px; }
.fd-tp-hr { border: none; border-top: 1px solid var(--line-soft, #ECEAF6); margin: 20px 0 18px; opacity: 1; }
.fd-tp-chiprow { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.fd-tp-chip { border: none; cursor: pointer; }
.fd-tp-inline { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* The assigned subjects, as a grid instead of one full-width row each. */
.fd-tp-subj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
.fd-tp-subj {
    position: relative;
    display: flex; flex-direction: column; gap: 2px;
    padding: 12px 12px 10px;
    border-radius: 14px;
    background: var(--tl, #F0EEFF);
    min-width: 0;
}
.fd-tp-subj strong { font-size: 13.5px; line-height: 1.25; word-break: break-word; padding-right: 18px; }
.fd-tp-subj small { font-size: 11px; color: var(--text-muted); }
.fd-tp-subj-ic {
    width: 30px; height: 30px; margin-bottom: 6px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 12px;
    background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6));
}
.fd-tp-subj-x {
    position: absolute; top: 6px; right: 6px;
    width: 22px; height: 22px; padding: 0;
    border: none; border-radius: 50%;
    background: rgba(0, 0, 0, .06); color: var(--text-muted, #6B6880);
    font-size: 10px; cursor: pointer; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
}
.fd-tp-subj-x:hover { background: rgba(250, 82, 82, .16); color: #E03131; }
html[data-theme="dark"] .fd-tp-subj { background: rgba(255, 255, 255, .05); }
html[data-theme="dark"] .fd-tp-subj-x { background: rgba(255, 255, 255, .1); }
@media (max-width: 480px) {
    .fd-tp-subj-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   2026-09-22 (thirty-ninth follow-up) - the shared "topic style" list
   (partials/topic_rows.php + fd-topic-rows.js), quoted directly: "online
   classes, tasks list should all have same style like the topics style with
   their buttons revealed at the bottom of the pop up when openned."

   The rows themselves reuse .fd-note-row/.fd-note-pill/.fd-note-go exactly
   as the Tasks list already did - nothing new is invented for them. Only two
   things are additional: a pill colour the older inline version never needed,
   and the footer that holds the item's real actions.
   ========================================================================== */
.fd-note-pill.warn { background: #F59F00; color: #fff; }
.fd-task-note { margin: 14px 0 0; padding: 12px 14px; border-radius: 14px; background: var(--surface-2, #F7F6FD); font-size: 13px; line-height: 1.55; }
html[data-theme="dark"] .fd-task-note { background: rgba(255, 255, 255, .05); }
.fd-task-actions { display: flex; gap: 10px; width: 100%; flex-wrap: wrap; padding: 4px 0; }

/* ==========================================================================
   2026-09-22 (thirty-ninth follow-up) - the summary-block pattern for the
   studios and builders.

   Quoted directly: "the builder and stuio used in the platfrom admin and
   school admin/teacher is quite good already but its abit overwhelming. i am
   thinking in the studio or builder secttions we make it in such a way that
   for example classes just shows the classes count and summry info then when
   u click on it it opens an other pop up where u can edit or add or delete
   classes then when u save it reduces back to just the summary same for
   options; subjects teachers students or auestions or topics etc. this will
   help to group data into a summary block rather than listing for exaple all
   classes or topics like that so now we only open them and work save and it
   goes back to the summry so everythig is organized and we scroll less."

   A block is one card: a big count, a couple of summary lines, and an open
   affordance. The editing UI it opens is the page's existing panel, drawn
   into a pop-up - nothing about those panels changes, which is the whole
   point of making this a wrapper rather than a rewrite.
   ========================================================================== */
.fd-sum-intro { margin: 0 0 16px; }
.fd-sum-intro h2 { font-family: 'Poppins', sans-serif; font-size: 20px; margin: 0 0 4px; }
.fd-sum-intro p { margin: 0; font-size: 13.5px; color: var(--text-muted); max-width: 62ch; }
.fd-sum-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.fd-sum-card {
    position: relative;
    display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
    text-align: left;
    padding: 18px 16px 52px;
    border: none; border-radius: 20px;
    background: var(--tl, #F0EEFF);
    cursor: pointer;
    transition: transform .12s, box-shadow .12s;
    min-height: 168px;
    width: 100%;
    font: inherit;
    color: inherit;
}
.fd-sum-card:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(30, 22, 90, .12); }
.fd-sum-ic {
    width: 40px; height: 40px; margin-bottom: 6px;
    border-radius: 13px;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 16px;
    background: var(--tg, linear-gradient(135deg, #7C73FF, #5849D6));
}
.fd-sum-n { font-family: 'Poppins', sans-serif; font-size: 30px; font-weight: 700; line-height: 1; color: var(--t, #5849D6); }
.fd-sum-n em { font-style: normal; font-size: 12.5px; font-weight: 600; color: var(--text-muted); margin-left: 6px; }
.fd-sum-card strong { font-size: 14.5px; }
.fd-sum-lines { display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--text-muted); }
.fd-sum-warn { margin-top: 4px; font-size: 11.5px; font-weight: 700; color: #C24E0A; }
.fd-sum-go {
    position: absolute; left: 16px; bottom: 14px;
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; font-weight: 700; color: var(--t, #5849D6);
}
html[data-theme="dark"] .fd-sum-card { background: rgba(255, 255, 255, .05); }
@media (max-width: 575.98px) {
    .fd-sum-grid { grid-template-columns: 1fr; }
    .fd-sum-card { min-height: 0; padding-bottom: 48px; }
}
/* The "add one more of these" block on a summary board - same card, drawn
   as an outline so it reads as an action rather than a count. */
.fd-sum-card.fd-sum-card-add { background: transparent; border: 1.5px dashed var(--brand-200, #C9C3F5); justify-content: center; min-height: 140px; }
.fd-sum-card.fd-sum-card-add .fd-sum-ic { background: var(--brand-50, #F0EEFF); color: var(--brand-600, #5849D6); }

/* ==========================================================================
   2026-09-22 (thirty-ninth follow-up) - "Generate with AI" in the Question
   studio (QuestionForge + fd-question-studio.js's third tab), quoted
   directly: "i want to add a working question generator ... the questions
   have an explanation for each of the MCQ anszers including why answer A is
   wrong or B ot C and ofcuz an explanation for the correct answer too."

   Everything else in that tab reuses the studio's own vocabulary
   (.gceb-field, .gceb-chipbtn, .gceb-seg). These are the three things it
   genuinely adds: the run log, the reviewable question list, and the
   per-option editor where those explanations are checked before saving.
   ========================================================================== */
.fdqs-ailog { margin: 14px 0 4px; display: flex; flex-direction: column; gap: 6px; }
.fdqs-ailog-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 12px; background: var(--surface-2, #F7F6FD); font-size: 13px; }
.fdqs-ailog-row i { width: 16px; text-align: center; color: var(--text-muted); }
.fdqs-ailog-row.done i { color: #12B886; }
.fdqs-ailog-row.failed i { color: #FA5252; }
.fdqs-ailog-row strong { font-size: 13px; }
.fdqs-ailog-row small { margin-left: auto; color: var(--text-muted); font-size: 11.5px; text-align: right; }

.fdqs-aihead { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 18px 0 8px; flex-wrap: wrap; }
.fdqs-aihead span { display: flex; gap: 6px; }
.fdqs-ailist { display: flex; flex-direction: column; gap: 8px; }
.fdqs-airow {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start; gap: 10px;
    padding: 12px 14px;
    border-radius: 14px;
    background: var(--surface-2, #F7F6FD);
    border: 1.5px solid transparent;
}
.fdqs-airow.on { border-color: var(--brand-200, #C9C3F5); background: var(--brand-25, #F7F6FD); }
.fdqs-aitick { border: none; background: none; padding: 0; font-size: 17px; cursor: pointer; color: var(--text-muted); line-height: 1; }
.fdqs-airow.on .fdqs-aitick { color: var(--brand-600, #5849D6); }
.fdqs-aitext { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fdqs-aitext strong { font-size: 13.5px; line-height: 1.4; font-weight: 600; }
.fdqs-aitext small { font-size: 11.5px; color: var(--text-muted); }
.fdqs-aiedit { grid-column: 1 / -1; margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--line-soft, #ECEAF6); }
.fdqs-aiopt { display: grid; grid-template-columns: 28px 1fr; gap: 8px; align-items: start; margin-bottom: 10px; }
.fdqs-aiopt .l {
    width: 28px; height: 28px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: 12px; cursor: pointer;
    background: #fff; border: 1.5px solid var(--line-soft, #ECEAF6); color: var(--text-muted);
}
.fdqs-aiopt .l.on { background: #12B886; border-color: #12B886; color: #fff; }
.fdqs-aiopt input, .fdqs-aiopt textarea {
    width: 100%; padding: 8px 10px; font: inherit; font-size: 13px;
    border: 1.5px solid var(--line-soft, #ECEAF6); border-radius: 10px; background: #fff; color: inherit;
}
.fdqs-aiopt textarea { margin-top: 6px; resize: vertical; }
html[data-theme="dark"] .fdqs-ailog-row,
html[data-theme="dark"] .fdqs-airow { background: rgba(255, 255, 255, .05); }
html[data-theme="dark"] .fdqs-aiopt input,
html[data-theme="dark"] .fdqs-aiopt textarea,
html[data-theme="dark"] .fdqs-aiopt .l { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .12); }
/* The super admin's per-account switch for the AI question generator
   (2026-09-22, thirty-ninth follow-up) - same shape as the platform-role
   cards it sits under in the Accounts pop-up. */
.fd-acc-aiforge { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; border-radius: 14px; background: var(--surface-2, #F7F6FD); cursor: pointer; }
.fd-acc-aiforge span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fd-acc-aiforge b { font-size: 13.5px; }
.fd-acc-aiforge small { font-size: 11.5px; color: var(--text-muted); line-height: 1.45; }
html[data-theme="dark"] .fd-acc-aiforge { background: rgba(255, 255, 255, .05); }

/* ==========================================================================
   2026-09-25 (fortieth follow-up) - ONE pop-up width.

   Quoted directly: "pop up widths vary alot on desktop. i have said all
   widths should be same and wide enough."

   He is right, and it was measurable. Ten different desktop widths were live
   at once, across five files and four rounds of "make pop-ups wide":

     520px  .bottom-sheet base                    (template-exact.css)
     560px  .fdq-modal-card                       (app-extra)
     620px  .fd-lb-modal .gceb-modal-box          (app-extra)
     720px  .fdq-sheet > *                        (app-extra)
     760px  .fd-onboarding-page .fd-wizard-sheet  (app-extra)
     780px  .gceb-modal-box                       (gce.css)
     960px  .gceb-modal-box.wide / .fd-modal-box  (gce.css / app-extra)
    1000px  .gceb-modal-box                       (app-extra, overriding gce)
    1040px  .bottom-sheet                         (app-extra)
    1060px  .gceb-modal-box.wide                  (app-extra)
    1120px  .bottom-sheet-wide / .fd-evb          (app-extra)
    1180px  .fd-page-modal                        (app-extra)
    1320px  .bottom-sheet-full                    (app-extra)

   The earlier rounds each widened the surfaces they happened to be looking
   at, which is exactly how you end up with ten values and no way to reason
   about any of them. The fix is not another pass of widening: it is ONE
   token, set once, that every pop-up surface on the platform reads. Change
   this number and every pop-up changes together - which is the only way this
   stays true after the next round.

   Mobile is deliberately untouched: a pop-up there is a full-width bottom
   sheet and always was.
   ========================================================================== */
:root {
    /* The one width. `calc(100vw - 64px)` keeps a 32px gutter either side on
       a narrow laptop, so it is "wide enough" without ever touching the edge. */
    --fd-popup-w: min(1100px, calc(100vw - 64px));
}

@media (min-width: 769px) {
    /* Bottom sheets (the shared #fdcSheet, the profile / wallet / class
       sheets, the wizard sheets) - all re-anchored as centred dialogs at this
       width. `.bottom-sheet-wide` and `.bottom-sheet-full` are kept as class
       names so no call site has to change, but they no longer mean three
       different sizes. */
    .bottom-sheet,
    .bottom-sheet.bottom-sheet-wide,
    .bottom-sheet.bottom-sheet-full,
    .fd-onboarding-page .bottom-sheet.fd-wizard-sheet {
        width: var(--fd-popup-w);
        max-width: var(--fd-popup-w);
    }

    /* The GCE-builder family: the question studio, the academic studio, the
       accounts/billing pop-ups, the page-in-a-pop-up, the evaluation builder,
       the leaderboard.
       
       header.php loads gce.css AFTER app-extra.css, so a bare
       `.gceb-modal-box` here (0,1,0) LOSES to gce.css's own
       `.gceb-modal-box` (0,1,0) on source order, and `.gceb-modal-box.wide`
       (0,2,0) likewise. Measured: 780px and 960px respectively, straight
       past this block. Qualifying with the `.gceb-modal` parent lifts these
       to (0,2,0) and (0,3,0), which beats gce.css on specificity regardless
       of load order - and without `!important`, so a future per-feature rule
       can still override deliberately. */
    .gceb-modal .gceb-modal-box,
    .gceb-modal .gceb-modal-box.wide,
    .fd-lb-modal .gceb-modal-box,
    .fd-page-modal .gceb-modal-box,
    .fd-evb .gceb-modal-box,
    .fdqs .gceb-modal-box {
        width: 100%;
        max-width: var(--fd-popup-w);
    }

    /* No gutter is set on the overlays on purpose: the token's own
       `calc(100vw - 64px)` IS the 32px-a-side gutter. Adding overlay padding
       on top double-counts it and puts the modals a few pixels narrower than
       the sheets - measured, and exactly the kind of near-miss that reads as
       "the widths still vary". An overlay that already carries its own
       padding (people.php prints `padding:16px` inline) is harmless: 16px is
       less than the token's own 32px, so the token still binds. */

    /* The older .fd-modal-overlay pop-ups (People, Academics). */
    .fd-modal-box {
        width: 100%;
        max-width: var(--fd-popup-w) !important;
    }

    /* The quiz's own answer sheet and result card - the same width as
       everything else, so a quiz does not read as a different app. */
    .fdq-modal-card { max-width: var(--fd-popup-w); }
    .fdq-sheet > * { max-width: var(--fd-popup-w); }
}

/* ==========================================================================
   2026-09-25 (fortieth follow-up) - ONE button.

   Quoted directly: "a the buttons too accross the entire platfrom needs to
   be ame style i notice a game like design and the normal design i want one
   unifrom design everywhere."

   The "game like design" is precise and findable: `.gce-btn-primary` and
   `.gce-btn-ok` (gce.css) carry `box-shadow: 0 4px 0 <darker>` - a hard,
   blur-less offset - plus `transform: translateY(1px)` on :active, which is
   the standard mobile-game "3D key press". Everything drawn with the GCE
   builder's vocabulary (the studios, the question studio, the pop-up
   footers) got that; everything drawn with the template's vocabulary
   (.btn-primary, .btn-sm-add) got a flat button with a soft glow. Both are
   in heavy use - 204 and 537 call sites - so they meet constantly.

   Four vocabularies were live, and they disagreed on nearly every property:

                 radius  weight  size    height        press effect
     .gce-btn      14      800    14     42px          hard 4px offset + sink
     .btn-primary  14      600    14     ~44 (13/32)   soft glow + lift
     .btn-sm-add   14      600    12     ~34 (8/18)    none

   Rewriting ~740 call sites is not the fix. Making the classes AGREE is:
   every one of them now resolves to the same geometry and the same flat
   treatment, so the markup can keep whichever name it already has and the
   screen still looks like one app. The flat treatment wins over the game
   one because that is what was asked for, and because a hard offset shadow
   cannot sit next to a soft one without one of them looking broken.

   Load order matters here: header.php loads gce.css AFTER app-extra.css, so
   every rule below is qualified with `body` to out-specify gce.css's own
   (0,1,0) selectors without `!important`.
   ========================================================================== */
:root {
    --fd-btn-radius: 14px;
    --fd-btn-h: 44px;
    --fd-btn-h-sm: 36px;
    --fd-btn-weight: 700;
    --fd-btn-size: 14px;
    --fd-btn-size-sm: 12.5px;
    --fd-btn-shadow: 0 6px 16px rgba(88, 73, 214, .22);
    --fd-btn-shadow-hover: 0 8px 20px rgba(88, 73, 214, .30);
}

/* ---- shared geometry ---- */
body .gce-btn,
body .btn-primary,
body .btn-sm-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--fd-btn-h);
    padding: 0 20px;
    border: none;
    border-radius: var(--fd-btn-radius);
    font-family: inherit;
    font-weight: var(--fd-btn-weight);
    font-size: var(--fd-btn-size);
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease, background .15s ease, filter .15s ease;
}
body .gce-btn-sm,
body .btn-sm-add {
    min-height: var(--fd-btn-h-sm);
    padding: 0 14px;
    font-size: var(--fd-btn-size-sm);
    border-radius: 12px;
}

/* ---- the one primary treatment: flat fill, soft shadow, a small lift ---- */
body .gce-btn-primary,
body .btn-primary,
body .btn-sm-add {
    color: #fff;
    background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6));
    box-shadow: var(--fd-btn-shadow);
}
body .gce-btn-ok {
    color: #fff;
    background: linear-gradient(135deg, #38D9A9, #12B886);
    box-shadow: 0 6px 16px rgba(18, 184, 134, .26);
}
body .gce-btn-primary:hover:not(:disabled),
body .btn-primary:hover:not(:disabled),
body .btn-sm-add:hover:not(:disabled),
body .gce-btn-ok:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: var(--fd-btn-shadow-hover);
    color: #fff;
}
/* The press: the same everywhere, and NOT the game sink. */
body .gce-btn:active:not(:disabled),
body .btn-primary:active:not(:disabled),
body .btn-sm-add:active:not(:disabled) {
    transform: none;
    filter: brightness(.94);
}
body .gce-btn:disabled,
body .btn-primary:disabled,
body .btn-sm-add:disabled { opacity: .5; cursor: default; box-shadow: none; transform: none; }

/* ---- the quiet variants keep their colour, gain the shared geometry ---- */
body .gce-btn-light { background: var(--surface, #fff); color: var(--brand-600, #5849D6); box-shadow: 0 2px 8px rgba(30, 22, 90, .10); }
body .gce-btn-ghost { background: var(--brand-50, #F0EFFA); color: var(--brand-600, #5849D6); box-shadow: none; }
body .gce-btn-danger { background: #FFF0F0; color: #C92A2A; box-shadow: none; }
body .gce-btn-light:hover:not(:disabled),
body .gce-btn-ghost:hover:not(:disabled),
body .gce-btn-danger:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(.97); }

html[data-theme="dark"] body .gce-btn-light { background: rgba(255, 255, 255, .08); color: #CFC9FF; }
html[data-theme="dark"] body .gce-btn-ghost { background: rgba(255, 255, 255, .07); color: #CFC9FF; }

/* 2026-09-25 (fortieth follow-up) - the full-screen host every quiz now
   mounts into. Quoted directly: "i want exact same screen when dealing with
   any quiz or evalution or self learning."
   The host is only a positioning shell; the `.fdq` inside it is the same
   element self-study renders, so there is nothing to keep in sync. */
.fdq-host { position: fixed; inset: 0; z-index: 3000; }
.fdq-host[hidden] { display: none; }
body.fdq-open { overflow: hidden; }
/* Full screen needs a way out - the study screen already had one, the
   evaluation markup did not until this round. */
.fdq-top .fdq-close { margin-right: 2px; }

/* ===================================================================
   2026-09-25 (fortieth follow-up, phase 2) - the Academic Studio
   (core_system_files/js/fd-academic-studio.js).

   Quoted: "I wnt simplicity and uniform UI acrose the entire
   platfrom." So this block deliberately adds no new colour: it reuses
   the tone-N tints (--t / --tl) the academic pages already paint
   their cards with, the theme variables (--surface, --line, --text,
   --text-muted) and the phase-1 button tokens. Every name is new
   (fdas-), so nothing already on a page changes.
   =================================================================== */
.fdas-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 20px 0 12px; }
.fdas-head:first-child { margin-top: 2px; }
.fdas-head h4 { margin: 0; font-size: 15.5px; font-weight: 700; font-family: 'Poppins', sans-serif; color: var(--text); }
.fdas-head small { display: block; margin-top: 3px; font-size: 12.5px; color: var(--text-muted); line-height: 1.45; }
.fdas-head .gce-btn, .fdas-head .btn { flex: 0 0 auto; }

/* --- the level tab reuses the school admin's own class blocks
       (.fd-class-block, audit C5) rather than a second card style; the only
       new part is a place for the block's own actions. --- */
.fd-class-block-acts { display: flex; gap: 6px; margin-left: auto; flex: 0 0 auto; }
@media (max-width: 480px) {
    .fd-class-block-head { flex-wrap: wrap; }
    .fd-class-block-acts { margin-left: 0; width: 100%; }
    .fd-class-block-acts .gce-btn:first-child { flex: 1 1 auto; }
}

/* --- inside the studio sheet --- */
.fdas-form { display: block; padding-bottom: 4px; }
.fdas-rows { display: flex; flex-direction: column; gap: 8px; }
.fdas-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 16px; background: var(--tl, #F0EEFF); flex-wrap: wrap; }
.fdas-row-icon { width: 36px; height: 36px; border-radius: 12px; display: grid; place-items: center; font-size: 14px; color: #fff; background: var(--tg, #5849D6); flex: 0 0 auto; }
.fdas-row-text { flex: 1 1 200px; min-width: 0; }
.fdas-row-text strong { display: block; font-size: 14px; font-weight: 700; color: var(--text); }
.fdas-row-text small { display: block; font-size: 12px; color: var(--text-muted); margin-top: 2px; line-height: 1.45; }
.fdas-row-acts { display: flex; gap: 6px; flex: 0 0 auto; flex-wrap: wrap; }
.fdas-row.bad { background: var(--err-bg, #FFECEA); }
.fdas-row.bad .fdas-row-icon { background: var(--err, #C92A2A); }

/* --- the one tick control used for options, subjects, scope, teachers --- */
.fdas-pick { display: flex; flex-direction: column; gap: 6px; }
.fdas-pick-row { position: relative; display: flex; align-items: center; gap: 10px; padding: 11px 13px; border: 1.5px solid var(--line); border-radius: 16px; cursor: pointer; background: var(--surface); }
.fdas-pick-row input { position: absolute; opacity: 0; width: 0; height: 0; }
.fdas-pick-text { flex: 1 1 auto; min-width: 0; }
.fdas-pick-text strong { display: block; font-size: 14px; font-weight: 700; color: var(--text); }
.fdas-pick-text small { display: block; font-size: 12px; color: var(--text-muted); margin-top: 2px; line-height: 1.45; }
.fdas-pick-row > .fa-check { width: 22px; height: 22px; border-radius: 8px; display: grid; place-items: center; font-size: 11px; border: 1.5px solid var(--line); color: transparent; flex: 0 0 auto; }
.fdas-pick-row.on { border-color: var(--brand-600, #5849D6); }
.fdas-pick-row.on > .fa-check { background: var(--brand-600, #5849D6); border-color: var(--brand-600, #5849D6); color: #fff; }
.fdas-pick-row input:disabled ~ .fdas-pick-text { opacity: .5; }

.fdas-note { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: 16px; background: var(--tl, #F0EEFF); color: var(--text); font-size: 13px; line-height: 1.5; margin-bottom: 12px; }
.fdas-note i { margin-top: 2px; color: var(--brand-600, #5849D6); }
.fdas-note.warn { background: var(--warn-bg, #FFF6E0); }
.fdas-note.warn i { color: var(--warn, #B8790A); }
.fdas-note.bad { background: var(--err-bg, #FFECEA); }
.fdas-note.bad i { color: var(--err, #C92A2A); }

@media (max-width: 768px) {
    .fdas-row-acts { width: 100%; }
    .fdas-row-acts .gce-btn { flex: 1 1 auto; }
    .fdas-head { align-items: flex-start; }
}

/* 2026-09-25 (forty-third follow-up): the two new dials on each activity
   card in Engagement > Rewards (pass mark, per-correct-answer scoring). */
.fd-pts-per { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-muted); }
.fd-pts-per input { width: auto; margin: 0; }

/* ===================================================================
   2026-09-26 (forty-third follow-up) - mobile chrome moves.
   =================================================================== */
/* The bell now sits in the mobile top bar, immediately before the menu
   button. It is an <a> inside .nav-icons, so template-exact.css already
   gives it the 32px chip; this only places its unread badge. */
.fd-mobile-bell { position: relative; }
.fd-mobile-bell .fd-nav-badge {
    position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px;
    padding: 0 4px; border-radius: 999px; background: var(--err, #C92A2A); color: #fff;
    font-size: 10px; font-weight: 800; line-height: 16px; text-align: center;
}
.fd-mobile-bell .fd-nav-badge[hidden] { display: none; }
/* "the support icon should go inside the profile pop up - on mobile":
   below 992px the floating rail's Support button steps aside for the row
   inside the account sheet, so there is one entry point, not two. Above
   it the rail keeps Support and the sheet row is the redundant one. */
@media (max-width: 991.98px) {
    .fd-util-rail .fd-util-support { display: none; }
}
@media (min-width: 992px) {
    .fd-sheet-support { display: none; }
}

/* The wallet balance now lives in the sheet's subtitle slot, under the
   "Wallet" title, with the pending total beneath it (2026-09-26). */
.sheet-sub.fd-wal-sub-balance { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
/* 2026-09-26 (forty-seventh follow-up): the figure keeps its size and loses
   its weight - quoted, "no need to make the balance bold leave same font size
   but do not make it bold". 400 rather than 800; the size is untouched. */
.fd-wal-sub-row { display: flex; align-items: center; gap: 10px; }
.fd-wal-sub-amt {
    font-size: 30px; font-weight: 400; line-height: 1.1; color: var(--text);
    font-family: 'Poppins', sans-serif; letter-spacing: -.5px;
}
/* The eye sits on the balance's own row now, so it costs no vertical space at
   all - it used to have a band of its own above the tabs. */
.fd-wal-eye-inline {
    width: 34px; height: 34px; flex: 0 0 auto; padding: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; border: none; cursor: pointer;
    background: var(--brand-50, #F0EEFF); color: var(--brand-600, #5849D6);
}
.fd-wal-eye-inline:hover { background: var(--brand-100, #E3E0FB); }
.fd-wal-sub-pending { font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.fd-wal-sub-pending i { margin-right: 4px; }
.fd-wal-title-icon { margin-right: 6px; color: var(--brand-600, #5849D6); }
@media (max-width: 480px) {
    .fd-wal-sub-amt { font-size: 26px; }
}

/* ===================================================================
   2026-09-26 (forty-third follow-up) - question studio: a breadcrumb
   where the subject list used to be, and topics/lessons as a tree.
   =================================================================== */
.fdqs-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 10px 12px; border-radius: 14px; background: var(--tl, #F0EEFF); margin-bottom: 4px; }
.fdqs-crumb { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.fdqs-crumb.on { font-weight: 800; color: var(--brand-600, #5849D6); }
.fdqs-crumb-sep { font-size: 9px; color: var(--text-faint); }

.fdqs-tree { display: flex; flex-direction: column; gap: 4px; }
.fdqs-tree-row {
    display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
    padding: 9px 12px; border-radius: 12px; border: 1.5px solid transparent;
    background: var(--surface); color: var(--text); font: inherit; font-size: 13.5px; cursor: pointer;
}
.fdqs-tree-row:hover { background: var(--tl, #F0EEFF); }
.fdqs-tree-row.on { border-color: var(--brand-600, #5849D6); background: var(--tl, #F0EEFF); font-weight: 700; }
.fdqs-tree-row span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fdqs-tree-row small { font-size: 11px; font-weight: 800; padding: 1px 7px; border-radius: 999px; background: var(--tl, #F0EEFF); color: var(--brand-600, #5849D6); }
.fdqs-tree-ic { width: 16px; text-align: center; color: var(--brand-600, #5849D6); font-size: 12.5px; }
/* The indent and the rail are what make it read as a tree rather than a list. */
.fdqs-tree-kids { display: flex; flex-direction: column; gap: 4px; margin: 2px 0 6px 18px; padding-left: 12px; border-left: 2px solid var(--line); }
.fdqs-tree-lesson { font-size: 13px; }
.fdqs-tree-lesson .fdqs-tree-ic { color: var(--text-muted); }

/* 2026-09-26 (forty-sixth follow-up) - the wallet pop-up's own footer.
   Quoted: "the buttons on the wallat pop up should be at the very bottom, i
   mean all the button while the tabs at the top then the actually content of
   each tab in the middle." The tab strip moved to the top of the scroller and
   the actions into a real footer outside it, so a long tab (History, Fees)
   no longer scrolls its own button off the screen. */
#fdWalletSheetFooter:empty { display: none; }
#fdWalletSheet .fd-wal-bar { margin: 0 0 14px; position: static; }

/* ---------------------------------------------------------------------
   2026-09-26 (forty-sixth follow-up) - the quiz explanation and its action.

   Quoted: "why is the submission button so big on desktop. and the
   explanation view is so small that part of it hides under the button. can
   we make the button like an icon with an arrow to continue maybe on the
   right side and the text takes the larger part of the width".
   --------------------------------------------------------------------- */
.fdq-sheet-foot {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 12px; border-radius: 16px; cursor: pointer;
    background: rgba(255, 255, 255, .55);
}
.fdq-sheet-foot:hover { background: rgba(255, 255, 255, .8); }
.fdq-sheet-foot-text { flex: 1 1 auto; font-weight: 700; font-size: 15px; }
.fdq-sheet-go {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 16px;
}
.fdq-sheet-go.ok { background: #12B886; }
.fdq-sheet-go.bad { background: #FA5252; }
html[data-theme="dark"] .fdq-sheet-foot { background: rgba(0, 0, 0, .18); }

/* The explanation gets the room the old full-width button was taking. */
.fdq-sheet-body { max-height: 38vh; }
@media (min-width: 769px) {
    .fdq-sheet-body { max-height: 46vh; }
    /* Submit was width:100% at every size, which on a desktop quiz is a
       button the width of the whole card. It only ever needs to be as wide
       as its own label. */
    .fdq-submit { width: auto; min-width: 200px; display: block; margin-left: auto; margin-right: auto; }
}

/* 2026-09-26 (forty-sixth follow-up): the bell already sits in the mobile top
   bar, so the floating rail copy is the redundant one under 992px - the same
   one-entry-point-per-breakpoint rule the Support button follows just above.
   Quoted: "why do we still have it floating again on the bottom right side of
   the screen? that should be removed." */
@media (max-width: 991.98px) {
    .fd-util-rail .fd-util-notif { display: none; }
}


/*
 * 2026-09-26 (forty-sixth follow-up): the "See all" pop-up's list.
 *
 * The cards are clones of the column's own .fd-ev nodes, so they arrive
 * carrying the narrow-column desktop layout (stacked, clamped title). Inside a
 * sheet there is room for the roomier row layout the phone list uses, so it is
 * restored here rather than a third variant being invented.
 */
.fd-week-more-list { display: flex; flex-direction: column; gap: 10px; }
.fd-week-more-list .fd-ev { flex-direction: row; align-items: flex-start; gap: 12px; padding: 12px 14px; border-radius: 15px; }
/* Start and end stay on one line with the dash between them - stacked, with no
   separator, "08:00 / 09:00" reads as two separate activities. */
.fd-week-more-list .fd-ev-time { flex: 0 0 96px; flex-direction: row; align-items: baseline; justify-content: flex-start; gap: 4px; padding-top: 2px; }
.fd-week-more-list .fd-ev-time small::before { content: '\2013 '; }
.fd-week-more-list .fd-ev-title { font-size: 14px; -webkit-line-clamp: unset; display: block; white-space: normal; }
.fd-week-more-list .fd-ev-body { flex: 1 1 auto; min-width: 0; }


/* ===================================================================
   2026-09-26 (forty-seventh follow-up) - the student dashboard round
   =================================================================== */

/* "so its always shown there school logo, name and any other related sub text
   about the school" - the same .fd-note-row the GCE block uses, so the two
   read as one stack. The logo slot holds a real logo when the school has one
   and the school's initials when it does not. */
.fd-school-block { margin-bottom: 22px; }
.fd-school-row { cursor: default; }
.fd-school-logo { overflow: hidden; background: #fff; box-shadow: inset 0 0 0 1px var(--brand-100, #E3E0FB); }
.fd-school-logo { position: relative; }
/* 2026-09-27: the initials sit underneath and the logo covers them once it
   loads - so the card is never an empty square while an image is fetching,
   and a logo that cannot load leaves the initials rather than a blank. */
.fd-school-logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; background: #fff; }
.fd-school-logo b { font-family: 'Poppins', sans-serif; font-size: 13px; font-weight: 800; letter-spacing: .5px; color: var(--brand-600, #5849D6); text-transform: uppercase; }

/* "the my subjects card on the student index page is abit boring can we add
   some design to it like book icon in the background of each card faded and
   maybe slidly at the coner" - a large, very faint glyph tucked into the
   bottom-right, clipped by the card. It is decorative only: aria-hidden, and
   it sits behind the real content, which keeps its own contrast. */
.fd-subj-card { position: relative; overflow: hidden; }
.fd-subj-card .fd-subj-ghost {
    position: absolute; right: -12px; bottom: -16px;
    font-size: 78px; line-height: 1; pointer-events: none;
    color: var(--t, #6C63FF); opacity: .085;
    transform: rotate(-12deg); transition: transform .3s ease, opacity .3s ease;
}
.fd-subj-card:hover .fd-subj-ghost { transform: rotate(-4deg) scale(1.06); opacity: .13; }
.fd-subj-card > * { position: relative; z-index: 1; }
@media (max-width: 768px) {
    .fd-subj-card .fd-subj-ghost { font-size: 60px; right: -10px; bottom: -12px; }
}

/* "reduce the vertical space betwwen the top nav bar on mobile and the school
   card." The hero above it is display:none on mobile but is still a DOM
   child, so `> :first-child { margin-top: 0 }` was landing on the hidden hero
   and the school title kept its full 26px. Naming the title is the reliable
   way to reach it; the generic rule below tightens whichever section title
   comes first when a student has no school at all. */
@media (max-width: 768px) {
    .fd-student-home .fd-dash-section-title { margin-top: 18px; }
    .fd-student-home .fd-school-title { margin-top: 2px; }
    .fd-student-home .fd-school-block { margin-bottom: 14px; }
}

/* ===================================================================
   2026-09-26 (forty-seventh follow-up) - tabbed detail pop-ups
   ("redesign te my class details ... u can put each on a tab in that my
   class pop up", and the same shell for attendance and the report card)
   =================================================================== */
.fdct-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.fdct-avatar {
    width: 54px; height: 54px; flex: 0 0 auto; border-radius: 18px;
    display: inline-flex; align-items: center; justify-content: center; font-size: 21px; color: #fff;
    background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6));
}
.fdct-head-text { display: flex; flex-direction: column; min-width: 0; }
.fdct-head-text strong { font-family: 'Poppins', sans-serif; font-size: 18px; font-weight: 700; color: var(--text); }
.fdct-head-text small { font-size: 12.5px; color: var(--text-muted); }

/* Four figures across the top - the answers to "how big is this class" that
   otherwise take four taps to find. */
.fdct-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-bottom: 16px; }
.fdct-stats > div {
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    padding: 11px 4px; border-radius: 15px; background: var(--brand-25, #F7F6FD);
}
.fdct-stats b { font-family: 'Poppins', sans-serif; font-size: 19px; font-weight: 700; color: var(--brand-600, #5849D6); }
.fdct-stats small { font-size: 10.5px; font-weight: 600; color: var(--text-muted); text-align: center; }

.fdct-tabs { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin-bottom: 14px; padding-bottom: 2px; }
.fdct-tabs::-webkit-scrollbar { display: none; }
.fdct-tab {
    flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 14px; border-radius: 999px; border: none; cursor: pointer;
    font: inherit; font-size: 12.5px; font-weight: 700;
    background: var(--brand-25, #F7F6FD); color: var(--text-muted);
    transition: background .2s ease, color .2s ease;
}
.fdct-tab:hover { background: var(--brand-50, #F0EEFF); color: var(--brand-600, #5849D6); }
.fdct-tab.active { background: var(--brand-600, #5849D6); color: #fff; }
.fdct-tab i { font-size: 12px; }

.fdct-rows { display: flex; flex-direction: column; gap: 9px; }
.fdct-rows-tight { gap: 6px; }
.fdct-row {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 13px; border-radius: 16px; background: var(--surface, #fff);
    box-shadow: inset 0 0 0 1px var(--brand-100, #E3E0FB);
}
.fdct-row.is-me { background: var(--brand-25, #F7F6FD); box-shadow: inset 0 0 0 1.5px var(--brand-300, #A9A2F2); }
.fdct-row-icon {
    width: 40px; height: 40px; flex: 0 0 auto; border-radius: 13px;
    display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
    font-size: 15px; background: var(--brand-50, #F0EEFF); color: var(--brand-600, #5849D6);
}
.fdct-initials b { font-size: 13px; font-weight: 800; text-transform: uppercase; }
.fdct-date b { font-family: 'Poppins', sans-serif; font-size: 15px; font-weight: 800; line-height: 1; }
.fdct-date small { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; }
.fdct-row-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; gap: 1px; }
.fdct-row-text strong { font-size: 14px; font-weight: 700; color: var(--text); }
.fdct-row-text small { font-size: 12px; color: var(--text-muted); }
.fdct-pill {
    flex: 0 0 auto; padding: 4px 10px; border-radius: 999px;
    font-size: 11.5px; font-weight: 700;
    background: var(--brand-50, #F0EEFF); color: var(--brand-600, #5849D6);
}
.fdct-pill.ok { background: rgba(18, 184, 134, .14); color: #087F5B; }

@media (max-width: 480px) {
    .fdct-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .fdct-avatar { width: 46px; height: 46px; font-size: 18px; border-radius: 15px; }
    .fdct-head-text strong { font-size: 16px; }
}

/* The report-card pop-up's per-subject rows stack their breakdown under the
   summary line, and every panel ends with its download button. */
.fdct-row-stack { flex-direction: column; align-items: stretch; gap: 8px; }
.fdct-row-main { display: flex; align-items: center; gap: 12px; }
.fdct-breakdown summary {
    cursor: pointer; font-size: 12px; font-weight: 700; color: var(--brand-600, #5849D6);
    padding: 4px 0; list-style: none;
}
.fdct-breakdown summary::-webkit-details-marker { display: none; }
.fdct-breakdown summary::before { content: '\25B8'; display: inline-block; margin-right: 6px; transition: transform .2s ease; }
.fdct-breakdown[open] summary::before { transform: rotate(90deg); }
.fdct-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.fdct-actions .gce-btn { flex: 1 1 auto; justify-content: center; }
/* The headline figure on an attendance period panel. */
.fdct-att-rate {
    display: flex; align-items: center; gap: 14px; padding: 16px 18px; border-radius: 20px;
    background: linear-gradient(135deg, var(--brand-500, #6C63FF), var(--brand-600, #5849D6)); color: #fff;
}
.fdct-att-rate b { font-family: 'Poppins', sans-serif; font-size: 34px; font-weight: 800; line-height: 1; }
.fdct-att-rate small { font-size: 12px; opacity: .92; line-height: 1.45; }

/* 2026-09-27 (fifty-seventh follow-up): picking which classes a fee applies to.
   Replaces a multi-select that needed Ctrl/Cmd and hid the answer behind a
   scrollbar - every class is a visible tick, and "the whole school" is one
   control because it is the common case. */
.fd-class-pick { border: 1.5px solid var(--line, #E7E5F4); border-radius: 16px; padding: 12px; background: var(--surface, #fff); }
.fd-class-pick-all { display: flex; align-items: center; gap: 9px; padding: 9px 12px; border-radius: 12px; cursor: pointer;
    border: 1.5px solid var(--line, #E7E5F4); background: var(--surface, #fff); font-weight: 700; font-size: 13px; margin-bottom: 10px; }
.fd-class-pick-all.on { border-color: var(--brand-500, #6C63FF); background: var(--brand-50, #F0EEFF); color: var(--brand-600, #5849D6); }
.fd-class-pick-all input { accent-color: var(--brand-500, #6C63FF); }
.fd-class-pick-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.fd-class-chip { position: relative; display: inline-flex; align-items: center; padding: 8px 13px; border-radius: 999px; cursor: pointer;
    border: 1.5px solid var(--line, #E7E5F4); background: var(--surface, #fff); font-size: 12.5px; font-weight: 600; transition: all .15s ease; }
.fd-class-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.fd-class-chip.on { border-color: var(--brand-500, #6C63FF); background: var(--brand-500, #6C63FF); color: #fff; }
.fd-class-chip:hover { border-color: var(--brand-300, #A9A2F2); }

/* 2026-09-27 (fifty-seventh follow-up): collections per class on the finance
   overview - one box per class, each showing what came in, what is still out,
   and how far along it is. Tapping one opens who owes. */
.fd-classfee-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.fd-classfee { display: flex; flex-direction: column; gap: 8px; text-align: left; padding: 14px 15px; border-radius: 18px;
    border: 1.5px solid var(--line, #E7E5F4); background: var(--surface, #fff); cursor: pointer; font: inherit; color: var(--text);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.fd-classfee:hover { transform: translateY(-2px); border-color: var(--brand-400, #8F86EE); box-shadow: 0 10px 26px rgba(30, 22, 90, .10); }
.fd-classfee-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.fd-classfee-top strong { font-size: 14px; font-family: 'Poppins', sans-serif; }
.fd-classfee-bar { display: block; height: 7px; border-radius: 999px; background: #ECEAF7; overflow: hidden; }
.fd-classfee-bar i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #38D9A9, #12B886); }
.fd-classfee-figs { display: flex; gap: 14px; }
.fd-classfee-figs span { display: flex; flex-direction: column; }
.fd-classfee-figs small { font-size: 10.5px; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .3px; }
.fd-classfee-figs b { font-size: 15px; font-family: 'Poppins', sans-serif; }
.fd-classfee-figs b.owing { color: #E03131; }
.fd-classfee-foot { font-size: 11.5px; color: var(--text-muted); }
@media (max-width: 480px) {
    .fd-classfee-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
    .fd-classfee { padding: 12px; }
    .fd-classfee-figs { gap: 10px; }
    .fd-classfee-figs b { font-size: 13.5px; }
}

/* =====================================================================
   SOCIAL SIGN-IN  (2026-10-02 gate rebuild)
   "ADD SOCIAL LOGIN. LETS START WITH GOOGLE."

   Google's brand guidelines for "Sign in with Google" require their own
   mark on a white or branded button with adequate contrast and no
   recolouring of the G. This renders a neutral white button with the
   official colours on the glyph, which satisfies that and also happens to
   sit correctly against this app's light surface.
   ===================================================================== */
.fd-social { margin: 0 auto 20px; max-width: 420px; }
.fd-social-btn {
    display: flex; align-items: center; justify-content: center; gap: 11px;
    width: 100%; min-height: 52px; margin-bottom: 10px; padding: 0 18px;
    border: 1.5px solid var(--border, #E8E9F3); border-radius: 14px;
    background: #fff; color: var(--text, #1C1D2B);
    font-size: 15px; font-weight: 600; text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.fd-social-btn:hover { color: var(--text, #1C1D2B); border-color: #C9CBDE; box-shadow: 0 4px 14px rgba(28,29,43,.07); }
.fd-social-btn:active { transform: scale(.985); }
.fd-social-btn i { font-size: 18px; }
.fd-social-google i { color: #4285F4; }

/* The "or" rule. A real divider, not a bare word floating between blocks. */
.fd-social-or { position: relative; text-align: center; margin: 18px 0 4px; }
.fd-social-or::before {
    content: ''; position: absolute; left: 0; right: 0; top: 50%;
    height: 1px; background: var(--border, #E8E9F3);
}
.fd-social-or span {
    position: relative; padding: 0 12px; background: #fff;
    font-size: 12.5px; color: var(--text-muted, #6B6F8D);
}

/* =====================================================================
   READY TOOLS  (2026-10-02, teacher dashboard)
   "WHEN THIS TURTOR OPENS THE APP HE WANTS TO SEE READY TOOLS LIKE SET
    EXAM, SET GCE MOCK ... THOSE ARE QUICK ACCESS."

   Full-width rows rather than a grid of small squares: a row can carry a
   sentence saying what the tool does, and for someone who did not come
   here to learn a new system, "Subject -> topic -> lesson. We build and
   section the paper." is worth more than a prettier icon.
   ===================================================================== */
.fd-quick-tools {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin: 4px 0 18px;
}
.fd-quick-tile {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 14px 15px;
    border-radius: 16px;
    border: 1.5px solid var(--border, #E8E9F3);
    background: #fff;
    color: var(--text, #1C1D2B);
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.fd-quick-tile:hover {
    color: var(--text, #1C1D2B);
    border-color: var(--brand-300, #B9B0F0);
    box-shadow: 0 6px 18px rgba(28, 29, 43, .07);
}
.fd-quick-tile:active { transform: scale(.99); }

/* The first tool is the one most tutors open the app to use, so it reads
   as the primary action rather than as one of three equals. */
.fd-quick-tile.primary {
    border-color: transparent;
    background: linear-gradient(135deg, var(--brand-500, #6C5CE7), var(--brand-700, #4A3BC4));
    color: #fff;
    box-shadow: 0 8px 22px rgba(88, 73, 214, .26);
}
.fd-quick-tile.primary:hover { color: #fff; opacity: .97; }
.fd-quick-tile.primary small { color: rgba(255, 255, 255, .82); }
.fd-quick-tile.primary .fd-quick-ico { background: rgba(255, 255, 255, .18); color: #fff; }
.fd-quick-tile.primary .fd-quick-go { color: rgba(255, 255, 255, .7); }

.fd-quick-ico {
    flex: 0 0 auto;
    width: 42px; height: 42px;
    border-radius: 13px;
    display: grid; place-items: center;
    font-size: 17px;
    background: var(--brand-50, #F2F0FF);
    color: var(--brand-600, #5849D6);
}
.fd-quick-ico.mock { background: #FFF4E0; color: #B4690E; }
.fd-quick-ico.papers { background: #E6F6EC; color: #1A7F43; }

.fd-quick-txt { flex: 1 1 auto; min-width: 0; }
.fd-quick-txt strong {
    display: block;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.3;
}
.fd-quick-txt small {
    display: block;
    font-size: 12.5px;
    color: var(--text-muted, #6B6F8D);
    margin-top: 2px;
    line-height: 1.4;
}
.fd-quick-count {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 99px;
    background: var(--brand-50, #F2F0FF);
    color: var(--brand-700, #4A3BC4);
    font-size: 11.5px;
    font-weight: 700;
    vertical-align: middle;
}
.fd-quick-go { flex: 0 0 auto; font-size: 13px; color: var(--text-muted, #6B6F8D); }

@media (min-width: 760px) {
    .fd-quick-tools { flex-direction: row; }
    .fd-quick-tile { flex: 1 1 0; min-width: 0; }
}

/* --------------------------------------------------------- escrow disputes
   2026-10-03. Super Admin > Wallets > Disputes.

   A dispute card is a decision, so it is laid out like one: the amount and
   who it is owed to first, then what the person actually wrote, then the two
   buttons. The complaint is a blockquote rather than another grey row because
   it is the only part of this card that is somebody's own words, and an
   administrator about to move someone's money should be reading it rather
   than skimming past it. */
.fd-stat .num { display: block; }
.fd-stat small { display: block; font-size: 11px; color: var(--text-muted); margin-top: 2px; }

.fd-dispute {
    border: 1px solid var(--brand-100);
    border-radius: var(--r-md);
    padding: 16px 18px;
    margin-bottom: 14px;
    background: #fff;
}
.fd-dispute-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; margin-bottom: 10px;
}
.fd-dispute-head strong { display: block; font-size: 18px; font-weight: 700; }
.fd-dispute-head small { color: var(--text-muted); font-size: 11.5px; }
.fd-dispute-who {
    display: flex; flex-wrap: wrap; gap: 6px 20px;
    font-size: 13px; margin: 0 0 10px;
}
.fd-dispute-who i { color: var(--brand-600); margin-right: 5px; }
.fd-dispute-what { font-size: 13px; color: var(--text-muted); margin: 0 0 10px; }
.fd-dispute-reason {
    margin: 0 0 14px;
    padding: 11px 14px;
    border-left: 3px solid var(--brand-600);
    background: var(--brand-25);
    border-radius: 0 var(--r-sm, 8px) var(--r-sm, 8px) 0;
    font-size: 14px;
    line-height: 1.6;
}
.fd-dispute-reason cite {
    display: block; margin-top: 7px;
    font-size: 11.5px; font-style: normal; color: var(--text-muted);
}
.fd-dispute-act input[type="text"] {
    width: 100%; margin-bottom: 10px;
    padding: 9px 12px;
    border: 1px solid var(--brand-100); border-radius: var(--r-sm, 8px);
    font-size: 13px;
}
.fd-dispute-btns { display: flex; flex-wrap: wrap; gap: 8px; }

@media (max-width: 560px) {
    .fd-dispute-head { flex-direction: column; gap: 4px; }
    .fd-dispute-btns .btn { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------- escrow
   2026-10-03. The money box on a booking card.

   It is deliberately the heaviest thing on the card. In this market the
   question "where is my money right now" is the one that decides whether
   somebody uses the app a second time, so the answer is a framed panel with
   the figure in bold, not a line of hint text under a button. The fee is
   shown as its own subtracted line rather than folded into the total: a
   tutor who discovers the deduction only by comparing two numbers in their
   wallet has been surprised, and a surprised tutor tells other tutors. */
.fd-esc-box {
    border: 1px solid var(--fd-line, #e4e4ef);
    border-radius: 14px;
    padding: 12px 14px;
    margin: 10px 0 12px;
    background: #fbfbfe;
}
.fd-esc-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    font-size: 14px;
    line-height: 1.5;
    padding: 2px 0;
}
.fd-esc-line strong { font-weight: 700; font-size: 15px; }
.fd-esc-line.muted { color: #6b6b80; font-size: 13px; }
.fd-esc-line + .fd-esc-line { border-top: 1px dashed #ececf4; }
.fd-esc-note {
    margin: 9px 0 0;
    font-size: 12.5px;
    line-height: 1.55;
    color: #5a5a70;
}
.fd-esc-note i { color: #5849d6; margin-right: 4px; }

/* "Paid - held" needs to read as in-progress, not as finished. The done
   state is the only green one on the card. */
