@import url("theme_settings/theme_settings.css");
@import url("https://use.typekit.net/noj8fgf.css");
@import url("https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400;1,700&display=swap");

:root {
    /* Theme tokens — every reference includes a diagnostic fallback so
       a missing theme_settings.css is visually obvious during review. */
    --color-1:        var(--color-1-theme, #00ff00);
    --color-2:        var(--color-2-theme, #ff00ff);
    --color-over-1:   var(--color-over-1-theme, #000000);
    --color-over-2:   var(--color-over-2-theme, #ffffff);
    --color-1-isDark: var(--color-1-theme-isDark, 0);
    --color-2-isDark: var(--color-2-theme-isDark, 0);

    /* Design-specific neutrals — grey (#AAAAAA) is a hairline/border tone,
       not a text or large-surface color. Fog is a derived pale band tint. */
    --site-ink:   #1c3664;
    --site-paper: #ffffff;
    --site-mist:  #aaaaaa;
    --site-fog:   #f2f4f7;

    /* Title tier (site name, hero motto) — Adobe Fonts Trajan Pro 3 */
    --font-display: 'trajan-pro-3', Georgia, 'Times New Roman', serif;
    --font-heading: 'Oswald', 'Segoe UI', Helvetica, Arial, sans-serif;
    --font-body:    'Source Sans 3', 'Segoe UI', Helvetica, Arial, sans-serif;

    /* Breakpoint tokens — media queries can't read custom properties,
       so the rem values repeat in @media (min-width: …) below. */
    --size-sm: 48rem;     /* tablet */
    --size-md: 64rem;     /* desktop */
    --size-lg: 85.375rem; /* large desktop */
    --size-xl: 120rem;    /* max content width */

    /* Sections span the viewport like the header, capped only on ultrawide so
       line lengths stay readable. --site-pad-x matches the header's edge padding
       so every band's content lines up vertically with the crest and nav. */
    --site-content-max: var(--size-xl);
    --site-pad-x: clamp(1rem, 3%, 2.5rem);

    /* Corner rounding — containers (cards, media, scrims) share one radius;
       controls use the smaller one so buttons don't read as pills. */
    --site-radius: 12px;
    --site-radius-sm: 6px;

    /* one size for every section heading so they stay consistent — scales down
       on narrow screens, tops out at the 55px desktop size */
    --site-section-title: clamp(1.75rem, 4vw, 3.4375rem);

    /* shared vertical rhythm between homepage sections — bigger than a single
       section's own internal spacing, so sections read as distinct blocks */
    --site-section-pad-y: clamp(3rem, 8vw, 6.5rem);
}

html { height: 100%; }

body {
    margin: 0;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
    color: var(--site-ink);
    background-color: var(--site-paper);
}

.site-header,
.site-footer { flex: none; }

#content_main {
    flex: 1 0 auto;
    width: 100%;
    box-sizing: border-box;
    max-width: var(--inside-content-max, var(--size-lg));
    padding: var(--inside-content-pad-y, 1.5rem) var(--inside-content-pad-x, clamp(0.5rem, 5%, 3rem));
    margin-inline: auto;
    background-color: #fff;
}

/* Homepage reset — the .site-homepage wrapper in index.jsp gates this. */
body:has(.site-homepage) #content_main {
    max-width: none;
    padding: 0;
    background-color: transparent;
}

.pageTitle {
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
    font-family: var(--font-display);
    font-size: 2rem;
    line-height: 1.25;
    margin-block: 0 1.5rem;
}

.site-header .site-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 0.5rem 1rem;
    background-color: var(--color-1);
    color: var(--color-over-1);
    text-decoration: none;
}
.site-header .site-skip-link:focus-visible { left: 0; }

.hidden-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

/* ---------- Base typography ---------- */

.site-header :where(h1, h2, h3),
.site-footer :where(h1, h2, h3),
.site-homepage :where(h1, h2, h3) {
    font-family: var(--font-heading);
    line-height: 1.2;
    margin: 0 0 0.5em;
}
/* Title tier, not a subtitle heading — stays on --font-display */
.site-motto__title { font-family: var(--font-display); }

.site-homepage img { max-width: 100%; height: auto; }

/* New-tab nav links carry a visual external-link indicator (a11y) */
.site-nav a[target="_blank"]::after {
    font-family: 'Material Symbols Outlined';
    content: 'open_in_new' / '';
    font-size: 0.9em;
    text-transform: none;
    margin-left: 0.2em;
    vertical-align: middle;
}

/* CMS-provided icons flattened to currentColor to coordinate with a
   colored background. Handles two-tone brand SVGs and single-tone icons. */
.flat-icon-colors svg.color-flatten .color-fill { fill: currentColor; }
.flat-icon-colors svg.color-flatten .transparency-change { fill: transparent; }
.flat-icon-colors svg:not(.color-flatten) { fill: currentColor; }

/* ---------- Header ---------- */

.site-header {
    display: flex;
    flex-direction: column;
    position: relative;
    /* .site-header__bar is fixed and contributes no flow height on its own —
       this keeps nav's top:100% anchor (and the homepage gradient below)
       sane before header.jsp's script measures the real value. */
    height: var(--site-header-bar-h, 6rem);
    background-color: var(--color-1);
    color: var(--color-over-1);
    border-bottom: 0;
}

/* Homepage only: the header overlays the hero video directly. Content sits on
   an opaque black container (a semi-transparent solid — WCAG-acceptable backing
   for white text over video, unlike a gradient), and a gradient container is
   stacked beneath it to blend the bar's edge into the video. Inside pages keep
   the solid navy header in normal flow. */
body:has(.site-homepage) .site-header {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
    border: 0;
    background-color: rgba(0, 0, 0, 0.75);
}
body:has(.site-homepage) .site-header::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    /* the hero video is edge-to-edge, so its rendered height tracks viewport
       width directly (16:9). A fixed rem height was tuned against a desktop
       video's height and overshoots past a mobile video's much shorter one,
       bleeding this dark fade into the motto title/caption below and
       washing them out. Scaling with vw keeps the fade inside the video at
       any width; the rem cap preserves the original desktop size. */
    height: min(18rem, 45vw);
    /* first stop matches the bar's own alpha exactly — a darker start reads as a
       hard line. A longer run with a smoothstep-shaped curve (many stops,
       biased toward a long, gentle tail at low opacity) reads as continuous —
       the eye is far more sensitive to banding in the faint end of a fade than
       a straight alpha ramp accounts for. */
    background: linear-gradient(to bottom,
        rgba(0, 0, 0, 0.75) 0%,
        rgba(0, 0, 0, 0.739) 7%,
        rgba(0, 0, 0, 0.708) 14%,
        rgba(0, 0, 0, 0.661) 21%,
        rgba(0, 0, 0, 0.601) 29%,
        rgba(0, 0, 0, 0.531) 36%,
        rgba(0, 0, 0, 0.455) 43%,
        rgba(0, 0, 0, 0.375) 50%,
        rgba(0, 0, 0, 0.295) 57%,
        rgba(0, 0, 0, 0.219) 64%,
        rgba(0, 0, 0, 0.149) 71%,
        rgba(0, 0, 0, 0.089) 79%,
        rgba(0, 0, 0, 0.042) 86%,
        rgba(0, 0, 0, 0.011) 93%,
        rgba(0, 0, 0, 0) 100%);
    pointer-events: none;
}
/* Header bar — fixed to the viewport top on every page (both the
   absolutely-positioned homepage header and the in-flow interior header),
   so the crest and hamburger/Translate pill stay visible and reachable
   while scrolled. .site-header itself has no in-flow content once this is
   fixed, so header.jsp's script measures the bar's real rendered height
   into --site-header-bar-h — the nav dropdown's top:100% anchor and the
   homepage gradient's ::after both depend on .site-header having a
   meaningful box size, and the crest's clamp() sizing means that size
   isn't a fixed constant. */
