/* ============================================================
   local_righttheme :: chrome.css
   Shared navigation / drawer / dropdown / modal chrome.

   SINGLE SOURCE OF TRUTH. Do not copy any rule from this file
   into a page. If a page needs a variation, override the token
   in :root, or add a page-scoped rule in that page's own <style>.

   Colour tokens are populated at runtime by
   \local_righttheme\theme::css_vars() from the homepage_admin
   row for $CFG->organization. The values below are fallbacks.

   Browser support: Chrome/Edge 90+, Firefox 90+, Safari 14.1+.
   Every vendor-specific guard in here is deliberate; the
   comment above it says which browser needs it.
   ============================================================ */

/* ============================================
   TOKENS
   ============================================ */
:root {
    /* Brand, overridden per-org from homepage_admin. */
    --theme-primary:      #000000;
    --theme-text:         #333333;
    --theme-heading:      #1a202c;
    --theme-button-bg:    #ffbf00;
    --theme-button-text:  #000000;

    /* Surfaces and lines. */
    --rt-nav-bg:          #ffffff;
    --rt-surface:         #f8fafc;
    --rt-surface-2:       #f1f5f9;
    --rt-surface-3:       #f0f2f5;
    --rt-border:          #e2e8f0;

    /* Text. Every value below is >= 4.5:1 on white. */
    --rt-ink:             #1a202c;  /* 15.3:1 */
    --rt-muted:           #64748b;  /*  4.8:1 */
    --rt-muted-2:         #6b7688;  /*  4.6:1 - was #94a3b8 at 2.6:1 */
    --rt-icon-idle:       #6b7280;  /*  4.8:1 - was #666 at 50% = 2.1:1 */
    /* Resting desktop nav icons only. Paler than --rt-icon-idle so the
       active page reads at a glance. Its own token because --rt-icon-idle
       also paints .empty-submessage, which is text and needs 4.5:1. */
    --rt-nav-idle:        #868e9e;  /*  3.3:1 on white, 5.0:1 against active */
    --rt-link:            #4f5fd0;  /*  5.4:1 - was #667eea at 3.7:1 */

    /* Accent. Decorative surfaces only, never text on white. */
    --rt-accent-a:        #667eea;
    --rt-accent-b:        #764ba2;
    --rt-accent-grad:     linear-gradient(135deg, var(--rt-accent-a), var(--rt-accent-b));

    /* Status. */
    --rt-danger:          #dc3545;
    --rt-badge:           #e41e3f;

    /* Nav metrics. */
    --rt-nav-h:           90px;
    --rt-nav-h-scrolled:  70px;

    /* Spacing scale. */
    --rt-space-1: 4px;
    --rt-space-2: 8px;
    --rt-space-3: 12px;
    --rt-space-4: 16px;
    --rt-space-5: 20px;
    --rt-space-6: 30px;

    /* Radius scale. */
    --rt-radius-sm:   6px;
    --rt-radius-md:   8px;
    --rt-radius-lg:   12px;
    --rt-radius-xl:   20px;
    --rt-radius-pill: 999px;

    /* Elevation. One scale, used everywhere. */
    --rt-shadow-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.10);
    --rt-shadow-2: 0 4px 6px -1px rgba(15, 23, 42, 0.08), 0 2px 4px -2px rgba(15, 23, 42, 0.06);
    --rt-shadow-3: 0 10px 20px -5px rgba(15, 23, 42, 0.12), 0 4px 8px -4px rgba(15, 23, 42, 0.08);
    --rt-shadow-4: 0 20px 40px -12px rgba(15, 23, 42, 0.25);

    /* Motion. */
    --rt-dur-fast: 120ms;
    --rt-dur-base: 220ms;
    --rt-dur-slow: 300ms;
    --rt-ease:     cubic-bezier(0.4, 0, 0.2, 1);

    /* Focus ring. 5.2:1 on white, 4.1:1 on black, so it stays
       visible whatever --theme-primary is set to. */
    --rt-focus:       #2563eb;
    --rt-focus-width: 3px;

    /* Minimum comfortable hit area (WCAG 2.5.5). */
    --rt-touch: 44px;

    /* The chrome's own typeface. Applied explicitly to every chrome root
       below, not left to inherit from body: pages set their own body font
       (courses.php uses Inter, courseinfo.php uses DM Sans) and the
       navigation, drawer and dropdowns were inheriting it, so the same
       chrome rendered in three different typefaces across the site. */
    --rt-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

    /* The active top-nav icon. Deliberately chrome-owned and NOT derived
       from a --theme-* token: this used to be var(--theme-primary), which
       an org could repaint, so the selected item was a different colour on
       the front page than everywhere else. Fixed here and pinned by
       chrome::lock_chrome(). 16.3:1 on the white nav bar, against 4.83:1
       for the inactive icons, so selected always reads as the strongest
       item in the bar. Point this at a --theme-* token again only if
       per-org control is wanted more than cross-page consistency. */
    --rt-nav-active: var(--rt-ink);

    /* Legacy aliases. Existing page CSS still references these. */
    --primary-color:      var(--theme-primary);
    --secondary-color:    #6c757d;
    --accent-color:       #20c997;
    --dark-color:         #212529;
    --notification-color: var(--rt-danger);
    --message-color:      #007bff;
}

