/* =========================================================
   Swiss Gardens Primary School — homepage mockup
   Applying brand guidelines v2.3
   ========================================================= */

@font-face {
  font-family: 'PeachyKeenJF';
  src: url('../fonts/PeachyKeenJF.woff2') format('woff2'), url('../fonts/PeachyKeenJF.otf') format('opentype');
  font-display: swap;
}
/* Body font: Inter (SIL Open Font License, fonts/Inter-LICENSE.txt), replacing
   Helvetica Neue in Oct 2026 — Apple's licence doesn't allow serving it on a website.
   size-adjust 95% matches Helvetica's x-height, so line lengths and wraps are unchanged.
   Files are subset to Latin + the punctuation/arrows the site uses. */
@font-face {
  font-family: 'InterBrand';
  src: url('../fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  size-adjust: 95%;
}
@font-face {
  font-family: 'InterBrand';
  src: url('../fonts/Inter-Medium.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
  size-adjust: 95%;
}
@font-face {
  font-family: 'InterBrand';
  src: url('../fonts/Inter-Bold.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
  size-adjust: 95%;
}
@font-face {
  font-family: 'InterBrand';
  src: url('../fonts/Inter-Light.woff2') format('woff2');
  font-weight: 300;
  font-display: swap;
  size-adjust: 95%;
}

:root {
  /* ---------- BRAND COLOUR PALETTE ---------- */
  /* Primary identity */
  --dark-teal: #147484;       /* Headlines, primary backgrounds, the brand voice */
  --teal-deep: #0e5966;       /* Footer, utility strip, hover state for dark-teal */
  --light-teal: #58C4C4;      /* Accents, hover states, decorative wave motifs */

  /* Accents */
  --coral: #F06468;           /* Decorative coral — backgrounds, badges, dividers, large display */
  --coral-deep: #d9484c;      /* Coral decorative-hover */
  --coral-text: #C73E40;      /* Text-grade coral — eyebrows, links, anything coral-coloured at body size on light surfaces. WCAG AA passes 4.5:1 on sky/white. */
  --sunshine: #FCD438;        /* Decorative shapes, badges — and ONE alt panel/page; also primary CTA button surface */
  --sunshine-deep: #EAC020;   /* Sunshine hover — slightly darker for button hover states */
  --logo-gold: #FCC800;       /* RESERVED — only for the gold inside the swan-circle logo */

  /* Surfaces */
  --sky: #ECF5FC;             /* Secondary section background, alternates with white */
  --white: #FFFFFF;
  --ink: #222222;             /* Body text on light surfaces */
  --ink-soft: #4a4a4a;        /* Secondary body, captions, supporting copy */

  /* Semantic foreground tokens */
  --fg-1: var(--ink);
  --fg-2: var(--ink-soft);
  --fg-on-dark: var(--white);
  --fg-on-dark-muted: rgba(255, 255, 255, 0.85);
  --fg-link: var(--dark-teal);
  --fg-accent: var(--coral);

  /* Semantic surface tokens */
  --surface-1: var(--white);
  --surface-2: var(--sky);
  --surface-brand: var(--dark-teal);
  --surface-brand-deep: var(--teal-deep);
  --surface-yellow: var(--sunshine);

  /* Borders / hairlines */
  --border-card: rgba(20, 116, 132, 0.12);
  --border-card-strong: rgba(20, 116, 132, 0.18);
  --border-hairline: #eef1f3;

  /* ---------- TYPOGRAPHY ---------- */
  --font-display: 'PeachyKeenJF', 'Quicksand', system-ui, -apple-system, sans-serif;
  --font-body: 'InterBrand', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  /* Type scale — locked, web-design-system.md §0. 10 sizes only. */
  --fs-11: 11px;   /* Caption / page-number / fine-print */
  --fs-13: 13px;   /* Eyebrows, captions, breadcrumbs, footer text, value-pills */
  --fs-14: 14px;   /* Small-text bands — author notes, metadata footers,
                      download-pill body, signature-space "named after"
                      labels. Added 13 May 2026 after a codebase audit
                      (8+ class definitions across 6 pages) confirmed it
                      was a missing token, not drift. The 13→16 step is
                      the scale's largest jump; 14 lives there. */
  --fs-16: 16px;   /* Body, button labels, nav links, card body */
  --fs-17: 17px;   /* Body+ (sparingly — Ofsted pull quotes etc) */
  --fs-19: 19px;   /* Lede / large body */
  --fs-22: 22px;   /* H4 / small heading / hero kicker */
  --fs-26: 26px;   /* H3 / card heading / brand wordmark line */
  --fs-36: 36px;   /* H2 / section title / scene-band quote */
  --fs-48: 48px;   /* H1 page-hero / CTA-band heading */
  --fs-60: 60px;   /* H1 homepage hero / large stat */
  /* --fs-96 reserved for a homepage display moment if ever needed */

  /* Weights */
  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-bold: 700;

  /* Line heights */
  --lh-display: 1.05;
  --lh-heading: 1.1;
  --lh-body: 1.55;
  --lh-tight: 1.15;

  /* Letter spacing */
  --tracking-eyebrow: 0.14em;   /* uppercase eyebrows */
  --tracking-label: 0.08em;
  --tracking-tight: -0.005em;

  /* ---------- BORDER-RADIUS SCALE — locked, §0a ---------- */
  --r-tag: 6px;       /* Tags, metadata pills, chips */
  --r-button: 8px;    /* Buttons, nav links, action pills, download-pill */
  --r-card: 12px;     /* Cards, panels, info-cards */
  --r-card-lg: 14px;  /* Larger cards, team-cards */
  --r-card-xl: 16px;  /* Welcome panel, hero-image rounding */
  --r-pill: 999px;    /* RESERVED — only for tiny badge-style overlays (video-caption-dur etc.) */

  /* ---------- ELEVATION ---------- */
  --shadow-sm: 0 1px 2px rgba(20, 116, 132, 0.20);
  --shadow-card: 0 5px 12px rgba(20, 116, 132, 0.22);
  --shadow-tile-hover: 0 12px 28px rgba(20, 116, 132, 0.15);
  --shadow-video: 0 18px 48px rgba(20, 116, 132, 0.25);
  --shadow-cta: 0 8px 24px rgba(0, 0, 0, 0.30);

  /* ---------- LAYOUT ---------- */
  --container-max: 1240px;
  --container-pad: 32px;
  --section-pad-y: 80px;
  --section-pad-y-large: 96px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font-body);
  color: var(--fg-1);
  background: var(--surface-1);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; display: block; }
a { color: var(--dark-teal); text-decoration: none; }
a:hover { text-decoration: underline; }
/* a11y (WCAG 1.4.1 Use of Colour, 20 Oct 2026): links sitting inside
   running text in the page body get a fine underline — teal on #222
   body copy is only 2.92:1, so colour alone can't mark them out.
   Scoped to class-less links in paragraphs, list items and table/
   definition cells inside <main>, so buttons (.btn), cards, pills and
   other styled links keep their own look. :where() keeps specificity
   at a bare `a`, so any component rule that sets its own
   text-decoration still wins. */
:where(main) :where(p, li, dd, td, blockquote, figcaption) a:where(:not([class])) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
/* Components that already mark their links another way — a border
   underline (breadcrumbs, Parents forms list) or a tile shape (homepage
   parents links) — opt back out so they don't get a double line. */
:where(.breadcrumb, .parents-links, .forms-col) a { text-decoration: none; }

.container {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 32px;
}

/* ---------- utility strip ---------- */
.utility {
  background: var(--teal-deep);
  color: var(--white);
  font-size: 13px;
  padding: 8px 0;
  letter-spacing: 0.01em;
}
.utility-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
}
.utility-left, .utility-right {
  display: flex;
  gap: 24px;
  align-items: center;
}
.utility .u-link {
  color: var(--white);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  opacity: 0.95;
}
.utility .u-link:hover { opacity: 1; text-decoration: none; }
.u-icon { width: 14px; height: 14px; }
/* Tap targets (mobile audit 8 Oct 2026): text links were 20px tall and
   the icon-only links/search button 14x14 — below the 24px WCAG 2.5.8
   minimum. Bigger hit areas; negative margins keep the bar's height. */
.utility .u-link { min-height: 24px; }
.utility-right .u-link,
.utility .search-toggle { min-width: 32px; min-height: 32px; justify-content: center; margin-top: -4px; margin-bottom: -4px; }
@media (max-width: 560px) {
  .utility-inner { gap: 12px; }
  .utility-right { gap: 4px; }
}

/* (.u-pill removed 6 May 2026 — Cowork audit Task 6 reverted by Al's
   call. Was visually noisy in the utility strip; parents reach the
   Parents page via the primary nav.) */

/* ---------- site alert / closure banner ----------
   Empty by default. Rendered above the utility bar by site.js when
   window.SG_SITE_ALERT is set on a page (snow days, water leaks, etc.).
   Cowork audit Task 7, 6 May 2026. */
.site-alert {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 24px;
  background: var(--sunshine);
  color: var(--ink);
  font-size: 13px;
  line-height: 1.4;
  border-bottom: 2px solid rgba(0,0,0,0.08);
}
.site-alert--urgent { background: var(--coral); color: var(--white); }
.site-alert--info   { background: var(--sky);   color: var(--ink);  }
.site-alert-body { flex: 1; min-width: 0; }
.site-alert-msg  { margin: 0; font-weight: var(--fw-bold); }
.site-alert-time { margin: 4px 0 0; font-size: 11px; opacity: 0.8; }
.site-alert-dismiss {
  background: transparent;
  border: 0;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: inherit;
  padding: 4px 10px;
  opacity: 0.7;
  flex-shrink: 0;
  border-radius: 6px;
}
.site-alert-dismiss:hover { opacity: 1; background: rgba(0,0,0,0.06); }

/* ---------- header ---------- */
/* Canonical chassis from /projects/.../preview/components-header.html.
   Header sits as a bordered, rounded card on the page background, with the
   official seal+wordmark lockup left and PeachyKeen nav right. The nav uses
   colour-only hover (dark-teal → coral-deep) and a coral squiggle underline
   on the active page. The two states are separated on purpose — the squiggle
   ALWAYS marks "you are here", never the cursor. */
.site-header {
  background: var(--white);
  padding: 20px 0;
  position: sticky; top: 0; z-index: 20;
}
.header-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  background: var(--white);
  border: 1px solid rgba(20,116,132,0.12);
  border-radius: 12px;
  padding: 14px 22px 14px 18px;
}
.brand {
  display: flex; align-items: center; gap: 16px;
  flex-shrink: 0;
  color: var(--ink);
}
.brand:hover { text-decoration: none; }
.brand-logo {
  width: 96px; height: 96px;
}
/* Canonical lockup is a real wordmark image right of the seal:
   <img class="brand-wordmark">. The old CSS-retypeset brand-text /
   brand-name / brand-line-2 / brand-sub variant was removed
   15 May 2026 — the dead-CSS pass confirmed zero pages still used
   it, so the wordmark-image migration is complete. (Class names
   left undotted here so the dead-CSS audit doesn't read this
   comment as a phantom definition.) */
.brand-wordmark {
  height: 76px;
  width: auto;
  display: block;
}

/* ---------- primary nav (system canonical) ---------- */
.primary-nav ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: 6px; align-items: center;
}
.primary-nav a {
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--dark-teal);
  text-decoration: none;
  padding: 8px 10px;
  line-height: 1;
  position: relative;
  background: transparent;
  border-radius: 0;
  transition: color .15s ease;
  letter-spacing: 0.005em;
}
.primary-nav a:hover {
  color: #d9484c; /* coral-deep */
  background: transparent;
  text-decoration: none;
}
/* Active-page squiggle — coral wave drawn in SVG, anchored to the
   bottom of the link, 80% width centred. */
.primary-nav a[aria-current="page"] {
  color: var(--dark-teal);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 8' preserveAspectRatio='none'><path d='M2 4 Q 12 0 25 4 T 50 4 T 75 4 T 98 4' stroke='%23F06468' stroke-width='2.4' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: 50% 100%;
  background-size: 80% 6px;
  padding-bottom: 10px;
}
/* Active stays put on hover — the squiggle is the affordance, not a colour shift. */
.primary-nav a[aria-current="page"]:hover {
  color: var(--dark-teal);
  text-decoration: none;
}
/* "Joining us" nav link — coral by default so it pops as the prospective-
   parents recruitment CTA inside an otherwise dark-teal nav. Active and
   hover states stay coral so the link reads consistently across states.
   6 May 2026, Al's call.
   NB: uses [href*="starting-school"] (substring match) rather than an
   exact href because Netlify's Pretty URLs post-processing rewrites
   "starting-school.html" → "/starting-school" in served HTML; the
   substring selector matches both the on-disk and the served forms. */
.primary-nav a[href*="starting-school"],
.primary-nav a[href*="starting-school"][aria-current="page"],
.primary-nav a[href*="starting-school"][aria-current="page"]:hover {
  color: var(--coral-text);
}
.primary-nav a[href*="starting-school"]:hover {
  color: #D9484C; /* coral-deep, matches the existing nav-hover convention */
}

/* ---------- mobile nav (hamburger + slide-down drawer) ---------- */
/* Button is visible only at narrow widths (<860px) — see media block
   below. At wider widths the desktop nav row shows. The button itself
   uses three solid bars; the middle bar fades and the outer two
   rotate-and-cross to form an "X" when expanded. */