.site-header__bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    width: 100%;
    padding: 0.75rem var(--site-pad-x);
    box-sizing: border-box;
    /* solid backing on interior pages; the homepage override below lets the
       hero video show through the gap between the crest and the pill */
    background-color: var(--color-1);
}
body:has(.site-homepage) .site-header__bar {
    background-color: transparent;
}
/* on small screens the bar scrolls away with the page instead of staying
   pinned — .site-header itself already accounts for this: it's absolutely
   (not fixed) positioned on the homepage and normal-flow on interior
   pages, so once the bar drops out of `fixed` it just becomes a normal
   child of that box and scrolls naturally along with it */
@media (max-width: 48rem) {
    .site-header__bar { position: static; }
}

/* Rounded, textured pill — holds the hamburger toggle and Google Translate.
   Fills the remaining width beside the crest rather than a fixed size. */
.site-topbar {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 1rem;
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.4rem 1.5rem 0.4rem 1.75rem;
    border-radius: 999px;
    background-color: var(--color-1);
    background-image: url("/pics/header_bg.svg");
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
    color: var(--color-over-1);
}
/* the pill only holds the hamburger on mobile (Translate is hidden, the
   crest stays hidden until scrolled) — shrink it to fit that one control
   instead of stretching across the remaining width, which
   .site-header__bar's justify-content:space-between then naturally pushes
   flush against the right edge, next to the crest on the left. Placed
   after the base rule above (same specificity) so it actually wins the
   cascade instead of being overridden by source order. */
@media (max-width: 48rem) {
    .site-topbar { flex: none; }
}

/* Google Translate — white chip so its #666 text stays legible on navy.
   margin-left:auto pushes just this item to the pill's far right, keeping
   the crest and hamburger grouped together at the left regardless of
   whether the crest is shown (3 items) or hidden (2 items). */
#google_translate_element {
    background-color: #fff;
    padding: 0.25rem 0.5rem;
    border-radius: var(--site-radius-sm);
    flex: none;
    margin-left: auto;
}
/* Google's own widget markup (language select + "Powered by" badge) has no
   narrow-width layout of its own — it just keeps growing wider, overflowing
   the pill on small phones. Hiding it below this breakpoint is simpler and
   more reliable than fighting Google-owned markup we can't restyle. */
@media (max-width: 30rem) {
    #google_translate_element { display: none; }
}

.site-header .site-header__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    text-decoration: none;
    color: var(--color-over-1);
}
.site-header__crest { width: clamp(90px, 12vw, 160px); height: auto; }

/* On scroll, the large crest hides and a small one takes its place inside
   the pill (see the scroll-listener script in header.jsp). The pill crest is
   pre-cropped (header_logo_navy_crop.png) to the shield only — the wreath +
   wordmark baked into the full crest get cut off, so the wordmark repeats
   here as real text instead, to the crest's right. */
.site-header.is-scrolled .site-header__identity { display: none; }
.site-topbar__brand {
    display: none;
    flex: none;
    align-items: center;
    gap: 0.75rem;
    text-decoration: none;
    color: var(--color-over-1);
}
.site-header.is-scrolled .site-topbar__brand { display: inline-flex; }
.site-topbar__crest { width: 80px; height: auto; }
/* the ancestor-qualified selector beats the CMS system stylesheet's default
   text color, which otherwise wins against a single-class rule here */
.site-header .site-topbar__wordmark {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.8rem;
    line-height: 1.15;
    max-width: 20ch;
    color: var(--color-over-1);
}

/* ---------- Navigation: single hamburger-triggered menu, all breakpoints ---------- */

/* Toggle lives in the topbar (a normal flex child there, not absolutely
   positioned) — always visible, since the hamburger is now the only way
   to reach navigation at any screen size. */
.menu-toggle {
    flex: none;
    width: 2.75rem;
    height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--color-over-1);
    cursor: pointer;
}
.menu-toggle::after {
    font-family: 'Material Symbols Outlined';
    font-variation-settings: 'FILL' 1;
    font-size: 1.75rem;
    content: 'menu';
    text-transform: none;
}
.menu-toggle[aria-expanded="true"]::after { content: 'close'; }

/* Mega-menu panel — a wide navy card spanning almost the full header width,
   columns laid out via grid (auto-fit collapses to fewer columns, down to 1,
   as the viewport narrows — no extra breakpoints needed). Everything below
   the column header is always visible once the panel is open; there are no
   per-item disclosure toggles in this design.

   Fixed to the viewport (not positioned relative to .site-header) — the
   header bar itself is position:fixed, pinned to the viewport regardless of
   scroll, so .site-header's own box (a normal-flow/absolute element used
   only for sizing) no longer lines up with where the bar visually sits once
   scrolled. --site-header-bar-h (inherited from .site-header, kept current
   by header.jsp's script) anchors the panel to the bar's real height in
   both the at-rest and scrolled states. */
