@import url("theme_settings/theme_settings.css");
@import url("https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,600;0,700;1,400;1,700&family=Sora:wght@500;600;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);

    /* 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 */

    /* Palette — CMS theme colors plus white/black only.
       --brand / --accent are the two CMS brand colors; --on-brand /
       --on-accent are their CMS-guaranteed accessible text pairings.
       Neutrals and translucent lines/shadows derive only from white/black. */
    --brand:      var(--color-1);
    --accent:     var(--color-2);
    --on-brand:   var(--color-over-1);
    --on-accent:  var(--color-over-2);
    --white:      #FFFFFF;
    --ink:        #000000;
    --line:       rgba(0, 0, 0, 0.12);
    --hover-tint: rgba(0, 0, 0, 0.06);
    --line-on-brand: color-mix(in srgb, var(--color-over-1), transparent 78%);
    --fill-on-brand: color-mix(in srgb, var(--color-over-1), transparent 88%);
    --shadow-lg:  0 1.5rem 2.75rem rgba(0, 0, 0, 0.18);

    --font-head: 'Sora', system-ui, sans-serif;
    --font-body: 'Inter', system-ui, sans-serif;

    /* 8pt spacing scale */
    --s1: 0.5rem;  --s2: 1rem;   --s3: 1.5rem; --s4: 2rem;
    --s5: 2.5rem;  --s6: 3rem;   --s8: 4rem;   --s10: 5rem;
    --s12: 6rem;   --s15: 7.5rem;
}

html { height: 100%; scroll-behavior: smooth; scroll-snap-type: y proximity; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; scroll-snap-type: none; }
    .btn, .read .msi { transition: none; }
}

body {
    margin: 0;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    background-color: var(--white);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 1.125rem;
    font-weight: 400;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

.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: var(--white);
}

/* 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-head);
    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: 300;
    padding: 0.75rem 1.25rem;
    background-color: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
    text-decoration: none;
}
.site-header .site-skip-link:focus-visible { left: 1rem; top: 1rem; }

.hidden-text,
.hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* ============================ Shared ============================ */
.wrap {
    width: 100%;
    max-width: var(--size-xl);
    margin-inline: auto;
    padding-inline: clamp(1rem, 5%, 2rem);
    box-sizing: border-box;
}
/* Scroll-snap on the homepage's major sections — proximity, not mandatory,
   so scrolling through a tall section (e.g. Events) still feels unforced;
   the browser only aligns to a section edge when a scroll gesture ends near
   one. scroll-margin-top clears the sticky header pill so a snapped
   section's own heading doesn't land underneath it. */
.site-homepage > .video-section,
.site-homepage > .hero,
.site-homepage > .linkbar,
.site-homepage > .bento,
.site-homepage > .events-section,
.site-homepage > .banner,
.site-homepage > .news,
.site-homepage > .gallery {
    scroll-snap-align: start;
    scroll-margin-top: 6rem;
}
.section { padding-block: var(--s10); }
/* Consistent vertical rhythm between sections on mobile — every block gets
   the same top/bottom padding so inter-section gaps are uniform. */
@media (max-width: 47.99rem) {
    .section { padding-block: var(--s8); }
    .section:has(+ .banner) { padding-bottom: 0; }
    .hero { padding-block: var(--s8); }
    .banner { padding-block: var(--s8); }
    .events > .wrap { padding-block: var(--s8); }
    .site-footer { margin-top: var(--s8); }
}

.site-homepage h2,
.site-homepage h3,
.site-homepage h4 { font-family: var(--font-head); margin: 0; }
.num { font-variant-numeric: tabular-nums; }

.display {
    font-family: var(--font-head);
    font-weight: 700;
    font-size: clamp(2.25rem, 8vw, 5.5rem);
    line-height: 0.98;
    letter-spacing: -0.03em;
}
.h2 {
    font-family: var(--font-head);
    font-weight: 600;
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1.04;
    letter-spacing: -0.03em;
}
.h3 { font-family: var(--font-head); font-weight: 600; font-size: 1.5rem; line-height: 1.25; letter-spacing: -0.01em; }
.h4 { font-family: var(--font-head); font-weight: 500; font-size: 1.25rem; line-height: 1.3; }

/* Section headings on light surfaces use the primary theme colour
   (guarded so a light primary falls back to black). Headings on the navy
   panels — events, footer — keep their on-brand white. */
.bento .h2, .news .h2, .gallery .h2, .video-section .h2 {
    color: var(--color-1);
    filter: brightness(var(--color-1-isDark));
}

/* Flatten CMS-served icon SVGs to currentColor so they coordinate with
   the section's text color (see links.md — Icon color treatment). */
.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; }
.lead { font-size: 1.25rem; line-height: 1.55; }

