@import url("/css/zn_dark.css?v=20261015b");
/* ============================================================
   ZABDESK RESPONSIVE v2 - Accessibility & Modern Enhancements
   ============================================================ */

/* CSS Custom Properties for consistent spacing and colors */
:root {
    --zn-spacing-xs: 0.25rem;   /* 4px */
    --zn-spacing-sm: 0.5rem;    /* 8px */
    --zn-spacing-md: 1rem;      /* 16px */
    --zn-spacing-lg: 1.5rem;    /* 24px */
    --zn-spacing-xl: 2rem;      /* 32px */
    --zn-spacing-2xl: 3rem;     /* 48px */

    --zn-color-primary: #0A2F5A;
    --zn-color-primary-light: #1E4D8C;
    --zn-color-accent: #F5A623;
    --zn-color-accent-dark: #D48A0A;
    --zn-color-text: #1E293B;
    --zn-color-text-light: #64748B;
    --zn-color-bg: #ffffff;
    --zn-color-bg-alt: #F8FAFC;
    --zn-color-border: #E2E8F0;
    --zn-color-focus: #F5A623;
    --zn-color-error: #DC2626;
    --zn-color-success: #16A34A;

    --zn-font-size-xs: 0.75rem;    /* 12px */
    --zn-font-size-sm: 0.875rem;   /* 14px */
    --zn-font-size-base: 1rem;     /* 16px */
    --zn-font-size-lg: 1.125rem;   /* 18px */
    --zn-font-size-xl: 1.25rem;    /* 20px */
    --zn-font-size-2xl: 1.5rem;    /* 24px */
    --zn-font-size-3xl: 2rem;      /* 32px */

    --zn-line-height-tight: 1.2;
    --zn-line-height-normal: 1.5;
    --zn-line-height-relaxed: 1.75;

    --zn-radius-sm: 0.25rem;   /* 4px */
    --zn-radius-md: 0.5rem;    /* 8px */
    --zn-radius-lg: 0.75rem;   /* 12px */
    --zn-radius-xl: 1rem;      /* 16px */
    --zn-radius-full: 9999px;

    --zn-shadow-sm: 0 1px 2px rgba(10, 47, 90, 0.05);
    --zn-shadow-md: 0 4px 6px -1px rgba(10, 47, 90, 0.1), 0 2px 4px -2px rgba(10, 47, 90, 0.1);
    --zn-shadow-lg: 0 10px 15px -3px rgba(10, 47, 90, 0.1), 0 4px 6px -4px rgba(10, 47, 90, 0.1);
    --zn-shadow-xl: 0 20px 25px -5px rgba(10, 47, 90, 0.1), 0 8px 10px -6px rgba(10, 47, 90, 0.1);

    --zn-transition-fast: 150ms ease;
    --zn-transition-normal: 250ms ease;
    --zn-transition-slow: 350ms ease;

    --zn-zindex-dropdown: 100;
    --zn-zindex-sticky: 100;
    --zn-zindex-modal: 1000;
    --zn-zindex-toast: 1100;
    --zn-zindex-tooltip: 1200;
}

/* Fluid typography using clamp() */
html {
    font-size: 100%; /* 16px base */
}
body {
    font-size: clamp(var(--zn-font-size-sm), 1.5vw + 0.5rem, var(--zn-font-size-base));
    line-height: var(--zn-line-height-normal);
}

/* v20260914d - CRITICAL mobile fix.
   style.css still carries the legacy desktop-only rule `body { min-width: 998px }`.
   min-width ALWAYS beats max-width, so the `html, body { max-width: 100vw }`
   safety net further down could not contain it: every page that loads style.css
   (which includes all 8 sub-application login pages - AdmitCard, GS, degreq,
   OutlinePortal, isThesisPortal, EDCInternshipPortal, TES, SMS) was forced to
   998px wide, producing ~620px of horizontal overflow on a 375px phone in
   Chromium, Firefox AND WebKit. responsive.css loads after style.css, so
   resetting min-width here wins. Desktop layouts are unaffected because
   min-width only ever mattered below 998px. */
html,
body {
    min-width: 0;
}

/* Minimum touch target size (44x44px) for all interactive elements */
button,
a,
input[type="button"],
input[type="submit"],
input[type="reset"],
select,
[role="button"],
[tabindex]:not([tabindex="-1"]) {
    min-height: 44px;
    min-width: 44px;
}
input[type="checkbox"],
input[type="radio"] {
    min-width: 18px;
    min-height: 18px;
}

/* Ensure touch targets on mobile */
@media (pointer: coarse) {
    button,
    a,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    [role="button"] {
        min-height: 48px;
        min-width: 48px;
    }
}

/* Focus visible for keyboard navigation */
:focus-visible {
    outline: 2px solid var(--zn-color-focus);
    outline-offset: 2px;
}

/* Skip link visible on focus */
.zn-skip-link:focus {
    position: fixed;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10000;
}

/* Focus styles for interactive elements */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--zn-color-focus);
    outline-offset: 2px;
}

/* Reduced motion support */
@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;
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    :root {
        --zn-color-border: #000;
        --zn-color-focus: #000;
    }
    a {
        text-decoration: underline;
    }
}

/* v20260917 (S79) - ZabDesk is a LIGHT-ONLY design.
   This block used to flip the design tokens to a dark palette whenever the
   phone's OS was in dark mode. Only the form controls actually consumed those
   tokens (zn_global.css reads --zn-color-bg / --zn-color-text), so the result
   was a near-black textbox sitting on an otherwise white page - measured live
   at 390x844 with colorScheme=dark: every field rendered rgb(15,23,42) while
   the page stayed #fff. That is the owner's "textbox colour automatically goes
   black from white".
   Two things are fixed here:
     1. the tokens are pinned to the light palette, so a dark-mode phone sees
        exactly the same page as a light-mode one;
     2. `color-scheme: light` is declared, which also stops the browser from
        auto-darkening NATIVE controls - the case where the control surface goes
        dark while a legacy `input { color:#1d1d1d }` keeps the text dark. */
:root {
    color-scheme: light;
}
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: light;
        --zn-color-bg: #ffffff;
        --zn-color-bg-alt: #F8FAFC;
        --zn-color-text: #1E293B;
        --zn-color-text-light: #64748B;
        --zn-color-border: #E2E8F0;
    }
}

/* Print styles */
@media print {
    .zn-topbar,
    .zn-skip-link,
    button,
    [role="button"],
    .zn-menu-btn,
    .zn-sysstatus,
    nav {
        display: none !important;
    }
    body {
        background: white !important;
        color: black !important;
    }
    a {
        text-decoration: underline;
    }
    a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 0.8em;
        color: #666;
    }
}
/* ==========================================================================
   ZabDesk GLOBAL RESPONSIVE + ACCESSIBILITY LAYER  v2.0  (2026-08-27)
   --------------------------------------------------------------------------
   Applied site-wide via the chrome includes (header.asp / subheader.asp /
   PageTitleHeader.asp / footer.inc / std_footer.inc / inc_menu\*.inc) and
   directly into every page that carries its own <head> or <html>.
   Purpose: usable on phones/tablets/desktop in all modern browsers with
   progressive fallbacks for older browsers and for no-JS.
   Design rule: the DESKTOP layout is UNCHANGED (rules are additive or
   scoped to small screens / specific components). Nothing here may alter
   wide-screen rendering.
   ========================================================================== */

