/* _content/PubInfo_BL/Components/Layout/MainLayout.razor.rz.scp.css */
/* --------------------------------------------------------------------------
   Masthead.

   The navy gradient is the piece of the district look this app keeps unchanged
   from ESS_BL - it is what makes the two read as the same family of
   applications even though the ground under them differs.
   -------------------------------------------------------------------------- */
.pcs-topbar[b-morsl3zv5n] {
    background: linear-gradient(135deg, var(--pcs-navy-700) 0%, var(--pcs-navy-950) 100%);
    color: #fff;
}

.pcs-header[b-morsl3zv5n] {
    display: flex;
    align-items: center;
    gap: clamp(0.75rem, 3vw, 1.25rem);
    padding-block: clamp(0.85rem, 2.5vw, 1.25rem);
}

.brand-link[b-morsl3zv5n] {
    display: inline-flex;
    flex: 0 0 auto;
    border-radius: var(--pcs-radius-sm);
}

.brand-link:focus-visible[b-morsl3zv5n] {
    outline: 3px solid var(--pcs-focus-on-navy);
    outline-offset: 3px;
}

.pcs-logo[b-morsl3zv5n] {
    display: block;
    height: clamp(38px, 9vw, 54px);
    width: auto;
}

.pcs-title-wrap[b-morsl3zv5n] {
    display: flex;
    flex-direction: column;
    min-width: 0; /* lets the wordmark wrap instead of forcing the header wide */
}

.pcs-overline[b-morsl3zv5n] {
    font-family: var(--pcs-font-subhead);
    font-size: clamp(0.6rem, 1.6vw, 0.72rem);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    /* Not pure white: the overline is secondary to the wordmark under it, and
       at this size full white vibrates against the navy. Still 8.9:1. */
    color: #B9C4DA;
}

.pcs-title[b-morsl3zv5n] {
    font-family: var(--pcs-font-display);
    font-weight: 800;
    font-size: clamp(1.1rem, 4.4vw, 1.85rem);
    line-height: 1.05;
    text-transform: uppercase;
    letter-spacing: 0.005em;
    color: #fff;
}

/* The brand accent stripe. Gold, sky and lime in equal thirds - the same device
   that closes the ESS hero panel, reused here as the masthead base so the
   header terminates in brand color rather than a hard edge against the ivory. */
.pcs-accent-stripe[b-morsl3zv5n] {
    height: 5px;
    background: linear-gradient(
        to right,
        var(--pcs-gold) 0 33.34%,
        var(--pcs-sky) 33.34% 66.67%,
        var(--pcs-lime) 66.67% 100%
    );
}

/* --------------------------------------------------------------------------
   Page frame. Footer pinned to the bottom on short pages - a public one-task
   page often has little content, and a footer floating mid-viewport reads as a
   half-loaded page.
   -------------------------------------------------------------------------- */
.page[b-morsl3zv5n] {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh; /* accounts for mobile browser chrome */
}

main[b-morsl3zv5n] {
    flex: 1 0 auto;
    padding-block: clamp(1.25rem, 4vw, 2.25rem);
}

/* --------------------------------------------------------------------------
   Footer.
   -------------------------------------------------------------------------- */
.site-footer[b-morsl3zv5n] {
    flex: 0 0 auto;
    margin-top: clamp(1.5rem, 5vw, 3rem);
    background: var(--pcs-navy-900);
    color: #D6DCE9;
    font-size: 0.93rem;
}

.footer-inner[b-morsl3zv5n] {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 2.5rem;
    justify-content: space-between;
    align-items: flex-start;
    padding-block: 1.5rem;
}

.footer-org[b-morsl3zv5n] {
    margin: 0;
    line-height: 1.5;
}

.footer-org strong[b-morsl3zv5n] {
    font-family: var(--pcs-font-subhead);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #fff;
    font-weight: 600;
}

.site-footer nav ul[b-morsl3zv5n] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-footer a[b-morsl3zv5n] {
    /* Sky blue is used for text ONLY on navy, where it clears 7:1. The app.css
       token comment marks it decorative-only against white - this is the
       exception the comment allows for. */
    color: var(--pcs-sky);
    text-decoration: none;
    /* Comfortable tap target in the footer too. */
    display: inline-block;
    padding-block: 0.3rem;
}

.site-footer a:hover[b-morsl3zv5n] {
    color: #fff;
    text-decoration: underline;
}