/* The chrome does not inherit the page's typeface. Anything that is part
   of the shared chrome is listed here. */
.top-nav,
.mobile-drawer,
.mobile-drawer-overlay,
.notification-dropdown,
.message-dropdown,
.dropdown-content,
.login-modal,
.rt-skip-link {
    font-family: var(--rt-font);
    /* Same reason as the font: courseinfo.php sets body colour to its own
       --text-primary, which the chrome containers were inheriting. */
    color: var(--theme-text);
}

/* ============================================
   BASE
   ============================================ */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    /* iOS Safari inflates text when a phone is rotated to landscape
       unless this is pinned. Firefox and Edge need the unprefixed form. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    font-family: var(--rt-font);
    line-height: 1.6;
    color: var(--theme-text);
    background: #fff;
    /* iOS Safari paints a grey box over any tapped element. We supply
       our own :active states instead. */
    -webkit-tap-highlight-color: transparent;
}

/* ============================================
   FOCUS

   One ring for every interactive element in the chrome.
   :focus-visible keeps it off mouse clicks and on for keyboard.
   ============================================ */
.top-nav a:focus-visible,
.top-nav button:focus-visible,
.mobile-drawer a:focus-visible,
.mobile-drawer button:focus-visible,
.login-modal a:focus-visible,
.login-modal button:focus-visible,
.login-modal input:focus-visible,
.message-dropdown a:focus-visible,
.notification-dropdown a:focus-visible,
.dropdown-content a:focus-visible,
.message-item:focus-visible,
.notification-item:focus-visible,
.admin-edit-btn:focus-visible,
.rt-skip-link:focus-visible {
    outline: var(--rt-focus-width) solid var(--rt-focus);
    outline-offset: 2px;
    border-radius: var(--rt-radius-sm);
}

/* Safari 15.3 and earlier, and Firefox 84 and earlier, do not know
   :focus-visible. Give those keyboard users the ring on plain :focus
   rather than nothing. */
@supports not selector(:focus-visible) {
    .top-nav a:focus,
    .top-nav button:focus,
    .mobile-drawer a:focus,
    .mobile-drawer button:focus,
    .login-modal a:focus,
    .login-modal button:focus,
    .login-modal input:focus,
    .dropdown-content a:focus,
    .admin-edit-btn:focus {
        outline: var(--rt-focus-width) solid var(--rt-focus);
        outline-offset: 2px;
    }
}

/* Visible to screen readers, not to eyes. Used for the login form
   labels, which the compact modal shows as placeholders. */
.rt-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Skip link: first thing in the tab order, invisible until focused. */
.rt-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 10001;
    padding: var(--rt-space-3) var(--rt-space-5);
    background: var(--theme-primary);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 var(--rt-radius-md) 0;
}

.rt-skip-link:focus {
    left: 0;
}

/* ============================================
   NAVIGATION
   ============================================ */
.top-nav {
    background: var(--rt-nav-bg);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    height: var(--rt-nav-h);
    transition: height var(--rt-dur-slow) var(--rt-ease),
                box-shadow var(--rt-dur-slow) var(--rt-ease),
                border-color var(--rt-dur-slow) var(--rt-ease);
    border-bottom: 1px solid transparent;
}

.top-nav.scrolled {
    box-shadow: var(--rt-shadow-1);
    height: var(--rt-nav-h-scrolled);
    border-bottom-color: var(--rt-border);
}

.nav-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--rt-space-5);
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 100%;
}

.logo {
    display: flex;
    align-items: center;
    gap: var(--rt-space-2);
    text-decoration: none;
    color: var(--theme-primary);
    font-weight: 700;
    font-size: 1.5rem;
    flex-shrink: 0;
}

.logo img {
    height: 70px;
    width: auto;
    transition: height var(--rt-dur-slow) var(--rt-ease);
}

.top-nav.scrolled .logo img {
    height: 50px;
}

.main-nav {
    display: flex;
    list-style: none;
    gap: var(--rt-space-6);  /* 30px, matching every page that still overrides it */
    align-items: center;
}

.nav-item a {
    /* Was #666 at opacity .5, which computes to #b2b2b2 on white:
       2.1:1, well under the floor. Full opacity, muted colour. Icons are
       graphical objects, so the bar is WCAG 1.4.11's 3:1, not 4.5:1. */
    color: var(--rt-nav-idle);
    text-decoration: none;
    font-size: 25px;
    line-height: 1;
    transition: color var(--rt-dur-base) var(--rt-ease),
                background-color var(--rt-dur-base) var(--rt-ease);

    /* A 25px glyph is a 25px target. Pad it out to 44px. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--rt-touch);
    min-height: var(--rt-touch);
    border-radius: var(--rt-radius-md);
}

.nav-item a:hover {
    /* NOT --theme-primary. An org sets that from the homepage editor, and
       only index.php injects that CSS, so the hover tone came out yellow on
       the front page and dark everywhere else. Hover and active are chrome
       state, not brand. */
    color: var(--rt-nav-active);
    background: var(--rt-surface-2);
}

.nav-item a.active {
    color: var(--rt-nav-active);
}

.nav-item a:active {
    background: var(--rt-border);
}

.user-nav {
    display: flex;
    align-items: center;
    gap: var(--rt-space-3);
}