.nav-toggle {
  display: none; /* hidden by default; shown via media query */
  appearance: none;
  background: transparent;
  border: 0;
  padding: 12px;
  cursor: pointer;
  position: relative;
  width: 48px; height: 48px;
  align-self: center;
  flex-shrink: 0;
}
.nav-toggle:focus-visible {
  outline: 3px solid var(--sunshine);
  outline-offset: 3px;
  border-radius: 6px;
}
.nav-toggle-bar {
  display: block;
  width: 24px; height: 2px;
  background: var(--dark-teal);
  border-radius: 6px;
  margin: 5px auto;
  transition: transform .25s ease, opacity .15s ease;
  transform-origin: center;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Slide-down drawer behaviour — kicks in below 860px. */
@media (max-width: 860px) {
  /* Header layout: brand left, hamburger right, nav drops below in drawer.
     Brand simplifies to seal-only at this width — the wordmark image is
     ~3.5:1 wide and pushes the hamburger off-screen on phones. The seal's
     alt text already names the school, so screen readers don't lose info. */
  .header-inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 10px 14px;
  }
  .brand-logo { width: 56px; height: 56px; }
  .brand-wordmark { height: 44px; display: block; }
  .nav-toggle { display: block; order: 2; }
  /* Nav drops to a full-width drawer below the header row. */
  .primary-nav {
    order: 3;
    flex-basis: 100%;
    max-height: 0;
    overflow: hidden;
    transition: max-height .3s ease;
  }
  .primary-nav.is-open {
    max-height: 540px; /* enough for 6 links + comfortable padding */
  }
  .primary-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 0 16px;
    border-top: 1px solid var(--border-card);
  }
  .primary-nav li { width: 100%; }
  .primary-nav a {
    display: block;
    padding: 14px 12px;
    font-size: 19px;
    border-bottom: 1px solid var(--border-hairline);
  }
  .primary-nav a[aria-current="page"] {
    /* On mobile the squiggle reads as decoration on a single line —
       swap to a left-edge coral bar for clarity. */
    background-image: none;
    border-left: 4px solid var(--coral-text);
    padding-left: 14px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .nav-toggle-bar { transition: none; }
  .primary-nav { transition: none; }
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  background: var(--dark-teal);
  color: var(--white);
  overflow: hidden;
  padding: 72px 0 96px;
}
/* ---------- Accessibility — site-wide ---------- */

/* Anchor-jump scroll target — every in-page anchor (section / heading
   with id) keeps its focused element clear of the sticky site-header.
   WCAG 2.4.11 (Focus Not Obscured, Level AA in WCAG 2.2). Some pages
   set this in their local <style> as well; the values are identical so
   no conflict. */
section[id], h1[id], h2[id], h3[id], h4[id], aside[id] {
  scroll-margin-top: 80px;
}

/* Skip-to-content link — visually hidden until keyboard-focused, then
   appears top-left so keyboard users can bypass the repeated header /
   utility / nav. WCAG 2.4.1 (Level A). */
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 9999;
  background: var(--coral);
  color: var(--ink);
  padding: 12px 18px;
  font-size: var(--fs-16);
  font-weight: var(--fw-bold);
  text-decoration: none;
  border-radius: 8px;
  transform: translateY(-200%);
  transition: transform 0.15s;
}
.skip-link:focus {
  transform: translateY(0);
  outline: 3px solid var(--sunshine);
  outline-offset: 2px;
}

/* Visually hidden, still read by screen readers — for extra words a
   link or control needs in its accessible name but the design doesn't
   show (e.g. the policy title on Policies' "PDF" buttons, WCAG 2.4.4). */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Global :focus-visible — ensure every interactive element has a
   visible focus indicator. Per-component rules above can override
   for tighter local treatments (vc-prev/next, hero-ofsted, etc.). */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
details:focus-visible,
[role="tab"]:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--sunshine);
  outline-offset: 3px;
  border-radius: 6px;
}

/* Carousel dots — invisible hit zone around each dot, sized to NOT
   overlap its neighbours. The earlier inset:-14px gave a ~50x50px zone,
   but dot centres are only 36px apart, so adjacent zones overlapped by
   ~14px and a tap near a boundary could land on the wrong dot. A centred
   24x44 zone keeps a comfortable 44px vertical target (WCAG 2.5.8) while
   the 24px width sits within the 36px spacing — no overlap. Visible dot
   is 24x24 (see ~line 1830). */
.vc-dot { position: relative; }
.vc-dot::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 24px;
  height: 44px;
}

/* News band (homepage SchoolPing widget — sample data for now). 3-up
   on desktop, 2-up on tablet, 1-up on mobile. Tag colours follow the
   palette: school = teal, year = coral, community = sunshine. */
.news-band {
  padding: 80px 0;
  background: var(--white);
  position: relative; /* anchor for motif-corner-* absolute positioning */
}
.news-lede {
  font-size: var(--fs-19);
  line-height: var(--lh-body);
  color: var(--ink-soft);
  max-width: 720px;
  margin: 0 0 32px;
}
.news-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 980px) { .news-list { grid-template-columns: 1fr 1fr; } }
@media (max-width: 700px) { .news-list { grid-template-columns: 1fr; } }
.news-card {
  background: var(--sky);
  border-radius: var(--r-card-lg);
  padding: 24px 26px 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Optional lead photo: full-bleed across the top of the card. */
.news-card-photo {
  display: block;
  width: calc(100% + 52px);
  max-width: none;
  margin: -24px -26px 4px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-card-lg) var(--r-card-lg) 0 0;
}
.news-card-photos { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 4px; }
.news-card-photos img { display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--r-card); }
.news-card-meta {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.news-card-date {
  font-size: var(--fs-13);
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  font-weight: var(--fw-bold);
}
.news-card-tag {
  display: inline-block;
  padding: 3px 10px;
  color: var(--ink);
  border-radius: 6px;
  font-size: 11px;
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* Tag colours match FREE-values palette vocabulary: light-teal /
   coral / sunshine. Tints rather than full saturation so the headline
   stays the visual anchor. */
.news-card-tag-school    { background: rgba(88,196,196,0.30); }
.news-card-tag-year      { background: rgba(240,100,104,0.18); }
.news-card-tag-community { background: rgba(252,212,56,0.30); }
.news-card-tag-eco       { background: rgba(20,116,132,0.16); }
.news-card-title {
  font-family: var(--font-display);
  font-size: var(--fs-22);
  color: var(--dark-teal);
  margin: 0 0 4px;
  line-height: var(--lh-tight);
}
.news-card-body {
  font-size: var(--fs-16);
  color: var(--ink);
  line-height: 1.55;
  margin: 0;
}
.news-footer-row {
  margin-top: 28px;
  display: flex;
  gap: 18px;
  align-items: baseline;
  flex-wrap: wrap;
}
.news-source {
  font-size: var(--fs-13);
  color: var(--ink-soft);
  font-style: italic;
}

/* Hero video — same opacity treatment as .hero-photo so the same wash
   + text contrast applies whether the hero background is a photo or
   video. Muted, looped, ambient — for "watch me" video, use the
   .video-bleed band lower on the page. */
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.40;
  z-index: 1;
}

/* Hero video pause / play (WCAG 2.2.2) — small round control tucked
   beside the Ofsted badge, vertically centred on it. aria-pressed
   "true" = paused, so the icon swaps on that attribute. */
.hero-video-toggle {
  position: absolute;
  bottom: 58px;
  right: 136px;
  z-index: 6;
  width: 36px;
  height: 36px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.85);
  background: rgba(14,89,102,0.70); /* --teal-deep at 70% */
  color: var(--white);
  cursor: pointer;
  transition: background 0.15s;
}
.hero-video-toggle[hidden] { display: none; }
.hero-video-toggle:hover { background: var(--teal-deep); }
.hero-video-toggle:focus-visible { outline: 2px solid var(--sunshine); outline-offset: 3px; }
.hero-video-toggle svg { width: 16px; height: 16px; fill: currentColor; }
.hero-video-toggle .hvt-play,
.hero-video-toggle[aria-pressed="true"] .hvt-pause { display: none; }
.hero-video-toggle[aria-pressed="true"] .hvt-play { display: block; }
@media (max-width: 700px) {
  .hero-video-toggle { bottom: 32px; right: 96px; }
}

/* Ofsted Good badge — bottom-right of hero, links to the full report. */
.hero-ofsted {
  position: absolute;
  bottom: 28px;
  right: 28px;
  z-index: 6;
  display: block;
  width: 96px;
  height: 96px;
  transition: transform 0.15s;
}
.hero-ofsted:hover { transform: scale(1.05); }
.hero-ofsted img { width: 100%; height: 100%; display: block; }
.hero-ofsted:focus-visible { outline: 2px solid var(--sunshine); outline-offset: 4px; border-radius: 50%; }
@media (max-width: 700px) {
  .hero-ofsted { width: 72px; height: 72px; bottom: 14px; right: 14px; }
}

.hero-photo {
  position: absolute; inset: 0;
  background-image: url('../photos/sg-professional-classroom-girl-pencil-looking-up.jpg');
  background-size: cover;
  background-position: center 30%;
  opacity: 0.40;
  z-index: 1;
}
.hero-wash {
  position: absolute; inset: 0;
  /* Stronger weak-side opacity (was 0.55) so hero text contrast stays
     consistent across the gradient — covers any frame of the looping video. */
  background: linear-gradient(120deg, rgba(20,116,132,0.92) 30%, rgba(20,116,132,0.78) 100%);
  z-index: 2;
}

.hero-blob {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}
.hero-blob-coral {
  width: 280px; height: 280px;
  top: -60px; right: -80px;
  transform: rotate(18deg);
}
.hero-blob-sun {
  width: 160px; height: 160px;
  bottom: 60px; left: -50px;
  opacity: 0.75;
}
/* Hero-blob variants for per-cluster page-hero identity (13 May 2026).
   - .hero-blob-coral (above)  → arrows cluster (school-internal) — status quo, top-right.
   - .hero-blob-coral-br        → zigzag cluster (parent-facing)   — same coral, bottom-right.
   - .hero-blob-sun-tr          → stripes cluster (learning)       — sunshine, top-right.
   Mirrored geometry from .hero-blob-coral. */
.hero-blob-coral-br {
  width: 280px; height: 280px;
  bottom: -60px; right: -80px;
  transform: rotate(-18deg);
}
.hero-blob-sun-tr {
  width: 280px; height: 280px;
  top: -60px; right: -80px;
  transform: rotate(18deg);
}
/* Hero-inner inherits the .container width (1240px max-width with 32px padding)
   so hero text aligns to the same left baseline as body content below.
   Reading-width caps live on the title and lede themselves. */
.hero-inner {
  position: relative;
  z-index: 4;
}
.hero-kicker {
  font-family: var(--font-display);
  font-size: 26px;
  /* Sunshine on dark teal — matches the MB prospectus aesthetic and
     avoids the previous coral-on-teal clash that read as muddy and
     failed on contrast. The page-hero-photo has a dark-teal fallback
     background-color (see below) so even if the photo doesn't load,
     the kicker still sits on dark teal — never on white. Passes 3.65:1
     contrast at 26px display weight (large-text AA threshold is 3:1). */
  color: var(--sunshine);
  margin: 0 0 10px;
  letter-spacing: 0.01em;
}
.hero-title {
  font-family: var(--font-display);
  font-size: 48px;
  line-height: 1.1;
  margin: 0 0 24px;
  color: var(--white);
  letter-spacing: -0.005em;
  max-width: 820px;
}
.hero-lede {
  font-size: 22px;
  line-height: 1.55;
  max-width: 620px;
  color: rgba(255,255,255,0.92);
  margin: 0 0 36px;
  font-weight: 300;
}
/* (.hero-facts removed 6 May 2026 — Cowork audit Task 4 reverted by
   Al's call. The strip read as data-strip-y and clashed with the
   warmth of the kicker/headline/lede typography.) */

/* Hero aside — small line BELOW the CTAs, e.g. in-year joiner nudge
   (Cowork audit Task 3, 6 May 2026). Reads as a quiet supporting line. */
.hero-aside {
  font-size: 16px;
  line-height: 1.5;
  color: rgba(255,255,255,0.85);
  margin: 24px 0 0;
  max-width: 620px;
}
.hero-aside a {
  color: var(--sunshine);
  text-decoration: none;
  border-bottom: 1px solid rgba(252,212,56,0.4);
  font-weight: 600;
  white-space: nowrap;
}
.hero-aside a:hover { border-bottom-color: var(--sunshine); }
/* The link's nowrap (above) keeps it tidy on desktop, but the full
   "Tours every Thursday — we do this all the time." line is ~359px and
   overflowed the page below ~423px viewport. Allow it to wrap on mobile;
   white-space:normal only permits wrapping, so wider phones still keep
   it on one line until it genuinely needs to break. */
@media (max-width: 700px) {
  .hero-aside a { white-space: normal; }
}
.hero-ctas { display: flex; gap: 14px; flex-wrap: wrap; }

/* ---------- buttons (canonical system) ---------------------------------
   Three button forms, derived from /preview/components-buttons.html:
   - .btn-coral   = primary "leaf/petal" shape with white arrow circle
   - .btn-teal    = secondary "wave/sail" shape with coral arrow circle
   - .btn-ghost   = quiet text-only with coral arrow disc

   Markup must include a <span class="btn-shape"> SVG (for non-ghost buttons),
   <span class="btn-label">, and <span class="btn-arrow">. The legacy
   .btn padding-only form still renders if a button lacks the inner spans —
   useful for placeholders and inline calls — but new code should use the
   full pattern.
   ------------------------------------------------------------------------ */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 0 26px 0 30px;
  height: 64px;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  border: 0;
  background: transparent;
  transition: transform .18s ease;
  line-height: 1;
  color: var(--ink);
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn-shape {
  position: absolute;
  inset: -6px -10px;
  width: calc(100% + 20px);
  height: calc(100% + 12px);
  z-index: 0;
  pointer-events: none;
  transition: transform .3s cubic-bezier(.5,1.5,.4,1);
  overflow: visible;
}
.btn-shape svg { width: 100%; height: 100%; display: block; }
.btn-shape path { transition: fill .18s ease; }
.btn-label, .btn-arrow {
  position: relative;
  z-index: 1;
}
.btn-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  font-size: 13px;
  font-weight: 700;
  flex: 0 0 30px;
  transition: transform .18s ease, background .18s ease, color .18s ease;
}
.btn:hover .btn-shape { transform: rotate(-1.5deg) scale(1.025); }
.btn:active .btn-shape { transform: scale(0.98); }