.site-nav .nav-menu {
    display: none;
    position: fixed;
    /* the pill's own bottom edge, not the bar's (which has extra padding
       around the pill) — margin-top below is the whole visible gap */
    top: var(--site-topbar-bottom, var(--site-header-bar-h, 6rem));
    /* aligns to the pill, not the full bar — see header.jsp's script */
    left: var(--site-topbar-left, var(--site-pad-x));
    right: var(--site-pad-x);
    z-index: 30;
    margin: 8px 0 0;
    padding: 1.75rem 2rem;
    list-style: none;
    background-color: var(--color-1);
    border-radius: var(--site-radius);
    box-shadow: 0 18px 40px rgba(28, 54, 100, 0.28);
    max-height: calc(100vh - var(--site-topbar-bottom, var(--site-header-bar-h, 6rem)) - 1.5rem);
    overflow-y: auto;
    box-sizing: border-box;
}
.site-nav .nav-menu.show {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 1.75rem 1.5rem;
}

.site-nav .nav-item { position: relative; }

.site-nav .nav-item-inner {
    display: block;
    padding: 0 0 0.6rem;
    color: var(--color-over-1);
    font-weight: 700;
    font-size: 1.5rem;
    text-decoration: none;
}
/* only real links get the underline — container-only headers (no page of
   their own) render as a plain <div>, not an <a> */
.site-nav a.nav-item-inner { text-decoration: underline; text-underline-offset: 3px; }

.site-nav .sub-menu {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}
/* level-3: nested flat under its level-2 parent, no toggle — indented and
   slightly smaller rather than its own column */
.site-nav .sub-menu .sub-menu {
    margin-top: 0.5rem;
    padding-left: 1rem;
    gap: 0.45rem;
}

.site-nav .sub-menu-item > a,
.site-nav .sub-menu-inner {
    display: block;
    color: var(--color-over-1);
    text-decoration: none;
    font-weight: 400;
    opacity: 0.9;
}

/* Chevron toggle — hidden on desktop, where the flat column layout is
   always fully expanded. On small screens, every level with children
   collapses behind this button instead. */
.nav-item-toggle {
    display: none;
    background: none;
    border: 0;
    padding: 0.25rem;
    color: var(--color-over-1);
    cursor: pointer;
}
.nav-item-toggle-icon { transition: transform 0.2s ease; }
.nav-item-toggle[aria-expanded="true"] .nav-item-toggle-icon { transform: rotate(180deg); }

@media (max-width: 48rem) {
    /* full-bleed on small screens instead of an inset panel. Anchored to
       the whole bar's bottom edge (not just the pill's, like desktop uses)
       — the crest stays visible and is taller than the pill on mobile, so
       the pill-only anchor left the menu overlapping the crest's bottom. */
    .site-nav .nav-menu {
        top: var(--site-header-bar-bottom, var(--site-header-bar-h, 6rem));
        left: 0;
        right: 0;
        margin: 8px 0 0;
        border-radius: 0;
        max-height: calc(100vh - var(--site-header-bar-bottom, var(--site-header-bar-h, 6rem)));
    }
    /* single column, not auto-fit's 2-up at this width — a mega-menu grid
       doesn't read well split across narrow columns on a phone */
    .site-nav .nav-menu.show { grid-template-columns: 1fr; }
    .site-nav .nav-item { display: flex; flex-wrap: wrap; align-items: center; }
    .site-nav .nav-item-inner { flex: 1 1 auto; }
    .nav-item-toggle { display: inline-flex; align-items: center; justify-content: center; flex: none; }
    /* collapsed by default; JS toggles .is-open + aria-expanded together */
    .site-nav .nav-item > .sub-menu,
    .site-nav .sub-menu-item > .sub-menu {
        display: none;
        flex-basis: 100%;
    }
    .site-nav .nav-item.is-open > .sub-menu,
    .site-nav .sub-menu-item.is-open > .sub-menu {
        display: flex;
    }
    .site-nav .sub-menu-item { flex-wrap: wrap; align-items: center; }
    .site-nav .sub-menu-item > a,
    .site-nav .sub-menu-item > .sub-menu-inner { flex: 1 1 auto; }
}
@media (min-width: 48.01rem) {
    .nav-item-toggle { display: none !important; }
    .site-nav .nav-item > .sub-menu,
    .site-nav .sub-menu-item > .sub-menu { display: flex !important; }
}
.site-nav .sub-menu .sub-menu .sub-menu-item > a { font-size: 0.9em; }
.site-nav .sub-menu-item > a:hover,
.site-nav .sub-menu-item > a:focus-visible { opacity: 1; text-decoration: underline; }

/* ---------- Hero ---------- */

.site-hero {
    position: relative;
    background-color: var(--color-1);
    overflow: hidden;
}
.site-hero__media {
    position: relative;
    aspect-ratio: 16 / 9;
}
.site-hero__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.site-hero__embed { position: absolute; inset: 0; }
.site-hero__embed iframe,
.site-hero__embed video { width: 100%; height: 100%; object-fit: cover; }

/* Motto: title/caption/CTAs as a standalone block below the hero video (see
   index.jsp comment — moved off the video for blind/deafblind/low-vision
   readability, not a design preference). */
.site-motto {
    position: relative;
    overflow: hidden;
    background-color: var(--color-1);
    color: var(--color-over-1);
    text-align: center;
}
/* Same graphic as #site_swoosh_shared (Partners/Gallery/Footer), duplicated
   here since this section is self-contained and doesn't need JS-measured
   cross-section positioning — plain inset:0 cover is enough. Specificity
   bumped with the .site-motto ancestor to beat .site-homepage img's
   max-width/height reset. */
.site-motto .site-motto__swoosh {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    max-width: none;
    height: 100%;
    object-fit: cover;
    opacity: 0.2;
    pointer-events: none;
    user-select: none;
}
.site-motto__inner {
    position: relative;
    z-index: 1;
    max-width: var(--site-content-max);
    margin-inline: auto;
    padding: clamp(2rem, 5vw, 4rem) var(--site-pad-x);
    box-sizing: border-box;
}
.site-motto__title {
    color: var(--color-over-1);
    font-size: clamp(1.9rem, 4.6vw, 3.1rem);
    line-height: 1.08;
    margin: 0;
}
.site-motto__caption {
    margin: 0.85rem auto 0;
    font-size: clamp(1rem, 1.4vw, 1.15rem);
    max-width: 40rem;
}
.site-motto__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* Button system (navy/white) */
.site-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.75rem 1.6rem;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    border: 2px solid transparent;
    border-radius: var(--site-radius-sm);
    transition: background-color 0.15s ease, color 0.15s ease;
}
/* Every CTA outside the hero is an outline button that fills with its own
   outline colour on hover. Scoped under .site-homepage to beat the system
   a:link colour rule. */