.site-footer a:focus-visible[b-morsl3zv5n] {
    outline: 3px solid var(--pcs-focus-on-navy);
    outline-offset: 2px;
}
/* _content/PubInfo_BL/Components/Pages/AreaPrograms.razor.rz.scp.css */
/* --------------------------------------------------------------------------
   Magnet / fundamental programs: one trigger under the result grid, and the
   modal it opens.

   Rendered only while PubInfoOptions.ShowAreaPrograms is true, which it
   currently is. It was false between 2026-08-26 and 2026-09-08; none of this
   was deleted, which is why turning it back on took one setting.

   Moved here from SchoolCard.razor.css when the trigger stopped being per-card.
   The reason is measured and recorded on the component: a per-card trigger cost
   every card exactly 52px, whether it was a full-width band or a chip in the
   map/directions row. One trigger down here costs the cards nothing.
   -------------------------------------------------------------------------- */

/* Closed, the <details> is an ordinary block between the grid and the
   disclaimer. Deliberately no background or border of its own: the panels above
   and below it are already surfaces, and a third would make the page a stack of
   boxes. */
.programs[b-9q5sqpaf75] {
    margin-top: 1.25rem;
}

/* --------------------------------------------------------------------------
   The trigger.

   Reads as a button rather than as a card header, because it is the only thing
   on this page that opens something in place instead of navigating. Navy fill,
   matching .btn-primary, so it is unmistakably actionable next to the two link
   chips inside the cards above.
   -------------------------------------------------------------------------- */
.programs-trigger[b-9q5sqpaf75] {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    /* Comfortably over the 48px target minimum, and full width so it is the
       obvious next thing after three cards rather than a stray pill. */
    min-height: 56px;
    padding: 0.85rem 1.25rem;
    cursor: pointer;
    font-family: var(--pcs-font-subhead);
    font-size: 0.95rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #fff;
    background: linear-gradient(135deg, var(--pcs-navy-600) 0%, var(--pcs-navy-950) 100%);
    border: 1px solid var(--pcs-navy-700);
    border-radius: var(--pcs-radius);
    box-shadow: var(--pcs-shadow);
    list-style: none; /* hide the default disclosure triangle */
    transition: filter 0.15s ease;
}

.programs-trigger[b-9q5sqpaf75]::-webkit-details-marker { display: none; }

.programs > summary.programs-trigger:hover[b-9q5sqpaf75] {
    filter: brightness(1.18);
}

.programs > summary.programs-trigger:focus-visible[b-9q5sqpaf75] {
    outline: 3px solid var(--pcs-focus);
    outline-offset: 2px;
}

.programs-trigger-icon[b-9q5sqpaf75] {
    flex: 0 0 auto;
    font-size: 1.05rem;
    line-height: 1;
    color: var(--pcs-gold);
}

.programs-trigger-text[b-9q5sqpaf75] { flex: 1 1 auto; }

/* The count doubles as the affordance: a family can see there is something in
   there before opening it. */
.programs-count[b-9q5sqpaf75] {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    min-width: 28px;
    height: 28px;
    padding-inline: 0.45rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.2);
    color: #fff;
    font-size: 0.85rem;
}

/* Custom caret, rotated when open. transform only, so it is free to animate and
   is suppressed by the reduced-motion block in app.css. */
.programs > summary.programs-trigger[b-9q5sqpaf75]::after {
    content: "";
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg) translateY(-2px);
    transition: transform 0.15s ease;
}

/* The standalone unavailable note - the Focus bridge is down. Matches the
   disclaimer's quiet register rather than the alert styling, because the zoned
   schools above are all correct. */
.programs-note-standalone[b-9q5sqpaf75] {
    margin: 1.25rem 0 0;
    padding: 0.85rem 1.1rem;
    border: 1px solid var(--pcs-border);
    border-left: 5px solid var(--pcs-border-strong);
    border-radius: var(--pcs-radius-sm);
    background: var(--pcs-surface-sunken);
    font-size: 0.93rem;
    color: var(--pcs-ink-muted);
}

/* --------------------------------------------------------------------------
   Open: a modal panel over a dimmed page.

   The <details> element itself becomes the scrim - fixed to the viewport,
   filling it, tinted with the brand navy. Its two children, the <summary> and
   the .programs-modal panel, are stacked in the centre and given the same
   width, so they read as one card: summary = header, panel = body.

   Doing it this way rather than with a separate backdrop element is what keeps
   the modal working with JavaScript blocked. The summary is the only control
   that has to stay reachable to close the thing, and here it is the top of the
   panel rather than something buried behind the scrim.
   -------------------------------------------------------------------------- */