/* PRIMARY (.btn-coral) — leaf/petal silhouette, SUNSHINE fill, teal-deep label
   and arrow disc. (Class is still named .btn-coral for backwards-compat with
   page templates — the visual is sunshine + teal-deep for AA contrast: 5.41:1.)
   The shape itself points to the arrow; on hover the sunshine darkens. */
.btn-coral { color: var(--teal-deep); }
.btn-coral .btn-shape path { fill: var(--sunshine); }
.btn-coral:hover .btn-shape path { fill: var(--sunshine-deep); }
.btn-coral .btn-arrow { background: var(--teal-deep); color: var(--sunshine); }
.btn-coral:hover .btn-arrow { transform: translateX(3px); }

/* SECONDARY (.btn-teal) — wave/sail silhouette, dark-teal fill, coral arrow disc. */
.btn-teal { color: #fff; }
.btn-teal .btn-shape path { fill: var(--dark-teal); }
.btn-teal:hover .btn-shape path { fill: var(--teal-deep); }
.btn-teal .btn-arrow { background: var(--coral); color: var(--ink); }
.btn-teal:hover .btn-arrow { transform: translateX(3px); }

/* GHOST (.btn-ghost) — no shape, text only, coral arrow disc carries the affordance.
   Works on light surfaces; on dark surfaces (hero, scene), use .btn-ghost.btn-on-dark. */
.btn-ghost {
  color: var(--dark-teal);
  padding: 0 4px;
  height: 64px;
  gap: 14px;
}
.btn-ghost .btn-arrow { background: var(--coral); color: var(--ink); width: 32px; height: 32px; flex: 0 0 32px; }
.btn-ghost:hover { color: var(--coral-deep); transform: translateY(-1px); }
.btn-ghost:hover .btn-arrow { background: var(--coral-deep); transform: translateX(4px) scale(1.06); }
.btn-ghost.btn-on-dark { color: #fff; }
.btn-ghost.btn-on-dark .btn-arrow { background: var(--sunshine); color: var(--dark-teal); }
.btn-ghost.btn-on-dark:hover { color: var(--sunshine); }
.btn-ghost.btn-on-dark:hover .btn-arrow { background: var(--sunshine); transform: translateX(4px) scale(1.06); }

/* CTA-tail buttons sit on a dark-teal section — auto-promote any
   .btn-ghost inside .yp-cta to the on-dark variant so authors don't
   have to remember the .btn-on-dark modifier on every page.
   Bug fix: without this, ghost buttons in CTA tails rendered dark-teal
   text on a dark-teal background — invisible. */
.yp-cta .btn-ghost { color: #fff; }
.yp-cta .btn-ghost .btn-arrow { background: var(--sunshine); color: var(--dark-teal); }
.yp-cta .btn-ghost:hover { color: var(--sunshine); }
.yp-cta .btn-ghost:hover .btn-arrow { background: var(--sunshine); transform: translateX(4px) scale(1.06); }

/* Same auto-promotion for ghost buttons inside a .scene block — scene
   blocks render a teal-washed photo, so default coral/teal ghost text
   fails contrast just like inside .yp-cta. */
.scene .btn-ghost { color: #fff; }
.scene .btn-ghost .btn-arrow { background: var(--sunshine); color: var(--dark-teal); }
.scene .btn-ghost:hover { color: var(--sunshine); }
.scene .btn-ghost:hover .btn-arrow { background: var(--sunshine); transform: translateX(4px) scale(1.06); }

/* Same auto-promotion for ghost buttons inside a .hero / .page-hero
   block — hero surfaces are dark-teal, so a default ghost button renders
   teal-on-teal and is invisible. (Bug discovered 7 May 2026 — "How to
   apply" CTA in the starting-school page-hero.) Homepage uses .hero;
   sub-pages use .page-hero — covered here so authors don't have to
   remember .btn-on-dark on either. */
.hero .btn-ghost,
.page-hero .btn-ghost { color: #fff; }
.hero .btn-ghost .btn-arrow,
.page-hero .btn-ghost .btn-arrow { background: var(--sunshine); color: var(--dark-teal); }
.hero .btn-ghost:hover,
.page-hero .btn-ghost:hover { color: var(--sunshine); }
.hero .btn-ghost:hover .btn-arrow,
.page-hero .btn-ghost:hover .btn-arrow { background: var(--sunshine); transform: translateX(4px) scale(1.06); }

/* Backwards-compat: a .btn with no inner spans still renders as a plain
   pill. Many sub-page templates (curriculum-core, curriculum-foundation,
   curriculum-pe, wellbeing, about-swiss-gardens) use the bare-anchor
   form; without these fallbacks the button has no background and the
   teal-deep label text fails contrast against any non-white surface
   (axe flagged 1.46:1 on dark-teal CTA bands). */
.btn-coral:not(:has(.btn-shape)) {
  background: var(--sunshine);
  color: var(--teal-deep);
  padding: 14px 22px;
  border-radius: var(--r-button);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: var(--fs-16);
  font-weight: var(--fw-bold);
  text-decoration: none;
  border: 0;
  letter-spacing: 0.02em;
  transition: background .15s, color .15s, transform .15s;
}
.btn-coral:not(:has(.btn-shape)):hover {
  background: var(--sunshine-deep);
  color: var(--teal-deep);
  text-decoration: none;
  transform: translateY(-1px);
}
.btn-teal:not(:has(.btn-shape)) {
  background: var(--dark-teal);
  color: var(--white);
  padding: 14px 22px;
  border-radius: var(--r-button);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: var(--fs-16);
  font-weight: var(--fw-bold);
  text-decoration: none;
  border: 0;
  letter-spacing: 0.02em;
  transition: background .15s, transform .15s;
}
.btn-teal:not(:has(.btn-shape)):hover {
  background: var(--teal-deep);
  color: var(--white);
  text-decoration: none;
  transform: translateY(-1px);
}

/* ---------- shared section bits ---------- */
.eyebrow {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--coral-text);
  font-weight: 700;
  margin: 0 0 12px;
}
.eyebrow-light { color: var(--sunshine); }

/* ---------- YouTube lite-embed (privacy-friendly, click-to-play) ----------
   Pattern: <figure class="video-yt" data-video-id="…"> with a poster thumbnail and
   play button. On click, the JS at the bottom of the page swaps the button for an
   iframe loaded from youtube-nocookie.com. Until then, no YouTube cookies are set
   and no requests are made to Google. Reusable across the whole site —
   year-group pages, homepage promo, news posts, etc. */
.video-yt {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--ink);
  border-radius: 12px;
  overflow: hidden;
  margin: 0 0 12px;
}
.video-yt-play {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; padding: 0; cursor: pointer;
  background: transparent;
  display: block;
}
.video-yt-thumb {
  position: absolute; inset: 0;
  display: block;
  background-size: cover;
  background-position: center;
  background-color: var(--dark-teal);
  background-repeat: no-repeat;
  transition: transform .25s, filter .25s;
}
.video-yt-play:hover .video-yt-thumb { transform: scale(1.02); filter: brightness(1.05); }
.video-yt-icon {
  position: absolute; top: 50%; left: 50%;
  width: 72px; height: 72px;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.4));
  transition: transform .2s;
}
.video-yt-play:hover .video-yt-icon { transform: translate(-50%, -50%) scale(1.08); }
.video-yt-caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px 20px;
  background: linear-gradient(0deg, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0) 100%);
  color: var(--white);
  text-align: left;
  pointer-events: none;
}
.video-yt-title { display: block; font-weight: 700; font-size: 16px; line-height: 1.3; }
.video-yt-meta { display: block; font-size: 13px; opacity: 0.85; margin-top: 2px; }
/* On phones the overlay caption sat on top of the YouTube thumbnail's own
   title text (both Reception thumbnails carry their title). Hidden there
   (mobile audit 8 Oct 2026) — visually only, so it still names the play
   button: the button has no aria-label any more, because a "Play: …"
   label overrode the visible title on desktop (WCAG 2.5.3, 20 Oct 2026). */
@media (max-width: 700px) {
  .video-yt-caption {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
}
.video-yt iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---------- Self-hosted HTML5 video (for small MP4s the school uploads itself) ----------
   Use for short clips (under ~30 MB ideally) that don't need YouTube's CDN —
   classroom moments, term highlights, a single song verse. For anything longer
   or larger, use the .video-yt YouTube lite-embed instead.

   Pattern:
     <figure class="video-self">
       <video controls preload="metadata" poster="photos/poster.jpg">
         <source src="videos/my-video.mp4" type="video/mp4">
         <p>Your browser can't play this video. <a href="videos/my-video.mp4">Download it</a>.</p>
       </video>
     </figure>

   The video file goes in /videos/. The poster image goes in /photos/. The
   browser only loads the video itself when the user clicks play (preload=metadata
   only fetches the duration and dimensions, not the bytes). */
.video-self {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--ink);
  border-radius: 12px;
  overflow: hidden;
  margin: 0 0 12px;
}
.video-self video {
  width: 100%; height: 100%;
  display: block;
  object-fit: cover;
  background: var(--ink);
}
.section-title {
  font-family: var(--font-display);
  font-size: 48px;
  line-height: 1.1;
  color: var(--dark-teal);
  margin: 0 0 32px;
  letter-spacing: 0.005em;
}
.section-title-light { color: var(--white); }
.lede {
  font-size: 19px;
  color: var(--ink-soft);
  line-height: 1.55;
  font-weight: 300;
}
.inline-link {
  display: inline-block;
  margin-top: 18px;
  color: var(--coral-text);
  font-weight: 700;
  font-size: 16px;
}

/* ---------- video band ---------- */
.video-band {
  padding: 88px 0;
  background: var(--white);
  position: relative;
}
.video-copy .eyebrow { color: var(--coral-text); }
.video-copy .section-title { margin-bottom: 20px; }
.video-copy .lede { margin-bottom: 16px; }
.play-ring {
  position: absolute;
  inset: -12px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.55);
  pointer-events: none;
}
/* ---------- values ---------- */
.values {
  padding: 96px 0 80px;
  background: var(--sky);
}
.values .eyebrow, .values .section-title { text-align: center; }
.values .section-title { max-width: 680px; margin-left: auto; margin-right: auto; }
.values-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-top: 40px;
}

/* ---------------------------------------------------------------------
   Canonical FREE values tiles — design-system pattern from
   /preview/components-values.html. Solid-coloured tiles in coral / dark-teal
   / sunshine / light-teal. Big PeachyKeen letter top-left, value name +
   2-line blurb beneath. min-height 200px so the four tiles read as one
   confident row.
   --------------------------------------------------------------------- */
.values-tiles { gap: 14px; }
.value-tile {
  border-radius: 14px;
  padding: 24px 20px 22px;
  text-align: left;
  position: relative;
  overflow: hidden;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
/* Coral and light-teal tiles use ink text — even the big display
   letter/word fail contrast against dark-teal on those backgrounds.
   Sunshine and dark-teal tiles can keep their original tile colour
   for the big letter/word (passes 3:1 large), with ink-only blurb. */
.value-tile-coral { background: var(--coral); color: var(--ink); }
.value-tile-teal  { background: var(--dark-teal); color: var(--white); }
.value-tile-sun   { background: var(--sunshine); color: var(--dark-teal); }
.value-tile-light { background: var(--light-teal); color: var(--ink); }
.value-tile-sun .value-tile-blurb { color: var(--ink); opacity: 1; }
/* Drop the inherited 0.92 opacity for ink text on lighter tiles —
   opacity-on-light-bg reduces rendered contrast below the calculated ratio. */
.value-tile-coral .value-tile-letter,
.value-tile-coral .value-tile-blurb,
.value-tile-light .value-tile-letter,
.value-tile-light .value-tile-blurb { opacity: 1; }
.value-tile-letter {
  font-family: var(--font-display);
  font-size: 60px;
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0;
  opacity: 0.92;
}
.value-tile-word {
  font-family: var(--font-display);
  font-size: 26px;
  margin: 0 0 6px;
  line-height: 1.05;
}
.value-tile-blurb {
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.45;
  margin: 0;
  opacity: 0.92;
  text-wrap: pretty;
}

/* ---------- welcome ---------- */
.welcome {
  padding: 64px 0;
  background: var(--white);
  position: relative;
}
.welcome-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;  /* tighter photo column for portrait */
  gap: 56px;
  align-items: center;
}
/* Wrap exists so the sunshine ::before circle has a host element —
   pseudo-elements on <img> don't render. Aspect ratio matches the
   480×320 source so object-fit: cover doesn't crop the face tighter. */
.welcome-photo-wrap {
  position: relative;
  aspect-ratio: 3 / 2;
}
.welcome-photo-wrap::before {
  content: '';
  position: absolute;
  top: -24px; right: -24px;
  width: 120px; height: 120px;
  background: var(--sunshine);
  border-radius: 50%;
  z-index: -1;
}
.welcome-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
  border-radius: 14px;
  display: block;
}
.welcome-copy .section-title { margin-bottom: 20px; }
.welcome-copy .lede { margin-bottom: 20px; }
.welcome-copy p:not(.lede):not(.eyebrow) {
  font-size: 16px;
  color: var(--ink-soft);
  margin: 0 0 28px;
}

