/* ==========================================================================
   MagnetSchools.us design system - Phase 2A-1
   ==========================================================================

   Loaded AFTER default.min.css, which is the 2008-era stylesheet the rest of
   the site still depends on. This file does two separate jobs and the split
   matters:

     1. GLOBAL SHELL. Page background, base typography, links, header, mobile
        navigation and footer. These belong to every page and are meant to
        change everywhere at once.

     2. COMPONENTS. Prefixed `ms-`, plus refinements to the classes Phase 1C
        and 1D already ship (.school-card, .badge, .source-note, .breadcrumbs,
        .county-empty). Nothing here renames or restructures those; the county
        and school templates are untouched in this phase and simply inherit the
        tidier version.

   Page LAYOUT is not touched outside the homepage. Phase 2A-1 section 23 is
   explicit that the visual language is judged on one page before the rest of
   the site is locked into it.

   The palette is not new. Phase 1C already chose blue #1d4ed8 for magnet
   emphasis, zinc neutrals for supporting text and amber for provenance,
   because those pages had to distinguish a federal classification from a
   legacy flag. Half a design system was therefore already in the product; this
   file makes the shell agree with it instead of inventing a second language.
   ========================================================================== */

:root {
    /* --- type ------------------------------------------------------------
       A system stack, deliberately. A webfont on this site would cost a
       render-blocking third-party request and a CSP origin on every page, to
       replace Verdana with something a directory reader will never notice. */
    --ms-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
        Arial, "Noto Sans", sans-serif;

    --ms-size-display: 2.125rem;  /* homepage h1 */
    --ms-size-h1: 1.75rem;
    --ms-size-h2: 1.3125rem;
    --ms-size-h3: 1.0625rem;
    --ms-size-body: 1rem;         /* 16px, up from the legacy 13px */
    --ms-size-small: 0.875rem;
    --ms-size-label: 0.8125rem;

    --ms-lh-tight: 1.2;
    --ms-lh-heading: 1.3;
    --ms-lh-body: 1.6;

    /* --- neutrals --------------------------------------------------------
       Body text is 9.2:1 on white and muted text 5.4:1, so the small print
       that carries provenance is readable rather than technically present. */
    --ms-page: #f6f8fb;
    --ms-surface: #ffffff;
    --ms-sunken: #f1f5fa;
    --ms-border: #dfe4ec;
    --ms-border-strong: #c4cddb;
    --ms-ink: #16203a;
    --ms-body-ink: #39435c;
    --ms-muted: #5c6884;

    /* --- brand ----------------------------------------------------------- */
    --ms-primary: #1d4ed8;
    --ms-primary-dark: #1a3fae;
    --ms-primary-deep: #16307f;
    --ms-primary-wash: #eaf0fe;
    --ms-primary-edge: #c3d4fb;

    /* --- provenance -------------------------------------------------------
       Source notes read as a deliberate part of the record, not a disclaimer:
       warm, quiet, and never smaller than the small-text size. */
    --ms-source-ink: #7a4a09;
    --ms-source-wash: #fffaf0;
    --ms-source-rule: #c07d18;

    /* --- classification ---------------------------------------------------
       Every one of these is paired with a word and a glyph in the markup.
       Colour is never the only carrier (section 4). */
    --ms-whole-ink: #16307f;
    --ms-whole-wash: #dce7fd;
    --ms-whole-edge: #9dbbf8;
    --ms-program-ink: #0b5570;
    --ms-program-wash: #ddf1fa;
    --ms-program-edge: #93d3ec;
    --ms-legacy-ink: #4a4f5c;
    --ms-legacy-wash: #f1f2f5;
    --ms-legacy-edge: #cdd1da;
    --ms-charter-ink: #6b4106;
    --ms-charter-wash: #fdf0d5;
    --ms-charter-edge: #efcc86;

    /* --- spacing (4px scale) --------------------------------------------- */
    --ms-1: 4px;
    --ms-2: 8px;
    --ms-3: 12px;
    --ms-4: 16px;
    --ms-5: 24px;
    --ms-6: 32px;
    --ms-7: 48px;
    --ms-8: 64px;

    /* --- shape ------------------------------------------------------------
       One radius and one shadow. "Everything floats in a rounded card" is the
       look this is specifically avoiding. */
    --ms-radius: 6px;
    --ms-radius-lg: 10px;
    --ms-radius-pill: 999px;
    --ms-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
    --ms-shadow-raised: 0 2px 8px rgba(16, 24, 40, 0.08);

    /* --- containers -------------------------------------------------------
       960px is not a compromise, it is the width the rest of the site already
       is: #wrapper and #content have been 960 since the legacy stylesheet, and
       the county, state and school pages are laid out inside it. A wider shell
       would leave every one of those pages floating left in an over-wide white
       field until their own templates are redone. */
    --ms-max: 960px;
    --ms-max-narrow: 720px;
    --ms-gutter: 20px;
}

/* ==========================================================================
   Base
   ========================================================================== */

body {
    background: var(--ms-page);
    color: var(--ms-body-ink);
    font-family: var(--ms-font);
    font-size: var(--ms-size-body);
    line-height: var(--ms-lh-body);
    padding: 0;
    text-align: left;
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--ms-primary);
}

a:hover,
a:focus {
    color: var(--ms-primary-dark);
}

/* Visible focus everywhere, including for the legacy templates that never had
   one. :focus-visible keeps it off mouse clicks. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--ms-primary);
    outline-offset: 2px;
    border-radius: 3px;
}

h1, h2, h3, h4 {
    color: var(--ms-ink);
    line-height: var(--ms-lh-heading);
}

/* The legacy stylesheet paints every #content heading orange with a brown rule
   down its left edge, which is the single loudest piece of 2008 left on the
   county and school pages. Neutralised globally so those pages stop fighting
   the shell while their templates wait their turn. */
#content h1,
#content h2 {
    color: var(--ms-ink);
    border-left: 0;
    padding-left: 0;
    font-weight: 650;
}

#content h1 { font-size: var(--ms-size-h1); margin: 0 0 var(--ms-3); }
#content h2 { font-size: var(--ms-size-h2); margin: var(--ms-6) 0 var(--ms-3); }
#content h3 { font-size: var(--ms-size-h3); }

#content p {
    margin-left: 0;
    line-height: var(--ms-lh-body);
}

/* Legacy rule made every in-content link bold and brown. */
#content a {
    color: var(--ms-primary);
    font-weight: 400;
    text-decoration: underline;
    text-underline-offset: 2px;
}