/* Material Symbols — text-transform:none neutralizes uppercase parents
   that would otherwise clobber ligature matching. */
.msi {
    font-family: 'Material Symbols Outlined';
    font-weight: normal;
    font-style: normal;
    line-height: 1;
    text-transform: none;
    vertical-align: middle;
    -webkit-font-feature-settings: 'liga';
    font-feature-settings: 'liga';
    user-select: none;
}

/* Accent color used as an icon/text on a light (white) surface. The
   isDark filter renders --accent when it's dark, else black — so a light
   theme secondary stays legible on white (see CSS_AUTHORING dark/light). */
.accent-on-light { color: var(--accent); filter: brightness(var(--color-2-isDark)); }

/* Section label — editorial "01 / Upcoming" device */
.slabel { display: flex; align-items: center; gap: 1rem; margin-bottom: var(--s4); }
.slabel-idx { font-family: var(--font-head); font-weight: 700; font-size: 1.25rem; }
.slabel-txt { font-weight: 600; font-size: 1rem; letter-spacing: 0.14em; text-transform: uppercase; }
.slabel-rule { flex: 1; height: 2px; background: var(--accent); border-radius: 2px; }
.slabel.on-navy .slabel-idx,
.slabel.on-navy .slabel-txt { color: var(--on-brand); }

/* One CTA anchor per section rather than a duplicate hidden at each breakpoint:
   stacked below the heading at narrow widths, beside it from 48rem. */
.shead {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s4);
    margin-bottom: var(--s6);
}
.shead h2 { max-width: 18ch; }
@media (min-width: 48rem) {
    .shead {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        align-items: flex-end;
        gap: var(--s4);
        flex-wrap: wrap;
    }
}

/* Buttons — min target 48px */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    box-sizing: border-box;
    min-height: 3rem;
    padding: 0.75rem 1.625rem;
    border-radius: 999px;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    cursor: pointer;
    border: 2px solid transparent;
    text-decoration: none;
    transition: transform .15s ease, background-color .15s ease, color .15s ease, border-color .15s ease;
}
.btn .msi { font-size: 1.25rem; }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-dark { background: var(--brand); color: var(--on-brand); }
.btn-outline { background: transparent; color: var(--ink); border-color: var(--brand); }
.btn-outline-light { background: transparent; color: var(--on-brand); border-color: var(--on-brand); }
/* Button anchor colours must beat both the system a:link rule (0,1,1) and
   the header's white-link rule `body .site-header a` (0,1,2) — hence the
   compound .btn.btn-* selector (0,2,2) so a header primary button (Enroll)
   keeps its --on-accent text instead of inheriting the header's white. */
body a.btn.btn-primary { color: var(--on-accent); }
body a.btn.btn-dark { color: var(--on-brand); }
body a.btn.btn-outline { color: var(--ink); }
body a.btn.btn-outline-light { color: var(--on-brand); }
.btn:hover, .btn:focus-visible { transform: translateY(-2px); }
body a.btn.btn-outline:hover, body a.btn.btn-outline:focus-visible { background: var(--brand); color: var(--on-brand); }
body a.btn.btn-outline-light:hover, body a.btn.btn-outline-light:focus-visible { background: var(--on-brand); color: var(--brand); }
/* Filled variants — blue and white, both hovering to the accent (orange). */
body a.btn.btn-blue { background: var(--brand); color: var(--on-brand); }
body a.btn.btn-blue:hover, body a.btn.btn-blue:focus-visible { background: var(--accent); color: var(--on-accent); }
body a.btn.btn-white { background: var(--white); color: var(--ink); }
body a.btn.btn-white:hover, body a.btn.btn-white:focus-visible { background: var(--accent); color: var(--on-accent); }
body a.btn.btn-dark:hover, body a.btn.btn-dark:focus-visible { background: var(--accent); color: var(--on-accent); }

/* ============================ Header ============================ */
.site-header {
    position: sticky;
    top: 0.75rem;
    z-index: 200;
    padding-top: 0.75rem;
    padding-inline: clamp(0.75rem, 4%, 2rem);
}
.site-header__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    max-width: var(--size-xl);
    margin-inline: auto;
    background: var(--brand);
    min-height: 4.25rem;
    padding: 0.5rem 0.75rem 0.5rem 1.5rem;
    border-radius: 999px;
    box-shadow: 0 1rem 2.5rem rgba(0, 0, 0, 0.22);
}
.site-brand { display: inline-flex; align-items: center; gap: 0.75rem; min-height: 2.75rem; }
.site-brand__logo { height: 2.75rem; width: auto; flex: none; }
.site-brand__name {
    font-family: var(--font-head); font-weight: 700; font-size: 1.25rem;
    letter-spacing: -0.01em; line-height: 1.05;
}
body .site-header a { color: var(--on-brand); text-decoration: none; }