html {
    -webkit-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* ---------- 1. Fluid media ---------- */
img { max-width: 100%; }
/* keep aspect ratio when a width-attributed image is shrunk by max-width */
img[width] { height: auto; }
iframe, video, embed, object { max-width: 100%; }

/* ---------- 2. Form controls never exceed the viewport ---------- */
input[type="text"], input[type="password"], input[type="email"],
input[type="tel"], input[type="number"], input[type="date"], input[type="search"],
select, textarea, button {
    max-width: 100%;
    box-sizing: border-box;
}
/* iOS Safari zooms into any input < 16px when focused; prevent the jolt */
@media (max-width: 767px) {
    input[type="text"], input[type="password"], input[type="email"],
    input[type="tel"], input[type="number"], input[type="date"], input[type="search"],
    select, textarea { font-size: 16px; }
}

/* ---------- 3. Wide-table scroll wrapper (added by js/responsive.js) ---------- */
.table-responsive-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* v20260924a (S160): this was `max-width: 100%`, which caps the wrapper at
       its PARENT - and on some pages the parent chain is itself wider than the
       viewport (an over-wide table propagates its min-content up through the
       shell's layout tables, while html/body are overflow-x: hidden).  The
       wrapper then ends up exactly as wide as the table, so
       `scrollWidth === clientWidth`, it is NOT a scroll region at all, and the
       right-hand part of the table is clipped by the viewport and completely
       unreachable.  Measured on /Faculty/FacStdRecapSheet.asp at 390x844:
       wrapper 656px wide, scrollable=false, and "View Recap Sheet" only 61px of
       its 142px inside the viewport - the owner's "button is not working on
       mobile".  Cap it at the viewport instead, so overflow-x:auto can scroll. */
    max-width: calc(100vw - 16px);
    box-sizing: border-box;
}
.table-responsive-wrap table { min-width: 640px; }
/* Card-layout tables (stacked label/value) already fit the viewport — never
   force them wide, even if legacy markup left them inside a scroll wrapper. */
.table-responsive-wrap table.no-table-wrap,
.table-responsive-wrap table.zpcr-table,
/* v20260924a (S160): a table that CONTAINS form controls is a form/layout
   table (label + control + buttons), not a data grid.  js/responsive.js adds
   this class.  The 640px floor above would otherwise stretch a ~350px form
   table to 640px; on a phone that centres its row of buttons at x~300..500 and
   pushes the later buttons past the right edge of the viewport. */
.table-responsive-wrap table.table-form-layout { min-width: 0; }
/* keep large embedded preview images scrollable instead of crushed */
.table-responsive-wrap img { max-width: none; }

/* ---------- 4. Mobile navigation ---------- */
/* v20260916i: this drawer is a fixed overlay that covers most of a phone
   screen (measured 380x720 on a 390x844 viewport).  It was filled with
   #1d1d1d / #2d2d2d, i.e. near-black, so opening it looked like "a black
   screen over the text and most of the area".  Use the app navy family
   instead so it reads as a menu drawer, not a black screen. */
.zab-menu-res {
    display: none;
    clear: both;
    width: 100%;
    background: #1b2b3f;
}
.zab-menu-res ul { margin: 0; padding: 0; list-style: none; }
.zab-menu-res li { border-bottom: 1px solid rgba(255,255,255,.07); }
.zab-menu-res li:nth-child(2n+1) { background: #2b3c50; }
.zab-menu-res a { display: block; padding: 12px 16px; color: #fff; text-decoration: none; }
.zab-menu-res a:hover, .zab-menu-res a:focus { background: #3a5274; }

/* Unicode hamburger replacement used when Images/menu-4-64.png is missing */
.zab-hamburger { font-size: 24px; color: #fff; padding: 0 6px; vertical-align: middle; }

/* ---------- 5. Accessibility ---------- */
/* skip link (injected by js/responsive.js) */
.zab-skip-link {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}
.zab-skip-link:focus, .zab-skip-link:active {
    left: 0;
    top: 0;
    width: auto;
    height: auto;
    overflow: visible;
    padding: 10px 16px;
    background: #111;
    color: #fff;
    font-size: 16px;
    z-index: 99999;
    position: absolute;
    outline: 3px solid #ffb400;
}
/* visible keyboard focus on interactive elements (progressive enhancement) */
a:focus, button:focus, input:focus, select:focus, textarea:focus, [tabindex]:focus {
    outline: 2px dotted #1a4d8f;
    outline-offset: 1px;
}

/* ---------- 6. Tablet (<= 1024px) ---------- */
@media (max-width: 1024px) {
    /* keep the top navigation reachable by horizontal scroll */
    #menu .navigation-bar,
    ul.navigation-bar {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
        max-width: 100%;
    }
    #menu .navigation-bar li,
    ul.navigation-bar li {
        display: inline-block;
        float: none;
    }
    /* show the hamburger */
    .responsive-menu {
        display: block !important;
        float: right;
        margin-right: 5px;
    }
}

/* ---------- 7. Phone (<= 767px) ---------- */
@media (max-width: 767px) {
    /* clamp horizontal page overflow ONLY when JS ran; with no JS the page
       may scroll horizontally as a last resort instead of clipping content */
    html.zab-js body { overflow-x: hidden; }
    /* stack the header bar instead of squeezing it */
    .header-top-bar { text-align: center; }
    .header-top-bar .Logo,
    .header-top-bar a.dp-top,
    .header-top-bar a.username-top,
    .header-top-bar a.signout-icon {
        display: inline-block;
        float: none;
    }
    /* left sidebar stacks above the main content; menu tree contained */
    #sidebar {
        width: 100% !important;
        float: none !important;
    }
    #sidebar .leftmenus,
    #sidebar #tblMenu,
    #sidebar table {
        max-height: 260px;
        overflow-y: auto;
    }
    /* jquery-ui dialogs must fit the screen */
    .ui-dialog {
        max-width: 92vw !important;
        left: 50% !important;
        margin-left: 0 !important;
        -webkit-transform: translateX(-50%);
        -ms-transform: translateX(-50%);
        transform: translateX(-50%);
    }
    .ui-dialog .ui-dialog-content {
        max-width: 100%;
        overflow-x: auto;
    }
    /* dialogs opened with fixed left offsets */
    .ui-widget-overlay { position: fixed !important; }
    h1, h2, h3, h4 { word-wrap: break-word; overflow-wrap: break-word; }
}

/* ---------- 8. Small phones (<= 480px) ---------- */
@media (max-width: 480px) {
    .header-top-bar .Logo img { max-width: 200px; }
    table, td, th { word-wrap: break-word; }
}

/* ---------- 9. Touch-friendly controls on coarse pointers ---------- */
@media (pointer: coarse) {
    input[type="submit"], input[type="button"], button, a.btn, .btn,
    .leftmenus, .zab-menu-res a {
        min-height: 40px;
        padding: 6px 12px;
    }
}

/* ---------- 10. Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
    * {
        -webkit-animation: none !important;
        animation: none !important;
        -webkit-transition: none !important;
        transition: none !important;
    }
}


/* ---------- 10b. Staff role shells on phone (MultipleRole / MultipleCourse) ----------
   style.css @media(max-width:790px) { #sidebar { display:none } } hid the left menu. */
@media (max-width: 790px) {
    #wrapper, #header, #page, #page-bgtop, #page-bgbtm, #footer {
        width: 100% !important;
        max-width: 100% !important;
        height: auto !important;
        background-image: none !important;
    }
    #page-bgbtm {
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
        -ms-flex-direction: column;
        flex-direction: column;
    }
    #sidebar {
        display: block !important;
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
        -webkit-box-ordinal-group: 2;
        -ms-flex-order: 1;
        order: 1;
        margin: 0 0 12px 0 !important;
    }
    #sidebar .leftmenus,
    #sidebar #tblMenu,
    #sidebar table {
        max-height: none !important;
        overflow: visible !important;
        width: 100% !important;
    }
    #content, #page #content, #main-content {
        display: block !important;
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
        margin: 0 !important;
        padding: 8px !important;
        -webkit-box-ordinal-group: 3;
        -ms-flex-order: 2;
        order: 2;
        /* Override zn_home.css flex-basis:280px and overflow-x:auto
           that clip the notice board to a 280px scrollable box on mobile */
        height: auto !important;
        max-height: none !important;
        overflow: visible !important;
        overflow-x: visible !important;
        flex: none !important;
        flex-basis: auto !important;
    }
    /* Override jQuery UI tabs inline style: notices.js sets
       min-height:500px; overflow:auto on #divTabsPanel — clip on mobile */
    #divTabsPanel {
        min-height: 0 !important;
        overflow: visible !important;
    }
    #content iframe, iframe#fraRightFrame {
        width: 100% !important;
        min-height: 55vh;
        border: 0;
    }
    #notification { display: none !important; }
}
/* ---------- 11. Print ---------- */
@media print {
    .no-print, #menu, .navigation-bar, .responsive-menu, .zab-menu-res,
    .zab-skip-link, #sidebar, .ui-dialog-buttonpane,
    .header-top-bar a.signout-icon { display: none !important; }
    .table-responsive-wrap { overflow: visible !important; }
    .table-responsive-wrap table { min-width: 0 !important; }
}

/* ============================================================
   ZABDESK text wordmark (guarantees correct brand spelling;
   replaces the old logofull.png placeholder artwork)
   ============================================================ */
.zn-wordmark {
    display: inline-block;
    font-family: Inter, Roboto, Poppins, "Segoe UI", Verdana, Geneva, Arial, sans-serif;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: 2px;
    line-height: 1;
    color: #0A2F5A;
    white-space: nowrap;
}
.zn-wm-accent { color: #F5A623; }
.zn-wordmark-sm { font-size: 18px; letter-spacing: 1.5px; }
.zn-wordmark-footer { color: #ffffff; font-size: 26px; }

/* Sidebar wordmark override: zn-brand.css sets ALL .zn-wordmark to white,
   which makes it invisible on the light sidebar background. Force dark blue. */
#sidebar .zn-wordmark,
.zn-login-logo .zn-wordmark {
    color: #0A2F5A !important;
}
/* v20260916d - the gold accent needs a darker tone on the LIGHT sidebar.
   #F5A623 on #F8FAFC is only 1.94:1 (fails even the 3:1 large-text floor).
   #b45309 is the same amber family already used by .zn-forgot on this
   sidebar, and gives ~6:1. The navy topbar keeps the original #F5A623. */
#sidebar .zn-wordmark .zn-wm-accent,
.zn-login-logo .zn-wordmark .zn-wm-accent {
    color: #b45309 !important;
}

/* ============================================================
   ZabDesk footer (rendered by footer.inc on every page)
   SZABIST dark blue (#0A2F5A), white text, gold (#F5A623) accents.
   3 columns: brand logos | navigation | contact info.
   Bottom row: centered copyright under a thin gold border.
   Stacks vertically + centered on mobile.
   ============================================================ */
#footer, .znf-root {
    background: #0A2F5A !important;
    border-top: 3px solid #072244 !important;
    width: 100%;
    box-sizing: border-box;
    color: #ffffff;
}
#footer .znf-inner,
.znf-root .znf-inner {
    max-width: 1400px;
    margin: 0 auto;
    padding: 30px 24px 26px;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
}
/* spacing via margins: works on ALL browsers (incl. iOS Safari <14.1, which ignores flex gap) */
#footer .znf-inner > *,
.znf-root .znf-inner > * { margin-bottom: 32px; }
#footer .znf-inner > *:last-child,
.znf-root .znf-inner > *:last-child { margin-bottom: 0; }
#footer .znf-col,
.znf-root .znf-col { flex: 1 1 0; min-width: 220px; }

/* column 1: SZABIST crest image + university name + tagline, stacked */
#footer .znf-col-brand,
.znf-root .znf-col-brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    max-width: 280px;
}
#footer .znf-col-brand > * + *,
.znf-root .znf-col-brand > * + * { margin-top: 10px; }
#footer .znf-crest,
.znf-root .znf-crest {
    display: inline-flex;
    align-items: center;
    flex: none;
    line-height: 0;
}
#footer .znf-crest img,
.znf-root .znf-crest img {
    display: block;
    height: auto;
    width: auto;
    max-height: 60px;
    max-width: 100%;
    padding: 6px 10px;
    background: #ffffff;
    border-radius: 4px;
}
#footer .znf-univ-name {
    margin: 0;
    color: #ffffff;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: .5px;
}
#footer .znf-tagline {
    margin: 0;
    color: #ffffff;
    opacity: .7;
    font-size: 12.5px;
    font-style: italic;
    letter-spacing: .3px;
}

/* column 2: navigation (mirrors the header menu) */
#footer .znf-heading {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: none;
    color: #F5A623;
}
#footer .znf-heading::after {
    content: "";
    display: block;
    width: 34px;
    height: 2px;
    margin-top: 6px;
    background: #F5A623;
    border-radius: 2px;
}
#footer .znf-col-nav {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}
#footer .znf-col-nav > * + * { margin-top: 6px; }
#footer .znf-col-nav a {
    color: #ffffff;
    opacity: .85;
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
    padding: 3px 0;
    line-height: 1.4;
    white-space: nowrap;
    min-height: 0;
    min-width: 0;
    transition: color .15s ease, opacity .15s ease;
}
#footer .znf-col-nav a:hover,
#footer .znf-col-nav a:focus { color: #F5A623; opacity: 1; text-decoration: underline; }

/* column 3: contact info with small icons */
#footer .znf-col-contact p {
    margin: 0 0 10px;
    font-size: 12.5px;
    line-height: 1.6;
    color: #ffffff;
    opacity: .9;
    letter-spacing: 0;
    text-transform: none;
    display: flex;
    align-items: flex-start;
}
#footer .znf-col-contact p .znf-ico { margin-right: 8px; }
#footer .znf-ico {
    width: 14px;
    height: 14px;
    flex: none;
    margin-top: 3px;
    stroke: #F5A623;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}
#footer .znf-col-contact a {
    color: #ffffff;
    text-decoration: underline;
    min-height: 0;
    min-width: 0;
    transition: color .15s ease;
}
#footer .znf-col-contact a:hover { color: #F5A623; text-decoration: none; }

/* bottom row: centered copyright under a thin gold border */
#footer .znf-bottom {
    border-top: 2px solid #F5A623;
    background: rgba(0, 0, 0, .15);
}
#footer .znf-copy {
    max-width: 1400px;
    margin: 0 auto;
    padding: 14px 24px;
    color: #ffffff;
    opacity: .8;
    font-size: 12px;
    text-align: center;
    letter-spacing: 0;
}
#footer .znf-copy a {
    color: #ffffff;
    opacity: .95;
    text-decoration: underline;
    transition: color .15s ease, opacity .15s ease;
}
#footer .znf-copy a:hover { color: #F5A623; opacity: 1; text-decoration: none; }

