/* ---------------------------------------------------------------------------
   PubInfo_BL - School Zone Locator
   Pinellas County Schools brand tokens.

   Source: PCS Branding & Style Guide, updated September 2025 (pages 8-9).
   The token block is deliberately the same one ESS_BL carries, so a brand
   retune lands in both apps the same way.

   WHAT DIFFERS FROM ESS_BL, and why:

   1. Page background. ESS uses --pcs-page-bg #F2F4F8, a cool grey-blue that sits
      quietly behind dense payroll tables. This app is public and it is the first
      thing a prospective family sees of the district, so the ground is a warm
      ivory instead. It also does the practical job of making the two apps
      instantly distinguishable when both are open in a browser - staff run them
      side by side.

   2. Navy and the navy gradient are unchanged. They carry the brand here exactly
      as they do in ESS: the masthead, the hero panel, the primary button.

   3. No Bootstrap. Everything below is the whole stylesheet.

   Retune here - nothing downstream hard-codes a brand color or font family.
   --------------------------------------------------------------------------- */

/* Self-hosted rather than pulled from Google Fonts: this page is served to the
   public internet and should make no third-party requests on a family's behalf.
   Latin subset only. */
@font-face {
    font-family: 'PCS Prompt';
    src: url('fonts/prompt-extrabold-latin.woff2') format('woff2');
    font-weight: 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'PCS Oswald';
    src: url('fonts/oswald-semibold-latin.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

:root {
    /* --- Primary palette (official, guide p.9) ------------------------- */
    --pcs-navy: #0C173C;  /* Pantone 281C / 655U */
    --pcs-gold: #E4B123;  /* Pantone 110C / 7405U */
    --pcs-sky: #32C0E6;   /* Pantone 298C / 2985U */
    --pcs-lime: #8AB840;  /* Pantone 368C / 2299U */

    /* --- Secondary palette (official, guide p.9) ----------------------- */
    --pcs-dark-green: #008037;
    --pcs-orange: #F58220;
    --pcs-dark-orange: #E15100;
    --pcs-light-yellow: #FFD145;

    /* --- Navy ramp (derived from the brand navy hue, ~222deg) ---------- */
    --pcs-navy-950: #070E24;
    --pcs-navy-900: #0C173C; /* the brand navy itself */
    --pcs-navy-700: #17264F;
    --pcs-navy-600: #22376B;
    --pcs-navy-500: #2E4A8E;
    --pcs-navy-050: #EDF0F6;

    /* --- Neutrals ------------------------------------------------------
       Ink is the near-black the brand guide sets its own body copy in. The
       warm greys below are biased toward the ivory ground rather than toward
       navy (which is what ESS does) so borders read as chosen, not muddy. */
    --pcs-ink: #231F20;
    --pcs-ink-muted: #5B5449;

    /* THE CHANGE: warm ivory ground instead of ESS cool grey-blue. */
    --pcs-page-bg: #FBF7EF;
    --pcs-page-bg-deep: #F3EDDF; /* alternating bands, e.g. the step rail */

    --pcs-surface: #FFFFFF;
    --pcs-surface-sunken: #F7F2E7;
    --pcs-border: #E2DACA;
    --pcs-border-strong: #CFC4AD;

    /* --- Link + focus --------------------------------------------------
       The guide specifies no link color. This is a navy-hue step lightened
       until it reads as clickable next to body ink: 10.6:1 on white.
       Sky blue is NOT used for text - 2.1:1 on white, decorative only. */
    --pcs-link: #1D3A80;
    --pcs-link-hover: #0C173C;
    --pcs-focus: #2E4A8E;
    --pcs-focus-on-navy: #32C0E6;

    /* --- Status ---------------------------------------------------------
       Both are paired with an icon and a text label everywhere they appear;
       nothing in this app is signalled by color alone. */
    --pcs-error: #A3231B;
    --pcs-error-bg: #FCF0EE;
    --pcs-error-border: #E9C4C0;
    --pcs-notice-bg: #F1F7E8;
    --pcs-notice-border: #CFE0B4;

    --pcs-radius: 12px;
    --pcs-radius-sm: 8px;
    --pcs-shadow: 0 1px 2px rgba(35, 31, 32, 0.05), 0 6px 18px rgba(35, 31, 32, 0.07);
    --pcs-shadow-lift: 0 2px 4px rgba(35, 31, 32, 0.08), 0 14px 30px rgba(35, 31, 32, 0.14);

    /* Narrower than the ESS shell (1288px). This app is a single form and three
       result cards - a wider column would just stretch the measure of running
       prose past comfortable reading length. */
    --pcs-shell-max: 960px;

    /* --- Type roles (guide p.8) ---------------------------------------- */
    --pcs-font-display: 'PCS Prompt', 'Segoe UI', Tahoma, sans-serif;
    --pcs-font-subhead: 'PCS Oswald', 'Segoe UI', Tahoma, sans-serif;
    --pcs-font-body: Calibri, Carlito, 'Segoe UI', system-ui, sans-serif;
    --pcs-font-body-light: 'Calibri Light', Calibri, Carlito, 'Segoe UI', system-ui, sans-serif;
}

*, *::before, *::after {
    box-sizing: border-box;
}

html {
    /* The whole app is one page of GET navigations; smooth scroll makes the
         in-page jumps (skip link, results anchor) legible rather than jarring. */
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

body {
    margin: 0;
    font-family: var(--pcs-font-body);
    /* 17px base. Larger than the ESS default on purpose: this page is read by
       parents and grandparents on phones, not by staff at a desk all day. The
       legacy page set 12px. */
    font-size: 1.0625rem;
    line-height: 1.55;
    color: var(--pcs-ink);
    background-color: var(--pcs-page-bg);
    -webkit-text-size-adjust: 100%;
}

/* Guide p.8: both display faces are used in all caps, never mixed case. */
h1, h2, h3 {
    font-family: var(--pcs-font-subhead);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    color: var(--pcs-navy);
    margin: 0 0 0.5rem;
    text-wrap: balance;
}

h1 { font-size: clamp(1.5rem, 1.2rem + 1.6vw, 2.1rem); line-height: 1.15; }
h2 { font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem); }
h3 { font-size: 1.05rem; }

p { margin: 0 0 0.85rem; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--pcs-link);
    text-underline-offset: 0.15em;
}

a:hover { color: var(--pcs-link-hover); }

/* Keyboard focus is brand navy and always visible. Never removed anywhere in
   this stylesheet - on a form that some families will fill in entirely from the
   keyboard, the ring is the only thing telling them where they are. */
:focus-visible {
    outline: 3px solid var(--pcs-focus);
    outline-offset: 2px;
    border-radius: 2px;
}

/* --------------------------------------------------------------------------
   Skip link - visually hidden until focused.
   -------------------------------------------------------------------------- */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 0.75rem 1.25rem;
    background: var(--pcs-navy);
    color: #fff;
    font-family: var(--pcs-font-subhead);
    text-transform: uppercase;
    text-decoration: none;
    border-bottom-right-radius: var(--pcs-radius-sm);
}