.programs[open][b-9q5sqpaf75] {
    position: fixed;
    inset: 0;
    z-index: 200;
    margin: 0;
    display: grid;
    /* One explicit track, both children stretched into it. Letting the two
       auto-size themselves and centring each independently lets them disagree
       about their width, which shows up as the body sitting off-centre under its
       own header. */
    grid-template-columns: min(38rem, 100%);
    align-content: center;
    justify-content: center;
    justify-items: stretch;
    padding: clamp(0.75rem, 3vw, 2rem);
    background: rgba(7, 14, 36, 0.66); /* --pcs-navy-950 at 66% */
    /* Keep a rubber-band scroll on the panel from scrolling the page behind. */
    overscroll-behavior: contain;
}

/* The header. Sticky-feeling but not sticky: it is a sibling above the
   scrollable body, so it never scrolls away.

   This has to undo most of the trigger it is when closed - same element, two
   parts. The gradient and the full border in particular have to go, or the
   panel appears to have a floating navy button balanced on top of it. */
.programs[open] > summary.programs-trigger[b-9q5sqpaf75] {
    width: auto; /* the track sets the width */
    min-width: 0;
    border: 0;
    border-bottom: 1px solid var(--pcs-border);
    border-radius: var(--pcs-radius) var(--pcs-radius) 0 0;
    box-shadow: var(--pcs-shadow-lift);
    background: var(--pcs-surface);
    color: var(--pcs-navy);
}

.programs[open] > summary.programs-trigger:hover[b-9q5sqpaf75] {
    filter: none;
    background: var(--pcs-navy-050);
}

.programs[open] .programs-trigger-icon[b-9q5sqpaf75] {
    color: var(--pcs-gold);
}

/* Reversed-out-of-navy no longer applies on a white header. */
.programs[open] .programs-count[b-9q5sqpaf75] {
    background: var(--pcs-navy-600);
    color: #fff;
}

/* The caret becomes a close X. Same element, so nothing shifts, and the
   affordance matches what clicking it now does - dismiss the panel, not
   collapse a row. */
.programs[open] > summary.programs-trigger[b-9q5sqpaf75]::after {
    content: "\00D7"; /* multiplication sign - a true X, not the letter */
    width: auto;
    height: auto;
    border: 0;
    transform: none;
    font-size: 1.7rem;
    line-height: 1;
    color: var(--pcs-ink-muted);
}

.programs[open] > summary.programs-trigger:hover[b-9q5sqpaf75]::after {
    color: var(--pcs-ink);
}

.programs-modal[b-9q5sqpaf75] {
    width: auto;
    min-width: 0;
    background: var(--pcs-surface);
    border-radius: 0 0 var(--pcs-radius) var(--pcs-radius);
    box-shadow: var(--pcs-shadow-lift);
    /* The panel scrolls, not the page. Three levels at 11 / 11 / 44 programs is
       a real row count, and on a short viewport all of it has to stay
       reachable. */
    max-height: min(70vh, 36rem);
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Whose address this is. The scrim hides the page, so the panel restates it. */
.programs-modal-context[b-9q5sqpaf75] {
    margin: 0;
    padding: 0.7rem 1.25rem;
    border-bottom: 1px solid var(--pcs-border);
    background: var(--pcs-surface-sunken);
    font-family: var(--pcs-font-subhead);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--pcs-ink-muted);
}

/* --------------------------------------------------------------------------
   One group per grade level.

   The level headings are what make a single combined panel readable rather
   than a 66-item wall - they are also why the per-card version was redundant,
   since the panel already said which level each list belonged to.
   -------------------------------------------------------------------------- */
.programs-group[b-9q5sqpaf75] {
    padding: 0.9rem 1.25rem 0.2rem;
}

.programs-group + .programs-group[b-9q5sqpaf75] {
    border-top: 1px solid var(--pcs-border);
}

.programs-group-head[b-9q5sqpaf75] {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0 0 0.5rem;
    font-family: var(--pcs-font-subhead);
    font-size: 0.87rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--pcs-navy);
}

.programs-group-count[b-9q5sqpaf75] {
    display: grid;
    place-items: center;
    min-width: 24px;
    height: 24px;
    padding-inline: 0.4rem;
    border-radius: 999px;
    background: var(--pcs-page-bg-deep);
    color: var(--pcs-navy);
    font-size: 0.78rem;
}