/* The sitenav holds link and non-link items in the same visual position; the
   native underline is what tells them apart at rest, so it survives every
   interaction state. Brand and CTA anchors above stay undecorated. */
body .site-nav a.nav-item-inner,
body .site-nav .sub-menu-item > a { text-decoration: underline; }
body .site-nav a.nav-item-inner:hover,
body .site-nav a.nav-item-inner:focus-visible,
body .site-nav .sub-menu-item > a:hover,
body .site-nav .sub-menu-item > a:focus-visible { text-decoration: underline; }

/* Search + actions */
/* Holds the search icon link and the Enroll CTA — both fixed-size; the nav
   itself is what contracts (min-width: 0, below), and wraps to the
   hamburger below the desktop breakpoint. */
.site-header__actions { display: none; align-items: center; gap: 0.75rem; min-width: 0; }
.site-header__actions .site-search { flex: none; }
.site-header__actions .site-enroll { flex: 0 0 auto; }
.site-enroll { min-height: 2.5rem; padding-block: 0.375rem; }
body a.btn.site-enroll:hover, body a.btn.site-enroll:focus-visible { background: var(--white); color: var(--ink); }
/* Mobile: the hamburger is absolutely positioned (~4.5rem of right-side space),
   so reserve room on the bar; otherwise the brand name runs under it. */
@media (max-width: 47.99rem) { .site-header__bar { padding-right: 4.75rem; } }
.site-search {
    width: 2.5rem; height: 2.5rem; border-radius: 999px; flex: none;
    background: transparent; color: var(--on-brand); display: grid; place-items: center;
}
.site-search .msi { font-size: 1.375rem; }
.site-search:hover, .site-search:focus-visible { background: var(--fill-on-brand); }

/* ---- Desktop navigation ---- */
.site-nav--desktop { display: none; }
/* A flex item's default min-width is auto, which floors it at its content's
   unwrapped width regardless of flex-shrink — without this, the nav claims
   whatever width its labels need on one line and pushes search/Enroll (its
   flex siblings in .site-header__bar) past the bar's right edge instead of
   actually contracting. */
.site-nav--desktop { min-width: 0; }
.site-nav--desktop .nav-menu {
    display: flex; align-items: center; gap: 0.125rem;
    list-style: none; margin: 0; padding: 0;
    /* Default top-level nav text to the on-brand colour so CONTAINER items
       (rendered as <div>, not <a>) and the toggle chevrons aren't left black;
       the dropdown panel overrides back to --ink. */
    color: var(--on-brand);
}
.site-nav--desktop .nav-item { position: relative; display: inline-flex; align-items: center; min-width: 0; }
.site-nav--desktop .nav-item-inner {
    display: inline-flex; align-items: center; height: 2.75rem; padding: 0 0.375rem 0 0.75rem;
    font-weight: 600; font-size: 1rem; border-radius: 999px;
    white-space: nowrap;
}

/* Item count and label length are CMS-driven, so the bar has to absorb more
   and longer items than any one design anticipates: the row tightens its
   padding and type, then lets multi-word labels wrap to a second line,
   before the layout would otherwise overflow. */
@media (min-width: 64rem) and (max-width: 96rem) {
    .site-nav--desktop .nav-item-inner { padding: 0 0.25rem 0 0.5rem; font-size: 0.9375rem; }
    .site-nav--desktop .nav-item:not(.dropdown) .nav-item-inner { padding-right: 0.5rem; }
    .site-nav--desktop .dropdown-toggle { width: 1.25rem; }
    /* A small but non-zero gap — wrapped multi-word labels sitting flush
       against each other (0 gap) read as one run-together phrase. */
    .site-nav--desktop .nav-menu { gap: 0.5rem; }
    /* Wrap within a label rather than let the whole row grow wider — a fixed
       height would clip the second line, so the item grows to fit instead. */
    .site-nav--desktop .nav-item-inner {
        height: auto; min-height: 2.75rem;
        white-space: normal; text-align: center; line-height: 1.15;
    }
}
.site-nav--desktop .nav-item:not(.dropdown) .nav-item-inner { padding-right: 0.875rem; }
.site-nav--desktop .dropdown-toggle {
    height: 2.75rem; width: 1.75rem; padding: 0; border: 0; cursor: pointer;
    background: transparent; color: inherit; display: inline-grid; place-items: center;
    border-radius: 999px;
}
.site-nav--desktop .dropdown-toggle::after {
    font-family: 'Material Symbols Outlined'; content: 'expand_more';
    font-size: 1.25rem; text-transform: none; transition: transform .2s ease;
}
.site-nav--desktop .nav-item:hover > .dropdown-toggle,
.site-nav--desktop .nav-item:focus-within > .dropdown-toggle { background: var(--fill-on-brand); }
.site-nav--desktop .dropdown-toggle[aria-expanded="true"]::after,
.site-nav--desktop .nav-item.dropdown:hover > .dropdown-toggle::after,
.site-nav--desktop .nav-item.dropdown:focus-within > .dropdown-toggle::after { transform: rotate(180deg); }