.skip-link:focus {
    left: 0;
    color: #fff;
    outline: 3px solid var(--pcs-focus-on-navy);
    outline-offset: -3px;
}

/* --------------------------------------------------------------------------
   Shared content column. Header, hero and every panel measure from this, so
   their left edges line up at all widths.
   -------------------------------------------------------------------------- */
.pcs-shell {
    width: 100%;
    max-width: var(--pcs-shell-max);
    margin-inline: auto;
    padding-inline: clamp(1rem, 4vw, 1.5rem);
}

/* --------------------------------------------------------------------------
   Buttons.
   Minimum 44px tall everywhere: the WCAG 2.5.5 target size, and the difference
   between a usable and an infuriating form on a phone. The legacy buttons were
   70x35 CSS pixels.
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* justify-content centers the label as a block; this centers the LINES
       within it once a long label wraps. Without it a wrapped <a class="btn">
       reads left-aligned while a <button class="btn"> beside it looks centred,
       because the two elements disagree on the inherited default. */
    text-align: center;
    gap: 0.5rem;
    min-height: 48px;
    padding: 0.7rem 1.5rem;
    font-family: var(--pcs-font-subhead);
    font-size: 1rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-decoration: none;
    border: 2px solid transparent;
    border-radius: var(--pcs-radius-sm);
    cursor: pointer;
    transition: background-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.btn-primary {
    /* The brand navy gradient, kept from the district look. */
    background: linear-gradient(135deg, var(--pcs-navy-700) 0%, var(--pcs-navy-950) 100%);
    color: #fff;
    box-shadow: var(--pcs-shadow);
}