#content a:hover,
#content a:focus {
    color: var(--ms-primary-dark);
}

/* The rule above is for legacy prose, where an underlined link is right. The
   design-system components carry their own affordance -- a card, a button, a
   nav item -- and an id-specificity underline turns the state browser into a
   link farm, so they opt out at matching specificity. */
#content .ms-place,
#content .ms-statelist a,
#content .ms-btn,
#content .ms-nav a,
#content .school-card__name a,
#content .breadcrumbs a,
#content .ms-footer a {
    text-decoration: none;
}

/* Same reason as the underline: 56 state links all painted brand blue reads as
   a link farm. They keep body ink until hover, where the colour is the
   affordance. */
#content .ms-statelist a,
#content .ms-linklist a {
    color: var(--ms-body-ink);
}

/* And the same for buttons rendered as links. `#content a` is id specificity,
   so a white button label loses to it and the button ships blank -- which is
   exactly what /about's primary call to action did on first render. */
#content a.ms-btn--primary { color: #fff; }
#content a.ms-btn--secondary { color: var(--ms-ink); }
#content a.ms-btn--secondary:hover,
#content a.ms-btn--secondary:focus { color: var(--ms-primary-deep); }

#content .ms-place:hover,
#content .ms-place:focus,
#content .ms-statelist a:hover,
#content .ms-statelist a:focus {
    text-decoration: underline;
}

#content {
    background: var(--ms-surface);
}

.ms-container {
    width: 100%;
    max-width: var(--ms-max);
    margin: 0 auto;
    padding: 0 var(--ms-gutter);
    box-sizing: border-box;
}

.ms-container--narrow { max-width: var(--ms-max-narrow); }

/* The legacy shell pads #wrapper and #content by 15px on small screens, which
   would double up against .ms-container's own gutter and squeeze the homepage
   to ~305px on a 375px phone. The inset moves onto the two legacy content
   columns instead, so every existing page keeps exactly the margin it had and
   .ms-container becomes the only thing setting it on the new pages. */
@media (max-width: 767px) {
    #wrapper,
    #content {
        padding-left: 0;
        padding-right: 0;
    }

    #left-col,
    #right-col {
        padding-left: var(--ms-4);
        padding-right: var(--ms-4);
        box-sizing: border-box;
    }
}

/* Carried over from the inline <style> block that used to sit in the layout
   head; the search and contact forms are still sized by it. */
.textfield {
    width: 100%;
    max-width: 460px;
    box-sizing: border-box;
    font: inherit;
    color: var(--ms-ink);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius);
    padding: 10px var(--ms-3);
}

/* Screen-reader-only, for the skip link and for labels a sighted user gets
   from context. */
.ms-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.ms-skip {
    position: absolute;
    left: var(--ms-3);
    top: -100px;
    z-index: 100;
    background: var(--ms-surface);
    color: var(--ms-primary-deep);
    border: 2px solid var(--ms-primary);
    border-radius: var(--ms-radius);
    padding: var(--ms-2) var(--ms-4);
    font-weight: 600;
    text-decoration: none;
    transition: top 0.15s ease;
}

.ms-skip:focus { top: var(--ms-3); }

/* ==========================================================================
   Header
   ========================================================================== */

/* The legacy header was a 166px starburst JPEG with the site name absolutely
   positioned over it in green italics. Every rule below overrides that; the
   image is no longer requested. */
#header {
    background: var(--ms-surface);
    border-bottom: 1px solid var(--ms-border);
    padding: 0;
}

#nav {
    background: none;
    padding: 0;
}

#nav ul,
#nav li,
#nav li.home,
#nav a {
    background: none;
    border: 0;
}

.ms-header__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ms-4);
    min-height: 64px;
}

.ms-brand,
#nav .ms-brand {
    display: inline-flex;
    align-items: baseline;
    gap: 1px;
    text-decoration: none;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* .site-name is pinned by TemplateSeoTest: it is branding, not a heading, and
   must stay a span. The legacy absolute positioning is undone here. */
#nav .site-name,
#header .site-name {
    position: static;
    font-family: var(--ms-font);
    font-size: 1.3125rem;
    font-style: normal;
    font-weight: 700;
    line-height: 1.1;
    color: var(--ms-ink);
    margin: 0;
    padding: 0;
    top: auto;
    left: auto;
}

.ms-brand__tld { color: var(--ms-primary); }

.ms-nav ul {
    display: flex;
    align-items: center;
    gap: var(--ms-1);
    list-style: none;
    margin: 0;
    padding: 0;
    height: auto;
    line-height: normal;
}

.ms-nav li {
    float: none;
    list-style: none;
    margin: 0;
    padding: 0;
}

.ms-nav a,
#nav .ms-nav a {
    display: block;
    padding: var(--ms-2) var(--ms-3);
    border-radius: var(--ms-radius);
    color: var(--ms-body-ink);
    font-size: var(--ms-size-small);
    font-weight: 550;
    text-decoration: none;
}

.ms-nav a:hover,
#nav .ms-nav a:hover,
.ms-nav a:focus,
#nav .ms-nav a:focus {
    background: var(--ms-primary-wash);
    color: var(--ms-primary-deep);
}

.ms-nav a[aria-current="page"],
#nav .ms-nav a[aria-current="page"] {
    color: var(--ms-primary-deep);
    background: var(--ms-primary-wash);
}

.ms-navtoggle {
    display: none;
    align-items: center;
    gap: var(--ms-2);
    background: var(--ms-surface);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius);
    color: var(--ms-ink);
    font: inherit;
    font-size: var(--ms-size-small);
    font-weight: 600;
    padding: var(--ms-2) var(--ms-3);
    cursor: pointer;
}

.ms-navtoggle__bars {
    display: inline-block;
    width: 16px;
    height: 2px;
    background: currentColor;
    position: relative;
}

.ms-navtoggle__bars::before,
.ms-navtoggle__bars::after {
    content: "";
    position: absolute;
    left: 0;
    width: 16px;
    height: 2px;
    background: currentColor;
}

.ms-navtoggle__bars::before { top: -5px; }
.ms-navtoggle__bars::after { top: 5px; }

@media (max-width: 799px) {
    .ms-navtoggle { display: inline-flex; }

    .ms-nav {
        display: none;
        width: 100%;
        border-top: 1px solid var(--ms-border);
        padding: var(--ms-2) 0 var(--ms-3);
    }

    .ms-nav[data-open="true"] { display: block; }

    .ms-nav ul { display: block; }

    .ms-nav a,
    #nav .ms-nav a {
        padding: var(--ms-3) var(--ms-2);
        font-size: var(--ms-size-body);
        border-radius: var(--ms-radius);
    }

    .ms-header__bar { flex-wrap: wrap; min-height: 56px; }
}

