/*
 * schoolcompare — "Find the right school. For their future."
 *
 * Implements the schoolcompare brand guideline. Colour has four jobs and they
 * never borrow each other's hues:
 *   brand   (deep teal)  identity, navigation, headings, links, primary buttons
 *   action  (coral)      the one decisive action on a page — search, submit
 *   status  (green /     valence against the England average. Never a CTA.
 *            terracotta)
 *   phase   (desaturated) category chips, deliberately subordinate.
 *
 * Two deviations from the supplied swatches, both forced by contrast, both
 * confined to text and fills. Coral #F97360 carrying a white label measures
 * 2.75:1 where 4.5 is the floor, so --action is a darkened #BE3C27; the
 * original coral survives as --coral for tints, borders and illustration.
 * Mustard #F2C94C is 1.5:1 as text, so --mustard-ink carries any label while
 * --mustard stays exact for fills, rings and badges.
 *
 * Every value below clears WCAG AA on all three light grounds — Warm White,
 * white cards and Sand. Sand is the binding one; several values are a step
 * darker than they would need to be on white alone.
 */

:root {
    color-scheme: light;

    /* ── Ground ─────────────────────────────────────────────────────── */
    --bg-primary: #FAFAF8;      /* Warm White */
    --bg-secondary: #F5EFE6;    /* Sand — hero panels, sunken rows */
    --bg-card: #FFFFFF;
    --surface-inverse: #0F766E;

    /* ── Ink ────────────────────────────────────────────────────────── */
    --text-primary: #1C2731;    /* Ink */
    --text-secondary: #4A5560;
    --text-muted: #5F6A75;      /* 4.8:1 on Sand, the worst ground */
    --text-inverse: #FFFFFF;

    /* ── Line ───────────────────────────────────────────────────────── */
    --border: #E5E7EB;          /* Light Grey */
    --border-strong: #D3D7DD;

    /* ── Brand: deep teal ───────────────────────────────────────────── */
    --brand: #0F766E;           /* exact brand value; 4.8:1 on Sand */
    --brand-strong: #0C5F58;
    --brand-stronger: #0A4D47;
    --brand-bg: rgba(15, 118, 110, 0.10);
    --brand-on: #FFFFFF;

    /* ── Action: coral. One per screen, and only for the decisive one. ── */
    --action: #BE3C27;          /* darkened coral — 5.4:1 under a white label */
    --action-strong: #A33320;
    --action-stronger: #8C2B1B;
    /* Tint of --action, not of --coral, so a coral ghost button's label and
       ground share a hue. Unused today; the dark value was already correct. */
    --action-bg: rgba(190, 60, 39, 0.14);
    --action-on: #FFFFFF;

    /* ── Palette accents: exact brand values, for fills and tints only ── */
    --coral: #F97360;
    --mustard: #F2C94C;
    --mustard-ink: #806200;     /* any label that has to sit on or beside mustard */
    --sage: #A7D7C5;
    --sky: #C7EBF5;
    --lavender: #DDD8F5;
    --sand: #F5EFE6;

    /* ── Status: above / at / below the England average ─────────────── */
    --status-above: #36743F;
    --status-above-bg: rgba(54, 116, 63, 0.12);
    --status-below: #A9481F;
    /* The tint is the solid hue at low alpha, exactly as every other pair in
       this file is. It briefly carried the raw --coral tuple instead, which
       put a coral-pink wash behind terracotta text — the one mismatched pair
       in the palette. Alpha matches --status-above-bg so the two chips read
       as equal weight; at 0.15 the darker terracotta tint drops the label to
       4.45:1 on Warm White. */
    --status-below-bg: rgba(169, 72, 31, 0.12);
    --status-at: #5F6A75;
    --status-at-bg: rgba(95, 106, 117, 0.10);

    /* ── Charts ─────────────────────────────────────────────────────── */
    --chart-1: #0F766E;
    --chart-2: #36743F;
    --chart-3: #806200;
    --chart-4: #A9481F;
    --chart-5: #2F6F8F;
    --chart-6: #5F4FA8;
    --chart-grid: #E5E7EB;
    --chart-reference: #5F6A75;

    /* ── Series: up to 8 schools compared at once ───────────────────────
       Categorical, so wider than the four-hue rule — but every step is held
       to the same mid-dark tone and clears AA on the card, so they read as
       one family and work as legend text as well as chart lines. */
    --series-1: #0F766E;
    --series-2: #36743F;
    --series-3: #806200;
    --series-4: #A9481F;
    --series-5: #2F6F8F;
    --series-6: #5F4FA8;
    --series-7: #0E7A86;
    --series-8: #8A4A6B;

    /* ── Phase: category, desaturated so it stays under the status hues ── */
    --phase-primary: #0F766E;
    --phase-primary-bg: rgba(167, 215, 197, 0.40);
    --phase-primary-text: #0C5F58;
    --phase-secondary: #2F6F8F;
    --phase-secondary-bg: rgba(199, 235, 245, 0.55);
    --phase-secondary-text: #2A6180;
    --phase-all-through: #36743F;
    --phase-all-through-bg: rgba(54, 116, 63, 0.12);
    --phase-all-through-text: #2F6738;
    --phase-post16: #806200;
    --phase-post16-bg: rgba(242, 201, 76, 0.26);
    --phase-post16-text: #6E5500;
    --phase-nursery: #5F4FA8;
    --phase-nursery-bg: rgba(221, 216, 245, 0.55);
    --phase-nursery-text: #544396;

    /* ── Sunken surface: the footer, and anything meant to read as a deep
          teal anchor band. Stays teal in both themes on purpose — it is the
          "brand in action" card from the guideline. ─────────────────── */
    --surface-sunken: #0C5F58;
    --on-sunken: #FFFFFF;
    --on-sunken-muted: #C9E4DB;
    --on-sunken-faint: #A9D6CA;
    --on-sunken-link: #C7EBF5;

    /* ── Medals: rankings podium ────────────────────────────────────── */
    --medal-gold: #806200;
    --medal-silver: #6B7580;
    --medal-bronze: #8A5A2B;

    /* ── Channels ───────────────────────────────────────────────────────
       CSS can't interpolate a hex token into rgba(), so any tint that needs
       an arbitrary alpha reads the raw channels from here. Keep these in
       sync with the hex tokens above — they are the same colours. */
    --brand-rgb: 15, 118, 110;
    --action-rgb: 190, 60, 39;
    --coral-rgb: 249, 115, 96;
    --sage-rgb: 167, 215, 197;
    --status-above-rgb: 54, 116, 63;
    --status-below-rgb: 169, 72, 31;
    --ink-rgb: 28, 39, 49;
    --text-inverse-rgb: 255, 255, 255;
    --shadow-rgb: 28, 39, 49;
    --muted-rgb: 95, 106, 117;
    --phase-secondary-rgb: 47, 111, 143;
    --medal-silver-rgb: 107, 117, 128;
    --medal-bronze-rgb: 138, 90, 43;

    /* ── Elevation ──────────────────────────────────────────────────── */
    --shadow-soft: 0 1px 2px rgba(28, 39, 49, 0.04), 0 2px 8px rgba(28, 39, 49, 0.05);
    --shadow-medium: 0 4px 18px rgba(28, 39, 49, 0.09);
    --shadow-strong: 0 10px 34px rgba(28, 39, 49, 0.13);
    --scrim: rgba(28, 39, 49, 0.5);

    /* ── Type ───────────────────────────────────────────────────────────
       Manrope for headings and key messaging; Inter for body copy, every
       control and every figure. next/font expands each variable to the
       family plus its metric-matched fallback, and the classes sit on
       <html> so :root can see them — see app/layout.tsx. */
    --font-display: var(--font-manrope), -apple-system, BlinkMacSystemFont, sans-serif;
    --font-ui: var(--font-inter), -apple-system, BlinkMacSystemFont, sans-serif;
    --font-data: var(--font-inter), -apple-system, BlinkMacSystemFont, sans-serif;
    --font-prose: var(--font-inter), -apple-system, BlinkMacSystemFont, sans-serif;

    /* Type scale, straight from the guideline: H1 40/48, H2 32/40, H3 24/32,
       body large 16/24, body 14/20, small 12/16. */
    --step--2: 0.75rem;
    --step--1: 0.875rem;
    --step-0: 1rem;
    --step-1: 1.125rem;
    --step-2: 1.5rem;
    --step-3: 2rem;
    --step-4: 2.5rem;
    --step-5: 3rem;

    /* ── Geometry & motion ──────────────────────────────────────────────
       "Soft shapes, rounded corners" — the guideline's geometry is markedly
       rounder than the old system's 3/6/10/16. */
    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
    --radius-xl: 22px;

    --transition: 0.2s ease;
    --transition-slow: 0.4s ease;
}