/* ---------- quick links ---------- */
.quick-links {
  padding: 90px 0 40px;
}
.quick-links .eyebrow { margin-bottom: 24px; }
.ql-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.ql-tile {
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 32px 28px;
  border-radius: 14px;
  min-height: 180px;
  transition: transform .2s, box-shadow .2s;
  position: relative;
  overflow: hidden;
}
.ql-tile:hover {
  transform: translateY(-4px);
  text-decoration: none;
  box-shadow: 0 12px 28px rgba(20,116,132,0.15);
}
.ql-arrow {
  font-size: 26px;
  align-self: flex-end;
  transition: transform .2s;
}
.ql-tile:hover .ql-arrow { transform: translateX(4px); }
.ql-label {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.1;
  margin-top: 28px;
}
.ql-sub { font-size: 13px; margin-top: 6px; opacity: 0.92; }

.ql-tile-teal { background: var(--dark-teal); color: var(--white); }
.ql-tile-coral { background: var(--coral); color: var(--ink); }
.ql-tile-sun { background: var(--sunshine); color: var(--ink); }
.ql-tile-light { background: var(--light-teal); color: var(--ink); }
/* Lighter tiles use ink so opacity 1 keeps full contrast.
   The base 0.92 opacity (bumped from 0.85 in tune-up to clear AA on
   dark-teal: 4.62:1 vs the previous 4.41:1) covers the teal variant. */
.ql-tile-coral .ql-sub,
.ql-tile-sun .ql-sub,
.ql-tile-light .ql-sub { opacity: 1; }

/* ---------- diary ---------- */
.diary {
  padding: 80px 0 100px;
  background: var(--sky);
}
.diary-grid {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 64px;
  align-items: center;
}
.diary-main .eyebrow { color: var(--coral-text); }
.diary-list {
  list-style: none; padding: 0; margin: 0;
}
.diary-list li {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  padding: 18px 0;
  border-bottom: 1px solid #e8ecef;
}
.diary-list li:last-child { border-bottom: none; }
.diary-cal-btn { margin-top: 24px; }
.diary-list strong {
  font-weight: 700;
  color: var(--ink);
  font-size: 16px;
  display: block;
}
.d-sub {
  font-size: 13px;
  color: var(--ink-soft);
  display: block;
  margin-top: 2px;
}
.date-chip {
  /* Wider-palette use (5 May 2026): default chip is light-teal +
     ink text instead of dark-teal + white. Lighter, brighter, breaks
     up the teal-and-coral-and-white default rhythm with one more
     palette colour without breaking accessibility — ink on light-
     teal passes 7.5:1 (well above body text AA). The coral variant
     (.chip-coral) stays the highlighted-date accent. */
  flex: 0 0 60px;
  background: var(--light-teal);
  color: var(--ink);
  border-radius: 8px;
  padding: 10px 6px;
  text-align: center;
  line-height: 1;
}
.date-chip.chip-coral { background: var(--coral); color: var(--ink); }
.date-chip .d {
  font-family: var(--font-display);
  font-size: 26px;
  display: block;
}
.date-chip .m {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  display: block;
  margin-top: 4px;
}

.diary-photos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 160px 160px;
  gap: 16px;
}
.photo {
  border-radius: 14px;
  background-size: cover;
  background-position: center;
}
/* Diary-strip photos refreshed 12 May 2026 (Claude Design review pass):
   - photo-1 was a duplicate of the carousel's Julia Donaldson photo
     (same image ~1500px apart); the diary tile lost.
   - photo-2 and photo-3 were tourism shots (harbour, sea) which read
     as a Shoreham travel panel rather than the school events listed
     in the diary itself.
   All three now show current school-life moments to match the diary
   content (assemblies + trips). */
/* 19 Oct 2026 (Al): photo-1 back to Julia Donaldson at the library opening, even
   though it is also carousel slide 3 (only seen if you click through);
   photo-2 is the PTA Halloween disco to match the diary's autumn dates. */
.photo-1 {
  grid-column: 1 / 2; grid-row: 1 / 3;
  background-image: url('../photos/library-julia-donaldson-author.jpg');
  background-position: 58% center;
}
.photo-2 { background-image: url('../photos/news-halloween-disco-2026-group.jpg'); background-position: center 35%; }
.photo-3 { background-image: url('../photos/sg-samba-band-meads-2.jpg'); }

/* ---------- parents strip ---------- */
.parents-strip {
  background: var(--dark-teal);
  color: var(--white);
  padding: 80px 0;
  position: relative;
  overflow: hidden;
}
.parents-strip::before {
  content: '';
  position: absolute;
  width: 400px; height: 400px;
  background: var(--coral);
  opacity: 0.15;
  border-radius: 50%;
  top: -150px; right: -120px;
}
.parents-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
  position: relative;
  z-index: 2;
}
.parents-lede {
  font-size: 19px;
  color: rgba(255,255,255,0.88);
  line-height: 1.55;
  font-weight: 300;
  margin: 0;
}
.parents-links {
  list-style: none; padding: 0; margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.parents-links li a {
  display: block;
  padding: 14px 18px;
  background: rgba(255,255,255,0.1);
  border-radius: 8px;
  color: var(--white);
  font-weight: 500;
  transition: background .2s;
}
.parents-links li a:hover {
  background: rgba(255,255,255,0.2);
  text-decoration: none;
}

/* ---------- footer ---------- */
.site-footer {
  background: var(--teal-deep);
  color: rgba(255,255,255,0.9);
  padding: 72px 0 40px;
  font-size: 13px;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: 48px;
}
.footer-logo {
  width: 104px; height: 104px;
  margin-bottom: 16px;
}
/* Footer brand lockup — badge + stacked wordmark side by side, mirrors header.
   Used in both the legacy footer (.footer-brand) and system footer (.footer-brand-col). */
.footer-brand-lockup {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
}
.footer-brand-lockup .footer-logo,
.footer-brand-lockup .footer-logo-system {
  margin-bottom: 0;
}
.footer-wordmark-img {
  width: auto;
  display: block;
  /* Whiten the dark-teal wordmark for the dark-teal footer. */
  filter: brightness(0) invert(1);
}
.footer-brand .footer-wordmark-img { height: 60px; }
.footer-brand-col .footer-wordmark-img { height: 50px; }
/* System footer overrides — wordmark first, logo second, so the
   wordmark's left edge sits flush with the address line below and
   with the "Get in touch" / "School" / "Information" column
   headers across the row. row-reverse swaps the visual order
   without changing DOM order (screen readers still see logo-first,
   wordmark-second; the logo's alt is empty so this has no a11y
   effect). Top-aligned so the wordmark sits in line with the
   column headers vertically too. 5 May 2026, Al's feedback. */
.footer-brand-col .footer-brand-lockup {
  align-items: flex-start;
  flex-direction: row-reverse;
  justify-content: flex-end;
}
/* Legacy .site-footer link rules (incl. the old 2.5.8 target-size
   patch) removed 20 Oct 2026 — no page uses .site-footer any more;
   the live footer is .site-footer-system, see .footer-list a below. */

/* ---------- responsive ---------- */
@media (max-width: 980px) {
  /* Header layout for the 860–980px band — desktop nav still shows but
     allowed to flex-wrap if the items get tight. Below 860px, the
     mobile-nav rules above take over. */
  .primary-nav ul { flex-wrap: wrap; }
  .hero-title { font-size: 48px; }
  .values-row, .ql-grid { grid-template-columns: repeat(2, 1fr); }
  .welcome-grid, .diary-grid, .parents-grid, .footer-grid { grid-template-columns: 1fr; gap: 40px; }
  .diary-photos { grid-template-rows: 140px 140px; }
  .parents-links { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .hero { padding: 64px 0 100px; }
  /* Fluid on phones (~30px at 375 wide). A flat 36px ran the headline
     to 7 lines and the desktop &nbsp; pairs stranded "child to" and
     "an" on lines of their own (governor feedback, 7 Oct 2026). */
  .hero-title { font-size: clamp(26px, 8vw, 36px); }
  .hero-lede { font-size: 17px; }
  .section-title { font-size: var(--fs-36); }
  .values-row, .ql-grid { grid-template-columns: 1fr; }
  .utility-left { flex-direction: column; align-items: flex-start; gap: 6px; }
}

/* ---------- proof strip (Ofsted + parents) ---------- */
.proof {
  background: var(--sky);
  padding: 80px 0 80px;
  border-top: 1px solid rgba(20,116,132,0.06);
  border-bottom: 1px solid rgba(20,116,132,0.06);
}
.proof .proof-eyebrow { text-align: center; margin-bottom: 32px; }

/* ---------- canonical Ofsted credentials strip
   Pattern from /preview/brand-ofsted.html. Used in lieu of the older
   3-card .proof-grid for a quieter, more editorial credential moment.
   ---------------------------------------------------------------- */
.credentials {
  display: flex;
  align-items: center;
  gap: 32px;
  background: var(--white);
  padding: 28px 32px;
  border-radius: 14px;
  border: 1px solid var(--border-card);
  box-shadow: 0 1px 2px rgba(20,116,132,0.06);
  text-decoration: none;
  color: inherit;
  transition: transform .18s ease, box-shadow .18s ease;
  /* Block-center the strip so it aligns with the centered eyebrow + pull-quote
     above and below — the panel reads as one centered editorial unit. */
  max-width: 820px;
  margin: 0 auto;
}
.credentials.credentials-link:hover {
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(20,116,132,0.10);
}
.credentials-badge { width: 96px; flex: 0 0 96px; }
.credentials-badge img { width: 100%; height: auto; display: block; }
.credentials-grades {
  display: flex;
  align-items: stretch;
  gap: 32px;
  flex: 1;
}
.credentials .grade {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.credentials .grade-label {
  font-family: var(--font-body);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--ink-soft);
  font-weight: 500;
}
.credentials .grade-value {
  font-family: var(--font-display);
  font-size: 36px;
  line-height: 1;
  letter-spacing: -0.005em;
}
.credentials .grade-value.grade-good { color: var(--dark-teal); }
.credentials .grade-value.grade-outstanding { color: var(--coral); }
.credentials-divider {
  width: 1px;
  align-self: stretch;
  background: var(--border-hairline);
}
.credentials-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  flex-shrink: 0;
  color: var(--dark-teal);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
}
.credentials-cta-arrow {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--coral);
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  transition: transform .18s ease;
}
.credentials.credentials-link:hover .credentials-cta-arrow {
  transform: translateX(3px);
}

/* Second strip under the Ofsted one: the eco award (Oct 2026). */
.credentials--award { margin-top: 16px; }
.credentials--award .grade-value { white-space: nowrap; }
.credentials-badge.award-badge {
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--sunshine);
  box-shadow: inset 0 0 0 6px #fde07a;
  display: flex;
  align-items: center;
  justify-content: center;
}
.award-badge span {
  font-family: var(--font-display);
  font-size: 28px;
  color: var(--dark-teal);
  line-height: 1;
}

/* System pull-quote — replaces the older heavy boxed .ofsted-quote when
   used inside the .proof block. Coral hairline before the source line
   matches the type-eyebrow vocabulary. */
.ofsted-quote-system {
  background: transparent;
  border-left: 0;
  padding: 0;
  margin: 40px auto 0;
  max-width: 820px;
  text-align: center;
}
.ofsted-quote-system p {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--dark-teal);
  line-height: 1.25;
  margin: 0 0 12px;
  text-wrap: pretty;
  /* opacity: 0.92 removed (20 Oct 2026): at the 22px phone size the
     quote is no longer "large text", and the faded teal fell to 4.27:1
     on sky (Work for us). Full --dark-teal is 4.93:1. */
}
.ofsted-quote-system cite {
  font-style: normal;
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.10em;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.ofsted-quote-system cite::before {
  content: "";
  display: inline-block;
  width: 20px;
  height: 1px;
  background: var(--coral);
}

/* Parent-survey stat — moved into the .voices section (its source is parent
   survey data, not Ofsted, so it doesn't belong in the Ofsted credentials
   strip). See `.voices-headline` further down. */

@media (max-width: 720px) {
  .credentials { flex-direction: column; align-items: flex-start; gap: 20px; padding: 22px; }
  .credentials-cta { margin-left: 0; }
  /* Stack the two grades vertically so each gets the full card width.
     In a row, the "Behaviour & attitudes" grade is 232px wide (both its
     11px label AND its 36px "Outstanding" value measure 232px), which
     overflowed the ~267px card-content width and spilled "Outstanding"
     off the card. Stacking gives each grade the full width; the vertical
     hairline divider is meaningless once stacked, so hide it. */
  .credentials-grades { gap: 20px; flex-direction: column; }
  .credentials-divider { display: none; }
}
/* ---------- reusable full-width scene (immersive band) ---------- */
.scene {
  position: relative;
  min-height: 460px;
  overflow: hidden;
  display: flex;
  align-items: center;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.scene::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  background: linear-gradient(110deg, rgba(20,116,132,0.92) 0%, rgba(20,116,132,0.78) 55%, rgba(20,116,132,0.55) 100%);
  z-index: 1;
}
.scene-inner {
  position: relative;
  z-index: 2;
  color: var(--white);
  padding: 80px 32px;  /* horizontal padding kept alive — without it this rule wins over .container's pad on the same div (same-specificity, later in source) and the panel slams flush at viewport widths < the 700px max-width below */
  max-width: 700px;
  width: 100%;
}
@media (max-width: 700px) {
  .scene-inner { padding: 56px 24px; }
}
/* Left-align modifier — by default .scene-inner is auto-centred within
   the .scene flex container; this modifier aligns the content block to
   the SAME left gutter as other .container content on the page (so the
   scene's headline lines up with the journey strip, blocks etc. above).
   Achieved with a calc() that mirrors .container's auto-centring at
   max-width 1240. Used on the Mary's Garden "Come and see us" scene at
   the bottom of joining-us. 7 May 2026, Al's call. */
.scene-left > .scene-inner {
  /* Align with .container content's left edge: container is auto-
     centred at max-width 1240 with 32 px horizontal padding, so its
     content starts at max(32px, (vw - 1240)/2 + 32px). .scene-inner
     overrides padding to 80 0 so we shift the whole element by the
     same amount to land its content on that gutter. */
  margin-left: max(32px, calc((100vw - 1240px) / 2 + 32px));
  margin-right: auto;
}
.scene-kicker {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--sunshine);
  margin: 0 0 8px;
}
.scene-title {
  font-family: var(--font-display);
  font-size: 60px;
  line-height: 1.05;
  margin: 0 0 16px;
  color: var(--white);
  letter-spacing: -0.01em;
}
.scene-lede {
  font-size: 19px;
  line-height: 1.5;
  margin: 0 0 24px;
  color: rgba(255,255,255,0.95);
}