/* No script, no toggle: the list stays open rather than becoming unreachable. */
.no-js .ms-navtoggle { display: none; }
.no-js .ms-nav { display: block; }

/* ==========================================================================
   Footer
   ========================================================================== */

#footer {
    background: var(--ms-surface);
    border-top: 1px solid var(--ms-border);
    color: var(--ms-muted);
    text-align: left;
    padding: var(--ms-7) 0 var(--ms-6);
    font-size: var(--ms-size-small);
}

.ms-footer__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ms-5);
}

@media (min-width: 700px) {
    .ms-footer__grid { grid-template-columns: 1.6fr 1fr 1fr; gap: var(--ms-6); }
}

.ms-footer h2 {
    font-size: var(--ms-size-label);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ms-muted);
    margin: 0 0 var(--ms-3);
    font-weight: 650;
}

.ms-footer ul { list-style: none; margin: 0; padding: 0; }
.ms-footer li { margin: 0 0 var(--ms-2); }
.ms-footer li:last-child { margin-bottom: 0; }
.ms-footer a { color: var(--ms-body-ink); text-decoration: none; }
.ms-footer a:hover, .ms-footer a:focus { color: var(--ms-primary); text-decoration: underline; }
.ms-footer__blurb { margin: 0 0 var(--ms-3); max-width: 46ch; line-height: var(--ms-lh-body); }
.ms-footer__brand { font-weight: 700; color: var(--ms-ink); font-size: 1rem; display: block; margin-bottom: var(--ms-2); }

.ms-footer__base {
    margin-top: var(--ms-6);
    padding-top: var(--ms-4);
    border-top: 1px solid var(--ms-border);
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-2) var(--ms-4);
    align-items: center;
    justify-content: space-between;
    color: var(--ms-muted);
}

.ms-footer__base p { margin: 0; }

/* ==========================================================================
   Buttons
   ========================================================================== */

.ms-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ms-2);
    font: inherit;
    font-weight: 600;
    line-height: 1.2;
    padding: 13px var(--ms-5);
    border-radius: var(--ms-radius);
    border: 1px solid transparent;
    text-decoration: none;
    cursor: pointer;
    text-transform: none;
    height: auto;
    background-image: none;
}

.ms-btn--primary,
input.ms-btn--primary {
    background: var(--ms-primary);
    border-color: var(--ms-primary);
    color: #fff;
}

.ms-btn--primary:hover,
.ms-btn--primary:focus {
    background: var(--ms-primary-dark);
    border-color: var(--ms-primary-dark);
    color: #fff;
}

.ms-btn--secondary {
    background: var(--ms-surface);
    border-color: var(--ms-border-strong);
    color: var(--ms-ink);
}

.ms-btn--secondary:hover,
.ms-btn--secondary:focus {
    border-color: var(--ms-primary);
    color: var(--ms-primary-deep);
    background: var(--ms-primary-wash);
}

/* ==========================================================================
   Section header
   ========================================================================== */

.ms-section { padding: var(--ms-7) 0; }
.ms-section--tight { padding: var(--ms-6) 0; }
.ms-section--sunken { background: var(--ms-sunken); border-block: 1px solid var(--ms-border); }

.ms-section__head { max-width: 68ch; margin: 0 0 var(--ms-5); }
.ms-section__head h2 { font-size: var(--ms-size-h2); margin: 0 0 var(--ms-2); }
.ms-section__head p { margin: 0; color: var(--ms-muted); }

/* ==========================================================================
   Hero and search
   ========================================================================== */

.ms-hero {
    background: var(--ms-surface);
    border-bottom: 1px solid var(--ms-border);
    padding: var(--ms-7) 0 var(--ms-6);
}

.ms-hero__inner { max-width: 780px; }

.ms-hero h1 {
    font-size: var(--ms-size-display);
    line-height: var(--ms-lh-tight);
    letter-spacing: -0.02em;
    margin: 0 0 var(--ms-3);
    color: var(--ms-ink);
    border-left: 0;
    padding-left: 0;
}

.ms-hero__lede {
    font-size: 1.0625rem;
    color: var(--ms-body-ink);
    margin: 0 0 var(--ms-5);
    max-width: 62ch;
}

.ms-search {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius-lg);
    box-shadow: var(--ms-shadow-raised);
    padding: var(--ms-5);
}

.ms-search__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ms-4);
    align-items: end;
}

@media (min-width: 800px) {
    .ms-search__row { grid-template-columns: 1.35fr 1fr auto; }
}

.ms-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.ms-field label {
    font-size: var(--ms-size-label);
    font-weight: 650;
    color: var(--ms-ink);
    letter-spacing: 0.01em;
}

.ms-field__hint { font-size: var(--ms-size-label); color: var(--ms-muted); }

.ms-field input[type="text"],
.ms-field input[type="search"] {
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    color: var(--ms-ink);
    background: var(--ms-surface);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius);
    padding: 12px var(--ms-3);
}

/* The placeholder is a worked example of the accepted format, not decoration,
   so it is held to the same 4.5:1 the rest of the small text is. */
.ms-field input::placeholder { color: #6c7488; }

.ms-search .ms-btn { width: 100%; }

@media (min-width: 800px) {
    .ms-search .ms-btn { width: auto; }
}

.ms-search__hint,
.ms-search__foot {
    margin: var(--ms-4) 0 0;
    font-size: var(--ms-size-small);
    color: var(--ms-muted);
}

.ms-search__foot a { color: var(--ms-primary); }

/* ==========================================================================
   Classification indicator
   ========================================================================== */

.badge,
.ms-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--ms-size-label);
    font-weight: 600;
    line-height: 1.4;
    padding: 3px 10px;
    border-radius: var(--ms-radius-pill);
    border: 1px solid transparent;
    white-space: nowrap;
}

.badge--whole, .ms-badge--whole {
    background: var(--ms-whole-wash);
    color: var(--ms-whole-ink);
    border-color: var(--ms-whole-edge);
}

.badge--program, .ms-badge--program {
    background: var(--ms-program-wash);
    color: var(--ms-program-ink);
    border-color: var(--ms-program-edge);
}

.badge--unverified, .ms-badge--legacy {
    background: var(--ms-legacy-wash);
    color: var(--ms-legacy-ink);
    border-color: var(--ms-legacy-edge);
    border-style: dashed;
}