/*
 * Dark theme. Not in the guideline, which is light-only — but the site already
 * ships one, so removing it would be a visible regression. Built from the same
 * tokens: teal and coral are lifted independently so each still clears AA on
 * the dark ground, and the ground itself keeps the Ink hue rather than going
 * to black.
 *
 * Tokens only. Never style a component from inside this block, or the two
 * themes drift apart the first time someone edits one of them.
 */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;

        --bg-primary: #111A20;
        --bg-secondary: #16222A;
        --bg-card: #18242C;
        --surface-inverse: #E9EEF0;

        --text-primary: #E9EEF0;
        --text-secondary: #B4C2C7;
        --text-muted: #8B9AA1;      /* 5.5:1 on the card */
        --text-inverse: #111A20;

        --border: #26343D;
        --border-strong: #35454F;

        --brand: #5FC7BB;
        --brand-strong: #7BD6CC;
        --brand-stronger: #9BE3DB;
        --brand-bg: rgba(95, 199, 187, 0.14);
        --brand-on: #0A1418;

        --action: #F08A72;
        --action-strong: #F5A492;
        --action-stronger: #F8BFB1;
        --action-bg: rgba(240, 138, 114, 0.16);
        --action-on: #241009;

        --coral: #F08A72;
        --mustard: #F2C94C;
        --mustard-ink: #EFC658;
        --sage: #8FCBB7;
        --sky: #9CD4E6;
        --lavender: #C2BBEA;
        --sand: #1B2730;

        --status-above: #7FCB8A;
        --status-above-bg: rgba(127, 203, 138, 0.14);
        --status-below: #EFA184;
        --status-below-bg: rgba(239, 161, 132, 0.14);
        --status-at: #8B9AA1;
        --status-at-bg: rgba(139, 154, 161, 0.14);

        --chart-1: #5FC7BB;
        --chart-2: #7FCB8A;
        --chart-3: #EFC658;
        --chart-4: #EFA184;
        --chart-5: #8FB4D9;
        --chart-6: #B6A9DD;
        --chart-grid: #26343D;
        --chart-reference: #8B9AA1;

        --series-1: #5FC7BB;
        --series-2: #7FCB8A;
        --series-3: #EFC658;
        --series-4: #EFA184;
        --series-5: #8FB4D9;
        --series-6: #B6A9DD;
        --series-7: #6FD0DC;
        --series-8: #D99BB8;

        --phase-primary: #5FC7BB;
        --phase-primary-bg: rgba(95, 199, 187, 0.16);
        --phase-primary-text: #8ADACF;
        --phase-secondary: #8FB4D9;
        --phase-secondary-bg: rgba(143, 180, 217, 0.16);
        --phase-secondary-text: #AAC8E4;
        --phase-all-through: #7FCB8A;
        --phase-all-through-bg: rgba(127, 203, 138, 0.16);
        --phase-all-through-text: #9AD8A3;
        --phase-post16: #EFC658;
        --phase-post16-bg: rgba(242, 201, 76, 0.16);
        --phase-post16-text: #F2D179;
        --phase-nursery: #B6A9DD;
        --phase-nursery-bg: rgba(182, 169, 221, 0.16);
        --phase-nursery-text: #C8BEE6;

        --surface-sunken: #0C5F58;
        --on-sunken: #FFFFFF;
        --on-sunken-muted: #C9E4DB;
        --on-sunken-faint: #A9D6CA;
        --on-sunken-link: #C7EBF5;

        --medal-gold: #EFC658;
        --medal-silver: #A9B6BC;
        --medal-bronze: #C99070;

        --brand-rgb: 95, 199, 187;
        --action-rgb: 240, 138, 114;
        --coral-rgb: 240, 138, 114;
        --sage-rgb: 143, 203, 183;
        --status-above-rgb: 127, 203, 138;
        --status-below-rgb: 239, 161, 132;
        --ink-rgb: 233, 238, 240;
        --text-inverse-rgb: 17, 26, 32;
        --shadow-rgb: 0, 0, 0;
        --muted-rgb: 139, 154, 161;
        --phase-secondary-rgb: 143, 180, 217;
        --medal-silver-rgb: 169, 182, 188;
        --medal-bronze-rgb: 201, 144, 112;

        --shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(0, 0, 0, 0.3);
        --shadow-medium: 0 4px 18px rgba(0, 0, 0, 0.45);
        --shadow-strong: 0 10px 34px rgba(0, 0, 0, 0.55);
        --scrim: rgba(4, 8, 10, 0.65);
    }
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-ui);
    background: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.6;
    /* dvh (dynamic viewport) accounts for iOS Safari's collapsing toolbar;
       fall back to vh on older engines that don't recognise dvh. */
    min-height: 100vh;
    min-height: 100dvh;
    /* Suppress the iOS Safari grey tap flash — explicit :active states
       below carry the press feedback instead. */
    -webkit-tap-highlight-color: transparent;
}