/* The nav is fixed, so content has to start below it. Driven by the same
   token as the nav height, so the two can never disagree: redefining
   --rt-nav-h in a media query moves both. A page that needs a different
   offset just declares its own .main-content rule after chrome.css. */
.main-content {
    margin-top: var(--rt-nav-h);
}

/* ============================================
   LANGUAGE SWITCH
   ============================================ */
.lang-switch {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--rt-border);
    border-radius: var(--rt-radius-pill);
    overflow: hidden;
    background: var(--rt-surface-2);
    flex-shrink: 0;
    /* Stops the VI/EN labels being selected on a long-press. */
    -webkit-user-select: none;
    user-select: none;
}

.lang-switch-btn {
    position: relative;
    background: none;
    border: none;
    padding: 6px 12px;
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--rt-muted);
    cursor: pointer;
    text-decoration: none;
    line-height: 1.5;
    transition: background-color var(--rt-dur-base) var(--rt-ease),
                color var(--rt-dur-base) var(--rt-ease);
}

/* The pill stays 28px tall for the sake of the nav, but the tappable
   area is expanded to 44px with a transparent overlay. Standard trick,
   works in every target browser. */
.lang-switch-btn::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    height: var(--rt-touch);
    transform: translateY(-50%);
}

.lang-switch-btn:hover {
    /* Same reason as .nav-item a:hover. */
    color: var(--rt-nav-active);
    background: var(--rt-border);
    text-decoration: none;
}

.lang-switch-btn.active {
    background: var(--theme-primary);
    color: #fff;
    cursor: default;
}

.lang-switch-btn.active:hover {
    color: #fff;
    background: var(--theme-primary);
}

/* The ring would be clipped by the pill's overflow:hidden. */
.lang-switch-btn:focus-visible {
    outline-offset: -3px;
}

/* ============================================
   HAMBURGER
   ============================================ */
.hamburger-btn {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--rt-space-3);
    min-width: var(--rt-touch);
    min-height: var(--rt-touch);
    align-items: center;
    justify-content: center;
    z-index: 1001;
    border-radius: var(--rt-radius-md);
    transition: background-color var(--rt-dur-base) var(--rt-ease);
}

.hamburger-btn:hover {
    background: var(--rt-surface-2);
}

.hamburger-icon {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 24px;
    height: 18px;
}

.hamburger-icon span {
    display: block;
    height: 2px;
    width: 100%;
    background-color: var(--rt-ink);
    border-radius: 2px;
    transition: transform var(--rt-dur-slow) var(--rt-ease),
                opacity var(--rt-dur-fast) var(--rt-ease);
}

.hamburger-btn.active .hamburger-icon span:nth-child(1) {
    transform: translateY(8px) rotate(45deg);
}

.hamburger-btn.active .hamburger-icon span:nth-child(2) {
    opacity: 0;
}

.hamburger-btn.active .hamburger-icon span:nth-child(3) {
    transform: translateY(-8px) rotate(-45deg);
}

/* ============================================
   MOBILE DRAWER
   ============================================ */
.mobile-drawer-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(15, 23, 42, 0.45);
    z-index: 998;
    opacity: 0;
    transition: opacity var(--rt-dur-slow) var(--rt-ease);
}

.mobile-drawer-overlay.show {
    display: block;
    opacity: 1;
}