/* mobile: stack vertically, everything centered */
@media (max-width: 1024px) {
    #footer .znf-inner {
        flex-direction: column;
        align-items: center;
        text-align: center;
        padding: 24px 12px;
    }
    #footer .znf-inner > * { margin-bottom: 24px; }
    #footer .znf-inner > *:last-child { margin-bottom: 0; }
    #footer .znf-col { width: 100%; min-width: 0; }
    #footer .znf-col-brand { align-items: center; max-width: none; }
    #footer .znf-col-nav { align-items: center; }
    #footer .znf-col-nav a { padding: 6px 8px; min-height: 0; min-width: 0; }
    #footer .znf-col-contact p { margin-bottom: 6px; justify-content: center; text-align: left; }
}

@media print {
    #footer .znf-col-nav { display: none !important; }
}

/* ============================================================
   LEGACY BROWSER COMPATIBILITY LAYER v20260902a  (responsive.css)
   REVISED: previous version (v20260901a) unconditionally set
   body{font-size:14px} (killing the clamp() fluid typography in
   modern browsers too, since it appeared later in cascade order)
   and floated the footer columns in all browsers. Both are now
   scoped so modern browsers are untouched.
   ============================================================ */

/* ---------- 1. body font-size fallback: 14px FIRST, clamp() after ----------
   Browsers that cannot parse clamp() keep the 14px; browsers that
   can parse it override 14px with the fluid value. Order matters. */
body { font-size: 14px; font-size: clamp(0.875rem, 1.5vw + 0.5rem, 1rem); }

/* ---------- 2. Footer columns fallback ONLY for browsers without flexbox ---------- */
@supports not (display: flex) {
    #footer .znf-inner { *zoom: 1; }
    #footer .znf-inner:before, #footer .znf-inner:after { content: ""; display: table; }
    #footer .znf-inner:after { clear: both; }
    #footer .znf-col {
        float: left;
        width: 30%;
        margin: 0 1.5% 32px;
        box-sizing: border-box;
    }
    #footer .znf-col-nav { width: 30%; }
    #footer .znf-col-contact { width: 33%; }
}

/* ---------- 3. :focus-visible fallback ----------
   Old browsers ignore :focus-visible; this plain :focus set keeps
   keyboard focus visible. Modern browsers get both (harmless). */
a:focus, button:focus, input:focus, select:focus, textarea:focus, [tabindex]:focus {
    outline: 2px dotted #F5A623;
    outline-offset: 2px;
}

/* ---------- 4. IE8 structural guards (star hack - modern browsers never parse) ---------- */
.zab-menu-res { *display: none; }
.zn-wordmark { *font-size: 22px; }

/* ---------- 5. -webkit prefixes for old iOS/Android browsers ---------- */
.table-responsive-wrap { -webkit-overflow-scrolling: touch; }
.ui-dialog {
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
}
.zn-skip-link:focus {
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
}


/* ============================================================
   Option C header bar (2026-09-07) - deep navy band:
   SZABIST logo on white chip + ZABDESK wordmark (left),
   avatar + user name + Sign out aligned on one row (right).
   Applied via .zn-hdr-c on .header-top-bar in the two
   top-right includes (student_topright.inc / TopRight.inc).
   ============================================================ */
.zn-hdr-c {
    display: flex !important;
    align-items: center;
    flex-wrap: nowrap;
    gap: 14px;
    background: #0A2F5A !important;
    padding: 8px 16px !important;
    text-align: left !important;
    border-bottom: 3px solid #F5A623;
    box-sizing: border-box;
}
.zn-hdr-c a { color: #ffffff; border-bottom: none; margin-right: 0; font-size: 13.5px; }
.zn-hdr-c a:hover { background: none; }
.zn-hdr-c .Logo { float: none !important; margin: 0 !important; width: auto !important; }
.zn-hdr-c .zn-logochip {
    background: #ffffff;
    border-radius: 8px;
    padding: 4px 8px;
    display: inline-flex;
    align-items: center;
    line-height: 0;
}
.zn-hdr-c .Logo img,
.zn-hdr-c .zn-logochip img {
    height: 36px !important;
    width: auto !important;
    max-width: none !important;
    min-width: 0 !important;
    min-height: 0 !important;
    float: none !important;
    display: block !important;
    object-fit: contain !important;
    image-rendering: auto !important;
}
.zn-hdr-c a.zn-brand { text-decoration: none; }
.zn-hdr-c .zn-wordmark { color: #ffffff; font-size: 22px; }
.zn-hdr-c .zn-wordmark .zn-wm-accent { color: #F5A623; }
.zn-hdr-c .zn-spacer { flex: 1 1 auto; }
.zn-hdr-c a.dp-top {
    position: static;
    margin: 0;
    width: 36px;
    height: 36px;
    background: none;
    flex: none;
    display: inline-block;
}
.zn-hdr-c a.dp-top img.dp {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid #F5A623;
    display: block !important;
}
.zn-hdr-c a.username-top {
    background: none;
    color: #ffffff;
    font-weight: 600;
    padding: 4px 0 !important;
    margin: 0 !important;
    text-decoration: none;
    white-space: nowrap;
}
.zn-hdr-c a.username-top:hover { color: #F5A623; background: none !important; }
.zn-hdr-c a.signout-icon {
    display: inline-block !important;
    border: 1px solid rgba(255,255,255,.45);
    border-radius: 6px;
    padding: 6px 16px !important;
    margin: 0 !important;
    color: #ffffff;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.zn-hdr-c a.signout-icon:hover { background: rgba(255,255,255,.12) !important; }
@media (max-width: 640px) {
    .zn-hdr-c { gap: 10px; padding: 8px 12px !important; }
    .zn-hdr-c .Logo img,
    .zn-hdr-c .zn-logochip img { height: 32px !important; width: auto !important; }
    .zn-hdr-c .zn-wordmark { font-size: 17px; }
    .zn-hdr-c a.username-top { max-width: 42vw; overflow: hidden; text-overflow: ellipsis; }
    .zn-hdr-c a.signout-icon { padding: 5px 10px !important; }
}
@media (max-width: 480px) {
    /* v20260914e: Fix user cluster (photo + name + signout) to appear on RIGHT side.
       Previously .zn-spacer was flex:0 0 16px (fixed, not growing) which failed to
       push the user cluster right. Now uses flex:1 1 auto so it grows and pushes
       the user cluster to the right edge on all phone sizes. Also nowrap to keep
       everything on one row (elements shrink to fit). */
    .zn-hdr-c { gap: 8px !important; padding: 6px 10px !important; flex-wrap: nowrap !important; }
    .zn-hdr-c .zn-spacer { flex: 1 1 auto !important; min-width: 8px !important; }
    .zn-hdr-c .zn-wordmark { font-size: 14px !important; }
    .zn-hdr-c .zn-logochip { padding: 3px 6px !important; }
    .zn-hdr-c .Logo img,
    .zn-hdr-c .zn-logochip img { height: 28px !important; }
    .zn-hdr-c a.dp-top { width: 30px !important; height: 30px !important; }
    .zn-hdr-c a.dp-top img.dp { width: 30px !important; height: 30px !important; }
    .zn-hdr-c a.username-top { max-width: 28vw !important; font-size: 12.5px !important; }
    .zn-hdr-c a.signout-icon { padding: 4px 8px !important; font-size: 12px !important; }
}
@media print {
    .zn-hdr-c a { color: #ffffff !important; }
}

/* ============================================================
   CROSS-DEVICE RESPONSIVE LAYER v20260912a (responsive.css)
   --------------------------------------------------------------------------
   Breakpoints for:
   - Large LED displays (1600px, 1920px, 2560px, 3840px / 4K)
   - Very small phones (320px, 360px)
   - Landscape phones (568px-844px)
   - Small tablets / large phones (768px)
   Ensures the layout scales gracefully from 320px to 4K displays.
   All rules are ADDITIVE - desktop rendering is never reduced.
   ============================================================ */

/* ---------- Large desktop / LED display (>= 1600px) ---------- */
/* v20260915a: desktop max-width 1520px per responsive spec */
@media (min-width: 1600px) {
    #wrapper {
        max-width: 1520px;
    }
    #footer .znf-inner {
        max-width: 1520px;
    }
    #footer .znf-copy {
        max-width: 1520px;
    }
    .resource-box {
        width: 210px;
    }
    /* v20260916a: capped at 4 columns (was 5). Keep in sync with
       /css/notices.css — the notice board owns this grid, but this file
       loads later so its value would otherwise win. */
    .zn-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* ---------- Mid-size laptops / tablets landscape (1201px - 1400px) ----------
   Handles the awkward range where 8 nav items are too cramped but
   the viewport is still wide enough for desktop layout. */
@media (min-width: 1201px) and (max-width: 1400px) {
    .zn-topnav {
        gap: 12px !important;
    }
    .zn-topnav a {
        font-size: 12px !important;
    }
    .zn-wordmark {
        font-size: 18px !important;
    }
    .zn-lockup-univ img {
        height: 54px !important;
        max-width: 260px !important;
    }
    /* Sidebar wordmark - prevent overflow at mid-size */
    .zn-wordmark-sm {
        font-size: 16px !important;
        letter-spacing: 0 !important;
        white-space: nowrap;
        display: inline-block;
        max-width: 100%;
        overflow: visible;
    }
    /* Sidebar needs a bit more room at mid-size */
    #sidebar {
        min-width: 200px !important;
    }
    /* Reduce sidebar padding so wordmark fits */
    #sidebar .zn-login-logo {
        padding: 4px 6px 10px !important;
        text-align: center;
    }
}

/* ---------- Desktop layout: Notice grid tuning (1025px - 1599px) ---------- */
@media (min-width: 1025px) and (max-width: 1599px) {
    /* Notice grid: 3 columns at this range */
    /* v20260916a: 4 columns (was 3) so desktop always shows at least 4 notes */
    .zn-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
        gap: 20px 16px !important;
    }
}

/* v20260916a: 1025-1439px keeps 3 columns — at 1280px the feed is only ~860px
   wide, so 4 columns would squeeze each sticky note to ~203px. Declared after
   the range above with the same specificity and !important, so this wins in
   the overlap. */
@media (min-width: 1025px) and (max-width: 1439px) {
    .zn-feed {
        grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    }
}

/* ---------- Full HD / large LED (>= 1920px) ---------- */
/* v20260915a: cap at 1520px for desktop; ≥2200px expands to 2080px */
@media (min-width: 1920px) {
    #wrapper {
        max-width: 1520px;
    }
    #footer .znf-inner {
        max-width: 1520px;
    }
    #footer .znf-copy {
        max-width: 1520px;
    }
    /* Sidebar scale is owned by the grid in zn_global.css */
    #sidebar .zn-card {
        max-width: 400px;
        margin-left: auto;
        margin-right: auto;
    }
    .resource-box {
        width: 230px;
    }
    /* v20260916a: 4 columns (was 6) */
    .zn-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
    #sidebar input[type="text"],
    #sidebar input[type="password"],
    #sidebar select {
        font-size: 16px;
        padding: 10px !important;
    }
}