.site-homepage .site-btn--solid {
    background-color: transparent;
    color: var(--color-1);
    border-color: var(--color-1);
}
.site-homepage .site-btn--solid:hover,
.site-homepage .site-btn--solid:focus-visible {
    background-color: var(--color-1);
    color: var(--color-over-1);
}

/* Motto sits on the navy block background: the filled button inverts to
   navy on hover, the outline one fills solid white. */
.site-motto__actions .site-btn--primary {
    background-color: var(--color-over-1);
    color: var(--color-1);
    border-color: var(--color-over-1);
}
.site-motto__actions .site-btn--primary:hover,
.site-motto__actions .site-btn--primary:focus-visible {
    background-color: var(--color-1);
    color: var(--color-over-1);
    border-color: var(--color-over-1);
}
.site-motto__actions .site-btn--outline {
    background-color: transparent;
    color: var(--color-over-1);
    border-color: var(--color-over-1);
}
.site-motto__actions .site-btn--outline:hover,
.site-motto__actions .site-btn--outline:focus-visible {
    background-color: var(--color-over-1);
    color: var(--color-1);
}

/* ---------- Image quicklinks ---------- */

/* a floating card, same pattern as the Superintendent card — overlaps up
   into the bottom of the News + Events navy band above it instead of
   sitting flush against it. Transparent outer section (only the narrower
   __inner card below paints white) so the navy shows through on the sides
   in the overlap zone, instead of this section's own full-bleed background
   covering it. -2rem here is a no-JS fallback only; footer.jsp measures the
   card's real height and sets this inline. */
.site-quicklinks {
    background-color: transparent;
    margin-top: -2rem;
}
.site-quicklinks__inner {
    max-width: min(84vw, 72rem);
    margin-inline: auto;
    padding: calc(var(--site-section-pad-y) * 0.4) var(--site-pad-x) var(--site-section-pad-y);
    position: relative;
    z-index: 2;
    background-color: var(--site-paper);
    border-radius: var(--site-radius);
}
.site-quicklinks__grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
@media (min-width: 48rem) {
    .site-quicklinks__grid { grid-template-columns: repeat(3, 1fr); }
}
/* auto-fit collapses unused tracks, so the row fills the full width whatever
   the item count is — 4 tiles stretch across; a 5th would slot in without a
   template change */
@media (min-width: 64rem) {
    .site-quicklinks__grid { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
}
.site-quicklinks__item a {
    position: relative;
    display: block;
    aspect-ratio: 3 / 4;
    border-radius: var(--site-radius);
    overflow: hidden;
    text-decoration: none;
}
.site-quicklinks__item img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.4s ease;
}
/* solid caption band — a semi-transparent solid carries the required contrast
   for white text over a photo; a gradient can't guarantee it (ACCESSIBILITY.md). */
.site-quicklinks__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 1rem;
    background-color: color-mix(in srgb, var(--color-1) 88%, transparent);
    transition: background-color 0.3s ease;
}
.site-quicklinks__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: clamp(1.15rem, 1.5vw, 1.5rem);
    line-height: 1.2;
    color: var(--color-over-1);
    transition: color 0.3s ease;
}
.site-quicklinks__subtitle {
    font-size: clamp(0.9rem, 1vw, 1.05rem);
    color: var(--color-over-1);
    transition: color 0.3s ease;
}
/* hover/focus: caption flips light with dark text while the photo zooms behind
   it. Matching the resting state's translucency (rather than going fully
   opaque) keeps the panel reading as a tinted overlay on the photo — a solid
   white would blend into the white section background instead. */
.site-quicklinks__item a:hover .site-quicklinks__caption,
.site-quicklinks__item a:focus-visible .site-quicklinks__caption {
    background-color: color-mix(in srgb, #fff 88%, transparent);
}
.site-quicklinks__item a:hover .site-quicklinks__title,
.site-quicklinks__item a:focus-visible .site-quicklinks__title,
.site-quicklinks__item a:hover .site-quicklinks__subtitle,
.site-quicklinks__item a:focus-visible .site-quicklinks__subtitle {
    color: #111;
}
.site-quicklinks__item a:hover img,
.site-quicklinks__item a:focus-visible img {
    transform: scale(1.08);
}
@media (prefers-reduced-motion: reduce) {
    .site-quicklinks__item img,
    .site-quicklinks__caption,
    .site-quicklinks__title,
    .site-quicklinks__subtitle { transition: none; }
    .site-quicklinks__item a:hover img,
    .site-quicklinks__item a:focus-visible img { transform: none; }
}

/* ---------- At A Glance stat band ---------- */

/* the navy container is inset — page background shows as white space around it,
   so the band itself is transparent and the fill/rounding sit on the inner */
.site-glance {
    background-color: transparent;
    padding: calc(var(--site-section-pad-y) * 0.5) var(--site-pad-x) var(--site-section-pad-y);
}
.site-glance .site-glance__title {
    font-size: var(--site-section-title);
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
    text-align: center;
    margin: 0 0 1.5rem;
}
.site-glance__inner {
    max-width: var(--site-content-max);
    margin-inline: auto;
    padding: clamp(1.75rem, 3vw, 2.75rem);
    background-color: var(--site-fog);
    color: var(--site-ink);
    border-radius: var(--site-radius);
}

/* Below desktop the accordion variant runs (content under its own title);
   from desktop up the two-column tabs take over. Only one is ever displayed. */
.site-glance__tabs { display: none; }
.site-glance__accordion { display: block; }
@media (min-width: 64rem) {
    .site-glance__accordion { display: none; }
    .site-glance__tabs {
        display: grid;
        grid-template-columns: minmax(14rem, 20rem) minmax(0, 1fr);
        gap: 3rem;
        align-items: start;
    }
}

/* ----- Accordion variant (below desktop) ----- */

.site-glance__acc-button {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0.85rem 0;
    font-family: var(--font-heading);
    font-size: 1.05rem;
    line-height: 1.3;
    color: var(--site-ink);
    cursor: pointer;
    border-top: 1px solid color-mix(in srgb, var(--site-ink), transparent 82%);
}
.site-glance__acc-button:first-of-type { border-top: 0; }
.site-glance__acc-button::after {
    font-family: 'Material Symbols Outlined';
    content: 'expand_more';
    font-size: 1.4rem;
    line-height: 1;
    text-transform: none;
    transition: transform 0.2s ease;
}
.site-glance__acc-button[aria-expanded="true"]::after { transform: rotate(180deg); }
.site-glance__acc-panel[aria-hidden="true"] { display: none; }
.site-glance__acc-panel { padding-bottom: 1.1rem; }
.site-glance__acc-panel img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    border-radius: var(--site-radius);
}
.site-glance__acc-summary {
    margin: 0.75rem 0 0;
    color: #333;
    font-size: 0.95rem;
}
.site-glance .site-glance__acc-link {
    display: inline-block;
    margin-top: 0.6rem;
    font-weight: 600;
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
}
@media (prefers-reduced-motion: reduce) {
    .site-glance__acc-button::after { transition: none; }
}

