﻿/* =========================================
   Omnia WebUI - Shell Layout
   ========================================= */

:root {
    --shell-sidebar-width: 260px;
    --shell-border-color: #ddd;
    --shell-nav-bg: #f3f3f3;
    --shell-backdrop-bg: rgba(0, 0, 0, 0.4);
}

/* Base reset */
html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

/* App shell */
.app-shell {
    height: 100vh; /* important: header + body fits viewport */
    display: flex;
    flex-direction: column;
}

/* Header */
.app-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--shell-border-color);
    background-color: #ffffff;
}

.app-title {
    font-weight: 600;
    font-size: 1.1rem;
}

.app-header-right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Body: sidebar + content */
.app-body {
    flex: 1;
    min-height: 0; /* important: enables inner scrolling */
    display: flex;
    width: 100%;
    overflow: hidden; /* prevent page scroll; content scrolls inside app-content */
    position: relative;
}

/* Navigation wrapper around Syncfusion sidebar */
.app-nav {
    background-color: var(--shell-nav-bg);
    flex-shrink: 0;
}

    .app-nav .e-sidebar {
        background-color: var(--shell-nav-bg);
        border-right: 1px solid #dee2e6;
    }

/* Sidebar content wrap — relative-positioned anchor for the edge toggle. */
.app-nav-content {
    position: relative;
    height: 100%;
}

/* Edge-mounted "hide menu" chevron — sits on the menu's right border.
   Slim tab (14×42), tucked into the top-right corner of the sidebar.
   Height matches the LEVEL 1 YEAR-tile (the red SCHOOL banner) so the
   two visually line up. Pairs with .app-nav-expand-tab below. */
.app-nav-edge-toggle {
    position: absolute;
    top: 0;
    right: 0;
    width: 14px;
    height: 42px;
    padding: 0;
    margin: 0;
    background: #f1f1f1;
    border: 1px solid #d0d0d0;
    border-radius: 0;
    color: #555;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    z-index: 2;
    transition: background 0.12s;
}

.app-nav-edge-toggle:hover {
    background: #e5e5e5;
}

/* Re-expand tab — visible when the main menu is closed. Same slim
   shape as the edge-toggle but anchored to the left edge of the
   body. Small left offset so it doesn't sit flush against the
   viewport. Click re-opens the menu. Stacks with the schools-list
   re-expand tab via the :has() rule further down. */
.app-nav-expand-tab {
    position: absolute;
    top: 0;
    left: 4px;
    width: 14px;
    height: 42px;
    padding: 0;
    margin: 0;
    background: #f1f1f1;
    border: 1px solid #d0d0d0;
    border-radius: 0;
    color: #555;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    z-index: 3;
    transition: background 0.12s;
}

.app-nav-expand-tab:hover {
    background: #e5e5e5;
}

/* When the main menu is also collapsed, push the schools re-expand
   tab (.sidebar-toggle, owned per-page in dashboard / assessments /
   allocation pages) down so the two tabs stack instead of colliding
   at top-left of the content area. 46px = 42 tab + 4 gap. Uses
   :has() — supported in all currently-shipping evergreen browsers;
   on the off-chance the user is on an old build the tabs will
   overlap rather than break layout. */
.app-shell:has(.app-nav:not(.app-nav-open)) .sidebar-toggle {
    margin-top: 46px;
}

/* Optional legacy nav list styling (kept to avoid breaking anything) */
.app-nav-list {
    list-style: none;
    margin: 0;
    padding: 0.5rem;
}

    .app-nav-list li {
        margin-bottom: 0.25rem;
    }

    .app-nav-list a {
        display: block;
        padding: 0.5rem 0.75rem;
        border-radius: 0.375rem;
        text-decoration: none;
        color: #333;
        transition: background-color 0.2s;
    }

        .app-nav-list a:hover {
            background-color: #e0e0e0;
        }

        .app-nav-list a.active {
            font-weight: 600;
            background-color: #e3f2fd;
            color: #0d47a1;
        }

/* Content area
   v04: padding stripped here so admin pages can run flush to the viewport.
   Per-page slices (.dashboard-slice / .student-slice / .assessment-slice)
   own their own outer padding. Old default was 1rem, which stacked with
   .shell-frame-body's 1rem and the slice padding to ~36px on the left and
   ~64px on top before the actual content started. */