/* [Structural] level-2 holder watches for .show */
.site-nav--desktop .sub-menu-holder { display: none; }
.site-nav--desktop .sub-menu-holder:has(.sub-menu.show) { display: block; }
/* TopLinkDisclosureMenu's hoverType:"on" binds hover to the top-level <a> for
   link items and to the toggle button for every item — but a CONTAINER item
   (rendered as <div class="nav-item-inner">, no href) has no anchor for the
   library to bind, so hovering its label alone never adds .show. This rule
   covers that gap for CONTAINER items specifically. Scoped to :has(> div...)
   so it doesn't also apply to link items, which the library already opens
   correctly on label hover. */
.site-nav--desktop .nav-item.dropdown:has(> div.nav-item-inner):hover > .sub-menu-holder,
.site-nav--desktop .nav-item.dropdown:has(> div.nav-item-inner):focus-within > .sub-menu-holder { display: block; }
/* Safety net: requires the panel's own trigger to still be genuinely
   hovered/focused, not just a stale .show left behind by the library. A wide
   panel (many/long children, e.g. a 15-item Athletics list) can visually
   overlap a narrow neighboring nav-item; when that happens the library's own
   hover tracking can fail to close the item the cursor has already left,
   leaving its panel rendered at the same time as the newly-hovered
   neighbor's. This class of failure is specific to sites whose nav content
   creates that overlap — most navs never trigger it. */
.site-nav--desktop .nav-item.dropdown:not(:hover):not(:focus-within) > .sub-menu-holder { display: none !important; }
/* [Structural] Flush against the trigger — hover is bound to this holder, so
   any gap here between the nav item and the panel lets the cursor exit both
   while crossing it, closing the menu before the pointer reaches the panel.
   The visual gap above the panel comes from .sub-menu's own margin instead. */
.site-nav--desktop .sub-menu-holder {
    position: absolute; top: 100%; left: 0; min-width: 15.5rem;
}
.site-nav--desktop .nav-item.drop-left .sub-menu-holder { left: auto; right: 0; }
.site-nav--desktop .sub-menu {
    list-style: none; margin: 0.625rem 0 0; padding: 0.5rem;
    background: var(--white); border-radius: 1.125rem; box-shadow: var(--shadow-lg);
}
.site-nav--desktop .sub-menu-item { position: relative; }
.site-nav--desktop .sub-menu-item.dropdown { display: grid; grid-template-columns: 1fr auto; align-items: center; }
body .site-nav--desktop .sub-menu a,
.site-nav--desktop .sub-menu .sub-menu-inner {
    display: flex; align-items: center; min-height: 2.75rem; padding: 0.5rem 1rem;
    border-radius: 0.75rem; font-weight: 600; font-size: 1rem; color: var(--ink);
}
body .site-nav--desktop .sub-menu a:hover,
body .site-nav--desktop .sub-menu a:focus-visible { background: var(--hover-tint); }
.site-nav--desktop .sub-menu .dropdown-toggle { color: var(--ink); }

/* [Structural] level-3 flyout — no holder wrapper at this level */
.site-nav--desktop .sub-menu .sub-menu { display: none; position: absolute; top: 0; left: 100%; min-width: 14rem; }
.site-nav--desktop .sub-menu .sub-menu.show { display: block; }
.site-nav--desktop .drop-left .sub-menu-item.dropdown > .sub-menu { left: auto; right: 100%; }

