/* GENERAL LAYOUT SETTINGS */

    * { font-family:  Arial, sans-serif ;         }
/* Headings are Arial. `*` above is specificity (0,0,0) -- the weakest selector there is -- so a
   heading takes any element- or class-level family ahead of it; this states the intent at (0,0,1)
   so a UA default or a bare third-party element rule cannot decide it.
   NOT !important, deliberately: the serif on the person view came from sr/srstyles.php dressing
   .stRegPublic in the school's registration branding, which is CORRECT on the public pages and
   is neutralised for internal screens at the foot of this file instead. Forcing it here would
   have stripped every school's chosen face off its own registration site. */
    h1, h2, h3, h4, h5, h6 { font-family: Arial, sans-serif; }

/* <editor-fold defaultstate="collapsed" desc="Design Tokens"> */
    /* The recurring palette, named by the role it plays rather than the shade it is.
       These are defined unconditionally, so they are used WITHOUT a fallback:
       var(--aceSurface), not var(--aceSurface, #F5F5F5). One source of truth.

       That is deliberately different from --aceAccent / --aceAccent2 / --aceAccent2Text,
       which are the per-entity branding colors injected by Settings::accentStyleBlock()
       (includes/stg_settings.php) into a <style> block AFTER this file loads. Those may
       legitimately be undefined, so every use of them keeps its literal as the var()
       fallback. Do not merge the two groups: --aceBrand below is the fixed grey-green
       used by tables and PO headers and must NOT follow an entity's chosen accent. */
    :root {
        /* Core palette */
        --aceBrand:      #7A9D96;   /* grey-green: table headings, PO headers, rules */
        /* NOTE: --aceBrand and the --aceAccent FALLBACK used to be the same #7A9D96 and are
           now deliberately different shades of one hue. --aceBrand is almost always a
           BACKGROUND (.results_table th, .short_table th, .hdgRow, .bgColor4, the PO header
           tables) carrying black text at 7.1:1, so darkening it would push that text under
           4.5:1 and break every table heading on the site. The accent fallback is always a
           FOREGROUND -- text, the dashboard stat rail, a hover border -- where #7A9D96 only
           managed 2.96:1 on white and failed AA outright. It is now #57756F: same hue 168 and
           the same saturation, taken down to 5.02:1 on white / 4.61:1 on --aceSurface, which
           is the lightest shade of it that clears 4.5:1 on every ground it lands on.
           Darken one without the other only if you have re-checked the text sitting ON it. */
        --aceBorder:     #707070;   /* standard border grey */
        --aceInk:        #4F4F4F;   /* dark charcoal: toolbars, focus rings, borders */
        --aceInkDeep:    #2A2A2A;   /* near-black: heavy rules, help TOC links */
        --aceSurface:    #F5F5F5;   /* light panel background */
        --aceSurfaceAlt: #DEDEDE;   /* navigation / menu background */
        --aceShadow:     #B2B2B2;   /* box-shadow grey */
        --aceMuted:      #DBDBDB;   /* muted text on dark backgrounds */
        /* Highlights and status */
        --aceHighlight: #FFFFE3;   /* pale-yellow row / field highlight */
        --aceMint:      #DDFFEE;   /* mint selection and action boxes */
        --aceGold:      #FFF3A8;   /* gold emphasis / flash */
        --aceError:     #B02121;   /* error red -- 6.0:1 on the error pill (WCAG 2.2 1.4.3) */
        --aceDebug:     #D1CCFF;   /* debug-only text */
        /* Dashboard cards */
        --aceCardBorder:  #D8E2E0;   /* card outline */
        --aceCardDivider: #E3EAE8;   /* header rule / footer rule inside a card */
        /* Help surface */
        --aceHelpInk:   #16193B;   /* headings */
        --aceHelpBody:  #4A5060;   /* body copy */
        --aceHelpMuted: #7C8697;   /* meta, breadcrumbs, empty states */
        --aceHelpLink:  #2E74A7;   /* links, focus ring, active marker */
        --aceHelpTint:  #EEF4FB;   /* hover background */
    }
/* </editor-fold>*/
 