.site-glance__tablist {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.site-glance__tab {
    display: grid;
    grid-template-columns: 0.75rem minmax(0, 1fr);
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    text-align: left;
    padding: 0.65rem 1rem 0.65rem 0.35rem;
    background-color: transparent;
    border: 0;
    font-family: var(--font-heading);
    font-size: clamp(1.05rem, 1.6vw, 1.4rem);
    line-height: 1.25;
    color: color-mix(in srgb, var(--site-ink), transparent 12%);
    cursor: pointer;
}
/* selection marker — the column reserves its space at all times so the label
   never shifts; it fades in and scales up on select and reverses on deselect */
.site-glance__tab::before {
    content: "";
    box-sizing: border-box;
    width: 0.75rem;
    height: 0.75rem;
    border: 2px solid currentColor;
    border-radius: 50%;
    opacity: 0;
    transform: scale(0.3);
    transition: opacity 0.25s ease, transform 0.25s ease;
}
.site-glance__tab:hover,
.site-glance__tab:focus-visible { color: var(--site-ink); }
/* MonUI marks the active tab with aria-selected */
.site-glance__tab[aria-selected="true"] {
    color: var(--site-ink);
    font-weight: 700;
}
.site-glance__tab[aria-selected="true"]::before {
    opacity: 1;
    transform: scale(1);
}

/* all panels share one grid cell so switching tabs doesn't reflow the section,
   and visibility (not display) keeps inactive panels measurable */
.site-glance__panels {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "stack";
}
.site-glance__panels > .site-glance__panel {
    grid-area: stack;
    min-width: 0;
    position: relative;
    /* transitioning visibility defers the flip to the end of the fade, so the
       outgoing panel fades out instead of disappearing instantly */
    transition: opacity 0.35s ease, visibility 0.35s ease;
}
.site-glance__panels > .site-glance__panel[aria-hidden="true"] {
    visibility: hidden;
    opacity: 0;
}
.site-glance__card { transition: transform 0.35s ease; }
.site-glance__panel[aria-hidden="true"] .site-glance__card { transform: translateY(0.75rem); }

@media (prefers-reduced-motion: reduce) {
    .site-glance__tab::before,
    .site-glance__panels > .site-glance__panel,
    .site-glance__card { transition: none; }
}

.site-glance__media img {
    width: 100%;
    height: clamp(18rem, 37vw, 36.5rem);
    object-fit: cover;
    display: block;
    border-radius: var(--site-radius);
}
.site-glance__card {
    background-color: var(--site-paper);
    color: var(--site-ink);
    border-radius: var(--site-radius);
    padding: clamp(1.25rem, 2vw, 2rem) clamp(1.5rem, 2.2vw, 2.25rem);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
    margin: -2rem 1rem 0;
}
@media (min-width: 48rem) {
    .site-glance__card {
        position: absolute;
        left: 1.5rem;
        right: 1.5rem;
        bottom: 1.5rem;
        max-width: min(40rem, 68%);
        margin: 0;
    }
}
.site-glance__card-title { font-size: clamp(1.5rem, 2.2vw, 2.1rem); margin: 0 0 0.5rem; }
.site-glance .site-glance__card-title a { color: var(--site-ink); text-decoration: none; }
.site-glance__card-title a:hover,
.site-glance__card-title a:focus-visible { text-decoration: underline; }
.site-glance__card-summary { margin: 0; color: #333; font-size: clamp(1rem, 1.25vw, 1.2rem); }

/* ---------- Superintendent spotlight ---------- */

/* Deliberately NOT position:relative — this section overlaps News + Events
   below via a negative margin on that sibling (see the comment further
   down), which depends on both staying non-positioned so they compete on
   plain DOM order for paint priority. Giving this one position:relative
   would promote it into the "positioned" stacking bucket, which paints
   above static siblings regardless of DOM order — see the git history for
   the bug that caused (this section's white background wrongly covering
   the navy section behind it) when it briefly picked up position:relative
   for a decorative background that's since been removed. */
.site-super { background-color: var(--site-paper); }
/* a floating card, not a flat band. The overlap comes from .site-newsevents'
   negative margin-top (below) pulling the navy section up over the card's
   bottom edge — putting the negative margin on this card itself instead
   would just collapse .site-super's own height by the same amount (a
   classic margin-collapse gotcha), leaving the card flush against the navy
   section with no visible overlap at all. z-index lifts the card above that
   section (a plain static sibling, so it paints at stacking level 0)
   without needing position on .site-super itself. Narrower than the
   full-bleed navy section behind it, so navy shows on the sides too, not
   just below. */
.site-super__inner {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: center;
    /* narrower than .site-content-max on purpose — this is what leaves navy
       visible on the sides in the overlap zone below */
    max-width: min(84vw, 72rem);
    margin-inline: auto;
    padding: var(--site-section-pad-y) var(--site-pad-x) calc(var(--site-section-pad-y) * 0.4);
    position: relative;
    z-index: 2;
    background-color: var(--site-paper);
    border-radius: var(--site-radius);
}
.site-super__media { min-width: 0; }
.site-super__video,
.site-super__placeholder {
    width: 100%;
    aspect-ratio: 16 / 9;
    display: block;
    border-radius: var(--site-radius);
    background-color: var(--site-fog);
}
.site-super__embed { position: relative; aspect-ratio: 16 / 9; border-radius: var(--site-radius); overflow: hidden; }
.site-super__embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; }
.site-super__placeholder {
    border: 1px dashed var(--site-mist);
    display: grid;
    place-content: center;
}
.site-super__placeholder::after {
    font-family: 'Material Symbols Outlined';
    font-variation-settings: 'FILL' 1;
    font-size: 3rem;
    content: 'play_arrow';
    color: var(--site-mist);
}
.site-super__title {
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
    font-size: var(--site-section-title);
}
.site-super__cta { margin-top: 1rem; }

@media (min-width: 64rem) {
    .site-super__inner { grid-template-columns: 1.1fr 1fr; }
}

/* ---------- News + Events (shared container) ---------- */

/* one primary-blue container holds both subsections; the clock tower
   watermark sits behind them, bottom-center, clipped by overflow:hidden on
   the rounded box */
/* full-bleed like the header/hero — edge-to-edge, so no inset margin or
   rounding (rounding on this pattern elsewhere signals an inset card). */
/* pulled up over the superintendent card's bottom edge — see the comment
   on .site-super__inner above for why the overlap lives here, not there */
/* -2rem is a no-JS fallback only — footer.jsp measures the superintendent
   card's real height and sets this inline to exactly a quarter of it */
.site-newsevents { background-color: var(--color-1); margin-top: -2rem; }
.site-newsevents__inner {
    position: relative;
    overflow: hidden;
    color: var(--color-over-1);
}
.site-newsevents__content {
    position: relative;
    z-index: 1;
    max-width: var(--site-content-max);
    margin-inline: auto;
    padding: var(--site-section-pad-y) var(--site-pad-x);
}
/* centered across the shared Events+News container (not bottom-anchored) so
   it stays visible behind whichever subsection is on screen, instead of
   sitting below the fold past both of them — full container height so it
   touches the top and bottom edges */
.site-newsevents__inner .site-newsevents__watermark {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 0;
    height: 100%;
    width: auto;
    max-width: none;
    opacity: 0.12;
    pointer-events: none;
    user-select: none;
}
/* soft dark wash over the watermark for depth — sits between the graphic and
   the content, so the tower reads as part of the background rather than a
   flat sticker */
.site-newsevents__inner::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(to bottom,
        rgba(0, 0, 0, 0.22) 0%,
        rgba(0, 0, 0, 0.10) 38%,
        rgba(0, 0, 0, 0.16) 70%,
        rgba(0, 0, 0, 0.34) 100%);
}
.site-news,
.site-events { position: relative; z-index: 1; }
.site-events ~ .site-news { margin-top: clamp(5rem, 9vw, 7rem); }
@media (min-width: 64rem) {
    .site-events ~ .site-news { margin-top: clamp(4rem, 7vw, 6rem); }
}