/* Form controls don't inherit font or colour from their parent — the UA
   supplies its own. Without this they render in the system font at pure
   black, which is nearly invisible against --text-primary in light mode and
   completely invisible on the dark ground. */
input,
select,
textarea,
button {
    font-family: inherit;
    color: inherit;
}

/* Every digit that could line up in a column does. This is a data product;
   proportional numerals in a results table read as amateur. */
/* The interface is mostly figures, so tabular is the default here rather
   than something each component has to remember. Running prose opts back out
   below — proportional figures read better in a sentence. */
.main,
table,
[data-numeric] {
    font-variant-numeric: tabular-nums;
}

/* Prose gets the serif; the interface never does. */
.prose {
    font-family: var(--font-prose);
    font-variant-numeric: normal;
    font-size: var(--step-0);
    line-height: 1.65;
}

/* Provide a baseline press feedback for the most common interactive
   elements — replaces the suppressed default tap highlight. Buttons and
   .btn-* classes carry their own :active states already; this handles
   plain anchors used as inline links and bare button elements. */
@media (hover: none) and (pointer: coarse) {
    a:active,
    button:active {
        opacity: 0.7;
    }
}

/* Reserve space for the fixed mobile bottom tab bar (56px + safe-area inset). */
@media (max-width: 640px) {
    body {
        padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
    }
}