/* <editor-fold defaultstate="collapsed" desc="General System Formats"> */
    .jsLink, .enableGet, .jsAuto { 
        color: blue !important;
        cursor: pointer; 
    }
    /* Icon::html() writes this onto every icon built through Icon::makejs() (its
       force_click_cursor flag), but nothing ever defined it -- so a clickable icon showed the
       default arrow. It cannot lean on being inside an anchor either: ace_end.js removes the
       href from every .nojslink as soon as it appears, which takes the anchor's own pointer
       cursor with it. */
    .click_cursor { cursor: pointer; }
    html, body { height: 100%; }
    
    @media print { 
         body { overflow: auto; }
    }
    
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="General Setup Styles"> */ 
    .centerBlock { 
        clear: both; 
        display: table; 
        margin: auto; 
        float: none !important; 
    }
    .centerButton { float: none !important; margin: 10px auto !important; display: block !important; }
    .clearfix { clear: both; }
    .hide, .hidden { display: none; }
    .toolbar { 
        clear: both;
        display: table; 
        margin: 10px auto 0 auto; 
        border: 2px solid var(--aceBorder); 
        background-color: var(--aceInk); 
        padding: 2px; 
        border-radius: 4px; 
    }
    .toolbar img { 
        width: 40px; 
        display: block; 
        float: left; 
    }
    .txtCenter { text-align: center; }    
    .center { text-align: center; float: none; display: block; margin: auto; }
    .italics { font-style: italic; }
    .right, .rightHalf { display: block; width: 49%; float: right; }
    .left, .leftHalf { display: block; width: 49%; float: left; }
    .block { 
        background-color: var(--aceSurface); 
        border-radius: 15px;
        border: 5px solid var(--aceBorder); 
        box-shadow: 4px 4px 2px var(--aceShadow);
        display: block; 
        min-width: 75px; 
        padding: 4px 10px 4px 10px; 
    }
    .block h1, .block h2, .block h3, .block h4, .block h5, .block h6 { text-align: center; }
    .autoLoadAndReplace { color: var(--aceBrand); font-style: italic; }
    .gold { background-color: var(--aceGold); }
    .errorBox { background-color: red; font-weight: bold; display: block; width: 100%; text-align: center; }
    .error {background-color: #FDFFCC; color: red; font-style:italic; }
    .lightGrey { color: #D5D5D5; font-style:italic; font-size: small; }
    .smalltext { font-size: 13px; }
    /* <small> renders at "smaller" (~0.83em), which under 13px body text lands at ~10.8px. Every
       <small> in the application wraps content (hints, ids, counts), so hold it at the 13px floor;
       max() still lets it scale down from a larger heading as intended. */
    small { font-size: max(13px, 0.83em); }
    .insetBox { display: block; width: 85%; margin: 10px auto; padding: 5px; background-color:var(--aceSurface); border: 2px solid black; }
    
    
    .infoBlock { display: block; width: 100%; }
    .infoBlock label {  display: block; float: left; clear: both;  font-family: Arial, sans-serif; font-weight: bolder; border-top: 1px dashed black; width: 250px; padding: 2px; margin:1px; text-align: right;  min-height: 24px; }
    .infoBlock p { display: block; float: left; font-family: Arial, sans-serif; font-weight: normal; padding: 2px 2px 2px 5px; margin: 1px;  min-height: 24px; }

    #criticalSystemMessage { 
        display: block; 
        background-color: red; 
        width: 100%;
        margin: 0px 0px 5px 0px; 
        padding: 4px; 
        font-weight: bold; 
        color: yellow; 
        text-align: center; 
        font-size: large; 
        font-family: Arial, sans-serif; 
    }
    #criticalSystemMessage p { margin: 0; padding: 1px; }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Primary Navigation Setup Styles"> */ 
    body {
        overflow:hidden;
        }

    /* <editor-fold defaultstate="collapsed" desc="Header Toolbar"> */ 
        #topBar { 
                        display: block; 
                        position: absolute; 
                        top: 0; 
                        left: 0; 
                        background-color: var(--aceSurface); 
                        border-bottom: solid 1px #C7C7C7; 
                        height: 45px; 
                        width: 100%; 
                        z-index: 900;
                        padding: 0; 
                } 
        /*
         * VERTICALLY CENTERED ON THE BAR (asked for 2026-09-24). Used to be `bottom: 0px` alone,
         * which sizes the box to fit its own content (tbWho's two text lines are taller than the
         * 30px icon row) and then sits that box on the bar's FLOOR -- so the icon row, top-aligned
         * within that box (see the "ONE ROW" comment below), ended up hugging the top of the bar
         * with empty space beneath it instead of centred in the 45px it lives in.
         *
         * `top: 0; bottom: 0` with no height makes the box fill the bar's full 45px (a plain CSS
         * abs-pos rule, not a guess), and `display: flex; align-items: center` centres every
         * direct child -- tbWho AND the icon row -- inside that. The icon row's OWN internal
         * alignment (all three pieces level with each other) is untouched; only where the whole
         * row sits on the bar changes.
         *
         * ORDER IS RESTATED so flex does not reshuffle the icons. tbWho keeps the default
         * order: 0 (still first / left). Without explicit orders below, a flex row lays children
         * out in DOM order -- ul, #sysInfoWrap, then the change-organization <a> -- which is NOT
         * today's visual order (float: right on the <ul> currently pulls it to the far right,
         * past both of the others). The order values below reproduce the existing order: info,
         * then change-organization, then the header-menu icons at the outer edge -- the same
         * relative order the phone breakpoint already uses for these same three elements.
         */
        #topBarRight {
                        display: flex;
                        align-items: center;
                        float: right;
                        position: absolute;
                        top: 0;
                        bottom: 0;
                        right: 10px;
                        text-align: right;
        }
        #topBar #topBarRight > #sysInfoWrap { order: 1; }
        #topBar #topBarRight > a { order: 2; }
        #topBar #topBarRight > ul { order: 3; float: none; }
        /* The signed-in person over the school they are in, in the top bar. Two lines rather
           than one bullet-joined line, because between a full name, a role in brackets, an id
           and a school name with its abbreviation there is more text here than a 45px bar can
           show on one. Blocks, so each takes its own line; the right-alignment comes from
           #topBarRight and the line-height from the inline style beside it in header.php. */
        #topBar .tbWho .tbWhoUser,
        #topBar .tbWho .tbWhoEnt { display: block; }

        /* A DEACTIVATED school, named in the top bar (header.php). #b42318 under white text is
           6.6:1 -- clear of WCAG 2.2 AA, and it stays legible against #topBar's light ground.
           The anchor needs its own colour stated: the school name is a link to select_ent.php,
           and the application link colour is unreadable on this red. Inline-block so the
           padding actually shows without lifting the name off the 45px bar's baseline. */
        #topBar .entDeactivated { 
                        display: inline-block; 
                        background-color: #b42318; 
                        color: #FFFFFF; 
                        padding: 1px 6px; 
                        border-radius: 4px; 
        }
        #topBar .entDeactivated a,
        #topBar .entDeactivated a:link,
        #topBar .entDeactivated a:visited,
        #topBar .entDeactivated a:hover { color: #FFFFFF; }
        /* <editor-fold defaultstate="collapsed" desc="Pinned transactions strip (top bar)"> */
    /* Absolutely positioned so it sits in the gap between the hamburger and the centred logo
       without joining the float row -- #topBar is position:absolute, so it is the containing
       block. acePinPosition() in ace_pinnedTra.js sets `left` from the MEASURED positions of
       those two, because the gap moves: the logo is centred (so it depends on window width)
       and non-production servers push a "SandBox Site" banner in after the hamburger.
       Hidden until it has something in it, so an empty strip costs nothing visually. */
    /* NO transform HERE, and that is load-bearing. #acePinBox below is position:fixed so it can
       hang under the bar over the page; a transformed ancestor becomes the containing block for
       its fixed descendants, so `transform: translateY(-50%)` on this element (the obvious way
       to centre it) silently re-anchored the dropdown card to this strip instead of the
       viewport -- the card's measured `left` was then applied to the wrong origin and it landed
       off to the right of where the button is. Stretching top-to-bottom and centring with flex
       gets the same vertical centring with no transform. */
    #acePinBar {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 60px;
        display: none;
        align-items: center;
        white-space: nowrap;
        z-index: 2;
    }
    #acePinBar:not(:empty) { display: flex; }
    /* The unpin control is a hit target, not a glyph to admire: 16px square keeps it clickable
       at this size without widening the chip. */
    .acePinX {
        cursor: pointer;
        color: #999;
        font-size: 15px;
        line-height: 14px;
        padding: 0 2px;
        border-radius: 8px;
        text-decoration: none;
    }
    .acePinX:hover { color: #a02121; background: var(--aceCardDivider, #eee); }
    /* margin-left, not margin-right: this is the SECOND pill in the strip (history sits to its
       left), and the gap belongs to the one that follows so the strip has no trailing space to
       throw its centring off. */
    /* The PDF pill (2026-09-16) wears the pin pill's box -- same strip, same shape, same job. */
    #acePinWrap,
    #acePdfWrap,
    #aceWatchWrap { position: relative; display: inline-block; vertical-align: middle; margin-left: 6px; }
    #acePinBtn,
    #acePdfBtn,
    #aceWatchBtn {
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        gap: 4px;
        padding: 2px 8px;
        border: 1px solid var(--aceCardBorder, #d8d8d8);
        border-radius: 12px;
        background: #ffffff;
        color: var(--aceAccent, #57756F);
        font-size: 13px;
        line-height: 18px;
    }
    #acePinBtn:hover,
    #acePdfBtn:hover,
    #aceWatchBtn:hover { background: var(--aceCardDivider, #eee); }
    #acePinBtn .acePinCount,
    #acePdfBtn .acePinCount,
    #aceWatchBtn .acePinCount { font-weight: bold; color: #333; }

    /* --- the watch pill when something has moved ---------------------------------------
       A RED FLAG, not a red eye: the shape changes as well as the colour, so the alert does
       not rest on telling two colours apart. #b02121 on white is 6.8:1, the same red this
       application already uses for a failed verdict.

       The blink is opacity only -- nothing moves, nothing resizes, so it cannot shift the
       strip around it. Two seconds is slow enough to read as "look here" rather than as a
       fault, and it is switched off entirely for anyone who has asked for reduced motion,
       where the red flag on its own still carries the whole message (WCAG 2.2 2.3.3). */
    #aceWatchBtn.aceWatchAlert {
        border-color: #b02121;
        color: #b02121;
        animation: aceWatchBlink 2s ease-in-out infinite;
    }
    #aceWatchBtn.aceWatchAlert .acePinCount { color: #b02121; }
    @keyframes aceWatchBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
    @media ( prefers-reduced-motion: reduce ) {
        #aceWatchBtn.aceWatchAlert { animation: none; }
    }
    /* The flag beside a changed row in the list, and the row it is on. */
    #aceWatchBox .aceWatchRowFlag { color: #b02121; }
    #aceWatchBox .acePinRow.aceWatchChanged .aceWatchOpen { font-weight: bold; }
    #aceWatchBoxHdg .aceWatchSeenAll {
        margin-left: auto;
        font-size: 13px;
        font-weight: normal;
        color: var(--aceHelpLink, #2B6CB0);
        cursor: pointer;
        text-decoration: underline;
    }
    /* The same card as #sysInfoBox at the other end of the bar: fixed under the button, accent
       top edge, opens on hover or click. Anchored by `left` rather than `right` because this
       one hangs off an element that moves with the window. */
    /* The history card is the same object in the same place doing the same job, so it wears
       the pin card's styling rather than a near-copy of it. Only the ids differ. */
    /* The notes card is in that list for the same reason: same object, same place, same job --
       and it is the one that must NOT be a near-copy, because it is built in a different file
       (npd_notepad.php) and would drift the moment either side was touched. */
    #acePinBox,
    #aceHistBox,
    #acePdfBox,
    #aceWatchBox,
    #aceNotesBox {
        display: none;
        position: fixed;
        top: 48px;
        /* No fixed width: the card shrink-wraps to its widest entry, because every entry is kept
           on ONE line and the card is what has to give. A report title runs to 80 characters, so
           the old fixed 320px simply cut them off. Capped at the viewport rather than at some
           chosen number of pixels -- the cap only exists so the card can never run off-screen. */
        min-width: 340px;
        max-width: 92vw;
        background: #ffffff;
        border: 1px solid var(--aceCardBorder, #c9aa71);
        border-top: 4px solid var(--aceAccent, #c9aa71);
        border-radius: 5px;
        box-shadow: 0 4px 18px rgba(0,0,0,0.22);
        padding: 10px 12px 12px 12px;
        text-align: left;
        z-index: 1000;
        color: #333;
        font-size: 13px;
        line-height: 1.4;
    }
    #acePinBoxHdg,
    #aceHistBoxHdg,
    #acePdfBoxHdg,
    #aceWatchBoxHdg,
    #aceNotesBoxHdg { font-size: 15px; font-weight: bold; color: #000; margin: 0 0 8px 0; padding-bottom: 6px; border-bottom: 1px solid #eee; }
    /* One entry, one line -- label, secondary text and the unpin control side by side. Nothing
       here wraps or truncates the label; the CARD widens to fit instead (see its max-width). */
    #acePinBox .acePinRow,
    #aceHistBox .acePinRow,
    #acePdfBox .acePinRow,
    #aceWatchBox .acePinRow,
    #aceNotesBox .acePinRow {
        display: flex;
        align-items: baseline;
        gap: 8px;
        padding: 5px 0;
        border-bottom: 1px solid #f4f4f4;
        white-space: nowrap;
    }
    #acePinBox .acePinRow:last-child,
    #aceHistBox .acePinRow:last-child,
    #acePdfBox .acePinRow:last-child,
    #aceWatchBox .acePinRow:last-child,
    #aceNotesBox .acePinRow:last-child { border-bottom: 0; }
    /* THE ONE PLACE THIS CARD DIFFERS. Every other card holds one-line rows and widens to fit
       them; a note is prose somebody typed, with their own line breaks in it, and it has to wrap
       and to scroll rather than stretch the card to the width of the longest line they wrote. */
    #aceNotesBox .aceNotesPeek {
        white-space: pre-wrap;
        word-break: break-word;
        max-height: 40vh;
        overflow-y: auto;
        margin: 0;
    }
    #aceNotesBox .aceNotesPeekHint { margin: 8px 0 0 0; padding-top: 6px; border-top: 1px solid #f4f4f4;
                                     color: #555; font-size: 13px; }
    #acePinBox .acePinOpen,
    #aceHistBox .acePinOpen,
    #acePdfBox .acePdfOpen,
    #aceWatchBox .aceWatchOpen {
        flex: 0 0 auto;               /* never squeezed: the whole label stays readable */
        color: var(--aceAccent, #57756F);
        /* Not bold. These run to 80 characters for a report, and a line of bold that long reads
           as shouting; the accent colour already separates the link from the muted text beside
           it, which is all the weight was doing. */
        font-weight: normal;
        cursor: pointer;
        text-decoration: none;
        white-space: nowrap;
    }
    #acePinBox .acePinOpen:hover,
    #aceHistBox .acePinOpen:hover,
    #acePdfBox .acePdfOpen:hover,
    #aceWatchBox .aceWatchOpen:hover { text-decoration: underline; }
    /* The secondary text is the one thing allowed to give, and only once the card has hit the
       viewport cap -- so an absurdly long title costs the vendor line, not the title. */
    #acePinBox .acePinVen,
    #aceHistBox .acePinVen,
    #acePdfBox .acePinVen,
    #aceWatchBox .acePinVen {
        flex: 1 1 auto;
        min-width: 0;
        font-size: 13px;
        color: #6b7583;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    #acePinBox .acePinX,
    #acePdfBox .acePinX,
    #aceWatchBox .acePinX { flex: 0 0 auto; }
    /* The history button matches the pin button; the heading carries a quiet Clear on its
       right. #6b7583 on white is 5.3:1 -- AA at this size. */
    #aceHistWrap { position: relative; display: inline-block; vertical-align: middle; }
    #aceHistBtn {
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        gap: 4px;
        padding: 2px 8px;
        border: 1px solid var(--aceCardBorder, #d8d8d8);
        border-radius: 12px;
        background: #ffffff;
        color: var(--aceAccent, #57756F);
        font-size: 13px;
        line-height: 18px;
    }
    #aceHistBtn:hover { background: var(--aceCardDivider, #eee); }
    #aceHistBtn .acePinCount { font-weight: bold; color: #333; }
    /* Both of these headings carry an action beside the title -- Clear on the history card,
       "mark all seen" on the watch card -- so both are flex rows.

       The watch one used to place its link with `float: right`, and a float is OUT OF FLOW: the
       heading's height came from its text line alone, so the link hung below the heading's own
       border and sat on top of the first row in the list. The row is in normal flow and paints
       its link above the float, so the click went to the ROW -- which is why "mark all seen"
       appeared to do nothing. The work behind it was fine all along; the click never reached it. */
    #aceHistBoxHdg,
    #acePdfBoxHdg,
    #aceWatchBoxHdg { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
    /*
     * THE HELP ICON IN THESE THREE HEADINGS.
     *
     * Recently Visited is a space-between flex row, so a third child (title, help, clear) would
     * strand the help icon in the middle of the bar. margin-right: auto puts the free space
     * AFTER the icon instead, which keeps the title and its help together on the left and sends
     * clear back to the right where it was.
     *
     * The other two headings are ordinary blocks with a floated action, so the icon simply
     * follows the words -- they need nothing but the shared sizing below.
     */
    /* Recent PDFs is the same shape -- title, help, clear -- and needs the same push.
       Watching too (added 2026-09-24): it became a space-between flex row when its float was
       removed, but was never added here, so its "?" sat at the far right -- or in the middle of
       the bar whenever "mark all seen" was showing -- instead of right after the title. */
    #aceHistBoxHdg .hlpIconLink,
    #acePdfBoxHdg .hlpIconLink,
    #aceWatchBoxHdg .hlpIconLink { margin-right: auto; }
    /* THE SCREEN-CODE CHIP (added 2026-09-25; only code viewers get one) follows the "?", so
       when it is there the free space moves from the "?" to the chip -- title, help and code stay
       together on the left and the action still goes right. margin-left: 0 !important overrides
       the chip's own inline 8px, which would otherwise stack on the heading's 12px gap. */
    #aceHistBoxHdg .hlpIconLink:has(+ .popModalCode),
    #acePdfBoxHdg .hlpIconLink:has(+ .popModalCode),
    #aceWatchBoxHdg .hlpIconLink:has(+ .popModalCode) { margin-right: 0; }
    #aceHistBoxHdg .popModalCode,
    #acePdfBoxHdg .popModalCode,
    #aceWatchBoxHdg .popModalCode { margin-right: auto; margin-left: 0 !important; }
    #acePdfBoxHdg .acePdfClear,
    #aceHistBoxHdg .aceHistClear { font-size: 13px; font-weight: normal; color: #6b7583; cursor: pointer; text-decoration: none; }
    #acePdfBoxHdg .acePdfClear:hover,
    #aceHistBoxHdg .aceHistClear:hover { color: #a02121; text-decoration: underline; }
    /* Phones: there is no gap between hamburger and logo to sit in, so the strip cannot stay
       absolutely positioned there -- it would land on top of one or the other. It used to be
       hidden outright; it now gets a row of its own on the second line of the bar. The
       positioning reset lives with the rest of the phone top-bar layout, in the breakpoint near
       the bottom of this file -- search "the top bar STACKS".
       Still `display: none` when EMPTY, via #acePinBar:not(:empty) above, so a user with no
       pins and no history gets no strip and no gap where one would be. */
    /* </editor-fold> */

/* <editor-fold defaultstate="collapsed" desc="Totals row -- one look for every table"> */
/* autoTable::addTotalRow() tags its row .aceTotalRow. Callers used to dress it themselves --
   #E6E6E6, #707070, #ffffe3, #7A9D96, bold in some and not others -- so the same component
   read as four different things depending which screen you were on. Those inline styles are
   gone; this owns it. --aceAccent2 / --aceAccent2Text are the card-header pair, which is
   contrast-safe against the brand colour by construction, so the totals row cannot end up
   as dark-on-dark the way the #707070 ones did. */
.aceTotalRow td {
    background-color: var(--aceAccent2, #F7FAF9);
    color: var(--aceAccent2Text, #2F4F4A);
    font-weight: 600;
    border-top: 2px solid var(--aceCardDivider, #D8E2E0);
}
/* Sits under a scrolling body in a long table, so it keeps its own ground. */
.aceTotalRow td a { color: inherit; }
/* </editor-fold> */


    #topBar ul { margin: 0; padding: 0; list-style-type: none; display: block; float: right; }
        #topBar li { display: block; float: right; }
        #topBar ul img { width: 30px; margin: 0; }
        #topBar .menuTitle { display: none; }
    /* THE ICONS IN THE TOP-RIGHT ARE ONE ROW AND MUST READ AS ONE ROW.
       They come from three different places -- the header menu's <ul> (Logout, Help, Settings,
       Refresh), the system-info button, and the change-organization link -- and each was sized
       only by WIDTH. Every one of those PNGs happens to be square today, so the heights matched
       by luck; the first non-square icon added to that row would have made it ragged. Stating
       both, with object-fit so a non-square source is fitted rather than stretched, means it
       cannot happen.
       vertical-align matters as much as the size here: the <ul> is floated, #sysInfoWrap is
       inline-block with vertical-align: top, and the change-organization <a> had neither -- so
       it sat on the text baseline, a few pixels below its neighbours, at exactly the same
       height as them. */
    #topBar ul img,
    #topBar #sysInfoBtn img,
    #topBar #topBarRight > a img {
        width: 30px;
        height: 30px;
        box-sizing: border-box;     /* the same model .ace-icon-wrap uses -- see #navigationMenu img */
        object-fit: contain;
        vertical-align: top;
    }
    
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Icon Toolbars"> */ 
        #navigationMenu { 
                display: inline-block; 
                float: left; 
                background-color: var(--aceSurfaceAlt); 
                width: auto; 
            }
        /* Height stated as well as width, for the same reason the top-bar row states it: every
           menu image is 80x80 today, so a width alone happened to give 40px of height -- 151
           distinct files, all square, all by convention rather than by anything enforcing it.
           object-fit so a non-square file added later is fitted, not stretched.

           box-sizing: border-box MATCHES THE ACEICON PATH. .ace-icon-wrap carries border-box
           (this file, further down), and this <img> was content-box -- the one remaining place
           the two icon shapes were measured differently. With no padding or border on the image
           the two models give the identical 40x40 box today, so this changes nothing on screen;
           what it buys is that they STAY identical. Add a border to either path tomorrow and
           both now shrink inward instead of one growing outward, which is the difference that
           made an outline the only safe way to draw the "you are here" ring (see the fold
           below). */
        #navigationMenu img { 
                width: 40px; 
                height: 40px; 
                box-sizing: border-box; 
                object-fit: contain; 
                display: block; 
                float: left; 
                clear:left; 
            }
        #navigationMenu ul { 
                list-style-type: none; 
                padding: 0; 
                margin: 10px 0 0 0 ; 
            }
        #navigationMenu .menuTitle { 
                display: none;
                float: left; 
                overflow: hidden; 
                font-size: 16px; 
                margin: 12px 2px 0 2px;

            }
        #navigationMenu .navMenu { 
                display: inline-block; 
                float: left; 
                background-color: var(--aceSurfaceAlt); 
                padding: 45px 3px 0 3px; 
                border-left: solid 1px #C7C7C7; 
                height: 100%; 
        }
        #navMenu1 { 
                top: 0;
                left: 0; 
                z-index: 10; 
            }
        /* THE HAMBURGER, at the top of the rail above Home (sysMenu::getFullNavMenus). It opens
           the slide-out menu. Sized by #navigationMenu img above like every other icon in the
           column; what it needs of its own is the gap that separates "the menu" from the
           destinations under it, and a pointer, since it is an <a> with no href. */
        #navMenu1 #showHiddenLeftPanel { display: block; float: left; clear: both; cursor: pointer; }
        /* Top margin so it is not jammed against the rail's edge, bottom margin to separate
           "the menu" from the destinations under it. The rail's own 45px top padding is shared
           with every column and is not the place to change one icon's spacing. */
        #navMenu1 #showHiddenLeftPanel img { margin: 10px 0 8px 0; }
        #navMenu1 #showHiddenLeftPanel:hover img { opacity: 0.75; }
        /* A visible focus ring: it is keyboard-reachable via tabindex in the markup, and an
           outline on the anchor would be clipped by the column's 3px padding. */
        #navMenu1 #showHiddenLeftPanel:focus-visible img { outline: 2px solid var(--aceAccent, #2b6cb0); outline-offset: -2px; }
        #navMenu2 { 
                top: 0; left: 48px; 
                z-index: 9; 
            }
        #navMenu3 { 
                top: 0; left: 96px; 
                z-index: 8;
            }
        #navMenu4 { 
                top: 0; left: 144px;
                z-index: 7; 
            }
        #navMenu5 {
                top: 0; left: 192px; 
                z-index: 6; 
            }
        #navigationMenu, #navigationMenu a { 
            color: black;
            font-size: medium;
            font-weight: normal; 
            text-decoration: none; 
        }
        /* <editor-fold defaultstate="collapsed" desc="You are here"> */
    /* The ring around the icon of the screen you are currently on, and a fainter one on its
       parent category. Applied by markCurrentNavItem() in ace_end.js, never server-side: the
       nav is rendered once per page load and never redrawn, so a server-rendered class would
       be right for the first paint and wrong from then on.

       OUTLINE, NOT BORDER, and this is not a preference:
         - .menuIcons on the <img> path is content-box, so a border GROWS the icon;
         - the AceIcon path is a <div> carrying INLINE box-sizing:border-box (and
           overflow:hidden from .ace-icon-wrap in this file), so the same border SHRINKS the
           glyph instead -- the two icon shapes would not match;
         - the columns are pinned 48px apart (#navMenu1-5 below) with 3px of padding around a
           40px icon, so there is no room to grow into;
         - calcNavWidth()/redrawScreen() sum outerWidth() of the columns to size #mainContent,
           so anything that changes an icon's outer width moves the whole page.
       An outline draws outside the box and occupies no space, so it does none of that.

       The fallback is required: --aceAccent is only written onto :root (by
       Settings::accentStyleBlock, via header_includes.php) when the entity has actually set
       accentPrimary. #2b6cb0 is the language's blue, the same fallback used elsewhere.

       Each selector is scoped to its own container ON PURPOSE -- class='menuItem' is carried
       by the left nav, the hamburger menu AND the top header row, so an unscoped rule would
       ring the same item in three places at once. */
    /* EVERY RING IS A CIRCLE, and border-radius is how that is achieved: a browser draws an
       outline (and an inset box-shadow) following the element's OWN border-radius, so the ring
       can only be as round as the box under it. Two halves to it:
         - the AceIcon chips now carry an inline border-radius:50% (menus.php sets
           'borderRadius' => '50%' in all three of its iconSettings arrays -- it used to be a
           flat 15px, which read as a circle at 25/30px and a rounded SQUARE at 40px);
         - the PNG icons get their radius here, because an <img> has no radius of its own and
           was therefore ringed square.
       Clipping the PNG costs nothing: every one of the 206 mnu_*.png files is circular artwork
       centred in an 80x80 box, with 0% of the pixels outside the inscribed circle opaque
       (measured 2026-08-26 across the whole directory). If a square-artwork icon is ever added
       it will clip when selected -- that is the trade, and it is why this is measured rather
       than assumed. */
    /* THE SVG CHIPS ARE SIZED TO THE PNG ARTWORK, so the two icon shapes read as one set.
       Measured rather than guessed (2026-09-01): every mnu_*.png is a filled #6D6E71 circle
       with a white glyph, and that circle occupies 74 of the file's 80 pixels -- 93%, or 37.2px
       once the image is drawn at 40. AceIcon paints its background across the whole 40px box,
       so its chip was the larger of the two by about 7% and sat flush where the PNGs have a
       hair of breathing room. The colour already matched exactly.

       background-clip: content-box is what shrinks the PAINT without moving the BOX. The box
       stays 40x40, so the column's spacing is untouched and -- the reason this matters -- the
       "you are here" outline still lands at the same 42px on both paths. Scaling the element
       instead would have shrunk that ring on one path only.

       The two paddings, and why they are what they are:
         wrapper 1.4px -> the painted circle is 40 - 2(1.4) = 37.2px, the PNG's diameter;
         inner   2.8px -> the glyph keeps the 85% of the circle it had before (34 of 40), so
                          the artwork inside the chip is not suddenly bigger relative to it.
       AceIcon writes padding:3px inline, which is why the wrapper value below needs the extra
       specificity of the #navigationMenu scope to win. */
    #navigationMenu .ace-icon-wrap.menuIcons {
        padding: 1.4px;
        background-clip: content-box;
    }
    #navigationMenu .ace-icon-wrap.menuIcons .ace-icon-inner { padding: 2.8px; box-sizing: border-box; }
    /* The slide-out menu draws the same chips at 30px: 93% of 30 is 27.9, so 1.05px a side. */
    #hiddenNavMenu .ace-icon-wrap { padding: 1.05px; background-clip: content-box; }
    #hiddenNavMenu .ace-icon-wrap .ace-icon-inner { padding: 2.1px; box-sizing: border-box; }

    /* KEYBOARD FOCUS IS DRAWN ON THE ICON, AS A CIRCLE -- and this is a bug fix, not a polish.
       Clicking a nav item focuses the <a class='disableLink'> around the icon (the anchor keeps
       its href; only its click is prevented). Nothing is visible while the pointer is driving,
       because browsers hold focus rings back for mouse input -- but the FIRST KEYSTROKE flips
       that heuristic on, and Escape is a keystroke. So closing a pop with Escape made the
       browser paint its default focus ring around that anchor, whose box is a plain rectangle
       around the 40px icon: the round "you are here" ring appeared to turn square.
       The ring is suppressed on the anchor and re-drawn on the icon inside it, with the same
       2px / 1px-offset / 50% treatment .navHere uses -- so focus stays visible (WCAG 2.4.7)
       and looks like everything else in the column. */
    #navigationMenu .menuItem a:focus,
    #hiddenNavMenu .hiddenNavItem a:focus { outline: none; }
    #navigationMenu .menuItem a:focus-visible .menuIcons,
    #navigationMenu .menuItem a:focus-visible .ace-icon-wrap {
        outline: 2px solid var(--aceAccent, #2b6cb0);
        outline-offset: 1px;
        border-radius: 50%;
    }
    /* The slide-out menu draws the same icons at 30px; same treatment, its own class. */
    #hiddenNavMenu .hiddenNavItem a:focus-visible .cstmIcon,
    #hiddenNavMenu .hiddenNavItem a:focus-visible .ace-icon-wrap {
        outline: 2px solid var(--aceAccent, #2b6cb0);
        outline-offset: 1px;
        border-radius: 50%;
    }
    #navigationMenu .navMenu .menuItem.navHere .menuIcons {
        /* 2 + 1 = 3px, exactly the column's horizontal padding. At offset 2 the ring paints
           1px past the column edge and over the next column's border -- and #navMenu1 has the
           higher z-index, so it wins that overlap and the bleed is visible. */
        outline: 2px solid var(--aceAccent, #2b6cb0);
        outline-offset: 1px;
        border-radius: 50%;
    }
    /* THE MASTER USER SETTINGS ICON RINGS RED, not in the school's accent, and it is the only
       item in any menu that does. The accent ring says "this is where you are"; a red one says
       that AND says what kind of place it is -- a screen whose settings reach every school, not
       the one you are working in. A school's accent could BE red, so the two would then read
       alike; that is accepted, because on those entities the ring still marks the current item
       correctly and nothing is lost but the second meaning.
       .mstIcon comes from the menu row's icon_settings JSON (cssClass), so the mark travels with
       the row rather than being pinned to an id that a re-numbered row would break. The same
       class is carried into the hamburger and the footer favourites, which draw the same item
       with their own ring, so all three agree. */
    #navigationMenu .navMenu .menuItem.navHere .menuIcons.mstIcon,
    #topBar .menuItem.navHere .menuIcons.mstIcon { outline-color: #b02121; }
    #hiddenNavMenu .hiddenNavItem.navHere .mstIcon,
    #footerShortcuts .favItem.navHere .mstIcon { box-shadow: inset 0 0 0 3px #b02121; }

    /* The categories above it, in the columns to the left. Told apart by DASH PATTERN alone --
       same 2px ring, same accent colour -- so the trail reads as one family of marks rather
       than as two different kinds of thing. Outlines follow the element's border-radius, so
       this dashes around the circle.

       THE DASH IS THE ONLY CUE, and it carries the full accent -- same colour and same weight
       as the current item. That is deliberate: a dash pattern reads the same on every brand
       colour, whereas a lighter tone does not. Softening depends on the accent having contrast
       to spare, and a pale one (entity 231's #A59229, say) has none, so on those schools a
       tonal cue would have collapsed back to no cue at all. Carrying full strength also keeps
       this ring at whatever contrast the accent itself holds, with nothing to re-check against
       WCAG 2.2 SC 1.4.11 when a school picks a new colour. */
    /* ONE ITEM PER COLUMN, and it is guaranteed by construction rather than by CSS.
       setNavPath() in ace_end.js is the only thing that writes either class: it rings the
       selected item solid and walks up marking each category above it dashed, so a column
       can never hold two -- the walk yields at most one ancestor per level, and an item can
       never be its own ancestor, so nothing can carry both classes at once.
       That is why there is no :not(.navHere) guard here. There used to be, back when a
       second writer (.navOpen, set on click for categories with no route of their own) could
       land on the same icon as this rule and win on source order. Collapsing both cases into
       the one path setter removed the conflict rather than papering over it. */
    #navigationMenu .navMenu .menuItem.navHereParent .menuIcons {
        outline: 2px dashed var(--aceAccent, #2b6cb0);
        outline-offset: 1px;
        border-radius: 50%;
    }
    /* THE SLIDE-OUT MENU RINGS ON THE INSIDE. #hiddenNavMenu ul li is overflow:hidden with no
       right padding, and img.cstmIcon is floated hard against that right content edge -- so an
       outline is sliced off on the very side it is drawn on, and again at the bottom. An inset
       shadow is painted within the icon's own box, so it survives the clip and, like an
       outline, takes no space. */
    /* Only .navHere here: markCurrentNavItem() never applies .navHereParent outside the left
       nav, because neither this menu nor the footer has a column chain to walk. */
    #hiddenNavMenu .hiddenNavItem.navHere .cstmIcon { box-shadow: inset 0 0 0 3px var(--aceAccent, #2b6cb0); border-radius: 50%; }
    /* THE FOOTER RING IS THE BAR'S INK, NOT THE ACCENT -- #footerBar's own background IS
       var(--aceAccent) (see that rule below), so an accent ring on it is invisible on exactly
       the entities that have bothered to set a brand colour. --aceAccentText is resolved
       server-side by Settings::accentTextColorStrict(), so it is readable against ANY accent a
       school can pick, which is the guarantee this ring needs.
       DESCENDANT, NOT CHILD, and the two icon shapes are why. getIcon()'s AceIcon path
       returns its <div class='ace-icon-wrap'> straight into this span, but its PNG path ends
       at Icon::makejs(), which finds $icon->target still Null -- getIcon only ever sets
       data-target/data-type/data-codes, and load_attr() files anything that is not a real
       property into $icon->attr -- so it builds a generic_auto.php fallback link and
       Icon::html() wraps the <img> in an <a>. The PNG icon is therefore a GRANDchild of
       .favItem while the SVG one is a child, and a `>` combinator rings only the SVG half of
       the bar. That is the whole of the "footer favourites highlight inconsistently" bug: a
       PNG favourite (Vendors' handshake, and most of the older icons) never matched.
       The two elements are still NAMED rather than using a bare descendant `*`: when a colour
       is set AceIcon emits a <style> element ahead of its div inside this same span, and the
       PNG path adds an <a> -- naming img/.ace-icon-wrap skips both. Nothing else in a favourite
       is an img or an .ace-icon-wrap, so there is no second element to catch.
       Offset 1: the icons are 30px with a 5px gap in a 40px bar, so 2+1 is the ceiling. */
    #footerShortcuts .favItem.navHere img,
    #footerShortcuts .favItem.navHere .ace-icon-wrap {
        outline: 2px solid var(--aceAccentText, #555555);
        outline-offset: 1px;
        border-radius: 50%;
    }
    /* THE HEADER ROW, upper right. #topBar's background is var(--aceSurface), a light panel
       like the nav, so this takes the accent rather than the footer's ink. Same 2px/1px-offset
       ring as the left nav; the icons are 35px here (#topBar ul img above) inside a 45px bar,
       so 2 + 1 clears the bar's edges.
       .navHere only: the header is a flat row with no hierarchy, so nothing above it can be a
       parent. Rows that cannot BE the current screen never match anyway -- Logout redirects to
       logout.php and Refresh's target is 'refresh', and neither is ever the route sitting in
       #mainContent -- so in practice this rings Help and Settings.
       Scoped to #topBar because class='menuItem' is shared with the left nav and the hamburger;
       see the note at the top of this fold. */
    #topBar .menuItem.navHere .menuIcons,
    #topBar .menuItem.navHere .ace-icon-wrap {
        outline: 2px solid var(--aceAccent, #2b6cb0);
        outline-offset: 1px;
        border-radius: 50%;
    }
    /* The wrapper userFavoritesIcons() puts around each footer shortcut so both the PNG and
       the SVG icons have somewhere to carry data-mnucodes. inline-block + baseline keeps the
       row in one inline flow, which is what holds the saved sort order and lines the SVGs up
       with the PNGs -- see the note in menus.php::userFavoritesIcons(). */
    #footerShortcuts .favItem { display: inline-block; vertical-align: baseline; }
    /* The build number in the footer -- master users only. Black rather than the muted grey
       it started as: it is read to answer "is this browser current?", and a number you have to
       squint at does not do that job. Monospace so two builds compare digit by digit. */
    #footerBar .copyright .aceBuildNo {
        /* NO font-family and NO font-size of its own -- both are inherited from #footerBar, so
           the build number renders identically to the copyright text and the two links beside it.
           It carried a monospace family at 11px, and BOTH made it look smaller: the extra pixel
           was the obvious half, but a monospace face at the same px size still reads smaller than
           the proportional one around it, because its x-height is lower. Matching the size alone
           was not enough. Restore the family here if a build number ever needs to be monospace
           again, but then it will not match its neighbours. */
        font-size: inherit;
        /* The bar's own ink, like everything else in the footer. This was #000000, which read as
           a different colour from the copyright text beside it and from the Notices and Need Help
           links -- and on a dark brand bar it was barely legible at all. --aceAccentText is
           contrast-safe against whatever the brand colour is, by construction. */
        color: var(--aceAccentText, #555555);
        cursor: help;
        white-space: nowrap;
    }
    /* </editor-fold> */

    #navigationMenu hr { 
            margin: 10px 0 5px 0;
            float: left;
            clear: both;
            width: 100%;
        }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Hidden Navigation Menu"> */ 
        #menuSidePanel { max-height: 100%; overflow: auto; }
        #hiddenNavMenu { 
            background-color: var(--aceSurfaceAlt);
            display: none; 
            width: 260px; 
            height: 100%; 
            position: absolute; 
            top: 0; 
            left: 0; 
            z-index: 999; 
            overflow-y: auto; 
            overflow-x: hidden; 
        }
        #hiddenNavMenu ul { margin: 0; padding: 0; list-style-type: none; width: 240px; }
        #hiddenNavMenu ul ul { margin: 0 0 0 10px; width: 230px; }
        #hiddenNavMenu ul ul ul { margin: 0 0 0 10px; width: 220px; }
        #hiddenNavMenu ul li { 
            border: 1px solid black; 
            height: 36px;
            width: 95%;
            display: block; 
            font-size: 16px;
            padding: 10px 0 0 10px;
            margin: 2px 0 0 0; 
            border-radius: 10px; 
            overflow: hidden; 
            background-color: white; 
            }
        /* Same treatment as the rail above -- the slide-out draws the same icons at 30px, and
           the same box model as the AceIcon chips it sits beside. */
        #hiddenNavMenu li img.cstmIcon { 
                width: 30px; 
                height: 30px; 
                box-sizing: border-box; 
                object-fit: contain; 
                display: block; 
                float: right;
            }
        #hiddenNavMenu, #hiddenNavMenu a { 
            color: black; 
            font-size: medium; 
            font-weight: normal; 
            text-decoration: none; 
        }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Footer Bar"> */ 
    /* The footer in the "New look and feel". It was the last black slab in the signed-in
       chrome -- #topBar has been light (var(--aceSurface) under a #C7C7C7 hairline) for a
       while, so the two ends of the page disagreed with each other and with every screen
       between them.

       THE BAR CARRIES THE ENTITY'S PRIMARY ACCENT. --aceAccent / --aceAccentText are written
       by Settings::accentStyleBlock() (includes/stg_settings.php) into a <style> block that
       header_includes.php emits AFTER this file, and only when the entity has actually set
       accentPrimary -- so both need their literal fallback here, which is the rule for every
       --aceAccent* use in this file.
       Falling back to #eef1f6 / #555555 rather than to the --aceAccent fallback the dashboard
       uses (#57756F): an entity that has chosen no brand colour gets this language's QUIET
       BAND, the same pair nlfToolbarStyle() (settings_page_style.php) uses for a tray of
       secondary actions -- which is what this bar is. A grey-green footer on every unbranded
       school would be a statement nobody asked for.
       --aceAccentText is resolved by Settings::accentTextColorStrict(), so it clears 4.5:1
       against ANY accent. Do not substitute --aceAccent2Text or a literal: a mid-tone brand
       colour will fail one of them.
       The seam is rgba black rather than a fixed hairline for the same reason -- it has to
       read against a background this file cannot know. It shows as a soft edge on a light
       accent and disappears into a dark one, where the accent itself is already the edge.

       font-size drops from `medium` (16px) to 12px: at 16px the copyright line was competing
       with the page content for attention, which is not what a footer is for. */
    #footerBar { 
            display: block; 
            position: absolute; 
            bottom: 0; 
            left: 0; 
            height: 40px; 
            background-color: var(--aceAccent, #eef1f6); 
            border-top: 1px solid rgba(0, 0, 0, 0.12); 
            box-sizing: border-box; 
            color: var(--aceAccentText, #555555); 
            width: 100%; 
            font-weight: normal; 
            font-size: 13px; 
            text-shadow: none; 
            
            }
    /* The search field and its Go button. Both are 26px tall with EQUAL top and bottom
       margins, which is what centres them on the 40px bar: a float is placed at the top of
       its containing block plus its top margin, so 7 + 26 + 7 is the only arithmetic that
       leaves the same gap above and below. The phone breakpoint below turns the bar into a
       flex row with align-items:center -- symmetric margins are centred there too, whereas
       the old `margin: 5px 5px 0 0` would have been pushed off-centre by half its own top
       margin. Change one height and you must change the other.
       border-box so the stated 26px is what is drawn: the input's border and padding used to
       be added on top of a 30px height, and the button's 34px + a 2px border came out at 38
       in a 40px bar -- which is why they read as different sizes sitting on the floor of the
       bar rather than in the middle of it. */
    /* Secondary-accent border + fill (asked for 2026-09-24, to match the Go button beside it --
       see that button's own comment for why --aceAccent2/Text and not a flat colour). color is
       set from the SAME pair so typed text stays readable against whatever fill an entity's
       accent2 turns out to be -- accent2Text is guaranteed contrast against accent2, by
       construction, the same guarantee the rest of the app relies on it for. */
    #mainSystemSearch {
            display: block;
            float: right;
            box-sizing: border-box;
            width: 135px;                   /* halved from 250px 2026-09-23, +10px 2026-09-24 */
            height: 26px;
            margin: 7px 5px 7px 0;
            padding: 2px 8px;
            background-color: var(--aceAccent2, #ffffff);
            color: var(--aceAccent2Text, #222222);
            border: 1px solid var(--aceAccent2Text, #8c8c8c);      /* the language's control border -- 1.4.11 */
            border-radius: 6px;
            font-size: 13px;
        }
    #mainSystemSearch:focus {
            outline: 2px solid #2b6cb0;
            outline-offset: 1px;
            border-color: #2b6cb0;
        }
    /* The placeholder is this field's only label on screen, so it is styled to be read, not
       to be decorative -- the italic grey it used to wear was neither. #666 is 5.7:1 on
       white. footer.php also carries an aria-label, because a placeholder disappears the
       moment anyone types (WCAG 2.2 3.3.2). */
    #mainSystemSearch::placeholder { color: #666666; opacity: 1; font-style: normal; }
    /*
     * THE SAME BUTTON AS THE FOOTER'S A- / 100% / A+ (asked twice on 2026-09-24/25: "the same
     * coloring and style as the A- button").
     *
     * The first attempt copied `.btnSecondary` -- white fill, #2b6cb0 outline -- on the belief
     * that the A- buttons ARE .btnSecondary. They are not quite: `#aceZoomCtl .aceZoomBtn` below
     * re-colours them with the entity's secondary accent (filled --aceAccent2, --aceAccent2Text
     * text and border, no hover change), so the copy never matched on screen. So the colours now
     * come from THAT rule -- this button is listed in it -- and only placement and geometry are
     * stated here, set to the A- button's own: 26px tall, 0 8px padding, 32px minimum width,
     * 6px corners, 13px Arial. One rule for the colour means the two cannot drift apart again.
     *
     * float / margin stay this button's own: it is placed in the footer bar differently from
     * the zoom group.
     */
    #mainSystemSearchGoButton {
            display: block;
            float: right;
            box-sizing: border-box;
            height: 26px;
            min-height: 26px;
            min-width: 32px;
            margin: 7px 5px 7px 0;
            padding: 0 8px;
            font-family: Arial, sans-serif;
            font-size: 13px;
            line-height: 1.2;
            border: 1px solid;
            border-radius: 6px;
            box-shadow: none;
            cursor: pointer;
        }
    /* The focus ring .btnSecondary gives the A- buttons. */
    #mainSystemSearchGoButton:focus { outline: 2px solid #2b6cb0; outline-offset: 2px; }
    #footerShortcuts { 
            display: block; 
            float: left; 
        }
    #footerBar img { 
                width: 30px;
                margin: 5px 0 0 5px; 
            }
    /* Stretched top-to-bottom of the 40px bar and centred as a flex line, rather than
       pinned to `bottom: 0` -- that put the text's baseline on the bar's bottom edge, so it
       read as sitting low rather than centred. The phone breakpoint below puts this box back
       into the flow (position: static) and re-centres it with the bar's own align-items, so
       it resets display/height there. */
    #footerBar .copyright { 
        position: absolute; 
        /* Was a flat 450px, which held "(c) 2026 - Notices" and nothing more. The
           "Need Help? Report a Bug?" link pushed past it, and in a centred flex row the
           overflow spills equally out of both ends and under the neighbouring controls.
           max-width keeps the centring and the ceiling; width:auto lets it take only what
           it needs, so the shorter signed-out version does not sit in an oversized box. */
        width: auto;
        max-width: 620px; 
        top: 0; 
        bottom: 0; 
        left: 50%; 
        /* translateX rather than the old margin-left:-225px, which only centred a box that
           was exactly 450px wide. */
        transform: translateX( -50% );
        margin: 0;
        text-align: center; 
        display: flex; 
        align-items: center; 
        justify-content: center; 
    }
    /* .jsLink carries `color: blue !important`, which outranks even an inline style on the
       anchor -- so the footer's Notices link needs its own !important to read white on the
       black bar. The underline stays: with no colour contrast against the surrounding text
       it is the only thing marking it as a link. */
    #footerBar .copyright a.jsLink,
    #footerBar .copyright a.jsLink:link,
    #footerBar .copyright a.jsLink:visited,
    #footerBar .copyright a.jsLink:hover,
    #footerBar .copyright a.jsLink:focus,
    #footerBar .copyright a.jsLink:active {
        /* Takes the bar's own ink rather than the language's #2b6cb0, because #2b6cb0 has no
           guaranteed contrast against an arbitrary brand colour whereas --aceAccentText does
           by construction. That leaves the UNDERLINE as the only thing marking it as a link,
           which is exactly what 1.4.1 asks for when a link is not distinguished by colour --
           and is what this line already did when the bar was black and the link was white. */
        color: var(--aceAccentText, #2b6cb0) !important;
        text-decoration: underline;
    }
    #liveSupportIcon { display: block; float: right }
    #liveSupportIcon img { width: auto; height: 100%; margin: 0; }
    #systemSearchTool { display: block; float: right }
    /* TEXT SIZE CONTROL (footer.php) and the zoom it applies (2026-09-23).
       ON THE CHILDREN OF #mainContent, NOT #mainContent: zoom scales an element's own box too,
       and redrawScreen() gives #mainContent a pixel width and height that fit the window -- a
       zoomed #mainContent would grow past both. Its children are auto / percentage width, which
       zoom lays out in a correspondingly smaller space, so they still fill the container and
       only fixed-width content (a wide table) scrolls, as it would when enlarged anyway. Every
       get_data('load') replaces those children, and the rule applies to the new ones at once. */
    /* --aceUnzoom exists ONLY inside the zoomed content, so a pinned bar there can divide its
       offsets by it: zoom scales a fixed element's top / left / right too, which would slide a bar
       under the menu when zoomed out and leave a gap when zoomed in. A popup or anything outside
       #mainContent never sees it and falls back to 1. See .qbsTopBar and the Bill.com fix bar. */
    html.aceZoomed #mainContent > * { zoom: var(--aceZoom, 1); --aceUnzoom: var(--aceZoom, 1); }
    /* Floated right AFTER the search in source, so it sits just left of it. Every property is
       stated because ace.css gives every <button> a float, shadow and min-width. 26px keeps the
       24px target-size floor (WCAG 2.2 2.5.8) inside the 40px bar. */
    /* margin-left: 50px (asked for 2026-09-24) -- more breathing room between this and the Go
       button beside it now that the two swapped places and sit right next to each other. */
    #aceZoomCtl { display: flex; float: right; align-items: center; gap: 4px; height: 100%; margin: 0 10px 0 50px; }
    #aceZoomCtl .aceZoomBtn { float: none; height: 26px; min-height: 26px; min-width: 32px; padding: 0 8px;
                              margin: 0; box-shadow: none; font-family: Arial, sans-serif; font-size: 13px; }
    /* Same reasoning as the Go button's hover, right above in this file (search "SECONDARY
       ACCENT"): these three buttons wear the app-wide .btnSecondary hover (a flat light blue),
       which is exactly what fights or vanishes into a footer painted in the entity's OWN accent
       colour. --aceAccent2 / --aceAccent2Text with today's own values as the literal fallback.
       STATED ON THE BASE STATE TOO, not just :hover (asked for 2026-09-24, "make it look the
       same unhovered as hovered -- I like the hovered look"). The :hover rule below is now
       identical on purpose -- kept as its own rule rather than deleted so a future "give hover
       its own look back" ask has a rule already sitting there to change.
       The footer's search Go button is listed here too (2026-09-25) so it wears exactly this
       colouring -- see its own rule, earlier in this file. */
    #aceZoomCtl .aceZoomBtn,
    #mainSystemSearchGoButton {
        color: var(--aceAccent2Text, #24598f);
        background-color: var(--aceAccent2, #eef3fa);
        border-color: var(--aceAccent2Text, #24598f);
    }
    #aceZoomCtl .aceZoomBtn:hover,
    #mainSystemSearchGoButton:hover {
        color: var(--aceAccent2Text, #24598f);
        background-color: var(--aceAccent2, #eef3fa);
        border-color: var(--aceAccent2Text, #24598f);
    }
    #aceZoomCtl .aceZoomPct { min-width: 50px; }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Status Messages"> */ 
        /* The toast that slides up at the bottom right, in the "New look and feel": a white
           card with a thin grey border, hairline-separated rows and a coloured rail per
           message. It replaces the #FFFD96 lozenge with dotted black separators.

           WHY THIS IS IN ace.css when the rest of the language lives in
           includes/general/settings_page_style.php: #statusMessages is written by header.php
           on every page load and filled by ace_end.js, so there is no partial to call and
           nothing to scope it to. These rules are the component's ONLY home -- overriding
           them from a style block elsewhere would leave the toast defined in two files. The
           id keeps the blast radius to this one widget, which is the reason the language
           stays out of .form_default / .results_table. */
        #statusMessages {
                display: none;
                float: right;
                position: absolute;
                bottom: 20px;
                right: 120px;
                background-color: #ffffff;
                border: 1px solid #c8c8c8;
                border-radius: 12px;
                /* Lifted further off the page than a settings card: this one floats over
                   whatever the user was reading, so the shadow is what separates it. */
                box-shadow: 0 3px 12px rgba(0, 0, 0, 0.18);
                padding: 6px 8px;
                z-index: 900;
                width: 450px;
                /* moveSysMessage()/addSysMessage() pin right:120px inline, so the box has to
                   fit in what is left of a narrow window rather than run off the left edge. */
                max-width: calc(100vw - 140px);
                box-sizing: border-box;
            }
        #statusMessages:empty, #statusMessages:blank { display: none;  }
        #statusMessages:-moz-only-whitespace { display: none; }
        /* One row per message, separated by the same hair line the settings tables use, and
           none under the last. A row is no longer dismissed by clicking it (ace_end.js) -- so its
           text can be selected and copied -- and has a copy button at the right instead.

           Both class names are listed because a message spends a moment as .sysMessage before
           ace_end.js's arrive() handler swaps it for .message -- and a PHP-rendered one
           ($session->getMessages() in header.php) is in the box from the first paint. Without
           .sysMessage here, that first frame flashes the old look. */
        #statusMessages .message,
        #statusMessages .sysMessage { 
            display: block; 
            border: 0;
            border-bottom: 1px solid #eef1f6;
            border-left: 3px solid #2b6cb0;
            border-radius: 4px;
            margin: 0;
            padding: 8px 10px 8px 12px;
            font-size: 13px;
            line-height: 1.4;
            color: #333333;
            background-color: transparent;
            font-style: normal;
            /* Room on the right for the copy button, and the text is selectable. */
            position: relative;
            padding-right: 44px;
            cursor: text;
            -webkit-user-select: text;
            user-select: text;
            transition: background-color 0.12s ease;
        }
        /* The copy button: a 28px square at the right of its own message (WCAG 2.2 2.5.8 asks 24px).
           #5f666d on white is 5.9:1, on the error tint 5.2:1; hover and focus darken it. The
           focus ring is the browser's own, kept visible for keyboard users. */
        #statusMessages .aceMsgCopy {
            position: absolute;
            top: 5px;
            right: 6px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 28px;
            height: 28px;
            margin: 0;
            padding: 0;
            float: none;
            /* The general button rule (below, ~line 1774) gives every <button> min-width 36px and a
               4px drop shadow; this one is a flat 28px square. */
            min-width: 0;
            box-shadow: none;
            text-shadow: none;
            border: 1px solid transparent;
            border-radius: 6px;
            background: transparent;
            color: #5f666d;
            font-family: Arial;
            font-size: 15px;
            line-height: 1;
            cursor: pointer;
        }
        #statusMessages .aceMsgCopy:hover,
        #statusMessages .aceMsgCopy:focus-visible {
            color: #24598f;
            background: #ffffff;
            border-color: #c8d4e4;
        }
        #statusMessages .aceMsgCopy.copied { color: #1d6b35; border-color: #b9d9c3; }
        #statusMessages .message:last-child,
        #statusMessages .sysMessage:last-child { border-bottom: 0; }
        /* The countdown line at the foot of the list. It began as a caption and is now also the
           list's one control -- clicking it clears every message -- so it carries a pointer and
           a hover state; a line that says "Click to clear" and does not respond to the pointer
           reads as broken. Still visually quiet: it reports first and offers second.

           It is a <p> rather than a div on purpose -- checkSystemMessages() counts DIVs to decide
           whether the box has anything in it, and a div here would hold an empty box open for
           ever. #767676 on white is 4.54:1, which clears WCAG 2.2 AA for normal text, and the
           hover colour is darker still. */
        #statusMessages #sysMsgCountdown {
            display: block;
            margin: 4px 0 0 0;
            padding: 6px 10px 2px 12px;
            border-top: 1px solid #eef1f6;
            text-align: center;
            font-size: 13px;
            font-style: normal;
            color: #767676;
            cursor: pointer;
            background: transparent;
        }
        #statusMessages #sysMsgCountdown:hover,
        #statusMessages #sysMsgCountdown:focus {
            color: #33475b;
            background: #eef3fa;
            text-decoration: underline;
        }
        #statusMessages .message:hover,
        #statusMessages .sysMessage:hover { background-color: #eef3fa; }
        /* Errors are RED: red text, red rail, and the warning glyph -- the glyph is there so
           the distinction is not carried by colour alone (WCAG 2.2 1.4.1). #b02121 is the red
           the New look and feel already uses for a destructive action, 6.8:1 on white and
           6.1:1 on the hover tint. Keyed on .error alone rather than .message.error so it
           lands whichever class the div is currently wearing, and so it outranks the global
           `.error` rule (#FDFFCC / red / italic), which is undone here. */
        #statusMessages .error {
            color: var(--aceError);
            border-left-color: var(--aceError);
            /* Light red ground so an error is picked out of a stack of ordinary messages at a
               glance. #fdecea is the language's error tint (the same one .msg.err and the
               duplicate report's error pill use); #b02121 on it is 6.0:1. */
            background-color: #fdecea;
            font-style: normal;
        }
        #statusMessages .error:hover { background-color: #f8dad6; }
        #statusMessages .error::before {
            /* \FE0E is VS15 -- forces the text glyph, so the warning sign does not
               arrive as a full-colour emoji on systems that have one. */
            content: "\26A0\FE0E";
            font-style: normal;
            margin-right: 6px;
            color: var(--aceError);
        }
    /* </editor-fold>*/
    
    #mainContent { 
            display: block; 
            position: absolute; 
            top: 46px; 
            left: 48px; 
            overflow: auto; 
            height: 600px; width: 100%; 
            padding: 4px; 
        }
    #background-shade, div.background-shade{ 
        width: 100%; 
        height: 100%;
        position: fixed;
        display: block;
        background-color: rgba(42, 42, 42, .8);
        top: 0; 
        left: 0;
        z-index: 20; 
    }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Pop Up Related Formats"> */

    .popped {
        background-color: var(--aceHighlight);
        float: left; 
        display: block; 
        margin: -9999px;
        /*
         * THE DEFAULT CONTENT SIZE FOR EVERY MODAL: 12px.
         *
         * Stated on .popped because .popped IS the modal -- makePop() builds this wrapper
         * around whatever a route returns, so a legacy dialog that never adopted
         * settingsPopupStyle() is covered by the same declaration as one that did.
         *
         * Nothing here stated a size until 2026-09-16, so anything a rule had not explicitly
         * named fell through to 16px, inherited from <body>. That is the BROWSER's default,
         * not a decision anybody made.
         *
         * The explicit sizes in settings_page_style.php are still needed for everything some
         * other rule NAMES -- inputs, table cells, buttons -- because an inherited value never
         * reaches an element another rule names. This sets the floor under all of them.
         */
        font-size: 13px;
        min-width: 500px; 
        position: fixed; 
        z-index: 21;
        top: 50%;
        left: 50%; 
        padding: 10px; 
        border: 6px solid #F7F7DC;
        border-radius: 15px; 
        
        -webkit-box-shadow:0 0 10px rgba(0,0,0,0.4);
        -moz-box-shadow:0 0 10px rgba(0,0,0,0.4); 
        box-shadow:0 0 10px rgba(0,0,0,0.4);
    }
    .internalPopped {
        display: block;

    }
    /* Help-topic popups (data-popclass='poppedHelp' on HLP::topicPopup's root div).
       Lighter, more modern chrome than the standard cream pop: white surface, hairline
       border, deeper shadow. Scoped to .poppedHelp so every other popup is unaffected. */
    .popped.poppedHelp {
        background-color: #FFFFFF;
        border: 1px solid #E4E8F0;
        border-radius: 14px;
        padding: 0;
        box-shadow: 0 18px 45px rgba(16, 22, 43, 0.30), 0 2px 8px rgba(16, 22, 43, 0.12);
    }
    /* Tall help topics scroll their BODY, not the whole pop, so the title bar stays put
       at the top and the scrollbar never runs up alongside it. makePop() sets
       overflow:auto inline on this div when the content doesn't fit, hence !important. */
    .popped.poppedHelp .internalPopped {
        background-color: #FFFFFF;
        border-radius: 14px;
        overflow: hidden !important;
        display: flex;
        flex-direction: column;
        min-height: 0;
    }
    .popped.poppedHelp .hlpTopicPop {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
        /* .hlpDoc (shared with the full help page) sets max-width:1100px and margin:0 auto.
           Auto side margins stop a flex child from stretching, which left the title bar
           and body sized to their content instead of filling the pop. */
        width: 100%;
        max-width: none;
        margin: 0;
    }
    /* THE POP TITLE BAR ALSO RENDERS OUTSIDE A POP.
       Every .hlpTopicPopHeader rule below is scoped under `.popped.poppedHelp`, so a block that
       is built with nlfPopWrap() and then rendered INLINE got none of them -- no ground, no ink,
       no family. SRPPL::viewInternalRelatedPeople is exactly that: it renders each related
       person's viewInternal() straight into the tab, so "Leah Condina (Parent)" was a bare <p>
       taking whatever font and colour happened to reach it -- which is where both the serif and
       the failed contrast came from.
       This base rule gives it the same identity it has in a pop (it is a card title bar either
       way). The scoped rules below still add the pop-only chrome -- the padding that clears the
       close and refresh buttons, and the corner radius -- and out-specify this one where they
       overlap. --aceAccent2Text on --aceAccent2 is the measured brand pair; the stated fallbacks
       (#333333 on #DCE6E3) are 9.91:1, well clear of WCAG 2.2 AA. */
    .hlpTopicPopHeader {
        display: flex;
        align-items: center;
        gap: 6px;
        margin: 0;
        padding: 10px 16px;
        font-family: Arial, sans-serif;
        font-size: large;
        font-weight: bold;
        /* #333333 FLAT, ASKED FOR 2026-09-09. This was --aceAccent2Text, which
           Settings::accentTextColorStrict() works out per school precisely so the ink flips
           to white on a dark brand: a title bar is 18px bold, BELOW the WCAG large-text
           threshold, so it is normal text and owes 4.5:1. A fixed dark ink cannot clear that
           on a dark bar -- entity 163's #8080A7 gives 3.35:1. Flagged; the flip is one var
           away if it has to come back. Every other title below is flattened the same way. */
        color: #333333;
        background-color: var(--aceAccent2, #DCE6E3);
        border-bottom: 1px solid #C0CECA;
        border-radius: 13px 13px 0 0;
    }
    .popped.poppedHelp .hlpTopicPopHeader { flex: 0 0 auto; }
    .popped.poppedHelp .hlpTopicPopBody   { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
    /* Shaped like a dashboard card: tinted title bar across the top, white body below. */
    .popped.poppedHelp .hlpTopicPop { padding: 0; }
    .popped.poppedHelp .hlpTopicPopHeader {
        display: flex;
        align-items: center;
        gap: 6px;
        margin: 0;
        padding: 10px 88px 10px 16px;   /* room for the close and refresh buttons */
        font-size: large;
        font-weight: bold;
        color: #333333;   /* flat title ink -- see the note above */
        background-color: var(--aceAccent2, #DCE6E3);
        border-bottom: 1px solid #C0CECA;   /* rule under the title + icon */
        border-radius: 13px 13px 0 0;
    }
    .popped.poppedHelp .hlpTopicPopHeader .bi-life-preserver { color: #333333; }
    /* The "?" help icon sitting in a title bar. Its own colour (--aceHelpMuted, #7C8697) is
       chosen against WHITE, where it clears 3:1; on the tinted bar (#DCE6E3) it falls to
       2.9:1 and fails WCAG 2.2 1.4.11. Same ink as the title solves it (9.6:1) and reads as
       part of the bar rather than as a stray link. */
    /* --- the support headset in a title bar --------------------------------------------
       THE CENTRING IS NOT HERE. SupportTicket::icon() writes `margin-left/right: auto` as an
       inline style, because this stylesheet is linked once per page load and the application
       never reloads the page -- a session that was already open when ace.css changed keeps the
       old copy, and a CSS-only rule would simply not exist for it. The note there has the full
       reasoning. What that inline pair does: the title bar is a flex row, so two auto margins
       split the leftover space evenly and drop the button in the middle of the gap between the
       end of the title and the buttons on the right.

       What IS here is the clearance from the pin, and it is geometry rather than a guess. The
       three round buttons are placed from the pop's right edge at 10 / 44 / 78px and are 28px
       wide, so the pin's left edge is 106px in. `.hasSupport` pushes the header's own content
       edge to 124px, which is what the auto margins measure against -- so even a title long
       enough to squeeze the gap to nothing still leaves 18px of air. Before a reload the older
       88px applies, which still clears the pin; the button just sits a little further right. */
    .popped.poppedHelp .hlpTopicPopHeader.hasSupport { padding-right: 124px; }
    .popped.poppedHelp .hlpTopicPopHeader a.popSupportButton {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        /* .hlpIconLink's box -- the headset sits immediately right of the help "?" and the two
           read as a pair only at the same height (2026-09-09). Also set inline by
           SupportTicket::icon() so a cached stylesheet cannot leave them mismatched. */
        width: 10px;
        height: 10px;
        border-radius: 50%;
        font-size: 10px;
        line-height: 1;
        /* #333333 flat, so every headset in the application is the same colour (asked for
           2026-09-09). It used to take --aceAccent2Text and so changed with the school's brand.
           An icon owes 3:1 under WCAG 1.4.11 rather than the 4.5:1 text owes, and #333333 clears
           that on the accent bars in use -- the darkest, entity 163's #8080A7, is 3.35:1. */
        color: #333333 !important;
        background: transparent;
        border: 1px solid transparent;
        text-decoration: none;
        cursor: pointer;
    }
    .popped.poppedHelp .hlpTopicPopHeader a.popSupportButton:hover,
    .popped.poppedHelp .hlpTopicPopHeader a.popSupportButton:focus {
        color: var(--aceHelpLink, #2B6CB0) !important;
        background: #FFFFFF;
        border-color: var(--aceCardBorder, #C0CECA);
    }
    /* Phones: the title bar is already tight and a centred button in the middle of a wrapped
       heading reads as part of the text. It goes to the end of the line instead, still clear of
       the round buttons above it. */
    @media ( max-width: 560px ) {
        .popped.poppedHelp .hlpTopicPopHeader.hasSupport { padding-right: 108px; }
        .popped.poppedHelp.aceHasRecBtns .hlpTopicPopHeader { padding-right: 124px; }
        .popped.poppedHelp.aceHasRecBtns .hlpTopicPopHeader.hasSupport { padding-right: 158px; }
        /* NOTHING HERE ANY MORE. This used to push the button to the end of the line, because
           the button was centred in the bar's free space and a centred control inside a wrapped
           heading reads as part of the text. It is not centred now -- it sits 5px after the help
           icon, hard against the title -- so on a phone it simply wraps with the words it belongs
           to, which is what is wanted. */
    }
    .popped.poppedHelp .hlpTopicPopBody { padding: 4px 16px 16px 16px; }
    .popped.poppedHelp .hlpTopicPopBody::-webkit-scrollbar { width: 10px; }
    .popped.poppedHelp .hlpTopicPopBody::-webkit-scrollbar-thumb { background-color: #C3D2CE; border-radius: 5px; border: 2px solid #FFFFFF; }
    .popped.poppedHelp .hlpTopicPopBody::-webkit-scrollbar-track { background-color: transparent; }
    /* The frame itself is shared with the full help page -- see ".hlpDoc .hlpBodyText img"
       in the Help Documentation section. Only the click-to-enlarge affordance is set
       here, because the lightbox handler is bound to the popup alone (ace_start.js).

       SCOPED TO THE ARTICLE, not to the pop. .hlpBodyText is a help topic's text and .hlpEmbed
       its embedded media (HLP::topicPopup) -- those are the only images a topic author writes.
       The transaction, comment, email and MFA modals all borrow .poppedHelp now, and the icons
       in their toolbars are CONTROLS, not illustrations: they were picking up the zoom cursor
       and opening in the lightbox.

       DO NOT go back to guarding this with `a[href]`. Icon::html() does wrap every js icon in
       an anchor, but ace_end.js line 33 strips the href off each .nojslink as soon as it
       arrives in the DOM, so the guard has already evaporated by the time anyone hovers. That
       is exactly how the toolbar icons slipped through. */
    .popped.poppedHelp .hlpTopicPopBody .hlpBodyText img,
    .popped.poppedHelp .hlpTopicPopBody .hlpEmbed img { cursor: zoom-in; }
    .popped.poppedHelp .hlpTopicPopBody .hlpBodyText a[href] img,
    .popped.poppedHelp .hlpTopicPopBody .hlpEmbed a[href] img { cursor: pointer; }   /* author linked it -- the link wins */
    .popped.poppedHelp .hlpChildList a.jsLink:hover { text-decoration: underline; }

    /* Close / refresh sit INSIDE the card, in its title bar, instead of hanging off
       the top-right corner the way the standard pop chrome places them. .popped is
       position:fixed, so it is the containing block for these. */
    .popped.poppedHelp a.poppedCloseButton,
    .popped.poppedHelp a.poppedPinButton,
    .popped.poppedHelp a.poppedWatchButton,
    .popped.poppedHelp a.poppedRefreshButton {
        position: absolute;
        top: 8px;
        float: none;
        margin: 0;
        width: 28px;
        height: 28px;
        padding: 0;
        line-height: 26px;
        text-align: center;
        font-size: 20px;
        font-weight: normal;
        color: var(--aceAccent, #57756F);
        background: transparent;
        border: 1px solid transparent;
        border-radius: 50%;
        box-shadow: none;
        z-index: 5;
    }
    .popped.poppedHelp a.poppedCloseButton   { right: 10px; }
    .popped.poppedHelp a.poppedRefreshButton { right: 44px; font-size: 18px; }
    /* Third in the row, keeping the 34px rhythm the other two are on. */
    .popped.poppedHelp a.poppedPinButton     { right: 78px; font-size: 16px; }
    .popped.poppedHelp a.poppedPinButton.acePinned { color: #a06a12; }
    /* Fourth: the watch eye, to the LEFT of the pin, same rhythm again. A filled eye when this
       record is being watched -- a different SHAPE as well as a different colour, so it does not
       depend on anyone telling the two greens apart.

       IT MUST ALSO BE IN THE SHARED BLOCK ABOVE. This `right` offset does nothing on its own:
       without `position: absolute` the anchor stays in the normal flow, and since the JS
       prepends it to .popped it lands at the top-left of the dialog and shoves the title bar
       sideways. That is what "the whole title bar is wonky" was. */
    .popped.poppedHelp a.poppedWatchButton   { right: 112px; font-size: 16px; }
    /* Only a RECORD modal carries the pin and the watch eye, and only there does the title bar
       need to keep clear of four buttons rather than two. ace_pinnedRecords.js stamps the class
       on the pop at the moment it adds them, so the reservation follows the buttons instead of
       costing every other dialog 52px of its title. */
    .popped.poppedHelp.aceHasRecBtns .hlpTopicPopHeader { padding-right: 140px; }
    .popped.poppedHelp.aceHasRecBtns .hlpTopicPopHeader.hasSupport { padding-right: 174px; }
    .popped.poppedHelp a.poppedWatchButton.aceWatching { color: #2b6cb0; }
    .popped.poppedHelp a.poppedCloseButton:hover,
    .popped.poppedHelp a.poppedPinButton:hover,
    .popped.poppedHelp a.poppedWatchButton:hover,
    .popped.poppedHelp a.poppedRefreshButton:hover {
        color: #333333;
        background: var(--aceCardDivider);
        border-color: var(--aceCardBorder);
    }
    /* Phones.
       These buttons are pinned to the TOP of the pop (top: 8px), which only lands them in the
       middle of the title bar while that bar is about 44px tall. `font-size: large` is 18px, and
       on a ~370px-wide card with 88px reserved for the buttons a longer heading -- "Updating Your
       CharterAce Password" -- wraps to two lines, the bar grows to ~70px, and the buttons are
       left floating near its top edge. Smaller type keeps most headings on one line; min-height
       fixes the geometry when one still wraps, and flex-start keeps the first line of a wrapped
       title level with the buttons instead of pushing them off-centre.

       text-size-adjust is stated because iOS inflates text in some layouts, which would make the
       bar taller again and undo the above. */
    @media ( max-width: 560px ) {
        .popped.poppedHelp { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
        .popped.poppedHelp .hlpTopicPopHeader {
            box-sizing: border-box;
            min-height: 44px;
            align-items: flex-start;
            padding-top: 9px;
            padding-bottom: 9px;
            font-size: 15px;
            line-height: 1.3;
        }
    }
    a.poppedCloseButton { 
        float:right;
        margin-top:-30px;
        margin-right:-30px;
        cursor:pointer;
        color: #fff;
        border: 1px solid #AEAEAE;
        border-radius: 30px;
        background: #605F61;
        font-size: 31px;
        font-weight: bold;
        display: inline-block;
        line-height: 0px;
        padding: 11px 3px;       
    }
    .poppedCloseButton:before {
        content: "×";
    }
    a.poppedRefreshButton{
        float:right;
        margin-top:-30px;
        margin-right:0;
        cursor:pointer;
        color: #fff;
        border: 1px solid #AEAEAE;
        border-radius: 30px;
        background: #605F61;
        font-size: 25px;
        font-weight: bold;
        display: inline-block;
        line-height: 0px;
        padding: 11px 3px;        
    }
    .poppedRefreshButton:before{
        content: "↺"; 
    }
    /* Pin sits to the LEFT of the refresh arrow. Close hangs 30px off the right edge and
       refresh sits flush at 0, so each further button steps another 30px inward. */
    a.poppedPinButton{
        float:right;
        margin-top:-30px;
        margin-right:30px;
        cursor:pointer;
        color: #fff;
        border: 1px solid #AEAEAE;
        border-radius: 30px;
        background: #605F61;
        font-size: 19px;
        font-weight: bold;
        display: inline-block;
        line-height: 0px;
        padding: 11px 5px;
    }
    a.poppedPinButton.acePinned { background: #a06a12; }

    /* Lightbox for help-topic images (opened by aceLightboxOpen in ace_start.js).
       z-index sits above the popup stack, whose boxes start at 20 and step by 2. */
    .aceLightbox {
        position: fixed;
        top: 0; left: 0; right: 0; bottom: 0;
        z-index: 3000;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        padding: 40px;
        background-color: rgba(16, 22, 43, 0.86);
        cursor: zoom-out;
    }
    .aceLightbox img {
        max-width: 92vw;
        max-height: 84vh;
        padding: 0;
        background-color: #FFFFFF;
        border: 3px solid #FFFFFF;
        border-radius: 8px;
        box-shadow: 0 20px 60px rgba(0,0,0,0.55);
    }
    .aceLightboxCaption {
        max-width: 80vw;
        margin-top: 12px;
        color: #E8EDF2;
        font-size: small;
        text-align: center;
    }
    .aceLightboxClose {
        position: absolute;
        top: 16px;
        right: 24px;
        color: #FFFFFF;
        font-size: 34px;
        line-height: 1;
        font-weight: bold;
        opacity: 0.85;
        cursor: pointer;
    }
    .aceLightboxClose:before { content: "\00d7"; }
    .aceLightboxClose:hover { opacity: 1; }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Form Formats"> */ 
    .form { 
        width: 960px; 
        max-width: 100%; 
        display: block; 
        margin: auto; 
        padding: 5px; 
    }
    .form h2 { text-align: center; display: block; margin: auto; }
    .form_default { 
        background-color: var(--aceSurface); 
        border-radius: 15px;
        border: 5px solid var(--aceBorder); 
        box-shadow: 4px 4px 2px var(--aceShadow);
    }
    /* <editor-fold defaultstate="collapsed" desc="Form Widths"> */ 
        .form span.fm { display: block; float: left; margin: 0 15px 0 0; min-height: 57px; }
        .form_w1 { max-width: 320px; padding: 15px 0 15px 15px; min-height: 57px; }
        .form_w2 { max-width: 640px; padding: 15px 0 15px 15px; min-height: 57px; }
        .form_w3 { max-width: 960px; padding: 15px 0 15px 15px; min-height: 57px; }
        /* <editor-fold defaultstate="collapsed" desc="1 Column Options"> */ 
        span.w11 { width: 290px; }
        .w11 input , .w11 textarea, .w11 select, .w13 .formResponse { width: 282px; }
        .w11 fieldset { width: 276px; }
        .w11 fieldset input, .w11 fieldset textarea, .w11 fieldset select, .w11 fieldset span.formResponse { width: 263px; }
        .w11 fieldset fieldset { width: 257px; }
        .w11 fieldset fieldset input, .w11 fieldset fieldset textarea, .w11 fieldset fieldset select, .w11 fieldset fieldset span.formResponse { width: 244px; }
        /* </editor-fold>*/
        /* <editor-fold defaultstate="collapsed" desc="2 Column Options"> */ 
        span.w12 { width: 297px; }
        .w12 input, .w12 textarea , .w12 select, .w12 .formResponse { width: 278px; }
        .w12 fieldset { width: 285px; }
        .w12 fieldset input, .w12 fieldset textarea, .w12 fieldset select { width: 272px; }
        .w12 fielset fieldset { width: 266px; }
        .w12 fieldset fieldset input, .w12 fieldsett fieldset textarea, .w12 fieldset fieldset select, .w12 fieldset fieldset span.formResponse { width: 253px; }

        span.w22 { width: 610px; }
        .w22 input, .w22 textarea , .w22 select, .w22 .formResponse { width: 591px; }
        .w22 fieldset { width: 591px; }
        .w22 fieldset input, .w22 fieldset textarea, .w22 fieldset select { width: 578px; }
        .w22 fielset fieldset { width: 572px; }
        .w22 fieldset fieldset input, .w22 fieldsett fieldset textarea, .w22 fieldset fieldset select, .w22 fieldset fieldset span.formResponse { width: 559px; }

        /* </editor-fold>*/
        /* <editor-fold defaultstate="collapsed" desc="3 Column Options"> */ 
        .form span.w13 { width: 300px; }
        .w13 input , .w13 textarea, .w13 select , .w13 .formResponse { width: 292px; }
        .w13 fieldset { width: 286px; }
        .w13 fieldset input , .w13 fieldset textarea , .w13 fieldset select , .w13 fieldset span.formResponse { width: 273px; }
        .w13 fieldset fieldset { width: 245px; }
        .w13 fieldset fieldset input, .w13 fieldset fieldset textarea, .w13 fieldset fieldset select, .w13 fieldset fieldset span.formResponse { width: 254px; } 

        .form span.w23 { width: 615px; }
        .w23 input , .w23 textarea , .w23 select , .w23 span.formResponse { width: 607px; }
        .w23 fieldest { width: 601px; }
        .w23 fieldset input , .w23 fieldset textarea , .w23 fieldset select , .w23 fieldset span.formResponse { width: 588px; }
        .w23 fieldset fieldset { width: 582px; }
        .w23 fieldset fieldset input, .w23 fieldset fieldset textarea, .w23 fieldset fieldset select, .w23 fieldset fieldset span.formResponse { width: 569px; } 

        .form span.w33 { width: 930px; }
        .w33 input , .w33 textarea , .w33 select , .w33 span.formResponse { width: 922px; }
        .w33 fieldset { width: 916px; }
        .w33 fieldset input , .w33 fieldset textarea , .w33 fieldset select , .w33 fieldset span formResponse { width: 903px; }
        .w33 fieldset fieldset { width: 897px; }
        .w33 fieldset fieldset input, .w33 fieldset fieldset textarea, .w33 fieldset fieldset select, .w33 fieldset fieldset span.formResponse { width: 884px; } 

        /* </editor-fold>*/
        /* <editor-fold defaultstate="collapsed" desc="4 Column Options"> */ 
        .form w14 { max-width: 240px; }
        .form w24 { max-width: 470px; }
        .form w34 { max-width: 700px; }
        .form w44 { max-width: 960px; } 

        span.w14 { width: 221px;}
        .w14 input , .w14 textarea , .w14 select , .w14 span.formResponse { width: 215px; }
        .w14 fieldset { width: 207px; }
        .w14 fieldset input , .w14 fieldset textarea , .w14 fieldset select , .w14 fieldset span.formResponse  { width: 194px; } 
        .w14 fieldset fieldset { width: 185px; }
        .w14 fielsdset fieldset input , .w14 fielsdset fieldset textarea , .w14 fielsdset fieldset select , .w14 fielsdset fieldset span.formResponse  { width: 172px; } 

        span.w24 { width: 457px;}
        .w24 input , .w24 textarea , .w24 select , .w24 span.formResponse { width: 451px; }
        .w24 fieldset { width: 443px; }
        .w24 fieldset input , .w24 fieldset textarea , .w24 fieldset select , .w24 fieldset span.formResponse  { width: 430px; } 
        .w24 fieldset fieldset { width: 424px; }
        .w24 fielsdset fieldset input , .w14 fielsdset fieldset textarea , .w14 fielsdset fieldset select , .w14 fielsdset fieldset span.formResponse  { width: 411px; } 

        span.w34 { width: 693px;}
        .w34 input , .w34 textarea , .w34 select , .w34 span.formResponse { width: 687px; }
        .w34 fieldset { width: 679px; }
        .w34 fieldset input , .w34 fieldset textarea , .w34 fieldset select , .w34 fieldset span.formResponse  { width: 666px; } 
        .w34 fieldset fieldset { width: 660px; }
        .w34 fielsdset fieldset input , .w14 fielsdset fieldset textarea , .w14 fielsdset fieldset select , .w14 fielsdset fieldset span.formResponse  { width: 647px; } 

        span.w44 { width: 929px;}
        .w44 input , .w44 textarea , .w44 select, .w44 span.formResponse { width: 923px; }
        .w44 fieldset { width: 915px; }
        .w44 fieldset input , .w44 fieldset textarea , .w44 fieldset select, .w44 fieldset span.formResponse { width: 902px; } 
        .w44 fieldset fieldset { width: 896px; }
        .w44 fielsdset fieldset input , .w14 fielsdset fieldset textarea , .w14 fielsdset fieldset select , .w14 fielsdset fieldset span.formResponse  { width: 883px; } 
        /* </editor-fold>*/
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="General Format For Form Objects Not In a Specific Form Type"> */ 
        button, input[type=submit], input[type=button], .button  { 
            display: block; 
            float: left; 
            width: auto; 
            min-width: 36px; 
            margin: 10px 10px 5px 0; 
            padding: 2px; 
            box-shadow: 4px 4px 2px var(--aceShadow); 
            border: 1px solid var(--aceBorder); 
            border-radius: 5px; 

        }
        input[type=radio] + label, input[type=checkbox] + label { 
            display: block; 
            float: left; 
        }

    /* </editor-fold>*/   
    /* <editor-fold defaultstate="collapsed" desc="Form DIV Setup"> */ 
        /* <editor-fold defaultstate="collapsed" desc="Quesion"> */     
            .form label { 
                font-weight: bold; 

            }
            .form input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]), .form textarea, .form select, span.formResponse {
                display: block;
                margin: -3px 0px 12px 4px; 
                padding: 2px; 
                font-size: large; 
                width: 100%; 
                box-sizing: border-box;
                border-radius: 5px;    
            }
            /* FOCUS MUST NOT RESIZE THE FIELD. This used to set `border: solid 2px` alongside
               the glow, so a field GREW by 2px the moment it was clicked into and nudged its whole
               row -- most visible on a form with several fields on one line. An outline is drawn
               OUTSIDE the box and takes no space in the layout, so it marks focus without moving
               anything. The drop shadow goes with it (asked for 2026-09-17); the outline is what
               keeps focus visible, which WCAG 2.2 SC 2.4.7 requires. The cream background stays --
               it is a second, non-geometric cue. Border is deliberately NOT declared here, so the
               field keeps whatever resting border its own block gave it. */
            .form input:not([type=checkbox]):not([type=radio]):focus, .form textarea:focus { box-shadow: none; background-color: #FEFEF3; outline: 2px solid var(--aceBrand); outline-offset: 1px; }
            
            
            .form .fm button, .form .fm input[type=submit], .form .fm input[type=button], .form .fm .button {
                float: none; 
                margin: auto; 
            }
            .form input[type=radio], .form input[type=checkbox], .entry_form input[type=radio], .entry_form input[type=checkbox] { 
                display: block;
                float: left;
                width: 30px; 
                clear: both; 
            }
            .form input[type=radio]:checked + label, .form input[type=checkbox]:checked + label { 
                background-color: #cc7829;
            }
            .fm fieldset { 
                border-radius: 10px; 
                border: 1px solid var(--aceBorder); 
            }

        /* </editor-fold>*/

        /* <editor-fold defaultstate="collapsed" desc="Placeholder Format"> */ 
            ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
                color: var(--aceDebug);
            }
            ::-moz-placeholder { /* Firefox 19+ */
                color: var(--aceDebug);
            }
            :-ms-input-placeholder { /* IE 10+ */
                color: var(--aceDebug);
            }
            :-moz-placeholder { /* Firefox 18- */
                color: var(--aceDebug);
            }
        /* </editor-fold>*/
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="entry_form Table Formats"> */ 
        .entry_form { 
            border-collapse: collapse; 
            border: 1px solid black; 
            width: 100%;
            background-color: var(--aceSurface);
            table-layout: fixed; 
            clear: both; 
        }
        .entry_form th { 
            text-transform: uppercase; 
            font-size: 12px; 
            text-align: left; 
            border-top: 1px solid black; 
            padding: 1px 0 0 4px; 
            font-family: Arial, sans-serif;
        }
        .entry_form td { 
            border-bottom: 1px solid black; 
            padding: 0 25px 8px 4px;
        }
        .entry_form input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]), .entry_form select, .entry_form textarea {
            width: 100%;
            border-radius: 6px;
            border-style: inset;
        }
        .entry_form button, .entry_form input[type=submit], .entry_form input[type=button], .entry_form .button {
            float: none; 
            margin: auto; 
        }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="list_form Table Formats"> */ 

        table.list_form { 
            width: 95%;
            margin: 5px auto 5px auto; 
            border-collapse: collapse; 
            border: none; 
            display: block;
        }
        table.list_form th.set { 
            background-color: var(--aceGold); 
            font-weight: bold; 
            text-align: left; 
        }
        table.list_form th { 
            font-weight: bold;
            text-align: right; 
            border-bottom: 1px solid #ffc6c6; 
        }
        table.list_form td { 
            border-bottom: 1px solid #ffc6c6; 
            max-width: 306px; 
            padding-left: 10px; 
        }
        /* A list form with no rules between its fields. Opt-in via Form::$table_class, because
           most list forms want the separators -- they are what keeps a long two-column list
           readable. On a short form they only add noise. */
        table.list_form.noFieldRules th,
        table.list_form.noFieldRules td { border-bottom: 0; }
        table.list_form fieldset { 
            min-width: 300px; 
            margin: 0; 
            padding: 3px;
            border: 0px transparent; 
        }
        table.list_form input:not([type=radio]):not([type=checkbox]):not([type=submit]):not([type=button]), table.list_form textarea, table.list_form select, span.formResponse {
            font-family: Arial, sans-serif;
            max-width: 100%; 
            width: 80%; 
        }
        table.list_form input[type=radio], table.list_form input[type=checkbox] { 
            display: block;
            float: left;
            width: 30px; 
            clear: both; 
        }


    
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="form_table Formats"> */ 
    .form_table { 
        table-layout: auto; 
        width: 100%;
        margin: auto 5px; 
    }
    .form_table tr { 
        height: 30px; 
        width: 100%; 
    }
    .form_table td { 
        vertical-align: top; 
        padding: 3px; 
    }
    .form_table input { 
        margin: auto; 
        display: block; 
        float: left; 
    }
    .form_table img { 
        margin: 2px; 
    }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Mini Instant Form Settings"> */ 
    div.miniInstantForm label { 
        float: left; 
        clear: both; 
        font-weight: bold; 
        margin: 0 6px 3px 1px; 
    }
    div.miniInstantForm input, div.miniInstantForm textarea {
        display: block; 
        float: right; 
        width: 75%; 
        margin: 0 2px 3px 2px; 
    }
    div.miniInstantForm span { 
        display: block; 
        clear: right; 
        margin: 0 0 3px 0; 
    }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Mini Instant Form Settings"> */ 
    .form .switch { 
        position: relative;
        display: inline-block;
        width: 60px;
        height: 34px;
      }

    .form .switch input { 
        opacity: 0;
        width: 0;
        height: 0;
      }

    .form .slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #ccc;
        -webkit-transition: .4s;
        transition: .4s;
      }

    .form .slider:before {
        position: absolute;
        content: "";
        height: 26px;
        width: 26px;
        left: 4px;
        bottom: 4px;
        background-color: white;
        -webkit-transition: .4s;
        transition: .4s;
      }

    .form input:checked + .slider {
        background-color: #2196F3;
      }

    .form input:focus + .slider {
        box-shadow: 0 0 1px #2196F3;
      }

    .form input:checked + .slider:before {
        -webkit-transform: translateX(26px);
        -ms-transform: translateX(26px);
        transform: translateX(26px);
      }

      /* Rounded sliders */
    .form .slider.round {
        border-radius: 34px;
      }

    .form .slider.round:before {
        border-radius: 50%;
      }
    .form .sliderLabel { display:table-cell; min-height: 34px; vertical-align: middle; padding-left: 5px; }
    .form .switchContainer { display: table-cell; vertical-align: middle; }
    /* </editor-fold>*/
    
    /* <editor-fold defaultstate="collapsed" desc="basicForm settings"> */ 
        div.basicForm  { background-color: var(--aceSurface); display: block; margin: 0 auto; min-width: 200px; max-width: 600px; width: 100%; border: solid 1px var(--aceBorder); border-radius: 6px; padding: 10px; box-shadow:4px 4px 2px var(--aceShadow); }
    
        div.basicForm label{ display: block; margin-top: 15px; }
        div.basicForm .checks label { margin-top: 0; }

        div.basicForm input { padding: 4px; border: solid 1px #999; }
        div.basicForm input[type="email"], div.basicForm input[type="text"] { width: 90%; }
        div.basicForm textarea{ height: 125px; width: 90%; padding: 5px; border: solid 1px #999 }

        div.basicForm .checks { margin-bottom: 15px; }
        div.basicForm .checks p { margin-bottom: 0; }

        div.basicForm input { font-size: large; border-radius: 3px; }
        div.basicForm input[type="checkbox"] + label, div.basicForm input[type="radio"] + label { display: inline-block; padding-top: 0; margin-top: 0; margin-left: 2px; }
        div.basicForm input[type="radio"] { margin-left: 25px; margin-right: 0; display: inline-block; float: left; width: auto; }
        div.basicForm input[type="checkbox"] { display: inline-block; float: left; margin-left: 0; clear: both; width: auto; }
        div.basicForm input[type="radio"]:first-of-type { margin-left: 0; }
        /* Shadow dropped to match the rule above. This one already used an outline, so it never
           had the resizing problem. */
        div.basicForm input:focus, div.basicForm textarea:focus { outline: solid 2px var(--aceInk); box-shadow: none; background-color: #FEFEF3;  }

        div.basicForm select { font-size: large; min-width: 45%; max-width: 90%; } 
    
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="info_form"> */ 

    
        .info_form { width: 100%; display: block; }
        .info_form.alternate .row:nth-child(even) { background: var(--aceSurface); }
        .info_form .row { width: 100%; display: block; clear: both; padding: 6px 0; border-top: 2px solid #afe3d9; }
        .info_form .row:first-child { border-top: none; }
        .info_form .left { width: 25%; display: block; float: left; clear: both; padding: 6px 0; }
        .info_form .right { width: 74%; display: block; float: right; padding: 6px 0; font-size: large; font-family: Arial, sans-serif; }
        .info_form .left label { display:block; float: right; clear: both; font-weight: bold; font-size: large; padding: 3px 0 0 0; text-align: right; }
        .info_form .info { font-style: italic; font-size: small; clear: both; display: block; float:right; text-align: right; }
        .info_form input:not([type=checkbox]):not([type=radio]), .info_form textarea { display: block;                 padding: 2px; 
                                                font-size: large;               font-family: Arial, sans-serif; 
                                                width: 98%; 
                                                align-content: box-sizing;      border-radius: 5px; 
                                                border-width: 2px;              border-style: inset; 
                                                border-color: initial;          border-image: initial; 
                                            }
        

        .info_form input[type=radio], .info_form input[type=checkbox] { display: block; float: left; clear: both; margin: 6px; }
        .info_form input[type=radio]+label, .info_form input[type=checkbox]+label { display: block; float: left; clear: none; font-weight: bold; }
        .info_form fieldset { border: 0px transparent; }
        .info_form select { min-width: 40%; font-size: large; font-family: Arial, sans-serif; }

    /* </editor-fold>*/
    
    .buttonBox { display: block; float: left; margin: 2px 5px; border-radius: 8px; border: 1px black solid; background-color: var(--aceHighlight); padding: 4px;  }
    .buttonBox .label { display: block; width: 100%; text-align: center; font-weight: bold; font-size: large; }
    .makeMeRichTextarea { height: 310px; }
/* </editor-fold>*/



div.purchaseOrder .poTerms input[type="radio"] { clear: both; display: block; float: left; width: auto; margin-right: 5px;  }
div.purchaseOrder .poTerms input[type="radio"] + label { clear: none; }
.transaction input[type='radio'] { clear: both; display: block; float: left; width: auto; margin-right: 5px;  }
.transaction input[type='radio'] + lael { clear: none; }

.zsiq_float1, .zsiq_custombtn, #zsiqwidget, #liveSupportIcon { z-index: 0 !important; }



/* <editor-fold defaultstate="collapsed" desc="Reoccuring Objects"> */ 
.reoccureform .fslabel { float: none; font-size: large; background-color: var(--aceHelpLink); color: var(--aceGold); font-weight: bold; padding: 0 5px 0 5px; border: 1px solid black; border-radius: 10px 10px 0px 0px; margin: 10px 0 0 0; border-bottom: 0px; }
.reoccureform fieldset { border-radius: 0 0px 10px 10px;
    padding: 5px 5px 5px 5px;
    margin: 0;
    border: 2px solid var(--aceInkDeep);
    max-width: 100%;
    display: block; 
}
.reoccureform span.w13 { float: left; margin: 5px 10px 0 0;  }
.reoccureform th { width: 35px; }
.reoccureform td { width: 35px; }
/* </editor-fold>*/

/* <editor-fold defaultstate="collapsed" desc="General CharterAce Specific Options"> */ 
.actCode, .acctCode { font-weight: bold; }
.actDesc, .acctDesc { font-style: italic; font-size: small; }
.actSelTreeSelected, .actSelTreeSelected:checked { font-weight: bold; color: var(--aceInk); background-color: var(--aceHighlight); margin: 3px 0 3px 0; border: 1px  dashed yellow; }
.actSelTreeParent { font-weight: bold; color: var(--aceInk); background-color: var(--aceHighlight); }
div.pplContactInfo { display: block; float: left; margin: 5px auto; border: 2px solid black; border-radius: 10px; padding: 0 8px 5px 8px; background-color: var(--aceHighlight); clear: both;   }
.switch-wrapper { display: inline-block; position: relative; top: 3px; }
div.searchResultBox { min-width: 1000px; min-height: 200px; border: 1px solid black; }
.actionBox400 { display: block; width: 400px; margin: 8px auto; padding: 4px; border: 2px solid black; border-radius: 5px; background-color: var(--aceMint); text-align: center; }
.actionBox500 { display: block; width: 500px; margin: 8px auto; padding: 4px; border: 2px solid black; border-radius: 5px; background-color: var(--aceMint); text-align: center; }

.selectionBox { display: block; border: 1px solid black; border-radius: 10px; background-color: var(--aceMint); padding: 5px 30px 10px 30px; text-align: center; min-height: 25px; margin: 20px auto; width: fit-content;}
.selectionBox:after { content:''; display: block; clear:both; }
.selectionBox h3 { margin: 2px auto 5px auto; }
.selectionBox button { margin: 0px 15px; border: 1px solid var(--aceInk); box-shadow: 2px 2px 2px #888080; padding: 3px 6px; display: inline-block; float: none; }
.selectionBox .option:first-of-class { margin: 0px 15px 0px 0px; }
.selectionBox .option:last-of-class { margin: 0px 0px 0px 15px; }
.selectionBox .selected { margin: 0px 15px; border: 1px solid var(--aceInk); box-shadow: none; padding: 3px 6px; display: inline-block; float: none; background-color: var(--aceHighlight); border-radius: 5px; }

    
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Messages or Emails"> */ 
    .msgMessage { border: solid 2px black; border-radius: 10px; background-color: var(--aceSurface); padding: 0 0 5px 0; }
    .msgMessage hr { height: 4px; width: 100%; background-color: black; }
    .msgMessage .info { margin: 5px; list-style-type: none; padding: 0; }
    .msgMessage .info .label { display: block; text-align: right; float: left; width: 82px; padding: 0 4px 0 0; font-weight: bold; clear: both; }
    .msgMessage .body { margin: 10px; display: block; height: 325px; overflow-y: auto;  } 

    .systemNews { border: 1px solid black; border-radius: 15px; padding: 8px; width: 450px; display: block; margin: auto; background-color: white;  }
    .systemNews .top { background-color: var(--aceMint); display: block; width: 100%; border-radius: 15px 15px 0 0; margin: -8px -8px 0 -8px; padding: 8px; }
    .systemNews hr { margin: 0 -7px; }

/* </editor-fold>*/   
/* <editor-fold defaultstate="collapsed" desc="Preview File Display"> */ 
/* ONE SIZE FOR EVERY TOOL ICON: 25x25 (asked for 2026-09-16).
   An icon in this application is an <img class='actionButton'> and nothing else, and until now
   its size came ENTIRELY from height=/width= attributes written at each call site. Surveyed
   before writing this: 25 is what most of them already say (60 call sites), but 40 appears 17
   times and 30, 35, 20 and 45 appear as well -- so the same row of controls was a different
   size depending on which screen you were looking at.

   !important because the size arrives as an ATTRIBUTE, and an attribute on the element is what
   a plain stylesheet rule loses to in exactly the cases that need fixing. Icon::SIZE stays at 25
   so the markup and the stylesheet agree rather than one silently overriding the other.

   25px clears the 24px pointer-target floor (WCAG 2.2 2.5.8) with one pixel to spare, which is
   why the number is 25 and not 24 or 20.

   NOTE: this catches the LARGE toolbar icons too -- the row at the foot of a purchase order and
   a transaction asked for 45 and 40. They are tool icons and the instruction was "all", so they
   come down with the rest; if those should stay large they need a class of their own rather than
   an exception written here. */
.actionButton, img.actionButton { width: 25px !important; height: 25px !important; }

    /* 12px, the application's content size (asked for 2026-09-16). #filPreview is the
       transaction-processing preview -- P294AF8 and its siblings -- and it is positioned
       absolutely over the whole of #mainContent, so it sits OUTSIDE .settingsPage and never
       inherited the 12px that wrapper states. It was rendering at the browser's 16px against
       a 12px application. Stated on the container so everything inside follows; the table
       cells are named separately below because ace.css sizes .dataTable cells at 14px with a
       rule this one cannot outrank on its own. */
    #filPreview { display: block; float: left; position: absolute; top: 0; left: 0; height: 98%; width: 98%; font-size: 13px; }
    /* Named element by element, because inheritance loses to any rule that names one -- and this
       screen is full of them: .venInfoLbl, .venInfoCSZ and .clickableEditNow all carried
       `font-size: small` (13px) from their own class rules, and a <button> starts from the
       browser's 13.33px default. Each of these selectors is (1,0,1), enough to settle it.
       HEADINGS ARE NOT IN THIS LIST: #filPreview h1/h2/h3 keep their own sizes below, which is
       what makes a heading read as one. */
    #filPreview p, #filPreview li, #filPreview label, #filPreview td, #filPreview th,
    #filPreview span, #filPreview div, #filPreview a, #filPreview button,
    #filPreview small, #filPreview em, #filPreview strong, #filPreview b,
    #filPreview input, #filPreview select, #filPreview textarea { font-size: 13px; }
    #filPreview table.dataTable th, #filPreview table.dataTable td,
    #filPreview table.dataTable thead th, #filPreview table.dataTable tbody td,
    #filPreview .results_table th, #filPreview .results_table td,
    #filPreview .brief_table th, #filPreview .brief_table td { font-size: 13px; }
    /* Headings keep their own sizes -- a card with no heading is not the ask. */
    #filPreview h1 { font-size: 18px; }
    #filPreview h2 { font-size: 16px; }
    #filPreview h3 { font-size: 13px; }
    #filPreview #gotoPrevious { display: block; float: left; position: absolute; left: 0; width: 41px; z-index: 12; }
    #filPreview #gotoNext { display: block; float: right; position: absolute; right: 15px; width: 41px; z-index: 12;  }
    /* 50/50 (2026-09-17). These two used to be 55% and 35% -- which do not add up, and did not
       agree with the .55 the sizing script applied a moment later. They are the FIRST PAINT only:
       PreviewDisplay::buildScript() immediately applies the person's remembered split. Keeping
       them equal means the flash before that runs is the default rather than a third layout. */
    /* box-sizing: border-box is what makes 50% + 50% actually MEET. These carry 50px of
       horizontal padding, so under the default content-box a 50% pane painted 50px wider than
       half and the two overlapped by 100px in the middle -- and every width the sizing script
       set was out by the same 50px. */
    #filPreview #preview { display: block; float: left; position: absolute; width: 50%; top: 0; left: 0; height: 95%; z-index: 10; padding: 5px 5px 5px 45px; box-sizing: border-box; }
    #filPreview #details { display: block; float: right; position: absolute; width: 50%; top:0; right: 0; height: 95%; z-index: 10; padding: 5px 5px 5px 45px; overflow-y: auto; box-sizing: border-box; }
    /* The drag handle between them. A 9px grab strip with a 1px rule drawn down the middle, so it
       is easy to hit (WCAG 2.2 2.5.8 wants 24px, which the full-height strip clears on the axis
       that matters) without looking like a 9px border. */
    #filPreview #filPreviewSplit {
        position: absolute; top: 0; bottom: 0; width: 9px; margin-left: -4px;
        z-index: 13; cursor: col-resize; background: transparent;
        display: flex; align-items: stretch; justify-content: center;
    }
    /* 3px and #8c8c8c at rest, not 1px of the card divider: at 1px in a near-white grey it read
       as an incidental hairline rather than something you could take hold of, and nothing else on
       the screen says the panes are adjustable. #8c8c8c is the same grey the field borders use --
       3.4:1 on white, past WCAG 2.2 1.4.11's 3:1 for the boundary of a control. */
    #filPreview #filPreviewSplit span { display: block; width: 3px; border-radius: 2px; background: #8c8c8c; }
    #filPreview #filPreviewSplit:hover span,
    #filPreview #filPreviewSplit.dragging span { width: 5px; background: #2b6cb0; }
    #filPreview #filPreviewSplit:focus-visible { outline: 2px solid #2b6cb0; outline-offset: -2px; }
    /* THE FIELDS, to the application standard. #filPreview is NOT inside .settingsPage or
       .settingsPopup -- the previewer is returned bare, so none of settingsPageStyle()'s control
       rules reach it and its inputs were 20px with the browser's own 2px border and square
       corners. Same exclusion list, same values, same list-box guard as the shared rule. */
    #filPreview input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=reset]):not([type=file]):not([type=image]):not([type=hidden]),
    #filPreview select,
    #filPreview textarea {
        border: 1px solid #8c8c8c;
        border-radius: 6px;
        padding: 5px 7px;
        font-size: 13px;
        /* Arial, stated: controls do not inherit font-family, and ace.css:2737 hands
           .transaction .invDetails input a Verdana stack that reached these. */
        font-family: Arial, sans-serif;
        box-sizing: border-box;
    }
    #filPreview input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=reset]):not([type=file]):not([type=image]):not([type=hidden]),
    #filPreview select:not([size]):not([multiple]) { height: 28px; }

    #filPreview #fileSelector { display: none; float: left; position: absolute; left: 0; bottom: 0; margin: 5px; z-index: 14; border: 2px solid black; border-radius: 5px; padding: 5px; background-color: white; }
    #filPreview #fileSelector p, #filPreview #listSelector p { text-align: center; width: 100%; display: block; margin: 1px auto; }
    #filPreview #listSelector { display: none; float: left; position: absolute; left: 0; bottom: 45px; margin: 5px; z-index: 14; border: 2px solid black; border-radius: 5px; padding: 5px; background-color: white; }
    #filPreview #leftToolbar { display: block; float: left; position: absolute; left: 0; bottom: 0; width: 42px; z-index: 12; }
    #filPreview #bottomToolbar { display: block; float: right; position: absolute; right: 0; bottom: 0; width: 35%; height: 48px; z-index: 12; }
    /* 12px, the application's content size. This said `large` -- 18px -- which made the details
       pane the only part of the screen not at the content size, and beat the 12px rule above it
       because an #id#id selector outranks #id+element. */
    #filPreview #details { font-size: 13px; font-family: Arial, sans-serif; }
    /* A top margin, so the Transaction Type / Invoice Number / Invoice Date / Due On row is not
       jammed against the Description above it. These float, so the margin is on the blocks
       themselves rather than on a wrapper -- there isn't one; the row is just a run of siblings
       between two clearfixes. Any later row of blocks gets the same gap, which is what you want
       when the custom fields (Processing Batch, Pay On, Pay Date) wrap onto a second line. */
    #filPreview #details .blocks { display: block; float: left; margin: 14px 10px 0 10px; padding: 0 10px 0 0; border-right: 1px solid var(--aceBrand); }
    #filPreview #details .processingComments { display: block; margin: 3px; padding: 6px; border: 2px solid black; border-radius: 5px; background-color: #FF9D9D; }
    #filPreview #details .processingComments ul { margin: 0px; font-size: 13px; padding-inline-start: 15px; }
    #filPreview #details label { display: block; clear: both; font-size: 13px; color: var(--aceBorder); margin: 5px 0 0 0; }
    /* THE BLANK LINE UNDER "Invoice Number:" AND "Invoice Date:".
       TRA::display() emits those two as `<label>…</label><BR>value`, and the rule above already
       makes the label display:block -- so the label ends the line and the <BR> then ends it
       again, leaving an empty one. The <BR> is NOT removed from the PHP: on the transaction view
       `.transaction .invDetails label` is `float: left`, where that <BR> is the only thing
       clearing the float. It is dropped here, where the label is a block and it is redundant. */
    #filPreview #details .invDetails br { display: none; }
    #filPreview #details div.amtLine { display: block; width: 100%; margin: 5px 0 0 0; border-bottom: 1px solid var(--aceBrand); padding: 2px 0 6px 0; }
    /* THE CODE SITS ON THE SAME LINE AS "Actg Code:". The label is an inline <strong>, but what
       follows it is the COA display, which renders as a block and so pushed itself onto the next
       line. A flex row with the label first puts them back together; align-items keeps them on a
       shared baseline when the code wraps to two lines, and the gap is the space the old inline
       label used to get from the text node after it. */
    #filPreview #details div.coaCodesBlock {
        display: flex;
        flex-wrap: wrap;
        /* flex-start, NOT baseline. What follows the label is the account SELECTOR -- a block
           over 100px tall -- and baseline alignment lines the label up with that block's first
           text baseline, which sits 90px down it. flex-start puts the two tops level, which is
           what "on the same line" means here. */
        align-items: flex-start;
        gap: 6px;
        float: left;
    }
    #filPreview #details div.coaCodesBlock > .amtLbl { flex: 0 0 auto; }
    /* Right-aligned (asked for 2026-09-17). The block already spans the full width with no
       float, so aligning the text is all that is needed -- money reads right-aligned, and it
       lines the figures up with each other when a transaction has several amount lines. */
    #filPreview #details div.amountBlock { display: block; text-align: right; }
    /* clear:both so the comment always starts its own line under the accounting code, rather
       than floating up beside it when the code is short. The class block below already clears,
       so the three read as one per line: Actg Code, Comments, Class.
       margin-top gives it air from the code above, matching the gap above the blocks row. */
    #filPreview #details div.commentBlock { display: block; float: left; clear: both; margin-top: 14px; } 
    /* LEFT, not right (asked for 2026-09-17). It floated right, so it sat alone against the far
       edge of the pane while the accounting code and the comment above it started at the left --
       three stacked rows that did not share a margin. clear:both still keeps it on its own line. */
    #filPreview #details div.classBlock { display: block; float: left; clear: both; text-align: left; }
    #filPreview #details .ui-tabs {font-size: small; }
    #filPreview #details .ui-tabs-anchor { font-size: small; }
    #filPreview #details h3 { margin: 15px auto 5px auto; text-align: center; }
    #filPreview #details fieldset label { clear: none; }
/* </editor-fold>*/   

/* <editor-fold defaultstate="collapsed" desc="Purchase Orders"> */ 
    div.purchaseOrder { 
        max-width: 95%; 
        background-color: var(--aceSurface); 
        border: 3px solid var(--aceBorder); 
        display: block; 
        margin: 10px auto 5px auto; 
        position: relative; 
        padding: 5px;
    }
    div.purchaseOrder .poNum { 
        /* margin:0 because this is an <h1> now and would otherwise carry the browser's
           default block margin into an absolutely positioned box. */
        margin: 0; 
        font-size: 75px; 
        font-family: Arial, sans-serif; 
        color: #B0E4F5; 
        margin: 0 10px -10px 0; 
        padding: 0 10px 0 0; 
        float: right; 
        position: absolute;  
        top: 0;
        right: 0; 
        z-index: 0;
        /*width: 100%;*/ 
        text-align: right; 
    }
    div.purchaseOrder .detailArea { 
        display: block; 
        position: relative; 
        top: 50px; 
        z-index: 5;
        margin: 0 auto 55px auto; 
        padding: 2px 2px 5px 2px; 
    }
    div.purchaseOrder .detailBox { 
        background-color: RGBA(245, 245, 245, 0.6) ;
        width: 98%;
        z-index: 5; 
        border: 1px solid var(--aceInk); 
        border-radius: 5px;
        float: left; 
        margin: 0 2px 5px 2px; 
        padding: 8px; 
    }
    div.purchaseOrder .poTerms label { 
        float: left; 
        clear: both; 
        font-weight: bold; 
        margin: 0 6px 3px 1px; 
    }
    div.purchaseOrder .poTerms input, div.purchaseOrder .poTerms textarea {
        display: block; 
        float: right; 
        width: 75%; 
        margin: 0 2px 3px 2px; 
    }
    div.purchaseOrder .poTerms span { 
        display: block; 
        clear: right; 
        margin: 0 0 3px 0;
        min-height: 20px; 
    }
    div.purchaseOrder .detailBox ul { 
        list-style: none; 
        margin: 0 0 7px -20px; 
    }
    div.purchaseOrder .vendorBox ul li:first-child, div.purchaseOrder .shippingBox ul li:first-child { 
        font-size: large; 
        font-weight: bold; 
        text-decoration: underline; 
    }
    div.purchaseOrder .detailBox h3 { 
        display: block; 
        clear: none; 
        font-size: x-large; 
        color: var(--aceBorder); 
        text-align: center; 
        margin: 0px; 
    }
    /* The "Purchase Order" label, pinned top-left. This rule used to be written against h1 --
       it moved to a class when the h1 became the PO NUMBER instead (PO::view). display:block
       because it is a span now. */
    div.purchaseOrder .poLabel { 
        text-align: left;
        z-index: 1; 
        position: absolute; 
        display: block;
        font-size: 1.6em;
        font-weight: bold;
        top: 5px; 
        left: 5px;
        margin: 0; 
    }
    div.purchaseOrder h2 { 
        text-align: center; 
        text-decoration: underline; 
    }
    div.purchaseOrder .poItem { 
        display: block; 
        border-bottom: 1px dashed var(--aceBrand); 
        font-size: large;
        clear: both; 
        padding: 7px 0; 
    }
    div.purchaseOrder .poItem input { width: 95%; display: block; margin: auto; }
    div.purchaseOrder .poItem img { display: block; float: right; margin: 3px 0 0 5px; }
    div.purchaseOrder .poItem .itemNmbr { width: 15%; float: left; font-weight: bold; }
    div.purchaseOrder .poItem .hdg { text-align: center; font-weight: bold; font-size: medium; }
    div.purchaseOrder .poItem .description { width: 40%; float: left; }
    div.purchaseOrder .poItem .priceEach { width: 12%; float: left; text-align: right; }
    div.purchaseOrder .poItem .qty { width: 5%; float: right; text-align: center; }
    div.purchaseOrder .poItem .subTotal { width: 10%; float: right; text-align: right; font-weight: bold; }
    div.purchaseOrder .poItem .accountCode { margin: 2px 0 0 25px; font-size: medium; font-weight: bold; display: block; float: left; max-width: 75%; clear: both; }
    div.purchaseOrder .poItem .accountCode .acctDesc { font-style: italic; font-weight: normal; }
    div.purchaseOrder .poItem .classBlock { display: block; float: right; margin: 5px 0 0 0; max-width: 23%; }
    div.purchaseOrder .poItem .classBlock label { display: block; float: left; font-weight: bold; }
    div.purchaseOrder .poItem .classBlock select { clear: both; display: block; float: left; width: 350px; }
    div.purchaseOrder div.po_id { 
        font-size: xx-large; 
        font-family: arial; 
        font-weight: bold; 
        color: var(--aceMuted); 
        display: block; 
        float: right; 
        position: absolute; 
        right: 5px;
        bottom: 5px;
    }
    


    div.printPO img.logo { max-width: 300px; max-height: 225px; float: left; }
    div.printPO div.titleBox { display: block; float: right; text-align: right; }
    div.printPO h1 { font-size: xxx-large; font-weight: bold; margin: 0; }
    div.printPO h2 { font-size: xx-large; font-weight: normal; margin: 0; }
    div.printPO table.poNumTable {  display: block; 
                                    float: right; 
                                    border-collapse: collapse; 
                                    margin-top: 30px; }
    div.printPO table th {  border: 1px solid black; 
                            padding: 5px 15px; 
                            background-color: var(--aceBrand); 
                            font-weight: bold; 
                            text-align: center; 
                            font-family: Arial, sans-serif;
                            font-size: large; }
    div.printPO table td {  border: 1px solid black; 
                            padding: 3px 5px; 
                            text-align: center; } 
    div.printPO div.infoBlock { 
                            display: block; 
                            width: 100%; }    
    
    div.printPO div.infoBlock div.left { 
                            display: block;
                            width: 45%; 
                            float: left; }
    div.printPO div.infoBlock div.right { 
                            display: block; 
                            width: 45%; 
                            float: right; }
    div.printPO div.infoBlock h3 { 
                            display: block; 
                            width: 100%; 
                            text-align: center; 
                            background-color: var(--aceBrand); 
                            padding: 5px 0px; 
                            font-weight: bold; 
                            font-family: Arial, sans-serif;
                            font-size: large; 
                            margin-bottom: 4px; }
    div.printPO div.infoBlock .name { 
                            font-weight: bold; 
                            font-size: large; 
                            display: block; 
                            margin-bottom: 3px; }
    div.printPO table .poTitle { font-size: x-large; }
    div.printPO table.items {   width: 100%;
                                border-collapse: collapse;
                                table-layout: auto;
                                margin: 40px 0px 100px 0px;}
    div.printPO table.items th { background-color: var(--aceBrand); }
    div.printPO table.items tr.hdg th { background-color: var(--aceInk); color: white; font-size: x-large; }
    div.printPO table.items .txtRight  { text-align: right; }
    div.printPO table.items .txtLeft   { text-align: left; }
    div.printPO table.items .txtCenter { text-align: center; }
    div.printPO table.items tr.total th { background-color: var(--aceSurface); }
    div.printPO table.items .clear { background-color: none; border: 0px transparent; }
    div.printPO table.items .total { border-top: 4px solid black; }
    
    div.printPO table.auth {    width: 100%; 
                                border-collapse: collapse; 
                                table-layout: auto; 
                                margin: 0;}
    div.printPO table.auth tr.hdg th { background-color: var(--aceInk); color: white; font-size: large; }
    div.printPO .comments { padding: 0; border: 1px solid black; min-height: 125px; }
    div.printPO .comments h3 { margin: 0; }
    div.printPO .comments span { margin: 5px; display: block; }
    
    table.poAddresses { border-collapse: collapse; width: 100%; border: 0px transparent; margin: 20px 0px !important; table-layout: fixed; }
    table.poAddresses th { text-align: center; border: 0px transparent !important; padding: 4px !important; background-color: var(--aceBrand);  }
    table.poAddresses tr { border: 0px transparent !important; }
    table.poAddresses td { text-align: left !important; border: 0px transparent !important; padding: 0; vertical-align: top; }
    table.poAddresses td.spacer { width: 20px; }
    table.poAddresses h3 { margin: 0px !important; }
    
    @media print {
        div.footer {    display: block; 
                        position: absolute; 
                        bottom: 25px; right: 25px; 
                        font-size: small; 
                        font-style: italic; 
                        border-top: 1px solid black; 
                        width: 100%; 
                        text-align: right; }
    }
    
    
/* </editor-fold>*/   
/* <editor-fold defaultstate="collapsed" desc="Tables Formatting"> */
    /* <editor-fold defaultstate="collapsed" desc="General Tables Classes"> */ 
    .fixed { 
        table-layout: fixed; 
    }
    .alternate tr:nth-child(even) {
        background-color: #FFF;
    }
    .alternate tr:nth-child(odd) {
        background-color: #EDEDED;
    }
    .alignTop { 
        vertical-align: top; 
    }
    tr.boldRow { font-weight: bold; }
    tr.italicRow { font-style: italic; } 
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="results_table Table Setup"> */ 
    .results_table { 
        border-collapse: collapse; 
        border: 1px solid black; 
        width: 100%;
        margin-bottom: 20px;
        background-color: white; 
    }
    .results_table th { 
        background-color: var(--aceBrand); 
        font-weight: bold; 
        border: 1px solid black; 
        border-bottom: 4px solid var(--aceInkDeep); 
    }
    .results_table td { 
        border: 1px solid black;
    }
    /* Default cell and heading size for every table the application builds.
       BOTH class families are listed, and that is the point: an autoTable does NOT carry
       .results_table. $autoTableSettings in config.php gives it class ["display","dataTable"],
       so a rule written only against .results_table reaches the hand-built tables and misses
       every autoTable on the site. The DataTables selectors are spelled at thead/tbody depth to
       match the CDN stylesheet's own specificity; ace.css loads after it, so equal specificity
       resolves here. 13px is the content floor (New look and feel), and tables are content. */
    .results_table th, .results_table td,
    table.dataTable th, table.dataTable td,
    table.dataTable thead th, table.dataTable thead td, table.dataTable tbody td { font-size: 13px; }
    /* Column titles are CENTRED everywhere. Same two-family listing and the same reason as the
       size rule above -- an autoTable carries .dataTable, not .results_table -- so a rule
       written against one family silently misses half the tables on the site.

       This does not fight the DataTables stylesheet: it ships no generic thead alignment, only
       the opt-in .dt-head-left / .dt-head-center / .dt-head-right classes, and those are one
       class more specific than this, so a table that genuinely needs a left-aligned title can
       still ask for it with dt-head-left. An inline hdgStyle['text-align'] also still wins. */
    .results_table th,
    table.dataTable th, table.dataTable thead th { text-align: center; }
    /* ...and the opt-out has to be restated afterwards, louder than the rule above. Since the
       default became the 13px content floor there is nothing smaller to drop to, so a
       .smallerFont table now renders at 13px too; max() keeps it from ever going under. */
    table.smallerFont th, table.smallerFont td,
    table.dataTable.smallerFont thead th, table.dataTable.smallerFont thead td,
    table.dataTable.smallerFont tbody td { font-size: max(13px, 0.875em); }
    .results_table span { display: block; }
    .results_table input, .results_table select, .results_table textarea { display: block; width: 98%;  }
    .results_table input[type='radio'] { width: 20px; display: block; float: left; }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="Opt-in table utilities"> */
        /* Every column's DATA on one line. Opt in with $t->addClass('nowrapCols').
           Stops TEXT wrapping only: .results_table span is display:block above, so a cell
           built from stacked spans still stacks. That is structure, not wrapping, and
           unpicking it here would re-flow cells that are meant to have several lines.

           Column titles are deliberately left free to wrap -- a two-word heading over a
           short value would otherwise set the column's width for every row. Said out loud
           rather than left to the default because white-space inherits, so a nowrap set
           on any ancestor would otherwise reach the headings. */
        table.nowrapCols td { white-space: nowrap; }
        table.nowrapCols th { white-space: normal; }

        /* THE FOUR COLUMN MARKS BELOW ARE KEYED ON THE CELL CLASS ALONE -- td.dateCol, not
           ".results_table td.dateCol, table.dataTable td.dateCol" as they were until
           2026-09-01. autoTable::$class defaults to an EMPTY array: a table only carries
           .results_table if its caller added it, and .dataTable only once DataTables has
           initialised it (dtSet). So every autoTable that does neither was marking its cells
           and then matching no rule at all -- the class was there in the HTML and the dates
           wrapped anyway. Nothing else in this application uses these four class names, so
           there is nothing for the unscoped selector to catch by accident, and markup built by
           hand outside autoTable can opt in just by adding the class.

           A DATE COLUMN. autoTable::markDateColumns() puts this on the <td>s of any column whose
           values are dates -- either because the caller declared a date cleanData type, or because
           every value in the column looks like one. A date is a single value and should read as
           one: "2026-08-20" breaking after the year, or "01/26/2026 10:38 AM" dropping its time to
           a second line, makes a column of them hard to scan.

           On the <td> only -- the <th> is deliberately left free to wrap, for the same reason
           nowrapCols leaves its headings alone: a two-word title like "Status Updated" that cannot
           break would set the column's width for every row.

           Both families listed, as everywhere else in this fold: an autoTable carries .dataTable,
           not .results_table. Opt a table out with $t->autoNowrapDates = False. */
        td.dateCol { white-space: nowrap; }

        /* A MONEY COLUMN, marked the same way and for the same reason: "$30,651.91" breaking
           after the comma is unreadable, and a column of amounts you cannot scan straight down
           is the whole point of the column defeated. Detected from a CURRENCY / DOLLARS /
           THOUSANDS cleanData type, or from every value in the column looking like an amount.
           <td> only, same as dateCol -- the title is free to wrap. */
        td.moneyCol { white-space: nowrap; }

        /* A PHONE COLUMN. autoTable::markTypedColumns() puts this on the <td>s of any column
           whose KEY carries one of $phoneColWords (phone, fax, mobile, cell, telephone) or that
           declares the PHONE cleanData type -- and it gives that column the PHONE format at the
           same time, so the same number cannot read "(352) 955-4444" on one screen and
           "3529554444" on the next.
           A phone number is a single value and should read as one: breaking after the area code
           is the same defeat as a date breaking after the year.
           <td> only, same as the others: the heading is free to wrap. Opt a table out with
           $t->autoPhoneCols = False. */
        td.phoneCol { white-space: nowrap; }

        /* A TOOLS COLUMN -- the row of action icons at the end of a table.
           autoTable::markTypedColumns() puts this on the <td>s of any column KEYED 'tools',
           'icons' or 'actions' ($toolColNames), which is what this application calls that
           column. Decided by the key and not by the contents, because some of those cells are
           built from $t->icons[] and others have their buttons written straight into $t->data
           -- and an icon in a cell does not make it a tools column (there is an info icon on a
           'description' column in msc_miscObjects, which must stay free to wrap).

           Each icon is an inline <a><img>, so they break at the gaps BETWEEN them and a narrow
           column stacks them two and three high, making every row that tall. white-space
           inherits, so this reaches the <span> autoTable::getIcon() wraps them in as well.

           <td> only, same as dateCol and moneyCol -- the title is free to wrap. Opt a table out
           with $t->autoNowrapTools = False. */
        td.toolCol { white-space: nowrap; }
        /*
         * BOOTSTRAP-ICON TOOLS: NO SIZE SET, ON PURPOSE.
         *
         * This column had `font-size: x-large` on the cell, which is where the "too big" came
         * from. The obvious repair -- state a size -- went wrong twice and both failures are
         * worth keeping: a glyph's LINE BOX is taller than its font-size (measured in Chrome,
         * font-size 25px renders a 28px box, x-large renders 27px), so asking for 25 made them
         * BIGGER; and a fixed 20px box is still half again the size of every other tools
         * column, because a glyph with no rule on it inherits the cell's 14px and renders a
         * 16px box.
         *
         * So the size is not stated at all now. These inherit exactly what a tools glyph
         * anywhere else in the application inherits, which is the only definition of
         * "consistent with the others" that cannot drift when one of them is next retuned.
         *
         * What IS still needed here is the layout below -- that is a different fault.
         */
        /*
         * THE ICONS STAY ON ONE LINE. `white-space: nowrap` was never the problem:
         * `.results_table span { display: block; }` (a few rules up) turns the wrapper the
         * cancel-payment link arrives in into a BLOCK, and a block takes its own line no
         * matter what white-space says. Measured in Chrome -- with that span the row broke
         * onto two lines, without it one -- rather than guessed at.
         *
         * PUT BACK TO `inline`, AND NOTHING ELSE. An earlier attempt made the wrapper (and
         * the anchors) inline-FLEX, which fixed the line but made every glyph a flex item
         * and left them 17.8px tall against the 16px an untouched tools glyph measures. The
         * icons are not styled here at all now: the only thing wrong with them was this
         * span, so this is the only thing changed.
         *
         * (0,2,1) beats that rule's (0,1,1), so no !important is needed.
         */
        td.toolCol.bcPayTools span { display: inline; }

        /* NOWRAP AND NOTHING ELSE. markTypedColumns() falls back to this for a column whose NAME
           says date or amount but whose values the sniffers could not confirm -- one "n/a" row,
           or amounts printed without a currency symbol, used to leave such a column wrapping.
           It deliberately carries no meaning beyond "do not break this": moneyCol also drives
           the numeric sort order, and a column that is merely NAMED "total" has not earned that.
           Guarded by a length check on the values, so a "Date Notes" column of prose keeps its
           wrapping. <td> only, same as the rest. */
        td.nowrapCol { white-space: nowrap; }

        /* One step down from the surrounding text, for tables carrying a lot of columns.
           Opt in with $t->addClass('smallerFont'). Form controls do not inherit font-size,
           so the DataTables search inputs in the header keep their own. */
        table.smallerFont th, table.smallerFont td { font-size: max(13px, 0.875em); }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="brief_table Setup"> */ 
        table.brief_table { width: 80%; display: table; margin: 5px auto 5px auto; border-collapse: collapse; }
        table.brief_table tr:nth-child(odd) { background-color: #CCCCCC; }
        table.brief_table tr:nth-child(even) { background-color: var(--aceSurface); }
        table.brief_table tr.hdg { border-bottom: 3px solid black; background-color: var(--aceSurface); font-size: large; }
        table.brief_table th { font-weight: bolder; text-align: center; padding: 1px 5px;  }
        table.brief_table td { padding: 1px 3px 1px 5px; }
    /* </editor-fold>*/
    /* <editor-fold defaultstate="collapsed" desc="brief_table Setup"> */ 
        table.short_table { max-width: 80%; display: table; margin: 5px auto; border-collapse: collapse; }
        table.short_table th { font-weight: bolder; text-align: center; padding: 1px 5px; border: 1px solid black; background-color: var(--aceBrand); }
        table.short_table td { padding: 1px 3px 1px 5px; border: 1px solid black; }
    /* </editor-fold>*/
    
    /* <editor-fold defaultstate="collapsed" desc="listTable"> */ 
        table.listTable { border-collapse: collapse; }
        table.listTable tr { border: 1px solid black; }
        table.listTable td { border: 0px transparent; padding: 0 5px; }
/* </editor-fold>*/
    
    .popIconMenuToggle {
        text-align: right;
        float: right;
    }

    /* DataTables per-column filter row (built by autoTable::dtAddBlankSearchRow).
       A bare text input carries a browser default width of about 20 characters, and
       because it sits in the header it sets a FLOOR on the column: a 5-character
       "TRA ID" column ends up as wide as its "Search TRA ID" box, which is where the
       dead space in these tables comes from. Letting the input track the column
       instead means column widths follow the data. */
    tr.searchRow td { padding: 1px 3px; }
    tr.searchRow input {
        width: 100%;
        min-width: 0;
        box-sizing: border-box;
        font-size: 13px;
        padding: 2px 4px;
    }
    /* The TRA ID filter only ever holds a few digits, so it is pinned narrow on every
       table that offers it rather than tracking the column like the other filters.
       The [i] flag covers both heading spellings in use ("TRA ID" and "Tra ID"). */
    tr.searchRow input[placeholder='Search TRA ID' i] {
        width: 75px;
        box-sizing: border-box;
    }

    tr.borderBlack1 { border: 1px solid black; }
    tr.borderBlack1 td, tr.borderBlack1 th { border: 0 transparent; border-top: 1px solid black; border-bottom: 1px solid black; }
    tr.borderBlack1 td:first-child, tr.borderBlack1 th:first-child { border-left: 1px solid black; }
    tr.borderBlack1 td:last-child, tr.borderBlack1 th:last-child { border-right: 1px solid black; }
    tr.hdgRow td, tr.hdgRow th { background-color: var(--aceBrand); font-weight: bold; font-size: large; }
    .pad5 { padding: 5px; }


    table.divideLines tr td { border-bottom: 1px solid black; }
    table.divideLines tr:last-child td { border-bottom: 0px transparent; }
    table.collapse { border-collapse: collapse;}
    table.dataList tr td:first-child { padding-left: 15px; padding-right: 5px; font-size: small; } 
    table.dataList tr td:last-child { padding-right: 20px; padding-left: 5px; font-size: large; }
        
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Transaction Parts"> */ 
    .transaction { 
        max-width: 95%; 
        background-color: var(--aceSurface); 
        border: 3px solid var(--aceBorder); 
        display: block; 
        margin: 10px auto 5px auto; 
        padding: 5px;
        position: relative;
        min-width: 650px;
    }
    .transaction.urgent { background-color: #ffcfcf; }
    .transaction .ui-button-text { height: 20px; }
    /* Tab labels across the top of a transaction (Info / Apprs / Vendor / Actg Sync / ...).
       Scoped with > so tab boxes nested INSIDE a tab's content keep their own sizing. */
    .transaction > .ui-tabs > .ui-tabs-nav li a { font-size: max(13px, 0.85em); padding: 0.4em 0.8em; }
    .transaction label { 
        display: block; 
        float: left; 
        font-weight: bold; 
        margin: 0 0 0 -2px ; 
        font-style: normal; 
        font-variant: normal; 
        font-size: medium; 
    } 
    .transaction .type { 
        display: block; 
        float: left; 
        padding: 0 0 0 10px; 
        
    }
    .transaction .type .line { display: block; clear: both; }
    .transaction .status { 
        display: block;
        margin: auto; 
        width: auto; 
        min-width: 100px;
        max-width: 250px;
        text-align: center; 
        border: 1px solid black;
        font-weight: bold; 
        font-variant: small-caps; 
        font-style: italic;
    }
    .transaction .meta { 
        display: block;
        float: right; 
        padding: 0 10px 0 0; 
        text-align: right;
    }
    .transaction .vendor { 
        clear: both; 
        display: block;
        float: left; 
        width: 74%; 
        font-weight: bold;
        font-size: large; 
        padding: 20px 0 0 0; 
    }
    .transaction .amount {
        display: block;
        width: 24%;
        padding: 20px 0 0 0;
        text-align: right;
        float: right;
        font-size: large;
        font-weight: bold;

    }

    .transaction .description { 
        width: 90%; 
        display: block;
        clear: both; 
        margin: 0 0 0 8px;
    }    
    .transaction .description textarea {
        width: 90%;
        display: block; 
        clear: both;
    }
    .transaction .amtLine { 
        width: 80%; 
        border: 1px solid #BEE6DE; 
        display: block; 
        margin: auto; 
        padding: 4px; 
    }
    /*
     * ONE RHYTHM FOR THE WHOLE LINE.
     *
     * The four blocks each carried their own spacing -- the account block none, class and
     * comments 5px, the amount block whatever its input padding gave it -- so the gaps between
     * the rows were all slightly different. They are rows of one record and should read as
     * evenly spaced, so the vertical gap is set in ONE place (--amtRowGap) and every row after
     * the first takes it. Change the rhythm here, not on the individual blocks.
     */
    .transaction .amtLine { --amtRowGap: 6px; }
    /*
     * LABEL BESIDE ITS VALUE, on each block's OWN rule.
     *
     * It was written once as a shared `.coaCodesBlock, .classBlock, .commentBlock { display:flex }`
     * higher up -- which lost, because the per-block rules further down redeclare `display: block`
     * at the same specificity and the later rule wins. Only the account block (whose own rule
     * comes first) took the flex, so Class and Comments stayed stacked. Declared here instead,
     * where nothing below can undo it.
     *
     * Flex rather than floats because .coaSelectLine opens with its own clearfix and the account
     * selector arrives later through loadAfter as a block -- either drops the value onto the next
     * line. A flex row lays its children out side by side whatever they do internally.
     *
     * baseline so the bold label sits on the same text baseline as the value rather than being
     * centred against a taller control. The outer float is what still puts the account on the
     * left and the amount on the right.
     */
    .transaction .amtLine .coaCodesBlock {
        display: flex;
        align-items: baseline;
        gap: 5px;
        float: left; 
        margin: 0;
    }
    /* The field name in front of a value. A LABEL, not a control: it sits outside the
       editableNow wrapper (see AMT::disSpan) so clicking the word does not open the editor,
       and the default cursor is what says so. */
    .transaction .amtLine .amtLbl {
        font-weight: bold;
        margin-right: 5px;
        white-space: nowrap;
        cursor: default;
    }
    .transaction .amtLine .amtLbl { margin-right: 0; }          /* the row's gap does this */
    .transaction .amtLine .coaCodesBlock .coaSelectLine { margin: 0; }
    /* The comment is the one that should take the leftover width. */
    .transaction .amtLine .commentBlock .editableNow,
    .transaction .amtLine .commentBlock .clickableEditNow { flex: 1 1 auto; }
    .transaction .amtLine .amountBlock {
        display: block;
        float: right;
        text-align: right;
    }
    .transaction .amtLine .amountBlock input , .transaction .amtLine .amountBlock .editableNow, .transaction .amtLine .amountBlock .clickableEditNow { 
        clear: both; 
        display: block; 
        width: 100%;
        padding: 0 4px; 
    }
    /*
     * VERTICAL padding on the INPUT only, and this is what evens the rows up.
     *
     * The amount shares the first row with the account code, and it was the taller of the two:
     * 4px of padding top and bottom on its read-only span made row one 8px deeper than its own
     * text. Class clears that row (clear: both), so the gap above Class came out 8px bigger than
     * the gap above Comments and the three rows read as unevenly spaced.
     *
     * The horizontal padding stays -- it is what keeps the figure off the card's right edge --
     * and the input keeps its full padding, because there it is the click target of a form
     * field rather than a line of text.
     */
    .transaction .amtLine .amountBlock input { padding: 4px; }
    .transaction .amtLine .classBlock { 
        clear: both; 
        display: flex;
        align-items: baseline;
        gap: 5px;
        float: left;
        margin: var(--amtRowGap) 0 0 0; 
    }
    .transaction .amtLine .classBlock select { 
        clear: both;
        display: block;
        float: left;
        width: 350px;
    }
    .transaction .amtLine .commentBlock {
        display: flex;
        align-items: baseline;
        gap: 5px;
        float: left; 
        clear: both;
        margin: var(--amtRowGap) 0 0 0; 
        max-width: 100%;
    }
    /* The amount is the first row's right-hand half, so it must not add height of its own --
       any padding here shows up as an uneven gap above Class. */
    .transaction .amtLine .amountBlock { margin: 0; }
    .transaction .amtLine .commentBlock input { 
        width: 100%; 
        clear: both; 
    }
    .transaction div.trans_id { 
        font-size: xx-large; 
        font-family: Arial, sans-serif;
        font-weight: bold; 
        color: var(--aceMuted); 
        display: block; 
        float: right; 
        position: absolute; 
        right: 5px;
        bottom: 5px;
    }
    .transaction .invDetails { display: block; float: left; width: 25%; margin: 5px 0 0 8px; }
    .transaction .invDetails input {display: block; float: left; clear: both; font-family: Arial, sans-serif; font-size: 1em;  padding: 5px 10px; height: 24px; width: 90%; }
    .transaction .invDetails label { display: block; float: left; font-weight: bold; margin: 0 0 0 -2px; font-style: normal; font-variant: normal; font-size: medium; }
    
    .amountsTable {
        width: 75%;
        border: 1px solid var(--aceBorder); 
        border-collapse: collapse; 
        margin: auto;
        
    }
    table.infoBlockTable { 
        border-collapse: collapse; 
        display: table; 
        width: 85%; 
        margin: auto;
        position: relative;
    }
    table.infoBlockTable th { 
        text-align: right; 
        width: 25%;
    }
    table.infoBlockTable td:nth-child(2) {
        text-align: center;
    }
    table.infoBlockTable td:nth-child(3) {
        text-align: left;
    }
    table.infoBlockTable tr { 
        border-bottom: 1px black dashed; 
    }    
    .traMajorNote {
        position: absolute; 
        margin: -25px auto;
        line-height: 1;
        font-family: Arial, sans-serif; font-weight: bold;
        color: var(--aceMuted); 
        font-size: 125px;
        content: attr(data-bg-text);
        display: block;
        width: 100%; 
        text-align: center;
     }
    .traStatusBar { 
        display: block;
        float: left;
        width: 200px;
        height: 41px;
        max-width: 100%;
        text-align: center;
        /* 12px bold, the application's content size (2026-09-17). `large` is 18px, which made the
       status word the biggest text in a row of 12px cells. Bold is what keeps it prominent at the
       smaller size -- the coloured bar behind it already carries the emphasis. */
        font-size: 13px;
        font-weight: bold; 
        vertical-align: middle;
        margin: 0 2px;                
    }
    .traStatusBar .statusText { 
        margin: 10px 2px;
        display: block;
    }
    
    .assignCOACategories { width: 95%; height: 95%; display: block; position: absolute; bottom: 0; }
    .assignCOACategories .droppable { display: block; background-color: var(--aceHighlight); }
    .categoryHolder { width: 550px; margin: 0 10px 0 10px; height: 95%; border: 3px solid black; overflow-y: scroll; overflow-x: hidden; display: block; float: left; }
    .assignCOACategories  li { display: block; width: 475px; border: 1px solid gray; margin: 5px; padding: 2px; font-size: large; }
    .assignCOACategories li li { width: 425px; }
    .assignCOACategories li li li { width: 375px; }
    .assignCOACategories li li li li { width: 325px; }
    .assignCOACategories li li li li li { width: 275px; }
    .assignCOACategories li li li li li li { width: 225px; }
    .assignCOACategories li span.count { display: block; float: right; color: gray; margin: 0 3px; font-size: small; }
    .assignCOACategories .coaList { display: block; float: left; margin: 0 10px; height: 95%; border: 3px solid black; }
    .assignCOACategories .categoryAccountList li { margin: 0; padding: 0; font-size: 13px; border: 0px transparent;  }
    .missingerror { background-color: red; color: yellow; padding: 1px 5px; margin: 0px 5px; }
    
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Dashboard Settings"> */
/* ONE SIZE FOR THE WHOLE DASHBOARD: 12px -- the application's default content size.
   (It was 14px until 2026-09-16.)

   FOUR THINGS KEEP THEIR OWN SIZE, all of them display type or chrome rather than
   content, and each says so where it is set:
     - the page's own heading, .dashHeader h1 / h2 (28px / 22px);
     - the figure on each stat tile, .dashStats .stat .data (clamped to the tile);
     - the card title bars, .dashGroup .blk .item > .title and the phone breakpoint's
       .dashStatsCard > .dashStatsTitle (both `large`) -- the same decision as
       .hlpTopicPopHeader, which is every dialog's title bar;
     - the collapse chevrons, .dshCardToggle / .dshCardChevron (14px) -- glyph controls
       sized against the title bar they sit in, not lines of text.

   .dashStatsCard IS IN THE LIST, and has to be: it is the WRAPPER around .dashStats
   (added for the phone breakpoint, where the stat bar becomes a collapsible card), so
   its own title bar is a sibling of .dashStats rather than a child. Without it that
   title inherited the browser's 16px and nothing here reached it.

   Headings are listed out because h1-h6 carry a UA font-size in em, so they would
   scale off this size instead of taking it; the same goes for any heading a widget
   renders inside a card. */
.dashHeader, .dashStats, .dashStatsCard, .dashGroup, .dashFooter { font-size: 13px; }
.dashHeader    h1, .dashHeader    h2, .dashHeader    h3, .dashHeader    h4, .dashHeader    h5, .dashHeader    h6,
.dashStats     h1, .dashStats     h2, .dashStats     h3, .dashStats     h4, .dashStats     h5, .dashStats     h6,
.dashStatsCard h1, .dashStatsCard h2, .dashStatsCard h3, .dashStatsCard h4, .dashStatsCard h5, .dashStatsCard h6,
.dashGroup     h1, .dashGroup     h2, .dashGroup     h3, .dashGroup     h4, .dashGroup     h5, .dashGroup     h6,
.dashFooter    h1, .dashFooter    h2, .dashFooter    h3, .dashFooter    h4, .dashFooter    h5, .dashFooter    h6 { font-size: 13px; }
.dashHeader {
    display: block; 
    width: 100%; 
    text-align: center; 
    margin: 0;
    background-color: #FFFFFF;
    border-bottom: 12px solid var(--aceAccent, #BFE3DC);
}
.dashHeader h1, .dashHeader h2, .dashHeader h3, .dashHeader h4, .dashHeader p { margin: 0; }
.dashHeader h1 { font-size: 28px; }   /* "<name> Dashboard" -- the page's own heading */
.dashHeader h2 { font-size: 22px; font-weight: normal; }   /* the entity name under the heading */
/* Stats bar -- each stat is its own small card, laid out on a grid that reflows
   with the window. auto-fit + minmax gives as many equal columns as will fit, so
   the tiles are always the same size as each other however wide the screen is
   (a content-sized flex row made them all different widths and left ragged gaps).
   The min(...) is what keeps a phone-width screen to one full-width tile rather
   than overflowing the page: a track can never be asked to be wider than the row.

   The 140px minimum is what sets the wrap point: a column costs 140px + the 10px
   gap, so eight tiles fit from roughly 1200px of window upwards. Raise it and the
   last tile drops to a row of its own on smaller laptops. auto-fit (not auto-fill)
   then collapses the tracks nothing landed in, so the tiles that ARE there spread
   out to fill the row instead of huddling at 140px with dead space beside them --
   max-width keeps that from stretching a two-tile dashboard across the monitor. */
.dashStats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
    gap: 10px;
    align-items: stretch;
    box-sizing: border-box;
    width: 100%;
    background-color: #FFFFFF;
    margin: 0;
    padding: 10px;
    clear: both;
}
.dashStats > .clearfix { display: none; }
/*
 * VENDORS NEEDING ATTENTION (#venNeedingAttention) AND SCHOOL INFORMATION (#entContactIncomplete)
 * ALWAYS LAND ON THEIR OWN ROW TOGETHER, UNDER EVERY OTHER STAT TILE (asked for 2026-09-24). Both
 * are "something is wrong, go look" cards (see .dshNeedsAttention above/below) rather than plain
 * figures, so they read as a bottom row of callouts instead of being shuffled in among the
 * numbers by dsh_options.sort_order or however many other tiles a school has enabled.
 *
 * THIS IS A SECOND, SEPARATE .dashStats GRID (DSH::buildHtml, `.dashStatsAttn`), not a placement
 * trick inside the main one. An earlier version used a full-span `::before` spacer plus
 * `order: 900` on these two ids to push them down and together within the ONE grid -- that broke
 * the moment the main grid's own tile count made IT wrap to two rows: an ordinary tile could
 * land between the spacer and the ordered-900 pair, splitting the three of them across separate
 * rows instead of grouping the two attention tiles. A dedicated grid holding only these two has
 * nothing else that can land in it, so "always together, always last" needs no placement math at
 * all.
 *
 * IT IS FLEX, NOT GRID, BELOW -- .dashStatsAttn overrides .dashStats's own `display: grid`
 * (same specificity, later in the file wins). Grid auto-fit/minmax computes its column count
 * PER CONTAINER, from that container's own width and its own content -- it is not shared with
 * the .dashStats row above just because both carry the same class. With only one or two items
 * ever inside .dashStatsAttn, auto-fit created exactly as many 1fr tracks as the spanning item
 * needed and nothing more, and those 1fr tracks then split the FULL ROW WIDTH between them --
 * so a lone "span 2" card filled the entire width edge to edge instead of reading as "two tiles
 * wide" (screenshotted 2026-09-24: entContactIncomplete was skipped that day, so
 * venNeedingAttention was the ONLY item in the grid and stretched the full width). Flex with an
 * explicit max-width sidesteps the whole problem: the size is stated outright rather than
 * derived from how many tracks a mostly-empty grid decides to create.
 */
.dashStatsAttn { display: flex; flex-wrap: wrap; }
/*
 * TWICE AS WIDE, HALF AS TALL (asked for 2026-09-24) -- same footprint as an ordinary tile, a
 * different shape: a short, wide banner instead of a tall, narrow tile, now that the two of
 * them have a whole row of their own and are not trying to line up with anything else.
 *
 * 656px = 2 * 320px (.dashStats .stat's own normal-tile cap) + the 16px gap between them --
 * an explicit "two tiles" size instead of a fraction of whatever the grid above computed.
 * flex-basis 296px (2 * 140px + gap) is the matching floor, so it still shrinks sensibly on a
 * narrow window instead of only ever being exactly 656px. Height comes down with the padding
 * (halved, top and bottom) and by letting the title sit on ONE line instead of reserving room
 * for two -- a two-line reservation made sense at the old narrow width where "Vendors Needing
 * Attention" could wrap; at twice the width it fits on one line with room to spare.
 */
.dashStatsAttn > .stat {
    flex: 1 1 296px;
    max-width: 656px;
    padding-top: 4px;
    padding-bottom: 4px;
}
.dashStatsAttn > .stat .top {
    min-height: 0;
}
/* THE STAT BAR'S CARD WRAPPER (DSH::buildHtml). On a wide screen it is not a card at all --
   no border, no header, and .cardCollapsed deliberately does NOTHING here. The collapsed state
   is stored per USER, not per device, so a bar shut on a phone must not blank the stats on the
   desktop; the whole collapse lives in the phone breakpoint near the bottom of this file
   (search "the stat bar is one collapsible card"). */
.dashStatsCard > .dashStatsTitle { display: none; }
.dashStats .stat {
    /* Column so the footer can be pinned to the bottom -- tiles in a row are
       equal height, and the footers then line up across the row. */
    display: flex;
    flex-direction: column;
    float: none;
    box-sizing: border-box;
    min-width: 0;               /* a grid item defaults to min-content wide; this lets it shrink */
    max-width: 320px;           /* stops a 2-3 tile dashboard stretching each one across the screen */
    margin: 0;                  /* the grid gap does the spacing now */
    padding: 8px 11px;
    background-color: white;
    border: 1px solid var(--aceCardBorder);
    border-left: 4px solid var(--aceAccent, #57756F);
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    overflow-wrap: break-word;  /* a long word wraps instead of widening the tile */
    container-type: inline-size;/* lets .data size itself against the tile -- see below */
}
.dashStats .stat p { margin: 0; padding: 0; }
/* Every title occupies two lines whether it needs them or not, so the figure and
   the footer below it start at the same height on every tile in the row. A title
   long enough to need a third line still gets one -- this is a floor, not a clamp,
   because truncating a stat's name would be worse than one tile running deeper. */
.dashStats .stat .top {
    font-size: 13px;
    color: var(--aceInk);
    line-height: 1.2;
    min-height: 2.4em;          /* 2 lines x line-height */
}
/* The figure is never allowed to wrap -- "$13,690.34" broken across two lines
   reads as two numbers.
   It is sized against the TILE (cqi), not the viewport, because those pull in
   opposite directions here: a wider window fits more columns, which makes each
   tile NARROWER, so a vw-based figure grows exactly when it has less room and
   the longest amounts overflow their card. Tiles in a row are all the same
   width, so this still renders every figure at the same size.
   The plain rem above is the fallback for anything too old for container units
   (pre-2023 browsers) -- it drops the declaration it can't parse and keeps that. */
.dashStats .stat .data {
    font-size: 1.2rem;
    font-size: clamp(0.95rem, 16cqi, 1.5rem);
    color: black;
    font-weight: bolder;
    line-height: 1.15;
    margin: 1px 0 3px 0;
    white-space: nowrap;
}
.dashStats .stat .bottom { font-size: 13px; color: var(--aceBorder); line-height: 1.25; margin-top: auto; }
/* First child kept its own rule when the tiles were divider-separated; now it is a card like the rest. */
.dashStats .stat:first-child { border: 1px solid var(--aceCardBorder); border-left: 4px solid var(--aceAccent, #57756F); }
/* A tile asking for something to be fixed. Every stat already carries a 4px left border in the
   accent colour, so this changes only its COLOUR -- nothing moves and no tile changes size.
   #b3261e is the red the Organization form uses for its master-only fields; on a border it is
   1.4.11's 3:1 that applies, and it is 6.5:1 on white. Colour is never the only signal -- the
   tile says what is missing in words. */
.dashStats .stat.dshNeedsAttention { border-left-color: #b3261e; }
.dashStats .stat[onclick] { cursor: pointer; }
.dashStats .stat[onclick]:hover { box-shadow: 0 2px 6px rgba(0,0,0,0.14); }
/* Deferred (AJAX-loaded) tiles carry an inline display/float, so centre the
   spinner with text-align rather than flex -- the inline style would win. */
.dashStats .stat.replaceDshBrd { text-align: center; }
.dashStats .stat.replaceDshBrd img { max-width: 100%; height: auto; }
@media (max-width: 600px) {
    /* Phone widths: give the content the space the chrome was using. */
    .dashStats { gap: 8px; padding: 8px; }
    .dashStats .stat { padding: 8px 10px; }
}

/* Widget groups -- a light board that the widget cards sit on. Groups no longer
   render as alternating full-width bands; each widget is its own card instead. */
.dashGroup {
    display: flex;
    flex-wrap: wrap;
    /* flex-start, NOT stretch: each card is only as tall as its own content, so
       expanding/collapsing one card can't add blank space to its neighbours. */
    align-items: flex-start;
    box-sizing: border-box;
    clear: both;
    margin: 0;
    padding: 4px 6px;
    background-color: #FFFFFF;
    border-bottom: 0 none;
}
.dashGroup:nth-child(odd) { background-color: #FFFFFF; }
.dashGroup > .clearfix { display: none; }
.dashGroup > .title {
    font-size: 13px;
    text-align: center;
    display: block;
    flex: 0 0 100%;
    width: 100%;
    margin: 2px 0;
}
.dashGroup .blk {
    display: flex;
    float: none;
    background-color: unset;
    box-sizing: border-box;
    height: auto;
}
.googleChartHolder { margin: 5px; padding: 5px;  }
.dashGroup .blk .item {
    display: block;
    flex: 1 1 auto;
    box-sizing: border-box;
    background-color: white;
    border: 1px solid var(--aceCardBorder);
    margin: 8px;
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    height: auto;
    padding: 12px 14px;
}
.dashGroup .blk .item:hover { box-shadow: 0 2px 6px rgba(0,0,0,0.14); }
/* Card header -- full-bleed across the top of the card, and the collapse control. */
.dashGroup .blk .item > .title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: large;
    font-weight: bold;
    color: #333333;   /* flat title ink -- see .hlpTopicPopHeader */
    margin: -12px -14px 10px -14px;
    padding: 8px 14px;
    background-color: var(--aceAccent2, #F7FAF9);
    border-bottom: 1px solid var(--aceCardDivider);
    border-radius: 9px 9px 0 0;
}
/* An autoTable's heading. See autoTable::headingClasses() -- it used to be a bare <h2>
   inheriting whatever ink reached it, which on some screens was a pale brand colour on
   white and failed WCAG 2.2 AA. --aceInk (#4F4F4F) on white is 8.19:1, clearing AA (4.5:1)
   and AAA (7:1). !important is deliberate: the point is that nothing inherits over it. */
.atHeading { color: var(--aceInk, #4F4F4F) !important; }

/* The title bar is the drag handle for repositioning the card. */
.dashGroup .blk .item > .title { cursor: move; }
/* ...but the screen code inside it is text meant to be read out and copied, so it keeps a
   normal caret and stays selectable. It is also in the sortable's `cancel` list in
   ace_start.js -- both are needed: this one for the cursor, that one for the selection. */
.dashGroup .blk .item > .title .popModalCode { cursor: text; -webkit-user-select: text; user-select: text; }
/* NOT `flex: 1 1 auto`. A growing title span pushed the help icon the whole width of the
   card, so it read as a right-aligned control rather than as part of the title. The free
   space is taken AFTER the icon instead (see the .hlpIconLink margin-right in
   dshItem::nlfCardStyle), which keeps title + "?" together and the chevron on the right --
   the same arrangement #aceHistBoxHdg uses. */
.dashGroup .blk .item > .title > .titleText { flex: 0 1 auto; }
.dashGroup .blk .item > .title > .titleText[onclick] { cursor: pointer; }
.dashGroup .blk .item > .title > .titleText[onclick]:hover { text-decoration: underline; }
.dashGroup .blk .item > .title:hover { background-color: #EDF4F2; }
.dashGroup .blk .item > .title .dshCardToggle {
    flex: 0 0 auto;
    cursor: pointer;
    color: var(--aceAccent, #57756F);
    font-size: 14px;
    line-height: 1;
    padding: 2px 2px 2px 8px;
}
.dashGroup .blk .item > .title .dshCardToggle i { display: inline-block; transition: transform 0.15s ease; }
.dashGroup .blk .item .itemBody > .footer { margin: 10px -14px -12px -14px; padding: 6px 14px; border-top: 1px solid var(--aceCardDivider); color: var(--aceBorder); font-size: 13px; }

/* Collapsed: only the title bar remains, and it becomes the whole card. */
.dashGroup .blk .item.cardCollapsed > .itemBody { display: none; }
.dashGroup .blk .item.cardCollapsed > .title {
    margin-bottom: -12px;
    border-bottom: 0 none;
    border-radius: 9px;
}
.dashGroup .blk .item.cardCollapsed > .title .dshCardToggle i { transform: rotate(180deg); }
/*
 * A MASTER-USERS-ONLY 'blk' CARD (asked for 2026-09-25; first use: dshItem::qbsSyncThroughput).
 * Generic and reusable -- any future master-only block card adds `dshMasterOnly` to $i->classes
 * rather than inventing its own border. #b42318 is the app's established master-only red (the
 * top menu's .atnMaster rows, the Advanced Search master-only checkbox border) -- one colour for
 * "this is restricted to master users" everywhere it appears, not a fourth candidate red.
 */
.dashGroup .blk.dshMasterOnly .item { border: 2px solid #b42318; }
/*
 * TITLE BAR WRAP (asked for 2026-09-28: P37A642 still a little too wide even after the table
 * got its own overflow-x:auto). The title row (.dashGroup .blk .item > .title) is display:flex
 * with no flex-wrap, and this card's title bar packs FOUR things onto it that cannot shrink:
 * the help+support icon pair plus the "Master Users Only" badge (SupportTicket::noBreak's group,
 * explicitly white-space:nowrap and flex:0 0 auto), the screen-code chip, and the collapse
 * chevron. Their combined minimum width is wider than col1-4 (~24%), and since a flex item's
 * automatic minimum size is content-based unless something intervenes, that unshrinkable total
 * was still forcing the CARD wider than its column even with the table fixed.
 *
 * flex-wrap: wrap lets whatever does not fit drop to a second line instead of stretching the
 * card -- the same "let it wrap, don't let it force overflow" fix as the table's overflow-x, one
 * level up. Scoped to .dshMasterOnly rather than every .title bar in the app: this is the one
 * card asked to be this narrow while carrying this much title-bar chrome; other cards' title
 * bars already fit their columns and this rule would do nothing for them anyway.
 */
.dashGroup .blk.dshMasterOnly .item > .title { flex-wrap: wrap; row-gap: 4px; }
/* The titleNote badge (dshItem::$titleNote) that rides after the help/support icons in a card's
   title bar -- e.g. "Master Users Only". Same red, on a pale tint so it reads as a label rather
   than an error; normal weight so it does not compete with the title itself. */
.dashGroup .blk .item > .title .dshTitleNote {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    line-height: 1;
    font-size: 11px;
    font-weight: normal;
    color: #b42318;
    background-color: #fbe9e7;
    border-radius: 3px;
    padding: 1px 6px;
    white-space: nowrap;
}
/*
 * THE CALENDAR CARD WRAPS FIXED 36px DAY SQUARES (dshItem::calendarCard; asked for 2026-09-24,
 * "each calendar day square should be 36x36px").
 *
 * It used to be the other way round: a 270px card forced square with aspect-ratio, and the grid
 * rows stretched (minmax(0, 1fr)) to share whatever height was left. The squares were therefore
 * never a dependable size -- 34px wide and ~22px tall on a 6-row month -- and every attempt to
 * keep the card square traded one problem for another: dead space at the bottom, or the
 * checklist link pushed out past the card's edge. Now the grid is fixed (.dshCalGrid below:
 * 7 x 36px columns, 36px rows) and the card is simply as wide as the grid and as tall as the
 * month needs, five rows or six.
 *
 * `.dshCalendarBlk` USED TO override the ordinary col1-4 percentage width down to the grid's own
 * fixed size (2026-09-24) -- REVERSED 2026-09-28: every dashboard card must land on a clean
 * 1/2/3/4-column boundary, never a fraction, and shrinking to the 252px grid undershot col1-4's
 * ~24% on most screens ("a little short of one column"). The card box now takes the ordinary
 * col1-4 width like every other card; only the GRID inside stays a fixed 36px square (see
 * .dshCalGrid / .dshCalDow below, now centred rather than left-hugged so the fixed-size grid
 * doesn't read as stranded in a too-wide box).
 *
 * flex: 0 0 auto is KEPT (not reverted to the inherited flex: 1 1 auto) -- that is what stops
 * the card stretching past its col1-4 share when it is the only/last card in its .dashGroup row
 * (the bug this rule was originally written to fix, 2026-09-24). col1-4's own width/min-width/
 * max-width now does the sizing instead of a fixed pixel width.
 */
.dashGroup .blk.dshCalendarBlk { flex: 0 0 auto; }
/* .item now inherits the ordinary .dashGroup .blk .item rule (flex: 1 1 auto), so it fills its
   parent .blk's col1-4 box instead of shrinking to the grid's own width. */
.dashGroup .blk.dshCalendarBlk .item {
    display: flex;
    flex-direction: column;
}
.dashGroup .blk.dshCalendarBlk .item > .itemBody { display: flex; flex-direction: column; }
.dshCalWrap { display: flex; flex-direction: column; }
/* margin-top: 10px (asked for 2026-09-24; was 4px) -- more air between the grid and the link
   below it, plus a hairline divider so it reads as its own footer row rather than crowding
   the last week of the grid. */
/* border-top removed (asked for 2026-09-24) -- keeps the 10px + 6px gap above without the
   hairline divider that came with it. */
/* The 10px/6px gap above the footer row now lives on .dshCalFooter (the shared wrapper for
   this link and the subscribe icon, asked for 2026-09-28) rather than on the link itself. */
.dshCalChecklistLink { flex: 1 1 auto; display: block; text-align: left; font-size: 13px; min-width: 0; }
/* Checklist link on the left, Subscribe icon pinned to the right edge (asked for 2026-09-28,
   "bottom right of the calendar card") -- one flex row rather than the icon floating on its
   own line, so it reads as part of the card's footer chrome. flex:0 0 auto keeps the row
   itself from stretching or shrinking the rest of .dshCalWrap's column layout. */
.dshCalFooter { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; padding-top: 6px; flex: 0 0 auto; }
/* Same icon-button language as .dshCalNav just above (border, radius, hover, focus-visible),
   so the subscribe icon reads as one family with the rest of this card's chrome rather than a
   bolted-on control. 24x24 is the WCAG 2.2 2.5.8 touch-target floor. */
.dshCalSubscribeBtn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; flex: 0 0 auto;
    border: 1px solid var(--aceCardBorder); border-radius: 4px; background-color: #ffffff;
    color: var(--aceInk); font-size: 13px; line-height: 1; cursor: pointer;
    text-decoration: none;
}
.dshCalSubscribeBtn:hover { background-color: var(--aceAccent2, #EDF4F2); color: var(--aceInk); text-decoration: none; }
.dshCalSubscribeBtn:focus-visible { outline: 2px solid var(--aceAccent, #2b6cb0); outline-offset: 1px; }
/* << then the month-year, LEFT-aligned beside it; Today and >> pushed to the right edge
   (asked for 2026-09-25: Today "to the right next to >>", then "keep the month/year aligned
   left"). margin-left: auto on the right-hand group takes all the free space. */
.dshCalHead { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex: 0 0 auto; }
.dshCalHeadRight { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.dshCalTitle { font-size: 13px; font-weight: bold; color: var(--aceInk); }
/* Every geometry property is restated -- ace.css's global `button` rule otherwise adds its
   own shadow, border, margin, min-width and float:left (see the note beside .atnSearch .atnGo
   for the same trap). 24px is the WCAG 2.2 2.5.8 touch-target floor for a control this size. */
.dshCalNav {
    float: none; box-shadow: none; cursor: pointer;
    width: 24px; height: 24px; min-width: 24px; padding: 0; margin: 0;
    border: 1px solid var(--aceCardBorder); border-radius: 4px; background-color: #ffffff;
    font-size: 13px; line-height: 1; color: var(--aceInk);
}
.dshCalNav:hover { background-color: var(--aceAccent2, #EDF4F2); }
.dshCalNav:focus-visible { outline: 2px solid var(--aceAccent, #2b6cb0); outline-offset: 1px; }
/* "Today" shares .dshCalNav's border/hover/focus language, but carries a word instead of a
   glyph, so the fixed 24px square is widened into a small pill instead of clipping the text.
   11px is the style guide's chrome-text size (badges / small controls), not the 13px content
   floor -- this is chrome, not calendar content. Its own class: .dshCalToday is today's CELL. */
.dshCalTodayBtn { width: auto; min-width: 0; padding: 0 8px; font-size: 11px; font-weight: bold; }
/* Chrome, not content -- the day-of-week initials are a header row, the same reasoning the
   style guide gives for a 12px uppercase table heading. */
/* Same 36px columns as the grid below, and the same 1px left offset the grid's own left border
   gives its cells, so each initial sits centred over its column. */
.dshCalDow {
    display: grid; grid-template-columns: repeat(7, 36px); padding-left: 1px;
    text-align: center; font-size: 11px; font-weight: bold; text-transform: uppercase;
    color: var(--aceBorder); margin-bottom: 2px; flex: 0 0 auto;
    /* align-self: center (was flex-start until 2026-09-28) -- now that the card box takes the
       full col1-4 width instead of shrinking to the grid, centring the fixed-width day-of-week
       row keeps it lined up with the grid below rather than both reading as stranded on the
       left of a wider card. */
    align-self: center;
}
/*
 * GRID LINES, LIKE A NORMAL CALENDAR (asked for 2026-09-24; used to be bare spans with no
 * borders between them). The grid itself carries the lines on its OUTER edge and gets a
 * negative margin equal to the border width, so the outer edge does not read thicker than the
 * lines between cells -- the same 1px-collapse trick a plain HTML table gets for free from
 * border-collapse, done by hand because this is a CSS grid, not a table.
 */
/*
 * 36 x 36px DAY SQUARES (asked for 2026-09-24). Each cell is border-box and carries its own
 * right/bottom line, so 36px is the square as seen, lines included. Fixed tracks also settle
 * "every square the same height with or without a pill" for good: a row can no longer grow to
 * fit its content (number 13px + 1px gap + 14px pill + 3px padding top and bottom = 34px, inside
 * 36px) or shrink to fit the card.
 *
 * align-self: NOT stretch (the column-flex .dshCalWrap default) -- the grid box would otherwise
 * stretch to the card's full width whenever the heading or checklist link is wider than the
 * seven columns, running its top border out past the last column. center (was flex-start until
 * 2026-09-28, when the card itself grew from the grid's own 252px to a full col1-4 width) keeps
 * the fixed-size grid in the middle of the now-wider card instead of jammed against its left
 * edge with dead space on the right.
 */
.dshCalGrid {
    display: grid; grid-template-columns: repeat(7, 36px); grid-auto-rows: 36px;
    flex: 0 0 auto; align-self: center; text-align: center;
    border-top: 1px solid var(--aceCardBorder); border-left: 1px solid var(--aceCardBorder);
}
.dshCalGrid .dshCalCell,
.dshCalGrid .dshCalBlank {
    border-right: 1px solid var(--aceCardBorder); border-bottom: 1px solid var(--aceCardBorder);
    box-sizing: border-box;
}
/* justify-content: flex-start (asked for 2026-09-24; was center) -- the day number sits at
   the top of its square, same as a normal paper calendar, with the item pill directly under
   it rather than the whole pair floating in the cell's middle. */
.dshCalCell {
    display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
    gap: 1px; padding: 3px 0; min-width: 0; min-height: 0; cursor: pointer;
}
.dshCalCell:hover { background-color: var(--aceAccent2, #EDF4F2); }
.dshCalCell:focus-visible { outline: 2px solid var(--aceAccent, #2b6cb0); outline-offset: -2px; }
.dshCalNum { font-size: 13px; color: var(--aceInk); line-height: 1; }
/*
 * TODAY -- OUTLINE ONLY, SQUARE, NO FILL (asked for 2026-09-24; used to be a solid filled
 * circle). box-shadow: inset instead of `border` so the outline draws INSIDE the cell's own
 * grid-line border rather than adding to the cell's box size -- an actual `border` here would
 * make today's cell a pixel or two bigger than its neighbours and throw off the grid lines
 * around it. No border-radius: the ask was specifically no oval/circle -- today reads as a
 * squared-off cell, matching the rest of the grid's own right angles.
 */
.dshCalCell.dshCalToday { box-shadow: inset 0 0 0 2px var(--aceAccent, #57756F); }
.dshCalCell.dshCalToday .dshCalNum { font-weight: bold; }
/* 11px badge -- the style guide's explicit exception to the 13px content floor for a chip like
   this. --aceAccent2 / --aceAccent2Text: the same contrast-safe secondary-accent pairing the
   footer buttons and the to-do count pill use, so every small chip on the dashboard reads as
   one language. */
.dshCalPill {
    display: inline-block; min-width: 14px; height: 14px; line-height: 14px; padding: 0 3px;
    border-radius: 7px; font-size: 11px; font-weight: bold;
    background-color: var(--aceAccent2, #57756F); color: var(--aceAccent2Text, #ffffff);
    cursor: pointer;
}
.dshCalPill:hover { filter: brightness(0.92); }
/* The day-review/add modal (CAL::dayModal). Plain list, no bullets -- these are short one-line
   notes, not a document. */
.dshCalModalList { list-style: none; margin: 0 0 10px 0; padding: 0; font-size: 13px; }
.dshCalModalList li {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 5px 0; border-bottom: 1px solid var(--aceCardDivider, #eeeeee);
}
.dshCalModalList li:last-child { border-bottom: 0 none; }
.dshCalModalList li span { overflow-wrap: break-word; }
/* The "X", same shape/behaviour as the to-do list's own remove control (.dshTodoRemove). */
/* margin-left: auto (asked for 2026-09-24, "the X to the far right") -- belt and braces beside
   the row's own justify-content: space-between: an auto margin absorbs every bit of leftover
   space on its own, so the X sits flush against the row's right edge regardless of how that
   row is laid out. */
.dshCalItemRemove {
    flex: 0 0 auto; width: 20px; height: 20px; line-height: 20px; text-align: center;
    border-radius: 50%; cursor: pointer; color: var(--aceBorder); font-size: 15px;
    text-decoration: none; margin-left: auto;
}
.dshCalItemRemove:hover { background-color: #f7e6e6; color: #8a1c1c; }
.dshCalModalEmpty { font-size: 13px; color: var(--aceBorder); margin: 0 0 10px 0; }
/* COLUMN, NOT A ROW (changed 2026-09-24 for the 3-row textarea) -- a multi-line field beside a
   button reads oddly; the button sits below it now, right-aligned, the way a comment box's
   submit button normally sits under the box rather than beside it. */
.dshCalModalAdd { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.dshCalModalAdd textarea {
    width: 100%; box-sizing: border-box; resize: vertical;
    padding: 6px 8px; font-size: 13px; font-family: Arial, sans-serif; line-height: 1.35;
    border: 1px solid #8c8c8c; border-radius: 6px; background-color: #ffffff; color: #222222;
}
.dshCalModalAdd textarea:focus { outline: 2px solid #2b6cb0; outline-offset: 1px; border-color: #2b6cb0; }
.dshCalModalAdd .btnSecondary { float: none; margin: 0; height: 28px; padding: 0 12px; box-shadow: none; }
/* Share checkbox + Add button, same line (asked for 2026-09-28) -- the row itself still lands
   right-aligned because .dshCalModalAdd (its parent) is a column flex with align-items: flex-end. */
.dshCalModalAddRow { display: flex; align-items: center; gap: 12px; }
.dshCalModalAddRow .dshCalShareLink { margin: 0; }
.dshCalModalAddRow .btnSecondary { float: none; margin: 0; height: 28px; padding: 0 12px; box-shadow: none; }
/* SchoolLink (asked for 2026-09-24): the checkbox that fans a new item out to a person's other
   linked schools, and the icon marking an item that already was. One icon style shared by both
   the calendar modal and the to-do list. */
/* flex, not block (changed 2026-09-28 for the checkbox + Add same-line layout) -- centres the
   checkbox against the text the same way .dshTodoShareLink already does. */
.dshCalShareLink { display: flex; align-items: center; gap: 6px; font-size: 13px; margin: 6px 0; cursor: pointer; }
/* Same explicit geometry as .dshTodoShareLink's checkbox below, and the SAME SIZE (asked for
   2026-09-28: "use this same size checkbox on MDC0CB6 too") -- restated rather than left to the
   browser default so the two can never drift apart even though this one has never been reported
   broken the way the to-do list's was. */
.dshCalShareLink input[type=checkbox] {
    display: inline-block; float: none; width: 14px; height: 14px; min-width: 14px;
    margin: 0; flex: 0 0 auto; cursor: pointer; opacity: 1; visibility: visible; position: static;
}
/* SchoolLink settings (M722936) -- the school-picker list in columns (asked for 2026-09-24).
   column-gap keeps a comfortable gutter; each label avoids breaking across a column boundary
   (a checkbox on one column's bottom edge with its own name at the top of the next reads as two
   broken rows instead of one). 3 columns only once there is room for them at 700px wide with
   text this size -- narrower windows fall back to 2, then 1 via the max-width query. */
.slkSchoolCols { column-count: 3; column-gap: 24px; }
.slkSchoolCols label { break-inside: avoid; -webkit-column-break-inside: avoid; }
@media ( max-width: 620px ) { .slkSchoolCols { column-count: 2; } }
@media ( max-width: 380px ) { .slkSchoolCols { column-count: 1; } }
.dshSchoolLinkIcon { color: var(--aceAccent, #57756F); margin-right: 4px; font-size: 13px; vertical-align: -1px; }
/* The undone-count pill IN THE TITLE BAR (dshItem::toDoList), same 11px-badge language as
   .dshCalPill above. vertical-align keeps it level with the title text beside it rather than
   sitting on the baseline a few px low.
   A DARK OUTLINE (asked for 2026-09-24, after "more contrast from the background") -- a fixed
   dark border rather than a lighter/darker fill, because the fill colour comes from the
   entity's own --aceAccent2 and this file cannot know whether that will read as light or dark
   against the title bar; a literal dark line separates the pill from its background either way. */
.dashGroup .blk .item > .title .dshTodoCountPill {
    display: inline-block; min-width: 16px; height: 16px; line-height: 14px; padding: 0 4px;
    border-radius: 8px; font-size: 11px; font-weight: bold; vertical-align: middle;
    background-color: var(--aceAccent2, #57756F); color: var(--aceAccent2Text, #ffffff);
    border: 1px solid #2b2b2b; box-sizing: border-box;
}
/*
 * THE TO-DO LIST CARD (dshItem::toDoList / TDI, finished 2026-09-24). Every geometry property
 * on the button and input is restated for the same reason as .dshCalNav above -- ace.css's
 * global `button` rule otherwise adds its own shadow, border, margin, min-width and float.
 */
.dshTodoWrap { font-size: 13px; }
.dshTodoAdd { display: flex; gap: 6px; margin-bottom: 8px; }
.dshTodoInput {
    flex: 1 1 auto; min-width: 0; box-sizing: border-box;
    height: 28px; padding: 2px 8px; font-size: 13px; font-family: Arial, sans-serif;
    border: 1px solid #8c8c8c; border-radius: 6px; background-color: #ffffff; color: #222222;
}
.dshTodoInput:focus { outline: 2px solid #2b6cb0; outline-offset: 1px; border-color: #2b6cb0; }
/* justify-content: flex-end (asked for 2026-09-28) -- the label is a full-width flex container
   (its own box is not constrained), so this pushes the checkbox and text to the row's right
   edge rather than centering only the CONTENTS of an already-right-aligned box. */
.dshTodoShareLink { display: flex; align-items: center; justify-content: flex-end; gap: 6px; font-size: 13px; margin: 0 0 8px; cursor: pointer; }
/* Reported 2026-09-28: the checkbox was not visibly appearing next to the "SchoolLink" label
   text, only the text itself. Every geometry property is restated here rather than left to
   inherit -- the same defensive pattern .dshCalNav and others in this file already use -- so
   nothing an ancestor or a later global rule sets can shrink or hide it again. flex on the
   label (was display:block) plus align-items:center is what keeps the box centred against
   13px text instead of sitting on its own baseline.
   14px, not 16px (asked for 2026-09-28: "use the same size checkbox for the items and the share
   box, the smaller box") -- matches .dshTodoItem's own per-item checkboxes below and
   .dshCalShareLink's above, so all three read as the same control. Only the SIZE moved; the
   display/float/opacity/visibility/position overrides that actually fixed the original
   invisibility bug are unchanged. */
.dshTodoShareLink input[type=checkbox] {
    display: inline-block; float: none; width: 14px; height: 14px; min-width: 14px;
    margin: 0; flex: 0 0 auto; cursor: pointer; opacity: 1; visibility: visible; position: static;
}
.dshTodoAddBtn {
    float: none; box-shadow: none; margin: 0; min-width: 0;
    height: 28px; padding: 0 12px; font-size: 13px; cursor: pointer;
}
.dshTodoEmpty { font-size: 13px; color: var(--aceBorder); margin: 0; }
.dshTodoList { list-style: none; margin: 0; padding: 0; }
.dshTodoItem {
    display: flex; align-items: center; gap: 8px;
    padding: 5px 0; border-bottom: 1px solid var(--aceCardDivider, #eeeeee);
}
.dshTodoItem:last-child { border-bottom: 0 none; }
.dshTodoItem label { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; cursor: pointer; }
/* Same explicit size as .dshTodoShareLink's checkbox (asked for 2026-09-28: "use the same size
   checkbox for the items and the share box") -- this one was never explicitly sized before, so
   without this rule the two would only match by coincidence of the browser's own default. */
.dshTodoItem input[type=checkbox] {
    display: inline-block; float: none; width: 14px; height: 14px; min-width: 14px;
    margin: 0; flex: 0 0 auto; cursor: pointer; opacity: 1; visibility: visible; position: static;
}
.dshTodoItem label span { overflow-wrap: break-word; }
/* Struck through and quieted, not hidden -- checking a box is a satisfying "done", and an
   item that vanished the instant you clicked it would read as it having been deleted. */
.dshTodoItem.dshTodoDone label span { text-decoration: line-through; color: var(--aceBorder); }
.dshTodoRemove {
    flex: 0 0 auto; width: 20px; height: 20px; line-height: 20px; text-align: center;
    border-radius: 50%; cursor: pointer; color: var(--aceBorder); font-size: 15px;
    text-decoration: none;
}
.dshTodoRemove:hover { background-color: #f7e6e6; color: #8a1c1c; }
/* Deferred (AJAX-loaded) widgets: centre the spinner in the space the card will occupy. */
.dashGroup .blk.replaceDshBrd { align-items: center; justify-content: center; min-height: 140px; }
/* ...unless the user has that card collapsed -- then it only needs a title bar's worth. */
.dashGroup .blk.replaceDshBrd.cardCollapsed { min-height: 40px; }
.dashGroup .blk.replaceDshBrd.cardCollapsed img { max-height: 28px; width: auto; }

/* An empty row takes up no space until a drag starts, then becomes a visible
   "start a new row" drop zone. Without these rows, cards could only ever be
   moved between the rows the dashboard already built. */
.dashGroup.dshEmptyRow { padding: 0 6px; }
.dashGroup .dshRowHint { display: none; }
body.dshDragging .dashGroup.dshEmptyRow { padding: 6px; }
body.dshDragging .dashGroup.dshEmptyRow .dshRowHint {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    flex: 1 1 100%;
    min-height: 54px;
    margin: 0 8px;
    border: 2px dashed var(--aceAccent, #A9C6C0);
    border-radius: 10px;
    background-color: #EAF1EF;
    color: var(--aceAccent, #57756F);
    font-size: 13px;
}
/* Once a card is hovering over the row, the placeholder says it better than the hint. */
body.dshDragging .dashGroup.dshEmptyRow:has(.dshCardPlaceholder) .dshRowHint { display: none; }

/* Dashboard footer: reset control on the left, the school's logo centred.
   The two .dashFootSide cells are equal-width, which is what keeps the logo in
   the true middle of the page rather than the middle of the leftover space. */
.dashFooter {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    width: 100%;
    clear: both;
    padding: 6px 14px 12px 14px;
    background-color: #FFFFFF;
    text-align: left;
}
.dashFooter .dashFootSide { flex: 1 1 0; min-width: 0; }
.dashFooter .dashFootLogo { flex: 0 0 auto; text-align: center; padding: 0 12px; }
.dashFooter .dashFootLogo img {
    display: inline-block;
    height: 100px;
    max-width: 100%;
    width: auto;
    opacity: 0.9;
    transition: opacity 0.15s ease;
}
/* Linked to the school's website (Entity Settings -> Appearance -> Website). */
.dashFooter .dashFootLogo a { display: inline-block; text-decoration: none; border: 0 none; }
.dashFooter .dashFootLogo a img { cursor: pointer; }
.dashFooter .dashFootLogo a:hover img { opacity: 1; }
/* Shown only while the school is still on the shared CharterAce mark. */
.dashFooter .dashFootLogoUpload { margin-top: 4px; font-size: 13px; }
.dashFooter .dashFootLogoUpload a { display: inline-block; cursor: pointer; white-space: nowrap; }
.dashFooter .dashFootLogoUpload a:hover { text-decoration: underline; }
.dashFooter .dshResetLayout { color: var(--aceAccent, #57756F); font-size: 13px; cursor: pointer; }
.dashFooter .dshResetLayout:hover { color: var(--aceInk); text-decoration: underline; }
/* The right-hand cell carries every layout control, stacked. A flex column rather than
   display:block on the anchors: the links are inline elements, and this keeps the
   right-alignment (align-items) and the spacing (gap) in one place, so the 700px rule
   below only has to flip align-items to re-centre the whole stack. */
.dashFooter .dashFootActions { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.dashFooter .dashFootActions a { white-space: nowrap; }
.dashFooter .dshDefaultLayout { color: var(--aceAccent, #57756F); font-size: 13px; cursor: pointer; }
.dashFooter .dshDefaultLayout:hover { color: var(--aceInk); text-decoration: underline; }

@media (max-width: 700px) {
    /* Narrow screens: stack the logo above the layout controls instead of squeezing both. */
    .dashFooter { flex-wrap: wrap; justify-content: center; }
    .dashFooter .dashFootSide { flex: 1 1 100%; text-align: center; }
    .dashFooter .dashFootLogo { flex: 1 1 100%; margin-top: 8px; }
    /* The controls cell is a flex column, so text-align above does not centre it -- its
       children are flex items, and align-items is what positions them on the cross axis. */
    .dashFooter .dashFootActions { align-items: center; }
    /* Empty on every screen; without this it takes a full row of its own and pushes the
       logo down by its (zero-content but still laid-out) line box. */
    .dashFooter .dashFootSide:empty { display: none; }

    /* Phones: pull the top-bar logo over to the left, next to the menu button.
       header.php centres it with an inline "margin: auto", so this needs !important to
       win. Floating rather than just zeroing the left margin matters: the logo is a
       display:block img, and a block box does not shrink away from the floated
       hamburger -- left-aligning it any other way slides it underneath the menu icon. */
    #topBar #topBarLogo { float: left !important; margin: 0 0 0 6px !important; }
    /* The logo is wrapped when the screen-code switch is on the bar (header.php), and it
       is the WRAPPER that has to move -- floating the image inside it would take the
       image out of flow and collapse the wrapper to no height, taking the switch with
       it. So the wrapper floats and the image inside goes back to being plain. */
    #topBar #topBarLogoWrap { float: left !important; margin: 0 0 0 6px !important; }
    #topBar #topBarLogoWrap #topBarLogo { float: none !important; margin: 0 !important; }

    /* Phones: the top bar STACKS onto two rows --
         line 1  hamburger, logo, then the icon buttons pushed right
         line 2  the history + pin pills, then the user's name and school
       All of it used to be crammed onto one 45px line: #topBarRight is bottom-anchored
       (position: absolute; bottom: 0), so when its contents ran out of width the overflow line
       grew UPWARD and the buttons were clipped off the top of the bar. Squeezing it into a
       nowrap row (what was here before) stopped the clipping but ellipsised the school name
       down to nothing and left no room for the pins at all.

       display: contents on #topBarRight is what makes two rows possible: it stops generating a
       box, so ITS children become flex items of #topBar directly and can be ordered onto either
       line. The element itself keeps its identity in selectors -- display: contents changes
       box generation, not the DOM -- so "#topBar #topBarRight > ul" still matches, which is how
       the change-organization <a> is told apart from the hamburger <a> beside it.

       The line breaks are #topBar::after and #topBar::before: a pseudo-element on a flex
       container IS a flex item, so a zero-height item at 100% width, ordered between two groups,
       ends a line. Two of them give three rows with no markup and none needed. They are used in
       ORDER, not in name order -- ::after ends row 1 and ::before ends row 2, which looks
       backwards and is not: only the `order` values decide where a flex item lands.

       Orders are stated for everything on the bar. An item with no order falls to 0 and would
       silently jump to the front of line 1. */
    #topBar { display: flex; flex-wrap: wrap; align-items: center; height: auto;
              min-height: 45px; row-gap: 2px; padding-bottom: 2px; }
    /* THE RULE THE PARAGRAPH ABOVE IS ABOUT. Without it #topBarRight keeps the base
       `display: block; position: absolute; bottom: 0`, its children are never hoisted, and
       every order below silently applies to nothing.
       position and order are the fallback for a browser that will not do display: contents:
       the block then stays one in-flow item and lands after the logo, which is at least the
       old single-row arrangement rather than a pile at the front of the bar. */
    #topBar #topBarRight { display: contents; position: static; order: 4; }
    /* The environment banner ("Online Testing Site" and friends) -- only on the non-live
       servers, and only ever a direct child span. Shrinkable, because it is the least important
       thing on the line. */
    #topBar > span { order: 2; flex: 0 1 auto; min-width: 0; overflow: hidden;
                     white-space: nowrap; text-overflow: ellipsis; font-size: large !important; }
    #topBar #topBarLogo { order: 3; flex: 0 0 auto; }
    #topBar #topBarLogoWrap { order: 3; flex: 0 0 auto; }
    /* THE ICON GROUP, IN THE SAME LEFT-TO-RIGHT ORDER AS THE DESKTOP.
       On a wide screen these are not ordered by the DOM at all: #topBar ul is `float: right`
       while #sysInfoWrap and the change-organization <a> are inline, so the floated LIST ends
       up right of both of them -- info, change-org, then the menu icons. The first version of
       this block ordered the list first, which is why the six icons came out in a different
       order on a phone than on a desktop.
       margin-left: auto sits on whichever item is FIRST in the group; that is what pins the
       whole group to the right-hand end of line 1. */
    #topBar #topBarRight > #sysInfoWrap { order: 4; flex: 0 0 auto; margin-left: auto; }
    #topBar #topBarRight > a { order: 5; flex: 0 0 auto; }
    /* row-reverse inside the list reproduces `#topBar li { float: right }`, which reverses the
       list against its source order on the desktop. */
    #topBar #topBarRight > ul { order: 6; flex: 0 0 auto; display: flex;
                                flex-wrap: nowrap; flex-direction: row-reverse; float: none; }
    #topBar #topBarRight > ul > li { float: none; flex: 0 0 auto; }
    #topBar::after { content: ''; order: 7; flex: 0 0 100%; height: 0; }
    /* Line 2 -- who you are and which school you are in. !important on the margin because
       header.php sets `margin: 14px 5px 0 0` inline to drop it onto the 45px bar's baseline; an
       inline style outranks any stylesheet rule without it, and 14px of top margin on a row of
       its own just makes the bar taller. Allowed to shrink and ellipsise -- a long school name
       must not push the row wider than the screen. */
    #topBar #topBarRight > div:not(#sysInfoWrap) {
                                 order: 8; flex: 0 1 auto; min-width: 0; float: none;
                                 margin: 0 5px 0 6px !important; overflow: hidden;
                                 white-space: nowrap; text-overflow: ellipsis; }
    #topBar::before { content: ''; order: 9; flex: 0 0 100%; height: 0; }
    /* Line 3 -- the history and pin pills. Absolutely positioned into the hamburger/logo gap on
       wide screens; here an ordinary item on a row of its own, centred on it.
       margin: 0 auto is what centres it -- an auto margin on a flex item absorbs the free space
       on that side, and with the row to itself there is free space on both. That is also why
       this cannot be done with justify-content: that lives on the container and would move
       every row, including the hamburger. */
    #topBar #acePinBar { order: 10; position: static; top: auto; bottom: auto; left: auto;
                         flex: 0 0 auto; margin: 0 auto; }

    /* Phones: the stat bar is one collapsible card.
       Eight tiles two-across is most of a phone screen before the dashboard's actual cards
       start, so the whole bar shuts into a single header. It rides the same collapse plumbing
       as every dashboard card -- .dshCardToggle to operate it, .cardCollapsed as the state,
       DSH::saveCardCollapsed to remember it -- so it reopens where the user left it, and the
       state is applied server-side while the page renders rather than after paint. */
    /* EVERY VALUE HERE IS COPIED FROM THE REAL CARDS -- .dashGroup .blk .item and its
       > .title, further up this file. This bar sits directly above them, so anything that
       does not match reads as a different component. If those are ever retuned, retune these
       with them: white ground, --aceCardBorder, 10px radius and the same soft shadow for the
       card; --aceAccent2 ground, --aceAccent2Text ink, `large` bold and a --aceCardDivider
       rule for the header.
       The two deliberate differences: margin-bottom is a little larger, because this card is
       a section above the dashboard rather than one of its tiles; and the cursor is a pointer,
       not `move` -- a real card's title bar is also its drag handle, and this one is not. */
    .dashStatsCard {
        background: #FFFFFF;
        border: 1px solid var(--aceCardBorder, #D8E2E0);
        border-radius: 10px;
        box-shadow: 0 1px 3px rgba(0,0,0,0.08);
        overflow: hidden;
        margin: 8px 8px 12px 8px;
    }
    .dashStatsCard:hover { box-shadow: 0 2px 6px rgba(0,0,0,0.14); }
    .dashStatsCard > .dashStatsTitle {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        font-size: large;
        font-weight: bold;
        color: #333333;   /* flat title ink -- see .hlpTopicPopHeader */
        margin: 0;
        padding: 8px 14px;
        background-color: var(--aceAccent2, #F7FAF9);
        border-bottom: 1px solid var(--aceCardDivider);
        border-radius: 9px 9px 0 0;
        cursor: pointer;
    }
    .dashStatsCard > .dashStatsTitle:hover { background-color: #EDF4F2; }
    .dashStatsCard > .dashStatsTitle:focus-visible { outline: 2px solid var(--aceAccent, #2b6cb0); outline-offset: -2px; }
    .dashStatsCard > .dashStatsTitle > .titleText { flex: 1 1 auto; }
    /* Same chevron treatment as a card's, including the flip on collapse. */
    .dashStatsCard .dshCardChevron {
        flex: 0 0 auto;
        color: var(--aceAccent, #57756F);
        font-size: 14px;
        line-height: 1;
        padding: 2px 2px 2px 8px;
    }
    .dashStatsCard .dshCardChevron i { display: inline-block; transition: transform 0.15s ease; }
    /* Shut: the header IS the card, so it takes the full radius and loses its bottom rule --
       exactly what .item.cardCollapsed > .title does. */
    .dashStatsCard.cardCollapsed > .dashStatsTitle { border-bottom: 0 none; border-radius: 9px; }
    .dashStatsCard.cardCollapsed > .dashStats { display: none; }
    .dashStatsCard.cardCollapsed .dshCardChevron i { transform: rotate(180deg); }
    /* The row's own white ground and radius are the card's job now. */
    .dashStatsCard > .dashStats { background: transparent; border-radius: 0; }

    /* Phones: the footer STACKS -- favourites, then the notices line, then the search.
       .copyright is normally an absolutely positioned box centred on the bar; at phone width
       it is wider than the screen, so it hung off both edges and landed on the search field.
       This used to be answered by putting all three on one nowrap row and letting the
       copyright ellipsize, which kept the bar 40px tall but CUT OFF the very text it was
       hiding behind -- "Need Help? Report a Bug?" was never readable on a phone. Three rows
       show all of it.

       Order is set explicitly rather than left to the DOM so the intent is legible here:
       icons, notices, search. It happens to match source order today.

       height: auto is safe because the 40px is not reserved anywhere -- ace_start.js measures
       $("#footerBar").height() and sizes #mainContent from it, so a taller bar simply takes
       its space from the content area on the next resize pass. */
    #footerBar { display: flex; flex-direction: column; flex-wrap: nowrap;
                 align-items: center; justify-content: center; gap: 2px;
                 height: auto; min-height: 40px; padding: 4px 6px; }
    /* An empty div is still a flex ITEM and would open a gap above the icons. It is populated
       and shown by ace_end.js only when there is something to hover over. */
    #footerBar #hoverInfoBox:empty { display: none; }
    /* The favourites wrap onto a second line rather than run off the edge -- .favItem is
       inline-block, so centring the text centres the row. */
    #footerBar #footerShortcuts { order: 1; flex: 0 0 auto; float: none;
                                  max-width: 100%; text-align: center; }
    /* white-space: normal, NOT the nowrap+ellipsis this used to carry: the whole point of
       stacking is that the line is readable, and it is allowed to take two lines to do it. */
    #footerBar .copyright { order: 2; position: static; top: auto; bottom: auto; left: auto;
                            transform: none; width: auto; max-width: 100%; margin: 0;
                            display: block; flex: 0 0 auto; text-align: center;
                            line-height: 1.4; white-space: normal; overflow: visible;
                            text-overflow: clip; }
    /* The text size control now stacks BEFORE the search box (order 3, was 4) -- the desktop
       swap 2026-09-24, restated here so a phone reads them in the same order a wide screen
       shows them left-to-right. Centred, and stops floating like the search below. */
    #footerBar #aceZoomCtl { order: 3; flex: 0 0 auto; float: none; height: auto; margin: 0; }
    /* The field and Go keep their look but stop floating -- a float inside a column flex item
       leaves the form with no height and the row collapses. row-REVERSE because the button is
       first in the source and float:right is what put it on the right on desktop; reversing
       reproduces that order without touching the markup. Now order 4 (was 3) -- see above. */
    #footerBar #systemSearchTool { order: 4; flex: 0 0 auto; float: none; margin: 0; }
    #footerBar #systemSearchForm { display: flex; flex-direction: row-reverse;
                                   align-items: center; justify-content: center; }
    #footerBar #mainSystemSearchGoButton { float: none; margin: 0; }
    /* 60vw so it still fits beside Go on the narrowest phones, 240px so it does not sprawl
       on a small tablet. */
    #footerBar #mainSystemSearch { float: none; width: min( 130px, 30vw ); margin: 0 5px 0 0; }   /* halved 2026-09-23, +10px 2026-09-24 */
}

/* Drag and drop: the gap the card will land in, and the card being dragged. */
.dashGroup .dshCardPlaceholder {
    box-sizing: border-box;
    margin: 8px;
    border: 2px dashed #A9C6C0;
    border-radius: 10px;
    background-color: #E7EFED;
}
.dashGroup .blk.ui-sortable-helper { z-index: 900; }
.dashGroup .blk.ui-sortable-helper .item { box-shadow: 0 6px 16px rgba(0,0,0,0.22); }
.col1-3 { max-width: 100%; min-width: 33%; width: 33%; }
.col2-3 { max-width: 100%; min-width: 66%; width: 66%; }
.col3-3 { width: 100%; }
.col1-2 { max-width: 100%; min-width: 50%; width: 50%; }
.col2-2 { width: 100%; }
.col1-4 { max-width: 100%; min-width: 24%; width: 24%; }
.col2-4 { max-width: 100%; min-width: 49%; width: 49%; }
.col3-4 { max-width: 100%; min-width: 74%; width: 74%; }
.col4-4 { width: 100%; }

/* Narrow screens: dashboard cards stack full width instead of squeezing into columns.
   Scoped to .dashGroup so the generic colN-N classes are untouched elsewhere. */
@media (max-width: 900px) {
    .dashGroup .blk { min-width: 100%; width: 100%; max-width: 100%; }
}

.bgColor1 { background-color: var(--aceSurface);}
.bgColor2 { background-color: var(--aceHighlight);}
.bgColor3 { background-color: var(--aceMint);}
.bgColor4 { background-color: var(--aceBrand);}
.bgColor5 { background-color: var(--aceBorder);}
.bgColor6 { background-color: var(--aceInk);}

/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Detail Groups"> */ 
    .detailGroup { 
        display: block; 
        float: left; 
        border: 1px solid black; 
        padding: 0px; 
        width: 150px; 
    }
    .detailGroup .label { 
        display: block;
        background-color: var(--aceBrand); 
        border: 0 0 1px 0 solid black; 
        text-align: center;
        font-weight: bold;
        clear: both; 
        padding: 2px 4px 1px 4px; 
    }
    .detailGroup .info {
        display: block; 
        background-color: white; 
        clear: both; 
        padding: 2px 4px 2px 4px; 
        min-height: 23px; 
    }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Budget Formats"> */ 
    table.budget_table { 
        border-collapse: collapse; 
        table-layout: fixed; 
        width: 95%; 
        border: 3px solid black; 
        margin: 5px auto; 
    }
    table.budget_table td, table.budget_table tr, table.budget_table th { 
        min-width: 15px; 
    }
    table.budget_table td { 
        border: 1px solid black; 
        text-align: right; 
        font-size: small;
    }
    table.budget_table th.lvl1.income { background-color: #6471b6; text-align: left; font-size: x-large; font-weight: bolder; }
    table.budget_table th.lvl2.income { background-color: #727dbc; text-align: left; font-size: large; font-weight: bold; }
    table.budget_table th.lvl3.income { background-color: #868ec6; text-align: left; font-size: large;}
    table.budget_table th.lvl4.income { background-color: #9ea3d2; text-align: left; }
    table.budget_table th.lvl5.income { background-color: #b9bcdf; text-align: left; }
    table.budget_table th.lvl6.income { background-color: #d5d6ec; text-align: left; }
    
    table.budget_table th.lvl1.expense { background-color: #ffa40a; text-align: left; font-size: x-large; font-weight: bolder; }
    table.budget_table th.lvl2.expense { background-color: #ffb02b; text-align: left; font-size: large; font-weight: bold; }
    table.budget_table th.lvl3.expense { background-color: #ffc057; text-align: left; font-size: large;}
    table.budget_table th.lvl4.expense { background-color: #ffd286; text-align: left; }
    table.budget_table th.lvl5.expense { background-color: #ffe3b5; text-align: left; }
    table.budget_table th.lvl6.expense { background-color: #fff3de; text-align: left; }
    
    table.budget_table th:not(:empty) { border-top: 1px solid black; }
    table.budget_table th { border-left: 1px solid black; }
    table.budget_table td.annual { border-left: 3px solid black; border-right: 3px solid black; font-weight: bold; background-color: var(--aceHighlight); font-size: medium; }
    table.budget_table input { width: 95%; margin: auto; color: blue; font-weight: bold; background-color: yellow; }
    table.budget_table th.detailRow span.accountDescription { display: block; clear: both; font-size: 13px; font-style: italic; overflow: hidden; white-space: nowrap; font-weight: normal; }
    table.budget_table th.labelRow span.accountDescription { font-style: italic; font-weight: normal;}
    table.budget_table tr.total.income { border-top: 4px solid black; } 
    table.budget_table td.total { font-size: large; font-weight: bold; }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Help Screens"> */
.help_box { margin: 10px; display: block; max-width: 752px; border: 1px solid black; background-color: #dcdcdc; }
.help_box h2 { text-align: center; }

/* Modern Help page ------------------------------------------------------ */
/* THE help icon. Every "?" in the application is this one rule -- size, weight and the gap
   after the title. Nothing else may restate width/height/font-size/vertical-align for it:
   the dashboard cards and the pin/history/watch headings each used to set their own 13px,
   which is why the same icon read at three different sizes depending on the screen.
   font-weight is stated because most title bars are bold and the glyph would inherit it.

   COLOUR IS `inherit`, and that is the only way it can be the same everywhere. A modal title
   bar is painted with --aceAccent2, which is the SCHOOL'S OWN accent taken from its logo
   (STG::accentTextColor), so --aceAccent2Text is computed per school as #FFFFFF or #333333 --
   whichever reads on it. A fixed grey would be a mid-tone icon on a dark bar for any school
   that picked a dark accent. Inheriting means the "?" is always exactly the colour of the
   title it follows, on every palette, with no per-context rule to drift. Hover paints its own
   background, so it reads on a dark bar and a light one alike. */
/* TEN PIXELS, EVERYWHERE, AND THE SIZE IS !important ON PURPOSE (2026-09-16).
   The "?" is appended to headings that run from 12px to 20px and to plain body text, so the
   temptation on any one screen is a local rule making it "fit" that heading -- and the moment
   two screens do that, the same control is three sizes in three places and the reader stops
   recognising it. The purchase order page did exactly this and shipped a 15px one. The size is
   the icon's identity, not the heading's, so a per-screen rule cannot have it. MARGIN AND COLOUR
   ARE DELIBERATELY NOT LOCKED: how much air it needs does depend on what it follows (the
   dashboard cards and .nlfSecTitle both set their own), and the ink is inherited so it reads on
   whatever ground it lands on.
   The 10x10 box is below WCAG 2.2's 24px pointer target, and stays there under 2.5.8's INLINE
   exception: the icon sits within a line of heading text and its size is constrained by that
   line. It is unchanged from what has always shipped -- this only stops screens drifting off it. */
.hlpIconLink { display: inline-flex; align-items: center; justify-content: center; width: 10px !important; height: 10px !important; margin-left: 5px; color: inherit; cursor: pointer; text-decoration: none; border-radius: 50%; font-size: 10px !important; font-weight: normal; vertical-align: middle; line-height: 1; flex: 0 0 auto; }
.hlpIconLink:hover { color: var(--aceHelpLink); background: var(--aceHelpTint); }
.hlpIconLink i { line-height: 1; font-size: inherit !important; }
/* The help tab strip and every tab body render in Arial. jQuery UI puts a font-family
   on .ui-widget -- and again on the form controls inside it -- and the CDN theme loaded
   after the local one is not Arial, so stating it on the wrapper alone is not enough. */
.hlpTabs,
.hlpTabs .ui-widget,
.hlpTabs .ui-widget input,
.hlpTabs .ui-widget select,
.hlpTabs .ui-widget textarea,
.hlpTabs .ui-widget button { font-family: Arial, sans-serif; }
/* Body text in every tab is 14px. Headings are pinned in rem (root-relative) so they
   keep the sizes they render at today instead of scaling down off the 14px -- the
   values are the browser's own h1-h6 defaults. Tabs whose content sets its own sizes
   (the Documentation tab's .hlpDoc headings, the Zoho ticket form) are more specific
   and keep theirs. */
.hlpTabs, .hlpTabs .ui-widget { font-size: 13px; }
.hlpTabs h1 { font-size: 2rem; }
.hlpTabs h2 { font-size: 1.5rem; }
.hlpTabs h3 { font-size: 1.17rem; }
.hlpTabs h4 { font-size: 1rem; }
.hlpTabs h5 { font-size: 0.83rem; }
.hlpTabs h6 { font-size: max(13px, 0.67rem); }
.hlpTabs .ui-tabs .ui-tabs-nav li { font-size: 13px; height: auto; line-height: normal; padding: 0; }
.hlpTabs .ui-tabs .ui-tabs-nav li a { padding: 6px 14px; font-size: 13px; }
.hlpTabs .ui-tabs .ui-tabs-nav li i { font-size: 13px; margin-right: 3px; }
/* Support Ticket tab: the Zoho web-to-case form ships its own <style> block (.zsFontClass
   at 13px) which is injected into the page after this file, so matching it needs more
   specificity, not just a later rule. Form controls are listed out because they do not
   inherit font settings from their container by default. */
.hlpTabs #zohoSupportWebToCase,
.hlpTabs #zohoSupportWebToCase table,
.hlpTabs #zohoSupportWebToCase td,
.hlpTabs #zohoSupportWebToCase span,
.hlpTabs #zohoSupportWebToCase strong,
.hlpTabs #zohoSupportWebToCase input,
.hlpTabs #zohoSupportWebToCase select,
.hlpTabs #zohoSupportWebToCase textarea,
.hlpTabs #zohoSupportWebToCase button,
.hlpTabs #zohoSupportWebToCase .zsFontClass { font-family: Arial, sans-serif; font-size: 13px; }
/* Legal Notices policy list (EULA, Terms, Privacy, Cookie, Disclaimer). Stated on the
   list itself, not just inherited, because this block is also rendered outside the tabs. */
.hlpLegal, .hlpLegal li, .hlpLegal a { font-family: Arial, sans-serif; font-size: 13px; }
/* Help body text is 12px on both surfaces -- .hlpDoc is the root of the full help page
   AND of the help popup (which adds .hlpTopicPop). Titles and headings are unaffected:
   every one of them below carries its own px size (26 / 22 / 20 / 17 / 15), as does the
   popup's title bar (.popped.poppedHelp .hlpTopicPopHeader). */
.hlpDoc { max-width: 1100px; margin: 0 auto; font-size: 13px; font-family: Arial, sans-serif; }
.hlpDoc .hlpHeader { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid #d0d4dc; margin-bottom: 12px; }
.hlpDoc .hlpHeader h1 { margin: 0; font-family: Arial, sans-serif; font-size: 26px; color: var(--aceHelpInk); flex: 1; }
.hlpDoc .hlpHeader .hlpSearch { position: relative; flex: 0 1 320px; }
.hlpDoc .hlpHeader .hlpSearch i { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--aceHelpMuted); pointer-events: none; }
.hlpDoc .hlpHeader .hlpSearch input { width: 100%; padding: 7px 10px 7px 32px; border: 1px solid #c9cfda; border-radius: 20px; font-size: 13px; background: #fff; box-sizing: border-box; }
.hlpDoc .hlpHeader .hlpSearch input:focus { outline: none; border-color: var(--aceHelpLink); box-shadow: 0 0 0 3px rgba(46,116,167,.15); }

.hlpDoc .hlpBody { display: grid; grid-template-columns: 260px 1fr; gap: 18px; align-items: start; }
.hlpDoc .hlpTOC { min-width: 0; max-height: calc(100vh - 200px); overflow-y: auto; position: sticky; top: 10px; padding: 8px; border-right: 1px solid #e2e5ec; font-size: 13px; }
.hlpDoc .hlpTOC ul { list-style: none; margin: 0; padding-left: 12px; }
.hlpDoc .hlpTOC > ul { padding-left: 0; }
.hlpDoc .hlpTOC li { margin: 1px 0; }
.hlpDoc .hlpTOC .tocRow { display: flex; align-items: center; padding: 4px 6px; border-radius: 4px; cursor: pointer; color: var(--aceInkDeep); font-size: 13px; line-height: 1.35; text-decoration: none; border-left: 2px solid transparent; }
.hlpDoc .hlpTOC a.tocRow { color: var(--aceInkDeep); text-decoration: none; }
.hlpDoc .hlpTOC .tocRow:hover { background: var(--aceHelpTint); }
.hlpDoc .hlpTOC .tocRow.active { background: #e3ecf6; color: var(--aceHelpInk); font-weight: bold; border-left-color: var(--aceHelpLink); }
.hlpDoc .hlpTOC a.tocRow:hover, .hlpDoc .hlpTOC a.tocRow:focus { text-decoration: none; color: var(--aceHelpInk); }
.hlpDoc .hlpTOC .tocRow.hasKids > .tocCaret { display: inline-block; width: 14px; margin-right: 2px; font-size: 10px; color: var(--aceHelpMuted); text-align: center; }
.hlpDoc .hlpTOC .tocRow:not(.hasKids) > .tocCaret { display: inline-block; width: 14px; margin-right: 2px; }
.hlpDoc .hlpTOC .tocRoot > li > .tocRow.hasKids > .tocCaret { width: 18px; font-size: 14px; color: var(--aceHelpBody); }
.hlpDoc .hlpTOC .tocRow.hasKids.open > .tocCaret::before { content: '\25BE'; }
.hlpDoc .hlpTOC .tocRow.hasKids:not(.open) > .tocCaret::before { content: '\25B8'; }
.hlpDoc .hlpTOC .tocLabel { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.hlpDoc .hlpTOC li.tocHidden { display: none; }
.hlpDoc .hlpTOC li.collapsed > ul { display: none; }
.hlpDoc .hlpTOC .tocEmpty { padding: 20px 6px; color: var(--aceHelpMuted); font-style: italic; font-size: 13px; text-align: center; }

.hlpDoc .hlpContent { min-width: 0; padding: 4px 6px 60px 14px; scroll-behavior: smooth; }
.hlpDoc .hlpContent .hlpIntro { padding: 6px 0 18px 0; color: var(--aceHelpBody); font-size: 13px; border-bottom: 1px solid #eef1f5; margin-bottom: 12px; }
.hlpDoc .hlpContent .hlpIntro h2 { margin: 0 0 6px 0; font-family: Arial, sans-serif; color: var(--aceHelpInk); font-size: 20px; }
.hlpDoc .hlpContent .hlpTopic { padding-top: 8px; margin-bottom: 26px; scroll-margin-top: 20px; }
.hlpDoc .hlpContent .hlpTopic.hlpHilite { animation: hlpHiliteFlash 1.6s ease-out 1; }
@keyframes hlpHiliteFlash { 0% { background: var(--aceGold); } 100% { background: transparent; } }
.hlpDoc .hlpContent .hlpTopic h2, .hlpDoc .hlpContent .hlpTopic h3.hlpSection { margin: 0 0 6px 0; font-family: Arial, sans-serif; color: var(--aceHelpInk); border-bottom: 2px solid #f0d75f; padding-bottom: 6px; scroll-margin-top: 20px; }
.hlpDoc .hlpContent .hlpTopic h2 { font-size: 22px; }
.hlpDoc .hlpContent .hlpTopic h3.hlpSection { font-size: 17px; border-bottom-width: 1px; }
.hlpDoc .hlpContent .hlpTopic h4.hlpSection { font-size: 15px; color: var(--aceInkDeep); margin: 8px 0 4px 0; }
.hlpDoc .hlpContent .hlpTopic .hlpCrumb { color: var(--aceHelpMuted); font-size: 13px; margin-bottom: 4px; }
.hlpDoc .hlpContent .hlpTopic .hlpBodyText { line-height: 1.55; margin: 8px 0; color: #23262d; }
/* Every image an author puts in a help topic is framed, wherever that topic is being
   shown -- the full documentation page and the help popup both wrap their content in
   .hlpBodyText / .hlpEmbed, so scoping to those covers both (and any later renderer)
   while leaving the help chrome's own icons alone. Screenshots are the bulk of help
   content and they need an edge: most are light-backgrounded and otherwise bleed into
   the page. max-width keeps a full-resolution screenshot inside its column. */
.hlpDoc .hlpBodyText img,
.hlpDoc .hlpEmbed img {
    max-width: 100%;
    height: auto;
    padding: 3px;
    background-color: #FFFFFF;
    border: 1px solid #C0CECA;
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.hlpDoc .hlpBodyText img:hover,
.hlpDoc .hlpEmbed img:hover { border-color: var(--aceAccent, #57756F); }
.hlpDoc .hlpContent .hlpTopic .hlpEmbed { margin: 12px 0; text-align: center; }
.hlpDoc .hlpContent .hlpTopic .hlpEmbed iframe, .hlpDoc .hlpContent .hlpTopic .hlpEmbed video { max-width: 100%; border-radius: 6px; }
.hlpDoc .hlpContent .hlpTopic .hlpLink { margin: 12px 0; }
.hlpDoc .hlpContent .hlpTopic .hlpLink a { color: var(--aceHelpLink); word-break: break-all; }
.hlpDoc .hlpContent .hlpEmptyState { padding: 40px 20px; text-align: center; color: var(--aceHelpMuted); }
.hlpDoc .hlpContent .hlpEmptyState i { font-size: 44px; color: #c9d1e0; display: block; margin-bottom: 8px; }

/* Admin controls */
.hlpDoc .hlpAdminBtn { display: inline-flex; align-items: center; gap: 4px; padding: 6px 12px; margin-left: 8px; background: var(--aceHelpLink); color: #fff; border: 1px solid #24608a; border-radius: 4px; text-decoration: none; font-size: 13px; cursor: pointer; }
.hlpDoc .hlpAdminBtn:hover { background: #24608a; color: #fff; }
.hlpDoc .hlpAdminBtn.hlpBtnPrimary i { font-size: 14px; }
.hlpDoc .hlpTopic { position: relative; }
.hlpDoc .hlpTopic .hlpTopicTools { position: absolute; top: 6px; left: 50%; transform: translateX(-50%); display: flex; gap: 2px; background: rgba(255,255,255,0.92); border: 1px solid #d0d4dc; border-radius: 4px; padding: 2px 4px; opacity: 0; transition: opacity .15s; }
.hlpDoc .hlpTopic:hover .hlpTopicTools, .hlpDoc .hlpTopic .hlpTopicTools:hover { opacity: 1; }
.hlpDoc .hlpTopic .hlpToolBtn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 22px; color: var(--aceHelpBody); cursor: pointer; border-radius: 3px; text-decoration: none; font-size: 13px; }
.hlpDoc .hlpTopic .hlpToolBtn:hover { background: var(--aceHelpTint); color: var(--aceHelpInk); }
.hlpDoc .hlpTopic .hlpToolBtn.hlpToolDanger:hover { background: #fde7e7; color: #b8272c; }
.hlpDoc .hlpTopic.hlpInactive { opacity: 0.55; }
.hlpDoc .hlpTopic.hlpInactive:hover { opacity: 1; }
.hlpDoc .hlpTopic .hlpBadge { font-size: 11px; font-weight: normal; padding: 2px 6px; border-radius: 3px; vertical-align: middle; margin-left: 8px; }
.hlpDoc .hlpTopic .hlpBadgeHidden { background: #fff3cd; color: #7c6c1a; border: 1px solid #ffd94a; }
.hlpDoc .hlpTopic .hlpAdminHint { padding: 8px 12px; background: #f5f7fa; border-left: 3px solid #c9d1e0; color: var(--aceHelpMuted); font-size: 13px; font-style: italic; margin-top: 8px; border-radius: 3px; }
.hlpDoc .hlpTOC li.hlpInactive > .tocRow .tocLabel { color: #a4a4a4; font-style: italic; }

@media (max-width: 640px) {
    .hlpDoc .hlpBody { grid-template-columns: 1fr; }
    .hlpDoc .hlpTOC { position: static; max-height: none; border-right: none; border-bottom: 1px solid #e2e5ec; padding-bottom: 12px; margin-bottom: 12px; }
    .hlpDoc .hlpHeader { flex-wrap: wrap; }
    .hlpDoc .hlpHeader .hlpSearch { flex: 1 1 100%; }
}
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="hoverInfoBox Styles"> */ 
    /* The toast that slides in at the bottom-left -- a vendor's recent transactions, a record's
       details on hover. It was a dark grey slab with a 3px black border and white text, which is
       the one surface in the application that still looked like the old one. Same white card as
       everything else now: hairline border, 12px radius, a real shadow to lift it off the page.

       WIDTH. `width: 500px` was fixed, so the table inside overflowed it. max-width instead, with
       the content deciding, and a viewport cap so it can never run off a phone. */
    #hoverInfoBox {
        display: none;
        min-width: 320px;
        width: max-content;
        max-width: min( 640px, calc( 100vw - 24px ) );
        min-height: 50px;
        background-color: #ffffff;
        border: 1px solid #c8c8c8;
        border-radius: 12px;
        box-shadow: 0 8px 28px rgba(16, 22, 43, 0.22), 0 2px 6px rgba(16, 22, 43, 0.10);
        color: #333333;
        font-size: 13px;
        line-height: 1.45;
        position: absolute;
        bottom: 10px;
        left: 10px;
        padding: 12px 14px;
        z-index: 999;
        /* Long content scrolls inside the toast rather than growing it off the top of the page. */
        max-height: min( 70vh, 520px );
        overflow-y: auto;
    }
    #hoverInfoBox strong { color: #333333; }
    /* The labels were --aceBrand, chosen to carry against the dark ground. On white that is the
       school's own accent at full strength, which is exactly what the settings screens tint
       before using -- so these go to the same quiet grey the rest of the language uses for a
       label, and the value beside them keeps the ink. */
    #hoverInfoBox .label {
        display: block; float: left; clear: both; min-width: 100px;
        text-align: right; margin: 5px 5px 0 0;
        color: #555555; font-weight: bold; font-size: 13px;
    }
    #hoverInfoBox .info { display: table-cell; margin: 2px 0 6px 5px; padding: 5px 0 0 0; text-align: left; color: #333333; }
    #hoverInfoBox .clickableEditNow { color: var(--aceHelpLink, #2B6CB0); }
    /* .results_table hard-codes a black border on the table and every cell plus a #7A9D96
       header. Undo it here the same way the settings card does, and separate the rows with hair
       lines instead -- the toast's own border is the only frame needed. */
    #hoverInfoBox .results_table {
        border: 0;
        background-color: transparent !important;
        border-collapse: collapse;
        margin: 6px 0 0 0;
        width: 100%;
        color: #333333 !important;
    }
    #hoverInfoBox .results_table th {
        background-color: transparent;
        border: 0;
        border-bottom: 1px solid #c8c8c8;
        color: #555555;
        font-size: 12px;
        font-weight: bold;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        text-align: left;
        padding: 4px 8px 4px 0;
        white-space: nowrap;
    }
    #hoverInfoBox .results_table td {
        border: 0;
        border-bottom: 1px solid #eef1f6;
        padding: 5px 8px 5px 0;
        font-size: 13px;
        color: #333333;
        vertical-align: middle;
    }
    #hoverInfoBox .results_table tr:last-child td { border-bottom: 0; }
    #hoverInfoBox .results_table a { color: var(--aceHelpLink, #2B6CB0); }
    /* The Hide control and the keep-open pin, written by ace_start.js when it fills the box. */
    #hoverInfoBox .hoverHideRow {
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 12px 0 0 0;
    }
    /* A caption UNDER the button, not a second thing beside it. Its own line, centred, muted and
       small, so it reads as a status line about the toast rather than as something to click.
       min-height holds the line even while it is empty, so the toast does not jump by a line the
       moment the countdown starts. */
    #hoverInfoBox .aceToastNote {
        display: block;
        margin: 4px 0 0 0;
        min-height: 14px;
        text-align: center;
        font-size: 13px;
        color: #767676;
    }
    /* THE KEEP-OPEN PIN. Deliberately unlike the record pin in a modal's title bar, because they
       do entirely different things and confusing them would be easy: that one is an ANGLED pin
       (bi-pin-angle) that bookmarks a record into the strip at the top of the screen, this is a
       STRAIGHT pin (bi-pin) that only stops this toast closing itself. Different shape, and the
       active colour is the accent blue rather than that one's amber.
       Top-RIGHT of the toast, which is also as far from the title-bar pins as it can be. */
    #hoverInfoBox .aceToastPin {
        position: absolute;
        top: 6px;
        right: 8px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        font-size: 14px;
        line-height: 1;
        color: #767676 !important;
        border: 1px solid transparent;
        cursor: pointer;
        text-decoration: none;
        z-index: 2;
    }
    #hoverInfoBox .aceToastPin:hover {
        color: var(--aceHelpLink, #2B6CB0) !important;
        background: #eef3fa;
        border-color: #c8d4e4;
    }
    /* Pinned: the pin fills in and takes the accent, and the toast gets an accent left edge so
       the state reads even when the pin itself is out of the corner of the eye. */
    #hoverInfoBox.aceToastPinned .aceToastPin { color: var(--aceHelpLink, #2B6CB0) !important; }
    #hoverInfoBox.aceToastPinned { border-left: 4px solid var(--aceHelpLink, #2B6CB0); }
    /* Keep the heading out from under the pin. :first-OF-TYPE, not :first-child -- the pin
       anchor is prepended ahead of the heading, so the heading is never the first child. */
    #hoverInfoBox > strong:first-of-type { display: inline-block; padding-right: 28px; }
    .showHoverBox { color: var(--aceHelpLink, #2B6CB0); }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Student Registration System Related Styles"> */ 
    /* <editor-fold defaultstate="collapsed" desc="Custom Search Forms"> */ 
    div.srSearchSetup { border: solid 2px black; border-radius: 15px; background-color: var(--aceHighlight); padding: 10px;  width: 80%; margin: 10px auto;}
    div.srSearchSetup .centerButtons { display: table; margin: 2px auto; }
    div.srSearchSetup h2 { text-align: center; margin: 2px auto;}
    div.srSearchSetup input, div.srSearchSetup textarea, div.srSearchSetup select { width: 95%;  }
    div.srSearchSetup label { font-weight: bold; font-style: italic; }
    div.srSearchSetup label::after { content: ""; display: block; clear: both; }
    div.srSearchSetup .divider { display: block; text-align: center; font-weight: bold; font-style: italic; margin: 10px 0 0 0; }
    div.srSearchSetup .divider {width: 100%; text-align: center; border-bottom: 1px solid var(--aceBorder); line-height: 0.1em; margin: 10px 0 20px; }
    div.srSearchSetup .divider span { background:var(--aceHighlight); padding:0 10px; }                                
    div.srSearchCritiera .divider span { background:var(--aceSurface); }                                
    div.srSearchCritiera { border: solid 2px black; border-radius: 15px; background-color: var(--aceSurface); padding: 10px;  width: 80%; margin: 10px auto; }
    div.srSearchCritiera  h3 { margin: 3px auto 2px auto; text-align: center; width: 100%; }
    div.srSearchCritiera  .srSrchOpt { display: block; width: 25%; float: left; padding: 4px; }
    div.srSearchCritiera  .srSrchOpt label::after { content: ""; display: block; clear: both; }
    div.srSearchSetup #sortableavail, div.srSearchSetup #sortableuse{ background: transparent; max-width: 200px; padding: 0; min-height: 150px; }
    div.srSearchSetup #sortableavail li, div.srSearchSetup #sortableuse li { font-size: 1em; padding: 2px; width: 175px; margin 4px 0 4px 2px; }
    
    /* </editor-fold>*/
    
    div.srMergeDupsTable { border: 3px solid var(--aceInk); border-radius: 8px; padding: 5px; margin: 15px; background-color: var(--aceHighlight); }
    div.srMergeDupsTable table { border-collapse: collapse; border: 2px solid var(--aceBorder); margin: 0 auto; background-color: var(--aceSurface); } 
    div.srMergeDupsTable td { min-width: 175px; padding: 2px; border: 1px solid var(--aceBrand); text-align: center;  }
    div.srMergeDupsTable td:nth-child(even) { background-color: var(--aceMint); }
    div.srMergeDupsTable ul { padding-inline-start: 5px; text-align: left; }
    div.srMergeDupsTable li { text-align: left; }
    
    table.srMergeDupsTable td input:not([type=checkbox]):not([type=radio]) { width: 100%; }
    table.srMergeDupsTable td select { width: 100%; }
    table.srMergeDupsTable td textarea { width: 100%; height: 100px; }
    
    table.srMergeDupsTable input[type=checkbox] { float: left; margin: 2px; }
    table.srMergeDupsTable input[type=radio] { float: left; margin: 2px; }

    .stRegPublic .srpplid {
        font-size: xx-large;
        font-family: arial;
        font-weight: bold;
        color: var(--aceMuted);
        display: block;
        float: right;
        position: relative;
        right: 5px;
        bottom: -5px;
        margin: 0 10px -30px 0;
    }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Student Registration System Related Styles"> */
    .bgPaleYellow { background-color: #FEFFC6; }
/* </editor-fold>*/

div.scrollingBox { display: block; float: left; border: 1px solid black; height: 350px; width: 300px; overflow: auto; padding: 5px; margin: 10px;  }
div.scrollingBox h3 { margin: 0px; }
div.scrollingBox h4 { margin: 0px; } 
div.scrollingBox ul { list-style:none; text-indent:5px; padding-inline-start: 10px; margin-block-start: 0px; margin-block-end: 5px; }
div.scrollingBox li { line-height:25px; }
div.scrollingBox li:nth-child(even) { background:var(--aceSurface); }


.traSubForm span { display: block; clear:both; }
.traSubForm .blocks { display: block; float: left; margin: 0 10px; padding: 0 10px 0 0; border-right: 1px solid var(--aceBrand); }
.traSubForm p { font-size: small; display: block; float: left; clear: both; margin: 0 0 0 5px; }
.traSubForm label { display: block; clear: both; font-size: small; color: var(--aceBorder); margin: 5px 0 0 0; }
.traSubForm div.amtLine { display: block; width: 100%; margin: 5px 0 0 0; border-bottom: 1px solid var(--aceBrand); padding: 2px 0 6px 0; }
.traSubForm div.coaCodesBlock { display: block; float: left; }
.traSubForm div.amountBlock { display: block; float: right;   }
.traSubForm div.commentBlock { display: block; float: left; } 
.traSubForm div.classBlock { display: block; float: right; clear: both;  }
.traSubForm .ui-tabs {font-size: small; }
.traSubForm .ui-tabs-anchor { font-size: small; }
.traSubForm h3 { margin: 15px auto 5px auto; text-align: center; }
.traSubForm fieldset label { clear: none; }

div.progressTracker { display: block; margin: 20px auto; border: 3px solid var(--aceInk); border-radius: 25px; background-color: var(--aceHighlight); width: 600px; min-height: 300 px; text-align: center; padding: 20px; }
div.progressBar { display: block; border: 1px solid var(--aceInk); background-color: var(--aceMint); border-radius: 5px; width: 400px; height: 30px; margin: 5px auto; padding: 0px; text-align: center; font-size: x-large; color:var(--aceBrand);}
div.progressBar .progress{ border: 0x transparent; background-color: var(--aceBorder); border-radius: 5px; height: 100%; display: block; margin: 0px; text-align: center; color: white; font-size: x-large; width: 0px; }
div.progressBar .text { text-align: center; font-size: xlarge; }

div.mapLegend { display: block; background-color: white; border: 3px solid black; padding: 10px; margin: 10px; font-size: medium;  }
div.mapLegend h3 { margin-top:0px; text-align: center; font-size: large; text-decoration: underline;   }
div.mapLegend igm { vertical-align: middle; }


/* <editor-fold defaultstate="collapsed" desc="AceIcon Styles"> */

/* ── AceIcon Styles ── */
.ace-icon-wrap {
    display: inline-block;
    overflow: hidden;
    box-sizing: border-box;
    vertical-align: middle;
    text-align: center;
    line-height: 0;
}
.ace-icon-wrap svg {
    display: inline-block;
    max-width: 100%;
    max-height: 100%;
}
.ace-icon-inner {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}
.ace-icon-gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    padding: 10px;
}
.ace-icon-gallery-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}
.ace-icon-gallery-item span {
    font-size: 13px;
    color: #555;
    max-width: 120px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* </editor-fold>*/

/* <editor-fold defaultstate="collapsed" desc="Multiple Payment Forms for BC Payments"> */
/* Card container: flex row with equal columns */
.multipleProcessTransactions {
    display: flex;
    border-radius: 15px;
    border: 1px solid black;
    padding: 5px;
    width: 95%;
    gap: 6px;
    margin: 20px 2px;
    box-shadow: 0 4px 8px rgba( 0, 0, 0, 0.4 );
}

/* All four columns: equal flex, box-sizing so padding/border included in width */
.multipleProcessTransactions .col1,
.multipleProcessTransactions .vendorBlock,
.multipleProcessTransactions .billBlock,
.multipleProcessTransactions .paymentBlock {
    flex: 1 1 0;
    min-width: 0;              /* allow flex children to shrink below content size */
    box-sizing: border-box;
    padding: 5px;
    overflow: hidden;           /* clip anything that still overflows */
}

.multipleProcessTransactions .col1 {
    border: 1px solid black;
    border-radius: 15px;
    background-color: #f7ffed;
}

/* fullPaymentForm wrapper: behaves as a flex row taking 3 of 4 equal parts */
.multipleProcessTransactions .fullPaymentForm {
    flex: 3 1 0;
    min-width: 0;
    display: flex;
    gap: 6px;
}

/* When a <form> wraps billBlock + paymentBlock, use grid for clean 2-col layout */
.multipleProcessTransactions > form,
.multipleProcessTransactions .fullPaymentForm > form {
    flex: 2 1 0;
    min-width: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
}

/* Submit button: span both columns, auto-width, centered */
.multipleProcessTransactions form button.center {
    grid-column: 1 / -1;
    justify-self: center;
}

/* Force all form elements, tables, and comboboxes to stay within column */
.multipleProcessTransactions select,
.multipleProcessTransactions input,
.multipleProcessTransactions textarea,
.multipleProcessTransactions table,
.multipleProcessTransactions .ui-widget,
.multipleProcessTransactions .custom-combobox,
.multipleProcessTransactions .custom-combobox-input {
    max-width: 100%;
    width: 100%;
    box-sizing: border-box;
}

/* Tables: fixed layout prevents columns from blowing out */
.multipleProcessTransactions table {
    table-layout: fixed;
    word-wrap: break-word;
}

/* THE NORMAL TITLE SIZE. ace.css sets no size on a bare h2, so this fell back to the browser's
   1.5em -- around 24px, half again the 16px every other card title uses (.settingsPage
   .settingsCard h2). Stated here so it matches. display:flex so the "?" and the page code sit on
   the baseline beside the words rather than on their own line. */
.billPayHeading h2 {
    display: flex;
    align-items: center;
    font-size: 16px;
    color: #333;
    font-weight: bold;
    margin: 2px 0 12px 0;
    line-height: 1.3;
}
.multipleProcessTransactions span.billPayHeading { display: none; }
.multipleProcessTransactions form button.center { width: auto; }

/* ── col1: two-column table layout (label | value) ── */
.multipleProcessTransactions .col1 {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 8px;
    align-content: start;
}

/* Labels: left column, right-aligned */
.multipleProcessTransactions .col1 > label {
    font-weight: bold;
    font-size: small;
    color: var(--aceBorder);
    text-align: right;
    white-space: nowrap;
    padding: 2px 0;
}

/* Values (spans next to labels): right column */
.multipleProcessTransactions .col1 > span:not(.blocks):not(.billPayHeading) {
    padding: 2px 0;
    min-width: 0;
    overflow: hidden;
}

/* .blocks: dissolve into the parent grid so inner label+span become their own row */
.multipleProcessTransactions .col1 .blocks {
    display: contents;
}
/* Dissolve clickableEditNow inside .blocks so children become grid items */
.multipleProcessTransactions .col1 .blocks .clickableEditNow {
    display: contents;
}
/* .invDetails: also dissolve so its label participates in the grid */
.multipleProcessTransactions .col1 .invDetails {
    display: contents;
}
/* Hide the <br> between label and value inside invDetails */
.multipleProcessTransactions .col1 .invDetails br {
    display: none;
}
.multipleProcessTransactions .col1 .blocks label {
    font-weight: bold;
    font-size: small;
    color: var(--aceBorder);
    text-align: right;
    white-space: nowrap;
    padding: 2px 0;
}

/* Full-width items: span both columns */
.multipleProcessTransactions .col1 > span:first-child,
.multipleProcessTransactions .col1 > hr,
.multipleProcessTransactions .col1 > .clearfix,
.multipleProcessTransactions .col1 > .amtLine,
.multipleProcessTransactions .col1 > .processingComments {
    grid-column: 1 / -1;
}

/* Description spans full width */
.multipleProcessTransactions .col1 .description {
    min-width: 0;
    overflow: hidden;
}
.multipleProcessTransactions .col1 .description textarea {
    width: 100%;
    box-sizing: border-box;
}

/* Clearfix: collapse to nothing in grid */
.multipleProcessTransactions .col1 .clearfix {
    height: 0;
    margin: 0;
    padding: 0;
}

/* Amount lines: full width, internal float layout preserved */
.multipleProcessTransactions .col1 .amtLine {
    border: 1px solid #BEE6DE;
    padding: 4px;
    box-sizing: border-box;
    overflow: hidden;
}
.multipleProcessTransactions .col1 .amtLine .coaCodesBlock {
    display: block;
    float: left;
}
.multipleProcessTransactions .col1 .amtLine .amountBlock {
    display: block;
    float: right;
    text-align: right;
}
.multipleProcessTransactions .col1 .amtLine .classBlock {
    clear: both;
    display: block;
    float: left;
    margin: 5px 0 0 0;
}
.multipleProcessTransactions .col1 .amtLine .commentBlock {
    display: block;
    float: left;
    clear: both;
    margin: 5px 0 0 0;
    max-width: 100%;
}
.multipleProcessTransactions .col1 .amtLine .commentBlock input {
    width: 100%;
}


/* </editor-fold>*/

/* <editor-fold defaultstate="collapsed" desc="Custom Script Styles - Miscellaneous Tools Settings"> */
.clickableEditNow {
    text-decoration: underline dashed #FFC7C7; 
    color: #090045;
}
div.matchedGroup { border-radius: 10px; border: 3px solid black; background-color: var(--aceMint); width: 95%; margin: 30px auto; padding: 4px; align-items: center; justify-content: center; text-align: center; }
div.matchedGroup table { display: table; float: left; width: 100%; border: 1px solid black; border-radius: 10px; border-collapse: collapse; } 
div.matchedGroup table th, div.matchedGroup table td { border: 1px solid black; }
div.matchedGroup table th { background-color: #8A9D96; font-weight: bolder; }
div.matchedGroup button { display: block; margin: 5px auto; justify-content: center; clear: both; padding: 4px; }
div.matchedGroup input { width: 95%; margin: auto; }   
.qbSyncFix.complete { display: none; }
.qbSyncFix h2 { display:block; width: 100%; background-color: var(--aceInk); color: white; font-weight: bold; font-size: xx-large; }
    
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Custom Script Styles - Pop Icons"> */ 
    /* The row-tools menu is anchored to its own table cell, so it opens immediately to
       the right of the tools icon -- over the next column -- instead of dropping inside
       a 30px-wide cell wherever its static position happens to land.
       z-index matters as much as the offsets: ace_start.js switches the left nav columns
       to position:absolute at runtime, which turns on the z-index: 6-10 that #navMenu1-5
       carry, and the tools column is the content nearest to them. Without a z-index of
       its own this menu has z-index:auto and a nav column paints straight over it. 15 is
       above the nav and below the popup stack (which starts at 20), so a menu inside a
       popup still sits inside that popup's stacking context rather than over later ones. */
    td:has( > .popIconMenu ) { position: relative; }
    /* THE ROW MENU, in the "New look and feel": a small white card, the same language as the
       dashboard cards and the modals -- hairline border, 10px radius, a soft lift.
       It used to be --aceHighlight (#FFFFE3) inside an --aceBrand border. Pale yellow is what
       this file uses to say "look at this value", not what a menu is made of, and the brand
       colour is the entity's, so on some schools the menu was outlined in something loud. */
    .popIconMenu {
        display: none;
        border: 1px solid var(--aceCardBorder, #D8E2E0);
        border-radius: 10px;
        background-color: #FFFFFF;
        box-shadow: 0 4px 14px rgba(0,0,0,0.16);
        padding: 4px;
        position: absolute;
        top: 0;
        left: 100%;
        z-index: 15;
        /* Width comes from the longest label, not from the cell. An absolutely positioned
           box shrink-to-fits against its containing block, and that block is the 30px-wide
           tools cell, so the box would otherwise settle at min-content width -- which wraps
           every multi-word label ("Merge With Another Vendor") onto two or three lines.
           Capped so a single long label can't stretch the menu across the table. */
        width: max-content;
        min-width: 225px;
        max-width: 320px;
        overflow: hidden;           /* belt and braces: nothing can paint past the rounded border */
    }
    .popIconMenu ul {
        list-style-type: none;
        list-style-image: none;
        margin: 0;
        padding: 0;                 /* the card's own 4px padding keeps rows off the border */
    }
    /* Flex row so the icon and its label stay centred on each other, and -- the actual
       fix -- min-height instead of height: the old fixed 29px could not grow, so a label
       that did wrap rendered its second line below the menu's bottom border. */
    .popIconMenu li {
        display: flex;
        align-items: center;
        gap: 6px;
        min-height: 30px;
        padding: 2px 10px 2px 4px;
        border-radius: 6px;
        color: var(--aceInkDeep, #2A2A2A);
        /* 12px, the application's default content size. It was 14px, which made a menu item
           read a size larger than the table row it was opened from. min-height above holds the
           30px target, so the hit area is unchanged (WCAG 2.2 2.5.8). */
        font-size: 13px;
        line-height: 1.25;
        cursor: pointer;            /* the whole row acts, not just the icon -- see ace_end.js */
        overflow-wrap: break-word;  /* even an unbroken long word stays inside */
    }
    /* The hover an item in a menu is expected to have. The row is the target now, so the
       highlight has to cover the row rather than sit behind the icon alone. */
    .popIconMenu li:hover { background-color: var(--aceAccent2, #EDF4F2); }
    .popIconMenu li img {
        flex: 0 0 auto;             /* the icon keeps its size; the label takes the slack */
        vertical-align: middle;
        margin: 2px;
    }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Custom Script Styles - Custom ComboBox"> */ 
    /*
     * THE AUTOCOMPLETE DROPDOWN, which had no rules of its own at all.
     *
     * jQuery UI puts no height limit on the suggestion list, so a combobox over a school's whole
     * vendor list opened a menu hundreds of rows tall. Being absolutely positioned it covers
     * whatever is beneath it -- in "Change The Vendor On This Record" that is the Update and
     * Cancel buttons, which is how the dialog came to look unusable.
     *
     * A capped, scrolling list is the fix: it can never be taller than the space a modal has,
     * and the buttons stay reachable while it is open.
     *
     * The z-index is deliberately high. The list is appended near the end of the document, so
     * inside a popup (which sits at z-index 21 and upward, two per open pop) it would otherwise
     * paint UNDER the dialog it belongs to. It is a transient thing the user is actively
     * pointing at, so being above the stack while open is right.
     */
    /*
     * SIZE, stated rather than inherited. The list is appended to the end of the document and
     * had no font rule of its own, so it took whatever it inherited -- which inside a modal is
     * the dialog's own larger body text. At that size a capped 260px box shows only a handful
     * of vendors and the menu still swallows everything under it. Stating 13px makes the cap
     * mean something: the same box now holds roughly twice the rows.
     *
     * Both the item and its wrapper: jQuery UI 1.12+ puts the text in a .ui-menu-item-wrapper
     * inside the <li>, older builds put it straight on the <li>, and this codebase ships both.
     */
    .ui-autocomplete,
    .ui-autocomplete .ui-menu-item,
    .ui-autocomplete .ui-menu-item-wrapper,
    .ui-autocomplete .ui-menu-item a {
        font-size: 13px;
        line-height: 1.35;
    }
    .ui-autocomplete .ui-menu-item-wrapper,
    .ui-autocomplete .ui-menu-item a { padding: 4px 8px; }
    .ui-autocomplete {
        max-height: 260px;
        overflow-y: auto;
        overflow-x: hidden;
        z-index: 9999;
    }
    .custom-combobox {
        position: relative;
        display: inline-block;
        float: left; 
        clear: both; 
    }
    .custom-combobox-toggle {
        position: absolute;
        top: 0;
        bottom: 0;
        margin-left: -1px;
        padding: 0;
    }
    /*
     * 250px, halved from 500. A vendor or state picker is type-to-search: what matters is that
     * the chosen value reads whole, not that the box spans the dialog. At 500 it dominated
     * every screen it appeared on and pushed the buttons beside it out of the row.
     *
     * max-width keeps it inside a narrow column -- the shipping State sits in a 28% cell, and a
     * fixed 250 would have overflowed it.
     */
    .custom-combobox-input {
        margin: 0;
        display: block; float: left; 
        padding: 5px 10px;
        width: 250px;
        max-width: 100%;
        box-sizing: border-box;
        clear: both; 
        font-size: 13px;    /* match the list it opens -- see .ui-autocomplete above */
    }
    /* The suggestion list is positioned against the input, so it inherits the same ceiling. */
    .ui-autocomplete { max-width: 100%; }
    /*
     * THE CONTROL ITSELF, sized to match the list it opens.
     *
     * Everything here sits inside a .ui-widget, and jQuery UI's theme gives that font-size: 1em
     * -- so the combobox inherits whatever the surrounding screen uses, which in a modal is the
     * dialog's larger body text. The <select> is styled too, because it is what shows for the
     * moment before the script replaces it, and on any screen where the script has not run.
     */
    /*
     * SPECIFICITY, not just a value. The previous attempt set .custom-combobox-input and lost:
     * the jQuery UI theme ships
     *
     *     .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button
     *         { font-family: Arial, sans-serif; font-size: 1em; }
     *
     * which is (0,1,1) against a bare class's (0,1,0) -- so it won no matter which stylesheet
     * loaded last. And `1em` means "inherit", so the control took the size of whatever screen
     * it was dropped into. The widget also builds its box as a bare $("<input>") with NO type
     * attribute, so `input[type=text]` rules never reached it either -- which is why the
     * purchase order's own 13px rule for its fields did not apply.
     *
     * Qualifying with .ui-widget puts these at (0,2,1) and settles it. The font-family is
     * restated for the same reason: Verdana came from that same rule and is nothing else on
     * these screens.
     */
    select.combobox,
    .custom-combobox,
    .custom-combobox-toggle,
    .comboBoxWidthFull,
    .comboBoxWidthFull select { font-size: 13px; }
    .ui-widget input.custom-combobox-input,
    .ui-widget select.combobox,
    .ui-widget .custom-combobox-input {
        font-size: 13px;
        font-family: Arial, sans-serif;
    }
    /* The suggestion list is a .ui-menu inside a .ui-widget, so its items need the same
       treatment for the same reason. */
    .ui-widget.ui-autocomplete,
    .ui-widget.ui-autocomplete .ui-menu-item,
    .ui-widget.ui-autocomplete .ui-menu-item-wrapper,
    .ui-widget.ui-autocomplete .ui-menu-item a {
        font-size: 13px;
        font-family: Arial, sans-serif;
        line-height: 1.35;
    }
    .comboBoxWidthFull .custom-combobox { 
        width: 100%; 
    }
    /*
     * THE TOGGLE IS A SQUARE THE HEIGHT OF THE BOX IT OPENS.
     *
     * It used to be `width: 4%; height: 38px` against an input of 28px, so the arrow button stood
     * a third taller than its own field -- and, being a percentage of whatever contained it, it
     * was a fat square on a wide screen and a tall thin sliver in a narrow column. Inside a "New
     * look and feel" modal it was worse again: nlfFormPopStyle() pins every input in a dialog to
     * 27px at (0,7,1), which no rule here can outrank, so the gap was 11px there.
     *
     * The height is therefore not stated at all. .custom-combobox-toggle is absolutely positioned
     * with top:0 and bottom:0 inside .custom-combobox, which is an inline-block and so contains
     * the floated input -- meaning the wrapper is exactly as tall as the input, and the button
     * stretches to it. That is right in every context, including the ones that override the
     * input's height, rather than right only where the number happens to match.
     *
     * `height: auto` is stated rather than omitted because it is what makes top/bottom do the
     * sizing -- jQuery UI's own .ui-button rules are what put a height on it in the first place.
     * The width is a fixed 28px for the same reason the height is not a percentage: an icon
     * button is the size of its icon, not a share of the row. .ui-button-icon-only ships
     * `width: 2em`, but the theme's later `.ui-button { width: 14em }` beats it at equal
     * specificity, so a value has to be given here.
     *
     * The input's width is calc() rather than 90% so the two always add up to the row: at 90% + a
     * fixed button the pair could overflow a narrow column, and at 90% + 4% they left a gap on a
     * wide one.
     */
    .comboBoxWidthFull .custom-combobox-input { 
        width: calc( 100% - 30px ); 
        height: 28px; 
    }
    .comboBoxWidthFull .custom-combobox-toggle,
    .comboBoxWidthFull .ui-button-icon-only { 
        width: 28px; 
        height: auto; 
        min-height: 0; 
        padding: 0; 
        box-sizing: border-box; 
    }
    /*
     * THE "Show All Items" TOOLTIP on that toggle (ace_end.js calls .tooltip() on it).
     *
     * jQuery UI appends .ui-tooltip to the BODY and gives it `padding: 8px` and, through
     * .ui-widget, `font-size: 1em` + Verdana -- so a one-line label rendered as a large bubble in
     * a face used nowhere else on these screens. Qualified with .ui-widget for the same reason
     * .ui-widget.ui-autocomplete above is: the tooltip carries both classes, and matching only
     * .ui-tooltip is a tie decided by which stylesheet loaded last.
     */
    .ui-widget.ui-tooltip,
    .ui-tooltip {
        padding: 5px 8px;
        max-width: 260px;
        font-size: 13px;
        line-height: 1.35;
        font-family: Arial, sans-serif;
        border-radius: 6px;
        box-shadow: 0 2px 6px rgba( 0, 0, 0, 0.18 );
    }
/* </editor-fold>*/
/* <editor-fold defaultstate="collapsed" desc="Custom Script Styles - Custom ComboBox"> */ 
    /* <editor-fold defaultstate="collapsed" desc="Sortable Divs"> */ 
        #sortable, .sortable { 
            list-style-type: none; 
            margin: 0; 
            padding: 0; 
            width: 400px; 
        }
        #sortable li, .sortable li { 
            margin: 0 3px 3px 3px; 
            padding: 0.4em; 
            padding-left: 1.5em; 
            font-size: 1.4em; 
            height: 18px; 
        }
        #sortable li span, .sortable li span { 
            position: absolute; 
            margin-left: -1.3em; 
        }
        #sortable1, #sortable2, #sortable3, .sortableList { 
            list-style-type: none; 
            margin: 0; 
            float: left; 
            margin-right: 10px; 
            background: #eee; 
            padding: 5px; 
            width: 245px;

        }
        #sortable1 li, #sortable2 li, #sortable3 li, .sortableList li  { 
            margin: 5px; 
            padding: 5px; 
            font-size: 1.2em; 
            width: 225px;
        }
    /* </editor-fold>*/
/* </editor-fold>*/


img.headerLogo { max-width: 25%; max-height: 150px; }

@media print {
    html, body { height: 99%; }
    .dataTables option { display: none !important; }
}




/* <editor-fold defaultstate="collapsed" desc="SR public skin does not dress internal screens"> */
/*
 * THE PURPLE BAR, THE 3px PURPLE FRAME AND THE SERIF WERE ALL ONE CAUSE.
 *
 * header.php includes sr/srstyles.php on EVERY page, and that file dresses .stRegPublic in the
 * school's own registration branding -- $srSystemColors and $srSystemFonts, read from the
 * srColorScheme / font settings. For SouthTech Preparatory Academy (entity 61) colour [6] is
 * #2C1D63, a dark indigo. The three rules responsible:
 *
 *     .stRegPublic                  { <$srSystemFonts['txt']> }          -> the serif
 *     .stRegPublic h2               { background-color: <colour 6>; color: white;
 *                                     text-align: center; font-size: xx-large; }  -> the bar
 *     .stRegPublic div.srPersonInfo { border: 3px solid <colour 6>; }    -> the frame
 *
 * SRPPL::viewInternal() keeps .stRegPublic and .srPersonInfo because they carry the layout, so
 * the INTERNAL person view inherited the PUBLIC registration skin along with it. That is why the
 * colour appeared in no stylesheet and no accent setting: it is neither, it is srColorScheme.
 *
 * No !important needed. srstyles.php loads after ace.css, so these win on specificity instead --
 * adding .settingsPage / .popped puts them a class ahead of the originals.
 */
.settingsPage .stRegPublic,
.popped .stRegPublic { font-family: Arial, sans-serif; font-size: 13px; }

.settingsPage .stRegPublic h1, .popped .stRegPublic h1,
.settingsPage .stRegPublic h2, .popped .stRegPublic h2,
.settingsPage .stRegPublic h3, .popped .stRegPublic h3,
.settingsPage .stRegPublic h4, .popped .stRegPublic h4 {
    background-color: transparent;
    color: var(--aceInk, #4F4F4F);
    font-family: Arial, sans-serif;
    text-align: left;
    text-decoration: none;
    padding: 0;
}
.settingsPage .stRegPublic h2, .popped .stRegPublic h2 { font-size: 16px; margin: 2px 0 12px 0; }
.settingsPage .stRegPublic h3, .popped .stRegPublic h3 { font-size: 14px; }

/*
 * MATCH srstyles.php's DEPTH, or it wins.
 *
 * That file styles the inner elements with deeper selectors than the wrappers above:
 *     .stRegPublic div.srPersonInfo h2        (0,2,2)
 *     .stRegPublic div.srPersonInfo .box h4   (0,3,2)
 * and it is included by header.php AFTER ace.css, so at equal specificity it wins on order.
 * `.settingsPage .stRegPublic h2` is only (0,2,1) and lost to the first of those -- which is
 * why the person's name and the "General Information" / "Address" / "Related People" /
 * "Provided Data" / "Office Information" / "Login Information" headings stayed serif and
 * underlined after the outer rules were already right. Each selector below is one class deeper
 * than the rule it is answering.
 */
.settingsPage .stRegPublic div.srPersonInfo h1, .popped .stRegPublic div.srPersonInfo h1,
.settingsPage .stRegPublic div.srPersonInfo h2, .popped .stRegPublic div.srPersonInfo h2,
.settingsPage .stRegPublic div.srPersonInfo h3, .popped .stRegPublic div.srPersonInfo h3,
.settingsPage .stRegPublic div.srPersonInfo h4, .popped .stRegPublic div.srPersonInfo h4,
.settingsPage .stRegPublic div.srPersonInfo .box h4, .popped .stRegPublic div.srPersonInfo .box h4,
.settingsPage .stRegPublic div.srDashItem h3, .popped .stRegPublic div.srDashItem h3 {
    font-family: Arial, sans-serif;
    background-color: transparent;
    color: var(--aceInk, #4F4F4F);
    text-decoration: none;
    text-align: left;
    border-radius: 0;
}
/* The data the form prints, and its labels -- srstyles gives these the school's faces too. */
.settingsPage .stRegPublic div.srPersonInfo .formResponse, .popped .stRegPublic div.srPersonInfo .formResponse,
.settingsPage .stRegPublic .formResponse, .popped .stRegPublic .formResponse,
.settingsPage .stRegPublic label, .popped .stRegPublic label,
.settingsPage .stRegPublic .list_form th, .popped .stRegPublic .list_form th,
.settingsPage .stRegPublic .list_form td, .popped .stRegPublic .list_form td,
.settingsPage .stRegPublic div.srPersonInfo .gradeLevel, .popped .stRegPublic div.srPersonInfo .gradeLevel {
    font-family: Arial, sans-serif;
}

/* The frame round the tab box, and the tinted ground behind it. */
.settingsPage .stRegPublic div.srPersonInfo,
.popped .stRegPublic div.srPersonInfo {
    border: 0 none;
    border-radius: 0;
    background-color: transparent;
    margin: 0;
}
/* </editor-fold> */