.badge--charter, .ms-badge--charter {
    background: var(--ms-charter-wash);
    color: var(--ms-charter-ink);
    border-color: var(--ms-charter-edge);
}

/* The two definitions, side by side. Not a card grid: two short blocks with a
   rule, so the distinction reads as a definition rather than a feature list. */
.ms-classes {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ms-5);
}

@media (min-width: 760px) {
    .ms-classes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ms-6); }
}

.ms-class {
    border-top: 3px solid var(--ms-border);
    padding-top: var(--ms-4);
}

.ms-class--whole { border-top-color: var(--ms-primary); }
.ms-class--program { border-top-color: var(--ms-program-edge); }
.ms-class h3 { margin: var(--ms-3) 0 var(--ms-2); font-size: var(--ms-size-h3); }
.ms-class p { margin: 0; color: var(--ms-body-ink); }

/* ==========================================================================
   Key stats
   ========================================================================== */

.ms-stats {
    list-style: none;
    margin: var(--ms-6) 0 var(--ms-4);
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-3);
}

.ms-stat {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-left: 3px solid var(--ms-primary);
    border-radius: var(--ms-radius);
    padding: var(--ms-3) var(--ms-4);
    min-width: 150px;
}

.ms-stat__value {
    display: block;
    font-size: 1.375rem;
    font-weight: 700;
    color: var(--ms-ink);
    line-height: 1.2;
}

.ms-stat__label {
    display: block;
    font-size: var(--ms-size-label);
    color: var(--ms-muted);
    margin-top: 2px;
}

/* Content-width cards stack raggedly on a phone; full width reads as a list. */
@media (max-width: 560px) {
    .ms-stat { flex: 1 1 100%; }
}

/* ==========================================================================
   Source / provenance note
   ========================================================================== */

.source-note,
.ms-source {
    background: var(--ms-source-wash);
    border: 1px solid #f0e2c6;
    border-left: 3px solid var(--ms-source-rule);
    border-radius: var(--ms-radius);
    color: var(--ms-body-ink);
    padding: var(--ms-3) var(--ms-4);
    margin: var(--ms-4) 0;
    font-size: var(--ms-size-small);
    line-height: 1.55;
}

.source-note p,
.ms-source p { margin: 0 0 var(--ms-2); }
.source-note p:last-child,
.ms-source p:last-child { margin-bottom: 0; }

.ms-source__label {
    display: block;
    font-size: var(--ms-size-label);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ms-source-ink);
    margin-bottom: var(--ms-2);
}

/* The trust section: source rows, not fine print. */
.ms-sources { display: grid; grid-template-columns: 1fr; gap: var(--ms-4); }

@media (min-width: 760px) {
    .ms-sources { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ms-5); }
}

.ms-sourcecard {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
    padding: var(--ms-4) var(--ms-5);
}

.ms-sourcecard h3 { margin: 0 0 var(--ms-1); font-size: var(--ms-size-h3); }
.ms-sourcecard p { margin: 0; color: var(--ms-body-ink); font-size: var(--ms-size-small); }

.ms-sourcecard__year {
    display: inline-block;
    font-size: var(--ms-size-label);
    font-weight: 650;
    color: var(--ms-source-ink);
    background: var(--ms-source-wash);
    border: 1px solid #f0e2c6;
    border-radius: var(--ms-radius-pill);
    padding: 1px 9px;
    margin-bottom: var(--ms-2);
}

.ms-caveats { margin: var(--ms-5) 0 0; padding: 0; list-style: none; }

.ms-caveats li {
    position: relative;
    padding-left: var(--ms-5);
    margin-bottom: var(--ms-2);
    color: var(--ms-body-ink);
    font-size: var(--ms-size-small);
}

.ms-caveats li::before {
    content: "";
    position: absolute;
    left: 6px;
    top: 9px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ms-source-rule);
}

/* ==========================================================================
   Browse by place
   ========================================================================== */

.ms-places {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--ms-3);
}

.ms-place {
    display: block;
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
    padding: var(--ms-3) var(--ms-4);
    text-decoration: none;
    color: var(--ms-ink);
}

.ms-place:hover,
.ms-place:focus {
    border-color: var(--ms-primary);
    background: var(--ms-primary-wash);
    color: var(--ms-primary-deep);
}

.ms-place__name { display: block; font-weight: 650; }

.ms-place__count {
    display: block;
    font-size: var(--ms-size-label);
    color: var(--ms-muted);
    margin-top: 1px;
}

.ms-place:hover .ms-place__count,
.ms-place:focus .ms-place__count { color: var(--ms-primary-deep); }

/* The full A-Z list. Columns, not a wall: it is reference navigation and sits
   below the shortcuts. */
.ms-statelist {
    list-style: none;
    margin: 0;
    padding: 0;
    columns: 2;
    column-gap: var(--ms-5);
}

@media (min-width: 620px) { .ms-statelist { columns: 3; } }
@media (min-width: 960px) { .ms-statelist { columns: 4; } }

.ms-statelist__head {
    margin: var(--ms-6) 0 var(--ms-3);
    font-size: var(--ms-size-h3);
}

/* ------------------------------------------------------------ disclosure

   A native <details>. On a phone the 56-state index was ~1,300px of the page,
   below eight shortcuts that answer most of the intent; collapsing it costs
   nothing, because the links are server-rendered inside the element whether it
   is open or shut.

   The element ships CLOSED -- the state that is correct with no script at all.
   site.js opens it above 800px and marks the document, and only then is the
   summary hidden, so a desktop visitor with no JavaScript still sees a working
   control instead of an unreachable list. */

.ms-disclosure {
    margin-top: var(--ms-6);
    border-top: 1px solid var(--ms-border);
}

.ms-disclosure__summary {
    display: flex;
    align-items: center;
    gap: var(--ms-2);
    list-style: none;
    cursor: pointer;
    padding: var(--ms-4) 0;
    font-weight: 650;
    color: var(--ms-ink);
}

/* Safari draws its own triangle through a webkit pseudo-element. */
.ms-disclosure__summary::-webkit-details-marker { display: none; }

/* Our own marker, so it can rotate and sit on the correct side. */
.ms-disclosure__summary::before {
    content: "";
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--ms-primary);
    border-bottom: 2px solid var(--ms-primary);
    transform: rotate(-45deg);
    transition: transform 0.15s ease;
    margin-right: var(--ms-1);
}

.ms-disclosure[open] > .ms-disclosure__summary::before { transform: rotate(45deg); }