/* responsive scene */
@media (max-width: 800px) {
  .scene { min-height: 360px; }
  .scene-title { font-size: var(--fs-36); }
}

/* ---------- video band: full-bleed variant (video first, explainer after) ---------- */
.video-band-full {
  /* No bottom padding — the next section's own top padding owns the gap and
     the colour seam reads as a clean divider rather than a stranded white band. */
  padding: 0;
}
.video-band-full .video-band-intro-tight {
  padding: 24px 32px 28px;
  max-width: 820px;
  margin: 0 auto;
  text-align: center;
}
.video-band-full .video-band-intro-tight .eyebrow { margin: 0 0 6px; }
.video-band-full .video-band-intro-tight .section-title { margin: 0; }
.video-band-full .video-band-intro {
  text-align: center;
  max-width: 780px;
  margin: 0 auto;
}
.video-band-full .video-band-intro-after {
  margin-top: 48px;
}
.video-bleed {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  position: relative;
  aspect-ratio: 21 / 9;
  background: var(--dark-teal);
  overflow: hidden;
}

/* ---------- Video-band carousel ---------- */
/* Stacks slides in the same 21:9 frame; user flips between them with
   overlaid prev/next arrows or numbered dots. No auto-advance, but
   per Al's spec a carousel nav DOES auto-play the entering video and
   pause the leaving one. Per design system §6 refined rule. */
.video-carousel { position: relative; }
.video-carousel-track {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  aspect-ratio: 21 / 9;
  background: var(--dark-teal);
  overflow: hidden;
}
.video-carousel-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}
.video-carousel-slide.is-active {
  opacity: 1;
  pointer-events: auto;
}
/* Photo slides can wrap their content in an <a> to link through to a
   destination page (e.g. the Julia Donaldson slide → library.html).
   The link fills the slide; the overlay title sits on top as before. */
.carousel-slide-link {
  position: absolute;
  inset: 0;
  display: block;
  color: inherit;
  text-decoration: none;
}
.carousel-slide-link:hover .video-bleed-photo { filter: brightness(1.04); }
.carousel-slide-link:focus-visible { outline: 3px solid var(--sunshine); outline-offset: -3px; }
.video-bleed-video,
.video-bleed-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  background: var(--dark-teal);
}
/* Photo slides re-use the slide chassis but have no play affordance —
   the title overlay sits permanently. */
.video-carousel-slide.is-photo .video-overlay-title { opacity: 1; }
/* When the video band is full-bleed (no white intro panel), each slide
   carries its own title overlay. A dark gradient at the top of the
   slide gives the white text contrast over any video/poster
   underneath; both gradient and overlay fade once a video starts
   playing so neither sits over the moving image. */
/* Black gradient (rather than teal) so the video band reads as a
   distinct moment from the dark-teal hero above. Stronger contrast
   for the white Peachy Keen heading too. */
/* Title gradient now sits at the BOTTOM of each slide so the title
   text doesn't cover children's faces (which usually fall in the
   upper-middle third of the frame). Also a more conventional video-
   title placement (TV / film-poster style). */
.video-carousel-slide::before {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 55%;
  background: linear-gradient(0deg, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.40) 45%, rgba(0,0,0,0) 100%);
  z-index: 5;
  pointer-events: none;
  transition: opacity 0.3s;
}
.video-carousel-slide.is-playing::before { opacity: 0; }

/* Overlay aligned with the body container (1240px max, 32px side
   padding). Bottom-aligned, sitting in the lower third of the slide
   so the title doesn't obscure people's faces. */
.video-overlay-title {
  position: absolute;
  bottom: 88px;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 1240px;
  padding: 0 32px;
  box-sizing: border-box;
  z-index: 7;
  color: var(--white);
  transition: opacity 0.3s;
  pointer-events: none;
}
.video-carousel-slide.is-playing .video-overlay-title { opacity: 0; }
.video-carousel-slide.is-playing .video-bleed-play { display: none; }
.vot-eyebrow {
  font-size: var(--fs-13);
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  font-weight: var(--fw-bold);
  color: var(--sunshine);
  margin: 0 0 10px;
}
.vot-title {
  font-family: var(--font-display);
  font-size: var(--fs-60);
  line-height: var(--lh-display);
  color: var(--white);
  margin: 0;
  letter-spacing: 0.005em;
  max-width: 880px;
}
@media (max-width: 980px) {
  .video-overlay-title { bottom: 72px; padding: 0 24px; }
  .vot-title { font-size: var(--fs-48); }
}
@media (max-width: 700px) {
  .video-overlay-title { bottom: 60px; padding: 0 18px; }
  .vot-title { font-size: var(--fs-26); }
  /* 21:9 left the carousel ~160px tall on a phone, so the title, the
     play button and the dots sat on top of each other. A portrait
     frame gives each its own band; play lifts above the title. */
  .video-carousel-track { aspect-ratio: 4 / 5; }
  .video-carousel-slide .video-bleed-play { top: 40%; }
}

/* When the carousel is bleed-mode (no intro panel), the section
   itself loses its top padding so the gradient meets the section
   above cleanly. */
.video-carousel-bleed { padding-top: 0; padding-bottom: 0; }

/* Carousel arrow buttons — overlaid on the video frame, left and right
   edge, vertically centred. White circles for contrast against any
   video frame. */
.vc-prev, .vc-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 8;
  width: 48px; height: 48px;
  background: rgba(255,255,255,0.88);
  color: var(--dark-teal);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  font-size: 26px;
  line-height: 1;
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, transform 0.15s;
  box-shadow: 0 2px 14px rgba(0,0,0,0.18);
}
.vc-prev { left: 18px; }
.vc-next { right: 18px; }
.vc-prev:hover, .vc-next:hover {
  background: var(--white);
  transform: translateY(-50%) scale(1.05);
}
.vc-prev:focus-visible, .vc-next:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 3px;
}
/* Hide prev/next on mobile — the swipe gesture replaces them (and they
   visually clash with the slide title at narrow widths, since the arrows
   sit at vertical-centre of the slide and the 3-line title overruns
   them). Dots remain as the visible affordance for "which slide am I
   on". Placed AFTER the base .vc-prev/.vc-next rule so this override
   wins on source order (equal specificity). */
@media (max-width: 700px) {
  .vc-prev, .vc-next { display: none; }
}

/* Dots — bottom-centre of the video frame. */
.vc-dots {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 8;
  display: flex;
  gap: 12px;
}
.vc-dot {
  /* Visible target bumped 11px → 24px for WCAG 2.2 SC 2.5.8 (Target
     Size, Min). The earlier ::before hit-area trick (inset:-14px)
     gave a 38×38 click target, but axe scores by visible size, not
     hit area. 24px clears axe and makes the dots more confident. */
  width: 24px; height: 24px;
  border-radius: 50%;
  background: rgba(255,255,255,0.45);
  border: 1px solid rgba(255,255,255,0.70);
  padding: 0;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s;
}
.vc-dot:hover { background: rgba(255,255,255,0.85); }
.vc-dot.is-active {
  background: var(--white);
  transform: scale(1.10);
}
.vc-dot:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 3px;
}
/* Video-vs-photo distinction in the dot row. Slides that contain
   a <video> get .vc-dot-video — a small dark-teal play triangle
   centred inside. Photo slides keep the plain circle. Cowork's UX
   review point: parents should be able to tell ahead of clicking
   whether a slide is a video (will play) or a photo (won't). */
.vc-dot { position: relative; }
.vc-dot-video::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-30%, -50%);
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent var(--dark-teal);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .video-carousel-slide { transition: none; }
}
.video-bleed-play {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 110px; height: 110px;
  background: var(--coral);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: transform .2s, background .2s;
  z-index: 5;
}
.video-bleed-play:hover { transform: translate(-50%, -50%) scale(1.05); background: #d9484c; }
.video-bleed-play .play-ring {
  position: absolute; inset: -14px;
  border: 1.5px solid rgba(252,212,56,0.7);
  border-radius: 50%;
  pointer-events: none;
}
.video-bleed-play svg { width: 44px; height: 44px; margin-left: 4px; }
@media (max-width: 800px) {
  .video-bleed { aspect-ratio: 16 / 9; }
  .video-bleed-play { width: 80px; height: 80px; }
  .video-bleed-play svg { width: 32px; height: 32px; }
}

/* ---------- proof badges (Ofsted + parent stat) ---------- */
.ofsted-badge {
  width: 84px;
  height: 84px;
  margin-bottom: 16px;
  display: block;
}

/* update — official Ofsted badge as <img>, plus brand "outstanding" callout */
img.ofsted-badge {
  width: 84px;
  height: 84px;
  margin-bottom: 16px;
  display: block;
}

/* ---------- Welcome from the Head (small attribution + placeholder note) ---------- */
.welcome-attribution {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0 0 24px;
  line-height: 1.5;
}
.welcome-attribution strong {
  color: var(--dark-teal);
  font-weight: 700;
}
.welcome-placeholder {
  font-size: 13px;
  color: var(--coral-text);
  font-style: italic;
}

/* ---------- Ofsted detail (full ratings + inspector quote) ---------- */
.ofsted-detail {
  padding: 88px 0;
  background: var(--white);
  border-top: 1px solid #eef1f3;
}
.ofsted-ratings {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 0 0 48px;
}
.rating-card {
  background: var(--sky);
  border: 1px solid rgba(20,116,132,0.12);
  border-radius: 12px;
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rating-card.rating-overall {
  background: var(--dark-teal);
  border-color: var(--dark-teal);
}
.rating-card.rating-overall .rating-area,
.rating-card.rating-overall .rating-value {
  color: var(--white);
}
.rating-card.rating-outstanding {
  background: var(--coral);
  border-color: var(--coral);
}
.rating-card.rating-outstanding .rating-area,
.rating-card.rating-outstanding .rating-value {
  color: var(--ink);
}
.rating-area {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  font-weight: 700;
}
.rating-value {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--dark-teal);
  line-height: 1;
  letter-spacing: -0.005em;
}
.ofsted-quote {
  background: var(--sky);
  border-left: 4px solid var(--coral);
  padding: 32px 36px;
  margin: 0 0 28px;
  border-radius: 12px;
}
/* When the quote sits inside the proof panel (sky background), give it a
   white inner so it stands out from the surrounding sky. The system variant
   .ofsted-quote-system overrides this back to a transparent editorial style. */
.proof .ofsted-quote {
  background: var(--white);
  margin: 56px 0 0;
  max-width: 900px;
}
.proof .ofsted-quote.ofsted-quote-system {
  background: transparent;
  border-left: 0;
  padding: 0;
  margin: 40px auto 0;
  max-width: 820px;
}
.ofsted-quote p {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.3;
  color: var(--dark-teal);
  margin: 0 0 14px;
  letter-spacing: -0.005em;
}
.ofsted-quote cite {
  font-style: normal;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  font-weight: 700;
}
.ofsted-meta {
  font-size: 16px;
  text-align: center;
  margin: 0;
}
.ofsted-meta a {
  color: var(--dark-teal);
  border-bottom: 1px solid var(--light-teal);
  padding-bottom: 2px;
  font-weight: 500;
}
.ofsted-meta a:hover { border-bottom-color: var(--dark-teal); text-decoration: none; }

/* ---------- Quick links — audience-clustered groups ---------- */
.ql-group { margin-bottom: 40px; }
.ql-group:last-child { margin-bottom: 0; }
.ql-group .eyebrow { margin-bottom: 18px; }
.ql-grid-2 { grid-template-columns: repeat(2, 1fr); }
.ql-grid-3 { grid-template-columns: repeat(3, 1fr); }
.ql-grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 980px) { .ql-grid-4 { grid-template-columns: repeat(2, 1fr); } }

@media (max-width: 800px) {
  .ofsted-ratings { grid-template-columns: 1fr; }
  .ofsted-quote p { font-size: 22px; }
  .ql-grid-2, .ql-grid-3, .ql-grid-4 { grid-template-columns: 1fr; }
}

/* Voices section headline — combines the 98%-of-parents stat (moved here
   from the Ofsted section, because it's parent-survey data, not Ofsted)
   with the section title in one editorial line. The big PeachyKeen number
   sits above its qualifier. */
.voices-headline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  margin: 0 0 40px;
  text-wrap: pretty;
}
.voices-stat {
  font-family: var(--font-display);
  font-size: 96px;
  line-height: 0.9;
  color: var(--coral-text);
  letter-spacing: -0.02em;
}
.voices-stat-text {
  font-family: var(--font-display);
  font-size: 36px;
  line-height: 1.1;
  color: var(--dark-teal);
  max-width: 600px;
}
@media (max-width: 800px) {
  .voices-stat { font-size: 60px; }
  .voices-stat-text { font-size: 26px; }
}