/* ---- Mobile navigation ---- */
.site-nav--mobile { position: static; }
.site-nav--mobile .menu-toggle {
    /* Offset = header padding-inline + inset, so the button tracks the pill's
       inset right edge at every width instead of spilling onto the white bg. */
    position: absolute; top: calc(50% + 0.375rem); right: calc(clamp(0.75rem, 4%, 2rem) + 0.75rem); transform: translateY(-50%); z-index: 210;
    width: 2.75rem; height: 2.75rem; border: 0; border-radius: 999px; cursor: pointer;
    background: var(--fill-on-brand); color: var(--on-brand); display: grid; place-items: center;
}
.site-nav--mobile .menu-toggle::after {
    font-family: 'Material Symbols Outlined'; content: 'menu'; font-size: 1.5rem; text-transform: none;
}
.site-nav--mobile .menu-toggle[aria-expanded="true"]::after { content: 'close'; }
.site-nav--mobile .nav-menu {
    display: none;
    position: absolute; left: clamp(0.75rem, 4%, 2rem); right: clamp(0.75rem, 4%, 2rem); top: calc(100% + 0.5rem);
    background: var(--brand); border-radius: 1.5rem; padding: 0.75rem;
    list-style: none; margin: 0; box-shadow: var(--shadow-lg);
    max-height: 80vh; overflow-y: auto;
}
.site-nav--mobile .nav-menu.show { display: block; }
.site-nav--mobile .nav-item { width: 100%; }
.site-nav--mobile .nav-item.dropdown { display: grid; grid-template-columns: 1fr auto; align-items: center; }
body .site-nav--mobile .nav-item-inner {
    display: flex; align-items: center; min-height: 2.75rem; padding: 0.5rem 1rem;
    color: var(--on-brand); font-weight: 600; font-size: 1.0625rem;
}
.site-nav--mobile .dropdown-toggle {
    grid-column: 2; height: 2.75rem; width: 2.75rem; padding: 0; border: 0; cursor: pointer;
    background: transparent; color: var(--on-brand); display: grid; place-items: center; border-radius: 0.75rem;
}
.site-nav--mobile .dropdown-toggle::after {
    font-family: 'Material Symbols Outlined'; content: 'expand_more'; font-size: 1.375rem; text-transform: none; transition: transform .2s ease;
}
.site-nav--mobile .dropdown-toggle[aria-expanded="true"]::after { transform: rotate(180deg); }
.site-nav--mobile .sub-menu-holder { display: none; grid-column: 1 / -1; }
.site-nav--mobile .sub-menu-holder:has(.sub-menu.show) { display: block; }
.site-nav--mobile .sub-menu { list-style: none; margin: 0; padding: 0; }
.site-nav--mobile .sub-menu-item.dropdown { display: grid; grid-template-columns: 1fr auto; align-items: center; }
body .site-nav--mobile .sub-menu a,
.site-nav--mobile .sub-menu .sub-menu-inner {
    display: flex; align-items: center; min-height: 2.75rem; padding: 0.5rem 1rem 0.5rem 2rem;
    color: var(--on-brand); font-weight: 600; font-size: 1rem;
}
.site-nav--mobile .sub-menu .sub-menu { display: none; grid-column: 1 / -1; }
.site-nav--mobile .sub-menu .sub-menu.show { display: block; }
body .site-nav--mobile .sub-menu .sub-menu .sub-menu-item > a { padding-left: 3rem; }
body .site-nav--mobile .nav-item-inner:hover,
body .site-nav--mobile .nav-item-inner:focus-visible,
body .site-nav--mobile .sub-menu a:hover,
body .site-nav--mobile .sub-menu a:focus-visible { background: var(--fill-on-brand); }
.site-nav--mobile .nav-item--cta { padding: 0.5rem 0.5rem 0.25rem; }
.site-nav--mobile .nav-item--cta .btn { width: 100%; justify-content: center; }
/* Matches the desktop Enroll hover — .btn-primary carries no hover of its own,
   so without this the mobile CTA would only lift, never recolor. */
body .site-nav--mobile .nav-item--cta a.btn:hover,
body .site-nav--mobile .nav-item--cta a.btn:focus-visible { background: var(--white); color: var(--ink); }

@media (min-width: 64rem) {
    .site-nav--desktop { display: block; }
    .site-header__actions { display: flex; }
    .site-nav--mobile { display: none; }
}

/* ============================ Hero ============================ */
.hero { padding-block: var(--s8) var(--s6); }
.hero-grid { display: grid; grid-template-columns: 1fr; gap: var(--s6); align-items: center; }
.hero-copy { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s5); }
.site-homepage .hero-title { color: var(--color-1); filter: brightness(var(--color-1-isDark)); margin: 0; }
.hero-lead { max-width: 46ch; margin: 0; }
.hero-lead > :first-child { margin-top: 0; }
.hero-lead > :last-child { margin-bottom: 0; }
.hero-cta { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 0; }
.hero-media { position: relative; max-width: 32rem; order: -1; }
.hero-media__frame { position: relative; z-index: 2; border-radius: 1.75rem; overflow: hidden; aspect-ratio: 4 / 5; }
.hero-media__frame img { width: 100%; height: 100%; object-fit: cover; }
.hero-media::before {
    content: ""; position: absolute; z-index: 1; right: -1.25rem; bottom: -1.25rem;
    width: 70%; height: 70%; background: var(--accent); border-radius: 1.75rem;
}
@media (min-width: 64rem) {
    .hero { padding-block: var(--s10) var(--s6); }
    .hero-grid { grid-template-columns: 1.2fr 0.8fr; gap: var(--s8); }
    .hero-media { max-width: 30rem; justify-self: end; order: 0; }
}
/* Tablet: hero is still single-column here, so shrink the portrait. */
@media (min-width: 48rem) and (max-width: 63.99rem) {
    .hero-media { max-width: 16rem; }
}