.programs-list[b-9q5sqpaf75] {
    margin: 0;
    padding-left: 1.2rem;
    font-size: 0.97rem;
}

.programs-list li[b-9q5sqpaf75] { margin-bottom: 0.4rem; }

.programs-list a[b-9q5sqpaf75] { overflow-wrap: anywhere; }

/* Sits directly under the address, above the lists - see the note on the
   markup for why it is not a footer. */
.programs-note[b-9q5sqpaf75] {
    margin: 0;
    padding: 0.8rem 1.25rem;
    border-bottom: 1px solid var(--pcs-border);
    font-size: 0.9rem;
    color: var(--pcs-ink-muted);
    line-height: 1.45;
}

/* On a phone the panel is the screen. Rounding the corners of something that
   reaches all four edges just looks like a rendering fault. */
@media (max-width: 26rem) {
    .programs[open][b-9q5sqpaf75] {
        padding: 0;
    }

    .programs[open] > summary.programs-trigger[b-9q5sqpaf75] {
        border-radius: 0;
    }

    .programs-modal[b-9q5sqpaf75] {
        border-radius: 0;
        max-height: calc(100vh - 56px); /* 56px = the trigger's min-height */
    }
}
/* _content/PubInfo_BL/Components/Pages/Error.razor.rz.scp.css */
.error-panel[b-yqa08nslfe] {
    max-width: 640px;
    margin-inline: auto;
    border-top: 5px solid var(--pcs-gold);
}

.error-actions[b-yqa08nslfe] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.25rem;
}

.error-contact[b-yqa08nslfe] { margin-top: 1rem; }
/* _content/PubInfo_BL/Components/Pages/SchoolCard.razor.rz.scp.css */
/* --------------------------------------------------------------------------
   One school card: this year's school on top, the proposed one beneath it.

   Flex column with the proposed block pushed to the bottom, so that in a
   three-up row the proposed sections line up across all three cards even when
   one school name wraps to two lines and the others do not.

   No programs disclosure here any more: it is one trigger below the whole grid
   now, in AreaPrograms.razor, precisely so that it costs these cards no height.
   -------------------------------------------------------------------------- */
.school-card[b-235zxiqoly] {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--pcs-surface);
    border: 1px solid var(--pcs-border);
    border-radius: var(--pcs-radius);
    box-shadow: var(--pcs-shadow);
    overflow: hidden;
}

/* A card whose level is moving gets a gold edge, matching the "Changing" flag
   in its header and the gold rail on the proposed block. Three signals, and the
   two that matter are words - see the header note. */
.school-card-changing[b-235zxiqoly] {
    border-color: var(--pcs-gold);
    box-shadow: var(--pcs-shadow-lift);
}

/* The level band. Navy gradient, so each card is anchored by the brand color
   and the three levels scan as one set. */
.school-card-head[b-235zxiqoly] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    background: linear-gradient(135deg, var(--pcs-navy-700) 0%, var(--pcs-navy-950) 100%);
    padding: 0.7rem 1.1rem;
}

.school-level[b-235zxiqoly] {
    margin: 0;
    font-family: var(--pcs-font-subhead);
    font-size: 0.9rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #fff;
}

/* "Changing", on the navy band. Gold on navy is 8.4:1 - it is a label being
   read, not a decoration. */
.change-flag[b-235zxiqoly] {
    flex: 0 0 auto;
    padding: 0.15rem 0.6rem;
    border: 1px solid var(--pcs-gold);
    border-radius: 999px;
    background: rgba(228, 177, 35, 0.16);
    color: var(--pcs-light-yellow);
    font-family: var(--pcs-font-subhead);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Section labels: "This year 2026-2027" / "Proposed 2027-2028".

   Rendered only while a proposal is open. With no proposal the card has one
   school in it and a label over it would be answering a question nobody asked.
   -------------------------------------------------------------------------- */
.block-label[b-235zxiqoly] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin: 1rem 1.1rem 0.15rem;
    font-family: var(--pcs-font-subhead);
    font-size: 0.76rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--pcs-ink-muted);
}

/* The year, set apart from the word so the eye can land on either. */
.block-label-year[b-235zxiqoly] {
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--pcs-page-bg-deep);
    color: var(--pcs-navy);
    letter-spacing: 0.05em;
}

.school-name[b-235zxiqoly] {
    font-family: var(--pcs-font-display);
    font-weight: 800;
    font-size: clamp(1.1rem, 1rem + 0.6vw, 1.3rem);
    line-height: 1.15;
    text-transform: uppercase;
    color: var(--pcs-navy);
    margin: 1.1rem 1.1rem 0.4rem;
    text-wrap: balance;
}