/* ---------- 2K / QHD displays (>= 2560px) ---------- */
/* v20260915a: cap at 2080px per large-screen spec */
@media (min-width: 2560px) {
    html {
        font-size: 112.5%;
    }
    #wrapper {
        max-width: 2080px;
    }
    #footer .znf-inner {
        max-width: 2080px;
    }
    #footer .znf-copy {
        max-width: 2080px;
    }
    .resource-box {
        width: 260px;
    }
    /* v20260916a: 4 columns (was 6) */
    .zn-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 30px 24px;
    }
    .zn-card {
        padding: 20px 20px 16px;
    }
    .zn-title {
        font-size: 19px;
    }
    .zn-body {
        font-size: 14.5px;
    }
}

/* ---------- 4K / Ultra HD displays (>= 3840px) ---------- */
/* v20260915a: cap at 2080px per large-screen spec */
@media (min-width: 3840px) {
    html {
        font-size: 125%;
    }
    #wrapper {
        max-width: 2080px;
    }
    #footer .znf-inner {
        max-width: 2080px;
    }
    #footer .znf-copy {
        max-width: 2080px;
    }
    /* v20260916a: 4 columns (was 7) */
    .zn-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 36px 28px;
    }
}

/* ---------- Very small phones (<= 360px: iPhone SE, small Android) ---------- */
@media (max-width: 360px) {
    body {
        font-size: 13px;
    }
    #wrapper, #page, #page-bgtop, #page-bgbtm {
        padding: 0 !important;
        margin: 0 !important;
    }
    #sidebar {
        margin: 0 !important;
        padding: 8px !important;
    }
    #sidebar .zn-card {
        padding: 10px !important;
    }
    #sidebar input[type="text"],
    #sidebar input[type="password"],
    #sidebar select {
        font-size: 16px;
        padding: 10px 8px !important;
    }
    .zn-wordmark {
        font-size: 16px;
        letter-spacing: 1px;
    }
    .zn-wordmark-sm {
        font-size: 14px;
    }
    .resource-box {
        width: 100%;
        float: none;
        margin: 10px 0;
    }
    .zn-chip {
        font-size: 12px;
        padding: 8px 12px;
    }
    .zn-title {
        font-size: 14px;
    }
    .zn-body {
        font-size: 11.5px;
    }
    .zn-action {
        padding: 8px 10px;
        font-size: 11px;
    }
    .zn-action-label {
        max-width: 100px;
    }
    #footer .znf-copy {
        font-size: 10px;
        padding: 10px 8px;
    }
    .zn-drawer {
        width: 100vw;
        max-width: 100vw;
    }
}

/* ---------- Extra small phones (<= 320px) ---------- */
@media (max-width: 320px) {
    body {
        font-size: 12px;
    }
    .zn-topbar-inner {
        padding: 0 4px;
    }
    .zn-wordmark {
        font-size: 14px;
    }
    .zn-lockup-univ img {
        max-width: 180px !important;
        height: 52px !important;
    }
    #sidebar .zn-btn-group input[type="submit"],
    #sidebar .zn-btn-group button {
        font-size: 13px;
        padding: 10px !important;
    }
}

/* ---------- Landscape phones (480px-844px) ---------- */
@media (min-width: 480px) and (max-width: 844px) and (orientation: landscape) {
    #page-bgbtm {
        display: flex;
        flex-direction: row;
    }
    #sidebar {
        width: 40% !important;
        max-width: 300px;
        float: left;
    }
    #content, #main-content {
        width: 60% !important;
        float: right;
    }
    .zn-feed {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ---------- Touch device enhancements (all touch screens) ---------- */
@media (hover: none) and (pointer: coarse) {
    .zn-card {
        transform: rotate(0deg) !important;
    }
    .zn-card:hover,
    .zn-card:focus-within {
        transform: translateY(-2px) !important;
    }
    .zn-card::before {
        top: -7px;
        width: 10px;
        height: 10px;
    }
    .zn-title-btn {
        -webkit-tap-highlight-color: rgba(21, 101, 192, 0.15);
    }
    .zn-more-btn {
        padding: 6px 8px;
        -webkit-tap-highlight-color: rgba(21, 101, 192, 0.15);
    }
    .zn-action {
        min-height: 44px;
        padding: 10px 14px;
    }
    .zn-chip {
        min-height: 44px;
        padding: 10px 16px;
    }
    .zn-pw-toggle {
        width: 44px;
        height: 44px;
    }
}

/* ---------- Orientation change handling ---------- */
@media (orientation: portrait) and (max-width: 600px) {
    .zn-feed {
        grid-template-columns: 1fr;
    }
}

/* ---------- Print color adjust ---------- */
@media print {
    * {
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }
}

/* ============================================================
   CROSS-BROWSER COMPATIBILITY ENHANCEMENTS v20260912a
   --------------------------------------------------------------------------
   Progressive enhancement fallbacks for:
   - IE 8/9/10/11 (conditional comments already handle JS)
   - Old Firefox (before flexbox gap support)
   - Old Safari/iOS (before grid support)
   - Old Chrome/Android (before flexbox)
   All rules use feature detection (@supports) or IE-only hacks.
   Modern browsers are NEVER affected by these rules.
   ============================================================ */

/* CSS Grid fallback for old browsers without grid support */
@supports not (display: grid) {
    .resource-box {
        display: inline-block;
        vertical-align: top;
        width: 30%;
        margin: 1.5%;
    }
    @media (max-width: 1024px) {
        .resource-box { width: 48%; }
    }
    @media (max-width: 600px) {
        .resource-box { width: 100%; margin: 8px 0; }
    }
}

/* Flexbox gap fallback for old browsers */
@supports not (gap: 8px) {
    #footer .znf-inner > * { margin-right: 24px; }
    #footer .znf-inner > *:last-child { margin-right: 0; }
}

/* object-fit fallback for IE/old browsers */
@supports not (object-fit: contain) {
    .zn-hdr-c .Logo img,
    .zn-hdr-c .zn-logochip img {
        width: auto !important;
        height: auto !important;
        max-width: 100%;
        max-height: 40px;
    }
    .zn-hdr-c a.dp-top img.dp {
        width: 36px !important;
        height: 36px !important;
    }
}

/* position: sticky fallback */
@supports not ((position: -webkit-sticky) or (position: sticky)) {
    #page-bgbtm > #sidebar > form {
        position: static;
    }
    .zn-topbar {
        position: absolute;
    }
}

/* viewport units fallback for very old browsers (IE8) */
@supports not (width: 100vw) {
    .ui-dialog {
        width: 90% !important;
    }
    .zn-drawer {
        width: 90%;
    }
}

/* -webkit- prefixes for old iOS Safari */
@media (-webkit-min-device-pixel-ratio: 0) {
    .zn-feed {
        -webkit-backface-visibility: hidden;
    }
    .zn-card {
        -webkit-backface-visibility: hidden;
    }
}

/* High DPI / Retina display optimization */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
    img {
        image-rendering: -webkit-optimize-contrast;
    }
    .zn-card {
        box-shadow: 0 8px 12px -4px rgba(0, 0, 0, 0.15);
    }
}

/* Dark mode color scheme preference */
@media (prefers-color-scheme: light) {
    :root {
        --zn-color-bg: #ffffff;
        --zn-color-bg-alt: #F8FAFC;
        --zn-color-text: #1E293B;
    }
}

/* Staff/role shells (TopRight.inc). Do not apply to Index (zn-topbar) or student. */
html.zn-staff-shell,
html.zn-staff-shell body {
    max-width: none;
    width: 100%;
    min-height: 100%;
}
html.zn-staff-shell body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
html.zn-staff-shell #page {
    flex: 1 1 auto;
}
html.zn-staff-shell #wrapper,
html.zn-staff-shell #header,
html.zn-staff-shell #page,
html.zn-staff-shell #page-bgtop,
html.zn-staff-shell #page-bgbtm {
    max-width: none !important;
    width: 100% !important;
    margin: 0 !important;
    background-image: none !important;
    height: auto !important;
    box-sizing: border-box;
}
html.zn-staff-shell #page-bgbtm {
    display: block !important;
    overflow: hidden;
    *zoom: 1;
}
html.zn-staff-shell #page-bgbtm:after {
    content: "";
    display: table;
    clear: both;
}
html.zn-staff-shell #page-bgbtm > div[style*="clear"] {
    display: none !important;
}
html.zn-staff-shell #sidebar,
html.zn-staff-shell #sidebar.sidebar {
    display: block !important;
    float: left !important;
    width: 23% !important;
    max-width: 280px !important;
    box-sizing: border-box;
}
html.zn-staff-shell #content,
html.zn-staff-shell #page #content {
    display: block !important;
    float: right !important;
    width: 76% !important;
    max-width: none !important;
    margin-left: 0 !important;
    padding: 12px 16px !important;
    box-sizing: border-box;
}
html.zn-staff-shell iframe[name="fraRightFrame"],
html.zn-staff-shell #fraRightFrame {
    width: 100% !important;
    min-height: 70vh;
    border: 0;
}
html.zn-staff-shell #footer {
    width: 100% !important;
    max-width: none !important;
    margin-top: 16px !important;
    clear: both;
    float: none !important;
    flex: 0 0 auto;
    order: 99;
    box-sizing: border-box;
}
html.zn-staff-shell #footer .znf-inner {
    padding: 20px 24px 12px !important;
}
html.zn-staff-shell #footer .znf-inner > * { margin-bottom: 12px; }

@media (max-width: 900px) {
    html.zn-staff-shell #page-bgbtm {
        display: block !important;
        -ms-flex-direction: unset !important;
        flex-direction: unset !important;
    }
    html.zn-staff-shell #sidebar,
    html.zn-staff-shell #sidebar.sidebar {
        display: block !important;
        float: left !important;
        width: 28% !important;
        max-width: 240px !important;
    }
    html.zn-staff-shell #content,
    html.zn-staff-shell #page #content {
        display: block !important;
        float: right !important;
        width: 70% !important;
        margin: 0 !important;
        padding: 8px !important;
    }
    html.zn-staff-shell #footer .znf-inner {
        padding: 16px 12px 8px !important;
    }
}

@media (max-width: 790px) {
    html.zn-staff-shell #page-bgbtm {
        display: block !important;
        flex-direction: unset !important;
    }
    html.zn-staff-shell #sidebar,
    html.zn-staff-shell #sidebar.sidebar {
        display: block !important;
        float: left !important;
        width: 32% !important;
        max-width: 220px !important;
    }
    html.zn-staff-shell #content,
    html.zn-staff-shell #page #content {
        float: right !important;
        width: 66% !important;
        margin: 0 !important;
    }
}

@media (min-width: 1600px) {
    html.zn-staff-shell #sidebar { max-width: 300px !important; }
}

/* ============================================================
   STAFF SHELL LAYOUT DEFENSE  v20260913c
   ----------------------------------------------------------------
   zn_global.css introduces a CSS grid layout for the public home
   page (body.zn-show-topbar) with selectors like
   #page-bgbtm > #sidebar that have higher specificity than the
   staff-shell rules above.  style.css has #page #content rules
   (specificity 0,2,0,0) that override the earlier staff-shell
   rules (0,1,1,1) even with !important, causing the content area
   to get margin:auto and display:inline-block which creates a
   large gap between sidebar and content.

   The selectors below use #page > #page-bgbtm > #content path
   (specificity 0,3,1,1 with html.zn-staff-shell) to decisively
   win the cascade battle on all staff/role-shell pages.
   ============================================================ */