.btn-primary:hover {
    background: linear-gradient(135deg, var(--pcs-navy-600) 0%, var(--pcs-navy-900) 100%);
    box-shadow: var(--pcs-shadow-lift);
    color: #fff;
}

.btn-primary:active { transform: translateY(1px); }

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

.btn-secondary:hover {
    background: var(--pcs-surface-sunken);
    border-color: var(--pcs-navy-500);
    color: var(--pcs-navy);
}

/* --------------------------------------------------------------------------
   Action rows.

   ALL GLOBAL, not scoped to SchoolLocator. A .locator-actions row is filled
   from two components - the page itself and SupportActions - and Blazor
   rewrites a scoped `.locator-actions .btn` to
   `.locator-actions .btn[b-<page>]`, an attribute the buttons coming from the
   other component do not carry. Every rule below that reaches a .btn child
   would therefore silently skip exactly the buttons it exists for. Keep them
   here.
   -------------------------------------------------------------------------- */

/* Long labels - "I am having trouble finding my address" is the longest string
   on the page - wrap to two lines inside a narrow button. Balanced, so the
   lines come out a similar length instead of one word dangling under the
   other three. */
.locator-actions .btn { text-wrap: balance; }

.result-actions { margin-top: 1.25rem; }

/* Below the one-line breakpoint the row stacks, and each button takes the full
   width of the column so that a long label wraps INSIDE it.

   The basis is what matters: left to size themselves, "I am having trouble
   finding my address" (38 characters) and "To learn more about Planning for
   Progress" (41) lay out as a single uppercase line about 400px wide, which is
   wider than the content column on any phone - so the buttons stopped wrapping
   and started overflowing the page instead. min-width: 0 is needed with it,
   because a flex item refuses to shrink below its content width by default. */
.result-actions > * {
    flex: 1 1 100%;
    min-width: 0;
}

/* One row of equal-width buttons on the address-list and results screens, at
   the district's request.

   flex: 1 1 0 rather than a 4-column grid because the same row carries two
   buttons on step 2 and four on step 3, and a fixed column count would leave
   step 2 with two quarter-width buttons and a gap. Basis 0 (not auto) is what
   makes them EVEN: it ignores the label lengths, which differ by a factor of
   two here, and splits the row equally. min-width: 0 stops the longest label
   from pushing its own button wider than its share, which is flexbox's
   default. align-items: stretch gives them one common height, set by whichever
   label wraps to the most lines.

   NOT APPLIED ON A PHONE. Below this breakpoint the row keeps the wrapping
   layout from .locator-actions: four even buttons across a 360px screen is
   ~80px each, which neither fits a 38-character label nor clears the 44px
   WCAG 2.5.5 target these buttons are sized for everywhere else. The step-1
   form row is untouched at every width - its submit button carries the
   longest label on the page and must not be squeezed to half a row. */
@media (min-width: 720px) {
    .result-actions {
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 0.5rem;
    }

    /* Direct children, not .btn: the third button is a <details> wrapping
       its <summary>, so the flex item is the <details>. */
    .result-actions > * {
        flex: 1 1 0;
        min-width: 0;
    }

    .result-actions .btn {
        /* The 960px shell leaves about 220px per button once the gaps are
           taken out. At the 1rem default the longest two labels need three
           lines at that width; this fits them in two. */
        font-size: 0.8rem;
        letter-spacing: 0.02em;
        padding-inline: 0.75rem;
    }
}

/* --------------------------------------------------------------------------
   "I am having trouble finding my address" - a <details> disclosure holding
   the Student Assignment office's email and phone.

   <details> and not script because the app is static SSR and works with
   JavaScript blocked; see Program.cs and Components/SupportActions.razor.
   -------------------------------------------------------------------------- */
.address-help {
    position: relative;
    /* So the <summary> fills the height the stretched row hands the <details>,
       and the button reads as exactly the same object as its three siblings. */
    display: flex;
    flex-direction: column;
}

.address-help > summary {
    flex: 1 1 auto;
    /* Drop the disclosure triangle: this has to look like a button, not like a
       collapsed section. Both are needed - ::marker is the standard, and the
       -webkit- pseudo-element is what Blink and WebKit still use. */
    list-style: none;
}