.site-news__title,
.site-events__title {
    color: var(--color-over-1);
    font-size: var(--site-section-title);
    text-align: center;
}

/* ---------- Carousel shell (news + events) ---------- */

.site-news__carousel,
.site-events__carousel { position: relative; margin-top: 1.5rem; }
.site-news__carousel .swiper,
.site-events__carousel .swiper { width: 100%; }
.site-news__carousel .swiper-slide,
.site-events__carousel .swiper-slide { height: auto; }

/* arrows flank the "More …" button in a centered controls row rather than
   overlaying the slides — position:static opts them out of Swiper's absolute
   placement so they participate in the flex row. White-on-transparent here
   (not navy) since the controls sit on the section's own navy container. */
.site-carousel__controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 2rem;
}
.site-carousel__controls .swiper-button-prev,
.site-carousel__controls .swiper-button-next {
    position: static;
    margin: 0;
    width: 2.75rem;
    height: 2.75rem;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 2px solid var(--color-over-1);
    border-radius: 50%;
    background-color: transparent;
    color: var(--color-over-1);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.site-carousel__controls .swiper-button-prev::after,
.site-carousel__controls .swiper-button-next::after {
    font-family: 'Material Symbols Outlined';
    font-variation-settings: 'FILL' 1;
    font-size: 1.5rem;
    text-transform: none;
}
.site-carousel__controls .swiper-button-prev::after { content: 'chevron_left'; }
.site-carousel__controls .swiper-button-next::after { content: 'chevron_right'; }
.site-carousel__controls .swiper-button-prev:hover,
.site-carousel__controls .swiper-button-next:hover,
.site-carousel__controls .swiper-button-prev:focus-visible,
.site-carousel__controls .swiper-button-next:focus-visible {
    background-color: var(--color-over-1);
    color: var(--color-1);
}
.site-carousel__controls .swiper-button-disabled { opacity: 0.35; }

/* nothing to advance in either direction — drop the arrows, keep the button */
.swiper-container:has(.swiper-button-prev.swiper-button-disabled):has(.swiper-button-next.swiper-button-disabled) .swiper-button {
    display: none;
}

/* "More …" button reversed (white on navy) so it reads against the section's
   own navy container — the shared .site-btn--solid is navy-on-white and would
   disappear here. */
.site-newsevents .site-carousel__more {
    background-color: transparent;
    color: var(--color-over-1);
    border-color: var(--color-over-1);
}
.site-newsevents .site-carousel__more:hover,
.site-newsevents .site-carousel__more:focus-visible {
    background-color: var(--color-over-1);
    color: var(--color-1);
}

/* News keeps the card treatment — white cards read as distinct tiles against
   the navy container. */
.site-news__card {
    background-color: var(--site-paper);
    color: var(--site-ink);
    border-radius: var(--site-radius);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 100%;
}
/* overflow:hidden keeps the 16/9 box from being stretched by a portrait image
   (the logo fallback) — without it the intrinsic height wins over aspect-ratio */
.site-news__thumb { aspect-ratio: 16 / 9; background-color: var(--site-fog); overflow: hidden; }
.site-news__thumb img,
.site-news__video { width: 100%; height: 100%; object-fit: cover; display: block; }
.site-news__thumb img.site-news__thumb-fallback {
    object-fit: contain;
    padding: 1.5rem;
    box-sizing: border-box;
}
.site-news__body { padding: 1rem; }
.site-news__card-title {
    font-size: 1.2rem;
    margin: 0 0 0.25rem;
}
.site-news .site-news__card-title a { color: var(--site-ink); text-decoration: none; }
.site-news__card-title a:hover,
.site-news__card-title a:focus-visible { text-decoration: underline; }
.site-news__summary { margin: 0; color: #333; }

/* Events drops the card look — only the date badge keeps a container; the
   rest of the row sits directly on the section's navy background. */
.site-events__row {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 1.25rem;
    align-items: start;
    height: 100%;
    box-sizing: border-box;
}
.site-events__date {
    display: grid;
    place-content: center;
    text-align: center;
    width: 4rem;
    height: 4rem;
    flex: none;
    background-color: var(--site-paper);
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
    border-radius: var(--site-radius);
}
.site-events__month { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; }
.site-events__day { font-family: var(--font-display); font-size: 1.6rem; font-weight: 700; line-height: 1; }
.site-events__name { font-size: 1.2rem; margin: 0 0 0.25rem; }
.site-events .site-events__name a { color: var(--color-over-1); text-decoration: none; }
.site-events__name a:hover,
.site-events__name a:focus-visible { text-decoration: underline; }
.site-events__meta,
.site-events__loc { margin: 0; color: var(--color-over-1); opacity: 0.85; font-size: 0.95rem; }

/* ---------- Decorative section watermark ---------- */

/* ONE <img>, appended at the end of the document (footer.jsp) since a
   wrapping element can't cross the </main> boundary between Gallery and
   Footer. Sized/positioned by JS (footer.jsp) to span from Partners' own
   top to Footer's own bottom. z-index:-1 keeps it behind Partners/Gallery/
   Footer's own content regardless of DOM order — those sections don't set
   their own z-index (auto = 0), so -1 always paints underneath them.
   Uses the SVG directly (not a rasterized copy) — it scales losslessly to
   whatever height this span works out to, avoiding the blur a fixed-
   resolution raster would show once stretched this tall. This asset is a
   single simple shape (unlike the much more complex multi-fragment torn-
   brushstroke SVG used earlier), so it doesn't carry the same scroll-jank
   risk that motivated switching to a raster back then. */
#site_swoosh_shared {
    position: absolute;
    left: 0;
    z-index: -1;
    width: 100%;
    max-width: none;
    object-fit: cover;
    pointer-events: none;
    user-select: none;
}

/* ---------- Partners ---------- */

/* transparent outer section (page white shows), title sits directly on it.
   No boxed/carded look — the brush-stroke graphic (its own navy color,
   same asset used in Superintendent's Message/Our Impact/Footer) is a
   loose decorative accent directly on this section's own background, not
   a fill standing in for a card shape. The source graphic is mostly a
   solid-filled band with only its edges torn/textured, so at any size
   large enough to read as a "fill" it just looks like a plain rectangle —
   it only reads as a brush accent kept modestly sized like the other
   three placements. */
/* secondary-brand-colored copy of the same file (fill changed at the file
   level to match --color-2's resolved value, #AAAAAA on this site — not a
   live CSS variable, since an externally-referenced SVG can't read the
   host page's custom properties), sized to cover the whole section rather
   than sit as a small accent */
.site-partners {
    position: relative;
    overflow: hidden;
    background-color: transparent;
    background-image: url("/pics/brush_stroke_fog.svg");
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
    padding: calc(var(--site-section-pad-y) * 0.5) var(--site-pad-x) var(--site-section-pad-y);
}
.site-partners__title {
    position: relative;
    z-index: 1;
    font-size: var(--site-section-title);
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
    text-align: center;
    margin: 0 0 1.5rem;
}
.site-partners__inner {
    position: relative;
    z-index: 1;
    max-width: var(--site-content-max);
    margin-inline: auto;
    padding: clamp(1.75rem, 3vw, 2.75rem);
}
.site-partners__carousel { position: relative; margin-top: 1.5rem; }
.site-partners__carousel .swiper { width: 100%; }
.site-partners__carousel .swiper-slide { height: auto; }
/* light background here (unlike Events/News, both on navy) — override the
   shared control color for contrast against it */
.site-partners .site-carousel__controls .swiper-button-prev,
.site-partners .site-carousel__controls .swiper-button-next {
    border-color: var(--color-1);
    color: var(--color-1);
}
.site-partners .site-carousel__controls .swiper-button-prev:hover,
.site-partners .site-carousel__controls .swiper-button-next:hover,
.site-partners .site-carousel__controls .swiper-button-prev:focus-visible,
.site-partners .site-carousel__controls .swiper-button-next:focus-visible {
    background-color: var(--color-1);
    color: var(--color-over-1);
}
.site-partners__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    height: 100%;
}
.site-partners__item a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    text-decoration: none;
}
/* the ring (hand-drawn scribble circle, decorative) sits behind the white
   badge. Masked rather than tinted via filter — the source SVG is a solid
   shape, so using it as a mask lets each item take an exact brand color via
   background-color instead of an approximate hue-rotate. Cycles through 4
   colors: item 5 repeats item 1's color, item 6 repeats item 2's, etc. */
