/* ==========================================================================
   Rohi Schools — public site design system
   Loaded AFTER Bootstrap so these deliberately override it.

   The brand runs two palettes (kiddies purple, college orange). Rather than
   fight over which wins, purple carries structure and orange carries action:
   headings/surfaces lean purple-ink, CTAs and accents are orange. That keeps
   both without the page looking like two schools bolted together.
   ========================================================================== */

:root {
  /* Brand */
  --brand: #590694;
  --brand-700: #46057a;
  --brand-300: #a06bd4;
  --brand-50: #f6f1fc;

  --accent: #ff8c00;
  --accent-600: #e07600;
  --accent-50: #fff6ec;

  --sky: #00bfff;

  /* Ink & surface */
  --ink: #14101c;
  --ink-2: #3d3552;
  --muted: #6b6480;
  --line: #e7e3ef;
  --surface: #ffffff;
  --surface-2: #faf8fd;
  --surface-3: #f3eefa;

  /* Type scale — 1.25 ratio, clamped so it breathes on desktop without
     blowing out on a 320px phone. */
  --step--1: clamp(0.82rem, 0.79rem + 0.11vw, 0.89rem);
  --step-0:  clamp(1rem, 0.96rem + 0.15vw, 1.08rem);
  --step-1:  clamp(1.2rem, 1.12rem + 0.32vw, 1.45rem);
  --step-2:  clamp(1.45rem, 1.31rem + 0.60vw, 1.95rem);
  --step-3:  clamp(1.75rem, 1.5rem + 1.02vw, 2.6rem);
  --step-4:  clamp(2.1rem, 1.66rem + 1.79vw, 3.5rem);
  --step-5:  clamp(2.5rem, 1.75rem + 2.89vw, 4.5rem);

  /* Spacing rhythm */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;
  --sp-4: 1rem;     --sp-5: 1.5rem;   --sp-6: 2rem;
  --sp-7: 3rem;     --sp-8: 4rem;     --sp-9: 6rem;

  --radius: 0.875rem;
  --radius-lg: 1.375rem;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(20, 16, 28, 0.06), 0 2px 8px rgba(20, 16, 28, 0.04);
  --shadow-md: 0 4px 12px rgba(20, 16, 28, 0.07), 0 12px 28px rgba(20, 16, 28, 0.07);
  --shadow-lg: 0 12px 28px rgba(20, 16, 28, 0.1), 0 28px 60px rgba(89, 6, 148, 0.12);

  --nav-h: 4.25rem;   /* 68px at 100%; scales with the root */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- Base ----------
   The whole design system is rem-based, so one root font-size acts as a
   global zoom. 85% (13.6px) reproduces the density of Chrome at 85% without
   the user having to zoom manually. The vw terms in the type/spacing clamps
   below are scaled by the same 0.85, otherwise headings would keep their full
   size on wide screens while everything around them shrank. */
html { scroll-behavior: smooth; font-size: 85%; }
body {
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ink-2);
  background: var(--surface);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6, .display {
  font-family: "Sora", "Inter", system-ui, sans-serif;
  color: var(--ink);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
p { text-wrap: pretty; }

a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-700); }
img { max-width: 100%; }

.container-narrow {
  width: 100%;
  max-width: 760px;
  margin-inline: auto;
  padding-inline: var(--sp-4);
}
.container-wide {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--sp-4);
}

.section { padding-block: clamp(3rem, 2rem + 4.25vw, 6rem); }
.section-tint { background: var(--surface-2); }
.section-brand {
  background: linear-gradient(160deg, var(--brand-50), var(--surface));
}

/* Section headers get a consistent eyebrow + title + lede rhythm */
.section-head { max-width: 60ch; margin-bottom: var(--sp-6); }
.section-head.center { margin-inline: auto; text-align: center; }
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-600);
  margin-bottom: var(--sp-2);
}
.eyebrow::before {
  content: "";
  width: 22px; height: 2px;
  background: var(--accent);
  border-radius: 2px;
}
.section-head.center .eyebrow::before { display: none; }
.section-lede { color: var(--muted); font-size: var(--step-1); margin-top: var(--sp-3); }