/* With a label above it the name needs no top margin of its own. */
.block-label + .school-name[b-235zxiqoly] {
    margin-top: 0.25rem;
}

.school-address[b-235zxiqoly] {
    /* Override the browser default italic - a postal address is easier to scan
       upright, and it is being read off a phone in a parking lot. */
    font-style: normal;
    font-size: 0.97rem;
    color: var(--pcs-ink-muted);
    line-height: 1.45;
    margin: 0 1.1rem 0.9rem;
}

.school-none[b-235zxiqoly] {
    margin: 1.1rem;
    font-size: 0.97rem;
    color: var(--pcs-ink);
}

/* --------------------------------------------------------------------------
   The proposed block.

   margin-top:auto pins it to the card bottom; see the note at the top. It is a
   sunken surface with a rail down its left edge, which is the same device the
   result header and the disclaimer use on the page around it - a card within a
   card would be one border too many at this size.
   -------------------------------------------------------------------------- */
.proposed[b-235zxiqoly] {
    margin-top: auto;
    border-top: 1px solid var(--pcs-border);
    border-left: 5px solid var(--pcs-border-strong);
    background: var(--pcs-surface-sunken);
    padding-bottom: 0.2rem;
}

/* Changing: gold rail and a warmer ground, so a family scanning three cards can
   find the one that moved without reading any of them. Never the only signal -
   the header says "Changing" and this block names a different school. */
.proposed-changing[b-235zxiqoly] {
    border-left-color: var(--pcs-gold);
    background: #FDF6E3;
}

/* Unchanged: green rail, and the block collapses to a single line. */
.proposed-unchanged[b-235zxiqoly] {
    border-left-color: var(--pcs-lime);
    background: var(--pcs-notice-bg);
}

/* Not listed in the proposal - neither reassuring nor alarming. */
.proposed-notlisted[b-235zxiqoly] {
    border-left-color: var(--pcs-border-strong);
}

.proposed .block-label[b-235zxiqoly] {
    margin-top: 0.8rem;
}

.proposed-name[b-235zxiqoly] {
    color: var(--pcs-navy);
}

/* The one-line outcomes: "No change proposed", "not covered". */
.proposed-note[b-235zxiqoly] {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.35rem 1.1rem 0.9rem;
    font-size: 0.95rem;
    line-height: 1.45;
    color: var(--pcs-ink);
}

.proposed-icon[b-235zxiqoly] {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    margin-top: 0.1rem;
    border-radius: 50%;
    background: var(--pcs-border-strong);
    color: #fff;
    font-family: var(--pcs-font-subhead);
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1;
}

.proposed-unchanged .proposed-icon[b-235zxiqoly] {
    background: var(--pcs-dark-green);
}

/* The links inside the proposed block belong to SchoolLinks, a separate
   component, so they are reached with ::deep. Slightly tighter than in the
   card body above - this block is a footnote to the answer, not the answer. */
.proposed[b-235zxiqoly]  .school-links {
    margin-bottom: 0.9rem;
}

.proposed[b-235zxiqoly]  .school-link {
    background: var(--pcs-surface);
}

/* _content/PubInfo_BL/Components/Pages/SchoolLinks.razor.rz.scp.css */
/* --------------------------------------------------------------------------
   Map and directions links.

   Real links with text labels. The legacy page used a 16px drive.gif with a
   tooltip - no accessible name, and a target far under the 24px minimum.

   These moved out of SchoolCard.razor.css with the markup: Blazor scopes a
   stylesheet to its own component, so the rules have to travel with the element
   they style.
   -------------------------------------------------------------------------- */
.school-links[b-2qkvqh3jky] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 1.1rem 1.1rem;
}

.school-link[b-2qkvqh3jky] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    padding: 0.5rem 0.85rem;
    font-family: var(--pcs-font-subhead);
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: none;
    color: var(--pcs-navy);
    background: var(--pcs-navy-050);
    border: 1px solid var(--pcs-border);
    border-radius: var(--pcs-radius-sm);
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.school-link:hover[b-2qkvqh3jky] {
    background: var(--pcs-surface-sunken);
    border-color: var(--pcs-navy-500);
    color: var(--pcs-navy);
}