html.zn-staff-shell #page-bgbtm,
html.zn-staff-shell #page > #page-bgbtm {
    display: block !important;
    grid-template-columns: none !important;
    flex-direction: unset !important;
}
html.zn-staff-shell #page-bgbtm > #sidebar,
html.zn-staff-shell #page-bgbtm > #sidebar.sidebar,
html.zn-staff-shell #page > #page-bgbtm > #sidebar,
html.zn-staff-shell #page > #page-bgbtm > #sidebar.sidebar {
    display: block !important;
    float: left !important;
    width: 23% !important;
    max-width: 280px !important;
    margin: 0 !important;
    box-sizing: border-box;
}
html.zn-staff-shell #page-bgbtm > #content,
html.zn-staff-shell #page-bgbtm > #main-content,
html.zn-staff-shell #page > #page-bgbtm > #content,
html.zn-staff-shell #page > #page-bgbtm > #main-content,
html.zn-staff-shell #page #content {
    display: block !important;
    float: right !important;
    width: 76% !important;
    max-width: none !important;
    margin: 0 !important;
    margin-left: 0 !important;
    margin-top: 0 !important;
    padding: 12px 16px !important;
    box-sizing: border-box;
}
html.zn-staff-shell #page-bgbtm > div[style*="clear"],
html.zn-staff-shell #page > #page-bgbtm > div[style*="clear"] {
    display: none !important;
}

/* Full-width content for staff pages that have NO sidebar
   (e.g. ZabdeskAdmin, MultipleRole, Student-). Pages opt in by
   adding class="full-width" to their #content div. */
html.zn-staff-shell #page #content.full-width,
html.zn-staff-shell #page-bgbtm > #content.full-width,
html.zn-staff-shell #page-bgbtm > #main-content.full-width,
html.zn-staff-shell #page > #page-bgbtm > #content.full-width,
html.zn-staff-shell #page > #page-bgbtm > #main-content.full-width {
    float: none !important;
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 16px !important;
}

/* Sidebar link readability: ensure text is white and legible on
   the dark sidebar background. style.css .leftmenu/.leftmenus
   rules set color but inline VBScript output and specificity from
   #sidebar a can override. These rules lock readability. */
html.zn-staff-shell #sidebar .leftmenu,
html.zn-staff-shell #sidebar .leftmenus,
html.zn-staff-shell #sidebar a.leftmenu,
html.zn-staff-shell #sidebar a.leftmenus,
html.zn-staff-shell #tblMenu .leftmenu,
html.zn-staff-shell #tblMenu .leftmenus,
html.zn-staff-shell #tblMenu a.leftmenu,
html.zn-staff-shell #tblMenu a.leftmenus {
    color: #ffffff !important;
    font-size: 13px !important;
    font-weight: 600 !important;
    text-decoration: none !important;
    display: block !important;
    padding: 8px 10px !important;
    border-bottom: 1px solid rgba(255,255,255,0.08) !important;
    line-height: 1.4 !important;
}
html.zn-staff-shell #sidebar .leftmenu:hover,
html.zn-staff-shell #sidebar .leftmenus:hover,
html.zn-staff-shell #tblMenu .leftmenu:hover,
html.zn-staff-shell #tblMenu .leftmenus:hover {
    background: #3a5274 !important;
    color: #ffffff !important;
}
html.zn-staff-shell #sidebar a:link,
html.zn-staff-shell #sidebar a:visited,
html.zn-staff-shell #sidebar a:active,
html.zn-staff-shell #tblMenu a:link,
html.zn-staff-shell #tblMenu a:visited,
html.zn-staff-shell #tblMenu a:active {
    color: #ffffff !important;
    text-decoration: none !important;
    border-bottom: none !important;
}
html.zn-staff-shell #sidebar a:hover,
html.zn-staff-shell #tblMenu a:hover {
    color: #F5A623 !important;
}
html.zn-staff-shell #sidebar h4.leftmenus,
html.zn-staff-shell #tblMenu h4.leftmenus {
    color: #9fb3cc !important;
    font-size: 12px !important;
    text-transform: uppercase !important;
    letter-spacing: 0.5px !important;
    padding: 6px 10px !important;
    font-weight: 700 !important;
}
/* Sidebar folder icons — hide spacer.gif, keep folder icons visible */
html.zn-staff-shell #sidebar img[src*="Spacer"],
html.zn-staff-shell #tblMenu img[src*="Spacer"] {
    display: none !important;
}
html.zn-staff-shell #sidebar img[src*="folder"],
html.zn-staff-shell #tblMenu img[src*="folder"] {
    width: 20px !important;
    margin: 0 4px 0 0 !important;
    vertical-align: middle !important;
}
html.zn-staff-shell #sidebar img[src*="file"],
html.zn-staff-shell #tblMenu img[src*="file"] {
    width: 16px !important;
    margin: 0 4px 0 0 !important;
    vertical-align: middle !important;
}
/* Sidebar container background */
html.zn-staff-shell #sidebar {
    background: #253342 !important;
    border-radius: 0 !important;
    overflow: hidden;
}
html.zn-staff-shell #tblMenu {
    width: 100% !important;
    border-collapse: collapse !important;
}
html.zn-staff-shell #tblMenu tbody tr td {
    background: #253342 !important;
    padding: 0 !important;
}
html.zn-staff-shell #tblMenu div {
    margin-top: 0 !important;
}

@media (max-width: 1024px) {
    html.zn-staff-shell #page-bgbtm,
    html.zn-staff-shell #page > #page-bgbtm {
        display: block !important;
        flex-direction: unset !important;
    }
    html.zn-staff-shell #page-bgbtm > #sidebar,
    html.zn-staff-shell #page-bgbtm > #sidebar.sidebar,
    html.zn-staff-shell #page > #page-bgbtm > #sidebar,
    html.zn-staff-shell #page > #page-bgbtm > #sidebar.sidebar {
        width: 32% !important;
        max-width: 240px !important;
    }
    html.zn-staff-shell #page-bgbtm > #content,
    html.zn-staff-shell #page-bgbtm > #main-content,
    html.zn-staff-shell #page > #page-bgbtm > #content,
    html.zn-staff-shell #page > #page-bgbtm > #main-content,
    html.zn-staff-shell #page #content {
        width: 66% !important;
    }
}

@media (max-width: 900px) {
    html.zn-staff-shell #page-bgbtm > #sidebar,
    html.zn-staff-shell #page-bgbtm > #sidebar.sidebar,
    html.zn-staff-shell #page > #page-bgbtm > #sidebar,
    html.zn-staff-shell #page > #page-bgbtm > #sidebar.sidebar {
        width: 28% !important;
        max-width: 240px !important;
    }
    html.zn-staff-shell #page-bgbtm > #content,
    html.zn-staff-shell #page-bgbtm > #main-content,
    html.zn-staff-shell #page > #page-bgbtm > #content,
    html.zn-staff-shell #page > #page-bgbtm > #main-content,
    html.zn-staff-shell #page #content {
        width: 70% !important;
    }
}

@media (max-width: 790px) {
    html.zn-staff-shell #page-bgbtm,
    html.zn-staff-shell #page > #page-bgbtm {
        /* flex column (NOT block) so the content can be ordered above the long
           left menu — see the order rules on #sidebar / #content below. */
        display: -webkit-box !important;
        display: -ms-flexbox !important;
        display: -webkit-flex !important;
        display: flex !important;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
        -ms-flex-direction: column;
        /* v20260915: `!important` is REQUIRED here. The earlier <=1024px block
           (and the <=900px block) declare `flex-direction: unset !important`,
           which resolves to the initial value `row`. Without !important the
           `unset` won the cascade, so the stacked mobile layout became a ROW
           flex container and the 100%-wide sidebar was squeezed to 0px —
           making the entire staff navigation invisible and unreachable on
           tablets/phones (768px, etc.). */
        /* v20260915b: `-webkit-flex-direction` is the 2011-spec WebKit property
           (old iOS Safari, stock Android 4.x). The `-webkit-box-*` pair above is
           the 2009 spec and does NOT cover those engines. */
        -webkit-flex-direction: column !important;
        flex-direction: column !important;
    }
    html.zn-staff-shell #page-bgbtm > #sidebar,
    html.zn-staff-shell #page-bgbtm > #sidebar.sidebar,
    html.zn-staff-shell #page > #page-bgbtm > #sidebar,
    html.zn-staff-shell #page > #page-bgbtm > #sidebar.sidebar {
        display: block !important;
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
        margin: 0 0 12px 0 !important;
        /* Menu AFTER the content: the staff accordion is often >1900px tall,
           so stacking it first buried the page the user just asked for. */
        -webkit-box-ordinal-group: 3;
        -ms-flex-order: 2;
        order: 2;
    }
    html.zn-staff-shell #page-bgbtm > #content,
    html.zn-staff-shell #page-bgbtm > #main-content,
    html.zn-staff-shell #page > #page-bgbtm > #content,
    html.zn-staff-shell #page > #page-bgbtm > #main-content,
    html.zn-staff-shell #page #content {
        display: block !important;
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
        margin: 0 !important;
        padding: 8px !important;
        /* Content FIRST so tapping a menu item shows the result immediately. */
        -webkit-box-ordinal-group: 2;
        -ms-flex-order: 1;
        order: 1;
    }
    html.zn-staff-shell #page-bgbtm > #content iframe,
    html.zn-staff-shell #page-bgbtm > #main-content iframe,
    html.zn-staff-shell #page-bgbtm > #content iframe#fraRightFrame,
    html.zn-staff-shell #page-bgbtm > #main-content iframe#fraRightFrame,
    html.zn-staff-shell #page > #page-bgbtm > #content iframe,
    html.zn-staff-shell #page > #page-bgbtm > #main-content iframe {
        width: 100% !important;
        min-height: 55vh;
        border: 0;
    }
}

/* =====================================================================
   LARGE SCREEN LAYOUT — v20260913n
   Targets: Large Multimedia Project, Large LED Screen, 4K monitors.
   Strategy: widen sidebar + content, increase font sizes, add padding,
   but cap content width at ~1400px for readability beyond 1920px.
   ===================================================================== */
@media (min-width: 1600px) {
    html { font-size: 112.5%; } /* 18px base */
    #sidebar { width: 240px !important; }
    #content { margin-left: 240px !important; width: calc(100% - 240px) !important; }
    .zn-hdr-c { padding: 10px 24px !important; }
    html.zn-staff-shell #page > #page-bgbtm > #content {
        padding: 20px 32px !important;
    }
    html.zn-staff-shell #page > #page-bgbtm > #content iframe {
        min-height: 75vh;
    }
}

@media (min-width: 1920px) {
    html { font-size: 125%; } /* 20px base */
    #sidebar { width: 260px !important; }
    #content { margin-left: 260px !important; width: calc(100% - 260px) !important; }
    .zn-hdr-c { padding: 12px 32px !important; }
    .zn-topbar-inner { max-width: 1600px; margin: 0 auto; }
    html.zn-staff-shell #page > #page-bgbtm > #content {
        padding: 24px 40px !important;
    }
    html.zn-staff-shell #page > #page-bgbtm > #content iframe {
        min-height: 80vh;
    }
}