.address-help > summary::-webkit-details-marker { display: none; }
.address-help > summary::marker { content: ""; }

/* The open state deserves to look pressed rather than identical to the closed
   one, and there is no :active to lean on once it is latched open. */
.address-help[open] > summary { box-shadow: var(--pcs-shadow-lift); }

.address-help-panel {
    margin-top: 0.5rem;
    padding: 0.85rem 1rem;
    border-radius: var(--pcs-radius-sm);
    border: 1px solid var(--pcs-border-strong);
    border-left: 5px solid var(--pcs-sky);
    background: var(--pcs-surface);
    box-shadow: var(--pcs-shadow);
    text-align: left;
}

.address-help-lede {
    margin: 0 0 0.5rem;
    font-family: var(--pcs-font-subhead);
    font-weight: 600;
    color: var(--pcs-navy);
}

.address-help-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.4rem;
}

/* A fixed column for the labels so the address and the number line up under
   each other instead of starting at two different x positions. */
.address-help-list li {
    display: grid;
    grid-template-columns: 3.4rem 1fr;
    gap: 0.5rem;
    align-items: baseline;
}

.address-help-label {
    font-family: var(--pcs-font-subhead);
    font-weight: 600;
    color: var(--pcs-ink-muted);
}

/* Open as a popover, but only where the row is a single line.

   In flow, the panel would grow the <details>, and align-items: stretch would
   pass that height on to all four buttons - opening it would double the height
   of the whole row. Absolute takes it out of flow, so the row never moves.

   Below the breakpoint the row is already stacked one button per line, where an
   in-flow panel simply pushes the next button down and needs none of this. */
@media (min-width: 720px) {
    .address-help-panel {
        position: absolute;
        z-index: 30;
        top: calc(100% + 0.4rem);
        left: 0;
        margin-top: 0;
        /* At least as wide as the button, and as much wider as the email
           address needs - it does not fit in 220px and must not be broken
           across lines. */
        min-width: 100%;
        width: max-content;
        max-width: min(24rem, calc(100vw - 2rem));
    }
}

/* --------------------------------------------------------------------------
   Panels - the one surface primitive the whole app is built from.
   -------------------------------------------------------------------------- */
.panel {
    background: var(--pcs-surface);
    border: 1px solid var(--pcs-border);
    border-radius: var(--pcs-radius);
    box-shadow: var(--pcs-shadow);
    padding: clamp(1.1rem, 3vw, 1.75rem);
}

.panel + .panel { margin-top: 1.25rem; }

.panel-heading {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin-bottom: 0.25rem;
}

.lede {
    font-family: var(--pcs-font-body-light);
    font-size: 1.09rem;
    color: var(--pcs-ink);
    max-width: 62ch;
}

.muted {
    color: var(--pcs-ink-muted);
    font-size: 0.95rem;
}

/* --------------------------------------------------------------------------
   Visually hidden, but present for assistive technology.
   -------------------------------------------------------------------------- */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   Print. Families print or PDF this page to take to a school office, so the
   result is laid out for paper rather than left to chance.
   -------------------------------------------------------------------------- */
@media print {
    body { background: #fff; font-size: 11pt; }

    .skip-link,
    .pcs-topbar .brand-link,
    .locator-actions,
    .site-footer nav,
    .btn { display: none !important; }

    .panel {
        box-shadow: none;
        border: 1px solid #999;
        break-inside: avoid;
    }

    /* A printed page cannot be clicked, so show where the links went. */
    a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 8pt;
        word-break: break-all;
    }

    /* Programs are collapsed on screen; on paper, print them all. */
    details { display: block; }
    details > summary { list-style: none; font-weight: bold; }
    details:not([open]) > *:not(summary) { display: revert !important; }
}

/* --------------------------------------------------------------------------
   Set by programs-modal.js while a programs panel is open, so the page behind
   the scrim does not scroll. Deliberately not a CSS-only rule: with scripts
   blocked the panel is still usable, and locking scroll is the one part of the
   modal behaviour that would be actively harmful to leave stuck on.
   -------------------------------------------------------------------------- */
html.programs-modal-open {
    overflow: hidden;
}