.ms-disclosure__summary:hover { color: var(--ms-primary-deep); }

.ms-disclosure__count {
    font-size: var(--ms-size-label);
    font-weight: 600;
    color: var(--ms-muted);
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius-pill);
    padding: 1px 9px;
}

/* The heading inside is for the document outline; the summary already labels
   the region on screen. */
.ms-statelist__head--indesc {
    margin-top: 0;
}

@media (min-width: 800px) {
    /* Only once the script has confirmed it can open the element. */
    .ms-js .ms-disclosure__summary { display: none; }
    .ms-js .ms-disclosure { border-top: 0; margin-top: 0; }
    .ms-js .ms-statelist__head--indesc { margin-top: var(--ms-6); }
}

.ms-statelist li { break-inside: avoid; margin-bottom: 2px; }

.ms-statelist a {
    display: block;
    padding: 5px 0;
    color: var(--ms-body-ink);
    text-decoration: none;
    font-size: var(--ms-size-small);
}

.ms-statelist a:hover,
.ms-statelist a:focus { color: var(--ms-primary); text-decoration: underline; }

/* A short list of links, not an A-Z index. Separate class rather than an
   override, so it never has to out-specify the column media queries. */
.ms-linklist { list-style: none; margin: 0; padding: 0; }
.ms-linklist li { margin-bottom: var(--ms-1); }

.ms-linklist a {
    display: block;
    padding: 4px 0;
    color: var(--ms-body-ink);
    font-size: var(--ms-size-small);
}

#content .ms-linklist a { text-decoration: none; }
#content .ms-linklist a:hover,
#content .ms-linklist a:focus { color: var(--ms-primary); text-decoration: underline; }

/* ==========================================================================
   School card (Phase 1C markup, refined here)
   ========================================================================== */

.school-cards {
    list-style: none;
    margin: 0 0 var(--ms-5);
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ms-3);
}

@media (min-width: 700px) {
    .school-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.school-card {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-left: 3px solid var(--ms-primary);
    border-radius: var(--ms-radius);
    box-shadow: var(--ms-shadow);
    padding: var(--ms-4);
}

.school-card--secondary {
    border-left-color: var(--ms-border-strong);
    background: var(--ms-sunken);
    box-shadow: none;
}

.school-card__name { margin: 0 0 2px; font-size: var(--ms-size-h3); line-height: 1.35; }
.school-card__name a { color: var(--ms-ink); font-weight: 650; text-decoration: none; }
.school-card__name a:hover, .school-card__name a:focus { color: var(--ms-primary); text-decoration: underline; }

/* Phase 2B-R1 section 4. The title link measured 22px tall at 375px and
   nothing else in the card was clickable, so the primary target on every
   listing page -- county, search, state sample, related schools -- sat under
   the 24px floor of WCAG 2.2 SC 2.5.8 and well under a comfortable thumb.

   The existing link now stretches over the whole card through a pseudo-
   element. No second anchor, no nested interactive element, no markup change:
   the accessible name, the href and the tab order are exactly what they were,
   and the hit area becomes the card.

   PRECONDITION: a .school-card holds exactly one link. The overlay sits above
   the card's other content, so a second control added here would be
   unreachable by pointer. partials/school-card.blade.php and the
   programme/historical branch of partials/search-result.blade.php both satisfy
   this. The county filter is unaffected -- it reads data-* attributes off the
   <li> and never clicks.

   Known trade: text inside a stretched card cannot be selected by dragging.
   Accepted for a result card whose text is a name, a place and three facts. */
.school-card { position: relative; }

.school-card__name a::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: var(--ms-radius);
}

/* Hover now has a whole card to report on, so the title carries the
   affordance for a pointer anywhere inside it. */
.school-card:hover .school-card__name a { color: var(--ms-primary); text-decoration: underline; }

/* And the focus ring moves to the box a keyboard user is actually
   activating. Without this the ring would outline four words in the corner of
   a target the full width of the page. */
.school-card__name a:focus-visible { outline: none; }
.school-card__name a:focus-visible::after {
    outline: 3px solid var(--ms-primary);
    outline-offset: 2px;
}

.school-card__place { margin: 0 0 var(--ms-3); font-size: var(--ms-size-small); color: var(--ms-muted); }
.school-card__badges { margin: 0 0 var(--ms-3); display: flex; flex-wrap: wrap; gap: 6px; }

.school-card__facts {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-1) var(--ms-4);
    font-size: var(--ms-size-small);
}

.school-card__facts div { display: flex; gap: 5px; }
.school-card__facts dt { color: var(--ms-muted); margin: 0; }
.school-card__facts dt::after { content: ":"; }
.school-card__facts dd { margin: 0; color: var(--ms-ink); font-weight: 600; }

.school-cards--secondary .school-card { border-left-color: var(--ms-border-strong); }

/* ==========================================================================
   Plain listing rows
   ==========================================================================

   Phase 2A-2B. The "other schools listed here" section on a county page is
   deliberately not cards: these are the rows the directory holds which the
   federal magnet collection does not identify as magnets, and giving them the
   same visual weight as the results above would undo the distinction Phase 1C
   exists to draw. A county can hold two hundred of them. */

.ms-listing-list { list-style: none; margin: 0; padding: 0; }

.ms-listing {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--ms-1) var(--ms-3);
    padding: 9px 0;
    border-bottom: 1px solid var(--ms-border);
}

.ms-listing:last-child { border-bottom: 0; }
.ms-listing__name { font-weight: 600; }
.ms-listing__place { color: var(--ms-muted); font-size: var(--ms-size-small); }

#content .ms-listing__name { text-decoration: none; color: var(--ms-ink); }
#content .ms-listing__name:hover,
#content .ms-listing__name:focus { color: var(--ms-primary); text-decoration: underline; }

/* ==========================================================================
   County result filters
   ==========================================================================

   Phase 1C section 17 built these and the rules have not changed: they hide
   and show cards already in the document, so there is no request, no URL
   change and no crawlable filter variant. They stay hidden until the script
   reveals them, so a visitor without JavaScript never meets a control that
   would do nothing. This is their styling only. */

.county-filters { margin: 0 0 var(--ms-4); }

.county-filters fieldset {
    border: 1px solid var(--ms-border);
    background: var(--ms-surface);
    border-radius: var(--ms-radius);
    padding: var(--ms-3) var(--ms-4);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ms-2) var(--ms-4);
    margin: 0;
}

.county-filters legend {
    font-size: var(--ms-size-label);
    font-weight: 650;
    color: var(--ms-ink);
    padding: 0 var(--ms-1);
}