/* ---------- Buttons ---------- */
.btn-primary-solid, .btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 46px;
  padding: 0.7rem 1.4rem;
  border-radius: var(--radius-pill);
  font-weight: 650;
  font-size: var(--step-0);
  text-decoration: none;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background 0.18s var(--ease);
}
.btn-primary-solid {
  background: linear-gradient(135deg, var(--accent), var(--accent-600));
  color: #fff;
  box-shadow: 0 6px 18px rgba(255, 140, 0, 0.28);
}
.btn-primary-solid:hover { color: #fff; transform: translateY(-2px); box-shadow: 0 10px 26px rgba(255, 140, 0, 0.36); }
.btn-ghost { background: transparent; color: var(--brand); border-color: var(--line); }
.btn-ghost:hover { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-700); }
.btn-on-dark { background: rgba(255,255,255,0.12); color: #fff; border-color: rgba(255,255,255,0.35); backdrop-filter: blur(6px); }
.btn-on-dark:hover { background: rgba(255,255,255,0.2); color: #fff; }

/* ---------- Chips ---------- */
.chip {
  display: inline-block;
  padding: 0.28rem 0.7rem;
  border-radius: var(--radius-pill);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--surface-3);
  color: var(--brand);
}
.chip-admissions { background: var(--accent-50); color: var(--accent-600); }
.chip-events     { background: #e8f7ff; color: #0284a8; }
.chip-achievements { background: #e9f9ee; color: #1a7f42; }
.chip-notices    { background: #fdeced; color: #b3261e; }

/* ==========================================================================
   NAVIGATION
   Was: opaque dark bar with five identical links, no active state, sitting
   over the hero imagery. Now: transparent over the hero, solid on scroll,
   a real active indicator, and Portal promoted to a button because it is the
   one thing parents actually come here to do.
   ========================================================================== */
.site-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 1000;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  transition: background 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-nav.is-solid {
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: var(--line);
  box-shadow: 0 2px 20px rgba(20, 16, 28, 0.06);
}
.nav-inner {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--sp-4);
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  margin-right: auto;
  min-width: 0;
}
.nav-brand img {
  width: 38px; height: 38px;
  border-radius: 10px;
  object-fit: cover;
  flex-shrink: 0;
}
.nav-brand-text { display: flex; flex-direction: column; line-height: 1.1; min-width: 0; }
.nav-brand-name {
  font-family: "Sora", sans-serif;
  font-weight: 800;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
  color: #fff;
  white-space: nowrap;
}
.nav-brand-sub {
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.7);
  white-space: nowrap;
}
.site-nav.is-solid .nav-brand-name { color: var(--ink); }
.site-nav.is-solid .nav-brand-sub { color: var(--muted); }

.nav-links { display: flex; align-items: center; gap: 0.15rem; list-style: none; margin: 0; padding: 0; }
.nav-links a {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 42px;
  padding-inline: 0.9rem;
  border-radius: 10px;
  font-size: 0.94rem;
  font-weight: 550;
  color: rgba(255,255,255,0.9);
  text-decoration: none;
  transition: color 0.2s var(--ease), background 0.2s var(--ease);
  white-space: nowrap;
}
.site-nav.is-solid .nav-links a { color: var(--ink-2); }
.nav-links a:hover { background: rgba(255,255,255,0.12); color: #fff; }
.site-nav.is-solid .nav-links a:hover { background: var(--brand-50); color: var(--brand); }

/* The active indicator that was missing entirely — you could not tell which
   page you were on. */
.nav-links a.is-active::after {
  content: "";
  position: absolute;
  left: 0.9rem; right: 0.9rem; bottom: 6px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}
.nav-links a.is-active { color: #fff; font-weight: 700; }
.site-nav.is-solid .nav-links a.is-active { color: var(--brand); }

.nav-cta { margin-left: 0.5rem; }
.nav-cta .btn-primary-solid { min-height: 42px; padding: 0.5rem 1.15rem; font-size: 0.94rem; }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  border: none;
  background: transparent;
  color: #fff;
  font-size: 1.5rem;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  cursor: pointer;
}
.site-nav.is-solid .nav-toggle { color: var(--ink); }

/* Mobile: a full-height panel rather than the cramped Bootstrap dropdown. */
.nav-panel {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(88vw, 360px);
  background: var(--surface);
  transform: translateX(100%);
  transition: transform 0.32s var(--ease);
  z-index: 1002;
  display: flex;
  flex-direction: column;
  padding: var(--sp-5);
  box-shadow: -20px 0 60px rgba(20, 16, 28, 0.18);
  overflow-y: auto;
}
.nav-panel.open { transform: translateX(0); }
.nav-panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-5); }
.nav-panel-close { width: 44px; height: 44px; border: none; background: var(--surface-3); border-radius: 12px; font-size: 1.3rem; color: var(--ink); cursor: pointer; }
.nav-panel a.panel-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 54px;
  padding: 0 var(--sp-4);
  border-radius: 12px;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.nav-panel a.panel-link:last-of-type { border-bottom: none; }
.nav-panel a.panel-link.is-active { background: var(--brand-50); color: var(--brand); }
.nav-panel a.panel-link i { color: var(--muted); }
.nav-panel .btn-primary-solid { margin-top: var(--sp-5); width: 100%; }
.nav-scrim {
  position: fixed; inset: 0;
  background: rgba(20, 16, 28, 0.5);
  opacity: 0; pointer-events: none;
  transition: opacity 0.3s var(--ease);
  z-index: 1001;
}
.nav-scrim.open { opacity: 1; pointer-events: auto; }

@media (max-width: 900px) {
  .nav-links, .nav-cta { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* Pages that don't have a hero start solid, so the nav is never invisible. */
body:not(.has-hero) .site-nav { background: rgba(255,255,255,0.9); backdrop-filter: saturate(180%) blur(14px); border-bottom-color: var(--line); }
body:not(.has-hero) .nav-brand-name { color: var(--ink); }
body:not(.has-hero) .nav-brand-sub { color: var(--muted); }
body:not(.has-hero) .nav-links a { color: var(--ink-2); }
body:not(.has-hero) .nav-links a.is-active { color: var(--brand); }
body:not(.has-hero) .nav-toggle { color: var(--ink); }


/* ==========================================================================
   FOOTER
   Rebuilt: the old one was three loose Bootstrap columns of unstyled lists.
   Now a proper four-track masthead — identity, two link columns and contact
   with its own portal CTA — over a brand-tinted ground with an accent rule.
   ========================================================================== */
.site-footer {
  position: relative;
  background:
    radial-gradient(900px 380px at 8% 0%, rgba(89, 6, 148, 0.55), transparent 62%),
    linear-gradient(168deg, #191024 0%, #221630 55%, #17101f 100%);
  color: rgba(255, 255, 255, 0.7);
  padding-block: var(--sp-8) var(--sp-5);
  margin-top: var(--sp-9);
  font-size: 0.94rem;
}
.footer-accent {
  position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--brand-300) 45%, var(--sky) 100%);
}

.footer-top {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1fr 1.5fr;
  gap: var(--sp-7) var(--sp-6);
  padding-bottom: var(--sp-7);
}
.footer-top > * { min-width: 0; }

.footer-brand { display: flex; align-items: center; gap: 0.75rem; margin-bottom: var(--sp-4); }
.footer-brand img { width: 48px; height: 48px; border-radius: 13px; object-fit: cover; flex-shrink: 0; }
.footer-brand-name {
  display: block;
  font-family: "Sora", sans-serif; font-weight: 800; font-size: 1.05rem;
  color: #fff; letter-spacing: -0.01em; line-height: 1.2;
}
.footer-brand-sub {
  display: block; font-size: 0.72rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--accent);
}
.footer-tagline { max-width: 40ch; margin: 0 0 var(--sp-5); line-height: 1.7; }

.footer-col h6 {
  color: #fff; font-family: "Sora", sans-serif;
  font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid rgba(255,255,255,0.12);
}
.footer-col ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.7rem; }
.site-footer a { color: rgba(255,255,255,0.7); text-decoration: none; transition: color 0.2s var(--ease); }
.footer-col a { display: inline-flex; align-items: center; gap: 0.4rem; }
.footer-col a::before {
  content: ""; width: 0; height: 1px; background: var(--accent);
  transition: width 0.24s var(--ease);
}
.footer-col a:hover { color: #fff; }
.footer-col a:hover::before { width: 12px; }

.footer-contact { display: grid; gap: 0.85rem; }
.footer-contact li { display: flex; gap: 0.65rem; align-items: flex-start; min-width: 0; line-height: 1.6; }
.footer-contact i { color: var(--accent); margin-top: 0.25rem; flex-shrink: 0; }
.footer-contact li span, .footer-contact li a { min-width: 0; overflow-wrap: anywhere; }
.footer-contact a:hover { color: #fff; }

.footer-portal-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  margin-top: var(--sp-5);
  min-height: 46px; padding: 0.65rem 1.1rem;
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.22);
  color: #fff !important; font-weight: 650; font-size: 0.9rem;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.footer-portal-btn:hover {
  background: linear-gradient(135deg, var(--accent), var(--accent-600));
  border-color: transparent; transform: translateY(-2px);
}