.mobile-drawer {
    position: fixed;
    top: 0;
    right: -300px;
    width: 300px;
    height: 100%;
    background: #fff;
    z-index: 999;
    transition: right var(--rt-dur-slow) var(--rt-ease);
    box-shadow: -5px 0 20px rgba(15, 23, 42, 0.10);
    overflow-y: auto;
    /* Stops a flick at the end of the drawer scrolling the page behind it. */
    overscroll-behavior: contain;
    /* iOS Safari momentum scrolling inside the panel. */
    -webkit-overflow-scrolling: touch;
    /* Respect the notch and the home indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0);
}

.mobile-drawer.open {
    right: 0;
}

.drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--rt-space-5);
    border-bottom: 1px solid var(--rt-border);
    background: var(--rt-accent-grad);
    color: #fff;
    padding-top: calc(var(--rt-space-5) + env(safe-area-inset-top, 0px));
}

.drawer-header h3 {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 600;
}

.drawer-close {
    background: rgba(255, 255, 255, 0.2);
    border: none;
    color: #fff;
    font-size: 20px;
    cursor: pointer;
    min-width: var(--rt-touch);
    min-height: var(--rt-touch);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--rt-radius-md);
    transition: background-color var(--rt-dur-base) var(--rt-ease);
}

.drawer-close:hover {
    background: rgba(255, 255, 255, 0.32);
}

.drawer-close:focus-visible {
    outline-color: #fff;
}

.drawer-nav {
    list-style: none;
    padding: var(--rt-space-3) 0;
    margin: 0;
}

.drawer-nav-item {
    border-bottom: 1px solid var(--rt-surface-2);
}

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

.drawer-nav-item a {
    display: flex;
    align-items: center;
    gap: var(--rt-space-4);
    padding: var(--rt-space-4) 25px;
    min-height: var(--rt-touch);
    color: var(--theme-text);
    text-decoration: none;
    font-size: 1rem;
    font-weight: 500;
    transition: background-color var(--rt-dur-fast) var(--rt-ease),
                color var(--rt-dur-fast) var(--rt-ease);
}

.drawer-nav-item a:hover {
    background: var(--rt-surface);
    color: var(--rt-link);
}

.drawer-nav-item a:active {
    background: var(--rt-surface-2);
}

.drawer-nav-item a.active {
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.10), rgba(118, 75, 162, 0.10));
    color: var(--rt-link);
    box-shadow: inset 4px 0 0 var(--rt-accent-a);
}

.drawer-nav-item i {
    width: 24px;
    text-align: center;
    font-size: 1.1rem;
    color: var(--rt-icon-idle);
    flex-shrink: 0;
}

.drawer-nav-item a:hover i,
.drawer-nav-item a.active i {
    color: var(--rt-link);
}

.drawer-divider {
    height: 1px;
    background: var(--rt-border);
    margin: var(--rt-space-2) var(--rt-space-5);
}

.drawer-nav-item.logout a {
    color: var(--rt-danger);
}

.drawer-nav-item.logout a:hover {
    background: #fef2f2;
    color: var(--rt-danger);
}

.drawer-nav-item.logout i {
    color: var(--rt-danger);
}

.drawer-lang {
    padding: var(--rt-space-4) 25px var(--rt-space-2);
    list-style: none;
}

body.drawer-open {
    overflow: hidden;
}

/* ============================================
   NOTIFICATION + MESSAGE ICONS
   ============================================ */
.custom-notifications {
    display: flex;
    align-items: center;
    gap: var(--rt-space-3);
}

.notification-icon-container,
.message-icon-container {
    position: relative;
    display: flex;
}

.notification-btn,
.message-btn {
    background: var(--rt-surface-3);
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color var(--rt-dur-base) var(--rt-ease),
                color var(--rt-dur-base) var(--rt-ease);
    color: #5b6472;
    font-size: 18px;
    position: relative;
}

/* 40px circle, 44px target. */
.notification-btn::after,
.message-btn::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--rt-touch);
    height: var(--rt-touch);
    transform: translate(-50%, -50%);
}

.notification-btn:hover,
.message-btn:hover {
    background: #e4e6ea;
    color: var(--rt-ink);
}

.notification-btn:active,
.message-btn:active {
    background: var(--rt-border);
}

.notification-badge,
.message-badge {
    position: absolute;
    top: -2px;
    right: -2px;
    background: var(--rt-badge);
    color: #fff;
    border-radius: var(--rt-radius-pill);
    /* box-sizing matters here. With the default content-box, min-width 18px
       plus 10px padding plus 4px border made EVERY badge 32px wide, so a
       one-digit count rendered as a stretched pill instead of a circle and
       sat 10px further left over the icon than the same badge on a page
       that overrides this rule. border-box makes min-width the real
       minimum: 22px circle for one digit, growing only as digits need. */
    box-sizing: border-box;
    min-width: 22px;
    height: 22px;
    padding: 0 5px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    border: 2px solid #fff;
    /* Keeps the badge above the 44px hit overlay. */
    z-index: 1;
    pointer-events: none;
}

.notification-badge.hidden,
.message-badge.hidden {
    display: none;
}

/* ============================================
   DROPDOWNS
   ============================================ */
.message-dropdown,
.notification-dropdown {
    display: none;
    position: absolute;
    top: 50px;
    right: 0;
    background: #fff;
    width: 380px;
    max-height: 500px;
    border-radius: var(--rt-radius-lg);
    box-shadow: var(--rt-shadow-3);
    border: 1px solid var(--rt-border);
    z-index: 1002;
    overflow: hidden;
    animation: dropdownSlideIn var(--rt-dur-slow) var(--rt-ease);
}

.message-dropdown.show,
.notification-dropdown.show {
    display: block;
}