/* ============================ Feature banner (full-bleed spotlight) ============================ */
.banner {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 26rem;
    padding-block: var(--s10);
    overflow: hidden;
    color: var(--white);
}
/* Overscanned by a fixed amount top and bottom so the parallax translate never
   exposes an edge — footer.jsp caps the drift at 128px, inside this 9rem.
   .banner's overflow:hidden clips the excess. */
.banner-bg {
    position: absolute; left: 0; top: -9rem;
    width: 100%; height: calc(100% + 18rem);
    object-fit: cover; z-index: 0;
    will-change: transform;
}
/* Semi-transparent solid overlay for legible white text over the photo. */
.banner::after {
    content: ""; position: absolute; inset: 0; z-index: 1;
    background: color-mix(in srgb, var(--brand) 72%, transparent);
}
.banner .wrap { position: relative; z-index: 2; }
.banner-inner { max-width: 46rem; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s5); }
.banner-title { color: var(--white); margin: 0; }
.banner-lead { color: var(--white); max-width: 42rem; margin: 0; }
.banner-lead > :first-child { margin-top: 0; }
.banner-lead > :last-child { margin-bottom: 0; }
.banner-cta { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 0; }
/* Banner CTA hovers to white (scoped so the header Enroll button is unaffected). */
body .banner a.btn.btn-primary:hover,
body .banner a.btn.btn-primary:focus-visible { background: var(--white); color: var(--ink); }
@media (min-width: 64rem) {
    .banner { min-height: 30rem; }
}
/* A full-bleed banner sits flush against the section above it. */
.section:has(+ .banner) { padding-bottom: 0; }

/* ============================ Link bar ============================ */
.linkbar { background: var(--brand); border-block: 2px solid var(--accent); }
.linkbar-list {
    list-style: none; margin-inline: auto; max-width: var(--size-xl);
    padding: 1.125rem clamp(1rem, 5%, 2rem);
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    row-gap: 0.5rem;
}
.linkbar-list li { display: inline-flex; align-items: center; }
body .linkbar a {
    display: inline-block;
    font-family: var(--font-head); font-weight: 600; font-size: 1.25rem;
    letter-spacing: 0.02em; text-transform: uppercase; color: var(--on-brand);
    transition: transform .15s ease, color .15s ease;
}
body .linkbar a:hover,
body .linkbar a:focus-visible { color: var(--accent); transform: translateY(-0.25rem); }
.linkbar-list li:not(:last-child)::after {
    content: "/"; color: var(--accent); padding-inline: 1.5rem;
    font-family: var(--font-head); font-weight: 600; font-size: 1.25rem;
}

/* ============================ Bento ============================ */
.bento .shead--bento { margin-bottom: var(--s5); }
@media (max-width: 47.99rem) { .bento .shead--bento .lead { margin-top: var(--s4); } }
.bento-grid { display: grid; grid-template-columns: 1fr; grid-auto-rows: minmax(11rem, auto); gap: var(--s2); }
.cell {
    border-radius: 1.5rem; padding: var(--s4);
    display: flex; flex-direction: column; justify-content: center; gap: var(--s2);
}
.cell-icon :is(svg, img) { width: 1.75rem; height: 1.75rem; }
.cell-value { font-family: var(--font-head); font-weight: 700; font-size: 3.25rem; line-height: 1; letter-spacing: -0.02em; margin-bottom: 0.5rem; }
.cell-label { font-size: 1rem; }
.cell-navy { background: var(--brand); color: var(--on-brand); }
.cell-coral { background: var(--accent); color: var(--on-accent); }
.cell-white { background: var(--white); color: var(--ink); border: 1px solid var(--line); }
.cell-navy .cell-icon { color: var(--accent); }
.cell-white .cell-icon { color: var(--accent); filter: brightness(var(--color-2-isDark)); }
.cell-img { padding: 0; overflow: hidden; }
.cell-img img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 48rem) {
    .bento-grid { grid-template-columns: repeat(2, 1fr); }
    .cell-img { grid-column: span 2; grid-row: span 2; }
}
@media (min-width: 64rem) {
    .bento-grid { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 11.25rem; }
    .cell-img { grid-column: span 2; grid-row: span 2; }
}