.footer-socials { display: flex; gap: 0.55rem; }
.footer-socials a {
  width: 42px; height: 42px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 12px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.1);
  font-size: 1.05rem; color: rgba(255,255,255,0.8);
  transition: background 0.2s var(--ease), transform 0.2s var(--ease), color 0.2s var(--ease);
}
.footer-socials a:hover { background: var(--accent); color: #fff; transform: translateY(-3px); border-color: transparent; }

.footer-base {
  padding-top: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,0.1);
  display: flex; flex-wrap: wrap; gap: var(--sp-3);
  align-items: center; justify-content: space-between;
  font-size: 0.84rem; color: rgba(255,255,255,0.55);
}
.footer-credit strong { color: var(--accent); font-weight: 700; }

@media (max-width: 980px) {
  .footer-top { grid-template-columns: 1fr 1fr; gap: var(--sp-6); }
  .footer-identity { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .footer-top { grid-template-columns: 1fr; }
  .footer-base { flex-direction: column; text-align: center; gap: var(--sp-2); }
  .footer-portal-btn { width: 100%; }
}

/* ==========================================================================
   NEWS
   Was: uniform Bootstrap cards, three across, no hierarchy — every story
   looked equally important. Now the newest story leads at full width and the
   rest follow as a grid, which is how a reader expects a newsroom to behave.
   ========================================================================== */
.news-lead {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
  margin-bottom: var(--sp-6);
}
.news-lead:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.news-lead-media { position: relative; min-height: 320px; background: var(--surface-3); }
.news-lead-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.news-lead-body { padding: clamp(1.5rem, 1rem + 2vw, 2.75rem); display: flex; flex-direction: column; gap: var(--sp-3); justify-content: center; }
.news-lead-body h2 { font-size: var(--step-2); margin: 0; }

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: var(--sp-5);
}
.news-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  text-decoration: none;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}
.news-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--brand-300); }
.news-card-media { position: relative; aspect-ratio: 16 / 10; background: var(--surface-3); overflow: hidden; }
.news-card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s var(--ease); }
.news-card:hover .news-card-media img { transform: scale(1.04); }
.news-card-media .chip { position: absolute; top: 12px; left: 12px; background: rgba(255,255,255,0.94); }
.news-card-body { padding: var(--sp-4) var(--sp-5) var(--sp-5); display: flex; flex-direction: column; gap: 0.5rem; flex: 1; }
.news-card-body h3 { font-size: var(--step-1); margin: 0; }
.news-card-body time, .news-meta time { font-size: var(--step--1); color: var(--muted); font-weight: 600; letter-spacing: 0.02em; }
.news-excerpt { color: var(--muted); margin: 0; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.news-readmore { margin-top: auto; padding-top: var(--sp-2); color: var(--brand); font-weight: 650; font-size: var(--step--1); display: inline-flex; align-items: center; gap: 0.4rem; }
.news-card:hover .news-readmore i, .news-lead:hover .news-readmore i { transform: translateX(3px); }
.news-readmore i { transition: transform 0.2s var(--ease); }
.news-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-2); }
.news-placeholder {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(140deg, var(--brand-50), var(--surface-3));
  color: var(--brand-300); font-size: 2.5rem;
}
.empty-note { text-align: center; padding: var(--sp-9) var(--sp-4); color: var(--muted); }
.empty-note i { font-size: 2.5rem; color: var(--line); }
.empty-note h3 { margin-top: var(--sp-3); }