.link-icon[b-2qkvqh3jky] {
    font-size: 1rem;
    line-height: 1;
    color: var(--pcs-navy-500);
}
/* _content/PubInfo_BL/Components/Pages/SchoolLocator.razor.rz.scp.css */
/* --------------------------------------------------------------------------
   Hero.

   Navy gradient, same family as the masthead but angled the other way so the
   two panels read as separate surfaces rather than one long block.
   -------------------------------------------------------------------------- */
.hero[b-np7a62grz8] {
    border-radius: var(--pcs-radius);
    overflow: hidden;
    box-shadow: var(--pcs-shadow);
    margin-bottom: clamp(1.25rem, 3vw, 1.75rem);
}

.hero-body[b-np7a62grz8] {
    background: linear-gradient(135deg, var(--pcs-navy-600) 0%, var(--pcs-navy-950) 85%);
    color: #fff;
    padding: clamp(1.4rem, 4.5vw, 2.5rem);
}

.hero-body[b-np7a62grz8]  h1 {
    color: #fff;
    margin-bottom: 0.6rem;
}

.hero-lede[b-np7a62grz8] {
    font-family: var(--pcs-font-body-light);
    font-size: clamp(1.02rem, 0.98rem + 0.4vw, 1.2rem);
    /* Not pure white - long prose at full white on navy shimmers. 12.4:1. */
    color: #E4E9F3;
    max-width: 56ch;
    margin: 0;
}

.hero-meta[b-np7a62grz8] { margin: 1.1rem 0 0; }

.hero-badge[b-np7a62grz8] {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    border: 1px solid rgba(228, 177, 35, 0.5);
    border-radius: 999px;
    background: rgba(228, 177, 35, 0.12);
    color: var(--pcs-light-yellow);
    font-family: var(--pcs-font-subhead);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* A second badge next to the school-year one, for the proposed year. Bordered
   in sky rather than gold so the two are told apart at a glance without either
   looking like a warning. */
.hero-badge-proposed[b-np7a62grz8] {
    margin-left: 0.4rem;
    border-color: rgba(50, 192, 230, 0.5);
    background: rgba(50, 192, 230, 0.12);
    color: #A9E6F6;
}

/* Closes the hero in brand color, mirroring the masthead stripe. */
.hero-stripe[b-np7a62grz8] {
    height: 6px;
    background: linear-gradient(
        to right,
        var(--pcs-gold) 0 33.34%,
        var(--pcs-sky) 33.34% 66.67%,
        var(--pcs-lime) 66.67% 100%
    );
}

/* --------------------------------------------------------------------------
   Step rail.

   Horizontal on a wide screen, and still horizontal on a phone - three short
   labels fit, and stacking them would push the form below the fold.
   -------------------------------------------------------------------------- */
.steps[b-np7a62grz8] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.4rem;
    list-style: none;
    margin: 0 0 1.25rem;
    padding: 0;
    counter-reset: none;
}

.step[b-np7a62grz8] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 0.7rem 0.4rem;
    border-radius: var(--pcs-radius-sm);
    background: var(--pcs-page-bg-deep);
    color: var(--pcs-ink-muted);
    text-align: center;
    /* The state is carried by the number badge, the label weight AND a top
       border - never by color alone. */
    border-top: 3px solid transparent;
}

.step-num[b-np7a62grz8] {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--pcs-border-strong);
    color: #fff;
    font-family: var(--pcs-font-subhead);
    font-size: 0.85rem;
    font-weight: 600;
}

.step-label[b-np7a62grz8] {
    font-family: var(--pcs-font-subhead);
    font-size: clamp(0.7rem, 2.2vw, 0.83rem);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.2;
}

.step-done[b-np7a62grz8] {
    background: var(--pcs-navy-050);
    color: var(--pcs-navy-600);
    border-top-color: var(--pcs-lime);
}

.step-done .step-num[b-np7a62grz8] {
    background: var(--pcs-lime);
}

.step-current[b-np7a62grz8] {
    background: var(--pcs-surface);
    color: var(--pcs-navy);
    border-top-color: var(--pcs-navy);
    box-shadow: var(--pcs-shadow);
}

.step-current .step-num[b-np7a62grz8] {
    background: linear-gradient(135deg, var(--pcs-navy-600), var(--pcs-navy-950));
}

.step-current .step-label[b-np7a62grz8] { font-weight: 600; }

/* --------------------------------------------------------------------------
   Search form.

   Two fields side by side on a wide screen; stacked on a phone, with the house
   number narrow because it holds at most six digits and a full-width box
   invites a full address.
   -------------------------------------------------------------------------- */