/* Skip link — visible only on focus for keyboard users */
.skip-link {
    position: absolute;
    top: -100px;
    left: 1rem;
    z-index: 10000;
    padding: 0.5rem 1rem;
    background: var(--surface-inverse);
    color: var(--text-inverse);
    font-size: 0.875rem;
    font-weight: 600;
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: top 0.15s ease;
}
.skip-link:focus {
    top: 0.5rem;
}

/* Focus indicators — brand hue, visible on both grounds */
:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* ================================================================
   Shared button classes — use these across all components
   ================================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
    text-decoration: none;
    white-space: nowrap;
}
.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Primary: brand fill — main CTAs (Search, Compare now) */
.btn-primary {
    background: var(--brand);
    color: var(--brand-on);
    border-color: var(--brand);
}
.btn-primary:hover:not(:disabled) {
    background: var(--brand-strong);
    border-color: var(--brand-strong);
}
.btn-primary:active:not(:disabled) {
    background: var(--brand-stronger);
    border-color: var(--brand-stronger);
}

/*
 * Action: coral fill — the one decisive action on a page, and only that.
 *
 * The guideline gives coral to "calls to action, highlights, important
 * buttons" while its own UI-components sheet draws the primary button in
 * teal. Both are honoured by making this a scarce, separate class: teal is
 * the default primary, coral marks the single action a page exists for —
 * the search submit. Use it more than once per screen and it stops meaning
 * anything.
 */