@media (max-width: 860px) {
  .news-lead { grid-template-columns: 1fr; }
  .news-lead-media { min-height: 220px; aspect-ratio: 16/9; }
}

/* ---------- Article ---------- */
.post-page { padding-bottom: var(--sp-8); }
.post-header { padding-block: var(--sp-7) var(--sp-5); background: linear-gradient(170deg, var(--brand-50), var(--surface)); }
.post-header h1 { margin: var(--sp-3) 0 var(--sp-2); }
.back-link { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--muted); text-decoration: none; font-size: var(--step--1); font-weight: 600; margin-bottom: var(--sp-4); }
.back-link:hover { color: var(--brand); }
.post-meta { color: var(--muted); font-size: var(--step--1); font-weight: 600; margin: 0; }
.post-cover { width: 100%; border-radius: var(--radius-lg); margin-block: var(--sp-5); box-shadow: var(--shadow-md); aspect-ratio: 16/9; object-fit: cover; }

/* A comfortable reading measure — the old post body ran the full container. */
.prose { font-size: 1.06rem; line-height: 1.8; color: var(--ink-2); }
.prose > * + * { margin-top: 1.1em; }
.prose h2 { font-size: var(--step-2); margin-top: 2em; }
.prose h3 { font-size: var(--step-1); margin-top: 1.6em; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li + li { margin-top: 0.4em; }
.prose img { border-radius: var(--radius); }
.prose blockquote {
  border-left: 3px solid var(--accent);
  padding-left: var(--sp-4);
  color: var(--ink);
  font-size: var(--step-1);
}
.post-nav { display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: space-between; margin-top: var(--sp-8); padding-top: var(--sp-5); border-top: 1px solid var(--line); }

/* ==========================================================================
   HERO
   Was: three carousel slides each carrying their own headline, so the copy
   slid away while you were reading it, at a fixed 90vh that overflowed short
   phone viewports. Now the imagery cross-fades behind a single fixed message.
   ========================================================================== */
.hero {
  position: relative;
  min-height: min(92svh, 780px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}
.hero .carousel, .hero .carousel-inner, .hero .carousel-item { position: absolute; inset: 0; }
.hero-slide {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
  transform: scale(1.06);
  animation: heroDrift 14s ease-out forwards;
}
@keyframes heroDrift { to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .hero-slide { animation: none; transform: none; } }

/* Two-stop scrim: strong at the base where the type sits, light at the top so
   the photograph still reads. */
.hero-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(14,8,24,0.93) 0%, rgba(14,8,24,0.72) 32%, rgba(14,8,24,0.25) 62%, rgba(14,8,24,0.45) 100%);
  z-index: 1;
}
.hero-content {
  position: relative;
  z-index: 2;
  color: #fff;
  padding-block: calc(var(--nav-h) + var(--sp-7)) var(--sp-8);
  max-width: 1240px;
}
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: rgba(255,255,255,0.14);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.22);
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius-pill);
  font-size: var(--step--1); font-weight: 600;
  margin-bottom: var(--sp-4);
}
.hero-eyebrow i { color: var(--accent); }
.hero-title {
  font-size: var(--step-5);
  color: #fff;
  max-width: 17ch;
  margin: 0 0 var(--sp-4);
}
.hero-lede {
  font-size: var(--step-1);
  color: rgba(255,255,255,0.86);
  max-width: 52ch;
  margin: 0 0 var(--sp-6);
}
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