@media (min-width: 2560px) {
    html { font-size: 150%; } /* 24px base */
    #sidebar { width: 280px !important; }
    #content { margin-left: 280px !important; width: calc(100% - 280px) !important; max-width: 1600px; }
    .zn-hdr-c { padding: 14px 48px !important; }
    .zn-topbar-inner { max-width: 1800px; margin: 0 auto; }
    html.zn-staff-shell #page > #page-bgbtm > #content {
        padding: 28px 48px !important;
    }
    html.zn-staff-shell #page > #page-bgbtm > #content iframe {
        min-height: 85vh;
    }
}

/* Smooth scrolling for in-page anchor navigation */
html { scroll-behavior: smooth; }

/* Ensure iframes never overflow their container on any screen */
#content iframe,
html.zn-staff-shell #content iframe {
    max-width: 100% !important;
    overflow: auto;
    display: block;           /* v20260914c: prevents inline baseline gap */
    vertical-align: top;      /* v20260914c: ensures content starts at top */
    margin: 0 auto;          /* v20260914c: center within parent */
}

/* v20260914c: Remove inline-block whitespace gap on #content that pushes
   iframe content to bottom (the "Faculty Home Page after sidebar" bug).
   Also neutralise the old height="100%" HTML attribute by giving the
   iframe a reasonable default until calcHeight() runs. */
#content .entry > p > iframe#fraRightFrame,
#content .entry iframe,
#content > .post iframe {
    display: block;
    vertical-align: top;
}

/* Prevent horizontal scroll on all pages */
html, body { overflow-x: hidden; max-width: 100vw; }

/* Improve form input touch targets on mobile */
@media (max-width: 900px) {
    input[type="text"],
    input[type="password"],
    input[type="email"],
    input[type="number"],
    input[type="tel"],
    input[type="date"],
    select,
    textarea {
        font-size: 16px !important; /* Prevents iOS zoom-on-focus */
        min-height: 44px;
    }
}

/* ============================================================
   TES /resetpwd.aspx Mobile Support — v20260913u
   The TES virtual directory is external; these rules improve
   the page when served from any domain. Targets:
   - #wrapper (form container)
   - input[type=submit] (Submit button)
   - .g-recaptcha (CAPTCHA widget)
   - #menu (navigation)
   ============================================================ */
#wrapper.content {
    margin: 12px auto !important;
    padding: 16px !important;
    max-width: 480px !important;
    box-sizing: border-box !important;
}
#wrapper.content h2 {
    font-size: 1.3em !important;
    text-align: center !important;
    margin: 8px 0 16px !important;
}
input[type="submit"], #cmdSubmit {
    cursor: pointer !important;
    -webkit-tap-highlight-color: transparent !important;
    touch-action: manipulation !important;
    font-size: 16px !important;
    font-weight: 600 !important;
}
input[type="submit"]:active, #cmdSubmit:active {
    transform: scale(0.98);
    transition: transform 0.1s;
}
.g-recaptcha, #g-recaptcha {
    transform: scale(0.95);
    transform-origin: 0 0;
    -webkit-transform: scale(0.95);
}
@media (max-width: 480px) {
    .g-recaptcha, #g-recaptcha {
        transform: scale(0.85);
        -webkit-transform: scale(0.85);
        transform-origin: 0 0;
    }
    /* v20260924a FIX (S160) — this rule used to be
           input[type="submit"], #cmdSubmit { width: 100% !important }
       with NO page scope.  /css/responsive.css is loaded by every page in the
       portal, so at <=480px it forced width:100% !important onto EVERY
       <input type="submit"> on EVERY page.  Any row holding more than one
       submit then overflowed: measured on /Faculty/FacStdRecapSheet.asp at
       390x844 the "View" and "View Recap Sheet" buttons each became 692px wide
       inside a 707px table cell, the row grew to 1457px and "View Recap Sheet"
       was laid out at x=781 - past the right edge of a 390px viewport, so it
       could not be tapped (the owner's "button is not working on mobile"
       report).  At 1440x900 the same two buttons measure 49px and 142px.
       Scope the rule to the container this block's own comment names
       (#wrapper.content) and to the one control it explicitly named
       (#cmdSubmit = FacTextReferenceBook.asp's "Next" button). */
    #wrapper.content input[type="submit"],
    #wrapper.content #cmdSubmit,
    input[type="submit"][name="cmdSubmit"],
    input#cmdSubmit {
        width: 100% !important;
        max-width: none !important;
    }
}
@media (max-width: 380px) {
    #wrapper.content { padding: 12px !important; }
    .g-recaptcha, #g-recaptcha {
        transform: scale(0.75);
        -webkit-transform: scale(0.75);
    }
}
/* Show friendly fallback if reCAPTCHA shows "Invalid domain" */
.g-recaptcha > div:has(> div:contains("Invalid domain"))::after,
#g-recaptcha:has(> div:contains("Invalid domain"))::after {
    content: "reCAPTCHA not configured for this domain. Please contact support.";
    display: block;
    color: #b91c1c;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 4px;
    padding: 8px;
    margin-top: 8px;
    font-size: 13px;
    text-align: center;
}

/* ============================================================
   v20260915c — COMPREHENSIVE RESPONSIVE ENHANCEMENTS
   --------------------------------------------------------------------------
   Adds:
   1. touch-action: pan-x on wide-table scroll wrappers (iOS/Android)
   2. ≥2200px large-screen breakpoint (2080px, 15-17px fonts)
   3. ≤900px tablet: tab wrapping + KPI 2-column grid
   4. ≤600px mobile: stack toolbars, full-width search, compact tables,
      stacked page headers, 40-44px touch targets
   5. IE9/10 CSS Grid KPI fallback to stacked layout
   All rules are ADDITIVE. Existing functionality is never reduced.
   ES5-safe: no modern CSS features that IE9/10 cannot parse.
   ============================================================ */

/* ---- 1. touch-action for smooth iOS/Android touch scrolling ---- */
.table-responsive-wrap {
    touch-action: pan-x;
    -webkit-overflow-scrolling: touch;
}

/* ---- 2. Large screens / LED walls (≥2200px): 2080px, 15-17px fonts ---- */
@media (min-width: 2200px) {
    html {
        font-size: 106.25%;   /* root 17px → body clamp stays 15-17px */
    }
    body {
        font-size: clamp(15px, 0.5vw + 12px, 17px);
        line-height: 1.55;
    }
    #wrapper,
    #footer .znf-inner,
    #footer .znf-copy {
        max-width: 2080px;
    }
    /* Scale up headings proportionally on very large screens */
    h1 { font-size: 2rem; }
    h2 { font-size: 1.75rem; }
    h3 { font-size: 1.5rem; }
    /* v20260916a: 4 columns at large width (was 6) */
    .zn-feed {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 28px 20px;
    }
    /* Sidebar card centre on wide screens */
    #sidebar .zn-card {
        max-width: 380px;
        margin-left: auto;
        margin-right: auto;
    }
    /* Staff shell: widen content area to use the space */
    html.zn-staff-shell #page-bgbtm > #content,
    html.zn-staff-shell #page > #page-bgbtm > #content {
        max-width: calc(2080px - 300px) !important;
    }
}