/* ============================ Events ============================ */
.events { position: relative; color: var(--on-brand); }
/* Full-bleed navy background on its own layer behind the content column. */
.events::before {
    content: "";
    position: absolute;
    z-index: 0;
    top: 0; bottom: 0;
    left: 0;
    right: 0;
    background: var(--brand);
}
.events > .wrap { position: relative; z-index: 1; padding-block: var(--s10); padding-inline: clamp(2rem, 7%, 4.5rem); }
.events h2 { color: var(--on-brand); }
.ev-row {
    display: grid; grid-template-columns: 1fr; gap: var(--s2);
    padding-block: var(--s4); border-top: 1px solid var(--line-on-brand);
}
.ev-row:first-of-type { border-top: 0; }
.ev-date { font-family: var(--font-head); line-height: 1; display: flex; align-items: baseline; gap: 0.75rem; }
.ev-date__d { font-weight: 700; font-size: 2.75rem; letter-spacing: -0.02em; }
.ev-date__m { font-weight: 600; font-size: 1.25rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); }
.ev-main { display: flex; flex-direction: column; gap: 0.75rem; }
.ev-title { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.02em; }
body .events a { color: var(--on-brand); }
body .ev-title a { text-decoration: none; }
body .ev-title a:hover, body .ev-title a:focus-visible { color: var(--accent); text-decoration: underline; }
.ev-meta { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; font-size: 1rem; }
.ev-meta span { display: inline-flex; align-items: center; gap: 0.5rem; }
.ev-meta .msi { font-size: 1.125rem; color: var(--accent); }
@media (min-width: 48rem) {
    .ev-row { grid-template-columns: 8.25rem 1fr; gap: var(--s5); align-items: center; padding-block: var(--s5); }
    .ev-date { display: block; }
    .ev-date__d { display: block; font-size: 3.5rem; }
    .ev-date__m { display: block; margin-top: 0.375rem; }
    .ev-title { font-size: 2rem; }
}

/* Events *feature* page (/apps/events/): the platform's date box is a fixed 80px,
   sized for its default font — our taller Sora/Inter overflows it and the row's
   overflow:hidden clips the weekday. !important overrides the platform sheet
   (loaded after ours) so the box can grow to its content. */
body .event-day .day-date-box { height: auto !important; min-height: 80px; }
body li.event-day { overflow: visible; }

/* ============================ News ============================ */
/* Every slide uses one card layout (thumbnail on top, body below) at every
   breakpoint — slidesPerView is what changes, not the card shape. */
.news-lead { background: var(--white); border: 1px solid var(--line); border-radius: 1.75rem; overflow: hidden; display: flex; flex-direction: column; height: 100%; }
.news-lead__thumb { aspect-ratio: 16 / 9; }
.news-lead__thumb img { width: 100%; height: 100%; object-fit: cover; }
/* Fallback when an article has no featured photo (news.md's thumbnail chain,
   step 3): the school crest, contained rather than cropped, on a tinted plate
   sized well below the box so a square mark doesn't fill a 16:9 slot edge to edge. */
.news-lead__thumb--logo {
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--brand), transparent 92%);
}
.news-lead__thumb--logo img {
    width: 45%; height: 45%; object-fit: contain;
}
.news-lead__body { padding: var(--s4); display: flex; flex-direction: column; gap: 1rem; flex: 1; }
.news-lead__body h3 { font-size: 1.75rem; letter-spacing: -0.02em; }
.news-summary { margin: 0; font-size: 1rem; }
.news h3 { color: var(--ink); }
body .news a { color: var(--ink); }
/* News cards have no "Learn More" link, so the title itself is the affordance. */
body .news h3 a { text-decoration: underline; }
body .news h3 a:hover, body .news h3 a:focus-visible { color: var(--accent); filter: brightness(var(--color-2-isDark)); }
/* Learn More link: underline only the label text, never the arrow icon. */
.news .read { text-decoration: none; }
.news .read__label { text-decoration: underline; }

/* Carousel: side gutters reserve room for the prev/next buttons so they sit
   beside the track rather than over the first/last visible card. */
.news__carousel { position: relative; padding-inline: 3.5rem; }
.news__carousel .swiper { width: 100%; }
.news__carousel .swiper-slide { height: auto; }
.news__carousel .swiper-button-prev,
.news__carousel .swiper-button-next {
    --swiper-navigation-color: var(--on-brand);
    --swiper-navigation-bg: var(--brand);
    --swiper-navigation-sides-offset: 0px;
    width: 2.75rem; height: 2.75rem;
    border-radius: 50%;
    background: var(--swiper-navigation-bg);
}
.news__carousel .swiper-button-prev::after,
.news__carousel .swiper-button-next::after {
    font-size: 1.25rem;
}
@media (max-width: 47.99rem) {
    .news__carousel { padding-inline: 2.75rem; }
    .news__carousel .swiper-button-prev,
    .news__carousel .swiper-button-next {
        width: 2.25rem; height: 2.25rem;
    }
}