/* ---------- parent voices ---------- */
.voices {
  padding: 88px 0 96px;
  background: var(--sky);
}
/* on sky bg, the voice cards need a subtle border instead of being pure white */
.voices .voice-feature { background: var(--white); }
.voices .voice-card { background: var(--white); }
.voice-feature {
  background: var(--sky);
  border-left: 4px solid var(--coral);
  padding: 28px 36px 26px;
  margin: 0 0 28px;
  border-radius: 12px;
  position: relative;
}
.voice-feature::before {
  content: "\201C";
  position: absolute;
  top: -8px;
  left: 22px;
  font-family: var(--font-display);
  font-size: 60px;
  color: var(--coral);
  line-height: 1;
  opacity: 0.45;
}
.voice-feature p {
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.3;
  color: var(--dark-teal);
  margin: 0 0 12px;
  letter-spacing: -0.005em;
}
.voice-feature cite {
  font-style: normal;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  font-weight: 700;
}
.voices-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
.voice-card {
  background: var(--white);
  border: 1px solid rgba(20,116,132,0.16);
  border-radius: 12px;
  padding: 28px 28px 24px;
  margin: 0;
  position: relative;
}
.voice-card::before {
  content: "\201C";
  position: absolute;
  top: -2px;
  left: 18px;
  font-family: var(--font-display);
  font-size: 60px;
  color: var(--light-teal);
  line-height: 1;
}
.voice-card p {
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  margin: 16px 0 14px;
}
.voice-card cite {
  font-style: normal;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  font-weight: 700;
}
@media (max-width: 800px) {
  .voices-row { grid-template-columns: 1fr; }
  .voice-feature { padding: 24px 22px; }
  .voice-feature p { font-size: 19px; }
}

/* =========================================================
   download-pill — system signature interaction
   Default: dark-teal background, coral ↓ icon, white type,
            subtle lift on hover (translateY + shadow swap).
   Hover:   inverts to white background with dark-teal type;
            coral icon and uppercase meta both ease through.
   ---------------------------------------------------------
   Canonical updated 13 May 2026 (evening). The previous form
   (16px font / 14-22 padding / 8px radius) was dormant — every
   consumer page had its own inline .download-pill rule and
   won via cascade source-order. This canonical now matches
   the de-facto modern form (V1) that was already in production
   on parents + Y3-6, parameterised through the design tokens.
   The reconciliation also brings curriculum-* into line on the
   hover transform + shadow (previously flat on those 3 pages
   — accidental drift, not deliberate). See:
   - scripts/audit-cascade-overrides.py  (the audit that found it)
   - preview/download-pill-variants.html  (the visual diff)
   - web-design-system.md § Park-with-deadline  (the method)
   - next-up.md                            (the resolved entry)
   Update 13 May 2026 (later evening): the previously-flagged off-scale
   `font-size: 14px` was reconciled by adding --fs-14 to the type scale
   itself. A codebase grep found 8+ class definitions across 6 pages
   using literal 14px for small-text needs (author notes, metadata
   footers, named-after labels) — the pill was the audit trigger, not
   the outlier. 14 lives between 13 and 16 in the locked scale now.
   ========================================================= */
.download-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 20px;
  margin: 4px 6px 4px 0;
  background: var(--dark-teal);
  color: var(--white);
  border: 2px solid var(--dark-teal);
  border-radius: var(--r-button);
  font-family: var(--font-body);
  font-size: var(--fs-14);
  font-weight: var(--fw-bold);
  letter-spacing: 0.02em;
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: background .15s, color .15s, transform .15s, box-shadow .15s;
}
.download-pill:hover {
  background: var(--white);
  color: var(--dark-teal);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}
.download-pill .icon {
  color: var(--coral-text);
  font-weight: 900;
  font-size: 18px;
  line-height: 1;
  transition: color .15s;
}
.download-pill .meta {
  font-weight: var(--fw-regular);
  color: rgba(255,255,255,0.95);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: color .15s;
}
.download-pill:hover .meta {
  color: var(--ink-soft);
}
.download-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 12px 0 0;
}

/* =========================================================
   System footer — the canonical pattern (kit §07)
   Three-column dark teal panel + teal-deep utility row with
   the white Ofsted badge.
   ========================================================= */
.site-footer-system {
  background: var(--dark-teal);
  color: rgba(255,255,255,0.9);
  margin-top: 0;
}
.footer-grid-system {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 36px;
  padding: 56px 32px 44px;
  font-size: 13px;
  line-height: 1.35;
}
.footer-brand-col .footer-logo-system {
  width: 88px;
  height: 88px;
  margin-bottom: 14px;
}
.footer-brand-col .footer-wordmark {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--white);
  margin: 0 0 10px;
  letter-spacing: 0.005em;
}
.footer-brand-col .footer-address {
  margin: 0;
  /* opacity 0.85 dropped contrast to 3.88:1 on --teal-deep — bumped
     to 1 for AA. Visual change is minimal at full white. */
  opacity: 1;
}
.footer-col-h {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--white);
  margin: 0 0 14px;
  font-weight: 400;
  letter-spacing: 0.005em;
}
.footer-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  /* Was gap: 4px with bare inline links — each target 15px tall,
     fails WCAG 2.2 SC 2.5.8 (Target Size, Min) on every page. The
     links now carry their own 24px+ hit area, so the gap closes up
     and the visual rhythm grows by only ~4px a row. */
  gap: 0;
}
.footer-list a {
  display: inline-block;
  min-height: 24px;
  padding: 4px 0;
}
.site-footer-system a {
  /* Was rgba(255,255,255,0.85) — rendered at 4.41:1 on --teal-deep,
     just under 4.5:1. Solid white is ~10:1 — clears 12 footer link
     nodes flagged by axe. */
  color: var(--white);
}
.site-footer-system a:hover {
  color: var(--sunshine);
  text-decoration: none;
}
.footer-bar {
  background: var(--teal-deep);
  padding: 16px 0;
}
.footer-bar-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  font-size: 13px;
  color: rgba(255,255,255,0.78);
}
.footer-ofsted {
  height: 48px;
  width: auto;
  display: block;
}

/* a11y: links in the dark footer strips must be distinguishable from
   surrounding low-opacity text (axe-core link-in-text-block, WCAG 1.4.1).
   Full-white text + underline gives both colour contrast against the
   surrounding grey copy and a non-colour visual cue. */
.footer-bar a {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.footer-bar a:hover {
  color: var(--sunshine);
  text-decoration: underline;
}

@media (max-width: 800px) {
  .footer-grid-system {
    grid-template-columns: 1fr;
    gap: 32px;
    padding: 44px 24px 32px;
  }
  .footer-bar-inner {
    flex-direction: column;
    gap: 14px;
    text-align: center;
  }
}

/* ============================================================
   §15 DECORATIVE MOTIFS
   Geometric SVG accents inspired by the MB Brand Communications
   head-recruitment prospectus (Feb 2024). All decorative — none
   carry information, all sit behind aria-hidden wrappers.

   Three colours, all from the brand palette:
   - sunshine (#FCD438)   primary motif colour, on dark or light bg
   - light-teal (#58C4C4) for waves / squiggles, works on either
   - coral (#F06468)      for accent panels behind motifs

   Apply as decorative <span aria-hidden="true" class="motif-..."></span>
   wrapped inside the host section, positioned via the host's own
   placement classes or inline style.
   ============================================================ */

.motif-zigzag {
  display: inline-block;
  width: 96px; height: 64px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 64' fill='none' stroke='%23FCD438' stroke-width='5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4,14 16,4 28,14 40,4 52,14 64,4 76,14 88,4'/><polyline points='4,32 16,22 28,32 40,22 52,32 64,22 76,32 88,22'/><polyline points='4,50 16,40 28,50 40,40 52,50 64,40 76,50 88,40'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
}

.motif-arrows {
  display: inline-block;
  width: 130px; height: 80px;
  /* stroke-width bumped to 3.5 so the arrows actually read at the
     130×80 size — at 2 they were nearly invisible against the dark-
     teal page-hero wash. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 130 80' fill='none' stroke='%23FCD438' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2 10 L18 10 M14 6 L18 10 L14 14 M28 10 L44 10 M40 6 L44 10 L40 14 M54 10 L70 10 M66 6 L70 10 L66 14 M80 10 L96 10 M92 6 L96 10 L92 14 M106 10 L122 10 M118 6 L122 10 L118 14 M2 30 L18 30 M14 26 L18 30 L14 34 M28 30 L44 30 M40 26 L44 30 L40 34 M54 30 L70 30 M66 26 L70 30 L66 34 M80 30 L96 30 M92 26 L96 30 L92 34 M106 30 L122 30 M118 26 L122 30 L118 34 M2 50 L18 50 M14 46 L18 50 L14 54 M28 50 L44 50 M40 46 L44 50 L40 54 M54 50 L70 50 M66 46 L70 50 L66 54 M80 50 L96 50 M92 46 L96 50 L92 54 M106 50 L122 50 M118 46 L122 50 L118 54 M2 70 L18 70 M14 66 L18 70 L14 74 M28 70 L44 70 M40 66 L44 70 L40 74 M54 70 L70 70 M66 66 L70 70 L66 74 M80 70 L96 70 M92 66 L96 70 L92 74 M106 70 L122 70 M118 66 L122 70 L118 74'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
}

.motif-squiggle {
  display: inline-block;
  width: 96px; height: 18px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 18' fill='none' stroke='%2358C4C4' stroke-width='3.5' stroke-linecap='round'><path d='M3 9 Q 12 1 21 9 T 39 9 T 57 9 T 75 9 T 93 9'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
}

.motif-stripes {
  display: inline-block;
  width: 120px; height: 120px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120' fill='none' stroke='%23FCD438' stroke-width='5' stroke-linecap='round'><line x1='-20' y1='40' x2='100' y2='160'/><line x1='-20' y1='20' x2='100' y2='140'/><line x1='-20' y1='0' x2='100' y2='120'/><line x1='-20' y1='-20' x2='100' y2='100'/><line x1='-20' y1='-40' x2='100' y2='80'/><line x1='-20' y1='-60' x2='100' y2='60'/><line x1='-20' y1='-80' x2='100' y2='40'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
}

/* Wrapper that centres a motif as a between-section divider.
   Uses padding rather than margin so it sits cleanly on whichever
   surface (white / sky) it's placed against. */
.section-divider {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 32px 0;
  background: var(--white);
}
.section-divider.on-sky { background: var(--sky); }

/* Corner-anchor helpers for placing a motif inside any
   position:relative section. Defaults to 24px inset on a slight
   opacity dial-back so the motif reads as decoration, not signage. */
.motif-corner-tl,
.motif-corner-tr,
.motif-corner-bl {
  position: absolute;
  /* z-index 3 sits above the page-hero-wash overlay (z-index 2) so
     cluster motifs on sub-page heroes don't get hidden behind the
     dark-teal photo wash. Section content (.page-hero-inner) is at
     z-index 4, so motif still sits behind the title/breadcrumb. */
  z-index: 3;
  pointer-events: none;
  opacity: 0.85;
}
.motif-corner-tl { top: 24px;    left: 24px;  }
.motif-corner-tr { top: 24px;    right: 24px; }
.motif-corner-bl { bottom: 24px; left: 24px;  }
/* Page banners: the breadcrumb starts 88px down, so a corner motif must
   finish above that. At 24px + 80px (arrows) or 120px (stripes) it ran
   into "Home / …" whenever the text column sat near the left edge —
   any screen narrower than ~1480px (spotted 16 Oct 2026). */
.page-hero .motif-corner-tl { top: 14px; }
.page-hero .motif-arrows.motif-corner-tl { width: 104px; height: 64px; }
.page-hero .motif-stripes.motif-corner-tl { width: 64px; height: 64px; }

/* ============================================================
   SITE SEARCH (added 6 May 2026)
   Magnifier button injected into .utility-right by site.js.
   Modal panel covers the viewport; centred input + result list.
   Cowork rec from 3 May UX review — small magnifying-glass that
   pays for itself on a school site (uniform policy / term dates /
   SEND contact info).
   Index built by scripts/build-search-index.py at /search-index.json.
   ============================================================ */
.search-toggle {
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  color: inherit;
  /* Match the surrounding .u-link spacing */
  margin-right: 4px;
}
.search-toggle:hover { opacity: 0.85; }
.search-toggle:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; border-radius: 6px; }

.search-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: none;
}
.search-modal.is-open { display: block; }
.search-modal-overlay {
  position: absolute;
  inset: 0;
  background: rgba(20, 116, 132, 0.7);
}
.search-modal-panel {
  position: relative;
  max-width: 720px;
  margin: 80px auto 24px;
  background: var(--white);
  border-radius: var(--r-card-lg);
  box-shadow: 0 20px 60px -20px rgba(20,116,132,0.45);
  overflow: hidden;
}
.search-input-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border-card);
}
.search-input-icon {
  width: 22px;
  height: 22px;
  color: var(--ink-soft);
  flex-shrink: 0;
}
.search-input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: var(--fs-19);
  color: var(--ink);
  padding: 4px 0;
}
.search-input::placeholder { color: var(--ink-soft); }
.search-close {
  background: transparent;
  border: 0;
  color: var(--ink-soft);
  font-size: 26px;
  line-height: 1;
  padding: 0 8px;
  cursor: pointer;
  border-radius: 6px;
}
.search-close:hover { color: var(--coral-text); }
.search-close:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }

.search-results {
  max-height: 60vh;
  overflow-y: auto;
  padding: 8px 0;
}
.search-empty {
  padding: 24px 20px;
  margin: 0;
  font-size: var(--fs-16);
  color: var(--ink-soft);
  text-align: center;
}
.search-result {
  display: block;
  padding: 14px 20px;
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid var(--border-card);
  transition: background .12s;
}
.search-result:last-child { border-bottom: 0; }
.search-result:hover,
.search-result:focus-visible {
  background: var(--sky);
  text-decoration: none;
  outline: 0;
}
.search-result:focus-visible {
  box-shadow: inset 3px 0 0 var(--coral);
}
.search-result-title {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-19);
  color: var(--dark-teal);
  margin: 0 0 4px;
  line-height: var(--lh-tight);
}
.search-result-snippet {
  display: block;
  font-size: var(--fs-13);
  line-height: 1.5;
  color: var(--ink);
  margin: 0 0 4px;
}
.search-result-snippet mark {
  background: var(--sunshine);
  color: var(--teal-deep);
  padding: 0 2px;
  border-radius: 6px;
}
.search-result-url {
  display: block;
  font-size: var(--fs-13);
  color: var(--ink-soft);
}

.search-tips {
  padding: 12px 20px 16px;
  margin: 0;
  border-top: 1px solid var(--border-card);
  background: var(--sky);
  font-size: var(--fs-13);
  color: var(--ink-soft);
  text-align: center;
}
.search-tips kbd {
  display: inline-block;
  padding: 2px 6px;
  border: 1px solid rgba(20,116,132,0.30);
  border-radius: 6px;
  background: var(--white);
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--dark-teal);
  margin: 0 2px;
}

@media (max-width: 700px) {
  .search-modal-panel { margin: 24px 16px; max-width: none; }
  .search-results { max-height: calc(100vh - 220px); }
  .search-tips { display: none; } /* phones use touch, not keyboard */
}

/* Team-card stacking on narrow phones (Al's gov feedback 6 May 2026).
   The .team-card pattern (used on reception/year-1-and-2/year-3/year-4/
   year-5/year-6) puts a 110px photo column beside a body column. On a
   ~412px Pixel-class screen that's a tall narrow vertical strip with
   author headshots squashed sideways. Stacking on screens under 480px
   puts the photo on top at 4:3 with the body below — much better
   read on phones. CSS lives globally rather than being duplicated
   in every year-* page. */
@media (max-width: 480px) {
  .team-card { flex-direction: column; }
  .team-portrait { width: 100% !important; aspect-ratio: 4 / 3; background-position: center 30%; }
}

/* Mobile decoration policy (Al's gov, 6 May 2026): hide the corner
   motifs (zigzag, arrows, stripes) and the page-hero blobs on phones
   entirely. They take valuable real estate, compete with breadcrumb +
   title, and don't earn it on a small screen. Desktop keeps them as
   intended.
   What stays visible:
   - .motif-squiggle (used as section divider site-wide) — kept,
     shrunk slightly for mobile rhythm.
   - List-bullet squiggle glyphs in .reading-list and .ambient-list —
     these are inline-svg backgrounds, not .motif-* elements, so this
     rule doesn't touch them. */
@media (max-width: 700px) {
  .motif-zigzag,
  .motif-zigzag-teal,
  .motif-zigzag-dark-teal,
  .motif-arrows,
  .motif-arrows-teal,
  .motif-stripes,
  .motif-stripes-teal,
  .hero-blob-coral,
  .hero-blob-sun,
  /* The 13 May per-cluster variants were never added to this list, so on
     19 pages they sat over breadcrumbs, eyebrows and hero text on phones
     (mobile audit 8 Oct 2026). */
  .hero-blob-coral-br,
  .hero-blob-sun-tr { display: none; }
  .motif-squiggle { width: 64px; height: 12px; }
}
/* Host-section requirements — any section hosting a corner motif
   needs position:relative and overflow:hidden. The Welcome / parents
   blocks already have it; the Ofsted .proof block needs it added. */
.proof { position: relative; overflow: hidden; }
.yp-cta { position: relative; overflow: hidden; }

/* Light-teal motif variants — for use on white / sky backgrounds
   where sunshine yellow fades out. Same shapes, brand --light-teal. */
.motif-zigzag-teal {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 64' fill='none' stroke='%2358C4C4' stroke-width='5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4,14 16,4 28,14 40,4 52,14 64,4 76,14 88,4'/><polyline points='4,32 16,22 28,32 40,22 52,32 64,22 76,32 88,22'/><polyline points='4,50 16,40 28,50 40,40 52,50 64,40 76,50 88,40'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  display: inline-block;
  width: 96px; height: 64px;
  pointer-events: none;
}

.motif-arrows-teal {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 130 80' fill='none' stroke='%2358C4C4' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2 10 L18 10 M14 6 L18 10 L14 14 M28 10 L44 10 M40 6 L44 10 L40 14 M54 10 L70 10 M66 6 L70 10 L66 14 M80 10 L96 10 M92 6 L96 10 L92 14 M106 10 L122 10 M118 6 L122 10 L118 14 M2 30 L18 30 M14 26 L18 30 L14 34 M28 30 L44 30 M40 26 L44 30 L40 34 M54 30 L70 30 M66 26 L70 30 L66 34 M80 30 L96 30 M92 26 L96 30 L92 34 M106 30 L122 30 M118 26 L122 30 L118 34 M2 50 L18 50 M14 46 L18 50 L14 54 M28 50 L44 50 M40 46 L44 50 L40 54 M54 50 L70 50 M66 46 L70 50 L66 54 M80 50 L96 50 M92 46 L96 50 L92 54 M106 50 L122 50 M118 46 L122 50 L118 54 M2 70 L18 70 M14 66 L18 70 L14 74 M28 70 L44 70 M40 66 L44 70 L40 74 M54 70 L70 70 M66 66 L70 70 L66 74 M80 70 L96 70 M92 66 L96 70 L92 74 M106 70 L122 70 M118 66 L122 70 L118 74'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  display: inline-block;
  width: 130px; height: 80px;
  pointer-events: none;
}

.motif-zigzag-dark-teal {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 64' fill='none' stroke='%23147484' stroke-width='5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4,14 16,4 28,14 40,4 52,14 64,4 76,14 88,4'/><polyline points='4,32 16,22 28,32 40,22 52,32 64,22 76,32 88,22'/><polyline points='4,50 16,40 28,50 40,40 52,50 64,40 76,50 88,40'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  display: inline-block;
  width: 96px; height: 64px;
  pointer-events: none;
}

.motif-stripes-teal {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120' fill='none' stroke='%2358C4C4' stroke-width='5' stroke-linecap='round'><line x1='-20' y1='40' x2='100' y2='160'/><line x1='-20' y1='20' x2='100' y2='140'/><line x1='-20' y1='0' x2='100' y2='120'/><line x1='-20' y1='-20' x2='100' y2='100'/><line x1='-20' y1='-40' x2='100' y2='80'/><line x1='-20' y1='-60' x2='100' y2='60'/><line x1='-20' y1='-80' x2='100' y2='40'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  display: inline-block;
  width: 120px; height: 120px;
  pointer-events: none;
}

/* Section divider on white surface (default) — paired with .on-sky which
   exists already. .on-dark inverts for dark-teal panels with a sunshine
   squiggle variant. */
.section-divider.on-dark { background: var(--dark-teal); }

/* Banked design-system option (5 May 2026): copy panel on coral.
   Used on the homepage Mrs Doble welcome — the right column of a
   2-col welcome-grid becomes a coral panel with white text, while
   the photo column stays as a normal portrait. Reusable elsewhere
   wherever a 2-col text-and-photo composition wants the prospectus-
   style colour-panel-on-text moment without disturbing the photo
   side. Reuses the existing .welcome-copy / .eyebrow / .section-title
   / .lede / .welcome-attribution selectors so authoring just adds
   one extra class to the inner div. Sister to the full-bleed-coral
   variant (.welcome-bg-coral) for cases where the WHOLE section
   should be coral. */
/* a11y (20 Oct 2026): the panel stays --coral (Al's call: not the
   darker --coral-text). White on --coral is 3.12:1, which passes only
   for large text, so the display headline stays white and everything
   at body size (eyebrow, lede, body, attribution, ticks) is --ink,
   5.1:1. The sunshine eyebrow was 2.17:1. */
.welcome-copy-panel {
  background: var(--coral);
  color: var(--white);
  padding: 48px 56px;
  position: relative;
}
.welcome-copy-panel .eyebrow,
.welcome-copy-panel .yp-eyebrow { color: var(--ink); }
.welcome-copy-panel .section-title,
.welcome-copy-panel h2 { color: var(--white); }
.welcome-copy-panel .lede,
.welcome-copy-panel .yp-lede { color: var(--ink); }
.welcome-copy-panel p { color: var(--ink); }
/* Matches the specificity of `.welcome-copy p:not(.lede):not(.eyebrow)`
   (ink-soft), which otherwise beat the panel rules on the homepage and
   left the attribution at #4a4a4a on red — 1.76:1. */
.welcome-copy-panel p:not(.lede):not(.eyebrow),
.welcome-copy-panel .welcome-attribution { color: var(--ink); }
.welcome-copy-panel .welcome-attribution strong { color: var(--ink); }
/* When used as a "lede only" panel (no inner list), allow constrained
   width so the panel doesn't span the whole section. */
.welcome-copy-panel.lede-panel { max-width: 880px; border-radius: var(--r-card-lg); margin-bottom: 40px; }
/* check-list inside coral panel — borders go translucent white,
   arrows go sunshine. Used on starting-school's "What to expect". */
.welcome-copy-panel .check-list li { color: var(--ink); border-top-color: rgba(255,255,255,0.30); }
.welcome-copy-panel .check-list li:last-child { border-bottom-color: rgba(255,255,255,0.30); }
.welcome-copy-panel .check-list li::before { color: var(--ink); }
@media (max-width: 800px) {
  .welcome-copy-panel { padding: 36px 28px; }
}

/* Picture divider — photo strip used between major sections on long
   pages to break up the rhythm. No text overlay, no decoration on it
   — the photo itself IS the moment. Aria-hidden on the host element.

   Rule of use: ONLY between two text-block sections. Don't put a
   picture-divider next to (or near) a section that's already
   image-heavy — that produces image-after-image and the divider
   disappears into the noise.

   Photo aspect ratio matters. The default crop assumes a LANDSCAPE
   source (4:3 or wider). Square or portrait sources don't strip well
   even with .tall — see .contain below.

   Variants:
   - default: full-bleed, 240px tall
   - .contained: column-width, sits inside .container width, no
     rounded corners (5 May 2026 — square corners read better as a
     strip)
   - .tall: ~520px, for photos featuring people where the 240/280px
     crop risks cutting off heads. Use whenever subjects are in frame.
   - .contain: shows the whole photo (background-size: contain) with
     a centered photo and quiet bands either side. Use this when the
     source is SQUARE or PORTRAIT and would mangle in a strip crop.
     Works alongside .contained and .tall. */
.picture-divider {
  position: relative;
  width: 100%;
  height: 240px;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.picture-divider.contained {
  max-width: 1140px;
  margin: 0 auto;
  height: 280px;
  border-radius: var(--r-card-lg);
}
.picture-divider.tall { height: 520px; }
.picture-divider.contain {
  background-size: contain;
  background-position: center;
}
@media (max-width: 700px) {
  .picture-divider { height: 180px; }
  /* width:auto — at 100% the 16px side margins pushed it 16px past the
     screen edge, so seven pages scrolled sideways (mobile audit 8 Oct 2026). */
  .picture-divider.contained { height: 200px; margin: 0 16px; width: auto; }
  .picture-divider.tall { height: 360px; }
}

/* ============================================================
   Photo-pair — canonical 2-column image-pair pattern.
   Consolidates .fete-pair (sgpta), .area-pair (about),
   .garden-pair (marys-garden), .sign-pair (marys-garden) which
   were 4 inline-CSS one-page-only patterns of the same shape.
   Locked 13 May 2026.

   Default: background-image children (3:4 portrait aspect).
     <div class="photo-pair">
       <div class="photo-pair-photo" style="background-image: ..."></div>
       <div class="photo-pair-photo" style="background-image: ..."></div>
     </div>

   Modifier .photo-pair--natural: <figure>/<img> children at natural
   aspect, no crop (replaces the .sign-pair pattern):
     <div class="photo-pair photo-pair--natural">
       <figure><img src="..."></figure>
       <figure><img src="..."></figure>
     </div>
   ============================================================ */
.photo-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  max-width: 1240px;
  margin: 56px auto;
  padding: 0 32px;
}
.photo-pair-photo {
  aspect-ratio: 3 / 4;
  background-size: cover;
  background-position: center;
  border-radius: var(--r-card-lg);
  background-color: var(--sky);
}
.photo-pair--natural figure { margin: 0; }
.photo-pair--natural img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-card-lg);
}
@media (max-width: 700px) {
  .photo-pair { grid-template-columns: 1fr; gap: 16px; }
}

/* ============================================================
   Photo-figure — canonical single-image figure at natural aspect.
   Consolidates .signage-figure (720px) + .scene-figure (960px)
   which were 2 inline-CSS one-page-only patterns differing only
   in max-width. Locked 13 May 2026.

     <figure class="photo-figure">
       <img src="..." alt="...">
     </figure>

   Modifier .photo-figure--wide: max-width 960px for atmospheric
   scene photos that want visual weight.
     <figure class="photo-figure photo-figure--wide">
       <img src="..." alt="...">
     </figure>
   ============================================================ */
.photo-figure {
  margin: 56px auto;
  max-width: 720px;
  padding: 0 32px;
}
.photo-figure--wide { max-width: 960px; }
.photo-figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-card-lg);
}

/* ============================================================
   Sub-page chassis — promoted from per-page inline <style> on
   13 May 2026 (Phase 1 of the inline-CSS consolidation pass).
   These 8 rules were identical across 22-27 sub-pages each, kept
   inline only by convention. Now canonical. Pages may still
   override per-instance via the cascade if a one-off variation
   is genuinely needed.
   ============================================================ */