/* ---- 3. Tablet (≤900px): tabs wrap, KPI 2-column grid ---- */
@media (max-width: 900px) {
    /* Tab nav (and named custom tab containers): allow wrapping instead of overflowing.
       NOTE: do NOT use [class*="-tabs"] — that ALSO matches .ui-tabs-panel
       (which contains '-tabs-') and forces all 3 tab panels to display:flex,
       breaking jQuery UI tabs hiding of non-active panels. Use specific
       named selectors + .ui-tabs-nav (the nav, NOT the panels) only. */
    .zn-tabs, .awl-tabs, .csr-tabs, .dsl-tabs, .moc-tabs,
    .ui-tabs-nav, .nav-tabs {
        flex-wrap: wrap !important;
        white-space: normal !important;
        display: flex !important;
        display: -webkit-flex !important;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .zn-tabs > *, .awl-tabs > *, .csr-tabs > *, .dsl-tabs > *, .moc-tabs > *,
    .ui-tabs-nav li, .nav-tabs li {
        flex: 0 0 auto !important;
        -webkit-flex: 0 0 auto !important;
        white-space: nowrap !important;
    }
    /* Do NOT override display on .ui-tabs-panel — jQuery UI tabs sets inline
       style="display:none" on inactive panels. Using `!important` here would
       beat that inline style and show ALL 3 panels stacked (regression).
       Default UA display (block) is fine for the active panel; inactive
       panels stay hidden via the inline style jQuery UI sets. */
    /* Active tab panel must respect parent width — apply ONLY to the
       active panel via aria-hidden="false" so we don't widen hidden ones. */
    .ui-tabs-panel[aria-hidden="false"] {
        max-width: 100% !important;
        width: 100% !important;
        box-sizing: border-box;
        min-width: 0 !important;
    }
    /* KPI grid: 2-column grid on tablet */
    .zn-kpi-row {
        display: grid !important;
        grid-template-columns: repeat(2, 1fr) !important;
        gap: 10px !important;
    }
    /* Dashboard stat cards: 2-column grid on tablet */
    .stat-card, .metric-card, .dashboard-card,
    [class*="kpi"]:not([class*="-row"]):not([class*="-bar"]):not([class*="-label"]) {
        width: 48% !important;
        display: inline-block !important;
        vertical-align: top !important;
    }
}

/* ---- 4. Mobile (≤600px): stack toolbars, full-width search,
          compact tables, stacked page headers, 40px touch targets ---- */
@media (max-width: 600px) {
    /* 4a. Stack toolbars vertically.
       NOTE (v20260915): the container is deliberately `display: block`, so the
       `flex-direction: column` pair below is INERT. Stacking is actually done by
       the child rule further down (the `> *` selector setting display:block and
       width:100%), which needs no flex support at all and therefore also works
       on legacy engines.
       The flex-direction pair is kept only as a defensive fallback in case some
       other rule ever makes a toolbar a flex container.
       Verified empirically at 375px: children stack at y=4/32/60, each 100% wide.
       Do NOT "fix" this by switching the container to display:flex — that would
       make the layout depend on flex support and regress old engines. */
    .awl-toolbar, .csr-toolbar, .dsl-toolbar, .moc-toolbar,
    .zn-toolbar, .ibbc-toolbar, .tb-toolbar,
    [class*="-toolbar"] {
        display: block !important;
        text-align: left !important;
        -webkit-flex-direction: column !important;
        flex-direction: column !important;
    }
    .awl-toolbar > *, .csr-toolbar > *, .dsl-toolbar > *, .moc-toolbar > *,
    .zn-toolbar > *, .ibbc-toolbar > *, .tb-toolbar > *,
    [class*="-toolbar"] > * {
        display: block !important;
        width: 100% !important;
        max-width: 100% !important;
        margin: 4px 0 !important;
        text-align: left !important;
        float: none !important;
    }
    /* 4b. Full-width search inputs */
    input[type="search"],
    input[type="text"][name*="search" i],
    input[type="text"][id*="search" i],
    input[type="text"][id*="Search" i],
    .search-box, .search-box input,
    [class*="search"] input[type="text"] {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
    }
    /* 4c. Compact tables: reduce padding and font */
    table {
        font-size: 13px !important;
    }
    table th, table td {
        padding: 4px 6px !important;
        white-space: nowrap;
    }
    /* Allow text wrapping in table data cells when space is tight */
    table td[data-wrap], table td.wrappable {
        white-space: normal !important;
        word-break: break-word !important;
    }
    /* v20260924a (S160): form/layout tables and card tables are NOT data grids.
       The nowrap above gives them a min-content as wide as their longest
       sentence - measured 722px on /Faculty/FacStdRecapSheet.asp, where the
       one-line "Recapsheet and Attendance will be locked..." warning set the
       table's min-content.  A 722px table inside a 374px wrapper pushes its
       row of buttons to x~300..500, so the second button sits past the right
       edge of a phone viewport and cannot be tapped.  Same escape hatch as
       above, applied to the whole table.  js/responsive.js adds
       .table-form-layout; .no-table-wrap / .zpcr-table are pre-existing. */
    table.table-form-layout th, table.table-form-layout td,
    table.no-table-wrap th, table.no-table-wrap td,
    table.zpcr-table th, table.zpcr-table td {
        white-space: normal !important;
        word-break: break-word !important;
    }
    /* 4c-bis. v20260930a (S237): the rule directly above fixes the 722px
       min-content, but it OVER-CORRECTS on a label column.  `word-break:
       break-word` drops a label cell's min-content to a SINGLE GLYPH, so the
       browser hands the whole width to the control column and the label renders
       one character per line.  Measured on /Student/StdChangePassword.asp at
       412px: <th> "Old Password" 24px wide x 191px tall (1 char/line), "Retype
       new Password" 24x287, "Secret Question" 24x223; the form table's
       min-content was 409px inside a wrapper capped at calc(100vw - 16px) =
       396px, so the wrapper also carried a 13px scrollbar; and 17 elements were
       wider than the viewport.
       Fix: KEEP `white-space: normal` (so a long label wraps at its spaces) but
       restore NORMAL word breaking on TH, so the label's natural min-content
       ("Password") is respected and the column can no longer collapse.  `td`
       keeps break-word, for long unbreakable values in data cells. */
    table.table-form-layout th {
        white-space: normal !important;
        word-break: normal !important;
        overflow-wrap: normal !important;
    }
    /* A control must fill its cell rather than keep an intrinsic width.  The
       legacy markup uses size="30" (intrinsic ~276px) and one field carries an
       inline style="width:400px"; those set the table's min-content ABOVE the
       wrapper's cap, which is what produced the scrollbar.  min-width:0 is
       load-bearing: an input's default min-width is its intrinsic size. */
    table.table-form-layout td > input[type="text"],
    table.table-form-layout td > input[type="password"],
    table.table-form-layout td > select,
    table.table-form-layout td > textarea {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box !important;
    }
    table.table-form-layout input[type="submit"],
    table.table-form-layout input[type="reset"],
    table.table-form-layout input[type="button"] {
        max-width: 100% !important;
        box-sizing: border-box !important;
    }
    /* The student info row (PageTitleHeader.asp PageHeader) is SIX columns:
       Student | name-regno | Section | value | Semester | value.  It needs
       ~395px, so on a 360px phone it overflowed the viewport even after the
       rules above.  Turn it into three label/value lines instead of trying to
       squeeze six columns into a phone. */
    #StudentSemesterHeader { display: block !important; width: auto !important; max-width: 100% !important; }
    #StudentSemesterHeader tbody { display: block !important; }
    #StudentSemesterHeader tr { display: block !important; }
    #StudentSemesterHeader td {
        display: inline-block !important;
        vertical-align: top !important;
        box-sizing: border-box !important;
        width: 64% !important;
        white-space: normal !important;
        word-break: normal !important;
        overflow-wrap: normal !important;
    }
    /* odd cells are the labels (Student / Section / Semester) */
    #StudentSemesterHeader td:nth-child(odd) { width: 34% !important; }
    /* 4d. Stack page headers vertically */
    .page-header, .header-top-bar,
    h1.page-title, h2.page-title {
        text-align: center !important;
        display: block !important;
    }
    .page-header > *, .header-top-bar > * {
        display: block !important;
        float: none !important;
        text-align: center !important;
        width: 100% !important;
        margin: 4px 0 !important;
    }
    /* 4e. KPI: single column on mobile */
    .zn-kpi-row {
        grid-template-columns: 1fr !important;
    }
    .zn-kpi-row > * {
        width: 100% !important;
        margin: 4px 0 !important;
        display: block !important;
    }
    .stat-card, .metric-card, .dashboard-card {
        width: 100% !important;
        display: block !important;
    }
    /* 4f. Tabs: horizontal scroll on mobile (preserve usability).
       NOTE: do NOT use [class*="-tabs"] here — it ALSO matches .ui-tabs-nav
       and would re-introduce the S49 bug (broad selector beating more-specific
       .ui-tabs-nav rule and forcing flex-wrap:nowrap). Use explicit named
       selectors only. */
    .zn-tabs, .awl-tabs, .csr-tabs, .dsl-tabs, .moc-tabs,
    .ui-tabs-nav, .nav-tabs {
        flex-wrap: nowrap !important;
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
        touch-action: pan-x;
    }
    /* 4g. Buttons and tab links: 40px minimum touch target */
    .zn-tabs a, .awl-tabs a, .csr-tabs a, .dsl-tabs a, .moc-tabs a,
    .ui-tabs-nav a, .nav-tabs a,
    button, a.btn, input[type="button"], input[type="submit"],
    input[type="reset"], [role="button"],
    .zn-tab, .awl-tab, .csr-tab, .dsl-tab, .moc-tab {
        min-height: 40px;
        min-width: 40px;
        padding: 8px 14px;
        font-size: 14px;
        -webkit-tap-highlight-color: transparent;
        touch-action: manipulation;
    }
    /* 4h. Staff shell: stack sidebar + content on mobile.
       v20260915: was `display: block`, which OVERRODE the flex-column +
       order rules from the <=790px block (a later `!important` on the same
       selector wins). With display:block the `order` properties are ignored,
       so the ~1900px staff accordion was rendered FIRST and the page the
       user actually asked for was pushed ~2000px down the screen. Keep it a
       flex column so #content (order:1) stays above #sidebar (order:2). */
    html.zn-staff-shell #page-bgbtm,
    html.zn-staff-shell #page > #page-bgbtm {
        display: -webkit-box !important;
        display: -ms-flexbox !important;
        display: -webkit-flex !important;
        display: flex !important;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
        -ms-flex-direction: column;
        -webkit-flex-direction: column !important;
        flex-direction: column !important;
    }
    html.zn-staff-shell #sidebar,
    html.zn-staff-shell #sidebar.sidebar {
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
        margin-bottom: 8px !important;
    }
    html.zn-staff-shell #content,
    html.zn-staff-shell #page > #page-bgbtm > #content {
        width: 100% !important;
        float: none !important;
        margin: 0 !important;
        padding: 8px !important;
    }
    /* 4i. jQuery UI dialogs: full-width on mobile */
    /* v20261008a: cancel the inherited transform.
       .ui-dialog carries `transform: translateX(-50%)` from two places
       above: the unconditional "-webkit prefixes for old iOS/Android"
       block (~line 776) and the @media (max-width:767px) block, where it
       is the partner of `left:50%`. In that pair it centres the dialog,
       and on desktop jQuery UI compensates for it when it positions the
       dialog. THIS rule then overrode `left:50%` with `left:2vw
       !important` and left the -50% shift in place, so the shift was
       applied to a dialog whose left was no longer 50%: at 390px the
       dialog rendered at 2vw - 374.4/2 = -179px, i.e. half of it past the
       left edge. html/body set overflow-x:hidden (clip rule, ~line 1793),
       so the hidden half could not be scrolled into view - the dialog was
       simply stuck. css/zn_student.css:727 already cancels the transform
       this way for student pages; staff pages never load that file, which
       is why only the staff Upload DP dialog broke. */
    .ui-dialog {
        max-width: 96vw !important;
        width: 96vw !important;
        left: 2vw !important;
        -webkit-transform: none !important;
        transform: none !important;
    }
    .ui-dialog-content {
        max-height: 70vh !important;
        overflow-y: auto !important;
    }
}

/* ---- 5. IE9/10 CSS Grid KPI fallback ---- */
/* IE9: does not support @supports, display:grid, or flexbox.
   It will ignore all grid/flex properties and use the default
   display (block/inline). The rules below provide an explicit
   stacked fallback for KPI and feed layouts.
   IE10: supports -ms-flexbox but not grid. The -ms-high-contrast
   hack targets IE10 only (modern browsers also support it but
   the rules inside are harmless — they just set display:block
   and inline-block which are overridden by grid/flex in modern
   browsers that load later in the cascade). */

/* Fallback for browsers without grid support (IE9, old Safari) */
.zn-kpi-row {
    /* Default: block layout. Grid is applied by inline page CSS
       and by the media queries above only in grid-capable browsers. */
}
@supports not (display: grid) {
    .zn-kpi-row {
        display: block !important;
    }
    .zn-kpi-row > * {
        display: inline-block !important;
        vertical-align: top !important;
        width: 48% !important;
        margin: 1% !important;
    }
    @media (max-width: 600px) {
        .zn-kpi-row > * {
            width: 100% !important;
            margin: 4px 0 !important;
            display: block !important;
        }
    }
}

/* IE10-specific: -ms-high-contrast hack (IE10 supports it, IE9 does not) */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
    /* IE10: KPI falls back to inline-block 2-column */
    .zn-kpi-row {
        display: block !important;
    }
    .zn-kpi-row > * {
        display: inline-block !important;
        vertical-align: top !important;
        width: 48% !important;
        margin: 1% !important;
    }
    /* IE10: notice feed falls back to inline-block */
    .zn-feed {
        display: block !important;
    }
    .zn-feed > * {
        display: inline-block !important;
        vertical-align: top !important;
    }
    @media (max-width: 600px) {
        .zn-kpi-row > * {
            width: 100% !important;
            margin: 4px 0 !important;
            display: block !important;
        }
    }
}

/* ---- 6. IE9-only fallback (property hack: \9) ---- */
/* IE9 parses \9 in property values. Provide stacked KPI for IE9. */
.zn-kpi-row > * {
    width: 48%\9;       /* IE9 only */
    display: inline-block\9;
    vertical-align: top\9;
    margin: 1%\9;
}
@media screen and (max-width: 600px) {
    .zn-kpi-row > * {
        width: 100%\9;
        display: block\9;
        margin: 4px 0\9;
    }
}

/* ---- 7. v20260915b — jQuery UI tab panel overflow fix ----
   jQuery UI's tabs() widget sets parent display:flex and panels
   become flex items with min-width:auto (default), which ignores
   parent width and expands to fit content. On landing page this
   caused #dvAntiPlag to balloon to 8615px at 375px viewport because
   it contained long unbreakable words ("Dissertations", "Verification",
   "Research", "Turnitin"). Add min-width:0 + max-width:100% to all
   tab panels so they stay inside their parent, and add word-break
   to the Anti Plagiarism content (Times New Roman + text-align:justify
   + unbreakable compound words = intrinsic min-content >> viewport). */