.county-filters__option {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--ms-size-small);
    color: var(--ms-body-ink);
    cursor: pointer;
    /* A comfortable target on a phone without becoming a button. */
    min-height: 32px;
}

.county-filters__option input { accent-color: var(--ms-primary); }

.county-filters__clear {
    font: inherit;
    font-size: var(--ms-size-small);
    font-weight: 600;
    padding: 6px var(--ms-3);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius);
    background: var(--ms-surface);
    color: var(--ms-ink);
    cursor: pointer;
}

.county-filters__clear:hover,
.county-filters__clear:focus {
    border-color: var(--ms-primary);
    color: var(--ms-primary-deep);
    background: var(--ms-primary-wash);
}

.county-filters__status {
    font-size: var(--ms-size-small);
    color: var(--ms-muted);
    margin: var(--ms-2) 0 0;
}

/* ==========================================================================
   Questions and answers
   ==========================================================================

   Existing functionality, restyled only. It used to arrive with six !important
   width overrides fighting the float layout it sat inside; there is no float
   layout any more, so there is nothing to fight. */

.ms-qa { display: grid; gap: var(--ms-3); margin-bottom: var(--ms-5); }

.ms-qa__item {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
    padding: var(--ms-4);
}

.ms-qa__question { margin: 0; color: var(--ms-ink); font-weight: 600; }

.ms-qa__meta {
    display: block;
    font-size: var(--ms-size-label);
    font-weight: 400;
    color: var(--ms-muted);
    margin-bottom: var(--ms-1);
}

.ms-qa__answer {
    margin: var(--ms-3) 0 0;
    padding-left: var(--ms-4);
    border-left: 2px solid var(--ms-border-strong);
    color: var(--ms-body-ink);
}

.ms-qa__item .ms-btn { margin-top: var(--ms-3); }

.ms-btn--small { padding: 7px var(--ms-3); font-size: var(--ms-size-small); }

/* ==========================================================================
   Empty state
   ========================================================================== */

.ms-empty,
.county-empty {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius-lg);
    padding: var(--ms-5);
    margin: var(--ms-4) 0;
}

.ms-empty h2,
.ms-empty h3,
.county-empty h2 {
    margin: 0 0 var(--ms-2);
    font-size: var(--ms-size-h3);
    color: var(--ms-ink);
    border-left: 0;
    padding-left: 0;
}

.ms-empty p,
.county-empty p { margin: 0 0 var(--ms-3); color: var(--ms-body-ink); max-width: 68ch; }
.ms-empty p:last-child,
.county-empty p:last-child { margin-bottom: 0; }

.ms-empty__actions { display: flex; flex-wrap: wrap; gap: var(--ms-2); margin-top: var(--ms-4); }

/* ==========================================================================
   School profile
   ==========================================================================

   Phase 2A-2C. Replaces partials/profile-styles.blade.php, whose 123 lines
   were loaded inside the body and therefore beat the design system above them
   -- so .badge and .source-note meant one thing on a school page and another
   everywhere else. */

.ms-profile__place {
    margin: 0 0 var(--ms-3);
    color: var(--ms-muted);
    font-size: 1.0625rem;
}

.ms-profile__badges {
    margin: 0 0 var(--ms-4);
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-2);
}

/* .badge is nowrap, which is right on a card where every label is two or
   three words. The profile's own labels are sentences -- "Legacy magnet
   listing - current magnet status unverified" - and at 375px a nowrap badge
   ran straight off the side of its container. These wrap. */
.ms-profile__badges .badge {
    white-space: normal;
    text-align: left;
    max-width: 100%;
}

.ms-profile__magnet {
    margin: 0 0 var(--ms-4);
    padding-left: var(--ms-4);
    border-left: 3px solid var(--ms-primary);
    color: var(--ms-body-ink);
    max-width: 68ch;
}

/* An unconfirmed claim does not get the brand colour. */
.ms-profile__magnet--warning { border-left-color: var(--ms-source-rule); }

.ms-profile__intro { margin: 0 0 var(--ms-5); max-width: 68ch; }

/* --- status banner ------------------------------------------------------ */

.ms-notice {
    border: 1px solid var(--ms-border);
    border-left: 4px solid var(--ms-muted);
    border-radius: var(--ms-radius);
    background: var(--ms-sunken);
    color: var(--ms-body-ink);
    padding: var(--ms-3) var(--ms-4);
    margin: 0 0 var(--ms-5);
    max-width: 72ch;
}

.ms-notice strong { color: var(--ms-ink); }

.ms-notice--historical {
    border-left-color: var(--ms-source-rule);
    background: var(--ms-source-wash);
    border-color: #f0e2c6;
}

/* --- facts -------------------------------------------------------------- */

.ms-facts {
    margin: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    border-top: 1px solid var(--ms-border);
}

@media (min-width: 620px) {
    .ms-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--ms-6); }
}

.ms-facts__item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ms-2) var(--ms-4);
    padding: 10px 0;
    border-bottom: 1px solid var(--ms-border);
}

.ms-facts__item dt { margin: 0; color: var(--ms-muted); font-size: var(--ms-size-small); }
.ms-facts__item dd { margin: 0; color: var(--ms-ink); font-weight: 600; text-align: right; }

/* Section 12: subordinate, and visibly so. */
.ms-facts--historical dd { font-weight: 500; color: var(--ms-body-ink); }

.ms-facts__status {
    margin: var(--ms-4) 0 0;
    font-size: var(--ms-size-small);
    color: var(--ms-body-ink);
}

/* Phase 0B-R1: the qualifier is part of the claim, not decoration, so it is
   never smaller than the small-text size and never lighter than muted. */
.data-qualifier { color: var(--ms-muted); }

/* --- contact and map ---------------------------------------------------- */

.ms-contact {
    font-style: normal;
    display: grid;
    gap: 6px;
    margin: 0 0 var(--ms-4);
}

.ms-contact__line { display: block; }

.ms-map {
    display: block;
    width: 100%;
    height: 320px;
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
}

@media (max-width: 620px) {
    /* Section 10: present, but not the page. */
    .ms-map { height: 220px; }
}

/* --- prose and corrections ---------------------------------------------- */

.ms-prose { max-width: 68ch; }
.ms-prose p { margin: 0 0 var(--ms-3); }

.ms-correction {
    margin-top: var(--ms-5);
    padding-top: var(--ms-4);
    border-top: 1px solid var(--ms-border);
}