.site-partners__ring-wrap {
    position: relative;
    width: 100%;
    max-width: 12.5rem;
    aspect-ratio: 1 / 1;
}
.site-partners__ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    -webkit-mask-image: url("/pics/partners_ring.svg");
    mask-image: url("/pics/partners_ring.svg");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}
/* .swiper-slide, not .site-partners__item, is the repeating sibling now
   that each item sits one level deeper inside its own slide wrapper */
.site-partners__carousel .swiper-slide:nth-child(4n+1) .site-partners__ring { background-color: #133A65; }
.site-partners__carousel .swiper-slide:nth-child(4n+2) .site-partners__ring { background-color: #32A57A; }
.site-partners__carousel .swiper-slide:nth-child(4n+3) .site-partners__ring { background-color: #84007F; }
.site-partners__carousel .swiper-slide:nth-child(4n)   .site-partners__ring { background-color: #FF9026; }
.site-partners__badge {
    position: absolute;
    inset: 1.25rem;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background-color: var(--site-paper);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
    overflow: hidden;
}
.site-partners__badge .site-partners__logo {
    max-width: 90%;
    max-height: 90%;
    width: auto;
    height: auto;
    object-fit: contain;
}
.site-partners__name {
    font-weight: 700;
    font-size: 1.15rem;
    line-height: 1.3;
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
    text-align: center;
    text-decoration: none;
}
.site-partners__item a:hover .site-partners__name,
.site-partners__item a:focus-visible .site-partners__name {
    text-decoration: underline;
}

/* ---------- Gallery ---------- */

.site-gallery {
    position: relative;
    overflow: hidden;
    background-color: transparent;
}
.site-gallery__inner {
    position: relative;
    z-index: 1;
    max-width: var(--site-content-max);
    margin-inline: auto;
    padding: var(--site-section-pad-y) var(--site-pad-x);
}
/* 3-across masonry with alternating tile heights — every other photo is
   taller. Column flow (rather than a grid) lets each photo pull up flush
   against the one above it, so a short tile never leaves a gap beneath it. */
.site-gallery__mosaic {
    column-count: 2;
    column-gap: clamp(0.75rem, 1.5vw, 1.25rem);
    /* sub-pixel column-height rounding can leave a hairline gap below the
       last row — invisible against the old plain white background, but
       visible as a stray line now that the swoosh graphic sits behind it.
       A small negative margin trades that gap for a slight, unnoticeable
       overlap instead. */
    margin-bottom: -2px;
}
@media (min-width: 48rem) {
    .site-gallery__mosaic { column-count: 3; }
}
.site-gallery__item {
    display: flex;
    flex-direction: column;
    margin: 0 0 clamp(0.75rem, 1.5vw, 1.25rem);
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    aspect-ratio: 3 / 2;
}
/* Two heights arranged so each column receives exactly one tall and one short
   tile — the columns therefore total the same height and finish flush, while
   the tall/short order flips in the middle column so the rows still stagger
   rather than reading as a plain grid. */
.site-gallery__item:nth-child(6n+1) { aspect-ratio: 1 / 1; }
.site-gallery__item:nth-child(6n+2) { aspect-ratio: 3 / 2; }
.site-gallery__item:nth-child(6n+3) { aspect-ratio: 3 / 2; }
.site-gallery__item:nth-child(6n+4) { aspect-ratio: 1 / 1; }
.site-gallery__item:nth-child(6n+5) { aspect-ratio: 1 / 1; }
.site-gallery__item:nth-child(6n+6) { aspect-ratio: 3 / 2; }
.site-gallery__item:has(figcaption) { aspect-ratio: auto; }
.site-gallery__item a {
    display: block;
    flex: 1;
    min-height: 0;
    line-height: 0;
}
.site-gallery__item:has(figcaption) a { aspect-ratio: 3 / 2; flex: none; }
.site-gallery__item img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--site-radius);
}
.site-gallery__item figcaption {
    flex: none;
    margin-top: 0.4rem;
    font-size: 0.85rem;
    line-height: 1.3;
    color: #333;
}

/* ---------- Scroll-in reveal ---------- */

/* [data-reveal] sections start faded down slightly; footer-init.js adds
   .is-revealed via IntersectionObserver the first time each one enters the
   viewport (one-shot — it doesn't re-hide on scroll back up). Sections start
   already visible if JS never runs (no-JS / init failure), so content is
   never permanently hidden. */
[data-reveal] {
    opacity: 0;
    transform: translateY(1.5rem);
    transition: opacity 0.6s ease, transform 0.6s ease;
}
[data-reveal].is-revealed {
    opacity: 1;
    /* transform: none, not translateY(0) — the latter is visually identical
       but still counts as "a transform" for stacking-context purposes,
       permanently trapping any z-index inside a revealed section (like the
       superintendent card's overlap into News + Events) in its own isolated
       context instead of competing normally with sibling sections. */
    transform: none;
}
[data-reveal="fade"] { transform: none; }
@media (prefers-reduced-motion: reduce) {
    [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ---------- Footer ---------- */

.site-footer__links {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.75rem;
}
.site-footer__linkgroup-title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    margin-bottom: 0.75rem;
}
.site-footer__linklist {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.9rem;
}
.site-footer .site-footer__links a { color: var(--color-over-1); text-decoration: underline; }

@media (min-width: 48rem) {
    .site-footer__links { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64rem) {
    .site-footer__links { grid-template-columns: repeat(4, minmax(8rem, 1fr)); gap: 2rem; }
}

/* transparent so the shared swoosh graphic (a sibling earlier in the
   .site-swoosh-host) shows through; .site-footer__inner below carries its
   own opaque navy panel so the address/links/logo stay legible regardless
   of what part of the graphic lands behind the footer */
/* decorative brush-stroke accent, white-on-navy — mirrors the navy one
   used in Partners, same idea flipped for contrast against this dark bg */
.site-footer {
    position: relative;
    overflow: hidden;
    background-color: transparent;
    background-image: url("/pics/brush_stroke_white.svg");
    background-repeat: no-repeat;
    background-position: center top;
    background-size: 45% auto;
    color: var(--color-over-1);
}
.site-footer__inner {
    position: relative;
    z-index: 1;
    background-color: var(--color-1);
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    max-width: var(--site-content-max);
    margin-inline: auto;
    padding: clamp(2rem, 5vw, 3.5rem) var(--site-pad-x);
    text-align: left;
}
/* logo left, name beside it with address + phone stacked underneath */
.site-footer__identity {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 1rem;
    text-align: left;
}
.site-footer__identity-text { display: flex; flex-direction: column; gap: 0.35rem; }
.site-footer__crest { width: 56px; height: auto; flex: none; }
.site-footer__name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.25rem;
}
.site-footer__contact { font-style: normal; display: flex; flex-direction: column; gap: 0.2rem; }
/* logo stacked above the name/address/phone on small screens, instead of
   squeezed beside them in a cramped row */
@media (max-width: 48rem) {
    .site-footer__identity { flex-direction: column; align-items: flex-start; gap: 0.85rem; }
}
.site-footer .site-footer__contact a { color: var(--color-over-1); text-decoration: underline; }
.site-footer__contact a:hover,
.site-footer__contact a:focus-visible { text-decoration: underline; }

.site-footer__social-list {
    display: flex;
    justify-content: flex-start;
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.site-footer .site-footer__social-link { display: inline-flex; color: var(--color-over-1); }
.site-footer__social-icon svg,
.site-footer__social-icon img { width: 1.5rem; height: 1.5rem; fill: currentColor; }
.site-footer__social-link:hover,
.site-footer__social-link:focus-visible { opacity: 0.75; }


.site-footer__legal { text-align: left; }
.site-footer__copyright { margin: 0 0 1rem; opacity: 0.85; font-size: 0.9rem; }
.site-footer__edlio { display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem; }
.site-footer .site-footer__edlio a { display: inline-flex; align-items: center; color: var(--color-over-1); }
.site-footer__edlio svg { fill: currentColor; }
.site-footer__edlio a[href*="edlio.com"] svg { width: 140px; height: 20px; }
.site-footer .site-footer__edlio-login { color: inherit; }
.site-footer__edlio-login svg { height: 1.5rem; width: auto; }

@media (min-width: 64rem) {
    .site-footer__inner {
        grid-template-columns: auto 1fr auto;
        text-align: left;
        align-items: start;
        gap: 4.5rem;
    }
    .site-footer__identity { justify-content: flex-start; }
    .site-footer__social-list { justify-content: flex-end; }
    .site-footer__legal { grid-column: 1 / -1; text-align: center; border-top: 1px solid color-mix(in srgb, var(--color-over-1), transparent 80%); padding-top: 1.25rem; }
    .site-footer__edlio { flex-direction: row; justify-content: center; }
}