/* ============================ Gallery ============================ */
.gallery-grid { display: grid; grid-template-columns: repeat(2, 1fr); grid-auto-rows: 11rem; gap: var(--s2); }
.gallery-tile { margin: 0; border-radius: 1.25rem; overflow: hidden; background: var(--brand); }
.gallery-tile img, .gallery-tile a { display: block; width: 100%; height: 100%; }
.gallery-tile img { object-fit: cover; }
@media (min-width: 64rem) {
    .gallery-grid { grid-template-columns: repeat(6, 1fr); grid-template-rows: 12rem 12rem 15rem; grid-auto-rows: 12rem; }
    .gallery-tile.a { grid-column: span 2; grid-row: span 2; }
    .gallery-tile.b { grid-column: span 3; grid-row: span 2; }
    .gallery-tile.c { grid-column: span 1; grid-row: span 2; }
    .gallery-tile.d { grid-column: span 2; }
    .gallery-tile.e { grid-column: span 2; }
    .gallery-tile.f { grid-column: span 2; }
}

/* ============================ Read-more link ============================ */
.read { display: inline-flex; align-items: center; gap: 0.375rem; min-height: 2.75rem; font-weight: 600; font-size: 1rem; align-self: flex-start; }
.read .msi { color: var(--accent); filter: brightness(var(--color-2-isDark)); transition: transform .15s ease; }
.read:hover .msi, .read:focus-visible .msi { transform: translateX(4px); }

/* ============================ Video ============================ */
/* Leads the page full-bleed: no .wrap, so the band spans the viewport and
   meets the header with no gap. The heading stays for screen readers only. */
.video-section { padding-bottom: var(--s10); }
.video-section .shead { margin-bottom: 0; }
.video-band { position: relative; overflow: hidden; }
.video-band video { width: 100%; display: block; aspect-ratio: 16 / 9; object-fit: cover; background: var(--ink); }
.video-embed { position: relative; aspect-ratio: 16 / 9; }
.video-embed :is(iframe, object, embed) { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-cap { display: flex; align-items: center; gap: 0.75rem; margin-top: var(--s3); font-size: 1rem; }
.video-cap .msi { color: var(--accent); filter: brightness(var(--color-2-isDark)); }
@media (max-width: 47.99rem) {
    .video-section { padding-bottom: var(--s8); }
}
@media (min-width: 64rem) {
    .video-band video { aspect-ratio: 21 / 9; }
}

/* ============================ Footer ============================ */
.site-footer { background: var(--brand); color: var(--on-brand); border-radius: 2.5rem 2.5rem 0 0; padding-block: var(--s10) var(--s6); margin-top: var(--s12); }
.footer-word { font-family: var(--font-head); font-weight: 700; font-size: clamp(3rem, 12vw, 7.5rem); line-height: 0.9; letter-spacing: -0.04em; margin-bottom: var(--s6); }
.footer-grid { display: grid; grid-template-columns: 1fr; gap: var(--s8); margin-bottom: var(--s6); }
.site-footer h3 { color: var(--on-brand); margin-bottom: var(--s3); }
.footer-about__text { max-width: 22rem; }
.footer-about__text > :first-child { margin-top: 0; }
.footer-about__text > :last-child { margin-bottom: 0; }
body .site-footer a { color: var(--on-brand); }
.footer-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.footer-col li a { display: inline-flex; align-items: center; min-height: 2.75rem; text-decoration: underline; }
.footer-contact address { font-style: normal; }
.contact-line { display: flex; gap: 0.625rem; align-items: center; margin-bottom: 0.75rem; min-height: 2.75rem; text-decoration: none; }
.contact-line .msi { color: var(--accent); font-size: 1.25rem; flex: none; }
.contact-line .contact-text { text-decoration: underline; }
.socials { display: flex; gap: 1rem; margin-top: var(--s3); }
.socials .social-link { width: 4rem; height: 4rem; border-radius: 1rem; background: var(--fill-on-brand); color: var(--on-brand); display: grid; place-items: center; }
.socials .social-link:hover, .socials .social-link:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.socials .social-icon :is(svg, img) { display: block; width: 1.5rem; height: 1.5rem; fill: currentColor; }
.footer-bottom {
    border-top: 1px solid var(--line-on-brand); padding-top: var(--s4);
    display: flex; flex-direction: column; gap: var(--s3); font-size: 1rem;
}
.footer-edlio { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
.footer-edlio svg { fill: currentColor; }
.footer-edlio a:first-child svg { width: 140px; height: 20px; }
.footer-edlio__login { color: inherit; }
.footer-edlio__login svg { height: 1.5rem; width: auto; }
@media (min-width: 48rem) {
    .footer-grid { grid-template-columns: repeat(2, 1fr); }
    .footer-bottom { flex-direction: row; justify-content: space-between; align-items: center; }
}
@media (min-width: 64rem) {
    .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; }
}