@keyframes dropdownSlideIn {
    from {
        opacity: 0;
        transform: translateY(-10px) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.dropdown-header {
    background: var(--rt-accent-grad);
    color: #fff;
    padding: var(--rt-space-4) var(--rt-space-5);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--rt-space-3);
}

.dropdown-header h4 {
    margin: 0;
    color: #fff;
    font-size: 1.1rem;
    font-weight: 600;
}

.message-count-badge,
.notification-count-badge {
    background: rgba(255, 255, 255, 0.22);
    padding: var(--rt-space-1) var(--rt-space-3);
    border-radius: var(--rt-radius-lg);
    font-size: 0.85rem;
    font-weight: 500;
    white-space: nowrap;
}

.message-list,
.notification-list {
    max-height: 320px;
    overflow-y: auto;
    overflow-x: hidden;
    /* Reaching the end of this list must not start scrolling the page. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;

    /* Firefox. */
    scrollbar-width: thin;
    scrollbar-color: var(--rt-border) transparent;
}

/* Chrome, Edge, Safari. Native scrollbars in a 380px panel are heavy
   on Windows in particular. */
.message-list::-webkit-scrollbar,
.notification-list::-webkit-scrollbar,
.mobile-drawer::-webkit-scrollbar {
    width: 8px;
}

.message-list::-webkit-scrollbar-track,
.notification-list::-webkit-scrollbar-track,
.mobile-drawer::-webkit-scrollbar-track {
    background: transparent;
}

.message-list::-webkit-scrollbar-thumb,
.notification-list::-webkit-scrollbar-thumb,
.mobile-drawer::-webkit-scrollbar-thumb {
    background: var(--rt-border);
    border-radius: var(--rt-radius-pill);
}

.message-list::-webkit-scrollbar-thumb:hover,
.notification-list::-webkit-scrollbar-thumb:hover,
.mobile-drawer::-webkit-scrollbar-thumb:hover {
    background: #cbd5e1;
}

.message-item,
.notification-item {
    display: flex;
    align-items: center;
    padding: var(--rt-space-3) var(--rt-space-5);
    min-height: var(--rt-touch);
    border-bottom: 1px solid var(--rt-surface-2);
    cursor: pointer;
    transition: background-color var(--rt-dur-fast) var(--rt-ease),
                box-shadow var(--rt-dur-fast) var(--rt-ease);
    background: #fff;
}

.message-item:hover,
.message-item:focus-visible {
    background: var(--rt-surface);
    box-shadow: inset 4px 0 0 var(--rt-accent-a);
}

.notification-item:hover,
.notification-item:focus-visible {
    background: var(--rt-surface);
    box-shadow: inset 4px 0 0 var(--rt-danger);
}

.message-item:last-child,
.notification-item:last-child {
    border-bottom: none;
}

.message-avatar,
.notification-avatar {
    margin-right: var(--rt-space-3);
    flex-shrink: 0;
}

.message-avatar img,
.notification-avatar img {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 2px solid var(--rt-border);
    object-fit: cover;
}

.userinitials {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--theme-primary);
    color: #fff;
}

.default-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--rt-accent-grad);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 16px;
    border: 2px solid var(--rt-border);
    flex-shrink: 0;
}

.notification-system-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, #dc3545, #c82333);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 16px;
    border: 2px solid var(--rt-border);
    flex-shrink: 0;
}

.message-content,
.notification-content {
    flex: 1;
    min-width: 0;
    margin-right: var(--rt-space-3);
}

.message-sender,
.notification-sender {
    font-weight: 600;
    font-size: 14px;
    color: var(--theme-heading);
    margin-bottom: var(--rt-space-1);
    display: flex;
    align-items: center;
    gap: var(--rt-space-2);
}

.notification-subject {
    font-weight: 600;
    font-size: 13px;
    color: #2d3748;
    margin-bottom: 2px;
}

.unread-count {
    background: var(--rt-badge);
    color: #fff;
    font-size: 10px;
    padding: 2px 6px;
    border-radius: var(--rt-radius-lg);
    font-weight: 600;
    flex-shrink: 0;
}

.message-preview,
.notification-preview {
    color: var(--rt-muted);
    font-size: 13px;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.message-time,
.notification-time {
    font-size: 12px;
    color: var(--rt-muted-2);
    font-weight: 500;
    flex-shrink: 0;
    text-align: right;
}

.dropdown-footer {
    padding: var(--rt-space-3) var(--rt-space-5);
    background: var(--rt-surface);
    border-top: 1px solid var(--rt-border);
    text-align: center;
}

.view-all-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--rt-touch);
    padding: 0 var(--rt-space-3);
    color: var(--rt-link);
    text-decoration: none;
    font-weight: 600;
    font-size: 14px;
    border-radius: var(--rt-radius-sm);
    transition: color var(--rt-dur-base) var(--rt-ease),
                background-color var(--rt-dur-base) var(--rt-ease);
}

.view-all-link:hover {
    color: #3f4cb8;
    background: var(--rt-surface-2);
    text-decoration: underline;
}

.dropdown-error {
    background: #fef2f2;
    color: #b91c1c;
    padding: var(--rt-space-4) var(--rt-space-5);
    border-left: 4px solid #b91c1c;
    margin: 0;
}

.dropdown-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--rt-space-2);
    padding: 40px var(--rt-space-5);
    color: var(--rt-muted);
    font-size: 0.9rem;
    font-weight: 500;
}

.dropdown-spinner {
    width: 20px;
    height: 20px;
    border: 2px solid var(--rt-border);
    border-top-color: var(--rt-accent-a);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    flex-shrink: 0;
}

/* ============================================
   EMPTY STATE
   ============================================ */
.empty-state {
    text-align: center;
    padding: 40px var(--rt-space-5);
    color: var(--rt-icon-idle);
}

.empty-icon {
    font-size: 3rem;
    margin-bottom: var(--rt-space-4);
    opacity: 0.45;
}

.empty-message {
    font-size: 1.1rem;
    font-weight: 600;
    color: #374151;
    margin-bottom: var(--rt-space-2);
}

.empty-submessage {
    font-size: 0.9rem;
    /* Was #9ca3af at 2.5:1. */
    color: var(--rt-icon-idle);
}

/* ============================================
   USER DROPDOWN
   ============================================ */
.user-dropdown {
    position: relative;
    display: inline-block;
}

.user-profile {
    display: flex;
    align-items: center;
    gap: var(--rt-space-2);
    padding: var(--rt-space-2) var(--rt-space-3);
    min-height: var(--rt-touch);
    border-radius: var(--rt-radius-pill);
    background: var(--rt-surface-2);
    text-decoration: none;
    color: var(--theme-text);
    transition: background-color var(--rt-dur-base) var(--rt-ease);
    cursor: pointer;
    border: none;
    font: inherit;
    font-size: 1rem;
}