.app-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0; /* standard flexbox fix */
    min-height: 0;
    overflow-y: auto; /* scroll inside content only */
    position: relative;
    padding: 0;
}

/* Mobile toggle button */
.nav-toggle {
    background: none;
    border: none;
    font-size: 1.5rem;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    color: #333;
}

/* Simple utility card (kept to avoid breaking anything) */
.card {
    padding: 1rem;
    border-radius: 0.5rem;
    border: 1px solid #e0e0e0;
    background-color: #fff;
    margin-bottom: 1rem;
}

/* Touch targets */
button, .btn, .e-btn {
    min-height: 40px;
}

/* Backdrop (mobile overlay) */
.app-backdrop {
    position: fixed;
    inset: 0;
    background-color: var(--shell-backdrop-bg);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
    z-index: 999; /* below sidebar, above content */
}

    .app-backdrop.app-backdrop-visible {
        opacity: 1;
        pointer-events: auto;
    }

/* --- DESKTOP (Min-width: 769px) --- */
@media (min-width: 769px) {

    .app-backdrop {
        display: none !important;
    }

    .app-nav {
        height: 100%;
        position: relative;
        z-index: 1;
        width: 0;
        overflow: hidden;
        transition: width 0.3s ease;
    }

    .app-nav.app-nav-open {
        width: var(--shell-sidebar-width);
    }

        .app-nav .e-sidebar {
            position: absolute !important;
            top: 0;
            bottom: 0;
            left: 0;
            width: var(--shell-sidebar-width) !important;
            transform: none !important;
            z-index: auto !important;
            box-shadow: none !important;
        }
}

/* --- MOBILE (Max-width: 768px) --- */
@media (max-width: 768px) {

    .app-nav {
        width: 0;
        flex: 0 0 0;
    }

        .app-nav .e-sidebar {
            position: fixed !important;
            top: 0;
            bottom: 0;
            left: 0;
            width: var(--shell-sidebar-width) !important;
            z-index: 1000 !important; /* above backdrop */
            transform: translateX(-100%);
            transition: transform 0.3s ease-in-out;
            box-shadow: 4px 0 10px rgba(0,0,0,0.1);
        }

            .app-nav.app-nav-open .e-sidebar,
            .app-nav .e-sidebar.e-open {
                transform: translateX(0) !important;
            }
}


.P4 {
    --runner-font-scale: 0.8;
}

.P6 {
    --runner-font-scale: 1;
}

.P8 {
    --runner-font-scale: 1.2;
}
/* =========================================
   Stefan admin-search (shared) — 200 × 30, grey magnifying-glass on the left,
   14 px inset from top-right of its column box. Consistent across every admin page.
   ========================================= */
.admin-search {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: var(--admin-search-box-w);    /* 200px */
    height: var(--admin-search-box-h);   /* 30px */
    padding: 0 10px;
    background: #fff;
    border: 1px solid #d0d0d0;
    border-radius: 0;
    box-sizing: border-box;
    font-family: var(--admin-font);
    color: var(--admin-charcoal);
}

.admin-search .admin-search-icon {
    color: #888;
    font-size: 13px;
    flex: 0 0 auto;
}

.admin-search .admin-search-input {
    flex: 1 1 auto;
    min-width: 0;
    border: none;
    outline: none;
    background: transparent;
    font-family: var(--admin-font);
    font-size: 13px;
    color: var(--admin-charcoal);
    padding: 0;
}

.admin-search .admin-search-input::placeholder {
    color: #9a9a9a;
}

/* ── Shared box-toggle button (Phase P) ──
   The square 24 × 24 "+" / "−" frame used on every expand/collapse toggle
   across admin pages: class cards, panel headers, validation panels, etc.
   Use this class instead of copying the same rule into each scoped .razor.css.
   Pair with the stable two-span icon pattern so Font Awesome's SVG swap
   doesn't break Blazor's DOM diff — see the "Box open / close" section in
   .claude/skills/admin-ui-design/SKILL.md. */