.yp-section { padding: 80px 0; }
.yp-section.alt { background: var(--sky); }
.yp-section h2 { font-family: var(--font-display); font-size: var(--fs-36); line-height: var(--lh-display); color: var(--dark-teal); margin: 0 0 14px; }
.yp-eyebrow { font-size: var(--fs-13); text-transform: uppercase; letter-spacing: var(--tracking-eyebrow); color: var(--coral-text); font-weight: var(--fw-bold); margin: 0 0 8px; }
.yp-lede { font-size: var(--fs-19); line-height: var(--lh-body); color: var(--ink-soft); margin: 0 0 32px; max-width: 720px; }
/* .yp-section h2 has the same specificity as .welcome-copy-panel h2
   but comes later, so a coral panel inside a .yp-section (Our people,
   Parents) had its heading turned teal on coral — 1.74:1. Re-assert
   white here, after the chassis rules. */
.yp-section .welcome-copy-panel h2 { color: var(--white); }

.yp-cta { padding: 80px 0; background: var(--dark-teal); color: var(--white); text-align: center; }
.yp-cta h2 { font-family: var(--font-display); font-size: var(--fs-36); color: var(--white); margin: 0 0 16px; }
.yp-cta p { font-size: var(--fs-19); max-width: 580px; margin: 0 auto 28px; color: rgba(255,255,255,0.92); }

/* ============================================================
   Story-grid family — promoted from per-page inline <style> on
   13 May 2026 (Phase 2 of the inline-CSS consolidation pass).
   2-column "text + photo" pattern used on 8 sub-pages with
   identical rules. Includes the .flip modifier (was only in
   library/meads/marys-garden inline; promoting makes it available
   site-wide).

   Design rule (12 May 2026): align-items: start so the photo's
   top lines up with the title; 28px margin-top on .story-photo
   offsets the eyebrow row so photo-top aligns with h2-top
   specifically.
   ============================================================ */
.story-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 48px; align-items: start; }
.story-grid.flip { grid-template-columns: 0.9fr 1.1fr; }
.story-photo { aspect-ratio: 4 / 3; background-size: cover; background-position: center; background-color: var(--sky); border-radius: var(--r-card-lg); margin-top: 28px; }
.story-copy h2 { margin-top: 0; }
.story-copy p { font-size: var(--fs-17); line-height: 1.6; color: var(--ink); margin: 0 0 14px; }
.story-copy p.lede { color: var(--ink-soft); }
@media (max-width: 800px) {
  .story-grid, .story-grid.flip { grid-template-columns: 1fr; gap: 32px; }
  .story-grid.flip .story-photo { order: -1; }
}

/* ============================================================
   Back-to-top — small caps coral link at the end of long-page
   sections. Promoted from per-page inline <style> on 13 May 2026
   (Phase 3 of the inline-CSS consolidation pass). Was on 11 pages
   identically; reception + year-1-and-2 had a literal-values
   equivalent (13px / 700 / 0.08em) reconciled to var-based here.
   ============================================================ */
.back-to-top { display: inline-block; padding: 4px 0; margin-top: 28px; font-size: var(--fs-13); font-weight: var(--fw-bold); color: var(--coral-text); text-decoration: none; text-transform: uppercase; letter-spacing: var(--tracking-label); }
.back-to-top:hover { text-decoration: underline; }
.back-to-top-wrap { text-align: right; }

/* ============================================================
   Info-grid — 2-column card grid for "info-card" content on
   parents.html and year-1-and-2 → year-6. Promoted 13 May 2026
   (Phase 3). Reception adopts the .info-grid--3col modifier
   below (deliberate per-page variation — Reception has more
   info-cards, so the 3-up shape reads better).
   ============================================================ */
.info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
@media (max-width: 800px) { .info-grid { grid-template-columns: 1fr; } }

/* .info-grid--3col — opt-in modifier for pages with 5+ info-cards.
   Adopted as a system class 13 May 2026 evening (Reception was using
   an inline override; promoted out to canonical as a modifier so the
   per-page choice is explicit in markup, not hidden in <style>).
   Responsive ladder is 3→2→1 (vs canonical's 2→1) for the larger
   card population. Inherits gap from canonical. */
.info-grid--3col { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .info-grid--3col { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .info-grid--3col { grid-template-columns: 1fr; } }

/* Responsive table wrapper — wrap any data table that's wider than a
   phone viewport. Overflow stays inside the wrapper rather than the
   page. Added 2026-06-05 per the mobile audit. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Subtle right-edge hint so mobile users see there's more to swipe to. */
  background:
    linear-gradient(to right, var(--white), var(--white)) left center / 20px 100% no-repeat,
    linear-gradient(to right, rgba(0,0,0,0), rgba(20,116,132,0.08)) right center / 12px 100% no-repeat;
}

/* ============================================================
   Curriculum-grid family — the "by-term" curriculum card grid on
   reception + year-1-and-2 through year-6 (6 pages). All 4 modifier
   rules were identical inline; reception + year-1-and-2 had literal-
   values equivalents for .curriculum-card and .term-label that have
   been reconciled to var-based here. One small intentional fix:
   reception/y1-2 had letter-spacing: 0.1em on .term-label while
   year-3-6 used var(--tracking-label) = 0.08em — canonicalised to
   the var (small visual tightening on reception/y1-2 only).
   Promoted 13 May 2026 (Phase 3).
   ============================================================ */
.curriculum-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 8px; }
.curriculum-card { background: var(--white); border-radius: var(--r-card); padding: 20px 22px; border: 1px solid var(--border-card); }
.curriculum-card.current { border-color: var(--coral-text); box-shadow: 0 0 0 2px rgba(240,100,104,0.14); }
.curriculum-card .term-label { font-size: var(--fs-13); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-soft); font-weight: var(--fw-bold); margin: 0 0 6px; }
.curriculum-card.current .term-label { color: var(--coral-text); }
.curriculum-card.current .term-label::after { content: " · current"; }
@media (max-width: 900px) { .curriculum-grid { grid-template-columns: 1fr 1fr; } }

/* ============================================================
   Phase 4 inline-CSS consolidation — promoted from per-page
   inline <style> on 15 May 2026. Surfaced by the monthly
   audit-inline-duplication run (next-up.md Phase 4 entry):
   12 base rules duplicated byte-identically across 5-6
   year-group / parents / clubs pages.

   SCOPE NOTE — only @media-free base rules are promoted here.
   The mobile rules .topic-grid/.expectations-grid/.info-grid
   { grid-template-columns: 1fr } are deliberately NOT in this
   pass: inline they sit in @media (max-width: 900px) but the
   canonical .info-grid mobile is @media (max-width: 800px)
   (line ~3172). The audit script strips @media context and
   couldn't see that breakpoint mismatch. Blind-deleting the
   inline copies would shift the year-group collapse point
   900→800px (a render change in the 800-900px band). Deferred
   to a design-decision sub-item — see next-up.md.

   .team-portrait base MUST stay below the @media(480) override
   at line ~2874 (width:100% !important; background-position
   center 30%). At ≤480px the !important locks width; the base
   here being source-order-later than 2874 preserves the
   pre-existing background-position: center 20% on phones
   (matches the old inline-after-external-CSS behaviour) —
   render-neutral.

   Variant pages keep their differing inline forms (inline
   <style> loads after this file, so it still wins via cascade
   — render-neutral for them). Reception's .topic-foot keeps
   its inline `font-size: 13px` literal drift (NOT in the
   identical set; flagged as a separate drift item, not fixed
   in a byte-identical promotion pass).
   ============================================================ */
.yp-section h3.subheading { font-family: var(--font-display); font-size: var(--fs-26); color: var(--dark-teal); margin: 0 0 14px; line-height: var(--lh-tight); }

.team-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; }
.team-portrait { width: 140px; flex-shrink: 0; background-size: cover; background-position: center 20%; background-color: var(--sky); }
.team-body { padding: 22px 24px 24px; flex: 1; }
.team-author-note { font-size: var(--fs-14); color: var(--ink-soft); margin: 0; line-height: 1.5; }

.topic-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; }
.topic-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.topic-foot { margin-top: 20px; font-size: var(--fs-14); color: var(--ink-soft); }
.topic-foot strong { color: var(--dark-teal); }

.expectation-card p { font-size: 15px; line-height: 1.55; color: var(--ink-soft); margin: 0; }

.info-card h3 { font-family: var(--font-display); font-size: var(--fs-22); color: var(--dark-teal); margin: 0 0 8px; line-height: var(--lh-tight); }
.info-card p { font-size: var(--fs-16); color: var(--ink-soft); margin: 0; line-height: 1.55; }
@media (max-width: 560px) { .curriculum-grid { grid-template-columns: 1fr; } }

/* ---------- mobile headline wrapping (7 Oct 2026) ----------
   Even out headline line lengths on phones so short headings don't
   end on a single stranded word ("Latest from / school."). Phones
   only: the desktop line breaks were set by hand and stay as they
   are. Browsers without support simply ignore it. */
@media (max-width: 700px) {
  h1, h2, h3, .hero-kicker, .eyebrow { text-wrap: balance; }
}

/* ---------- dated items (js/site.js, 8 Oct 2026) ----------
   List items with their own display rule (flex/grid) would otherwise
   ignore the hidden attribute the expiry script sets. */
[data-until][hidden],
[data-show-max] > [hidden] { display: none !important; }
.dated-empty {
  list-style: none;
  color: var(--ink-soft);
  font-style: italic;
  padding: 12px 0;
}

/* ---------- fluid display type on phones (mobile audit 8 Oct 2026) ----------
   The display tokens were fixed sizes at every width, so a 36px heading in
   the wide Peachy Keen face broke into 4–5 ragged lines on a 320–390px
   phone, and nbsp-joined phrases spilled past their boxes. Below 560px the
   tokens scale with the screen: ~30px for --fs-36 on a 390px phone, 26px
   minimum on the smallest. Desktop sizes are unchanged. */
@media (max-width: 560px) {
  :root {
    --fs-36: clamp(26px, 7.6vw, 36px);
    --fs-48: clamp(30px, 8.6vw, 48px);
    --fs-60: clamp(32px, 9.4vw, 60px);
  }
}

/* ---------- stacked tables on phones (js/site.js adds .table-stack) ---------- */
@media (max-width: 560px) {
  .table-scroll:has(.table-stack) { overflow-x: visible; background: none; }
  .table-stack, .table-stack tbody, .table-stack tr, .table-stack td { display: block; width: 100%; }
  .table-stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .table-stack tr { padding: 12px 0; border-bottom: 1px solid var(--border-card); }
  .table-stack tr:last-child { border-bottom: none; }
  .table-stack td { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding: 3px 0 !important; border: none !important; text-align: right; }
  .table-stack td::before { content: attr(data-label); flex-shrink: 0; text-align: left; font-size: var(--fs-13); font-weight: var(--fw-bold); color: var(--dark-teal); text-transform: uppercase; letter-spacing: var(--tracking-label); }
  .table-stack td:first-child { display: block; text-align: left; font-size: var(--fs-17); padding-bottom: 6px !important; }
  .table-stack td:first-child::before { content: none; }
}

/* ---------- labels that shouldn't split (mobile audit 8 Oct 2026) ---------- */
.download-pill .meta { white-space: nowrap; }
/* Let the meta drop to its own line as a unit rather than overflow. */
.download-pill { flex-wrap: wrap; row-gap: 2px; max-width: 100%; }
@media (max-width: 560px) {
  .welcome-copy-panel { padding-left: 22px; padding-right: 22px; }
  .welcome-copy-panel .btn { padding-left: 22px; padding-right: 18px; font-size: 15px; }
}
.stale-marker { white-space: nowrap; }
.nowrap { white-space: nowrap; }

/* ---------- mobile decoration policy, restated (mobile audit 8 Oct 2026) ----------
   The colour-variant motifs (.motif-*-teal / -dark-teal) are defined after
   the hide-on-phones block above and set display: inline-block, so on equal
   specificity they won. On phones they still sat behind breadcrumbs and
   eyebrows (curriculum heroes, the Library award card). This re-applies the
   policy after every motif definition. */
@media (max-width: 700px) {
  .motif-zigzag-teal,
  .motif-zigzag-dark-teal,
  .motif-arrows-teal,
  .motif-stripes-teal { display: none; }
}

/* Photos: no drag-out, no iOS long-press "Save to Photos" callout (see js/site.js). */
img, video, [style*="background-image"] { -webkit-user-drag: none; -webkit-touch-callout: none; }
img { user-select: none; -webkit-user-select: none; }

/* Homepage parents band: the bottom-left arrows motif (80px tall, 24px up)
   needs clear space under the text, or it sits on the lede at desktop and
   tablet widths. Motifs are hidden at 700px and below, so the padding
   goes back to normal there. */
.parents-strip:has(> .motif-corner-bl) { padding-bottom: 136px; }
@media (max-width: 700px) { .parents-strip:has(> .motif-corner-bl) { padding-bottom: 80px; } }
/* Homepage news band: the 120px stripes at top-left ran down over the
   "School news" eyebrow and heading. Sized and lifted like the page-hero
   motifs so it finishes above the text (band padding is 80px). */
.news-band > .motif-stripes.motif-corner-tl { top: 12px; width: 64px; height: 64px; }

/* Homepage "Already with us?" tiles stay 2x2 on phones (Oct 2026) so the
   four of them don't become a long one-per-row scroll. */
@media (max-width: 800px) {
  .ql-grid-4 { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .ql-grid-4 .ql-tile { min-height: 132px; padding: 18px 16px 20px; }
  .ql-grid-4 .ql-arrow { font-size: 22px; }
  .ql-grid-4 .ql-label { font-size: 21px; margin-top: 14px; }
  .ql-grid-4 .ql-sub { font-size: 12.5px; }
}