.hero-stats {
  display: flex; flex-wrap: wrap; gap: var(--sp-6);
  margin: var(--sp-7) 0 0;
  padding-top: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,0.18);
}
.hero-stats dt { font-family: "Sora", sans-serif; font-size: var(--step-1); font-weight: 700; color: #fff; }
.hero-stats dd { margin: 0; font-size: var(--step--1); color: rgba(255,255,255,0.66); }

.hero-dots { position: absolute; bottom: var(--sp-4); right: var(--sp-5); z-index: 3; display: flex; gap: 0.4rem; }
.hero-dots button {
  width: 28px; height: 4px; border: none; border-radius: 2px;
  background: rgba(255,255,255,0.35); cursor: pointer; padding: 0;
  transition: background 0.25s var(--ease), width 0.25s var(--ease);
}
.hero-dots button.active { background: var(--accent); width: 44px; }

@media (max-width: 720px) {
  .hero { min-height: min(88svh, 640px); align-items: center; }
  .hero-content { padding-block: calc(var(--nav-h) + var(--sp-6)) var(--sp-7); }
  .hero-stats { gap: var(--sp-4); }
  .hero-stats > div { flex: 1 1 40%; }
  .hero-dots { left: var(--sp-4); right: auto; bottom: var(--sp-3); }
  .hero-actions .btn-primary-solid, .hero-actions .btn-ghost { flex: 1 1 100%; }
}

/* ---------- Pillars ---------- */
.pillar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: var(--sp-5);
}
.pillar {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--sp-6) var(--sp-5);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}
.pillar:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: transparent; }
.pillar-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 16px;
  background: color-mix(in srgb, var(--c) 12%, transparent);
  color: var(--c); font-size: 1.4rem;
  margin-bottom: var(--sp-4);
}
.pillar h3 { font-size: var(--step-1); margin-bottom: var(--sp-2); }
.pillar p { color: var(--muted); margin: 0; }

.news-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-6); flex-wrap: wrap; }

/* ---------- Gallery ---------- */
.segmented {
  display: inline-flex;
  gap: 4px;
  padding: 5px;
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  margin-bottom: var(--sp-6);
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.segmented::-webkit-scrollbar { display: none; }
.segmented-btn {
  border: none;
  background: transparent;
  color: var(--ink-2);
  font-weight: 600;
  font-size: var(--step--1);
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  cursor: pointer;
  min-height: 42px;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.segmented-btn.active { background: var(--surface); color: var(--brand); box-shadow: var(--shadow-sm); }
.segmented-count { opacity: 0.55; font-weight: 600; margin-left: 0.2rem; }

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(220px, 45%), 1fr));
  gap: var(--sp-3);
}
.gallery-item {
  position: relative;
  border: none; padding: 0;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  cursor: zoom-in;
  background: var(--surface-3);
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.45s var(--ease); }
.gallery-item:hover img { transform: scale(1.06); }
.gallery-zoom {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(20,16,28,0.42);
  color: #fff; font-size: 1.3rem;
  opacity: 0; transition: opacity 0.25s var(--ease);
}
.gallery-item:hover .gallery-zoom, .gallery-item:focus-visible .gallery-zoom { opacity: 1; }