.btn-action {
    background: var(--action);
    color: var(--action-on);
    border-color: var(--action);
}
.btn-action:hover:not(:disabled) {
    background: var(--action-strong);
    border-color: var(--action-strong);
}
.btn-action:active:not(:disabled) {
    background: var(--action-stronger);
    border-color: var(--action-stronger);
}

/* Secondary: brand outline — supporting actions (Add to shortlist) */
.btn-secondary {
    background: transparent;
    color: var(--brand);
    border: 1px solid var(--brand);
}
.btn-secondary:hover:not(:disabled) {
    background: var(--brand-bg);
}

/* Tertiary: quiet — low-emphasis (View, Clear) */
.btn-tertiary {
    background: var(--bg-secondary);
    color: var(--text-secondary);
    border: 1px solid var(--border);
}
.btn-tertiary:hover:not(:disabled) {
    background: var(--border);
    color: var(--text-primary);
}

/* Active toggle state — the shortlist button once a school is on the list */
.btn-active {
    background: var(--brand-bg);
    color: var(--brand);
    border: 1px solid var(--brand);
}
.btn-active:hover:not(:disabled) {
    background: transparent;
    color: var(--text-secondary);
    border-color: var(--border-strong);
}

/* Small variant */
.btn-sm {
    padding: 0.3rem 0.625rem;
    font-size: 0.8125rem;
}

/*
 * Leaflet ships its own palette — a #ddd tile backdrop, #333 attribution text
 * and a #0078A8 link blue that is the most saturated colour anywhere on the
 * site and belongs to no part of this system. Pull the map chrome onto the
 * tokens. This matters most in dark mode, where Leaflet's white attribution
 * bar would otherwise sit on a near-black page.
 *
 * The tiles themselves stay as OSM renders them; only the chrome is ours.
 *
 * Every selector here is prefixed with `html` on purpose. leaflet.css is
 * imported from a client component, so its chunk loads AFTER globals.css; at
 * equal specificity the later sheet wins and these overrides lose silently.
 * The `html` prefix takes them to 0,1,1 so load order stops mattering.
 */
html .leaflet-container {
    background: var(--bg-secondary);
    font-family: var(--font-ui);
}

html .leaflet-control-attribution {
    background: rgba(var(--text-inverse-rgb), 0.82);
    color: var(--text-muted);
}

html .leaflet-control-attribution a {
    color: var(--brand);
}

html .leaflet-bar a {
    background: var(--bg-card);
    color: var(--text-primary);
    border-bottom-color: var(--border);
}

html .leaflet-bar a:hover {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

/* Main content column */
.main {
    max-width: 1400px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem;
    min-width: 0;
    overflow-x: clip;
}

@media (max-width: 768px) {
    .main {
        padding: 1rem;
    }
}

/* Honour the OS setting. Transitions collapse to near-instant rather than
   zero so state changes still register as changes. */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