.user-profile:hover {
    background: var(--rt-border);
    text-decoration: none;
    color: var(--theme-text);
}

.user-profile .fa-chevron-down {
    font-size: 0.75rem;
    color: var(--rt-muted);
    transition: transform var(--rt-dur-base) var(--rt-ease);
}

.user-profile[aria-expanded="true"] .fa-chevron-down {
    transform: rotate(180deg);
}

.user-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--theme-primary);
    color: #fff;
    display: flex;
    align-items: center !important;
    justify-content: center;
    font-weight: 600;
    font-size: 0.9rem;
    overflow: hidden;
    flex-shrink: 0;
}

.user-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.dropdown-content {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + var(--rt-space-2));
    background-color: #fff;
    min-width: 220px;
    box-shadow: var(--rt-shadow-3);
    border-radius: var(--rt-radius-md);
    z-index: 1001;
    border: 1px solid var(--rt-border);
    overflow: hidden;
    animation: dropdownSlideIn var(--rt-dur-base) var(--rt-ease);
}

.dropdown-content.show {
    display: block;
}

.dropdown-content a {
    color: var(--theme-text);
    padding: var(--rt-space-3) var(--rt-space-4);
    min-height: var(--rt-touch);
    display: flex;
    align-items: center;
    text-decoration: none;
    transition: background-color var(--rt-dur-fast) var(--rt-ease),
                color var(--rt-dur-fast) var(--rt-ease);
    border-bottom: 1px solid var(--rt-surface-2);
}

.dropdown-content a:last-child {
    border-bottom: none;
}

/* Was font-weight:bold + underline on hover, which reflows the menu
   by a pixel or two on every pass. A background change does not. */
.dropdown-content a:hover {
    background: var(--rt-surface);
    color: var(--rt-link);
    text-decoration: none;
}

.dropdown-content a:active {
    background: var(--rt-surface-2);
}

.login-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--rt-touch);
    text-decoration: none;
    font-weight: 600;
    padding: var(--rt-space-2) var(--rt-space-5);
    color: var(--theme-primary);
    border: 2px solid var(--theme-primary);
    border-radius: var(--rt-radius-sm);
    white-space: nowrap;
    transition: background-color var(--rt-dur-base) var(--rt-ease),
                color var(--rt-dur-base) var(--rt-ease);
}

.login-link:hover {
    background: var(--theme-primary);
    color: var(--theme-button-text);
    text-decoration: none;
}

/* ============================================
   LOGIN MODAL
   ============================================ */
.login-modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10000;
    animation: fadeIn var(--rt-dur-slow) var(--rt-ease);
}

.login-modal.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(15, 23, 42, 0.5);
    /* Safari, including every iOS browser, only honours the prefixed
       form. Without it the overlay is a flat wash on Safari. */
    -webkit-backdrop-filter: blur(5px);
    backdrop-filter: blur(5px);
}