.lightbox-img { width: 100%; height: auto; border-radius: var(--radius); box-shadow: var(--shadow-lg); }
.lightbox-close {
  position: absolute; top: -52px; right: 0;
  width: 44px; height: 44px; border: none; border-radius: 50%;
  background: rgba(255,255,255,0.16); color: #fff; font-size: 1.1rem; cursor: pointer;
}
.lightbox-close:hover { background: rgba(255,255,255,0.28); }

/* ---------- CTA band ---------- */
.cta-band {
  background: linear-gradient(135deg, var(--brand-700), var(--brand) 55%, #7a1fc0);
  color: #fff;
  padding-block: var(--sp-8);
}
.cta-inner { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-6); flex-wrap: wrap; }
.cta-band h2 { color: #fff; margin: 0 0 var(--sp-2); }
.cta-band p { color: rgba(255,255,255,0.82); margin: 0; }
.cta-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
@media (max-width: 640px) {
  .cta-actions { width: 100%; }
  .cta-actions > * { flex: 1 1 100%; }
}

/* ==========================================================================
   PAGE HERO (About / Contact) + ABOUT CONTENT
   The About page was a stack of near-identical grey/white bands with
   ALL-CAPS h3s and a five-item accordion. Same content, given hierarchy.
   ========================================================================== */
.page-hero {
  padding-block: var(--sp-7);
  background:
    radial-gradient(1000px 400px at 15% -10%, rgba(255,140,0,0.10), transparent 60%),
    linear-gradient(170deg, var(--brand-50), var(--surface));
  border-bottom: 1px solid var(--line);
}
/* The nav is fixed, so every page without a hero behind it must reserve its
   height. This is set once on <main> rather than on "the first child", which
   is what broke before: /news/ opens with a <header> and an article with an
   <article>, so a `main > section:first-child` rule matched neither and the
   nav sat on top of the text. */
body:not(.has-hero) main { padding-top: var(--nav-h); }

/* Anchor targets must clear the fixed nav too, or /about/#programmes lands
   with its heading underneath it. */
:target, [id] { scroll-margin-top: calc(var(--nav-h) + var(--sp-4)); }

.about-h {
  font-family: "Sora", sans-serif;
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
  margin-bottom: var(--sp-4);
  position: relative;
  padding-bottom: var(--sp-3);
}
.about-h::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 44px; height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, var(--accent), var(--brand-300));
}
.about-h.text-center { text-align: center; }
.about-h.text-center::after { left: 50%; transform: translateX(-50%); }

/* Portraits, restored from the pre-redesign rules.
   A centred 4:3 crop beheads a tall portrait, which is exactly what the
   original CSS avoided: it defaulted to object-position:top so faces stay in
   frame, with a per-image nudge where the subject sits lower. The redesign
   dropped both, and the proprietress image also still carried the old
   .about-img class whose stylesheet is no longer loaded — so it had no rules
   at all. Portrait framing is per-photo; there is no one-size crop. */
.about-media {
  width: 100%;
  height: 400px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  object-fit: cover;
  object-position: top;   /* keeps heads in frame by default */
  display: block;
}
.about-media.portrait-lower { object-position: 0% 37%; }
.about-media.portrait-centre { object-position: center; }

@media (max-width: 767px) {
  /* A fixed 400px is very tall next to a phone-width column. */
  .about-media { height: clamp(240px, 62vw, 360px); }
}

/* Accordion: Bootstrap's default is a boxy grey stack. */
.accordion { --bs-accordion-border-color: var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.accordion-item { border-color: var(--line); background: var(--surface); }
.accordion-button {
  font-family: "Sora", sans-serif;
  font-weight: 650;
  font-size: var(--step-0);
  color: var(--ink);
  padding: 1.15rem 1.25rem;
  background: var(--surface);
}
.accordion-button:not(.collapsed) { background: var(--brand-50); color: var(--brand); box-shadow: none; }
.accordion-button:focus { box-shadow: 0 0 0 3px rgba(89,6,148,0.14); border-color: transparent; }
.accordion-body { padding: 0 1.25rem 1.35rem; }
.accordion-body ul { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(210px,100%),1fr)); gap: 0.35rem 1.25rem; margin: 0; }
.accordion-body li { display: flex; align-items: center; gap: 0.55rem; color: var(--ink-2); padding: 0.3rem 0; }
.accordion-body li i { color: var(--accent); flex-shrink: 0; }