.ms-correction p { margin: 0 0 var(--ms-3); color: var(--ms-body-ink); }

/* --- comment form ------------------------------------------------------- */

.ms-disclosure--form { margin-top: var(--ms-5); }

.ms-form {
    display: grid;
    gap: var(--ms-4);
    max-width: 480px;
    padding-bottom: var(--ms-4);
}

.ms-form textarea {
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    color: var(--ms-ink);
    background: var(--ms-surface);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius);
    padding: 10px var(--ms-3);
}

.ms-form .ms-btn { justify-self: start; }

.ms-field__error { font-size: var(--ms-size-small); color: #a3320b; }

/* ==========================================================================
   Search results
   ========================================================================== */

.ms-results__summary {
    margin: var(--ms-4) 0 0;
    color: var(--ms-body-ink);
    max-width: 72ch;
}

.ms-results__summary strong { color: var(--ms-ink); }

/* ==========================================================================
   Documents and long-form prose
   ==========================================================================

   Phase 2A-2E. Articles, the privacy policy and anything else that is mostly
   words. The one rule is measure: 68 characters, not the 960px shell, because
   a line of body text that wide is measurably harder to read and the article
   pages were using every pixel of it.

   Article bodies are stored HTML written years ago -- <p>, <ul>, <b>, <a>,
   the odd <img>. Nothing here assumes more than that, and anything unexpected
   (a table, a wide image) is contained rather than allowed to break the page. */

.ms-doc {
    max-width: 68ch;
    color: var(--ms-body-ink);
    font-size: 1.0625rem;
    line-height: 1.7;
    /* Every stored article carries style="text-align: justify" on every
       paragraph. That is content, and section 8 says content is not rewritten
       here -- but justification without hyphenation is what produces the rivers
       of white space, and hyphens are a template decision. The narrower measure
       above does most of the work; this does the rest. */
    hyphens: auto;
    overflow-wrap: break-word;
}

.ms-doc > *:first-child { margin-top: 0; }
.ms-doc p { margin: 0 0 var(--ms-4); }

/* Phase 2B-R1 section 14. Phase 2A-2E left the stored justification alone and
   leaned on the 68ch measure and hyphens:auto above. Measured at 375px that is
   not enough: the column is about 39 characters wide and the widest space on a
   line runs 2.8x to 4.1x the median, which is what a river looks like. At 834px
   and above the same ratio falls to about 2x and justification is unobjectionable
   -- but the narrow case is the one most readers get.

   This is a presentation override, not a content edit. The 359 inline
   declarations across the ten stored articles stay exactly as written; the
   selector matches only elements that ask for justification, so no other inline
   style is touched. There are none: a census of all ten articles found 359
   `text-align: justify` and zero other inline alignments. `!important` is
   required and sufficient -- nothing else outranks an inline style. */
.ms-doc [style*="text-align: justify"],
.ms-doc [style*="text-align:justify"] {
    text-align: left !important;
}

.ms-doc h2 {
    font-size: var(--ms-size-h2);
    margin: var(--ms-7) 0 var(--ms-3);
    color: var(--ms-ink);
}

.ms-doc h3 {
    font-size: var(--ms-size-h3);
    margin: var(--ms-6) 0 var(--ms-2);
    color: var(--ms-ink);
}

.ms-doc ul,
.ms-doc ol { margin: 0 0 var(--ms-4); padding-left: var(--ms-5); }
.ms-doc li { margin-bottom: var(--ms-2); }
.ms-doc li:last-child { margin-bottom: 0; }
.ms-doc strong, .ms-doc b { color: var(--ms-ink); font-weight: 650; }

.ms-doc a {
    color: var(--ms-primary);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.ms-doc a:hover, .ms-doc a:focus { color: var(--ms-primary-dark); }

.ms-doc img {
    max-width: 100%;
    height: auto;
    border-radius: var(--ms-radius);
    margin: 0 0 var(--ms-4);
}

.ms-doc blockquote {
    margin: 0 0 var(--ms-4);
    padding-left: var(--ms-4);
    border-left: 3px solid var(--ms-border-strong);
    color: var(--ms-muted);
}

/* A table in an article body is rare and must not be what breaks the page on
   a phone. It scrolls inside its own box; the page never does. */
.ms-doc__scroll { overflow-x: auto; margin: 0 0 var(--ms-4); }

.ms-doc table {
    border-collapse: collapse;
    width: 100%;
    font-size: var(--ms-size-small);
}

.ms-doc th, .ms-doc td {
    border: 1px solid var(--ms-border);
    padding: var(--ms-2) var(--ms-3);
    text-align: left;
}

.ms-doc th { background: var(--ms-sunken); color: var(--ms-ink); }

.ms-doc__meta {
    margin: 0 0 var(--ms-5);
    color: var(--ms-muted);
    font-size: var(--ms-size-small);
}

/* ==========================================================================
   Article list
   ========================================================================== */

.ms-articles { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--ms-4); }

.ms-article {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
    padding: var(--ms-5);
}

.ms-article__category {
    display: inline-block;
    font-size: var(--ms-size-label);
    font-weight: 650;
    color: var(--ms-primary-deep);
    background: var(--ms-primary-wash);
    border-radius: var(--ms-radius-pill);
    padding: 1px 10px;
    margin-bottom: var(--ms-2);
}

.ms-article__title { margin: 0 0 var(--ms-2); font-size: var(--ms-size-h3); line-height: 1.35; }

#content .ms-article__title a { color: var(--ms-ink); text-decoration: none; font-weight: 650; }
#content .ms-article__title a:hover,
#content .ms-article__title a:focus { color: var(--ms-primary); text-decoration: underline; }

.ms-article__excerpt {
    margin: 0 0 var(--ms-3);
    color: var(--ms-body-ink);
    max-width: 72ch;
    /* The stored excerpt is the article's own opening HTML; it is trimmed to a
       few lines rather than truncated mid-sentence in PHP. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.ms-article__excerpt p { margin: 0; }
.ms-article__excerpt ul, .ms-article__excerpt ol { margin: 0; padding-left: var(--ms-5); }

.ms-article__media {
    float: right;
    width: 140px;
    height: auto;
    margin: 0 0 var(--ms-3) var(--ms-4);
    border-radius: var(--ms-radius);
}

@media (max-width: 560px) {
    .ms-article__media { float: none; width: 100%; margin: 0 0 var(--ms-3); }
}

/* ==========================================================================
   Pagination
   ========================================================================== */

.ms-pagination { margin-top: var(--ms-6); }
.ms-pagination nav { display: flex; justify-content: center; }
.ms-pagination svg { width: 18px; height: 18px; }

.ms-pagination .pagination {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-1);
    list-style: none;
    margin: 0;
    padding: 0;
}

.ms-pagination .page-link,
.ms-pagination .page-item span,
.ms-pagination .page-item a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 38px;
    height: 38px;
    padding: 0 var(--ms-2);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
    background: var(--ms-surface);
    color: var(--ms-ink);
    text-decoration: none;
    font-size: var(--ms-size-small);
}