.admin-box-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--admin-toggle-size);
    height: var(--admin-toggle-size);
    min-height: var(--admin-toggle-size);            /* beat global button min-height */
    padding: 0;
    border: 1px solid var(--admin-toggle-stroke);
    background: var(--admin-toggle-fill);
    color: var(--admin-toggle-symbol);                /* v04: darker grey, NOT charcoal */
    border-radius: 0;
    cursor: pointer;
    font-size: 12px;
    box-sizing: border-box;
    line-height: 1;
}

.admin-box-toggle:hover {
    background: var(--admin-surface-hover-strong);
}

/* Constrain the FA glyph inside the toggle so the SVG replacement doesn't
   balloon to fill the 24×24 frame. Matches the .alerts-chevron pattern. */
.admin-box-toggle > span > i,
.admin-box-toggle > span > svg {
    font-size: 12px;
    width: 12px;
    height: 12px;
}

/* ── Stefan v04 button hierarchy ──
   Three sizes (Button 1 / 2 / 3), all sharing Subheading-2 type and zero radius.
   Per-button fill colour and width is set on the host class — these classes
   only normalise the height, type, gap, and padding so that every admin
   button picks the same baseline. See SKILL.md → "Button hierarchy". */
.admin-btn-1, .admin-btn-2, .admin-btn-3 {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 12px;
    font-family: var(--admin-font);
    font-size: var(--admin-sub2-size);                 /* 12px */
    font-weight: var(--admin-sub2-weight);             /* 700 */
    letter-spacing: var(--admin-sub2-tracking);        /* 0.5px */
    text-transform: uppercase;
    border-radius: 0;
    box-sizing: border-box;
    cursor: pointer;
    white-space: nowrap;
}
.admin-btn-1 { height: var(--admin-btn1-h); min-height: var(--admin-btn1-h); }
.admin-btn-2 { height: var(--admin-btn2-h); min-height: var(--admin-btn2-h); }
.admin-btn-3 { height: var(--admin-btn3-h); min-height: var(--admin-btn3-h); }

/* ── Stefan v04 page-top row ──
   Shared layout for the first row of every admin page. School Header on the
   left (flex: 1), User Settings strip on the right (auto width), 30 px gap
   between them per Stefan's spec. Used by SchoolDashboard, AssessmentDashboard,
   StudentDashboard, and any future page that follows the same pattern. */
.page-top-row {
    display: flex;
    align-items: flex-start;
    gap: 30px;
    margin-bottom: 8px;
}

.page-top-row > .school-header-panel {
    flex: 1;
    min-width: 0;
    margin-bottom: 0;                            /* gap handled by .page-top-row */
    margin-right: 0;                             /* no absolute strip to dodge */
}

/* ── Inline schools-list collapse chevron ──
   Lives inside OrgUnitPickerPanel's HeaderActions slot (right-flushed beside
   "ALL SCHOOLS"). Same 24×24 charcoal chevron as the external .sidebar-toggle
   so the two render identically — only the layout differs (inline flex row
   vs grid column). Defined here so every admin page that hosts the picker
   inherits the same look without each scoped CSS having to redeclare it. */
.sidebar-toggle-inline {
    width: var(--admin-toggle-size);
    height: var(--admin-toggle-size);
    min-height: var(--admin-toggle-size);
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--admin-toggle-fill);
    border: 1px solid var(--admin-toggle-stroke);
    border-radius: 0;
    font-size: 12px;
    color: var(--admin-toggle-symbol);
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s;
}

.sidebar-toggle-inline:hover {
    background: var(--admin-surface-hover-strong);
}

/* ── Stacked-bar count label ──
   Tiny count rendered inside each segment of the class-card stacked bars
   (dashboard, assessments dashboard, students page). White text with a
   subtle shadow so it reads on top of any segment colour. Segments that
   are too narrow will clip the count via overflow:hidden on the seg. */
.bar-seg-count {
    color: var(--admin-white);
    font-size: 9px;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    pointer-events: none;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.45);
}

/* Shared loading-state for the student list panels (Students / Assessments
   / Dashboard pages). Parent flips `_isListLoading` true on a list reload;
   the panel passes it through to its root div so the grid dims and stops
   responding to clicks until the new data lands. Quick fade-in on opacity
   gives a subtle "something is happening" cue without a full spinner. */
.student-grid-panel.is-loading {
    opacity: 0.4;
    pointer-events: none;
    transition: opacity 0.12s ease-out;
    cursor: progress;
}