.modal-content {
    position: relative;
    background: #fff;
    border-radius: var(--rt-radius-xl);
    box-shadow: var(--rt-shadow-4);
    width: 90%;
    max-width: 400px;
    margin: var(--rt-space-5);
    animation: slideUp var(--rt-dur-slow) var(--rt-ease);
    overflow: hidden;
    /* Keeps a short phone in landscape from clipping the form. */
    max-height: 90vh;
    max-height: 90dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Login modal. Minimal: no header band, no dividers. Every brand colour
   comes from the --theme-* tokens (homepage_admin); greys and spacing are
   chrome-owned. */
.modal-header {
    padding: 40px 36px 0;
}

.modal-header h3 {
    margin: 0 0 var(--rt-space-2);
    padding-right: var(--rt-touch);   /* clear of the close button */
    color: var(--rt-ink);
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.25;
}

.modal-subtitle {
    margin: 0;
    color: var(--rt-muted);
    font-size: 0.95rem;
    line-height: 1.5;
}

.modal-close {
    position: absolute;
    top: var(--rt-space-3);
    right: var(--rt-space-3);
    background: none;
    border: none;
    font-size: 18px;
    cursor: pointer;
    color: var(--rt-icon-idle);
    min-width: var(--rt-touch);
    min-height: var(--rt-touch);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: background-color var(--rt-dur-base) var(--rt-ease),
                color var(--rt-dur-base) var(--rt-ease);
}

.modal-close:hover {
    background: var(--rt-surface-2);
    color: var(--rt-ink);
}

.modal-body {
    padding: 28px 36px 32px;
}

.form-group {
    margin-bottom: var(--rt-space-5);
}

.login-modal .form-group label {
    display: block;
    margin-bottom: var(--rt-space-2);
    color: var(--rt-ink);
    font-size: 0.875rem;
    font-weight: 600;
}

/* Label left, "Forgot password?" right, input underneath. The link is
   last in the DOM so Tab order stays username, password, forgot. */
.form-group-password {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    column-gap: var(--rt-space-3);
}

.form-group-password label       { grid-column: 1; grid-row: 1; }
.form-group-password .link-forgot { grid-column: 2; grid-row: 1; }
.form-group-password .input-password { grid-column: 1 / -1; grid-row: 2; }

.form-group input[type="text"],
.form-group input[type="password"] {
    width: 100%;
    height: 48px;
    padding: 0 14px;
    border: 1.5px solid var(--rt-border);
    border-radius: var(--rt-radius-lg);
    /* 16px exactly. Anything smaller makes iOS Safari zoom the page
       when the field is focused, and it never zooms back out. */
    font-size: 16px;
    font-family: inherit;
    color: var(--rt-ink);
    background: #fff;
    transition: border-color var(--rt-dur-base) var(--rt-ease),
                box-shadow var(--rt-dur-base) var(--rt-ease);
    box-sizing: border-box;
    /* Safari otherwise applies its own inner shadow and radius. */
    -webkit-appearance: none;
    appearance: none;
}

.form-group input[type="text"]:hover,
.form-group input[type="password"]:hover {
    border-color: #cbd5e1;
}

/* One line, one colour: the org's primary. The 1px ring in the same
   colour thickens the border so focus still reads when an org picks a
   light primary. */
.form-group input[type="text"]:focus,
.form-group input[type="password"]:focus {
    outline: none;
    border-color: var(--theme-primary);
    box-shadow: 0 0 0 1px var(--theme-primary);
}

.input-password {
    position: relative;
}

.form-group .input-password input {
    padding-right: 52px;
}

.toggle-password {
    position: absolute;
    top: 2px;
    right: 2px;
    width: var(--rt-touch);
    height: var(--rt-touch);
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    border-radius: var(--rt-radius-md);
    color: var(--rt-icon-idle);
    font-size: 16px;
    cursor: pointer;
    transition: color var(--rt-dur-base) var(--rt-ease);
    -webkit-appearance: none;
    appearance: none;
}

.toggle-password:hover,
.toggle-password[aria-pressed="true"] {
    color: var(--theme-primary);
}

.btn-login {
    width: 100%;
    height: 48px;
    margin-top: var(--rt-space-2);
    padding: 0 var(--rt-space-4);
    background: var(--theme-button-bg);
    color: var(--theme-button-text);
    border: none;
    border-radius: var(--rt-radius-lg);
    font-size: 1rem;
    font-family: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: filter var(--rt-dur-base) var(--rt-ease);
    -webkit-appearance: none;
    appearance: none;
}

.btn-login:hover {
    filter: brightness(0.95);
}

.btn-login:active {
    filter: brightness(0.9);
}

.btn-login:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}

.link-forgot {
    color: var(--theme-primary);
    font-size: 0.875rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.link-forgot:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.form-links {
    margin: var(--rt-space-6) 0 0;
    text-align: center;
    color: var(--rt-muted);
    font-size: 0.95rem;
}

.link-register {
    color: var(--theme-primary);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: var(--theme-button-bg);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
    white-space: nowrap;
}

.link-register:hover {
    text-decoration-color: var(--theme-primary);
}

.btn-login.loading {
    position: relative;
    color: transparent;
}

.btn-login.loading::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 20px;
    height: 20px;
    margin: -10px 0 0 -10px;
    border: 2px solid rgba(0, 0, 0, 0.2);
    border-top-color: var(--theme-button-text);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

/* ============================================
   ADMIN FLOATING BUTTON
   ============================================ */
.admin-edit-btn {
    position: fixed;
    bottom: var(--rt-space-6);
    right: var(--rt-space-6);
    bottom: calc(var(--rt-space-6) + env(safe-area-inset-bottom, 0px));
    z-index: 9999;
    background: var(--rt-accent-grad);
    color: #fff;
    border: none;
    border-radius: var(--rt-radius-pill);
    padding: var(--rt-space-3) 25px;
    min-height: var(--rt-touch);
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    box-shadow: 0 8px 30px rgba(102, 126, 234, 0.40);
    transition: transform var(--rt-dur-base) var(--rt-ease),
                box-shadow var(--rt-dur-base) var(--rt-ease);
    display: flex;
    align-items: center;
    gap: var(--rt-space-2);
    text-decoration: none;
}

.admin-edit-btn:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 40px rgba(102, 126, 234, 0.50);
    color: #fff;
    text-decoration: none;
}

.admin-edit-btn:active {
    transform: translateY(-1px);
}

.admin-edit-btn i {
    font-size: 1.2rem;
}

/* ============================================
   ANIMATIONS
   ============================================ */
@keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes slideUp {
    from {
        opacity: 0;
        transform: translateY(30px) scale(0.96);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes spin {
    0%   { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* ============================================
   REDUCED MOTION

   WCAG 2.3.3. Animation is cut to a near-instant crossfade rather
   than removed, so state changes stay legible. The spinners keep
   turning, slowly, because a frozen spinner reads as a hang.
   ============================================ */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .dropdown-spinner,
    .btn-login.loading::after {
        animation-duration: 1.5s !important;
        animation-iteration-count: infinite !important;
    }

    .admin-edit-btn:hover,
    .btn-login:hover {
        transform: none;
    }
}

/* ============================================
   FORCED COLORS (Windows high contrast)
   ============================================ */
@media (forced-colors: active) {
    .top-nav {
        border-bottom: 1px solid CanvasText;
    }

    .notification-badge,
    .message-badge,
    .unread-count {
        border: 1px solid CanvasText;
    }

    .message-dropdown,
    .notification-dropdown,
    .dropdown-content,
    .modal-content {
        border: 1px solid CanvasText;
    }

    .hamburger-icon span {
        background-color: CanvasText;
    }
}

/* ============================================
   RESPONSIVE :: TABLET
   ============================================ */
@media (max-width: 768px) {
    /* Moves .top-nav and .main-content together. */
    :root {
        --rt-nav-h: 70px;
        --rt-nav-h-scrolled: 60px;
    }

    .hamburger-btn {
        display: inline-flex;
        order: 4;
    }

    .main-nav.navbar-nav {
        display: none;
    }

    .main-nav {
        gap: var(--rt-space-5);
    }

    .logo img {
        height: 50px;
    }

    .top-nav.scrolled .logo img {
        height: 40px;
    }

    .user-nav {
        gap: var(--rt-space-2);
    }

    .custom-notifications {
        gap: var(--rt-space-2);
    }

    .notification-btn,
    .message-btn {
        width: 36px;
        height: 36px;
        font-size: 16px;
    }

    .notification-badge,
    .message-badge {
        min-width: 16px;
        height: 16px;
        font-size: 10px;
    }

    .user-avatar {
        width: 30px;
        height: 30px;
        font-size: 0.8rem;
    }

    .user-profile {
        padding: var(--rt-space-1) var(--rt-space-2);
    }

    .user-profile .fa-chevron-down {
        display: none;
    }

    /* The drawer carries the language switch on small screens. */
    .user-nav .lang-switch {
        display: none;
    }

    .message-dropdown,
    .notification-dropdown {
        width: 95vw;
        max-width: 350px;
        right: -10px;
    }

    .message-item,
    .notification-item {
        padding: var(--rt-space-3) var(--rt-space-4);
    }

    .message-avatar,
    .notification-avatar {
        margin-right: var(--rt-space-2);
    }

    .message-avatar img,
    .notification-avatar img,
    .default-avatar,
    .notification-system-avatar {
        width: 36px;
        height: 36px;
    }

    .dropdown-content {
        right: 0;
        min-width: 280px;
    }

    .nav-container {
        padding: 0 var(--rt-space-4);
    }

    .modal-content {
        width: 95%;
        margin: var(--rt-space-3);
    }

    .modal-header {
        padding: 32px var(--rt-space-5) 0;
    }

    .modal-body {
        padding: var(--rt-space-5) var(--rt-space-5) 28px;
    }

    .admin-edit-btn {
        bottom: var(--rt-space-5);
        right: var(--rt-space-5);
        bottom: calc(var(--rt-space-5) + env(safe-area-inset-bottom, 0px));
        padding: var(--rt-space-3) var(--rt-space-5);
        font-size: 0.9rem;
    }

    body.drawer-open {
        overflow: hidden;
    }
}

/* ============================================
   RESPONSIVE :: PHONE
   ============================================ */
@media (max-width: 480px) {
    :root {
        --rt-nav-h: 65px;
        --rt-nav-h-scrolled: 55px;
    }

    .logo img {
        height: 45px;
    }

    .top-nav.scrolled .logo img {
        height: 35px;
    }

    .nav-container {
        padding: 0 var(--rt-space-4);
    }

    .user-nav {
        gap: var(--rt-space-2);
    }

    .custom-notifications {
        gap: var(--rt-space-1);
    }

    .notification-btn,
    .message-btn {
        width: 34px;
        height: 34px;
        font-size: 15px;
    }

    .notification-badge,
    .message-badge {
        min-width: 14px;
        height: 14px;
        font-size: 9px;
        top: -1px;
        right: -1px;
    }

    .user-avatar {
        width: 28px;
        height: 28px;
        font-size: 0.75rem;
    }

    .message-dropdown,
    .notification-dropdown {
        width: 100vw;
        max-width: none;
        right: -16px;
        border-radius: 0 0 var(--rt-radius-lg) var(--rt-radius-lg);
        /* vh on iOS Safari measures the viewport with the URL bar
           collapsed, so a 70vh panel overflows the visible area.
           dvh tracks the real height; the vh line is the fallback
           for Firefox 100 and earlier. */
        max-height: 70vh;
        max-height: 70dvh;
    }

    .message-list,
    .notification-list {
        max-height: 48vh;
        max-height: 48dvh;
    }

    .dropdown-header h4 {
        font-size: 1rem;
    }

    .message-avatar img,
    .notification-avatar img,
    .default-avatar,
    .notification-system-avatar {
        width: 32px;
        height: 32px;
    }

    .mobile-drawer {
        width: 280px;
        right: -280px;
    }

    .admin-edit-btn span {
        display: none;
    }

    .admin-edit-btn {
        padding: var(--rt-space-3);
        border-radius: 50%;
    }
}

/* ============================================
   PRINT

   Teachers print course and report pages. None of the chrome
   should appear on paper, and the fixed nav must not reserve
   90px at the top of every sheet.
   ============================================ */
@media print {
    .top-nav,
    .mobile-drawer,
    .mobile-drawer-overlay,
    .login-modal,
    .admin-edit-btn,
    .rt-skip-link,
    .message-dropdown,
    .notification-dropdown,
    .dropdown-content {
        display: none !important;
    }

    .main-content {
        margin-top: 0 !important;
    }
}