.ms-pagination .page-item.active span,
.ms-pagination .page-item.active .page-link {
    background: var(--ms-primary);
    border-color: var(--ms-primary);
    color: #fff;
}

.ms-pagination .page-item.disabled span { color: var(--ms-muted); background: var(--ms-sunken); }

/* ==========================================================================
   Forms, continued
   ========================================================================== */

.ms-form--wide { max-width: 720px; }

.ms-form__grid { display: grid; gap: var(--ms-4); }

@media (min-width: 620px) {
    .ms-form__grid--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.ms-field select {
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    color: var(--ms-ink);
    background: var(--ms-surface);
    border: 1px solid var(--ms-border-strong);
    border-radius: var(--ms-radius);
    padding: 11px var(--ms-3);
}

.ms-field__required { color: var(--ms-source-ink); font-weight: 700; }

.ms-form__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-3);
    align-items: center;
    margin-top: var(--ms-2);
}

.ms-form__note { font-size: var(--ms-size-small); color: var(--ms-muted); margin: 0; }

.ms-fieldset {
    border: 0;
    padding: 0;
    margin: 0 0 var(--ms-6);
    display: grid;
    gap: var(--ms-4);
}

/* ==========================================================================
   Error pages
   ========================================================================== */

.ms-errorpage {
    max-width: 520px;
    margin: var(--ms-8) auto;
    padding: var(--ms-7) var(--ms-5);
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius-lg);
    text-align: center;
}

.ms-errorpage__glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--ms-sunken);
    color: var(--ms-muted);
    font-size: 20px;
    margin-bottom: var(--ms-4);
}

.ms-errorpage--alert .ms-errorpage__glyph { background: #fbeceb; color: #a3320b; }
.ms-errorpage--warn .ms-errorpage__glyph { background: var(--ms-source-wash); color: var(--ms-source-ink); }

.ms-errorpage h1 { font-size: var(--ms-size-h1); margin: 0 0 var(--ms-2); }
.ms-errorpage p { margin: 0 0 var(--ms-5); color: var(--ms-body-ink); }

.ms-errorpage__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-2);
    justify-content: center;
}

.ms-fieldset legend {
    padding: 0;
    margin-bottom: var(--ms-2);
    font-size: var(--ms-size-label);
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ms-muted);
}

/* The hCaptcha widget is 303px wide and does not shrink; it must not be what
   makes a 375px page scroll sideways. */
.ms-field .h-captcha { max-width: 100%; overflow-x: auto; }

/* ==========================================================================
   Breadcrumbs
   ========================================================================== */

.breadcrumbs {
    font-size: var(--ms-size-small);
    color: var(--ms-muted);
    margin: 0 0 var(--ms-4);
}

.breadcrumbs a { color: var(--ms-muted); text-decoration: none; }
.breadcrumbs a:hover, .breadcrumbs a:focus { color: var(--ms-primary); text-decoration: underline; }
.breadcrumbs__sep { margin: 0 6px; color: var(--ms-border-strong); }
.breadcrumbs__current { color: var(--ms-ink); font-weight: 600; }

/* ==========================================================================
   Ads
   ==========================================================================

   The units themselves are untouched -- same client, same slots, same
   adsbygoogle push. What changes is that each one now sits in a container with
   a reserved minimum height and real separation from the content above it, so
   a slot that fills late pushes nothing around and a slot that never fills
   does not leave the 700px of blank page the old homepage did. */

.ms-ad {
    display: block;
    margin: var(--ms-5) 0;
    text-align: center;
    overflow: hidden;
}

.ms-ad--banner { min-height: 100px; }

/* The site-wide banner unit's own dimensions, moved out of the inline <style>
   block that used to sit inside the layout's #content. */
.adslot_1 { display: block; height: 90px; }

@media (max-width: 600px) {
    .adslot_1 { width: 320px; height: 100px; margin: 0 auto; }
}

/* The state page's own responsive unit, moved out of the inline <style> block
   that used to sit inside school_state.blade.php. Same dimensions. */
.adslot_2 { display: block; width: 580px; height: 400px; max-width: 100%; margin: 0 auto; }

@media (max-width: 600px) {
    .adslot_2 { width: 300px; height: 250px; }
}
/* Reserve only what is actually known. The banner is a fixed 90/100px so
   holding that space costs nothing and prevents the shift; the responsive and
   link units have no height until they fill, so guessing a large one just
   leaves a hole on every page where the slot goes unsold. */
.ms-ad--inline { min-height: 100px; }
.ms-ad--links { min-height: 60px; }

/* AdSense stamps data-ad-status on the <ins> once it has decided. Collapsing
   the whole container on "unfilled" was tried and reverted: it removes ~100px
   AFTER the decision arrives, which is a cumulative-layout-shift regression on
   a site whose entire programme is search visibility. The reserved space stays;
   only the label goes, so an unsold slot is quiet whitespace rather than the
   word "Advertisement" sitting over nothing.

   Browsers without :has() simply keep the label. It is an enhancement, never a
   dependency. */
.ms-ad:has(ins[data-ad-status="unfilled"]) .ms-ad__label {
    visibility: hidden;
}

.ms-ad__label {
    display: block;
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    /* 4.7:1 on white. It was #97a1b4, which measured 2.6:1 -- quiet is a
       design choice, unreadable is not. */
    color: #6c7488;
    margin-bottom: var(--ms-1);
}

.ms-ad ins { display: block; }

/* ==========================================================================
   Cookie consent (Phase 1B behaviour untouched; this is layout only)
   ==========================================================================

   Checked at 375px before touching it: the modal fits and every button is
   reachable, so there was no bug to fix. The one real problem is that the
   longest option name wraps into a ragged two-line block against its
   description. Stacking the two below 520px is the whole change. Nothing here
   alters what the banner does, when it appears, or how the choice is stored. */

#cookie-banner .option {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--ms-1) var(--ms-3);
}

@media (max-width: 520px) {
    #cookie-banner .option { flex-direction: column; align-items: flex-start; }
}