.ui-tabs-panel,
.ui-widget-content.ui-tabs-panel {
    min-width: 0;            /* override flex item default (auto) */
    max-width: 100%;         /* never wider than parent */
    box-sizing: border-box;
    overflow-wrap: break-word;
}
.ui-tabs-panel img {
    max-width: 100% !important;
    height: auto !important;
}
#dvAntiPlag,
#dvAntiPlag p,
#dvAntiPlag ol,
#dvAntiPlag ul,
#dvAntiPlag li,
#dvAntiPlag b {
    overflow-wrap: break-word !important;
    word-wrap: break-word !important;
    word-break: break-word;       /* legacy IE/Edge fallback */
    -webkit-hyphens: auto;
    hyphens: auto;
}
@media (max-width: 900px) {
    /* NOTE: do NOT force display:block on .ui-tabs-panel — jQuery UI Tabs
       hides non-active panels with display:none, and overriding that breaks
       the tabs widget (all 3 panels show side-by-side). */
    /* Force the notice feed to a single column on mobile */
    .zn-feed {
        grid-template-columns: 1fr !important;
    }
    /* Constrain the *active* tab panel to parent width. Non-active panels
       are display:none by jQuery UI Tabs (inline style) so they don't need
       constraints.  IMPORTANT: do NOT use :not(.ui-tabs-hide) as a fallback —
       jQuery UI 1.10+ hides via inline style, NOT the .ui-tabs-hide class
       (that was ≤1.9). :not(.ui-tabs-hide) matches ALL panels in 1.10+ and
       display:block !important beats the inline display:none, re-breaking
       the tabs widget (all 3 panels visible stacked). */
    #divTabsPanel > .ui-tabs-panel[aria-hidden="false"] {
        max-width: 100% !important;
        width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box;
    }
    #dvHECResources .resource-box {
        /* resource-box already has width:100% from index.asp inline rule,
           just ensure it never exceeds viewport */
        max-width: calc(100vw - 40px) !important;
    }
    /* Sticky-note notice cards: full width on mobile */
    #dvNoticeBoard .zn-card {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box;
    }
    /* Title buttons (long uppercase titles like "FALL 2026 - ONLINE COURSE
       REGISTRATION") must wrap inside the card */
    #dvNoticeBoard .zn-title-btn {
        white-space: normal !important;
        word-break: break-word !important;
        line-height: 1.3 !important;
        text-align: left !important;
        height: auto !important;
        min-height: 44px;
    }
}

/* ============================================================
   v20260915e — Advanced search + export toolbar (search-enhance.js)
   ============================================================ */
.zn-search-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    padding: 10px 12px;
    margin: 12px 0;
    background: #F8FAFC;
    border: 1px solid #E2E8F0;
    border-radius: 8px;
    font-family: "Segoe UI", "Inter", Roboto, Helvetica, Arial, sans-serif;
}
.zn-search-bar .zn-search-input-wrap {
    flex: 1 1 220px;
    min-width: 0;
}
.zn-search-bar .zn-search-input {
    width: 100%;
    padding: 9px 12px;
    font-size: 14px;
    border: 1px solid #CBD5E1;
    border-radius: 6px;
    background: #fff;
    box-sizing: border-box;
    min-height: 40px;
    -webkit-appearance: none;
    appearance: none;
}
.zn-search-bar .zn-search-input:focus {
    outline: none;
    border-color: #0A2F5A;
    box-shadow: 0 0 0 3px rgba(10, 47, 90, 0.15);
}
.zn-search-bar .zn-search-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 2 1 300px;
}
.zn-search-bar .zn-search-filter {
    padding: 8px 10px;
    font-size: 13px;
    border: 1px solid #CBD5E1;
    border-radius: 6px;
    background: #fff;
    min-height: 40px;
    min-width: 110px;
    max-width: 200px;
    flex: 1 1 110px;
    box-sizing: border-box;
    -webkit-appearance: none;
    appearance: none;
}
.zn-search-bar .zn-search-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.zn-search-bar .zn-search-clear,
.zn-search-bar .zn-search-export {
    padding: 8px 14px;
    font-size: 13px;
    font-weight: 600;
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
    min-height: 40px;
    min-width: 80px;
    -webkit-appearance: none;
    appearance: none;
}
.zn-search-bar .zn-search-clear {
    background: #fff;
    border-color: #CBD5E1;
    color: #475569;
}
/* v20260917 (S79): light hover surface - pin the colour explicitly. It currently
   survives only because `.zn-search-bar .zn-search-clear` (0,2,0) outranks the
   generic `button:hover{color:#fff}` (0,1,1); declaring it here makes that
   independent of sheet order. */
.zn-search-bar .zn-search-clear:hover {
    background: #F1F5F9;
    border-color: #94A3B8;
    color: #475569;
}
.zn-search-bar .zn-search-export {
    background: #15803D;
    color: #fff;
    border-color: #116232;
}
.zn-search-bar .zn-search-export:hover {
    background: #116232;
}
.zn-search-bar .zn-search-count {
    font-size: 12px;
    color: #64748B;
    font-weight: 500;
    padding: 4px 8px;
    background: #fff;
    border: 1px solid #E2E8F0;
    border-radius: 4px;
    white-space: nowrap;
}

/* Stack the search toolbar vertically on mobile */
@media (max-width: 600px) {
    .zn-search-bar {
        flex-direction: column;
        align-items: stretch;
    }
    .zn-search-bar .zn-search-input-wrap,
    .zn-search-bar .zn-search-filters,
    .zn-search-bar .zn-search-actions {
        flex: 1 1 auto;
        width: 100%;
    }
    .zn-search-bar .zn-search-filter {
        max-width: 100%;
    }
    .zn-search-bar .zn-search-actions {
        justify-content: space-between;
    }
}

/* IE9/10: CSS Grid is unsupported; the toolbar uses flexbox so it works.
   IE9 lacks appearance:none and some gradient support but the layout holds. */
.lt-ie10 .zn-search-bar .zn-search-filter,
.lt-ie10 .zn-search-bar .zn-search-input {
    padding: 6px 8px;
}

/* ============================================================
   STANDALONE #tblMenu  v20260916i
   ----------------------------------------------------------------
   MenuProgram/default.asp emits <table id='tblMenu'> straight into
   the page body.  Its only consumer is
   Coordinator/CorOfferCourseMenu.asp, which has NO #sidebar wrapper.

   The sidebar rules above were written for #sidebar > #tblMenu:
     #tblMenu            { width: 100% !important }   -> 1487px wide
     #tblMenu tbody td   { background: #253342 }      -> dark band
   and default.asp's own markup ends every row with <BR>, which added
   a ~34px dead line per row.  Net result measured in the browser:
   a 1487 x 625px dark band covering most of the viewport, with
   #2d2d2d text on #253342 (1.07:1 - effectively invisible).

   Scope a compact panel look to the standalone table ONLY, via the
   .zn-menu-standalone class added to default.asp.  The shell sidebar
   (body > ... > #sidebar > #tblMenu, 280px, 0 <br>) is untouched.
   ============================================================ */
html.zn-staff-shell #tblMenu.zn-menu-standalone {
    width: auto !important;
    max-width: 360px !important;
    margin: 0 0 18px 0 !important;
    background: #253342 !important;
    color: #ffffff !important;
    border-collapse: collapse !important;
    border-radius: 6px;
    overflow: hidden;
}
html.zn-staff-shell #tblMenu.zn-menu-standalone td {
    padding: 6px 0 !important;
}
/* default.asp writes "<A class='leftmenu'>...</A><BR>" per row.  The
   link is display:block, so every <BR> is a redundant empty line. */
html.zn-staff-shell #tblMenu.zn-menu-standalone br {
    display: none !important;
}
html.zn-staff-shell #tblMenu.zn-menu-standalone a.leftmenu {
    padding: 9px 14px !important;
    border-bottom: 1px solid rgba(255,255,255,0.08) !important;
}
/* Sub-items are written with Document.gif, which the sidebar icon rule
   (img[src*="file"]) does not match - constrain it here. */
html.zn-staff-shell #tblMenu.zn-menu-standalone img[src*="Document"] {
    width: 16px !important;
    margin: 0 4px 0 0 !important;
    vertical-align: middle !important;
}
html.zn-staff-shell #tblMenu.zn-menu-standalone div[id^="txt_"] {
    margin-top: 0 !important;
    margin-bottom: 4px !important;
    padding-left: 8px !important;
}

/* ---------------------------------------------------------------------------
   S238e-mobile-header-fix (2026-09-30)
   Mobile header: the brand wordmark was rendered ON TOP of the university logo
   chip at <=600px.  `.header-top-bar` is a flex row, so the `> *` rule above
   (width:100% !important) makes every child request the full width and then
   shrink; `A.Logo` collapsed to its 44px touch-target minimum while its
   grandchild `SPAN.zn-logochip` stayed 100px and overflowed it by 56px.
   `flex:0 0 auto` keeps the logo at its true size.  That needs ~35px more than
   a 320px phone has, so the truncated username link is hidden -- it duplicates
   the avatar link, which is kept.
   Measured: chip/wordmark overlap 48x14px -> none; nothing past the viewport.
   --------------------------------------------------------------------------- */
@media (max-width: 600px) {
    .zn-hdr-c .Logo { flex: 0 0 auto !important; }
    .zn-hdr-c .username-top { display: none !important; }
}

/* ---------------------------------------------------------------------------
   S238e-prose-layout-fix (2026-09-30)
   A LAYOUT/PROSE table is not a data grid, but the mobile rule above
   (`table th, table td { white-space: nowrap }`) applied to every table, so a
   single-column layout table's min-content became the length of its longest
   sentence.  Measured on /FacultyHome.asp at 360x700: the content table
   rendered 1437px inside a 318px scroll wrapper -- the heading, the "New
   Feature" paragraph, the embedded schedule screenshot and the feedback line
   all ran off the right edge and needed a sideways swipe to read.
   js/responsive.js adds .table-prose-layout to a single-column table that
   carries block prose (a heading, <p> or <hr>) and no form controls.  Its
   cells wrap; its images fit the phone instead of forcing a scroll.
   Measured: content table 1437px -> 318px, wrapper scrollWidth 1437 -> 318.
   NOTE: the image cap is deliberately scoped to prose tables only -- data
   grids keep `max-width: none` (see the rule above) so their wide content
   stays scrollable.
   --------------------------------------------------------------------------- */
@media (max-width: 600px) {
    table.table-prose-layout th, table.table-prose-layout td {
        white-space: normal !important;
        word-break: break-word !important;
    }
    .table-responsive-wrap table.table-prose-layout { min-width: 0; }
    table.table-prose-layout img { max-width: 100% !important; height: auto !important; }
}

/* Contrast: the NEW flag inside the left menu is white ink on pure red (#ff0000),
   measured 4.00:1 at 12px -- below AA in BOTH colour schemes. #c62828 lifts the ink
   to 5.62:1 and still reads as a distinct component against the dark page (3.27:1).
   The flag is written as an inline style, so this needs !important to win. */
a.leftmenus span[style*="background-color: red" i],
a.leftmenus span[style*="background-color:red" i] {
    background-color: #c62828 !important;
    color: #ffffff !important;
}