/* Contact */
.contact-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
  box-shadow: var(--shadow-sm);
}
.form-control, .form-select {
  border-radius: 12px;
  border-color: var(--line);
  padding: 0.75rem 0.95rem;
  font-size: 1rem;
  min-height: 48px;
}
.form-control:focus, .form-select:focus {
  border-color: var(--brand-300);
  box-shadow: 0 0 0 4px rgba(89, 6, 148, 0.1);
}
.form-label { font-weight: 600; color: var(--ink); margin-bottom: 0.4rem; }

/* Bootstrap leftovers that would otherwise fight the new system */
.bg-light { background: var(--surface-2) !important; }
.text-muted { color: var(--muted) !important; }

/* ==========================================================================
   RESPONSIVE CORRECTIONS (measured, not guessed)
   ========================================================================== */

/* Bootstrap .row applies negative inline margins of half its gutter. With
   g-5 (3rem) that is -24px a side, against only 16px of container padding —
   so every .row inside our containers hung 8px past the screen. Our
   containers already provide the outer rhythm, so drop the pull-back. */
.container-wide > .row,
.container-narrow > .row,
.container-wide .contact-card .row { margin-inline: 0; }

/* Grid/flex children must be allowed to shrink; otherwise their content's
   min-content width becomes a floor and the track overflows. */
.footer-grid > *,
.news-lead > *,
.pillar-grid > *,
.news-grid > * { min-width: 0; }

.footer-contact li span { min-width: 0; overflow-wrap: break-word; }
.site-footer a { overflow-wrap: break-word; }

/* Long unbroken strings (emails, URLs) wrap at a sensible point rather than
   setting the layout width — but never mid-word for ordinary prose. */
.footer-contact, .prose, .news-excerpt, .section-lede {
  overflow-wrap: break-word;
  word-break: normal;
}

/* The contact <li>s are grid items containing an icon plus an unbroken
   email/phone string, so they needed the shrink permission too. */
.footer-contact li { min-width: 0; }
.footer-contact li span, .footer-contact li a { min-width: 0; overflow-wrap: anywhere; }

/* A chip in a flex column would otherwise stretch to the full column width. */
.news-lead-body .chip, .post-header .chip { align-self: flex-start; }
.post-header .chip { display: inline-block; }


/* ==========================================================================
   TOUCH TARGETS
   The 85% root shrinks rem-based controls with everything else, which would
   drop a 46px button to ~39px — under the 44px minimum that makes a tap
   reliable. On coarse pointers the interactive minimums are restored in px so
   they stay physically the same size while the type around them stays compact.
   ========================================================================== */
@media (pointer: coarse) {
  .btn-primary-solid, .btn-ghost, .footer-portal-btn { min-height: 44px; }
  .nav-panel a.panel-link { min-height: 52px; }
  .nav-toggle, .nav-panel-close, .footer-socials a, .lightbox-close { min-width: 44px; min-height: 44px; }
  .segmented-btn { min-height: 40px; }
}

/* ==========================================================================
   SCROLL REVEAL + MOTION POLISH

   CSS-first: elements start in their revealed state and are only hidden once
   JS confirms IntersectionObserver support (html.js-reveal). If the script
   fails or is blocked, every section is simply visible — content is never
   trapped behind an animation that never runs.

   Replaces the data-aos attributes that were on about/contact without the AOS
   library ever being loaded, so none of them had been animating at all.
   ========================================================================== */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.55s cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity, transform;
}
.js-reveal .reveal.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Directional variants */
.js-reveal .reveal-left  { transform: translateX(-22px); }
.js-reveal .reveal-right { transform: translateX(22px); }
.js-reveal .reveal-zoom  { transform: scale(0.965); }
.js-reveal .reveal-left.is-in,
.js-reveal .reveal-right.is-in,
.js-reveal .reveal-zoom.is-in { transform: none; }

/* Children stagger in sequence — set on a grid wrapper. Capped at 8 so a long
   gallery never leaves the last tiles waiting a second and a half. */