.search-form[b-np7a62grz8] {
    display: grid;
    gap: 1.1rem;
    margin-top: 1rem;
}

@media (min-width: 640px) {
    .search-form[b-np7a62grz8] {
        grid-template-columns: minmax(120px, 160px) 1fr;
        align-items: start;
        column-gap: 1.25rem;
    }

    .locator-actions[b-np7a62grz8] { grid-column: 1 / -1; }
}

.field[b-np7a62grz8] { display: flex; flex-direction: column; }

.field label[b-np7a62grz8] {
    font-family: var(--pcs-font-subhead);
    font-size: 0.95rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--pcs-navy);
    margin-bottom: 0.15rem;
}

.field-hint[b-np7a62grz8] {
    font-size: 0.92rem;
    color: var(--pcs-ink-muted);
    margin: 0 0 0.45rem;
    /* The hint sits ABOVE the input, not below it. A hint under the box is read
       after the field has already been filled in, which is too late. */
}

.text-input[b-np7a62grz8] {
    /* 1rem minimum. Anything smaller and iOS Safari zooms the viewport on
       focus, which on this form throws the layout sideways mid-entry. */
    font-family: var(--pcs-font-body);
    font-size: 1.05rem;
    min-height: 48px;
    padding: 0.6rem 0.75rem;
    color: var(--pcs-ink);
    background: var(--pcs-surface);
    border: 2px solid var(--pcs-border-strong);
    border-radius: var(--pcs-radius-sm);
    width: 100%;
}

.text-input:hover[b-np7a62grz8] { border-color: var(--pcs-navy-500); }

.text-input:focus-visible[b-np7a62grz8] {
    border-color: var(--pcs-navy);
    outline: 3px solid var(--pcs-focus);
    outline-offset: 1px;
}

/* Invalid state: thicker red border AND the message below AND aria-invalid.
   Three signals, only one of which is color. */
.text-input.has-error[b-np7a62grz8] {
    border-color: var(--pcs-error);
    background: var(--pcs-error-bg);
}

.field-error[b-np7a62grz8] {
    display: flex;
    align-items: flex-start;
    gap: 0.35rem;
    margin: 0.4rem 0 0;
    font-size: 0.93rem;
    font-weight: 600;
    color: var(--pcs-error);
}

.locator-actions[b-np7a62grz8] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.25rem;
}

/* --------------------------------------------------------------------------
   "About proposed zoned schools" - the note under the search button.

   Inside the form grid, so it has to span both columns on a wide screen or it
   would sit in the 160px house-number track. Sunken with a sky rail rather than
   an alert box: it is context for the button above it, not a warning, and this
   page already spends its alert styling on things that have gone wrong.
   -------------------------------------------------------------------------- */
.proposal-explainer[b-np7a62grz8] {
    grid-column: 1 / -1;
    margin-top: 0.25rem;
    padding: 0.9rem 1.1rem;
    border-radius: var(--pcs-radius-sm);
    border: 1px solid var(--pcs-border);
    border-left: 5px solid var(--pcs-sky);
    background: var(--pcs-surface-sunken);
}

.proposal-explainer[b-np7a62grz8]  h3 {
    margin: 0 0 0.35rem;
    font-size: 1rem;
}

.proposal-explainer p[b-np7a62grz8] {
    margin: 0 0 0.5rem;
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--pcs-ink);
    max-width: 68ch;
}

.proposal-explainer p:last-child[b-np7a62grz8] { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Alerts.
   -------------------------------------------------------------------------- */
.alert[b-np7a62grz8] {
    display: flex;
    gap: 0.75rem;
    padding: 0.9rem 1.1rem;
    border-radius: var(--pcs-radius-sm);
    border: 1px solid;
    margin: 1rem 0;
}

.alert-error[b-np7a62grz8] {
    background: var(--pcs-error-bg);
    border-color: var(--pcs-error-border);
    color: var(--pcs-ink);
}

.alert-notice[b-np7a62grz8] {
    background: var(--pcs-notice-bg);
    border-color: var(--pcs-notice-border);
}

/* The rezoning-proposal summary when something would actually change. Gold
   rather than red: a proposal is news, not a fault, and this page must not
   read as though the family has done something wrong. The heading states the
   count in words, so the colour is never carrying the message. */
.alert-change[b-np7a62grz8] {
    background: #FDF6E3;
    border-color: rgba(228, 177, 35, 0.55);
    color: var(--pcs-ink);
}

.alert-icon[b-np7a62grz8] {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    font-family: var(--pcs-font-subhead);
    font-weight: 600;
    font-size: 0.95rem;
    color: #fff;
    background: var(--pcs-navy-600);
}

.alert-error .alert-icon[b-np7a62grz8] { background: var(--pcs-error); }
.alert-notice .alert-icon[b-np7a62grz8] { background: var(--pcs-dark-green); }
.alert-change .alert-icon[b-np7a62grz8] { background: var(--pcs-dark-orange); }

.alert-title[b-np7a62grz8] {
    font-family: var(--pcs-font-subhead);
    font-size: 1.02rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--pcs-navy);
    margin: 0 0 0.35rem;
}

.alert-error .alert-title[b-np7a62grz8] { color: var(--pcs-error); }
.alert-change .alert-title[b-np7a62grz8] { color: var(--pcs-navy); }

.alert-list[b-np7a62grz8] {
    margin: 0;
    padding-left: 1.15rem;
}

.alert-list li + li[b-np7a62grz8] { margin-top: 0.3rem; }

/* --------------------------------------------------------------------------
   Address matches.

   A list of full-width tap targets, replacing a fixed-width GridView with a
   "Select" command column. On a 375px phone the legacy table was 776px wide and
   scrolled horizontally; the Select link was the leftmost of five columns.
   -------------------------------------------------------------------------- */
.match-list[b-np7a62grz8] {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.6rem;
}

.match-item[b-np7a62grz8] {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
        "address chevron"
        "locality chevron";
    align-items: center;
    column-gap: 0.75rem;
    /* Whole row is the target, comfortably over 48px tall. */
    min-height: 56px;
    padding: 0.75rem 1rem;
    background: var(--pcs-surface);
    border: 2px solid var(--pcs-border);
    border-left: 5px solid var(--pcs-navy-500);
    border-radius: var(--pcs-radius-sm);
    text-decoration: none;
    color: var(--pcs-ink);
    transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}

.match-item:hover[b-np7a62grz8] {
    background: var(--pcs-navy-050);
    border-color: var(--pcs-navy-500);
    border-left-color: var(--pcs-gold);
    color: var(--pcs-ink);
    transform: translateX(2px);
}

.match-address[b-np7a62grz8] {
    grid-area: address;
    font-family: var(--pcs-font-subhead);
    font-size: 1.05rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    color: var(--pcs-navy);
    /* Long addresses wrap rather than overflow. */
    overflow-wrap: anywhere;
}

.match-locality[b-np7a62grz8] {
    grid-area: locality;
    font-size: 0.93rem;
    color: var(--pcs-ink-muted);
}

.match-chevron[b-np7a62grz8] {
    grid-area: chevron;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--pcs-navy-500);
}

/* --------------------------------------------------------------------------
   Results.
   -------------------------------------------------------------------------- */
.result-header[b-np7a62grz8] {
    border-left: 6px solid var(--pcs-lime);
}

.result-address[b-np7a62grz8] {
    font-family: var(--pcs-font-subhead);
    font-size: clamp(1.05rem, 1rem + 0.5vw, 1.3rem);
    font-weight: 600;
    text-transform: uppercase;
    color: var(--pcs-navy);
    margin: 0.35rem 0 0.2rem;
    overflow-wrap: anywhere;
}

/* Three cards. Single column up to 720px, then side by side.
   auto-fit with a 260px floor means two-up on a tablet in portrait and
   three-up on a laptop, without a media query per breakpoint. */
.school-grid[b-np7a62grz8] {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    margin-top: 1.25rem;
}

@media (min-width: 720px) {
    .school-grid[b-np7a62grz8] {
        grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
        align-items: start;
    }
}

.disclaimer[b-np7a62grz8] {
    margin-top: 1.25rem;
    background: var(--pcs-surface-sunken);
    border-left: 6px solid var(--pcs-gold);
}

.disclaimer[b-np7a62grz8]  h3 { margin-bottom: 0.4rem; }

/* --------------------------------------------------------------------------
   The proposal summary, inside the result header.

   Last thing in that panel, so the reading order is: heading, address, current
   school year, then what the proposal does. A family who only wants this year's
   answer has it before this box starts.
   -------------------------------------------------------------------------- */
.proposal-summary[b-np7a62grz8] {
    margin-bottom: 0;
}

.proposal-summary p[b-np7a62grz8] {
    margin: 0 0 0.45rem;
    line-height: 1.5;
}

.proposal-summary p:last-child[b-np7a62grz8] { margin-bottom: 0; }