.js-reveal .reveal-stagger > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.js-reveal .reveal-stagger.is-in > * { opacity: 1; transform: none; }
.js-reveal .reveal-stagger.is-in > *:nth-child(1) { transition-delay: 0ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(2) { transition-delay: 70ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(3) { transition-delay: 140ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(4) { transition-delay: 210ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(5) { transition-delay: 280ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(6) { transition-delay: 350ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(7) { transition-delay: 420ms; }
.js-reveal .reveal-stagger.is-in > *:nth-child(n+8) { transition-delay: 490ms; }

/* Page-load settle: only the first screenful, so navigation feels immediate. */
@keyframes pageIn { from { opacity: 0; } to { opacity: 1; } }
body { animation: pageIn 0.35s var(--ease) both; }

/* ---------- Hover depth ---------- */
.pillar { transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease); }
.pillar:hover { transform: translateY(-4px); box-shadow: 0 16px 38px rgba(89,6,148,0.12); }
.pillar-icon { transition: transform 0.3s var(--ease); }
.pillar:hover .pillar-icon { transform: scale(1.08) rotate(-4deg); }

.news-card:hover .news-readmore i { transform: translateX(4px); }
.gallery-item { transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease); }
.gallery-item:hover { transform: translateY(-3px); box-shadow: 0 14px 32px rgba(15,23,42,0.16); }

/* Visible keyboard focus — was relying on the browser default. */
a:focus-visible, button:focus-visible, .btn-primary-solid:focus-visible, .btn-ghost:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ==========================================================================
   REDUCED MOTION
   One global switch. Previously only the hero honoured this.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal,
  .js-reveal .reveal-stagger > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  body { animation: none; }
  .pillar:hover,
  .gallery-item:hover { transform: none; }
  .pillar:hover .pillar-icon { transform: none; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   PATHWAY — the KG-to-SSS route on the homepage.

   A single connected band rather than five stacked cards: it stays one row
   tall on desktop, reads as a progression rather than a menu, and keeps the
   homepage from turning into a column of boxes.
   ========================================================================== */
.pathway {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--sp-4);
  position: relative;
}

/* The rail the steps sit on. Drawn behind the dots, stopping short at each
   end so it never dangles past the first and last step. */
.pathway::before {
  content: "";
  position: absolute;
  top: 27px;
  left: 10%;
  right: 10%;
  height: 2px;
  background: linear-gradient(90deg,
    var(--brand) 0%, var(--sky) 45%, var(--accent) 100%);
  opacity: 0.35;
  z-index: 0;
}

.pathway-step {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 0 0.35rem;
}

.pathway-dot {
  width: 54px;
  height: 54px;
  margin: 0 auto 0.9rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  color: var(--brand);
  background: #fff;
  border: 2px solid rgba(89, 6, 148, 0.18);
  box-shadow: 0 6px 18px rgba(89, 6, 148, 0.10);
  transition: transform 0.28s var(--ease), box-shadow 0.28s var(--ease),
              border-color 0.28s var(--ease), color 0.28s var(--ease);
}
.pathway-step:hover .pathway-dot {
  transform: translateY(-5px) scale(1.06);
  border-color: var(--brand);
  box-shadow: 0 14px 30px rgba(89, 6, 148, 0.22);
}
.pathway-step.is-final .pathway-dot {
  color: #fff;
  background: linear-gradient(135deg, var(--brand), #2a0450);
  border-color: transparent;
}

.pathway-step h3 {
  font-family: "Sora", sans-serif;
  font-size: 0.98rem;
  font-weight: 700;
  margin: 0 0 0.35rem;
  color: var(--ink);
}
.pathway-step p {
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--muted);
  margin: 0;
}

.pathway-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: var(--sp-6) auto 0;
  max-width: 62ch;
  text-align: center;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--ink-2, var(--muted));
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--line, rgba(0,0,0,0.07));
  border-radius: 14px;
  padding: 0.85rem 1.25rem;
}
.pathway-note i { color: #1a7f42; font-size: 1.05rem; flex: none; }

/* Tablet: two rows of steps, rail removed so it cannot cut between rows. */
@media (max-width: 900px) {
  .pathway { grid-template-columns: repeat(3, 1fr); gap: var(--sp-5) var(--sp-4); }
  .pathway::before { display: none; }
}

/* Phone: a vertical run with the rail on the left, which reads better than
   three cramped columns and keeps text at a comfortable measure. */
@media (max-width: 620px) {
  .pathway { grid-template-columns: 1fr; gap: var(--sp-4); }
  .pathway-step {
    display: grid;
    grid-template-columns: 54px 1fr;
    gap: 0 14px;
    text-align: left;
    align-items: start;
  }
  .pathway-dot { margin: 0; }
  .pathway-step h3 { grid-column: 2; margin-top: 0.35rem; }
  .pathway-step p { grid-column: 2; }
  .pathway-note { text-align: left; }
}

/* ---------- Contact: campus blocks ---------- */
.campus { margin-bottom: var(--sp-4); }
.campus-name {
  display: flex; align-items: center; gap: 7px;
  font-family: "Sora", sans-serif; font-weight: 700;
  font-size: 0.88rem; color: var(--brand);
  margin-bottom: 0.2rem;
}
.campus p { margin: 0; font-size: 0.88rem; line-height: 1.55; color: var(--muted); }
.campus-rule { border: 0; border-top: 1px solid rgba(0,0,0,0.08); margin: var(--sp-5) 0 var(--sp-4); }
