/* =========================================================================
   WELS School — main stylesheet
   Colour / shape tokens are injected as CSS variables from the Customizer
   (see inc/dynamic-css.php). Fallback values below keep the theme usable
   even before the plugin/customizer run.
   ========================================================================= */

:root {
	--wels-primary: #1f5f5b;
	--wels-primary-dark: #164542;
	--wels-accent: #e8792b;
	--wels-ink: #1e2a2a;
	--wels-muted: #5b6b6a;
	--wels-bg: #ffffff;
	--wels-alt-bg: #f4f1ea;
	--wels-header-bg: #ffffff;
	--wels-topbar-bg: #164542;
	--wels-footer-bg: #12211f;
	--wels-radius: 14px;
	--wels-btn-radius: 14px;
	--wels-base-size: 16px;
	--wels-heading-font: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	/*
	 * Body copy stays on the plain system font by default — even when a
	 * Google Font is configured for headings (--wels-gfont) — so paragraph
	 * text, nav, and dense data tables (faculty list, CBSE disclosure) stay
	 * easy to scan at small sizes. A display/serif face dresses up h1–h6
	 * only. inc/dynamic-css.php only ever overrides --wels-heading-font.
	 */
	--wels-body-font: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	/*
	 * Type scale. One set of heading sizes for the whole site, so the same
	 * kind of heading is the same size on every page. Components point at
	 * these rather than each picking their own — which is how six different
	 * section-heading sizes got into the site one component at a time.
	 *
	 *   h1  page titles and banners
	 *   h2  section headings — the level most pages use
	 *   h3  sub-headings, and titles inside a band
	 *   h4  small labels
	 */
	--wels-h1: clamp(1.9rem, 4.2vw, 2.7rem);
	--wels-h2: clamp(1.5rem, 3vw, 2.05rem);
	--wels-h3: clamp(1.15rem, 2.2vw, 1.45rem);
	--wels-h4: 1.05rem;
	/*
	 * Bands. The alternating photo-and-text pattern appears in three places
	 * built at three different times — Facilities, the leadership messages,
	 * Our Founder, Transport — and each had picked its own column split,
	 * gap, photo shape and shadow. They share these now, so the pattern
	 * reads as one thing wherever it turns up.
	 *
	 * Two differences are kept on purpose: a portrait of a person stays 4:5
	 * rather than 4:3, and a full-width tinted section keeps its tint. Those
	 * are decisions; the rest was drift.
	 */
	--wels-band-media: minmax(0, 44%);
	--wels-band-gap: clamp(24px, 4vw, 52px);
	--wels-band-rhythm: clamp(32px, 5vw, 56px);
	--wels-band-ratio: 4 / 3;
	--wels-band-shadow: 0 14px 34px rgba(20, 40, 38, 0.14);
	--wels-maxw: 1180px;
	--wels-shadow: 0 6px 24px rgba(20, 40, 38, 0.10);
	--wels-shadow-sm: 0 2px 10px rgba(20, 40, 38, 0.08);
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
	margin: 0;
	font-family: var(--wels-body-font);
	font-size: var(--wels-base-size);
	line-height: 1.65;
	color: var(--wels-ink);
	background: var(--wels-bg);
	-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--wels-primary); text-decoration: none; }
a:hover, a:focus { color: var(--wels-primary-dark); text-decoration: underline; }
h1, h2, h3, h4, h5, h6 { font-family: var(--wels-heading-font); line-height: 1.2; color: var(--wels-ink); font-weight: 700; letter-spacing: -0.01em; }

:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: 2px; }

.screen-reader-text {
	position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.wels-skip-link:focus {
	position: fixed; left: 12px; top: 12px; z-index: 1000; width: auto; height: auto;
	clip: auto; padding: 10px 16px; background: #fff; color: var(--wels-primary); border-radius: 8px;
}

.wels-container { max-width: var(--wels-maxw); margin: 0 auto; padding-left: 20px; padding-right: 20px; }

/* ---------- Buttons ---------- */
.wels-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 8px;
	padding: 12px 22px; border-radius: var(--wels-btn-radius); border: 2px solid transparent;
	font-weight: 600; font-size: 0.95rem; line-height: 1; cursor: pointer;
	text-decoration: none; transition: transform .15s ease, background .15s ease, color .15s ease, box-shadow .15s ease;
}
.wels-btn:hover, .wels-btn:focus { text-decoration: none; transform: translateY(-1px); }
.wels-btn-primary { background: var(--wels-primary); color: #fff; }
.wels-btn-primary:hover, .wels-btn-primary:focus { background: var(--wels-primary-dark); color: #fff; }
.wels-btn-accent { background: var(--wels-accent); color: var(--wels-accent-ink, #fff); }
.wels-btn-accent:hover, .wels-btn-accent:focus { filter: brightness(0.93); color: var(--wels-accent-ink, #fff); }
.wels-btn-outline { background: transparent; color: var(--wels-primary); border-color: var(--wels-primary); }
.wels-btn-outline:hover, .wels-btn-outline:focus { background: var(--wels-primary); color: #fff; }
.wels-btn-ghost { background: rgba(255,255,255,.14); color: #fff; border-color: rgba(255,255,255,.4); }
.wels-btn-ghost:hover, .wels-btn-ghost:focus { background: rgba(255,255,255,.25); color: #fff; }
.wels-btn-link { background: none; border: 0; color: var(--wels-primary); padding: 6px 2px; font-weight: 600; }
.wels-btn-link:hover, .wels-btn-link:focus { text-decoration: underline; }
.wels-btn-sm { padding: 8px 14px; font-size: 0.85rem; }
.wels-link { font-weight: 600; }

/* ---------- Sections ---------- */
.wels-section { padding: clamp(44px, 7vw, 84px) 0; background: var(--wels-bg); position: relative; }
/* Explicit alternating backgrounds (order-independent) */
.wels-journey, .wels-facilities, .wels-kg, .wels-faculty, .wels-notices, .wels-downloads, .wels-contact { background: var(--wels-alt-bg); }
.wels-stats, .wels-payfee { background: var(--wels-primary); }
.wels-section-head { max-width: 720px; margin: 0 auto clamp(28px, 4vw, 48px); text-align: center; }
.wels-section-title { font-size: var(--wels-h2); margin: 0 0 .3em; position: relative; }
.wels-section-title::after { content: ""; display: block; width: 56px; height: 4px; background: var(--wels-accent); border-radius: 3px; margin: 14px auto 0; }
.wels-section-sub { color: var(--wels-muted); margin: 0; font-size: 1.05rem; }
.wels-section-cta { text-align: center; margin-top: clamp(24px, 4vw, 40px); }

/* ---------- Top bar ---------- */
/* The ink colour is worked out from the bar's own background — see
   inc/dynamic-css.php — so a white bar gets purple text and a dark one
   white, without either being hardcoded here. */
.wels-topbar {
	background: var(--wels-topbar-bg);
	color: var(--wels-topbar-ink, #fff);
	font-size: 0.85rem;
	border-bottom: 1px solid color-mix(in srgb, var(--wels-topbar-ink, #fff) 14%, transparent);
}
.wels-topbar a { color: inherit; }
.wels-topbar a:hover { color: inherit; opacity: .72; text-decoration: none; }
.wels-topbar-inner { display: flex; flex-wrap: wrap; gap: 4px 22px; align-items: center; justify-content: space-between; padding-top: 8px; padding-bottom: 8px; }
/* Equal side groups are what centre the middle one. */
.wels-topbar-left { flex: 1 1 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 22px; }
/*
 * Nothing but the pill lives here, so this group is exactly as wide as the
 * pill and lands dead centre of the bar, under the crest. The phone number
 * sits over in the right-hand group beside the social icons.
 */
.wels-topbar-centre {
	flex: 0 0 auto;
	list-style: none; margin: 0; padding: 0;
	display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px;
}
.wels-topbar-phone { white-space: nowrap; }
.wels-topbar-email { display: inline-flex; align-items: center; gap: 6px; }
/* One icon, then each number as its own dialable link. */
.wels-topbar-phone { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.wels-topbar-sep { opacity: .5; font-weight: 400; }
.wels-topbar-icon { width: 16px; height: 16px; flex: 0 0 16px; }
.wels-topbar-right { flex: 1 1 0; list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 20px; align-items: center; justify-content: flex-end; }
.wels-topbar-right li { display: inline-flex; align-items: center; gap: 6px; }
.wels-topbar-right .dashicons { font-size: 16px; width: 16px; height: 16px; }
.wels-topbar-aff { font-weight: 600; letter-spacing: .02em; }
.wels-topbar-link a { opacity: .85; }
.wels-topbar-social { display: inline-flex; }
.wels-topbar-social .wels-social-row { gap: 8px; }
.wels-topbar-social .wels-social {
	width: 24px; height: 24px;
	background: color-mix(in srgb, var(--wels-topbar-ink, #fff) 13%, transparent);
	color: var(--wels-topbar-ink, #fff);
}
.wels-topbar-social .wels-social svg { width: 14px; height: 14px; }
.wels-topbar-social .wels-social:hover, .wels-topbar-social .wels-social:focus {
	background: color-mix(in srgb, var(--wels-topbar-ink, #fff) 24%, transparent);
	color: var(--wels-topbar-ink, #fff);
	opacity: 1;
}

/* ---------- Header (two-tier: brand strip + nav bar) ---------- */
.wels-site-header { background: var(--wels-header-bg); position: sticky; top: 0; z-index: 200; box-shadow: 0 1px 0 rgba(20,40,38,.08); transition: box-shadow .25s ease; }
.wels-site-header.is-shrunk { box-shadow: var(--wels-shadow); }

/* The compact state changes this header's HEIGHT, and the header is sticky
   and in the document flow — so its height is the page's top offset. Animating
   it over a quarter of a second therefore animates the position of everything
   below it: for 15 frames the content slides upward while the reader is also
   scrolling it, which feels exactly like the page stuttering or snagging.
   One frame is better than fifteen here. The padding and the logo change
   instantly; only the shadow fades, because a shadow costs no layout. */
.wels-header-inner { display: flex; align-items: center; gap: 20px 28px; padding-top: 16px; padding-bottom: 16px; }
.wels-site-header.is-shrunk .wels-header-inner { padding-top: 9px; padding-bottom: 9px; }

.wels-branding { display: flex; align-items: center; gap: 14px; min-width: 0; }
.wels-branding .custom-logo-link { display: inline-flex; flex: 0 0 auto; line-height: 0; }
/* No transition here either, and for the same reason as the padding above: the
   crest's box is part of the header's height. A site that sizes the crest by
   WIDTH in Additional CSS — which is how it is actually done, see the note on
   this rule in the project files — got a worse version of the fault, because
   the width snapped while the padding animated and the two disagreed for a
   quarter second. */
.wels-branding .custom-logo { width: auto; height: 60px; max-width: 260px; object-fit: contain; }
.wels-site-header.is-shrunk .wels-branding .custom-logo { height: 44px; }
.wels-branding-text { display: flex; flex-direction: column; min-width: 0; }
.wels-site-name { font-family: Georgia, 'Times New Roman', serif; font-weight: 700; font-size: clamp(1.4rem, 2.3vw, 1.9rem); color: var(--wels-primary); letter-spacing: .025em; line-height: 1.18; font-variant: small-caps; text-wrap: balance; }
a.wels-site-name:hover { text-decoration: none; color: var(--wels-primary); }
.wels-site-sub { font-size: 0.8rem; color: var(--wels-muted); letter-spacing: .035em; margin-top: .3rem; }
@media(max-width:600px) { .wels-site-name { font-size:1.18rem; letter-spacing:.01em; line-height:1.16; } .wels-site-sub { font-size:.7rem; letter-spacing:.015em; } }

.wels-header-right { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.wels-branding { margin-right: auto; }

/* ---- Header layout: two rows (stacked) ---- */
.wels-header-stacked .wels-header-inner { flex-wrap: wrap; }
.wels-header-stacked .wels-branding { margin-right: auto; }
.wels-header-stacked .wels-primary-nav {
	order: 3; flex-basis: 100%;
	margin: 12px -20px -16px; padding: 0 20px;
	border-top: 1px solid rgba(20,40,38,.08);
}
.wels-header-stacked.is-shrunk .wels-primary-nav { margin-top: 6px; margin-bottom: -9px; }
.wels-header-stacked .wels-primary-nav { justify-content: flex-start; }
.wels-header-stacked.wels-nav-center .wels-primary-nav { justify-content: center; }
.wels-header-stacked.wels-nav-right  .wels-primary-nav { justify-content: flex-end; }

/* ---- Header layout: single row (inline) ---- */
.wels-header-inline .wels-primary-nav { margin-left: auto; }
.wels-header-inline .wels-header-right { margin-left: 0; }
.wels-header-inline .wels-menu > .wels-menu-item > a { padding: 12px 14px; }

.wels-site-header.is-shrunk .wels-menu > .wels-menu-item > a { padding-top: 11px; padding-bottom: 11px; }
.wels-primary-nav { display: flex; }
.wels-menu { list-style: none; margin: 0; padding: 0; display: flex; align-items: stretch; flex-wrap: wrap; gap: 0; }
.wels-menu > .wels-menu-item > a { padding: 15px 16px; }
.wels-menu a {
	display: flex; align-items: center; gap: 6px; padding: 12px 16px;
	color: var(--wels-ink); font-weight: 600; font-size: 0.94rem; border-radius: 8px;
	position: relative; transition: color .18s ease, background .18s ease;
}
.wels-menu > .wels-menu-item > a::after {
	content: ""; position: absolute; left: 16px; right: 16px; bottom: 6px; height: 2px;
	background: var(--wels-accent); border-radius: 2px; transform: scaleX(0); transform-origin: left;
	transition: transform .22s ease;
}
.wels-menu > .wels-menu-item > a:hover::after,
.wels-menu > .wels-menu-item.current-menu-item > a::after,
.wels-menu > .wels-menu-item.current-menu-ancestor > a::after { transform: scaleX(1); }
.wels-menu a:hover, .wels-menu .current-menu-item > a, .wels-menu .current-menu-ancestor > a { color: var(--wels-primary); text-decoration: none; }
.wels-menu-item { position: relative; }
.wels-sub-menu {
	list-style: none; margin: 0; padding: 8px; position: absolute; left: 0; top: 100%;
	min-width: 230px; background: #fff; border-radius: 12px; box-shadow: var(--wels-shadow);
	opacity: 0; visibility: hidden; transform: translateY(10px); transition: opacity .2s ease, transform .2s ease, visibility .2s; z-index: 50;
	border: 1px solid rgba(20,40,38,.06);
}
.wels-sub-menu .wels-sub-menu { left: 100%; top: -9px; }
.wels-menu-item:hover > .wels-sub-menu, .wels-menu-item:focus-within > .wels-sub-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.wels-sub-menu a { padding: 10px 12px; font-weight: 500; border-radius: 7px; }
.wels-sub-menu a:hover { background: rgba(31,95,91,.08); }
.wels-submenu-toggle { display: none; }

.wels-caret { display: inline-block; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); margin-top: -3px; opacity: .6; }

.wels-header-actions { display: flex; align-items: center; gap: 10px; }
.wels-header-actions-header .wels-btn { padding: 9px 16px; font-size: 0.85rem; }
.wels-header-actions-mobile { flex-direction: column; align-items: stretch; margin-top: 20px; }
.wels-header-actions-mobile .wels-btn { width: 100%; }

/* ---------- Mobile nav toggle ---------- */
.wels-nav-toggle {
	display: none; width: 44px; height: 44px; border: 0; background: transparent; cursor: pointer;
	position: relative; border-radius: 8px; margin-left: auto;
}
.wels-nav-toggle-bar, .wels-nav-toggle-bar::before, .wels-nav-toggle-bar::after {
	content: ""; position: absolute; left: 10px; width: 24px; height: 2px; background: var(--wels-ink); transition: .2s ease;
}
.wels-nav-toggle-bar { top: 21px; }
.wels-nav-toggle-bar::before { top: -7px; }
.wels-nav-toggle-bar::after { top: 7px; }
body.wels-nav-open .wels-nav-toggle-bar { background: transparent; }
body.wels-nav-open .wels-nav-toggle-bar::before { top: 0; transform: rotate(45deg); }
body.wels-nav-open .wels-nav-toggle-bar::after { top: 0; transform: rotate(-45deg); }

/* ---------- Mobile off-canvas ---------- */
.wels-mobile-nav { position: fixed; inset: 0; z-index: 300; visibility: hidden; }
.wels-mobile-nav.is-open { visibility: visible; }
.wels-mobile-nav-overlay { position: absolute; inset: 0; background: rgba(10,20,19,.5); opacity: 0; transition: opacity .25s ease; }
.wels-mobile-nav.is-open .wels-mobile-nav-overlay { opacity: 1; }
.wels-mobile-nav-panel {
	position: absolute; top: 0; right: 0; height: 100%; width: min(86vw, 360px);
	background: #fff; padding: 64px 22px 40px; overflow-y: auto;
	transform: translateX(100%); transition: transform .28s ease; box-shadow: -12px 0 40px rgba(0,0,0,.18);
	z-index: 1;
}
.wels-mobile-nav.is-open .wels-mobile-nav-panel { transform: translateX(0); }
.wels-mobile-close { position: absolute; top: 14px; right: 16px; width: 40px; height: 40px; border: 0; background: #f1f1f1; border-radius: 50%; font-size: 24px; line-height: 1; cursor: pointer; }
.wels-menu-mobile { flex-direction: column; align-items: stretch; gap: 0; }
.wels-menu-mobile .wels-menu-item { border-bottom: 1px solid #eee; }
.wels-menu-mobile a { padding: 14px 6px; font-size: 1rem; }
.wels-menu-mobile .wels-sub-menu {
	position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none;
	padding: 0 0 8px 16px; min-width: 0; display: none;
}
.wels-menu-mobile .wels-menu-item.is-expanded > .wels-sub-menu { display: block; }
.wels-menu-mobile .wels-submenu-toggle {
	display: block; position: absolute; right: 0; top: 6px; width: 40px; height: 40px;
	background: transparent; border: 0; cursor: pointer; color: var(--wels-ink);
}
.wels-menu-mobile .wels-menu-item.is-expanded > .wels-submenu-toggle .wels-caret { transform: rotate(-135deg); margin-top: 2px; }

/* ---------- Hero slider ---------- */
.wels-hero { position: relative; overflow: hidden; background: #0c1a19; }
.wels-hero-track { position: relative; height: clamp(360px, 60vh, 620px); }

/* Hero height, chosen per site in Customize > School Website Design >
   Header & Layout > "Homepage hero height". The rule above is "Standard" and
   stays the default, so a site that never touches the control is unchanged.

   Each size is a clamp of (floor, share of the viewport, ceiling) rather than
   one pixel number, because the same hero has to be shorter on a phone held
   upright than on a wide monitor or it swallows the screen. The floor keeps
   it from collapsing into a strip; the ceiling keeps it from becoming a
   billboard on a very tall display.

   Height is not only a matter of taste here. background-size: cover makes a
   wide shallow band crop the top and bottom off any normal photograph — at
   1479px wide a 3:2 picture needs 986px of height to show whole, so the
   shorter the band, the more of the picture is thrown away. Taller shows more
   of what was photographed, not just more of the screen. */
body.wels-hero-h-compact .wels-hero-track { height: clamp(300px, 48vh, 520px); }
body.wels-hero-h-tall    .wels-hero-track { height: clamp(420px, 72vh, 780px); }

/* "Fills the screen": everything below the header, less a deliberate strip so
   the top of the next section still peeks and the page reads as scrollable.
   svh (the SMALL viewport height) is the one that ignores a mobile browser's
   retractable address bar — with plain vh the hero jumps taller the moment
   the bar hides. The vh line first is the fallback for anything that has not
   heard of svh; browsers that have simply use the second. */
body.wels-hero-h-screen .wels-hero-track { height: clamp(420px, calc(100vh - 260px), 860px); }
body.wels-hero-h-screen .wels-hero-track { height: clamp(420px, calc(100svh - 260px), 860px); }

/* A short viewport is a phone turned sideways, or a laptop with a lot of
   browser chrome. There the floors above are taller than the screen itself and
   the hero becomes the whole page, so the floor is dropped and the hero is told
   to take a share of what there is instead. */
@media (max-height: 560px) {
	body.wels-hero-h-tall .wels-hero-track,
	body.wels-hero-h-screen .wels-hero-track { height: 76vh; min-height: 240px; }
}

/* The curved divider is opt-out per site; see the rule that draws it below. */
.wels-slide {
	position: absolute; inset: 0; background-size: cover; background-position: center;
	opacity: 0; transition: opacity .7s ease; display: flex; align-items: flex-end;
}
.wels-slide.is-active { opacity: 1; }
.wels-slide::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(8,18,17,0) 30%, rgba(8,18,17,.72) 100%); }
.wels-slide-caption { position: relative; z-index: 2; width: 100%; padding-bottom: clamp(44px, 7vw, 84px); color: #fff; }
.wels-slide-caption h2 { color: #fff; font-size: clamp(1.7rem, 4.6vw, 3.1rem); margin: 0 0 .35em; max-width: 20ch; text-shadow: 0 2px 24px rgba(0,0,0,.4); line-height: 1.12; }
.wels-slide-caption p { font-size: clamp(1rem, 2vw, 1.28rem); max-width: 48ch; margin: 0 0 1.3em; opacity: 0; transform: translateY(16px); transition: opacity .6s ease .35s, transform .6s ease .35s; }
.wels-slide-caption .wels-btn { opacity: 0; transform: translateY(16px); transition: opacity .6s ease .5s, transform .6s ease .5s; }
.wels-slide.is-active .wels-slide-caption p,
.wels-slide.is-active .wels-slide-caption .wels-btn { opacity: 1; transform: none; }

/* Headline word-by-word reveal */
.wels-slide-caption h2 .wels-word {
	display: inline-block; opacity: 0; transform: translateY(28px) rotate(1.5deg);
	transition: opacity .5s cubic-bezier(.2,.7,.2,1), transform .5s cubic-bezier(.2,.7,.2,1);
}
.wels-slide.is-active .wels-slide-caption h2 .wels-word { opacity: 1; transform: none; }

/* Autoplay progress bar */
.wels-hero-progress { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255,255,255,.18); z-index: 3; }
.wels-hero-progress-bar { display: block; height: 100%; background: var(--wels-accent); transform: scaleX(0); transform-origin: left; }
.wels-hero-progress-bar.is-running { animation: wels-hero-progress var(--wels-hero-int, 6000ms) linear forwards; }
.wels-hero.is-paused .wels-hero-progress-bar.is-running { animation-play-state: paused; }
@keyframes wels-hero-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Curved divider where the hero meets the page.

   It is 54px of page colour painted OVER the photograph, not a gap below it,
   so it costs the picture that much height in the middle and crowds whatever
   the caption puts near the foot. Worth it on a tall hero, not on a short
   one. Switched off per site with the "Curved divider under the hero"
   checkbox, which adds .wels-hero-nocurve. */
.wels-hero::after {
	content: ""; position: absolute; left: -4%; right: -4%; bottom: -1px; height: 54px; z-index: 4;
	background: var(--wels-bg);
	border-radius: 50% 50% 0 0 / 100% 100% 0 0;
	pointer-events: none;
}
body.wels-hero-nocurve .wels-hero::after { display: none; }
.wels-hero-nav {
	position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
	width: 48px; height: 48px; border: 0; border-radius: 50%; background: rgba(255,255,255,.22);
	color: #fff; font-size: 26px; line-height: 1; cursor: pointer; backdrop-filter: blur(3px);
}
.wels-hero-nav:hover { background: rgba(255,255,255,.4); }
.wels-hero-prev { left: 16px; }
.wels-hero-next { right: 16px; }
.wels-hero-dots { position: absolute; left: 0; right: 0; bottom: 14px; z-index: 3; display: flex; justify-content: center; gap: 8px; }
.wels-hero-dot { width: 10px; height: 10px; border-radius: 50%; border: 0; background: rgba(255,255,255,.45); cursor: pointer; padding: 0; }
.wels-hero-dot.is-active { background: #fff; width: 26px; border-radius: 6px; }

/* ---------- Hero: split-panel layout ----------
   Selected per site in Customize > School Website Design > Header & Layout.
   The plugin's slider markup is unchanged; only its arrangement differs, so
   two schools built on this theme do not arrive with the same front page.
   The coloured panel is the slide's own ::after, re-shaped from a bottom
   scrim into a side panel. The crest badge is added by inc/dynamic-css.php,
   but only when the site actually has a logo. */
body.wels-hero-split .wels-hero { background: var(--wels-primary-dark); }
body.wels-hero-split .wels-hero-track { height: clamp(400px, 62vh, 600px); }
body.wels-hero-split .wels-slide { align-items: stretch; background-position: 74% center; }
body.wels-hero-split .wels-slide::after {
	right: auto; width: 46%;
	background: linear-gradient(165deg, var(--wels-primary) 0%, var(--wels-primary-dark) 100%);
}
body.wels-hero-split .wels-slide-caption {
	width: 46%; display: flex; align-items: center;
	padding: clamp(28px, 4vw, 52px) 0;
}
body.wels-hero-split .wels-slide-caption .wels-container {
	max-width: none; width: 100%;
	padding-left: clamp(26px, 4.4vw, 62px); padding-right: clamp(22px, 3vw, 44px);
}
body.wels-hero-split .wels-slide-caption h2 { font-size: clamp(1.45rem, 2.7vw, 2.2rem); max-width: 15ch; }
body.wels-hero-split .wels-slide-caption p { font-size: clamp(.94rem, 1.1vw, 1.06rem); max-width: 32ch; }
/* A soft arc on the panel edge, echoing the curve the full-width hero uses. */
body.wels-hero-split .wels-hero::after { display: none; }
body.wels-hero-split .wels-hero-prev { left: calc(46% + 16px); }

@media (max-width: 900px) {
	/* Photo on top, panel as a band beneath it — still nothing like a
	   full-bleed banner, and the caption stays readable on a phone. */
	body.wels-hero-split .wels-hero-track { height: clamp(500px, 84vh, 640px); }
	body.wels-hero-split .wels-slide { background-position: center 22%; }
	body.wels-hero-split .wels-slide::after {
		width: 100%; top: auto; height: 60%;
		background: linear-gradient(180deg, rgba(0,0,0,0) 0%, var(--wels-primary-dark) 24%);
	}
	body.wels-hero-split .wels-slide-caption {
		width: 100%; align-items: flex-end; padding-bottom: clamp(28px, 6vw, 48px);
	}
	body.wels-hero-split .wels-slide-caption h2 { max-width: 22ch; }
	body.wels-hero-split .wels-slide-caption p { max-width: 44ch; }
	body.wels-hero-split .wels-hero-prev { left: 16px; }
}

/* ---------- Hero: panel layout (no photograph) ----------
   For schools whose photographs are few or poor. The page opens on colour,
   type and facts instead of a picture, with a quick-links row across the foot
   of the hero. Markup comes from inc/hero-panel.php. */
.wels-heropanel {
	background: linear-gradient(150deg, var(--wels-primary) 0%, var(--wels-primary-dark) 100%);
	padding: clamp(34px, 5vw, 58px) 0 0; position: relative;
}
/* The slider's white curved foot is meant to meet the page background. Here
   the coloured panel follows it instead, so the curve would cut a white
   crescent between the photograph and the panel. Drop it. */
body.wels-hero-panel .wels-hero::after { display: none; }
body.wels-hero-panel .wels-hero + .wels-heropanel { padding-top: clamp(30px, 4vw, 50px); }
.wels-heropanel-in { display: grid; grid-template-columns: minmax(0,1fr) clamp(180px, 20vw, 260px); gap: clamp(24px, 4vw, 52px); align-items: center; }
.wels-hp-eyebrow {
	font-size: .72rem; letter-spacing: .15em; text-transform: uppercase;
	color: var(--wels-accent-light); font-weight: 700; margin: 0 0 14px;
}
.wels-hp-title {
	font-family: var(--wels-heading-font); color: #fff; margin: 0 0 16px;
	font-size: clamp(1.9rem, 4.2vw, 3rem); line-height: 1.12; max-width: 18ch;
}
.wels-hp-lede { color: rgba(255,255,255,.82); margin: 0 0 24px; line-height: 1.65; max-width: 50ch; font-size: clamp(.98rem, 1.2vw, 1.08rem); }
.wels-hp-btns { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: clamp(24px, 3vw, 34px); }
.wels-btn-gold { background: var(--wels-accent-light); color: var(--wels-primary-dark); border: 0; font-weight: 700; }
.wels-btn-gold:hover, .wels-btn-gold:focus { background: #fff; color: var(--wels-primary-dark); }
.wels-btn-ondark { background: transparent; color: #fff; border: 1.5px solid rgba(255,255,255,.45); }
.wels-btn-ondark:hover, .wels-btn-ondark:focus { background: rgba(255,255,255,.12); color: #fff; }
.wels-hp-facts {
	display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 22px;
	border-top: 1px solid rgba(255,255,255,.2); margin: 0; padding: 20px 0 clamp(26px, 3vw, 38px);
}
.wels-hp-facts dt { font-size: .68rem; letter-spacing: .13em; text-transform: uppercase; color: rgba(255,255,255,.58); margin-bottom: 6px; }
.wels-hp-facts dd { margin: 0; color: #fff; font-weight: 600; font-size: .96rem; line-height: 1.35; }
.wels-heropanel-crest img { display: block; width: 100%; height: auto; }

/* Quick links across the foot of the hero, overlapping the section below. */
.wels-quicklinks {
	display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px;
	background: var(--wels-primary-dark); border-radius: calc(var(--wels-radius) + 4px);
	padding: 12px; margin-bottom: -38px; position: relative; z-index: 3;
	box-shadow: 0 14px 36px rgba(0,0,0,.22);
}
.wels-quicklinks a {
	display: block; padding: 14px 16px; border-radius: var(--wels-radius);
	background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.15);
	text-decoration: none;
}
.wels-quicklinks a:hover, .wels-quicklinks a:focus { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.32); }
.wels-quicklinks b { display: block; color: #fff; font-size: .88rem; line-height: 1.3; margin-bottom: 4px; font-weight: 700; }
.wels-quicklinks i { font-style: normal; color: rgba(255,255,255,.62); font-size: .78rem; }

/* Welcome + At a glance */
.wels-welcome { background: var(--wels-alt-bg); }
body.wels-hero-panel .wels-welcome { padding-top: clamp(72px, 8vw, 96px); }
.wels-welcome-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: clamp(30px, 4vw, 56px); align-items: start; }
/* The accent is a brand colour, not a text colour. A gold or a lime is
   around 1.8:1 on white — present, unreadable. --wels-accent-text is the
   same hue walked down until it clears 4.5:1, and small uppercase labels
   like this one must use it. */
.wels-kicker { font-size: .72rem; letter-spacing: .15em; text-transform: uppercase; color: var(--wels-accent-text, var(--wels-primary)); font-weight: 700; margin: 0 0 12px; }
.wels-welcome-title { font-family: var(--wels-heading-font); font-size: var(--wels-h2); color: var(--wels-ink); margin: 0 0 16px; line-height: 1.2; }
.wels-welcome-text { color: var(--wels-muted); line-height: 1.75; }
.wels-welcome-more { display: inline-block; margin-top: 8px; font-weight: 700; }
.wels-glance { background: var(--wels-primary); border-radius: calc(var(--wels-radius) + 3px); padding: clamp(20px, 2.4vw, 28px); }
.wels-glance h3 { font-family: var(--wels-heading-font); color: #fff; margin: 0 0 16px; font-size: 1.14rem; }
.wels-glance dl { margin: 0; display: grid; grid-template-columns: auto minmax(0,1fr); gap: 12px 16px; }
.wels-glance dt { color: rgba(255,255,255,.66); font-size: .86rem; }
.wels-glance dd { margin: 0; color: #fff; font-weight: 700; font-size: .9rem; text-align: right; }

@media (max-width: 880px) {
	.wels-heropanel-in { grid-template-columns: 1fr; }
	.wels-heropanel-crest { order: -1; width: 96px; }
	.wels-hp-facts { grid-template-columns: 1fr; gap: 16px; }
	.wels-quicklinks { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
	.wels-welcome-grid { grid-template-columns: 1fr; }
	.wels-glance dd { text-align: left; }
	.wels-glance dl { grid-template-columns: 1fr; gap: 4px 0; }
	.wels-glance dt { margin-top: 10px; }
}

/* ---------- CBSE disclosure link in the top bar ----------
   functions.php puts the Mandatory Public Disclosure page first among the
   top-bar links, so the first one gets the accent pill. It stays visible on
   phones, where the other top-bar links are hidden — an inspector may well
   be looking at this on a handset.

   Note the selector: the disclosure link is the FIRST .wels-topbar-link, but
   it is not the first <li> in the bar (email and phone come before it), so
   :first-of-type would not match. Styling every .wels-topbar-link and then
   reverting each later sibling gives "first of this class" in plain CSS. */
.wels-topbar-link a {
	background: var(--wels-accent); color: var(--wels-accent-ink, #fff); font-weight: 700; opacity: 1;
	padding: 4px 12px; border-radius: 4px; letter-spacing: .01em;
}
.wels-topbar-link a:hover,
.wels-topbar-link a:focus { background: var(--wels-accent); color: var(--wels-accent-ink, #fff); opacity: 1; filter: brightness(1.08); }
.wels-topbar-link ~ .wels-topbar-link a,
.wels-topbar-link ~ .wels-topbar-link a:hover,
.wels-topbar-link ~ .wels-topbar-link a:focus {
	background: none; color: rgba(255,255,255,.92); font-weight: inherit; opacity: .85;
	padding: 0; border-radius: 0; filter: none;
}

/* ---------- About ---------- */
.wels-about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 64px); align-items: center; }
.wels-about-media img { border-radius: var(--wels-radius); box-shadow: var(--wels-shadow); width: 100%; object-fit: cover; }
.wels-about .wels-section-head { text-align: left; margin: 0 0 20px; }
.wels-about .wels-section-title::after { margin-left: 0; }
.wels-about-text { color: var(--wels-muted); font-size: 1.05rem; }

/* ---------- Statistics band ---------- */
.wels-stats { background: var(--wels-primary); color: #fff; padding: clamp(32px, 4vw, 52px) 0; }
.wels-stats-grid {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 28px 20px;
	text-align: center;
}
.wels-stat { display: flex; flex-direction: column; align-items: center; gap: 6px; position: relative; }
.wels-stat + .wels-stat::before {
	content: ""; position: absolute; left: -10px; top: 12%; bottom: 12%; width: 1px; background: rgba(255,255,255,.22);
}
.wels-stat-icon img { width: 40px; height: 40px; object-fit: contain; filter: brightness(0) invert(1); opacity: .9; margin-bottom: 4px; }
.wels-stat-number { font-family: var(--wels-heading-font); font-weight: 800; font-size: clamp(1.9rem, 4vw, 2.9rem); line-height: 1; display: inline-flex; align-items: baseline; gap: 2px; }
.wels-stat-affix { font-size: .6em; font-weight: 700; opacity: .85; }
.wels-stat-label { font-size: .95rem; opacity: .9; letter-spacing: .01em; }

.wels-kg-intro { text-align: center; max-width: 640px; margin: -18px auto 28px; color: var(--wels-muted); font-size: 1.05rem; }
.wels-kg-grid-preview { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.wels-kg-grid-preview .wels-kg-card { text-align: center; }
.wels-kg-grid-preview .wels-kg-card .wels-card-media img { height: 150px; }
.wels-kg-grid-preview .wels-kg-card .wels-card-title { margin: 14px 16px 18px; font-size: 1rem; }

/* ---------- Our Journey — timeline ---------- */
.wels-journey { background: var(--wels-alt-bg); }
.wels-timeline { list-style: none; margin: 0 auto; padding: 8px 0; position: relative; max-width: 960px; }

/* Centre line + scroll-fill */
.wels-tl-line {
	position: absolute; left: 50%; top: 0; bottom: 0; width: 3px; transform: translateX(-50%);
	background: rgba(20,40,38,.12); border-radius: 3px;
}
.wels-tl-progress {
	position: absolute; left: 0; top: 0; width: 100%; height: 0; border-radius: 3px;
	background: linear-gradient(var(--wels-primary), var(--wels-accent));
	transition: height .12s linear;
}

.wels-tl-item { position: relative; width: 50%; padding: 16px 44px 34px; box-sizing: border-box; }
.wels-tl-item.is-left  { left: 0;   text-align: right; }
.wels-tl-item.is-right { left: 50%; text-align: left; }

/* Marker on the line */
.wels-tl-dot {
	position: absolute; top: 30px; width: 18px; height: 18px; border-radius: 50%; z-index: 2;
	background: var(--wels-accent); border: 4px solid var(--wels-alt-bg);
	box-shadow: 0 0 0 2px var(--wels-accent);
}
.wels-tl-item.is-left  .wels-tl-dot { right: -9px; }
.wels-tl-item.is-right .wels-tl-dot { left: -9px; }

.wels-tl-card {
	background: #fff; border-radius: var(--wels-radius); box-shadow: var(--wels-shadow-sm);
	padding: 22px 24px; display: inline-block; text-align: left; max-width: 420px;
	border: 1px solid rgba(20,40,38,.06); position: relative; overflow: hidden;
}
/* Large faint year watermark */
.wels-tl-ghost {
	position: absolute; top: -14px; right: 14px; font-family: var(--wels-heading-font);
	font-weight: 800; font-size: 4.2rem; line-height: 1; color: var(--wels-primary);
	opacity: .06; pointer-events: none; letter-spacing: -.02em;
}
.wels-tl-year { position: relative; display: inline-block; font-weight: 800; color: var(--wels-primary); font-size: .8rem; letter-spacing: .06em; margin-bottom: 6px; text-transform: uppercase; }
.wels-tl-year::after { content: ""; display: block; width: 26px; height: 3px; background: var(--wels-accent); border-radius: 2px; margin-top: 6px; }
.wels-tl-item.is-left .wels-tl-year::after { margin-left: auto; }
.wels-tl-title { font-size: 1.14rem; margin: 0 0 8px; }
.wels-tl-media { margin: 12px 0; border-radius: 10px; overflow: hidden; }
.wels-tl-media img { width: 100%; height: 170px; object-fit: cover; display: block; }
.wels-tl-text { color: var(--wels-muted); font-size: .95rem; }

/* Slide-in from alternating sides (JS opts in via .wels-tl-anim) */
.wels-timeline.wels-tl-anim .wels-tl-card { opacity: 0; transition: opacity .55s ease, transform .55s cubic-bezier(.2,.8,.2,1); }
.wels-timeline.wels-tl-anim .wels-tl-item.is-left  .wels-tl-card { transform: translateX(28px); }
.wels-timeline.wels-tl-anim .wels-tl-item.is-right .wels-tl-card { transform: translateX(-28px); }
.wels-timeline.wels-tl-anim .wels-tl-item.is-in .wels-tl-card { opacity: 1; transform: none; }
.wels-timeline.wels-tl-anim .wels-tl-item .wels-tl-dot { transition: transform .3s ease; }
.wels-timeline.wels-tl-anim .wels-tl-item.is-in .wels-tl-dot { transform: scale(1.15); }

/* ---------- Card grid (academics / facilities / activities / kindergarten) ---------- */
.wels-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: clamp(18px, 3vw, 30px); }
.wels-card {
	background: var(--wels-bg); border: 1px solid rgba(20,40,38,.08); border-radius: var(--wels-radius);
	overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--wels-shadow-sm);
	transition: transform .18s ease, box-shadow .18s ease; color: var(--wels-ink);
}
a.wels-card:hover, a.wels-card:focus { transform: translateY(-4px); box-shadow: var(--wels-shadow); text-decoration: none; }
.wels-card-media img { width: 100%; height: 190px; object-fit: cover; }
.wels-facilities-full .wels-card:target { border:2px solid var(--wels-primary); box-shadow:var(--wels-shadow); }
.wels-page-body .wels-facilities-full { padding:24px 0 0; }
.wels-page-body .wels-facilities-full>.wels-container { width:100%; max-width:none; padding:0; }
.wels-card-icon { padding: 22px 22px 0; }
.wels-card-title { font-size: 1.12rem; margin: 18px 20px 8px; }
/* The class range, or whatever short line sits under the heading. Letter-spaced
   and small so it reads as a label rather than as the first sentence. Uses
   --wels-accent-text, never the raw accent: at this size a brand colour that
   measures 1.8:1 on white is simply not there. */
.wels-card-tagline {
	margin: -2px 20px 10px; font-size: .78rem; font-weight: 600; letter-spacing: .06em;
	text-transform: uppercase; color: var(--wels-accent-text, var(--wels-primary));
}
.wels-card-text { margin: 0 20px 20px; color: var(--wels-muted); font-size: 0.95rem; }
/* The "Explore →" cue on a linked card. margin-top:auto pins it to the foot so
   a row of cards of unequal text length still has its cues on one line. */
.wels-card-cue {
	margin: auto 20px 20px; padding-top: 2px; font-size: .88rem; font-weight: 700;
	color: var(--wels-primary); display: inline-flex; align-items: center; gap: 6px;
}
.wels-card-arrow { transition: transform .18s ease; }
a.wels-card:hover .wels-card-arrow,
a.wels-card:focus .wels-card-arrow { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) {
	.wels-card-arrow { transition: none; }
	a.wels-card:hover .wels-card-arrow,
	a.wels-card:focus .wels-card-arrow { transform: none; }
}
.wels-alt-bg .wels-card, .wels-journey .wels-card, .wels-facilities .wels-card, .wels-kg .wels-card { background: #fff; }

/* ---------- Leadership ---------- */
.wels-leader-grid {
	display: flex; flex-wrap: wrap; justify-content: center; align-items: stretch;
	gap: clamp(20px, 3vw, 32px);
}
.wels-leader-card {
	flex: 1 1 300px; max-width: 380px;
	display: flex; flex-direction: column;
	background: #fff; border-radius: var(--wels-radius); box-shadow: var(--wels-shadow-sm);
	padding: 26px; text-align: center; border: 1px solid rgba(20,40,38,.07);
}
.wels-leader-body { display: flex; flex-direction: column; flex: 1; }
.wels-leader-card .wels-leader-more { align-self: center; margin-top: auto; }
/* exactly 2 cards: give them a comfortable width, centred side by side */
.wels-leader-grid:has(.wels-leader-card:nth-child(2):last-child) .wels-leader-card { flex-basis: 340px; max-width: 420px; }
.wels-leader-photo {
	width: 128px; height: 128px; margin: 0 auto 16px; border-radius: 50%; overflow: hidden;
	background: var(--wels-alt-bg); display: flex; align-items: center; justify-content: center;
	border: 4px solid rgba(31,95,91,.14);
}
.wels-leader-photo img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.wels-leader-initials { font-size: 2.6rem; font-weight: 700; color: var(--wels-primary); }
.wels-leader-name { font-size: 1.15rem; margin: 0 0 2px; }
.wels-leader-role { color: var(--wels-accent-text, var(--wels-primary)); font-weight: 600; font-size: 0.9rem; text-transform: uppercase; letter-spacing: .04em; margin: 0 0 12px; }
.wels-leader-short { color: var(--wels-muted); font-size: 0.96rem; margin: 0 0 12px; }

/* ---------- Faculty table ---------- */
.wels-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid rgba(20,40,38,.12); border-radius: var(--wels-radius); }
.wels-table { width: 100%; border-collapse: collapse; min-width: 560px; background: #fff; }
.wels-table th, .wels-table td { padding: 13px 16px; text-align: left; border-bottom: 1px solid rgba(20,40,38,.1); font-size: 0.95rem; }
.wels-table thead th { background: var(--wels-primary); color: #fff; font-weight: 600; white-space: nowrap; }
.wels-table tbody tr:nth-child(even) { background: var(--wels-alt-bg); }
.wels-table tbody tr:last-child td { border-bottom: 0; }

/* ---------- Faculty photographs ----------
   The column only exists when at least one member of staff has a photograph,
   so these rules simply never apply on a school that has none. Anyone without
   a picture gets their initial rather than a gap, which keeps the column from
   looking broken while photographs are still being collected. */
.wels-faculty-table.has-photos { min-width: 640px; }
.wels-fac-photo { width: 64px; padding-right: 0 !important; }
.wels-fac-photo img,
.wels-fac-initial {
	display: block; width: 44px; height: 44px; border-radius: 50%;
	object-fit: cover; object-position: center top;
}
.wels-fac-initial {
	display: grid; place-items: center;
	background: var(--wels-alt-bg); color: var(--wels-primary);
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 1.05rem;
	border: 1px solid rgba(20,40,38,.12);
}

/* ---------- Achievements ----------
   A card is built from whatever the school has filled in: the photograph, the
   category chip, the name/class/year line and the description are each
   optional, so a bare "Won the district kabaddi final" still reads as a
   finished card rather than an empty frame. */
/* align-items:start, so a card with one line of text stays one line tall
   instead of stretching to match the tallest card in its row and leaving a
   white void. Most achievements are a single sentence. */
.wels-ach-grid {
	display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: clamp(18px, 2.6vw, 26px); align-items: start;
}
.wels-ach-card {
	display: flex; flex-direction: column;
	background: #fff; border: 1px solid rgba(20,40,38,.1); border-radius: var(--wels-radius);
	box-shadow: var(--wels-shadow-sm); overflow: hidden;
}
.wels-ach-photo { flex: 0 0 auto; background: var(--wels-alt-bg); aspect-ratio: 4/3; }
.wels-ach-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center top; display: block; }
/* Only drawn when the set has at least one real photograph, so the initial
   keeps the row aligned rather than announcing a missing picture. */
.wels-ach-photo.is-initial {
	display: grid; place-items: center;
	background: var(--wels-primary); color: #fff;
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 3rem; line-height: 1;
}
.wels-ach-body { padding: 18px 20px 22px; display: flex; flex-direction: column; gap: 8px; }
.wels-ach-cat {
	align-self: flex-start; background: var(--wels-alt-bg); color: var(--wels-accent-text, var(--wels-primary));
	font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
	padding: 4px 10px; border-radius: 999px;
}
.wels-ach-title { margin: 0; font-size: 1.08rem; line-height: 1.35; color: var(--wels-ink); }
.wels-ach-who { margin: 0; font-weight: 600; color: var(--wels-primary); font-size: .94rem; }
.wels-ach-text { color: var(--wels-muted); font-size: .92rem; }
.wels-ach-text p { margin: 0; }
.wels-ach-group + .wels-ach-group { margin-top: clamp(32px, 5vw, 52px); }
.wels-ach-group-title {
	font-size: clamp(1.2rem, 2.4vw, 1.5rem); color: var(--wels-primary);
	margin: 0 0 18px; padding-bottom: 10px; border-bottom: 2px solid var(--wels-accent);
}

/* ---------- Committees ---------- */
.wels-committee-block + .wels-committee-block { margin-top: clamp(28px, 4vw, 44px); }
.wels-committee-name { font-size: clamp(1.1rem, 2.2vw, 1.35rem); color: var(--wels-primary); margin: 0 0 14px; }
.wels-committee-table { min-width: 520px; }
.wels-committee-table th:first-child, .wels-committee-table td:first-child { width: 68px; }
.wels-committee-table th:nth-child(2), .wels-committee-table td:nth-child(2) { width: 34%; }

/* ---------- Gallery ---------- */
.wels-gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }

/* Homepage mosaic: first tile is a 2×2 feature on wider screens. */
.wels-gallery-mosaic { grid-auto-rows: 1fr; }
.wels-gallery-mosaic .wels-gallery-item { aspect-ratio: 4 / 3; width: 100%; min-width: 0; }
@media (min-width: 900px) {
	.wels-gallery-mosaic { grid-template-columns: repeat(4, 1fr); grid-auto-rows: minmax(0, 1fr); }
	.wels-gallery-mosaic .wels-gallery-item { aspect-ratio: auto; }
	.wels-gallery-mosaic .wels-gallery-item.is-featured { grid-column: span 2; grid-row: span 2; }
}

.wels-gallery-item {
	position: relative; display: flex; flex-direction: column;
	border-radius: var(--wels-radius); overflow: hidden; background: var(--wels-alt-bg);
	box-shadow: var(--wels-shadow-sm); transition: transform .2s ease, box-shadow .2s ease;
	min-height: 190px; text-decoration: none;
}
.wels-gallery-grid:not(.wels-gallery-mosaic) .wels-gallery-item { aspect-ratio: 4 / 3.35; }
.wels-gallery-item:hover, .wels-gallery-item:focus-visible { transform: translateY(-4px); box-shadow: var(--wels-shadow); text-decoration: none; }
.wels-gallery-media { position: relative; flex: 1; overflow: hidden; display: block; min-height: 0; }
.wels-gallery-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .45s ease; }
.wels-gallery-item:hover .wels-gallery-media img, .wels-gallery-item:focus-visible .wels-gallery-media img { transform: scale(1.06); }
.wels-gallery-media::after {
	content: ""; position: absolute; inset: 0;
	background: linear-gradient(180deg, rgba(12,26,25,0) 45%, rgba(12,26,25,.35) 100%);
	opacity: 0; transition: opacity .25s ease;
}
.wels-gallery-item:hover .wels-gallery-media::after, .wels-gallery-item:focus-visible .wels-gallery-media::after { opacity: 1; }

.wels-gallery-overlay {
	position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
	color: #fff; opacity: 0; transform: scale(.8); transition: opacity .25s ease, transform .25s ease;
}
.wels-gallery-overlay svg { background: rgba(255,255,255,.18); border: 2px solid rgba(255,255,255,.7); border-radius: 50%; padding: 12px; backdrop-filter: blur(2px); }
.wels-gallery-item:hover .wels-gallery-overlay, .wels-gallery-item:focus-visible .wels-gallery-overlay { opacity: 1; transform: scale(1); }

.wels-gallery-count {
	position: absolute; top: 10px; right: 10px; display: inline-flex; align-items: center; gap: 4px;
	padding: 4px 9px; border-radius: 999px; background: rgba(12,26,25,.62); color: #fff;
	font-size: 0.78rem; font-weight: 700; line-height: 1; backdrop-filter: blur(2px);
}
.wels-gallery-count .dashicons { font-size: 14px; width: 14px; height: 14px; }

.wels-gallery-tag {
	position: absolute; top: 10px; left: 10px; max-width: calc(100% - 70px);
	padding: 4px 10px; border-radius: 999px; background: rgba(255,255,255,.92); color: var(--wels-primary-dark);
	font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; line-height: 1.3;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.wels-gallery-info {
	flex: 0 0 auto; height: 3rem; padding: 0 15px; background: var(--wels-bg);
	display: flex; align-items: center;
	border-top: 3px solid var(--wels-accent);
}
.wels-gallery-title {
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 0.98rem; color: var(--wels-ink);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.wels-gallery-mosaic .wels-gallery-item.is-featured .wels-gallery-info { height: 3.4rem; }
.wels-gallery-mosaic .wels-gallery-item.is-featured .wels-gallery-title { font-size: 1.2rem; }

.wels-gallery-filter { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-bottom: 26px; }
.wels-gallery-filter button { padding: 9px 18px; border: 1px solid rgba(20,40,38,.16); background: var(--wels-bg); border-radius: 999px; cursor: pointer; font-weight: 600; font-size: 0.88rem; color: var(--wels-ink); transition: .15s ease; }
.wels-gallery-filter button:hover { border-color: var(--wels-primary); color: var(--wels-primary); }
.wels-gallery-filter button.is-active { background: var(--wels-primary); color: #fff; border-color: var(--wels-primary); }
.wels-gallery-item.is-hidden { display: none; }

@media (max-width: 560px) {
	.wels-gallery-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
	.wels-gallery-item { min-height: 150px; }
	.wels-gallery-mosaic .wels-gallery-item.is-featured { grid-column: span 2; }
}

/* ---------- Notices (auto scroller) ---------- */
.wels-notice-viewport { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none; }
.wels-notice-viewport::-webkit-scrollbar { display: none; }
.wels-notice-track { list-style: none; margin: 0; padding: 4px; display: flex; gap: 20px; }
.wels-notice-card {
	flex: 0 0 calc((100% - 40px) / 3); background: #fff; border-radius: var(--wels-radius);
	box-shadow: var(--wels-shadow-sm); padding: 22px; border-top: 4px solid var(--wels-accent);
	display: flex; flex-direction: column; min-height: 190px;
}
.wels-notice-date { font-size: 0.8rem; color: var(--wels-muted); font-weight: 600; }
.wels-notice-title { font-size: 1.05rem; margin: 6px 0 8px; }
.wels-notice-text { color: var(--wels-muted); font-size: 0.92rem; margin: 0 0 14px; overflow-wrap: anywhere; }
.wels-notice-actions { margin-top: auto; display: flex; flex-wrap: wrap; gap: 14px; }

/* ---------- Testimonials (auto scroller) ---------- */
.wels-tm-viewport { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none; }
.wels-tm-viewport::-webkit-scrollbar { display: none; }
.wels-tm-track { list-style: none; margin: 0; padding: 4px; display: flex; gap: 22px; }
.wels-tm-card { flex: 0 0 min(420px, 82vw); background: #fff; border-radius: var(--wels-radius); box-shadow: var(--wels-shadow-sm); padding: 28px; }
.wels-tm-quote { font-size: 1.05rem; font-style: italic; color: var(--wels-ink); margin: 0 0 18px; position: relative; padding-top: 14px; }
.wels-tm-quote::before { content: "\201C"; position: absolute; top: -14px; left: -4px; font-size: 3rem; color: var(--wels-accent); font-family: Georgia, serif; line-height: 1; }
.wels-tm-person { display: flex; align-items: center; gap: 12px; }
.wels-tm-avatar img { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; }
.wels-tm-person strong { display: block; }
.wels-tm-person em { font-style: normal; color: var(--wels-muted); font-size: 0.88rem; }

/* ---------- Downloads ---------- */
.wels-download-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; max-width: 860px; margin-inline: auto; }
.wels-download-item {
	display: flex; align-items: center; justify-content: space-between; gap: 16px;
	background: #fff; border: 1px solid rgba(20,40,38,.1); border-radius: var(--wels-radius); padding: 16px 20px;
}
.wels-download-meta { display: flex; align-items: center; gap: 14px; }
.wels-download-meta .dashicons { color: var(--wels-primary); font-size: 26px; width: 26px; height: 26px; }
.wels-download-meta em { display: block; font-style: normal; color: var(--wels-muted); font-size: 0.85rem; }
.wels-badge-pending { font-size: 0.8rem; font-weight: 600; color: #b42318; background: #fdecec; padding: 5px 10px; border-radius: 6px; }

/* ---------- Admissions / Pay Fee ---------- */
.wels-admissions-inner { text-align: center; max-width: 760px; margin: 0 auto; }
.wels-admissions-inner .wels-section-title::after { margin-inline: auto; }
.wels-admissions-text { color: var(--wels-muted); font-size: 1.05rem; margin-bottom: 22px; }
.wels-admissions-btn { margin: 4px 8px; }
.wels-payfee { background: var(--wels-primary); }
.wels-payfee .wels-section-title, .wels-payfee p { color: #fff; }
.wels-payfee-inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.wels-payfee-inner h2 { margin: 0 0 6px; }
.wels-payfee-inner p { margin: 0; opacity: .9; }

/* ---------- Contact ---------- */
.wels-contact-grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: clamp(28px, 5vw, 56px); align-items: start; }
.wels-contact .wels-section-head { text-align: left; margin: 0 0 20px; }
.wels-contact .wels-section-title::after { margin-left: 0; }
.wels-contact-list { list-style: none; margin: 0 0 22px; padding: 0; display: grid; gap: 14px; }
.wels-contact-list li { display: flex; gap: 12px; align-items: flex-start; color: var(--wels-muted); }
.wels-contact-list .dashicons { color: var(--wels-primary); flex: 0 0 auto; }
.wels-contact-map { border-radius: var(--wels-radius); overflow: hidden; box-shadow: var(--wels-shadow-sm); aspect-ratio: 4/3; background: var(--wels-alt-bg); }
.wels-contact-map iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---------- Social ---------- */
.wels-social-row { display: flex; gap: 10px; }
.wels-social {
	width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
	background: rgba(31,95,91,.1); color: var(--wels-primary); transition: .15s ease;
}
.wels-social:hover, .wels-social:focus { background: var(--wels-primary); color: #fff; }
.wels-site-footer .wels-social { background: rgba(255,255,255,.1); color: #fff; }
.wels-site-footer .wels-social:hover, .wels-site-footer .wels-social:focus { background: var(--wels-accent); color: #fff; }

/* ---------- Footer ---------- */
.wels-site-footer { background: var(--wels-footer-bg); color: rgba(255,255,255,.78); margin-top: 0; }
.wels-site-footer a { color: rgba(255,255,255,.82); }
.wels-site-footer a:hover { color: #fff; }
.wels-footer-grid {
	/* Four columns: who the school is, two of links, how to reach them.
	   Proportions follow the reference — identity and contact get the room,
	   the link columns are narrow because a list of five words needs no
	   more. */
	display: grid;
	/* Ratios, not percentages: percentage tracks are measured against the
	   full width and then shrink once the gaps are taken out, which landed
	   all four columns at roughly the same size. fr divides what is left
	   after the gaps, so 29/21/21/29 actually comes out as 29/21/21/29. */
	grid-template-columns: 2.9fr 2.1fr 2.1fr 2.9fr;
	gap: 40px clamp(28px, 4vw, 64px);
	padding: clamp(40px, 5vw, 72px) 20px clamp(28px, 3.5vw, 44px);
}
/* The optional extra widget area is a fifth thing in a four-column grid, so
   it takes a row of its own underneath rather than squeezing the four. */
.wels-footer-extra { grid-column: 1 / -1; }
.wels-footer-title { color: #fff; font-size: 1rem; margin: 0 0 14px; letter-spacing: .01em; }
.wels-footer-name { font-weight: 700; color: #fff; font-size: 1.1rem; margin: 10px 0 4px; }
.wels-footer-tagline { font-size: 0.9rem; margin: 0 0 16px; max-width: 34ch; }
.wels-footer-logo .custom-logo { height: 52px; width: auto; margin-bottom: 4px; }
.wels-footer-links ul, .wels-footer-menu { list-style: none; margin: 0; padding: 0; }
/* Two tidy columns so the list never elongates the footer */
.wels-footer-menu li { margin: 0; }
.wels-footer-menu a { display: inline-block; padding: 3px 0; font-size: 0.92rem; }
.wels-footer-menu a:hover { padding-left: 4px; transition: padding .15s ease; }
.wels-footer-contact ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; font-size: 0.92rem; }
.wels-footer-about .wels-social-row { margin-top: 16px; }
/* ---------- Footer, four-column ---------- */
.wels-footer-brand { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.wels-footer-logo { flex: 0 0 auto; }
.wels-footer-logo img { display: block; width: auto; max-height: 54px; }
.wels-footer-name {
	margin: 0; font-family: var(--wels-heading-font); font-weight: 700;
	font-size: 1.02rem; line-height: 1.25; letter-spacing: .01em;
}
.wels-footer-tagline { margin: 0; max-width: 34ch; line-height: 1.7; }

.wels-footer-title {
	font-size: 1.06rem; margin: 0 0 18px; font-weight: 700;
	letter-spacing: .01em;
}
/* One link per line. A leftover rule from the old wide Quick Links column
   was setting this to two columns, which is why the footer links were
   running in pairs — stated explicitly here so it cannot drift back. */
.wels-footer-menu {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: minmax(0, 1fr); gap: 11px;
}
.wels-footer-menu a { text-decoration: none; }
.wels-footer-menu a:hover, .wels-footer-menu a:focus-visible { text-decoration: underline; }

.wels-footer-contact-list { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 16px; }
.wels-footer-contact-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 12px; align-items: start; }
.wels-footer-contact-list a { text-decoration: none; }
.wels-footer-contact-list a:hover, .wels-footer-contact-list a:focus-visible { text-decoration: underline; }
.wels-footer-ico { display: block; width: 18px; margin-top: 2px; }
.wels-footer-ico svg { width: 18px; height: 18px; fill: currentColor; display: block; opacity: .85; }
.wels-footer-addr { line-height: 1.6; }

.wels-footer-legal { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.wels-footer-legal li + li::before { content: "|"; opacity: .4; margin-right: 14px; }
.wels-footer-legal a { text-decoration: none; }
.wels-footer-legal a:hover, .wels-footer-legal a:focus-visible { text-decoration: underline; }

@media (max-width: 1024px) {
	/* Two and two, rather than four squeezed columns. */
	.wels-footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
	.wels-footer-grid { grid-template-columns: minmax(0, 1fr); gap: 32px; }
	.wels-footer-tagline { max-width: none; }
	.wels-footer-legal { justify-content: flex-start; }
}

.wels-footer-bottom { border-top: 1px solid rgba(255,255,255,.12); }
.wels-footer-bottom-inner { display: flex; flex-wrap: wrap; gap: 10px 24px; justify-content: space-between; align-items: center; padding-top: 16px; padding-bottom: 16px; font-size: 0.85rem; }
.wels-footer-bottom-right { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.wels-credit { margin: 0; }
.wels-staff-login { opacity: .8; }

/* ---------- Back to top ---------- */
.wels-back-to-top {
	position: fixed; right: 20px; bottom: 20px; z-index: 250; width: 46px; height: 46px;
	border: 0; border-radius: 50%; background: var(--wels-primary); color: #fff; font-size: 20px;
	cursor: pointer; box-shadow: var(--wels-shadow); opacity: 0; transform: translateY(12px);
	transition: opacity .2s ease, transform .2s ease;
}
.wels-back-to-top.is-visible { opacity: 1; transform: translateY(0); }
.wels-back-to-top:hover { background: var(--wels-primary-dark); }

/* ---------- Modal (leadership read more) ---------- */
.wels-modal, .wels-lightbox { position: fixed; inset: 0; z-index: 400; display: flex; align-items: center; justify-content: center; }
.wels-modal[hidden], .wels-lightbox[hidden] { display: none; }
.wels-modal-overlay { position: absolute; inset: 0; background: rgba(10,20,19,.6); }
.wels-modal-panel {
	position: relative; z-index: 2; background: #fff; border-radius: var(--wels-radius); max-width: 720px;
	width: calc(100% - 32px); max-height: 88vh; overflow-y: auto; padding: 32px; box-shadow: var(--wels-shadow);
}
.wels-modal-close, .wels-lightbox-close {
	position: absolute; top: 12px; right: 14px; width: 40px; height: 40px; border: 0; border-radius: 50%;
	background: #f0f0f0; font-size: 24px; line-height: 1; cursor: pointer; z-index: 5;
}
.wels-modal-body { display: grid; grid-template-columns: 180px 1fr; gap: 24px; align-items: start; }
.wels-modal-photo img { width: 180px; height: 220px; object-fit: cover; object-position: top center; border-radius: var(--wels-radius); }
.wels-modal-role { color: var(--wels-accent-text, var(--wels-primary)); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: 0.85rem; margin: 0 0 14px; }

/* ---------- Lightbox ---------- */
.wels-lightbox { background: rgba(6,12,11,.92); }
.wels-lightbox-figure { margin: 0; max-width: 92vw; max-height: 82vh; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.wels-lightbox-figure img { max-width: 92vw; max-height: 74vh; width: auto; height: auto; border-radius: 8px; }
.wels-lightbox-figure figcaption { color: rgba(255,255,255,.85); font-size: 0.9rem; text-align: center; }
.wels-lightbox-prev, .wels-lightbox-next {
	position: absolute; top: 50%; transform: translateY(-50%); width: 54px; height: 54px; border: 0;
	border-radius: 50%; background: rgba(255,255,255,.16); color: #fff; font-size: 30px; cursor: pointer;
}
.wels-lightbox-prev { left: 14px; } .wels-lightbox-next { right: 14px; }
.wels-lightbox-prev:hover, .wels-lightbox-next:hover { background: rgba(255,255,255,.32); }

/* ---------- Admission pop-up ---------- */
.wels-popup-panel { padding: 0; max-width: 480px; overflow: hidden; border-radius: var(--wels-radius); }
.wels-popup-panel .wels-modal-close { background: rgba(255,255,255,.9); }
.wels-popup-link, .wels-popup-img { display: block; width: 100%; height: auto; }
.wels-lightbox-counter { position: absolute; top: 16px; left: 0; right: 0; text-align: center; color: rgba(255,255,255,.8); font-size: 0.85rem; }

/* ---------- Pages ---------- */
.wels-page-header { background: var(--wels-alt-bg); padding: clamp(30px, 5vw, 56px) 0; border-bottom: 1px solid rgba(20,40,38,.08); }
.wels-page-title { font-size: clamp(1.7rem, 3.6vw, 2.5rem); margin: 0; }
.wels-page-body { padding-top: clamp(30px, 5vw, 56px); padding-bottom: clamp(40px, 6vw, 72px); }
.wels-page-body h2 { margin-top: 1.6em; }

/* ---------- Type scale, applied ----------
   Headings written in the editor (About Us, Mission & Vision, General
   Regulations, Transport) had no size rule at all and fell back to the
   browser's default, which is why those pages never quite matched the ones
   built from components. They are on the scale now. */
.wels-page-body h2,
.wels-page-body .wp-block-heading { font-size: var(--wels-h2); }
.wels-page-body h3 { font-size: var(--wels-h3); margin-top: 1.4em; }
.wels-page-body h4 { font-size: var(--wels-h4); }

/* ---------- Two helpers for editor-written pages ----------
   .wels-lead      — the opening sentence, set larger than the body so a page
                     has somewhere to start. Content seeds have been writing
                     this class for a while with no rule behind it, so those
                     pages were quietly rendering it as an ordinary paragraph.
   .wels-focus-line — the "Focus  A · B · C" strip at the foot of a section.
                     A tinted band rather than a bold run-on, because its job
                     is to be skimmed rather than read. */
.wels-lead {
	font-size: clamp(1.02rem, 1.7vw, 1.16rem); line-height: 1.7;
	color: var(--wels-ink); margin-bottom: 1.1em;
}
.wels-focus-line {
	margin: 1.6em 0 0; padding: 14px 18px; border-radius: var(--wels-radius);
	background: var(--wels-alt-bg); border-left: 3px solid var(--wels-accent);
	font-size: .92rem; line-height: 1.7; color: var(--wels-ink);
}
.wels-focus-line strong {
	display: block; font-size: .74rem; letter-spacing: .09em; text-transform: uppercase;
	color: var(--wels-accent-text, var(--wels-primary)); margin-bottom: 3px;
}
.wels-single-thumb { margin: 0 0 24px; border-radius: var(--wels-radius); overflow: hidden; }
.wels-single-meta { color: var(--wels-muted); font-size: 0.9rem; }
.wels-eyebrow { text-transform: uppercase; letter-spacing: .06em; font-size: 0.8rem; font-weight: 700; color: var(--wels-accent-text, var(--wels-primary)); margin: 0 0 6px; }
.wels-eyebrow a { color: inherit; }

.wels-notice-page-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.wels-notice-row {
	display: grid; grid-template-columns: 130px 1fr auto; gap: 16px; align-items: center;
	background: #fff; border: 1px solid rgba(20,40,38,.1); border-radius: var(--wels-radius); padding: 16px 20px;
}
.wels-notice-row time { color: var(--wels-muted); font-size: 0.85rem; font-weight: 600; }
.wels-notice-row p { margin: 4px 0 0; color: var(--wels-muted); font-size: 0.9rem; }

.wels-post-list { display: grid; gap: 22px; }
.wels-post-card { display: grid; grid-template-columns: 260px 1fr; gap: 22px; background: #fff; border: 1px solid rgba(20,40,38,.1); border-radius: var(--wels-radius); overflow: hidden; }
.wels-post-thumb img { height: 100%; object-fit: cover; }
.wels-post-body { padding: 22px 24px; }
.wels-post-title { margin: 0 0 6px; font-size: 1.25rem; }

/* ---------- Search / comments ---------- */
.wels-search-form { display: flex; gap: 8px; margin: 16px 0; }
.wels-search-field { flex: 1; padding: 12px 14px; border: 1px solid rgba(20,40,38,.2); border-radius: var(--wels-btn-radius); font-size: 1rem; }
.wels-comments { margin-top: 40px; }
.wels-comment-list { list-style: none; padding: 0; }
.wels-comment-list ol { list-style: none; }

/* ---------- Utilities ---------- */
.wels-page-full .wels-page-body { max-width: var(--wels-maxw); margin: 0 auto; }

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 1080px) {
	/* Below this the desktop menu is replaced by the mobile off-canvas menu */
	.wels-primary-nav { display: none; }
	.wels-nav-toggle { display: block; }
	.wels-header-stacked .wels-header-inner { flex-wrap: nowrap; }
	.wels-header-inner { justify-content: space-between; }
	.wels-notice-card { flex-basis: calc((100% - 20px) / 2); }
}

@media (max-width: 640px) {
	.wels-header-actions-header { display: none; }
}

@media (max-width: 780px) {
	/* Tree collapses to a single trunk on the left, branches to the right */
	.wels-timeline { max-width: 560px; }
	.wels-tl-line { left: 9px; transform: none; }
	.wels-tl-item, .wels-tl-item.is-left, .wels-tl-item.is-right {
		width: 100%; left: 0; text-align: left; padding: 8px 0 30px 34px;
	}
	.wels-tl-item.is-left .wels-tl-dot, .wels-tl-item.is-right .wels-tl-dot { left: 1px; right: auto; }
	.wels-tl-item.is-left .wels-tl-year::after { margin-left: 0; }
	.wels-timeline.wels-tl-anim .wels-tl-item.is-left .wels-tl-card,
	.wels-timeline.wels-tl-anim .wels-tl-item.is-right .wels-tl-card { transform: translateX(20px); }
	.wels-tl-card { max-width: none; }
}

@media (max-width: 900px) {
	.wels-about-grid, .wels-contact-grid { grid-template-columns: 1fr; }
	.wels-about-media { order: -1; }
	.wels-post-card { grid-template-columns: 1fr; }
	.wels-post-thumb img { max-height: 220px; width: 100%; }
	.wels-modal-body { grid-template-columns: 1fr; text-align: center; }
	.wels-modal-photo img { margin: 0 auto; }
}

@media (max-width: 680px) {
	/* Keep the disclosure pill (the first one); hide any others. */
	.wels-topbar-link { display: inline-flex; }
	.wels-topbar-link ~ .wels-topbar-link { display: none; }
	.wels-topbar-inner { justify-content: center; }
	.wels-topbar-left { display: none; }
	.wels-topbar-centre { flex: 1 1 auto; justify-content: center; }
	.wels-topbar-right { flex: 1 1 auto; margin: 0 auto; justify-content: center; }
	.wels-notice-card { flex-basis: 86vw; }
	.wels-tm-card { flex-basis: 86vw; }
	.wels-footer-bottom-inner { justify-content: center; text-align: center; }
	.wels-notice-row { grid-template-columns: 1fr; }
	.wels-payfee-inner { flex-direction: column; text-align: center; }
	.wels-download-item { flex-direction: column; align-items: flex-start; }
}

/* =========================================================================
   Motion — scroll reveal + hero Ken Burns
   ========================================================================= */
/* Only elements the script has "armed" (below the fold) start hidden, so a
   slow or blocked script can never leave content invisible. */
.wels-js .wels-reveal.is-armed {
	opacity: 0; transform: translateY(24px);
	transition: opacity .65s cubic-bezier(.2,.7,.2,1), transform .65s cubic-bezier(.2,.7,.2,1);
}
.wels-js .wels-reveal.is-armed.is-in { opacity: 1; transform: none; }

/* Hero: subtle slow zoom on the active slide's image layer */
.wels-slide::before {
	content: ""; position: absolute; inset: 0; z-index: 0;
	background-image: inherit; background-size: cover; background-position: center;
	transform: scale(1.001);
}
.wels-slide::after { z-index: 1; }
.wels-slide-caption { z-index: 2; }
.wels-slide.is-active::before { animation: wels-kenburns 9s ease-out both; }
@keyframes wels-kenburns { from { transform: scale(1.02); } to { transform: scale(1.11); } }

/* Buttons get a soft press feedback */
.wels-btn:active { transform: translateY(0) scale(.98); }

/* Card media zoom already handled; add a gentle shadow grow on card hover */
.wels-card:hover { box-shadow: var(--wels-shadow); }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
	.wels-slide { transition: none; }
	.wels-js .wels-reveal.is-armed { opacity: 1 !important; transform: none !important; }
	.wels-slide.is-active::before { animation: none; }
}

/* =========================================================================
   Style presets — structural differences beyond colour/font/shape.
   Colour, heading font, radius and button shape come from the preset via
   CSS variables (inc/dynamic-css.php). These blocks handle card treatment,
   hero caption and section-title styling per preset.
   ========================================================================= */

/* ---- Classic: framed cards, formal hero, centred title rule ---- */
.wels-preset-classic .wels-card { box-shadow: none; border: 1px solid rgba(20,40,38,.16); }
.wels-preset-classic .wels-card:hover { box-shadow: 0 4px 18px rgba(20,40,38,.10); }
.wels-preset-classic .wels-tl-card,
.wels-preset-classic .wels-leader-card,
.wels-preset-classic .wels-notice-card,
.wels-preset-classic .wels-tm-card { box-shadow: none; border: 1px solid rgba(20,40,38,.16); }
.wels-preset-classic .wels-section-title { letter-spacing: 0; }
.wels-preset-classic .wels-section-title::after { width: 44px; height: 2px; }
.wels-preset-classic .wels-slide-caption h2 { border-top: 2px solid rgba(255,255,255,.5); padding-top: .35em; display: inline-block; }
.wels-preset-classic .wels-btn { text-transform: uppercase; letter-spacing: .04em; font-size: .85rem; }

/* ---- Warm: soft pillowy cards, centred hero caption ---- */
.wels-preset-warm .wels-card,
.wels-preset-warm .wels-tl-card,
.wels-preset-warm .wels-leader-card,
.wels-preset-warm .wels-notice-card,
.wels-preset-warm .wels-tm-card { border: 0; box-shadow: 0 14px 34px rgba(80,50,30,.12); }
.wels-preset-warm .wels-card:hover { box-shadow: 0 20px 44px rgba(80,50,30,.18); }
.wels-preset-warm .wels-section-title::after { width: 64px; height: 5px; }
.wels-preset-warm .wels-slide-caption { text-align: center; }
.wels-preset-warm .wels-slide-caption h2,
.wels-preset-warm .wels-slide-caption p { margin-left: auto; margin-right: auto; }
.wels-preset-warm .wels-hero-progress-bar { height: 4px; }

/* ---- Editorial: minimal cards, hero caption bar, hard-left title bar ---- */
.wels-preset-editorial .wels-card,
.wels-preset-editorial .wels-tl-card,
.wels-preset-editorial .wels-leader-card,
.wels-preset-editorial .wels-notice-card,
.wels-preset-editorial .wels-tm-card {
	border: 0; border-top: 3px solid var(--wels-ink); box-shadow: none; border-radius: 0;
}
.wels-preset-editorial .wels-card-title,
.wels-preset-editorial .wels-tl-title { font-size: 1.22rem; letter-spacing: -.01em; }
.wels-preset-editorial .wels-section-title { text-align: left; }
.wels-preset-editorial .wels-section-head { text-align: left; max-width: none; }
.wels-preset-editorial .wels-section-title::after { margin-left: 0; width: 40px; height: 5px; background: var(--wels-accent); }
.wels-preset-editorial .wels-section-sub { max-width: 60ch; }
.wels-preset-editorial .wels-slide { align-items: stretch; }
.wels-preset-editorial .wels-slide-caption {
	align-self: flex-end; background: rgba(20,20,20,.82); padding-top: clamp(24px,4vw,44px);
}
.wels-preset-editorial .wels-slide::after { display: none; }
.wels-preset-editorial .wels-slide-caption h2 { font-size: clamp(1.9rem, 5vw, 3.4rem); }
.wels-preset-editorial .wels-btn { text-transform: uppercase; letter-spacing: .05em; font-size: .82rem; }

/* ---------- Floating WhatsApp button ---------- */
.wels-whatsapp-float {
	position: fixed; right: 20px; bottom: 80px; z-index: 250; width: 52px; height: 52px;
	border-radius: 50%; background: #25D366; display: flex; align-items: center; justify-content: center;
	box-shadow: var(--wels-shadow); transition: transform .15s ease, background .15s ease, opacity .15s ease;
	/*
	 * A fixed button of any reasonable tap-target size will, at some
	 * scroll position, sit over whatever text happens to be underneath
	 * it — true of every "click to WhatsApp" bubble on the web, not
	 * something layout alone can fully rule out. Keeping it just under
	 * full opacity means anything it does overlap stays legible instead
	 * of being flatly hidden, while it's still unmistakably a bright
	 * green WhatsApp button.
	 */
	opacity: .92;
}
.wels-whatsapp-float:hover,
.wels-whatsapp-float:focus-visible { background: #1ebe5a; transform: scale(1.06); opacity: 1; }
.wels-whatsapp-float svg { width: 28px; height: 28px; fill: #fff; }
@media (max-width: 600px) {
	/* Right-aligned with the back-to-top button below it, instead of sitting closer to the edge. */
	.wels-whatsapp-float { right: 16px; bottom: 70px; width: 44px; height: 44px; }
	.wels-whatsapp-float svg { width: 22px; height: 22px; }
}

/* ------------------------------------------------------------------ *
 * Slide background video
 *
 * Sits above the slide's still image and below the gradient, so the
 * caption stays readable either way. It starts invisible and fades in
 * once it is actually playing — if the script decides not to load it
 * (narrow screen, reduced motion, data saver) the image simply stays,
 * and nothing about the slide looks unfinished.
 * ------------------------------------------------------------------ */
.wels-slide-video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity .8s ease;
	pointer-events: none;
}
.wels-slide-video.is-playing { opacity: 1; }

/* ------------------------------------------------------------------ *
 * Quick Links
 * ------------------------------------------------------------------ */
.wels-ql-grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 14px;
	grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
}
.wels-ql-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	/* Comfortably past the 44px a fingertip needs, in both directions. */
	min-height: 124px;
	height: 100%;
	padding: 20px 14px;
	text-align: center;
	color: var(--wels-ink);
	background: var(--wels-bg);
	border: 1px solid rgba(20, 40, 38, .10);
	border-radius: var(--wels-radius);
	box-shadow: var(--wels-shadow-sm);
	transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.wels-ql-card:hover,
.wels-ql-card:focus-visible {
	transform: translateY(-3px);
	border-color: var(--wels-primary);
	box-shadow: var(--wels-shadow);
	color: var(--wels-primary);
}
.wels-ql-card:focus-visible {
	outline: 2px solid var(--wels-primary);
	outline-offset: 3px;
}
.wels-ql-figure {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	color: var(--wels-primary);
}
.wels-ql-figure img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}
.wels-ql-icon { width: 30px; height: 30px; }
.wels-ql-label { font-weight: 600; line-height: 1.25; }
.wels-ql-note {
	font-size: .82rem;
	line-height: 1.3;
	color: var(--wels-muted);
}
.wels-ql-card:hover .wels-ql-note,
.wels-ql-card:focus-visible .wels-ql-note { color: inherit; }

@media (prefers-reduced-motion: reduce) {
	.wels-ql-card { transition: none; }
	.wels-ql-card:hover,
	.wels-ql-card:focus-visible { transform: none; }
}

@media (max-width: 480px) {
	.wels-ql-grid { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
	.wels-ql-card { min-height: 112px; padding: 16px 10px; }
}

/* ---------------------------------------------------------------------------
 * Pillars band
 *
 * Equal columns, centred, with a hairline between them rather than cards —
 * the band should read as one statement, not four boxes. It falls to two
 * columns on a tablet and one on a phone, and the dividers go with it.
 * ------------------------------------------------------------------------ */
.wels-pillars { background: var(--wels-alt-bg); }
.wels-pillar-grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 28px 0;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.wels-pillar {
	text-align: center;
	padding: 4px 24px;
	min-width: 0;
	border-left: 1px solid rgba(30, 42, 42, 0.12);
}
.wels-pillar:first-child { border-left: 0; }
.wels-pillar-figure {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-bottom: 12px;
	color: var(--wels-primary);
}
.wels-pillar-icon { width: 40px; height: 40px; }
.wels-pillar-title {
	margin: 0 0 6px;
	font-size: 1.05rem;
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--wels-ink);
}
.wels-pillar-text {
	margin: 0;
	font-size: .92rem;
	line-height: 1.5;
	color: var(--wels-muted);
}

/* Four and eight are the two counts the renderer settles on, so they are the
   two worth pinning: four columns exactly, which gives one full row or two,
   never an orphan. Auto-fit would otherwise resolve to three columns at some
   widths and print eight as 3 + 3 + 2. Every other count is left alone — three
   pillars still stretch across the full width as they always have. */
.wels-pillar-grid[data-count="4"],
.wels-pillar-grid[data-count="8"] { grid-template-columns: repeat(4, 1fr); }

/* With four per row, the rule belongs on every tile but the first of each row. */
.wels-pillar-grid[data-count="8"] .wels-pillar:nth-child(4n + 1) { border-left: 0; }

@media (max-width: 860px) {
	.wels-pillar-grid,
	.wels-pillar-grid[data-count="4"],
	.wels-pillar-grid[data-count="8"] { grid-template-columns: repeat(2, 1fr); gap: 26px 0; }
	/* With two per row, only the right-hand one of each pair keeps a rule. */
	.wels-pillar { border-left: 0; }
	.wels-pillar:nth-child(2n) { border-left: 1px solid rgba(30, 42, 42, 0.12); }
}
@media (max-width: 520px) {
	/* The pinned counts have to be repeated at every breakpoint below the one
	   that set them: a class-plus-attribute selector outranks the bare class,
	   and a media query adds no weight of its own, so the desktop pin would
	   otherwise hold four columns on a phone. */
	.wels-pillar-grid,
	.wels-pillar-grid[data-count="4"],
	.wels-pillar-grid[data-count="8"] { grid-template-columns: 1fr; gap: 22px 0; }
	.wels-pillar,
	.wels-pillar:nth-child(2n) { border-left: 0; padding: 0 8px; }
}

/* ---------------------------------------------------------------------------
 * Parent portal
 *
 * A single quiet band: what the portal is on the left, the way in on the
 * right. Same shape as the Pay Fee band so the two sit together without
 * arguing.
 * ------------------------------------------------------------------------ */
.wels-portal { background: var(--wels-primary); color: #fff; }
.wels-portal-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 20px 32px;
}
.wels-portal-copy { min-width: 0; flex: 1 1 320px; }
.wels-portal .wels-section-title { color: #fff; margin: 0 0 8px; }
.wels-portal-text { margin: 0; color: rgba(255, 255, 255, 0.86); max-width: 56ch; }
.wels-portal-links {
	list-style: none;
	margin: 12px 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px 20px;
}
.wels-portal-links a {
	color: #fff;
	font-size: .9rem;
	text-decoration: underline;
	text-underline-offset: 3px;
	overflow-wrap: anywhere;
}
.wels-portal-links a:hover,
.wels-portal-links a:focus-visible { text-decoration-thickness: 2px; }
.wels-portal-action { flex: 0 0 auto; }

@media (max-width: 600px) {
	.wels-portal-inner { display: block; }
	.wels-portal-action { margin-top: 18px; }
	.wels-portal-btn { display: block; text-align: center; }
}

/* ===========================================================================
 * Crest header layout
 *
 * A coloured bar with the menu split either side of the school crest, which
 * hangs below the bar's lower edge. The crest is absolutely centred rather
 * than being a flex child, so an odd number of menu items cannot drag it off
 * centre; the spacer the walker inserts keeps the links clear of it.
 *
 * Below 1080px there is not enough room to split a menu around a crest, so
 * the layout falls back to crest-left / hamburger-right and the whole menu
 * moves into the off-canvas panel.
 * ======================================================================== */
.wels-header-crest {
	background: var(--wels-primary);
	color: #fff;
	/* The crest hangs past the bar; nothing may clip it. */
	overflow: visible;
}
.wels-header-crest .wels-header-inner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 74px;
	/* The bar's height comes from the links inside it, not from padding —
	   otherwise the crest cannot hang below its edge, it just makes the bar
	   taller. */
	padding-top: 0;
	padding-bottom: 0;
	gap: 0;
}
/*
 * Two equal columns that meet at the centre of the bar. Because they are
 * equal, the join is always the centre line, and that is where the crest is,
 * whatever the labels say. Each column then holds its links clear of the
 * crest with a little padding at the join.
 */
.wels-header-crest .wels-nav-half {
	flex: 1 1 0;
	min-width: 0;
}
/*
 * The nav is itself a flex container, so the list inside it shrinks to the
 * width of its own links. It has to fill its half before flex-end on one
 * side and flex-start on the other mean anything — otherwise both halves
 * simply sit at their left edge and the bar is lopsided.
 */
.wels-header-crest .wels-nav-half .wels-menu {
	flex: 1 1 auto;
	min-width: 0;
}
.wels-header-crest .wels-nav-left .wels-menu {
	justify-content: flex-end;
	padding-right: 104px;
}
.wels-header-crest .wels-nav-right .wels-menu {
	justify-content: flex-start;
	padding-left: 104px;
}
.wels-header-crest .wels-menu {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: nowrap;
	gap: 26px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.wels-header-crest .wels-menu > .wels-menu-item > a {
	color: #fff;
	font-weight: 600;
	padding: 23px 0;
	display: inline-block;
	white-space: nowrap;
}
/*
 * The theme's underline is inset 16px either side and sits 6px off the
 * bottom, which suits a link with horizontal padding on a white bar. Here
 * the links have none, so it is pulled in under the word itself and lifted
 * clear of the bar's edge — otherwise it reads as a stray mark floating
 * below the bar rather than as an underline.
 */
.wels-header-crest .wels-menu > .wels-menu-item > a::after {
	left: 0;
	right: 0;
	bottom: 15px;
}

/* ---------------------------------------------------------------------------
 * Plain dropdowns in the crest bar
 *
 * Same spacing and colour as the panel, so the two kinds of menu read as
 * one system rather than two. The card starts flush under its own item and
 * has enough padding that the first link is not jammed against the corner.
 * ------------------------------------------------------------------------ */
.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu {
	padding: 22px 26px;
	min-width: 264px;
	border-radius: 10px;
	border: 0;
	box-shadow: 0 26px 54px rgba(43, 31, 48, .22), 0 2px 6px rgba(43, 31, 48, .08);
}
.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu > li + li {
	margin-top: 16px;
}
.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu a {
	display: block;
	padding: 0;
	border-radius: 0;
	font-size: 1rem;
	line-height: 1.35;
	font-weight: 500;
	color: var(--wels-primary);
}
.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu a {
	padding: 8px 12px;
	margin: -8px -12px;
	border-radius: 8px;
	transition: background .16s ease, box-shadow .16s ease, color .16s ease;
}
.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu a:hover {
	text-decoration: none;
	color: var(--wels-primary-dark);
	background: #f4edf7;
	box-shadow: 0 6px 16px rgba(43, 31, 48, .14);
}
.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu a:focus-visible {
	background: none;
	text-decoration: none;
	color: var(--wels-primary-dark);
	outline: 2px solid currentColor;
	outline-offset: 3px;
	border-radius: 2px;
}
.wels-header-crest .wels-submenu-toggle { color: #fff; }

/* The space the crest occupies. */
.wels-header-crest .wels-crest {
	position: absolute;
	left: 50%;
	top: 8px;
	transform: translateX(-50%);
	z-index: 3;
	display: block;
	line-height: 0;
}
.wels-crest-img {
	display: block;
	width: auto;
	height: 94px;
	max-width: 172px;
	object-fit: contain;
	/* The overhang: the crest drops below the bar and casts a soft shadow so
	   it reads as sitting in front of it rather than punched through it. */
	filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.28));
}
.wels-crest-fallback {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 84px;
	height: 84px;
	border-radius: 50%;
	background: #fff;
	color: var(--wels-primary);
	font-weight: 800;
	font-size: 1.4rem;
	letter-spacing: .04em;
	line-height: 1;
}
.wels-header-crest .wels-header-right {
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	gap: 10px;
}

/* ---------------------------------------------------------------------------
 * Mega panel
 * ------------------------------------------------------------------------ */
/*
 * Only a panel is positioned against the whole bar — it has to span it.
 * An ordinary dropdown stays anchored to its own menu item, or it opens
 * under whichever item happens to be first in the row.
 */
.wels-header-crest .wels-menu-item { position: relative; }
.wels-header-crest .wels-menu-item.wels-has-mega { position: static; }

.wels-mega {
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	background: #fff;
	color: var(--wels-ink);
	box-shadow: 0 26px 54px rgba(43, 31, 48, .22), 0 2px 6px rgba(43, 31, 48, .08);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-6px);
	transition: opacity .16s ease, transform .16s ease, visibility .16s;
	/* Belt and braces: a closed panel is not a surface you can point at. */
	pointer-events: none;
	z-index: 40;
}
.wels-has-mega:hover > .wels-mega,
.wels-has-mega:focus-within > .wels-mega,
.wels-has-mega.is-open > .wels-mega {
	opacity: 1;
	visibility: visible;
	transform: none;
	pointer-events: auto;
}
/*
 * Spacing measured off the reference panel rather than guessed: about 44px
 * of air above the headings, 26px from a heading to its first link, and
 * 19px between links. A panel is briefly a page of its own — it should
 * breathe like one, not read like a squashed dropdown.
 */
.wels-mega-inner {
	display: flex;
	/*
	 * Stretch, not flex-start: the photograph then matches the height of
	 * the columns beside it instead of hanging below them and leaving the
	 * left half of the panel looking empty.
	 */
	align-items: stretch;
	gap: 56px;
	/*
	 * Horizontal padding matters as much as vertical here. Writing it as
	 * "44px 0 46px" silently zeroed the container's own side padding, so the
	 * headings sat hard against the panel's left edge and the photograph
	 * against its right.
	 */
	padding: 44px 44px 46px;
}
/*
 * The two lists inside a panel are still .wels-sub-menu, so the ordinary
 * dropdown rules apply to them — absolutely positioned, invisible until
 * hovered, on their own white card. Inside a panel none of that is wanted:
 * the panel itself is the card, and its columns are simply laid out in it.
 */
.wels-mega .wels-mega-cols,
.wels-mega .wels-mega-list {
	position: static;
	opacity: 1;
	/*
	 * inherit, never visible. The panel above these is visibility:hidden
	 * until it opens; forcing its children visible puts them back in the
	 * hit-testing tree, so the closed panel still catches the mouse right
	 * across the page and opens itself.
	 */
	visibility: inherit;
	transform: none;
	transition: none;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	min-width: 0;
	padding: 0;
	top: auto;
	left: auto;
}
.wels-mega .wels-mega-list a {
	/*
	 * Must match the negative margin on .wels-mega-list a exactly. The two
	 * cancel out, so the hover chip can sit around the words while the words
	 * themselves stay flush with the column heading above them.
	 */
	padding: 8px 12px;
	border-radius: 8px;
	font-weight: 500;
}
/*
 * This sits at the same specificity as the reset above, so the hover chip
 * survives. It has to carry the tint and the shadow itself — a lower-
 * specificity rule elsewhere would be overridden and the panel would hover
 * differently from the plain dropdowns.
 */
.wels-mega .wels-mega-list a:hover {
	background: #f4edf7;
	box-shadow: 0 6px 16px rgba(43, 31, 48, .14);
	color: var(--wels-primary-dark);
}

.wels-mega-cols {
	display: flex;
	flex-wrap: wrap;
	gap: 36px 60px;
	flex: 1 1 auto;
	margin: 0;
	padding: 0;
	list-style: none;
	min-width: 0;
}
/*
 * Columns are as wide as their own labels, not equal slices of the panel.
 * An equal-width grid stretches three short lists across the whole width
 * and puts the leftover space between them, which reads as a gap rather
 * than as columns.
 */
/*
 * Equal columns, but capped. Sized purely to their labels they bunch up on
 * the left and leave a void before the picture; given the whole width each
 * they drift so far apart they stop reading as a group. 220px is wide
 * enough for the longest label here and narrow enough to stay a column.
 */
.wels-mega-col { min-width: 0; flex: 1 1 0; max-width: 220px; }
.wels-mega-heading {
	display: block;
	margin-bottom: 26px;
	font-weight: 700;
	font-size: 1.16rem;
	line-height: 1.3;
	color: var(--wels-ink);
	text-decoration: none;
}
a.wels-mega-heading:hover { color: var(--wels-primary-dark); }
a.wels-mega-heading:focus-visible {
	color: var(--wels-primary-dark);
	outline: 2px solid currentColor;
	outline-offset: 3px;
}
.wels-mega-list { list-style: none; margin: 0; padding: 0; }
.wels-mega-list > li + li { margin-top: 19px; }
.wels-mega-list a {
	/* The school's own colour, the way the reference uses its navy: the
	   links read as links without an underline sitting there. */
	color: var(--wels-primary);
	text-decoration: none;
	font-size: 1rem;
	line-height: 1.35;
	overflow-wrap: anywhere;
}
/*
 * Hover deepens the colour rather than underlining. An underline appearing
 * under the cursor in a menu is restless — the whole list twitches as the
 * pointer crosses it. Keyboard focus still gets a ring, because colour on
 * its own is not enough to show where the focus is.
 */
/*
 * The negative margin cancels the padding, so the tinted chip appears
 * around the words on hover without any of them shifting position.
 */
.wels-mega-list a {
	margin: -8px -12px;
	transition: background .16s ease, box-shadow .16s ease, color .16s ease;
}
.wels-mega-list a:hover {
	color: var(--wels-primary-dark);
	background: #f4edf7;
	box-shadow: 0 6px 16px rgba(43, 31, 48, .14);
}
.wels-mega-list a:focus-visible {
	color: var(--wels-primary-dark);
	outline: 2px solid currentColor;
	outline-offset: 3px;
	border-radius: 2px;
}
.wels-mega-figure {
	flex: 0 0 400px;
	max-width: 400px;
	min-height: 210px;
	margin-left: auto;
	line-height: 0;
}
.wels-mega-figure img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 8px;
}

@media (max-width: 1280px) {
	.wels-mega-figure { flex-basis: 300px; max-width: 300px; }
}
@media (max-width: 1080px) {
	.wels-mega-figure { display: none; }
}

/* ---------------------------------------------------------------------------
 * Narrow screens: no split menu, no panels — the off-canvas menu takes over.
 * ------------------------------------------------------------------------ */
@media (max-width: 1080px) {
	.wels-header-crest .wels-header-inner {
		justify-content: flex-start;
		min-height: 62px;
	}
	.wels-header-crest .wels-primary-nav,
	.wels-header-crest .wels-nav-half { display: none; }
	/* The crest stays centred and overhanging here too. */
	.wels-crest-img { height: 72px; max-width: 128px; }
	.wels-crest-fallback { width: 56px; height: 56px; font-size: 1.05rem; }
}

/* In the off-canvas panel a panel is just a nested list — the toggle button
   the walker prints opens and closes it. */
.wels-mobile-nav .wels-mega {
	position: static;
	opacity: 1;
	visibility: visible;
	transform: none;
	box-shadow: none;
	background: transparent;
	pointer-events: auto;
}
.wels-mobile-nav .wels-mega-inner { display: block; padding: 0; }
.wels-mobile-nav .wels-mega-cols { display: block; }
.wels-mobile-nav .wels-mega-col + .wels-mega-col { margin-top: 14px; }
.wels-mobile-nav .wels-mega-figure { display: none; }

@media (prefers-reduced-motion: reduce) {
	.wels-mega,
	.wels-mega-list a,
	.wels-header-crest .wels-menu > .wels-menu-item > .wels-sub-menu a { transition: none; }
}

/* ---------------------------------------------------------------------------
 * When the split menu will not fit
 *
 * The crest layout only works while both halves of the menu have room. Add
 * enough items, or long enough labels, and the last one slides under the
 * action buttons pinned to the right of the bar. Rather than letting that
 * happen silently, main.js measures the bar and sets this class, which hands
 * the whole menu to the off-canvas panel — the same thing that happens on a
 * narrow screen. Nothing is ever hidden or overlapped; the school just sees
 * the hamburger appear and knows the menu has outgrown the bar.
 * ------------------------------------------------------------------------ */
.wels-header-crest.is-nav-collapsed .wels-nav-half { display: none; }
.wels-header-crest.is-nav-collapsed .wels-nav-toggle { display: block; }
/*
 * The crest does not move. Whatever the menu is doing, it stays centred and
 * overhanging — it is the fixed point of this header, not a flexible item
 * that gets pushed aside when something else needs room.
 */
.wels-header-crest.is-nav-collapsed .wels-header-inner { justify-content: flex-start; }
.wels-header-crest .wels-nav-toggle-bar,
.wels-header-crest .wels-nav-toggle-bar::before,
.wels-header-crest .wels-nav-toggle-bar::after { background: #fff; }

/* ===========================================================================
 * Activities, in full
 *
 * One activity per row, photograph and words swapping sides down the page.
 * The swap is done with grid column placement rather than row-reverse, so
 * the reading order in the markup stays title-then-text whichever side the
 * picture is on — a screen reader hears the same thing on every row.
 * ======================================================================== */
.wels-activities-full { background: var(--wels-bg); }

.wels-act-lead { max-width: 760px; margin-bottom: 44px; }
.wels-act-eyebrow {
	margin: 0 0 10px;
	font-size: .78rem;
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--wels-muted);
}
.wels-act-heading {
	margin: 0 0 14px;
	font-size: var(--wels-h2);
	line-height: 1.22;
	color: var(--wels-ink);
}
.wels-act-intro { margin: 0; color: var(--wels-muted); line-height: 1.65; }

.wels-act-rows { display: flex; flex-direction: column; }

.wels-act-row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	align-items: center;
	gap: 40px;
	padding: 34px 0;
	border-top: 1px solid rgba(43, 31, 48, .09);
}
.wels-act-row:first-child { border-top: 0; }

.wels-act-media { grid-column: 1; grid-row: 1; line-height: 0; }
.wels-act-body { grid-column: 2; grid-row: 1; min-width: 0; }
.wels-act-row.is-flipped .wels-act-media { grid-column: 2; }
.wels-act-row.is-flipped .wels-act-body { grid-column: 1; }

.wels-act-media img {
	width: 100%;
	height: auto;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	border-radius: 6px;
	box-shadow: 0 10px 26px rgba(43, 31, 48, .12);
}

.wels-act-head { display: flex; align-items: center; gap: 14px; margin-bottom: 8px; }
.wels-act-badge {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	background: color-mix(in srgb, var(--wels-primary) 10%, transparent);
	color: var(--wels-primary);
}
.wels-act-icon { width: 24px; height: 24px; }
.wels-act-title {
	margin: 0;
	font-size: 1.42rem;
	line-height: 1.2;
	color: var(--wels-primary);
}
.wels-act-tagline {
	margin: 0 0 12px;
	/* The accent darkened until it is readable as text — see inc/dynamic-css.php. */
	color: var(--wels-accent-text, #8b6f00);
	font-size: .98rem;
}
.wels-act-text { color: var(--wels-muted); line-height: 1.7; }
.wels-act-text p { margin: 0 0 12px; }
.wels-act-text p:last-child { margin-bottom: 0; }

.wels-act-points { list-style: none; margin: 14px 0 0; padding: 0; }
.wels-act-points li {
	position: relative;
	padding-left: 18px;
	margin-bottom: 7px;
	color: var(--wels-muted);
	font-size: .95rem;
}
.wels-act-points li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .55em;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--wels-accent);
}

.wels-act-btn {
	margin-top: 20px;
	background: var(--wels-primary);
	color: #fff;
	display: inline-flex;
	align-items: center;
	gap: 10px;
}
.wels-act-btn:hover,
.wels-act-btn:focus-visible { background: var(--wels-primary-dark); color: #fff; }
.wels-act-arrow { transition: transform .16s ease; }
.wels-act-btn:hover .wels-act-arrow { transform: translateX(3px); }

@media (max-width: 860px) {
	/* Stack, and put the picture above the words on every row — alternating
	   sides means nothing in a single column, and a photo that sometimes
	   comes after its own heading reads as a mistake. */
	.wels-act-row {
		grid-template-columns: 1fr;
		gap: 20px;
		padding: 28px 0;
	}
	.wels-act-media,
	.wels-act-row.is-flipped .wels-act-media { grid-column: 1; grid-row: 1; }
	.wels-act-body,
	.wels-act-row.is-flipped .wels-act-body { grid-column: 1; grid-row: 2; }
	.wels-act-title { font-size: 1.24rem; }
}

@media (prefers-reduced-motion: reduce) {
	.wels-act-arrow { transition: none; }
	.wels-act-btn:hover .wels-act-arrow { transform: none; }
}

/* A homepage section that shows only the first few, and a way to the rest. */
.wels-card-more { margin: 34px 0 0; text-align: center; }
.wels-card-more .wels-btn {
	display: inline-flex;
	align-items: center;
	gap: 10px;
}

/* ===========================================================================
 * Interior page banner
 *
 * The page's name over a photograph, with the trail home underneath. Every
 * page that is not the homepage opens with this, so the site holds together
 * rather than each page starting from a blank sheet.
 *
 * The wash over the photograph is not decoration: white text on an
 * unpredictable photograph is unreadable, and the school will change this
 * picture without asking anyone. The gradient guarantees the contrast
 * whatever they choose.
 * ======================================================================== */
.wels-page-banner {
	position: relative;
	background: var(--wels-primary);
	background-size: cover;
	background-position: center;
	color: #fff;
	padding: 68px 0 60px;
	text-align: center;
	overflow: hidden;
}
.wels-page-banner.has-photo::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		color-mix(in srgb, var(--wels-primary-dark) 78%, transparent) 0%,
		color-mix(in srgb, var(--wels-primary-dark) 62%, transparent) 100%
	);
}
/* No photograph: the crest, large and very faint, instead of repeating one
   campus picture across every page that has none. Decorative only — the
   crest is already in the header with the school's name beside it, so this
   copy is hidden from screen readers by being a background. */
.wels-page-banner:not(.has-photo)::after {
	content: "";
	position: absolute;
	top: 50%; right: clamp(-40px, -2vw, 0px);
	transform: translateY(-50%);
	width: clamp(220px, 34vw, 420px);
	aspect-ratio: 1;
	background-image: var(--wels-crest, none);
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
	opacity: .10;
	pointer-events: none;
}
@media (max-width: 720px) {
	.wels-page-banner:not(.has-photo)::after { opacity: .07; right: -60px; }
}

.wels-page-banner-inner { position: relative; }

.wels-page-banner-title {
	margin: 0;
	color: #fff;
	font-size: clamp(1.8rem, 4.4vw, 2.9rem);
	line-height: 1.16;
	letter-spacing: .01em;
	text-shadow: 0 2px 12px rgba(0, 0, 0, .35);
}
.wels-page-banner-title::after {
	content: "";
	display: block;
	width: 58px;
	height: 3px;
	margin: 16px auto 0;
	border-radius: 2px;
	background: var(--wels-accent);
}
.wels-page-banner-sub {
	margin: 16px auto 0;
	max-width: 62ch;
	color: rgba(255, 255, 255, .92);
	font-size: 1.02rem;
	line-height: 1.6;
	text-shadow: 0 1px 8px rgba(0, 0, 0, .3);
}

/* ---------------------------------------------------------------------------
 * Breadcrumb
 * ------------------------------------------------------------------------ */
.wels-crumbs { margin-top: 20px; }
.wels-crumbs ol {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 6px 10px;
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: .88rem;
}
.wels-crumbs li { display: inline-flex; align-items: center; gap: 10px; }
.wels-crumbs li + li::before {
	content: "/";
	opacity: .55;
}
.wels-crumbs a { color: rgba(255, 255, 255, .88); text-decoration: none; }
.wels-crumbs a:hover,
.wels-crumbs a:focus-visible { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.wels-crumbs [aria-current="page"] { color: #fff; font-weight: 600; }

/* The page body no longer needs to open with its own top margin — the
   banner has already given the page a head. */
.wels-page-banner + .wels-page-body,
.wels-page-banner + .wels-container { padding-top: 46px; }

@media (max-width: 680px) {
	.wels-page-banner { padding: 46px 0 40px; }
	.wels-page-banner-sub { font-size: .95rem; }
	.wels-crumbs ol { font-size: .82rem; }
}

/* A school-supplied icon sits in the same circle as the built-in one, and
   is contained rather than cropped — a logo or a crest must not lose its
   edges to a square fill. */
.wels-act-icon-img {
	width: 26px;
	height: 26px;
	object-fit: contain;
	display: block;
}


/* ---------- Admission process ----------
   A numbered list that still reads as a list when the CSS never arrives:
   it is a real <ol>, the marker is suppressed and the number redrawn, so the
   order survives a stylesheet failure, a screen reader and a printout.
   The icon is optional and sits beside the number rather than instead of it,
   because the number is the part a parent is actually using. */
.wels-adm-subhead {
	font-size: clamp(1.15rem, 2vw, 1.4rem); margin: 0 0 18px;
}
.wels-adm-steps {
	list-style: none; margin: 0 0 clamp(32px, 4vw, 48px); padding: 0;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: clamp(16px, 2.2vw, 24px);
}
.wels-adm-step {
	display: flex; flex-direction: column; gap: 12px;
	background: #fff; border: 1px solid rgba(20,40,38,.1); border-radius: var(--wels-radius);
	box-shadow: var(--wels-shadow-sm); padding: 22px 22px 24px;
}
.wels-step-mark { display: flex; align-items: center; gap: 10px; }
.wels-step-num {
	display: grid; place-items: center; flex: 0 0 auto;
	width: 38px; height: 38px; border-radius: 50%;
	background: var(--wels-primary); color: #fff;
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 1.05rem; line-height: 1;
}
.wels-step-glyph { display: inline-flex; color: var(--wels-accent-text, var(--wels-accent)); }
.wels-step-icon { width: 24px; height: 24px; }
.wels-step-icon-img { width: 28px; height: 28px; object-fit: contain; display: block; }
.wels-step-title { font-size: 1.05rem; margin: 0; }
.wels-step-when {
	align-self: flex-start; margin: -4px 0 0;
	background: var(--wels-alt-bg); color: var(--wels-accent-text, var(--wels-primary));
	font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
	padding: 4px 10px; border-radius: 999px;
}
.wels-step-text { margin: 0; color: var(--wels-muted); font-size: 0.95rem; }

/* The documents list. Two columns once there is room, because six short
   lines down one side of a wide screen looks like an oversight. */
.wels-adm-docs {
	background: var(--wels-alt-bg); border-radius: var(--wels-radius);
	padding: clamp(22px, 3vw, 32px);
}
.wels-adm-docs .wels-adm-subhead { margin-bottom: 14px; }
.wels-adm-doclist {
	margin: 0; padding: 0; list-style: none;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 10px 28px;
}
.wels-adm-doclist li {
	position: relative; padding-left: 28px; line-height: 1.5;
}
.wels-adm-doclist li::before {
	content: ""; position: absolute; left: 4px; top: .45em;
	width: 11px; height: 6px; border-left: 2px solid var(--wels-accent);
	border-bottom: 2px solid var(--wels-accent); transform: rotate(-45deg);
}
.wels-adm-foot {
	display: flex; flex-wrap: wrap; align-items: center; gap: 16px 22px;
	margin-top: clamp(24px, 3vw, 34px);
}
.wels-adm-note { margin: 0; color: var(--wels-muted); font-size: 0.95rem; flex: 1 1 260px; }


/* ---------- Fee table ----------
   The class column is a <th scope="row">, so a screen reader reading across
   "Admission Fee: 5,000" still says which class it belongs to. Amounts are
   tabular-nums and right-aligned, which is the only way a column of money
   can be compared down the page. */
.wels-fee-block { margin: 0 0 clamp(24px, 3vw, 36px); }
.wels-fee-heading { font-size: var(--wels-h2); margin: 0 0 6px; }
.wels-fee-effective {
	margin: 0 0 18px; color: var(--wels-accent-text, var(--wels-primary));
	font-weight: 600; font-size: 0.95rem;
}
.wels-fee-table th[scope="row"] { font-weight: 600; color: var(--wels-ink); }
.wels-fee-class { white-space: nowrap; }
.wels-fee-rownote {
	display: block; font-weight: 400; font-size: 0.82rem; color: var(--wels-muted);
	white-space: normal;
}
.wels-fee-amt {
	text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.wels-fee-table thead th:not(:first-child):not(:nth-child(2)) { text-align: right; }
.wels-fee-blank { color: var(--wels-muted); }
.wels-fee-pending {
	background: var(--wels-alt-bg); border-radius: var(--wels-radius);
	padding: clamp(20px, 3vw, 28px); margin: 0; color: var(--wels-muted);
}
.wels-fee-note {
	margin-top: 16px; color: var(--wels-muted); font-size: 0.92rem;
}
.wels-fee-note p { margin: 0 0 6px; }
.wels-fee-note p:last-child { margin-bottom: 0; }

/* ---------- Card icon, while the photograph is still being collected ----------
   A tinted band the same height as the top of a photographed card, so a grid
   that mixes the two does not step up and down. When the photograph arrives
   it simply replaces this, and nothing else about the card changes. */
.wels-card-icon-svg {
	padding: 0; display: grid; place-items: center;
	height: 190px; background: var(--wels-alt-bg);
	border-bottom: 1px solid rgba(20,40,38,.08);
}
.wels-card-glyph {
	width: 54px; height: 54px; color: var(--wels-primary); opacity: .85;
}
.wels-facilities-full .wels-card-icon-svg { height: 150px; }
.wels-facilities-full .wels-card-glyph { width: 46px; height: 46px; }





/* ---------- Interior page with a section sidebar ----------
   A 3:1 split: the page's own content on the left, a short vertical menu on
   the right. The sidebar is optional at every level — no menu assigned, no
   aside in the markup, and the main column takes the full width. */
.wels-withside {
	display: grid; grid-template-columns: minmax(0, 3fr) minmax(220px, 1fr);
	gap: clamp(28px, 4vw, 56px); align-items: start;
}
.wels-withside.has-no-side { grid-template-columns: minmax(0, 1fr); }

.wels-sidenav {
	position: sticky; top: 96px;
	background: var(--wels-alt-bg); border-radius: var(--wels-radius);
	padding: 10px;
}
.wels-sidenav-list { list-style: none; margin: 0; padding: 0; }
.wels-sidenav-list li + li { border-top: 1px solid rgba(20,40,38,.09); }
.wels-sidenav-list a {
	display: block; padding: 13px 16px; border-radius: 9px;
	color: var(--wels-ink); font-weight: 600; font-size: 0.95rem;
	text-decoration: none; transition: background .16s ease, color .16s ease;
}
.wels-sidenav-list a:hover,
.wels-sidenav-list a:focus-visible {
	background: rgba(20,40,38,.07); color: var(--wels-primary); text-decoration: none;
}
/* WordPress marks the page you are on, so nothing here is maintained by hand. */
.wels-sidenav-list .current-menu-item > a,
.wels-sidenav-list .current_page_item > a,
.wels-sidenav-list .current-menu-ancestor > a {
	background: var(--wels-primary); color: #fff;
}
.wels-sidenav-list .current-menu-item > a:hover,
.wels-sidenav-list .current_page_item > a:hover {
	background: var(--wels-primary-dark, var(--wels-primary)); color: #fff;
}

/* ---------- A facility, stacked ---------- */
.wels-fblocks-heading { font-size: clamp(1.5rem, 3vw, 2.1rem); margin: 0 0 8px; }
.wels-fblock-group { margin: 0 0 clamp(32px, 4vw, 48px); }
.wels-fblock-grouptitle {
	font-size: var(--wels-h3); margin: 0 0 8px;
	text-transform: uppercase; letter-spacing: .04em;
}
.wels-fblock-groupintro { margin: 0 0 20px; color: var(--wels-muted); line-height: 1.65; }
.wels-fblock-stack { display: flex; flex-direction: column; gap: 14px; }

/* One column by default. The media column is added by PHP, which knows
   whether there is anything to put in it — rather than by :has(), which
   would leave older browsers with a 104px hole down the side. */
.wels-fblock {
	display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px;
	align-items: center;
	background: #fff; border: 1px solid rgba(20,40,38,.1);
	border-radius: var(--wels-radius); box-shadow: var(--wels-shadow-sm);
	padding: 18px 22px;
}
.wels-fblock.has-media { grid-template-columns: 104px minmax(0, 1fr); }
.wels-fblock:not(.has-media) .wels-fblock-media { display: none; }

.wels-fblock-media { display: grid; place-items: center; }
.wels-fblock-img {
	width: 104px; height: 78px; object-fit: cover; border-radius: 10px; display: block;
}
.wels-fblock-iconimg { width: 56px; height: 56px; object-fit: contain; display: block; }
.wels-fblock-glyph {
	display: grid; place-items: center;
	width: 72px; height: 72px; border-radius: 50%;
	background: var(--wels-alt-bg); color: var(--wels-primary);
}
.wels-fblock-svg { width: 34px; height: 34px; }
.wels-fblock-title { font-size: 1.1rem; margin: 0 0 6px; }
.wels-fblock-text { margin: 0; color: var(--wels-muted); font-size: 0.95rem; line-height: 1.6; }

/* ---------- School timings ---------- */
.wels-timings { margin: clamp(32px, 4vw, 48px) 0 0; }
.wels-timings-title { font-size: clamp(1.2rem, 2.4vw, 1.6rem); margin: 0 0 14px; }
.wels-timings-table th[scope="row"] { font-weight: 600; color: var(--wels-ink); }
.wels-timings-note { margin: 14px 0 0; color: var(--wels-muted); font-size: 0.92rem; }

@media (max-width: 900px) {
	.wels-withside { grid-template-columns: minmax(0, 1fr); }
	/* The menu goes under the content on a phone: somebody who has opened
	   this page is here for the page, not for the way out of it. */
	.wels-withside-side { order: 2; }
	.wels-sidenav { position: static; }
}
@media (max-width: 560px) {
	.wels-fblock { grid-template-columns: minmax(0, 1fr); gap: 14px; }
	.wels-fblock-media { justify-items: start; place-items: center start; }
}


/* ---------- A facility, as an accordion row ----------
   The icon stays on the summary, so a closed list still reads as a list of
   places rather than a stack of grey bars. The open panel carries the colour
   because one open panel is the thing the eye should land on. */
/* ---------- A group: the list on one side, its picture on the other ----------
   The first group has its list on the left; every group after it swaps. The
   swap is done with grid columns, not by reordering the source, so the list
   always comes first for a keyboard and a screen reader however the band is
   drawn.

   The picture keeps a 4:3 shape rather than stretching to the height of the
   list. Left to stretch, a group of eight items dragged its photograph into a
   tall crop and towered over a group of five. */
.wels-fgrp { margin: 0 0 var(--wels-band-rhythm); }
.wels-fgrp:last-child { margin-bottom: 0; }
.wels-fgrp-lead { max-width: 900px; margin: 0 0 clamp(16px, 2.4vw, 24px); }

.wels-fgrp-row {
	display: grid;
	/* Content first, photograph second — and swapped when flipped. The
	   split is asymmetric now: a list of facilities wants more room than
	   the photograph beside it, and the same split is used by every band. */
	grid-template-columns: minmax(0, 1fr) var(--wels-band-media);
	gap: var(--wels-band-gap); align-items: start;
}
.wels-fgrp.is-flipped .wels-fgrp-row {
	grid-template-columns: var(--wels-band-media) minmax(0, 1fr);
}
.wels-facx-list { grid-row: 1; grid-column: 1; }
.wels-fgrp-photo { grid-row: 1; grid-column: 2; position: relative; aspect-ratio: var(--wels-band-ratio); }
.wels-fgrp.is-flipped .wels-facx-list  { grid-column: 2; }
.wels-fgrp.is-flipped .wels-fgrp-photo { grid-column: 1; }

/* Taken out of flow and pinned to its cell: an image left in flow has to
   negotiate a height with a parent whose height comes from the row, and it
   loses — it collapses to a sliver. */
.wels-fgrp-photo-img {
	position: absolute; inset: 0; display: block;
	width: 100%; height: 100%;
	object-fit: cover; border-radius: var(--wels-radius);
	box-shadow: var(--wels-band-shadow);
}

/* No picture yet: the list takes the whole width. Stacked down one column a
   long list makes its band tower over the others, so it runs in columns
   instead. grid-column matters here — the base rule puts the list in column
   1, but on a one-column row an explicit column 2 would conjure an implicit
   second column and squeeze the list into a third of the width. */
.wels-fgrp.has-no-photo .wels-fgrp-row { grid-template-columns: 1fr; }
.wels-fgrp.has-no-photo .wels-facx-list {
	grid-column: 1;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: 8px 24px; align-content: start;
}
.wels-fgrp.has-no-photo .wels-facx { align-self: start; }

@media (max-width: 860px) {
	.wels-fgrp-row { grid-template-columns: 1fr; }
	.wels-facx-list,
	.wels-fgrp.is-flipped .wels-facx-list { grid-row: 2; grid-column: 1; }
	.wels-fgrp-photo,
	.wels-fgrp.is-flipped .wels-fgrp-photo { grid-row: 1; grid-column: 1; aspect-ratio: 16 / 10; }
}
.wels-facx-list { display: flex; flex-direction: column; gap: 8px; }
.wels-facx { border-radius: 10px; overflow: hidden; }
.wels-facx-summary {
	display: flex; align-items: center; gap: 14px;
	padding: 13px 18px; cursor: pointer; list-style: none;
	background: var(--wels-alt-bg); color: var(--wels-ink);
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 1rem;
	transition: background .18s ease, color .18s ease;
}
.wels-facx-summary::-webkit-details-marker { display: none; }
.wels-facx-summary:hover { background: rgba(20,40,38,.08); }
.wels-facx[open] .wels-facx-summary { background: var(--wels-primary); color: #fff; }
.wels-facx[open] .wels-facx-summary:hover { background: var(--wels-primary-dark, var(--wels-primary)); }
.wels-facx-summary:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: -3px; }

.wels-facx-name { flex: 1 1 auto; }
.wels-facx-icon { display: inline-flex; flex: 0 0 auto; color: currentColor; }
.wels-facx-svg { width: 22px; height: 22px; }
.wels-facx-iconimg { width: 24px; height: 24px; object-fit: contain; display: block; }

/* Drawn rather than typed, so it never picks up a font's idea of a minus. */
.wels-facx-sign { position: relative; flex: 0 0 auto; width: 14px; height: 14px; }
.wels-facx-sign::before,
.wels-facx-sign::after {
	content: ""; position: absolute; left: 0; top: 6px;
	width: 14px; height: 2px; border-radius: 2px; background: currentColor;
	transition: transform .18s ease, opacity .18s ease;
}
.wels-facx-sign::after { transform: rotate(90deg); }
.wels-facx[open] .wels-facx-sign::after { transform: rotate(0deg); opacity: 0; }

.wels-facx-body {
	background: var(--wels-primary); color: #fff;
	padding: 0 18px 16px 52px; font-size: 0.95rem; line-height: 1.65;
}
.wels-facx-body p { margin: 0; }

@media (prefers-reduced-motion: reduce) {
	.wels-facx-summary, .wels-facx-sign::before, .wels-facx-sign::after { transition: none; }
}
@media (max-width: 560px) {
	.wels-facx-body { padding-left: 18px; }
}


/* ---------- Card row that slides sideways ----------
   Built as a scroll container with snap points, which means it is draggable,
   swipeable, keyboard-scrollable and works with no JavaScript at all. The
   arrows and dots are added by the script on top; losing the script costs
   the controls, never the cards. */
.wels-card-grid.is-carousel {
	display: flex; gap: clamp(18px, 3vw, 30px);
	overflow-x: auto; overflow-y: hidden;
	scroll-snap-type: x mandatory;
	/* NO scroll-behavior HERE, deliberately.
	   `scroll-behavior: smooth` next to `scroll-snap-type: x mandatory` makes
	   Chrome swallow every programmatic scroll: both row.scrollTo() and a
	   plain row.scrollLeft = n move the row exactly zero pixels. That killed
	   the arrows and the dots on every carousel on every site — and only for
	   visitors NOT using reduced motion, because the reduced-motion block
	   below switched it back to auto and accidentally fixed it for them.
	   Smoothness belongs to the script, which asks for it per scroll with
	   scrollTo({ behavior: 'smooth' }) and can fall back to an instant jump.
	   This property never affected swiping or dragging — those are the user
	   scrolling, not the page. */
	scroll-padding-left: 2px;
	/* Room for the card shadow, which a scroll container would otherwise clip. */
	padding: 4px 4px 14px;
	margin: -4px -4px -14px;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}
.wels-card-grid.is-carousel::-webkit-scrollbar { display: none; }
.wels-card-grid.is-carousel > .wels-card {
	flex: 0 0 clamp(260px, 30%, 360px);
	scroll-snap-align: start;
}
.wels-card-grid.is-carousel:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: 4px; }

/* The strip of controls under the row. Added by the script, so it is never
   in the markup when it would do nothing. */
.wels-carousel-nav {
	display: flex; align-items: center; justify-content: center; gap: 14px;
	margin-top: 18px;
}
.wels-carousel-btn {
	display: grid; place-items: center; flex: 0 0 auto;
	width: 42px; height: 42px; border-radius: 50%;
	border: 1px solid rgba(20,40,38,.16); background: #fff; color: var(--wels-primary);
	cursor: pointer; transition: background .16s ease, color .16s ease, opacity .16s ease;
}
.wels-carousel-btn:hover:not(:disabled) { background: var(--wels-primary); color: #fff; }
.wels-carousel-btn:disabled { opacity: .35; cursor: default; }
.wels-carousel-btn svg { width: 18px; height: 18px; }
/* One arrow drawn once, flipped for the other direction. */
.wels-carousel-next svg { transform: rotate(180deg); }
.wels-carousel-dots { display: flex; gap: 8px; }
.wels-carousel-dot {
	width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%;
	background: rgba(20,40,38,.22); cursor: pointer;
	transition: background .16s ease, transform .16s ease;
}
.wels-carousel-dot[aria-current="true"] { background: var(--wels-primary); transform: scale(1.25); }
.wels-carousel-dot:focus-visible,
.wels-carousel-btn:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
	/* scroll-behavior is no longer set on the row at all, so there is nothing
	   to switch off here — the script takes the instant path for these
	   visitors by checking the media query itself. */
	.wels-carousel-dot { transition: none; }
}


/* ---------- Facilities on the homepage: collage + classification ----------
   Photographs on one side, the groups listed on the other in a card that
   overlaps them. The overlap is decoration: it is done with a negative
   margin that only applies once there is room for it, so on a narrow screen
   the two simply stack with nothing sitting on top of anything. */
.wels-fachome { background: var(--wels-alt-bg); overflow: hidden; }
.wels-fachome-inner {
	display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	align-items: center; gap: 0;
}
.wels-fachome-inner.has-no-photos { grid-template-columns: minmax(0, 1fr); }

/* The mosaic: one tall photograph beside a stack of smaller ones. With two
   or three the grid collapses gracefully rather than leaving holes. */
.wels-fachome-collage {
	display: grid; gap: 10px;
	grid-template-columns: 1fr 1fr;
	grid-auto-rows: 150px;
}
.wels-fachome-collage[data-count="1"] { grid-template-columns: 1fr; grid-auto-rows: 420px; }
.wels-fachome-collage[data-count="2"] { grid-auto-rows: 260px; }
.wels-fachome-collage[data-count="3"] > .wels-fachome-shot:first-child,
.wels-fachome-collage[data-count="4"] > .wels-fachome-shot:first-child { grid-row: span 2; }

.wels-fachome-shot {
	margin: 0; overflow: hidden; border-radius: var(--wels-radius);
	background: rgba(20,40,38,.06);
}
.wels-fachome-img { width: 100%; height: 100%; object-fit: cover; display: block; }

.wels-fachome-card {
	background: #fff; border-radius: var(--wels-radius);
	box-shadow: 0 18px 50px rgba(20,40,38,.13);
	padding: clamp(26px, 3.4vw, 44px);
	margin-left: -60px; position: relative; z-index: 2;
}
.wels-fachome-inner.has-no-photos .wels-fachome-card { margin-left: 0; }

.wels-fachome-title {
	font-size: clamp(1.5rem, 3vw, 2.15rem); margin: 0 0 12px;
	text-transform: uppercase; letter-spacing: .03em;
}
.wels-fachome-intro { margin: 0 0 24px; color: var(--wels-muted); line-height: 1.7; }

.wels-fachome-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
.wels-fachome-item { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 16px; align-items: start; }
/* No icon set: the row loses the column rather than keeping an empty one. */
.wels-fachome-item:only-child,
.wels-fachome-item > .wels-fachome-body:first-child { grid-column: 1 / -1; }
.wels-fachome-icon { display: grid; place-items: center; color: var(--wels-primary); padding-top: 2px; }
.wels-fachome-svg { width: 30px; height: 30px; }
.wels-fachome-name { font-size: 1.02rem; margin: 0 0 5px; }
.wels-fachome-text { margin: 0; color: var(--wels-muted); font-size: 0.92rem; line-height: 1.6; }
.wels-fachome-more { margin: 26px 0 0; }

@media (max-width: 980px) {
	.wels-fachome-inner { grid-template-columns: minmax(0, 1fr); gap: 0; }
	.wels-fachome-card { margin: -40px 16px 0; }
	.wels-fachome-collage { grid-auto-rows: 130px; }
	.wels-fachome-collage[data-count="1"] { grid-auto-rows: 240px; }
}
@media (max-width: 560px) {
	.wels-fachome-card { margin: -24px 0 0; }
	.wels-fachome-item { grid-template-columns: 36px minmax(0, 1fr); gap: 12px; }
	.wels-fachome-svg { width: 26px; height: 26px; }
}

.wels-fachome-iconimg { width: 34px; height: 34px; object-fit: contain; display: block; }


/* ---------- Apply / Admission strip ----------
   A thin band directly under the hero. A parent arriving in admission season
   wants one of these three and should not scroll past a welcome message to
   find it. Drops to one per line on a phone rather than shrinking the tap
   targets. */
.wels-applynow { background: var(--wels-primary); color: #fff; }
.wels-applynow-list {
	list-style: none; margin: 0; padding: 0;
	display: flex; flex-wrap: wrap; align-items: stretch;
}
.wels-applynow-item { flex: 1 1 200px; display: flex; }
.wels-applynow-item + .wels-applynow-item { border-left: 1px solid rgba(255,255,255,.18); }
.wels-applynow-link {
	flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 10px;
	padding: 18px 22px; color: #fff; text-decoration: none;
	font-family: var(--wels-heading-font); font-weight: 700; font-size: .98rem;
	letter-spacing: .02em; transition: background .16s ease;
}
.wels-applynow-link:hover,
.wels-applynow-link:focus-visible { background: rgba(255,255,255,.12); color: #fff; text-decoration: none; }
.wels-applynow-link:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: -3px; }
.wels-applynow .wels-act-arrow { transition: transform .16s ease; }
.wels-applynow-link:hover .wels-act-arrow { transform: translateX(3px); }

@media (max-width: 600px) {
	.wels-applynow-item { flex: 1 1 100%; }
	.wels-applynow-item + .wels-applynow-item {
		border-left: 0; border-top: 1px solid rgba(255,255,255,.18);
	}
}

/* ---------- Accreditations & affiliations ----------
   The one block a parent checks rather than reads, so the logos are large and
   the heading is small. Logos are set in a row that wraps, greyed back a
   little so a mixed bag of source images sits together, and brought to full
   colour on hover. */
.wels-accreds { padding-top: clamp(34px, 4vw, 52px); padding-bottom: clamp(34px, 4vw, 52px); }
.wels-accreds-title {
	font-size: clamp(1rem, 1.8vw, 1.15rem); margin: 0 0 24px; text-align: center;
	text-transform: uppercase; letter-spacing: .08em; color: var(--wels-muted); font-weight: 700;
}
/* The row scrolls sideways rather than wrapping, so a school can keep adding
   accreditations without the band growing a second and third line and pushing
   the page about.

   `overflow-x: auto` draws nothing at all until the logos actually outgrow the
   container, so one crest or three still sit centred with no scrollbar in
   sight — the scrolling only appears when it is needed, and on a phone that is
   sooner than on a desktop, which is exactly right.

   `safe center` is the important word. A plain centred flex row that overflows
   clips its FIRST items off the left edge and makes them unreachable, because
   there is no scrolling into negative space. `safe` tells the browser to stop
   centring and fall back to the start the moment overflow begins. The plain
   `center` above it is the fallback for anything that does not know the
   keyword. */
.wels-accreds-row {
	list-style: none; margin: 0; padding: 0 0 10px;
	display: flex; flex-wrap: nowrap;
	justify-content: center;
	justify-content: safe center;
	gap: clamp(24px, 4vw, 56px);
	overflow-x: auto; overscroll-behavior-x: contain;
	scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
	scrollbar-width: thin;
}
.wels-accreds-row:focus-visible {
	outline: 2px solid var(--wels-accent); outline-offset: 6px; border-radius: var(--wels-radius);
}
.wels-accred { display: flex; flex: 0 0 auto; scroll-snap-align: center; }
.wels-accred-inner {
	display: flex; flex-direction: column; align-items: center; gap: 8px;
	text-decoration: none; color: var(--wels-ink);
}
a.wels-accred-inner:hover { text-decoration: none; }
.wels-accred-logo {
	max-width: 160px; max-height: 76px; width: auto; height: auto; display: block;
	filter: grayscale(1); opacity: .75;
	transition: filter .18s ease, opacity .18s ease;
}
a.wels-accred-inner:hover .wels-accred-logo,
a.wels-accred-inner:focus-visible .wels-accred-logo { filter: none; opacity: 1; }

/* The greying exists so a mixed bag of source images sits together as a set.
   With one logo there is no set — it is just the school's only accreditation
   looking switched off, and if the record carries no link there is no hover to
   bring it back. So a lone mark keeps its own colour, and the rule undoes
   itself the moment a second one is added. */
.wels-accreds-row > .wels-accred:only-child .wels-accred-logo { filter: none; opacity: 1; }

.wels-accred-name {
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 1.05rem;
	color: var(--wels-primary); text-align: center; max-width: 22em; text-wrap: balance;
}
.wels-accred-note { font-size: .8rem; color: var(--wels-muted); }
a.wels-accred-inner:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: 4px; border-radius: 6px; }

@media (prefers-reduced-motion: reduce) {
	.wels-accred-logo, .wels-applynow-link, .wels-applynow .wels-act-arrow { transition: none; }
}

/* ---------- Houses on the homepage, short form ----------
   A few lines, the four names in their own colours, and a link. The chips are
   the only reason this band looks like houses rather than a paragraph — and
   they carry the names as real text, so the row still reads for somebody who
   cannot separate the red from the green. */
.wels-houses-teaser-text {
	max-width: 68ch; margin: 0 auto; text-align: center;
	color: var(--wels-muted); line-height: 1.75;
}
.wels-houses-chips {
	list-style: none; margin: 22px 0 0; padding: 0;
	display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
}
.wels-houses-chips li {
	background: var(--hs-colour); color: var(--hs-ink);
	border-radius: 20px; padding: 6px 16px;
	font-family: var(--wels-heading-font); font-weight: 700; font-size: .9rem;
}
.wels-houses-more { margin: 22px 0 0; text-align: center; }

/* ---------- House System page ----------
   House cards carry their own colour in --hs-colour and the lettering that
   sits ON that colour in --hs-ink, both written onto the element by PHP.
   --hs-ink is CALCULATED from the colour, never chosen: a yellow house needs
   dark text and a navy one needs white, and no office should have to know
   that. The card's tint is the same colour at 7% over white, so four houses
   are four shades of one idea rather than four unrelated pastels somebody
   picked.

   Colour is never the only signal — every house prints its name as real text,
   because telling the red house from the green one is exactly what around one
   man in twelve cannot do. */
.wels-hs { margin: 0; }
.wels-hs-head {
	display: flex; flex-wrap: wrap; gap: 20px 32px;
	align-items: flex-end; justify-content: space-between; margin-bottom: 28px;
}
.wels-hs-head-text { max-width: 60ch; }
.wels-hs-eyebrow {
	font-size: .76rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
	color: var(--wels-muted); margin: 0 0 .6em;
}
/* pre-line for the same reason as the house description below: this comes
   from a textarea, and somebody who presses Return between two paragraphs
   means two paragraphs, not one run-on sentence. */
.wels-hs-intro { margin: 0; color: var(--wels-muted); line-height: 1.7; white-space: pre-line; }
.wels-hs-cats-intro { margin: 26px 0 0; color: var(--wels-muted); line-height: 1.7; max-width: 72ch; }

.wels-hs-session { flex: 0 0 auto; }
.wels-hs-session label {
	display: block; font-size: .74rem; font-weight: 700; letter-spacing: .1em;
	text-transform: uppercase; color: var(--wels-muted); margin-bottom: 7px;
}
.wels-hs-session-row { display: flex; gap: 8px; align-items: center; }
.wels-hs-session select {
	background: #fff; border: 1px solid var(--wels-line, #d9e0ea);
	border-radius: 9px; padding: 10px 14px; color: var(--wels-ink); min-width: 150px;
	font: inherit;
}
.wels-hs-session select:focus-visible { outline: 3px solid var(--wels-accent); outline-offset: 3px; }
/* The script hides this once it can submit on change; without the script it
   stays, and the switch still works. */
.wels-hs-session.is-live .wels-hs-go { display: none; }

.wels-hs-grid {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px;
}
.wels-hs-card {
	border: 1px solid var(--wels-line, #e2e8f0);
	border-top: 7px solid var(--hs-colour, var(--wels-primary));
	border-radius: var(--wels-radius, 14px);
	background:
		linear-gradient(0deg, color-mix(in srgb, var(--hs-colour) 7%, #fff), color-mix(in srgb, var(--hs-colour) 7%, #fff));
	padding: 25px; box-shadow: 0 6px 20px rgba(18, 52, 90, .05);
}
/* color-mix is recent enough to deserve a floor: anything that cannot do it
   gets a plain white card, which is a card, not a mess. */
@supports not (background: color-mix(in srgb, red 7%, #fff)) {
	.wels-hs-card { background: #fff; }
}
.wels-hs-card-top { display: flex; gap: 20px; align-items: center; }
.wels-hs-emblem {
	width: 84px; height: 84px; flex: 0 0 auto; object-fit: contain; border-radius: 50%;
	background: #fff; padding: 8px; box-shadow: 0 2px 8px rgba(18, 52, 90, .07);
}
.wels-hs-emblem-none {
	display: grid; place-items: center; padding: 0;
	border: 2px solid var(--hs-colour); color: var(--hs-colour);
	font-family: var(--wels-heading-font); font-weight: 800; font-size: 2rem;
}
.wels-hs-name {
	margin: 0; font-size: clamp(1.25rem, 2.2vw, 1.6rem); line-height: 1.25;
	color: var(--wels-primary-dark, var(--wels-primary)); overflow-wrap: anywhere;
}
/* The colour as a WORD, on the colour itself. Redundant to anybody who can
   see that the card is red — and the only thing on the card that says so to
   anybody who cannot. --hs-ink keeps it legible on a yellow house. */
.wels-hs-tag {
	display: inline-block; margin: .5em 0 0;
	background: var(--hs-colour); color: var(--hs-ink);
	border-radius: 20px; padding: 3px 12px; font-size: .75rem; font-weight: 600;
	letter-spacing: .02em;
}
.wels-hs-motto { margin: .4em 0 0; font-size: 1rem; line-height: 1.5; color: var(--wels-ink); }
/* pre-line, because this comes from a TEXTAREA. Somebody who presses Return
   in the box means a line break, and without this the two lines run together
   into one paragraph mid-sentence. pre-line keeps their breaks and still
   collapses runs of spaces and wraps normally, which `pre` would not. */
.wels-hs-about {
	margin: 16px 0 0; font-size: .95rem; line-height: 1.7; color: var(--wels-muted);
	white-space: pre-line;
}
.wels-hs-master { margin: 14px 0 0; font-size: .85rem; color: var(--wels-muted); }
.wels-hs-subhead {
	margin: 20px 0 0; padding-top: 16px; font-size: 1.02rem;
	border-top: 1px solid rgba(18, 52, 90, .1); color: var(--wels-primary-dark, var(--wels-primary));
}
.wels-hs-people {
	list-style: none; margin: 16px 0 0; padding: 0;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 18px;
}
.wels-hs-person { display: flex; align-items: center; gap: 12px; min-width: 0; }
.wels-hs-photo {
	width: 56px; height: 56px; flex: 0 0 auto; border-radius: 50%;
	object-fit: cover; background: #e7edf4;
}
.wels-hs-photo-none {
	display: grid; place-items: center;
	font-family: var(--wels-heading-font); font-weight: 700; font-size: 1.15rem;
	color: var(--wels-primary); background: #e7edf4;
}
.wels-hs-person-text { min-width: 0; }
.wels-hs-person-name { display: block; font-size: .95rem; line-height: 1.4; overflow-wrap: anywhere; }
.wels-hs-person-meta { display: block; font-size: .78rem; color: var(--wels-muted); margin-top: 3px; }

.wels-hs-empty { margin: 22px 0 0; color: var(--wels-muted); }

.wels-hs-council {
	margin-top: 26px; padding: 26px; border-radius: var(--wels-radius, 14px);
	background: var(--wels-alt-bg, #f5f8fc); border: 1px solid var(--wels-line, #dce5ef);
	display: grid; grid-template-columns: 1fr 1.5fr; gap: 28px; align-items: center;
}
.wels-hs-council h3 { margin: 0; font-size: clamp(1.2rem, 2.2vw, 1.5rem); color: var(--wels-primary-dark, var(--wels-primary)); }
.wels-hs-council p { margin: .6em 0 0; font-size: .92rem; line-height: 1.65; color: var(--wels-muted); }
.wels-hs-council .wels-hs-people { margin-top: 0; }

.wels-hs-cats { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
/* No intro above it: the strip has to provide its own breathing space. */
.wels-hs-cats:first-child, .wels-hs-council + .wels-hs-cats, .wels-hs-grid + .wels-hs-cats { margin-top: 26px; }
.wels-hs-cats li {
	font-size: .85rem; background: #fff; border: 1px solid var(--wels-line, #e0e6ef);
	border-radius: 8px; padding: 8px 13px;
}
.wels-hs-cats b { color: var(--wels-primary-dark, var(--wels-primary)); margin-right: 5px; }

@media (max-width: 820px) {
	.wels-hs-grid, .wels-hs-council { grid-template-columns: 1fr; }
	.wels-hs-head { align-items: flex-start; }
	.wels-hs-card { padding: 20px; }
	.wels-hs-emblem { width: 68px; height: 68px; }
	.wels-hs-card-top { gap: 15px; }
}

/* ---------- Group of Schools (sister institutions) ----------
   A row of logos that drifts sideways and loops.

   THE LOOP. The viewport holds two identical tracks side by side and slides
   the pair left by exactly half the pair's width, then starts again. At the
   restart the second copy is sitting where the first one began, so there is
   no visible jump and no empty gap chasing the last logo across the screen.

   WHAT THE SCRIPT DECIDES, AND WHY IT IS NOT CSS. Whether the logos overflow
   at all depends on how many there are, how wide each one is and how wide the
   screen is. Three logos on a desktop fit, and a row of three sliding past for
   no reason looks like a fault. So the animation is only switched on — by
   .is-drifting, from the script — once there is genuinely more than fits. With
   no script the band is a plain centred row that can still be swiped and
   scrolled, which is the honest fallback. */
.wels-groupschools { padding-top: clamp(40px, 5vw, 64px); padding-bottom: clamp(40px, 5vw, 64px); }
.wels-gs-viewport {
	display: flex; width: 100%;
	/* The SAME gap the track uses internally, so the join between the real
	   list and its clone is spaced exactly like every other join. Without it
	   the last logo and the first logo of the copy touch, and the seam the
	   whole duplicate exists to hide becomes the one place you look. It is
	   also the distance the animation adds to its travel — the two have to
	   agree or the loop jumps. */
	gap: clamp(28px, 4vw, 60px);
	overflow-x: auto; overscroll-behavior-x: contain;
	-webkit-overflow-scrolling: touch; scrollbar-width: thin;
	padding-bottom: 10px;
	justify-content: center;
	justify-content: safe center;
}
.wels-gs-viewport:focus-visible {
	outline: 2px solid var(--wels-accent); outline-offset: 6px; border-radius: var(--wels-radius);
}
.wels-gs-track {
	list-style: none; margin: 0; padding: 0;
	display: flex; flex-wrap: nowrap; flex: 0 0 auto;
	gap: clamp(28px, 4vw, 60px);
	align-items: flex-start;
}
/* The clone only exists for the loop. Until the row is actually drifting it
   would just be every logo printed twice, so it is not there at all. */
.wels-gs-clone { display: none; }

.wels-gs { flex: 0 0 auto; display: flex; scroll-snap-align: center; }
.wels-gs-inner {
	display: flex; flex-direction: column; align-items: center; gap: 10px;
	text-decoration: none; color: var(--wels-ink); width: 190px;
}
a.wels-gs-inner:hover { text-decoration: none; }
a.wels-gs-inner:focus-visible {
	outline: 3px solid var(--wels-accent); outline-offset: 6px; border-radius: 6px;
}
.wels-gs-logo {
	max-width: 150px; max-height: 92px; width: auto; height: auto; display: block;
	object-fit: contain;
}
.wels-gs-name {
	font-family: var(--wels-heading-font); font-weight: 700; font-size: .98rem; line-height: 1.3;
	color: var(--wels-primary); text-align: center; text-wrap: balance;
}
a.wels-gs-inner:hover .wels-gs-name { color: var(--wels-primary-dark, var(--wels-primary)); text-decoration: underline; }
.wels-gs-note { font-size: .8rem; color: var(--wels-muted); text-align: center; }

/* Drifting. Once the script has measured an overflow it sets .is-drifting and
   a duration proportional to the distance, so six logos and sixteen move at
   the same speed rather than in the same time. */
.wels-gs-viewport.is-drifting {
	overflow-x: hidden; justify-content: flex-start;
	scroll-snap-type: none;
}
.wels-gs-viewport.is-drifting .wels-gs-clone { display: flex; }
.wels-gs-viewport.is-drifting .wels-gs-track {
	animation: wels-gs-drift var(--wels-gs-dur, 40s) linear infinite;
}
/* Pause on hover, and on focus anywhere inside — otherwise tabbing to a logo
   sends it sliding out from under the focus ring. */
.wels-gs-viewport.is-drifting:hover .wels-gs-track,
.wels-gs-viewport.is-drifting:focus-within .wels-gs-track { animation-play-state: paused; }

@keyframes wels-gs-drift {
	from { transform: translateX(0); }
	to   { transform: translateX(calc(-100% - var(--wels-gs-gap, 44px))); }
}

/* Asked for less motion, the band stops being a marquee entirely and goes back
   to being a row you scroll yourself. The clone is hidden again with it, so
   nobody gets the list twice. */
@media (prefers-reduced-motion: reduce) {
	.wels-gs-viewport.is-drifting { overflow-x: auto; justify-content: safe center; }
	.wels-gs-viewport.is-drifting .wels-gs-track { animation: none; }
	.wels-gs-viewport.is-drifting .wels-gs-clone { display: none; }
}

@media (max-width: 600px) {
	.wels-gs-inner { width: 148px; }
	.wels-gs-logo { max-width: 120px; max-height: 74px; }
}

/* A board's own mark standing at the head of a page about that board — the
   CBSE disclosure, an affiliation block. Capped so it never outgrows the text
   it introduces, and separated by a hairline rather than put in a box, because
   a box would read as a notice from the board rather than the school's own
   page. Written into page content, so the office can move or remove it without
   touching a template. */
.wels-affil-mark {
	text-align: center; margin: 0 0 clamp(20px, 3vw, 32px);
	padding-bottom: clamp(18px, 2.6vw, 26px);
	border-bottom: 1px solid var(--wels-line, #e6e9e4);
}
.wels-affil-mark img { display: block; width: 100%; max-width: 440px; height: auto; margin: 0 auto 10px; }
.wels-affil-mark small {
	display: block; font-size: .8rem; color: var(--wels-muted); letter-spacing: .03em;
}


/* ---------- About Us with no photograph ----------
   The two-column grid reserved half the width for a picture that was not
   there, so the welcome sat in the left column looking like a mistake. With
   no picture it becomes a single centred column, held to a comfortable
   reading width rather than running the full container. */
.wels-about-grid.is-centred { grid-template-columns: minmax(0, 1fr); }
.wels-about-grid.is-centred .wels-about-body {
	max-width: 860px; margin-inline: auto; text-align: center;
}
/* The section head is capped at 720px. Inside an 860px body with no auto
   margin it sat flush left, putting "About Us" 70px left of the crest above
   it — close enough to look like a mistake rather than a choice. */
.wels-about-grid.is-centred .wels-section-head { text-align: center; margin-inline: auto; }
.wels-about-grid.is-centred .wels-section-title::after {
	margin-left: auto; margin-right: auto;
}
.wels-about-grid.is-centred .wels-about-text { margin-bottom: 26px; }


/* ---------- About Us: sub-heading, closing line and feature tiles ---------- */
/* This carries the school's own message, not a label, so it is set as a line
   worth reading rather than a small caps eyebrow. */
.wels-about-subhead {
	margin: -4px auto 20px; max-width: 30em;
	font-family: var(--wels-heading-font); font-weight: 700;
	font-size: clamp(1.05rem, 2vw, 1.3rem); line-height: 1.45;
	color: var(--wels-primary);
}
.wels-about-closing {
	margin: 20px 0 0; font-family: var(--wels-heading-font); font-weight: 700;
	font-size: clamp(1rem, 1.7vw, 1.12rem); color: var(--wels-primary); line-height: 1.5;
}
.wels-aboutfeat { margin-top: clamp(34px, 4.5vw, 56px); }
.wels-aboutfeat-title {
	text-align: center; margin: 0 0 26px;
	font-size: clamp(1.15rem, 2.2vw, 1.5rem);
}
.wels-aboutfeat-grid {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
	gap: clamp(18px, 2.6vw, 30px);
}
/* Four and eight are the two counts the renderer settles on, so they get four
   columns exactly: one full row, or two. Left to auto-fit, eight resolves to
   three columns at some widths and prints as 3 + 3 + 2. Other counts keep the
   auto-fit behaviour they have always had. */
.wels-aboutfeat-grid[data-count="4"],
.wels-aboutfeat-grid[data-count="8"] { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px) {
	.wels-aboutfeat-grid[data-count="4"],
	.wels-aboutfeat-grid[data-count="8"] { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
	/* Repeated at this breakpoint on purpose: a class-plus-attribute selector
	   outranks the bare class and a media query adds no weight, so without
	   this the desktop pin would hold two columns on a phone. */
	.wels-aboutfeat-grid,
	.wels-aboutfeat-grid[data-count="4"],
	.wels-aboutfeat-grid[data-count="8"] { grid-template-columns: 1fr; }
}
.wels-aboutfeat-item {
	text-align: center; display: flex; flex-direction: column; align-items: center; gap: 10px;
	background: #fff; border: 1px solid rgba(20,40,38,.1); border-radius: var(--wels-radius);
	box-shadow: var(--wels-shadow-sm); padding: 26px 20px 28px;
}
.wels-aboutfeat-icon {
	display: grid; place-items: center; width: 62px; height: 62px; border-radius: 50%;
	background: var(--wels-alt-bg); color: var(--wels-primary);
}
.wels-aboutfeat-svg { width: 28px; height: 28px; }
.wels-aboutfeat-name { margin: 0; font-size: 1.02rem; }
.wels-aboutfeat-text { margin: 0; color: var(--wels-muted); font-size: .92rem; line-height: 1.6; }


/* ---------- Message from the Principal ----------
   One message, portrait beside it. The caret only exists while the script is
   typing; it is added and removed by the script, so a page that never runs it
   shows a plain paragraph with nothing blinking at the end of it. */
.wels-principal { background: var(--wels-alt-bg); }
.wels-principal-inner {
	display: grid; grid-template-columns: var(--wels-band-media) minmax(0, 1fr);
	gap: var(--wels-band-gap);
	/* Top, not centre: beside a message of any length the portrait then sits
	   level with the name it belongs to, instead of drifting down the band. */
	align-items: start;
}
.wels-principal-inner.has-no-photo { grid-template-columns: minmax(0, 1fr); }
.wels-principal-photo { position: relative; aspect-ratio: 4 / 5; }
.wels-principal-photo img {
	position: absolute; inset: 0; width: 100%; height: 100%;
	object-fit: cover; object-position: top center;
	border-radius: var(--wels-radius); display: block;
	box-shadow: var(--wels-band-shadow);
}
.wels-principal-eyebrow {
	margin: 0 0 6px; font-family: var(--wels-heading-font); font-weight: 700;
	text-transform: uppercase; letter-spacing: .08em; font-size: .78rem;
	color: var(--wels-accent-text, var(--wels-primary));
}
.wels-principal-name { font-size: var(--wels-h2); margin: 0 0 16px; }
.wels-principal-text {
	color: var(--wels-muted); font-size: 1.02rem; line-height: 1.75;
	/* The message is one text node so it can be typed out; the blank lines
	   between its paragraphs are what this honours. */
	white-space: pre-line;
	/* A comfortable measure. Long lines are what make a long message look
	   like a wall of text. */
	max-width: 62ch;
	/* No reserved height here: the script measures the real message and
	   holds that exact space while it types, then lets go. A guess in CSS
	   is either a gap under a short message or a jump under a long one. */
}
.wels-principal-caret {
	display: inline-block; width: 2px; height: 1.05em; vertical-align: -0.18em;
	margin-left: 2px; background: var(--wels-primary);
	animation: wels-blink 1s steps(1) infinite;
}
@keyframes wels-blink { 50% { opacity: 0; } }
.wels-principal-more { margin: 22px 0 0; }

/* Mirrored band. The portrait moves to the right-hand column, and the tint
   comes off, so a run of messages alternates on both counts. */
.wels-principal-flip .wels-principal-inner {
	grid-template-columns: minmax(0, 1fr) var(--wels-band-media);
}
.wels-principal-flip .wels-principal-photo { order: 2; }
.wels-principal-flip .wels-principal-inner.has-no-photo {
	grid-template-columns: minmax(0, 1fr);
}
.wels-principal-plain { background: transparent; }

/* ---------- Vacancies ---------- */
.wels-vac-list { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(18px, 2.4vw, 26px); }
.wels-vac > article {
	background: #fff;
	border: 1px solid rgba(20, 40, 38, .10);
	border-left: 4px solid var(--wels-primary);
	border-radius: var(--wels-radius);
	padding: clamp(18px, 2.4vw, 28px);
}
.wels-vac-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 16px; margin-bottom: 10px; }
.wels-vac-title { margin: 0; font-size: var(--wels-h3); }
.wels-vac-tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.wels-vac-tag {
	display: inline-block; padding: 3px 10px; border-radius: 999px;
	background: var(--wels-alt-bg); color: var(--wels-muted);
	font-size: .78rem; font-weight: 600;
}
.wels-vac-body { margin: 0 0 14px; color: var(--wels-muted); }

.wels-vac-facts {
	margin: 0 0 14px; display: grid; gap: 10px 26px;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.wels-vac-facts div { margin: 0; }
.wels-vac-facts dt {
	font-family: var(--wels-heading-font); font-weight: 700;
	text-transform: uppercase; letter-spacing: .07em;
	font-size: .72rem; color: var(--wels-muted); margin: 0 0 2px;
}
.wels-vac-facts dd { margin: 0; }

.wels-vac-perks { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.wels-vac-perks li {
	padding: 4px 12px; border-radius: 999px;
	background: color-mix(in srgb, var(--wels-primary) 10%, transparent);
	color: var(--wels-primary); font-size: .82rem; font-weight: 600;
}
.wels-vac-walkin {
	margin: 0 0 14px; padding: 12px 14px;
	background: var(--wels-alt-bg); border-radius: 10px; line-height: 1.6;
}
.wels-vac-apply { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin: 0; }
.wels-vac-contact { color: var(--wels-muted); font-size: .92rem; }
.wels-vac-none { color: var(--wels-muted); max-width: 60ch; }

/* ---------- School tour video ----------
   A still with a play button until somebody presses it; the script puts the
   real player in afterwards. Sized by aspect-ratio so nothing shifts when
   the iframe replaces the image. */
.wels-tour { background: var(--wels-alt-bg); }
.wels-tour-inner { max-width: 960px; }
.wels-tour-head { text-align: center; margin: 0 0 clamp(24px, 3.5vw, 40px); }
.wels-tour-eyebrow {
	margin: 0 0 10px;
	font-family: var(--wels-heading-font); font-weight: 700;
	text-transform: uppercase; letter-spacing: .12em; font-size: .78rem;
	color: var(--wels-primary);
}
.wels-tour-title { margin: 0; font-size: var(--wels-h2); font-weight: 400; line-height: 1.24; }
.wels-tour-text { margin: 12px auto 0; max-width: 60ch; color: var(--wels-muted); }

.wels-tour-frame {
	position: relative; aspect-ratio: 16 / 9;
	border-radius: var(--wels-radius); overflow: hidden;
	background: #000;
	box-shadow: var(--wels-band-shadow);
}
.wels-tour-poster {
	position: absolute; inset: 0;
	width: 100%; height: 100%; object-fit: cover; display: block;
}
.wels-tour-frame iframe {
	position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
}
/* The button is the whole frame, so the still is clickable without a second
   element over it stealing the pointer. */
.wels-tour-play {
	position: absolute; inset: 0;
	display: grid; place-items: center;
	width: 100%; height: 100%;
	background: rgba(12, 20, 20, .28);
	border: 0; padding: 0; cursor: pointer;
	transition: background .25s ease;
}
.wels-tour-play:hover { background: rgba(12, 20, 20, .14); }
.wels-tour-play:focus-visible { outline: 3px solid #fff; outline-offset: -6px; }
.wels-tour-play-ring {
	display: grid; place-items: center;
	width: clamp(64px, 8vw, 88px); aspect-ratio: 1; border-radius: 50%;
	background: var(--wels-primary);
	box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
	transition: transform .25s ease;
}
.wels-tour-play:hover .wels-tour-play-ring,
.wels-tour-play:focus-visible .wels-tour-play-ring { transform: scale(1.08); }
.wels-tour-play-ring svg {
	width: 38%; height: 38%; fill: #fff;
	/* The triangle's own empty left edge makes it look off-centre. */
	margin-left: 8%;
}
.wels-tour-fallback { text-align: center; margin: 16px 0 0; }

@media (prefers-reduced-motion: reduce) {
	.wels-tour-play, .wels-tour-play-ring { transition: none; }
	.wels-tour-play:hover .wels-tour-play-ring { transform: none; }
}

/* ---------- News & Events ----------
   Three cards, equal height whatever the titles do, on the site's own
   tokens: the same radius, the same shadow, the same heading scale. The
   container is narrower than the page so the band has air around it. */
.wels-updates-inner { max-width: 1080px; }
.wels-updates-head { text-align: center; margin: 0 0 clamp(30px, 4vw, 48px); }
.wels-updates-eyebrow {
	margin: 0 0 10px;
	font-family: var(--wels-heading-font); font-weight: 700;
	text-transform: uppercase; letter-spacing: .12em; font-size: .78rem;
	color: var(--wels-primary);
}
.wels-updates-title {
	margin: 0 auto; max-width: 20ch;
	font-size: var(--wels-h2); font-weight: 400; line-height: 1.24;
	letter-spacing: .01em;
}

.wels-updates-grid {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(20px, 2.6vw, 30px);
}
/* The card is the grid item; the article inside it is the full-height box,
   so three cards of different lengths still line up at top and bottom. */
.wels-update-card { display: flex; }
.wels-update-card > article {
	display: flex; flex-direction: column; width: 100%;
	background: #fff;
	border: 1px solid rgba(20, 40, 38, .10);
	border-radius: var(--wels-radius);
	overflow: hidden;
	transition: transform .25s ease, box-shadow .25s ease;
}
.wels-update-card > article:hover,
.wels-update-card:focus-within > article {
	transform: translateY(-4px);
	box-shadow: var(--wels-band-shadow);
}

.wels-update-media { aspect-ratio: 16 / 10; overflow: hidden; }
.wels-update-media img {
	width: 100%; height: 100%; object-fit: cover; display: block;
	transition: transform .5s ease;
}
.wels-update-card > article:hover .wels-update-media img,
.wels-update-card:focus-within .wels-update-media img { transform: scale(1.05); }

.wels-update-body {
	display: flex; flex-direction: column; flex: 1;
	padding: clamp(16px, 1.8vw, 22px);
}
.wels-update-meta {
	display: flex; flex-wrap: wrap; gap: 6px 18px;
	margin: 0 0 10px; font-size: .8rem; color: var(--wels-muted);
}
.wels-update-metaitem { display: inline-flex; align-items: center; gap: 6px; }
.wels-update-metaitem svg { width: 14px; height: 14px; fill: currentColor; opacity: .7; flex: 0 0 auto; }

.wels-update-title { margin: 0 0 8px; font-size: 1.08rem; line-height: 1.35; }
.wels-update-title a { text-decoration: none; color: inherit; }
.wels-update-title a:hover { color: var(--wels-primary); }
/* Held to three lines so a long title cannot push its card's button out of
   line with the two beside it. */
.wels-update-title a,
.wels-update-excerpt {
	display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.wels-update-title a { -webkit-line-clamp: 3; }
.wels-update-excerpt {
	-webkit-line-clamp: 3;
	margin: 0 0 16px; color: var(--wels-muted); font-size: .92rem; line-height: 1.6;
}
/* Pushed to the bottom of the card, so every button sits on one line. */
.wels-update-more { margin: auto 0 0; }
.wels-btn-sm { padding: 7px 18px; font-size: .84rem; border-radius: 999px; }

.wels-updates-all { text-align: center; margin: clamp(26px, 3.5vw, 40px) 0 0; }
.wels-updates-all a {
	font-family: var(--wels-heading-font); font-weight: 700; font-size: .95rem;
	text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 3px;
}
.wels-updates-all a:hover { color: var(--wels-primary); }

@media (max-width: 980px) {
	.wels-updates-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
	.wels-updates-grid { grid-template-columns: minmax(0, 1fr); }
	.wels-updates-title { max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
	.wels-update-card > article,
	.wels-update-media img { transition: none; }
	.wels-update-card > article:hover { transform: none; }
	.wels-update-card > article:hover .wels-update-media img { transform: none; }
}

/* ---------- Mandatory Public Disclosure ----------
   The page comes from the plugin with a palette and a type scale of its own
   — its own greys, its own borders, a 1.15rem section heading — so it read
   as a different website. Pointed at the site's tokens here rather than by
   editing the plugin, which keeps the approved CBSE layout in the plugin's
   hands where it belongs. `body` only to win on specificity, since the
   plugin's own stylesheet may load after the theme's. */
body .welsd-wrap {
	--welsd-text: var(--wels-ink);
	--welsd-accent: var(--wels-primary);
	--welsd-border: rgba(20, 40, 38, .14);
	--welsd-head: var(--wels-alt-bg);
}
body .welsd-section-title { font-size: var(--wels-h3); }
body .welsd-result-title { font-size: 1rem; }
body .welsd-intro,
body .welsd-updated { color: var(--wels-muted); }
body .welsd-table-scroll { border-radius: var(--wels-radius); }
body .welsd-view-btn { border-radius: var(--wels-btn-radius); }
/* The banner supplies the title now, so the template's own heading is gone;
   this catches the shortcode used on any other page. */
body .welsd-title { font-size: var(--wels-h2); }

/* ---------- Content bands ----------
   The alternating photo-and-text pattern, as a block anybody can add in the
   editor: insert a Media & Text block, and tick "Show media on right" on the
   next one so the page zig-zags. Written out in full rather than leaning on
   the core block stylesheet, which the theme does not load. */
.wp-block-media-text {
	display: grid;
	grid-template-columns: var(--wels-band-media) minmax(0, 1fr);
	gap: var(--wels-band-gap);
	align-items: start;
	margin: 0 0 var(--wels-band-rhythm);
}
.wp-block-media-text.has-media-on-the-right {
	grid-template-columns: minmax(0, 1fr) var(--wels-band-media);
}
.wp-block-media-text.has-media-on-the-right .wp-block-media-text__media { order: 2; }
/* Given a shape rather than left at whatever the file happens to be, so a
   portrait phone snap and a landscape one make the same band. */
.wp-block-media-text__media { margin: 0; aspect-ratio: var(--wels-band-ratio); }
.wp-block-media-text__media img {
	width: 100%; height: 100%; display: block;
	object-fit: cover;
	border-radius: var(--wels-radius);
	box-shadow: var(--wels-band-shadow);
}
.wp-block-media-text__content > *:first-child { margin-top: 0; }
.wp-block-media-text__content > *:last-child { margin-bottom: 0; }

@media (max-width: 820px) {
	.wp-block-media-text,
	.wp-block-media-text.has-media-on-the-right { grid-template-columns: minmax(0, 1fr); }
	/* One column: the photograph leads, whichever side it takes when wide. */
	.wp-block-media-text.has-media-on-the-right .wp-block-media-text__media { order: 0; }
}

/* A tribute, not a message. Restrained on purpose: a portrait, a rule, the
   words. The photograph is a small studio print from the prospectus, so it
   gets a plain frame rather than being blown up to look like a hero. */
.wels-tribute .wels-principal-photo img {
	object-position: center;
	box-shadow: 0 10px 28px rgba(20,40,38,.14);
}
.wels-tribute .wels-principal-name { margin-bottom: 4px; }
.wels-tribute .wels-principal-role {
	margin: 0 0 18px; padding-bottom: 16px;
	font-family: var(--wels-heading-font);
	letter-spacing: .06em; text-transform: uppercase;
	font-size: .8rem; color: var(--wels-muted);
	border-bottom: 1px solid rgba(0,0,0,.12);
	max-width: 62ch;
}

@media (max-width: 820px) {
	.wels-principal-inner,
	.wels-principal-flip .wels-principal-inner { grid-template-columns: minmax(0, 1fr); }
	.wels-principal-photo { max-width: 260px; aspect-ratio: 1 / 1; }
	/* One column: the portrait leads, whichever side it takes on a wide
	   screen. Mirroring only makes sense when there are two columns. */
	.wels-principal-flip .wels-principal-photo { order: 0; }
}
@media (prefers-reduced-motion: reduce) {
	.wels-principal-caret { display: none; }
}


/* ---------------------------------------------------------------------------
   Leadership summaries (wels-lmsg-*) — every leader on the homepage in a
   couple of lines, each linking through to their full message.

   NAMED lmsg, NOT leader-card, on purpose: .wels-leader-card is already the
   older vertical card used by the leadership grid, and it sets
   flex-direction: column and text-align: center. Reusing that name meant this
   component inherited both — and, worse, silently repainted the old one.
   Distinct names, no collision, both components keep working.

   flex-direction and text-align are stated explicitly rather than left to the
   default, so a per-school preset elsewhere in this file cannot quietly turn
   these cards into something else.
--------------------------------------------------------------------------- */
.wels-lmsg-grid { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 26px; align-items: stretch; }
.wels-lmsg-card { display: flex; flex-direction: row; text-align: left; gap: 20px;
  align-items: flex-start; background: var(--wels-bg); border: 1px solid rgba(0,0,0,.09);
  border-radius: var(--wels-radius); padding: 24px;
  transition: transform .25s ease, box-shadow .25s ease; }
.wels-lmsg-card:hover { transform: translateY(-4px); box-shadow: 0 16px 40px rgba(0,0,0,.09); }
.wels-lmsg-photo { flex: 0 0 104px; }
.wels-lmsg-photo img { width: 104px; height: 130px; object-fit: cover;
  object-position: top center; border-radius: calc(var(--wels-radius) - 4px);
  display: block; border: 1px solid rgba(0,0,0,.08); }
.wels-lmsg-body { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.wels-lmsg-role { margin: 0; font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; font-weight: 800; color: var(--wels-accent-text); }
.wels-lmsg-name { margin: 5px 0 10px; font-size: 1.12rem; line-height: 1.25;
  font-family: var(--wels-heading-font); color: var(--wels-primary); }
.wels-lmsg-text { margin: 0 0 16px; color: var(--wels-muted); font-size: .94rem; line-height: 1.6; }
/* Pushes the button to the bottom so two cards of unequal text still line
   their buttons up with each other. */
.wels-lmsg-more { margin: auto 0 0; }

@media (max-width: 620px) {
  .wels-lmsg-card { flex-direction: column; }
  .wels-lmsg-photo { flex: none; }
  .wels-lmsg-photo img { width: 92px; height: 115px; }
}

/* The full message band carries an id now, so a Read More lands on the person
   rather than the top of the page. Offset for the sticky header. */
.wels-principal[id] { scroll-margin-top: 110px; }


/* ---------------------------------------------------------------------------
   Tap targets — audit fix (wels-tap-target-audit)

   The telephone and e-mail links in the top bar and the footer rendered
   20-22px high. WCAG 2.5.8 asks for 24x24 as a minimum, and these are the
   links most likely to be tapped on a phone: a parent trying to ring the
   school. Padding rather than font-size, so nothing about the layout moves.
--------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .wels-topbar a,
  .wels-site-footer .wels-footer-contact a,
  .wels-site-footer .wels-footer-col a {
    display: inline-block;
    min-height: 24px;
    padding-block: 7px;
    line-height: 1.35;
  }
  .wels-topbar .wels-topbar-inner { row-gap: 2px; }

  /* The footer's bottom strip: Staff Login and the credit line sat at 22px
     and 18px. Same reasoning, same fix. */
  .wels-footer-bottom a,
  .wels-footer-legal a,
  .wels-staff-login,
  .wels-footer-credit a {
    display: inline-block;
    min-height: 24px;
    padding-block: 5px;
  }
}


/* ---------------------------------------------------------------------------
   The typed fee table (wels-fee-free)

   Deliberately NOT .wels-fee-table: that class carries
       thead th:not(:first-child):not(:nth-child(2)) { text-align: right }
   which assumes the older layout of "S. No. | Class | amounts…". A typed
   table starts its amounts one column earlier, so that rule right-aligned
   every heading except the first two while the figures beneath stayed left —
   heading at one edge of the column, number at the other.

   Alignment is now decided in PHP per column and carried by .wels-fee-num on
   the heading AND the cells together, so they cannot drift apart again.
--------------------------------------------------------------------------- */
.wels-fee-free th,
.wels-fee-free td { text-align: left; }
.wels-fee-free .wels-fee-num { text-align: right; }
.wels-fee-free th[scope="row"] { font-weight: 600; color: var(--wels-ink); }

/* Tabular figures: digits share one width, so the rupee amounts line up
   vertically down the column instead of drifting with the glyphs. */
.wels-fee-free .wels-fee-num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }


/* ---------------------------------------------------------------------------
   Card rows that actually fill the row (card-grid-fill-row)

   .wels-card-grid uses repeat(auto-fill, minmax(260px, 1fr)). At a 1180px
   container that makes FOUR tracks, and three cards sit in three of them —
   leaving a quarter of the row empty on the right. The cards were never
   misaligned with each other; the row was simply wider than the cards asked
   for. auto-fill keeps empty tracks; that is what it is for.

   Rather than switch the whole theme to auto-fit — which would stretch a
   lone card across the full width and look worse — the count is matched
   directly, the same way .wels-leader-grid already handles its two-card
   case. Two, three or four cards divide the row evenly.

   FIVE and SIX take three columns rather than four, which is the whole point
   of naming them: left to auto-fill at a 1140px container both resolve to
   four tracks, so five prints as 4 + 1 — a stranded single, which reads as
   though a card failed to load — and six as 4 + 2. Three columns give 3 + 2
   and 3 + 3 instead, both of which look chosen. Seven or more fall back to
   auto-fill, because past six the grid is a list and wrapping is right.

   Only above 900px. Below that the auto-fill behaviour is what keeps the
   cards stacking on a phone, and forcing three columns there would push the
   page sideways.

   :not(.is-carousel) so the horizontal-scroll variant is left alone.
--------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .wels-card-grid:not(.is-carousel):has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wels-card-grid:not(.is-carousel):has(> :nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .wels-card-grid:not(.is-carousel):has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .wels-card-grid:not(.is-carousel):has(> :nth-child(5):last-child),
  .wels-card-grid:not(.is-carousel):has(> :nth-child(6):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------------------
   HOUSES

   Each card carries its own colour as three custom properties, set inline by
   the renderer:

     --wels-house      the house colour, as the school gave it
     --wels-house-on   white or near-black, whichever can be read ON it
     --wels-house-ink  the same colour walked down until it can be read on white

   Three rather than one because a house colour has to do two different jobs.
   A school's yellow house is a fine background with dark lettering on it and
   hopeless as lettering itself — around 1.6:1 on white. A navy house is the
   reverse. The
   renderer works both out per house, so the stylesheet never has to guess and
   the school never has to be asked.

   The fallbacks below are the site palette, so a house with no colour set
   still looks like it belongs rather than rendering as a black slab.
--------------------------------------------------------------------------- */
.wels-house-grid {
  display: grid;
  gap: clamp(16px, 2.2vw, 26px);
  grid-template-columns: 1fr;
}

@media (min-width: 620px) {
  .wels-house-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Four houses is the common case and sits as one row; the :has() rules match
   whatever number the school actually entered, the same way the card grid
   does, so three houses are three across rather than two and a gap. */
@media (min-width: 1000px) {
  .wels-house-grid:has(> :nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .wels-house-grid:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .wels-house-grid:has(> :nth-child(5)) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.wels-house {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--wels-bg, #fff);
  border: 1px solid rgba(0, 0, 0, .09);
  border-radius: var(--wels-radius, 10px);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

/* A band of the house's own colour, carrying the emblem. Its aspect ratio is
   fixed so four cards line up whatever the uploaded images measure. */
.wels-house-band {
  position: relative;
  aspect-ratio: 3 / 2;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--wels-house, var(--wels-primary, #033570));
  color: var(--wels-house-on, #fff);
}

.wels-house-band img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* No emblem: the house's initial, which reads as a decision rather than as a
   missing picture. */
.wels-house-initial {
  font-size: clamp(2.6rem, 6vw, 4rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: .02em;
  color: var(--wels-house-on, #fff);
}

.wels-house-body {
  padding: clamp(16px, 2vw, 22px);
  display: flex;
  flex-direction: column;
  gap: .55em;
  flex: 1 1 auto;
}

/* The name uses the darkened version, never the raw house colour — that is
   the whole reason --wels-house-ink exists. */
.wels-house-name {
  margin: 0;
  font-size: clamp(1.08rem, 1.5vw, 1.25rem);
  color: var(--wels-house-ink, var(--wels-primary, #033570));
}

.wels-house-motto {
  margin: 0;
  font-style: italic;
  color: var(--wels-muted, #55627a);
}

.wels-house-text {
  margin: 0;
  font-size: .95rem;
  line-height: 1.6;
}

.wels-house-people {
  margin: .4em 0 0;
  padding-top: .7em;
  border-top: 1px solid rgba(0, 0, 0, .08);
  display: grid;
  gap: .35em;
  font-size: .9rem;
}

.wels-house-person {
  display: flex;
  justify-content: space-between;
  gap: 1em;
}

.wels-house-person dt {
  color: var(--wels-muted, #55627a);
  margin: 0;
}

.wels-house-person dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
}

@media (prefers-contrast: more) {
  .wels-house { border-color: rgba(0, 0, 0, .4); }
}

/* ---------------------------------------------------------------------------
   FACEBOOK FEED

   Two columns on desktop: our own words on the left, Facebook's panel on the
   right. The order matters. The text is ours and always renders; the panel is
   Facebook's and sometimes does not — a page that is not public, a country or
   age restriction, a browser blocking third-party frames. Putting our column
   first means the band still reads left-to-right as a finished section when
   the right-hand side is empty.

   The embed column is sized to the plugin's own range (180-500px, we ask for
   400). Facebook fixes the width on load and will not reflow on resize, so it
   is given a fixed column rather than a fluid one that would lie to it.
--------------------------------------------------------------------------- */
.wels-fbfeed-grid {
  display: grid;
  gap: clamp(20px, 3vw, 40px);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 900px) {
  /* Top-aligned, not centred. Centring was right when the column held one button;
     with a collage under the text both columns have real height, and two blocks of
     content that start on the same line read as a pair. */
  /*
   * minmax(0, 560px), not 1fr — and that is the whole fix for the gap.
   *
   * With 1fr the left column took every pixel the container had left (700px), while
   * the content inside it stopped at its 560px cap. Measured: 140px of dead column
   * plus the 40px gap, so 180px of air between the collage and the feed with no rule
   * anywhere saying "180px". Capping the TRACK instead of the content inside it means
   * the column ends where the pictures end.
   *
   * justify-content then centres the pair in the container rather than leaving the
   * slack on one side, so the band sits under its centred heading instead of hugging
   * the left edge. minmax's 0 floor lets the text column shrink below 560 between
   * 900px and 1000px, where the feed's fixed 400 would otherwise force an overflow.
   */
  .wels-fbfeed-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 1034px;
    margin-inline: auto;
    column-gap: clamp(20px, 2.4vw, 34px);
    align-items: start;
  }
}

/*
 * The band's own backdrop. A pale tint of the SCHOOL'S primary rather than a fixed
 * pale blue, so this reads correctly on every school built from this backbone — the
 * one with the maroon palette gets a pale maroon, not somebody else's blue.
 * color-mix keeps it tied to the token; the flat fallback covers older browsers.
 */
.wels-fbfeed { background: #f4f7fc; }
@supports (background: color-mix(in srgb, red 5%, white)) {
  .wels-fbfeed { background: color-mix(in srgb, var(--wels-primary, #2f5aa3) 6%, #fff); }
}

/* The gap before Admissions Open. The sections are flush — measured, the fbfeed band
   ends exactly where admissions begins — so what looked like a gap was this band's
   own 84px of bottom padding sitting under a short column. The collage fills most of
   it; this takes back the rest without making the band feel cramped. */
.wels-fbfeed { padding-bottom: clamp(44px, 5vw, 60px); }

.wels-fbfeed-subhead {
  margin: 0 0 10px;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  color: var(--wels-primary-dark, var(--wels-primary));
  position: relative; padding-bottom: 12px;
}
/* The lime accent, as a short rule under the heading rather than a block of colour —
   an accent that outweighs the thing it is accenting stops being an accent. */
.wels-fbfeed-subhead::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 54px; height: 4px; border-radius: 2px;
  background: var(--wels-accent, #aacd52);
}

/*
 * The collage: a 2x2 grid, which is why the renderer caps at four. Each tile is 4:3
 * and cropped to fill, so a mixed bag of phone photographs still lines up — the one
 * thing that makes a collage look careless is tiles of different heights.
 */
.wels-fbfeed-collage {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin: 18px 0 4px;
}
.wels-fbfeed-collage img {
  display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 12px;
}
a.wels-fbfeed-collage img { transition: transform .18s ease, box-shadow .18s ease; }
a.wels-fbfeed-collage:hover img { transform: translateY(-3px); box-shadow: var(--wels-shadow-sm); }
a.wels-fbfeed-collage:focus-visible {
  outline: 3px solid var(--wels-accent, #aacd52); outline-offset: 4px; border-radius: 14px;
}
@media (prefers-reduced-motion: reduce) {
  a.wels-fbfeed-collage img, a.wels-fbfeed-collage:hover img { transition: none; transform: none; }
}
@media (max-width: 420px) {
  /* One per row below this: a 2x2 grid in a 335px column gives 160px tiles, which is
     too small to make out a face. */
  .wels-fbfeed-collage { grid-template-columns: 1fr; }
}


/*
 * The left column, measured before this: 700px wide, 802px tall, holding one 60px
 * button. Two things were wrong and only one of them was the emptiness.
 *
 * 520px cap — 700px is far too wide a measure for prose; the eye loses the line
 * returning to the left edge. Capped, the leftover space reads as margin, which is
 * what deliberate whitespace looks like. The grid centres the column against the
 * feed (see align-items above), so a short paragraph sits level with the middle of
 * the panel instead of stranded at the top of 800px.
 */
/* 560 rather than 520 now the column holds a 2x2 collage: at 520 each tile is 254px,
   and the extra 40 buys back enough that faces in a group photograph are legible.
   Still well inside the measure where a line of prose becomes hard to track. */
/* The grid caps the column now, so this is only the floor for the stacked layout
   below 900px, where there is no second column to measure against. */
.wels-fbfeed-text { max-width: 560px; }
.wels-fbfeed-text > :first-child { margin-top: 0; }

.wels-fbfeed-text p {
  margin: 0 0 1em;
  line-height: 1.7;
}

/*
 * The column's footer: the main action on the left, the follow icons on the right.
 * space-between rather than a gap, so the two ends line up with the edges of the
 * collage above and the row reads as the bottom of the same block.
 *
 * It wraps, so a longer button label or a fourth network drops the icons to their
 * own line instead of squeezing both into an unreadable row.
 */
.wels-fbfeed-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px 20px; flex-wrap: wrap; margin-top: 1.1em;
}
.wels-fbfeed-link { margin: 0; }
.wels-fbfeed-text .wels-social-row { justify-content: flex-start; }
@media (max-width: 420px) {
  /* Side by side in a 335px column leaves the button too narrow to read. */
  .wels-fbfeed-actions { justify-content: flex-start; }
}

/* The frame keeps the panel from looking like a hole in the page while it
   loads, and gives it an edge of its own if it never fills. */
.wels-fbfeed-embed {
  max-width: 500px;
  width: 100%;
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: var(--wels-radius, 10px);
  overflow: hidden;
  background: #fff;
}

.wels-fbfeed-embed iframe {
  display: block;
  width: 100%;
  border: 0;
}

/* Below 900px the embed sits under the text and centres rather than hugging
   the left edge, which looks accidental on a phone. */
@media (max-width: 899px) {
  .wels-fbfeed-embed { margin-inline: auto; }
}

/* ---------------------------------------------------------------------------
   FACEBOOK FEED — when the panel is blocked

   Tracker blockers remove this embed: Privacy Badger, uBlock Origin, Brave's
   shields, Firefox's strict mode. They either delete the iframe or swap it for
   a short "this widget was replaced" link. It happened on the first machine
   this was ever opened on, so it is the normal case, not an edge case.

   Without these two rules the band survives but looks wrong: the text column
   stays at its two-column width with 400px of nothing beside it, and the
   bordered box frames a one-line replacement link like a broken image.

   :has() asks whether the iframe is actually still there. Lazy loading defers
   the FETCH, not the element, so for an ordinary visitor the iframe exists
   from the first paint and the two-column layout applies as normal.
--------------------------------------------------------------------------- */
@media (min-width: 900px) {
  /* Two columns only while there is something to put in the second one. */
  .wels-fbfeed-grid { grid-template-columns: 1fr; }
  /*
   * The track sizing has to be repeated here, and this is the trap worth naming: the
   * :has() selector above is two selectors to the earlier rule's one, so it wins on
   * specificity wherever the two disagree. Setting minmax(0, 560px) further up and
   * leaving 1fr here looked correct and measured as 706px — the gap I had just been
   * asked to close, unchanged, with no rule anywhere saying 706.
   *
   * Whenever a component's layout is declared in two places, the narrower selector
   * is the one that decides. Same lesson as .wels-stage-approach.has-no-media.
   */
  .wels-fbfeed-grid:has(.wels-fbfeed-embed iframe) {
    /*
     * Equal halves, capped so each lands on 500 — Facebook's Page Plugin will not
     * render wider than 500px, so matching the collage column to that ceiling is
     * the only way the two sides come out genuinely the same rather than roughly.
     *
     * Two 1fr tracks with a cap on the GRID, not two fixed 500px tracks: fixed
     * tracks plus the gap need 1034px and would overflow the container between
     * 900 and 1034, where 1fr simply shares out whatever is there and the halves
     * stay equal all the way down.
     */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 1034px;
    margin-inline: auto;
  }
}

/* No iframe, no frame — so a blocker's placeholder is not presented inside
   something that looks like a failed panel. */
.wels-fbfeed-embed:not(:has(iframe)) {
  border: 0;
  background: none;
  max-width: none;
}

/* ---------------------------------------------------------------------------
   ADMISSIONS BAND — the school's own photograph behind it

   Three custom properties are set inline by the renderer, only when a school
   has actually chosen a picture:

     --wels-adm-bg             the photograph
     --wels-adm-tint           a flat colour laid over it
     --wels-adm-tint-opacity   how much of that colour

   WHY THE TINT EXISTS. A school photograph is busy — bright sky, dark
   windows, faces between the two. White lettering is crisp over the windows
   and invisible over the sky. The wash compresses that range so one text
   colour reads everywhere on the picture, whatever picture it turns out to
   be. The alternative is asking each school to find a photograph with a
   conveniently empty corner, which no school has.

   Nothing here applies without .has-bg, so a school that chooses no picture
   keeps exactly the band it had before.
--------------------------------------------------------------------------- */
.wels-admissions.has-bg {
  position: relative;
  background-image: var(--wels-adm-bg);
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  isolation: isolate;
}

/* The tint. A pseudo-element rather than a gradient on the same background,
   so the opacity can be changed from the admin without rebuilding the image
   layer. */
.wels-admissions.has-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--wels-adm-tint, var(--wels-primary, #0d3b66));
  opacity: var(--wels-adm-tint-opacity, .55);
}

/* Text sits above both layers and is forced white, because the band is now a
   dark photograph whatever the section's normal colours were. */
.wels-admissions.has-bg .wels-container,
.wels-admissions.has-bg .wels-section-title,
.wels-admissions.has-bg .wels-admissions-text,
.wels-admissions.has-bg .wels-admissions-text p {
  position: relative;
  color: #fff;
}

.wels-admissions.has-bg .wels-section-title { color: #fff; }

/* The plain "More about admissions" link needs a visible treatment on a
   photograph — a bare coloured link disappears into it. */
.wels-admissions.has-bg .wels-btn-link {
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, .6);
}

/* Give the band room so the photograph is actually seen rather than peeking
   out from behind the text. */
.wels-admissions.has-bg {
  padding-block: clamp(56px, 8vw, 120px);
}

/* The parallax option. Deliberately not applied below 900px: iOS ignores
   background-attachment: fixed entirely, and on the Android browsers that do
   honour it the repaint cost on a long page is worse than the effect is
   worth. Desktop only, where it behaves. */
@media (min-width: 900px) {
  .wels-admissions.has-bg.is-fixed { background-attachment: fixed; }
}

@media (prefers-reduced-motion: reduce) {
  .wels-admissions.has-bg.is-fixed { background-attachment: scroll; }
}

/* A shadow under the band's text, as the second line of defence.

   The tint does the main work, but a school can set it low, or choose a
   photograph that is blown out white in one corner. Measured on a real
   campus photograph, a 55% tint gave 3.3:1 against white over the sky and
   7.2:1 on average — fine almost everywhere and failing exactly where the
   heading happened to sit. The default was raised to 70%, and this shadow
   means a lighter choice still reads rather than quietly becoming
   unreadable for the people least able to cope with it. */
.wels-admissions.has-bg .wels-section-title,
.wels-admissions.has-bg .wels-admissions-text,
.wels-admissions.has-bg .wels-admissions-text p {
  text-shadow: 0 1px 3px rgba(0, 0, 0, .45);
}

/* ===========================================================================
 * 1.4.2 — the off-canvas menu must not inherit the header bar
 *
 * The mobile panel is printed INSIDE <header id="masthead">, so every rule
 * written for the header bar also lands on it. Most are harmless. Four were
 * not, and three of those were invisible faults — the menu looked broken
 * without looking wrong, which is the worst kind.
 *
 *   1. COLOUR. The crest layout's bar is dark, so its links are #fff. In the
 *      white panel that made the top-level items white on white: present,
 *      laid out, tappable, unreadable. The current page gave itself away by
 *      its accent underline floating beneath nothing.
 *
 *   2. THE TOGGLES. Same colour, so the carets vanished too and nothing
 *      showed which items had a submenu at all.
 *
 *   3. PADDING AND ALIGNMENT. 23px top and bottom suits a bar 70px tall and
 *      makes a stack of rows enormous; `justify-content: center` and a 26px
 *      gap suit a row of links either side of a crest and, once stacked,
 *      centred every label and left the separator rules short of both edges.
 *
 *   4. PANELS TAKING UP ROOM WHEN CLOSED. In the bar a panel is absolutely
 *      positioned, so hiding it with opacity and visibility costs nothing.
 *      Dropped into the off-canvas list it is static, and a static element
 *      that is merely invisible still occupies its full height — tall blank
 *      gaps with separator lines stranded in the middle of them.
 *
 * And one plain bug found while fixing the rest: the walker wraps a panel's
 * list in two divs, so `.is-expanded > .wels-sub-menu` could never match it
 * and a panel could not be opened on a phone at all.
 *
 * Everything below is scoped to .wels-mobile-nav, so the bar itself is
 * untouched, and on the other header layouts these rules set the values
 * those sites already compute.
 *
 * NOTE for any future header layout: if it gets its own colours, check the
 * mobile panel. It is inside the header and it will inherit them.
 * ======================================================================== */
.wels-mobile-nav .wels-menu {
	display: block;
	gap: 0;
}
.wels-mobile-nav .wels-menu > .wels-menu-item {
	display: block;
}
.wels-mobile-nav .wels-menu > .wels-menu-item > a,
.wels-mobile-nav .wels-submenu-toggle {
	color: var(--wels-ink);
}
.wels-mobile-nav .wels-menu .current-menu-item > a,
.wels-mobile-nav .wels-menu .current-menu-ancestor > a {
	color: var(--wels-primary);
}
.wels-mobile-nav .wels-menu > .wels-menu-item > a {
	padding: 14px 6px;
	display: flex;
	white-space: normal;
}
.wels-mobile-nav .wels-menu a {
	justify-content: flex-start;
	text-align: left;
}
.wels-mobile-nav .wels-mega {
	display: none;
	padding: 0;
}
.wels-mobile-nav .wels-menu-item.is-expanded > .wels-mega {
	display: block;
}
.wels-mobile-nav .wels-menu-item.is-expanded .wels-mega .wels-sub-menu {
	display: block;
}


/* ===========================================================================
   STAGE PAGE  (.wels-stage)

   The long form of one academic stage: a hero with the class range, a strip of
   what the stage is about, the approach, the activities, and a closing band.
   Written as a component rather than as a block of CSS pasted into each page,
   because there are four of these pages and a palette change has to reach all
   of them at once. A page's own content is then just markup.

   Everything takes its colour from the preset — no hex values here beyond
   neutral tints. A stage page on a navy-and-gold school comes out navy and
   gold without anybody editing it.

   The theme's own page banner is hidden when a stage is present, so the page
   has ONE h1 (the stage hero's) rather than two.
   ======================================================================== */

/* The banner band stands down in PHP for a stage page (see
   wels_school_page_banner), so there is nothing to hide here — only the top
   padding to close up, since the hero now sits directly under the header. */
.wels-page:has(.wels-stage) .wels-page-body { padding-top: clamp(18px, 2.5vw, 30px); }

.wels-stage { --wels-stage-pad: clamp(24px, 4vw, 48px); }
.wels-stage > * + * { margin-top: clamp(26px, 4vw, 48px); }

/* ---- Hero ---- */
.wels-stage-hero {
	background: linear-gradient(110deg, var(--wels-alt-bg) 0%, #fff 55%, var(--wels-alt-bg) 100%);
	border-radius: var(--wels-radius);
	overflow: hidden;
}
.wels-stage-hero-grid { display: grid; grid-template-columns: 1fr 1.1fr; align-items: center; }
.wels-stage-hero-copy { padding: var(--wels-stage-pad); }
.wels-stage-eyebrow {
	text-transform: uppercase; letter-spacing: .12em; font-size: .78rem; font-weight: 700;
	color: var(--wels-accent-text, var(--wels-primary)); margin: 0 0 10px;
}
.wels-stage-hero-copy h1 {
	margin: 0; font-size: clamp(2rem, 4.4vw, 3.3rem); line-height: 1.05;
	color: var(--wels-primary-dark, var(--wels-ink));
}
.wels-stage-range {
	margin: 10px 0 16px; font-size: clamp(1.05rem, 2vw, 1.4rem); font-weight: 800;
	text-transform: uppercase; letter-spacing: .04em;
	color: var(--wels-accent-text, var(--wels-primary));
}
.wels-stage-tag {
	display: inline-block; background: var(--wels-alt-bg);
	border-left: 4px solid var(--wels-accent);
	padding: 10px 18px; border-radius: 6px; font-weight: 700;
	font-size: clamp(.98rem, 1.6vw, 1.12rem); color: var(--wels-ink); margin-bottom: 16px;
}
.wels-stage-hero-copy p { margin: 0; color: var(--wels-muted); font-size: 1.02rem; line-height: 1.75; }
/*
 * A hero with NO picture. The grid above is 1fr 1.1fr for copy-left / photo-right, so
 * without a media child the heading sits in the narrower column and over half the band
 * is empty — the same defect the stream cards had at tablet width, and the same one an
 * empty paragraph caused in the feature section.
 *
 * It matters here because a fabricated photograph is worse than none: a page waiting for
 * a real picture should look deliberate, not broken.
 *
 * Two classes via :not(:has()), so it outranks the single-class rules here and in the
 * breakpoint below.
 */
.wels-stage-hero-grid:not(:has(.wels-stage-hero-media)) { grid-template-columns: 1fr; }
.wels-stage-hero-media { align-self: stretch; min-height: 300px; }
.wels-stage-hero-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- The strip of six ---- */
.wels-stage-points {
	list-style: none; margin: 0; padding: clamp(18px, 2.4vw, 26px) 10px;
	background: #fff; border: 1px solid rgba(20,40,38,.08); border-radius: var(--wels-radius);
	box-shadow: var(--wels-shadow-sm);
	display: grid; grid-template-columns: repeat(6, 1fr);
}
.wels-stage-point { text-align: center; padding: 6px 14px; border-left: 1px solid rgba(20,40,38,.08); }
.wels-stage-point:first-child { border-left: 0; }
.wels-stage-ico {
	width: 52px; height: 52px; border-radius: 50%; background: var(--wels-alt-bg);
	display: grid; place-items: center; margin: 0 auto 11px;
}
.wels-stage-ico::before {
	content: ""; width: 26px; height: 26px; background: var(--wels-primary);
	-webkit-mask: var(--wels-ico) center / contain no-repeat;
	        mask: var(--wels-ico) center / contain no-repeat;
}
.wels-stage-point h3 { margin: 0 0 5px; font-size: .88rem; line-height: 1.3; color: var(--wels-ink); }
.wels-stage-point p { margin: 0; font-size: .78rem; line-height: 1.5; color: var(--wels-muted); }

/* ---- Approach ---- */
.wels-stage-approach.has-no-media { grid-template-columns: 1.4fr .72fr; }
.wels-stage-approach { display: grid; grid-template-columns: 1fr 1.05fr .62fr; gap: clamp(20px, 2.6vw, 32px); align-items: center; }
.wels-stage-approach-media img { width: 100%; height: 300px; object-fit: cover; border-radius: var(--wels-radius); display: block; }
.wels-stage-approach h2 { margin: 0 0 18px; font-size: var(--wels-h2); color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-stage-approach h2::after {
	content: ""; display: block; width: 48px; height: 4px; border-radius: 10px;
	background: var(--wels-accent); margin-top: 10px;
}
.wels-stage-approach p { margin: 0; color: var(--wels-muted); line-height: 1.8; }
.wels-stage-aside {
	background: var(--wels-alt-bg); border-radius: var(--wels-radius);
	padding: clamp(22px, 2.6vw, 30px) 24px; text-align: center;
}
.wels-stage-aside h3 { margin: 0 0 10px; font-size: 1.22rem; color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-stage-aside p { margin: 0; font-size: .92rem; line-height: 1.7; color: var(--wels-muted); }
.wels-stage-aside .wels-stage-ico { background: #fff; }

/* ---- Activities ---- */
.wels-stage-activities { background: var(--wels-alt-bg); border-radius: var(--wels-radius); padding: var(--wels-stage-pad); }
.wels-stage-activities h2 { margin: 0 0 10px; font-size: var(--wels-h2); color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-stage-activities h2::after {
	content: ""; display: block; width: 48px; height: 4px; border-radius: 10px;
	background: var(--wels-accent); margin-top: 10px;
}
.wels-stage-lead { max-width: 680px; margin: 0 0 26px; color: var(--wels-muted); line-height: 1.75; }
.wels-stage-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.wels-stage-card {
	background: #fff; border-radius: var(--wels-radius); overflow: hidden;
	box-shadow: var(--wels-shadow-sm); display: flex; flex-direction: column;
	transition: transform .18s ease, box-shadow .18s ease;
}
.wels-stage-card:hover { transform: translateY(-4px); box-shadow: var(--wels-shadow); }
/*
 * Card picture shape. aspect-ratio, not a fixed pixel height, and that is the point:
 * the card is 290-470px wide depending on the breakpoint, so a fixed height meant the
 * SHAPE of the slot changed with the viewport — measured, it ran from 1.44:1 on a phone
 * to 2.15:1 at 900px. A photograph cannot be cropped to fit a shape that will not hold
 * still, so whatever was framed for one width lost heads at another.
 *
 * 4:3 because the slot was too shallow: at 175px tall a portrait photograph kept 42%
 * of its height and cut people off. 4:3 keeps 56% and is deep enough for a standing
 * figure. The photographs on this component are now cut to 4:3 before upload, so the
 * browser crops nothing at all at any width.
 */
.wels-stage-card img { width: 100%; aspect-ratio: 4 / 3; height: auto; object-fit: cover; display: block; }
.wels-stage-card-body { padding: 17px 18px 19px; }
/* A card with no photograph yet gets the icon instead, so the row stays even
   while the school is still collecting pictures. It is CENTRED and given the
   room the picture would have taken — left top-aligned it reads as a card
   whose image failed to load, rather than as a card waiting for one. */
.wels-stage-card:not(:has(img)) { background: linear-gradient(180deg, var(--wels-alt-bg), #fff 60%); }
.wels-stage-card:not(:has(img)) .wels-stage-card-body {
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	text-align: center; height: 100%; padding: 30px 22px 32px;
}
.wels-stage-card:not(:has(img)) h3 { justify-content: center; }
.wels-stage-card-body > .wels-stage-ico { margin: 0 0 14px; width: 60px; height: 60px; background: #fff; }
.wels-stage-card-body > .wels-stage-ico::before { width: 30px; height: 30px; }
.wels-stage-card h3 { margin: 0 0 5px; font-size: 1.02rem; color: var(--wels-ink); display: flex; align-items: center; gap: 9px; }
.wels-stage-card p { margin: 0; font-size: .86rem; line-height: 1.6; color: var(--wels-muted); }

/* ---- Closing band ---- */
.wels-stage-closing {
	background: linear-gradient(120deg, var(--wels-primary-dark, var(--wels-primary)), var(--wels-primary));
	color: #fff; border-radius: var(--wels-radius);
	padding: clamp(38px, 5vw, 62px) var(--wels-stage-pad); text-align: center;
}
.wels-stage-closing h2 { color: #fff; margin: 0 0 12px; font-size: var(--wels-h2); }
.wels-stage-closing h2::after { content: none; }
.wels-stage-closing p { max-width: 700px; margin: 0 auto 24px; line-height: 1.75; color: rgba(255,255,255,.9); }
/* The accent is a light colour, so on this dark band it is the one thing that
   can carry a button: ink on accent reads where white on accent would not. */
.wels-stage-closing .wels-btn,
.wels-stage-closing .wels-btn:hover,
.wels-stage-closing .wels-btn:focus { background: var(--wels-accent); color: var(--wels-ink); border-color: var(--wels-accent); }


/* ---------------------------------------------------------------------------
   STAGE TONE  —  the same component, aged

   The four stage pages should read as one family while getting steadily more
   grown-up: the early years playful, primary a little more ordered, the middle
   and senior years more sober again. That is a handful of modifiers on this one
   component, not four stylesheets — so a change to the component still reaches
   all four, and the difference between them stays small enough to be a family
   rather than four designs.

   Add is-early / is-primary / is-middle / is-senior to .wels-stage.
------------------------------------------------------------------------- */

/* ---- Six soft tints behind the strip icons ----
   These belong to the COMPONENT, not to one tone. They were scoped to
   .is-early at first, on the reading that the later stages should be plainer —
   but the stage mockups all carry the same six circles, and the maturity the
   brief asks for lives in the CONTENT of each page (laboratories, board
   preparation, streams) rather than in taking the colour away. A page that
   loses its colour as the children get older reads as an omission, which is
   exactly how it was reported.
   The only hardcoded colours in this component, and they earn it: decorative
   grounds behind a brand-coloured icon, carrying no meaning and no contrast
   burden, desaturated enough to sit under any school's palette. */
.wels-stage .wels-stage-point:nth-child(1) .wels-stage-ico { background: #ffe9ef; }
.wels-stage .wels-stage-point:nth-child(2) .wels-stage-ico { background: #fff2d2; }
.wels-stage .wels-stage-point:nth-child(3) .wels-stage-ico { background: #ddf6e9; }
.wels-stage .wels-stage-point:nth-child(4) .wels-stage-ico { background: #e1f2fd; }
.wels-stage .wels-stage-point:nth-child(5) .wels-stage-ico { background: #ece8fb; }
.wels-stage .wels-stage-point:nth-child(6) .wels-stage-ico { background: #e8f6dd; }
/* The same six, for a row of cards that is showing icons rather than photographs. */
.wels-stage .wels-stage-card:nth-child(1) .wels-stage-ico { background: #ffe9ef; }
.wels-stage .wels-stage-card:nth-child(2) .wels-stage-ico { background: #fff2d2; }
.wels-stage .wels-stage-card:nth-child(3) .wels-stage-ico { background: #ddf6e9; }
.wels-stage .wels-stage-card:nth-child(4) .wels-stage-ico { background: #e1f2fd; }
.wels-stage .wels-stage-card:nth-child(5) .wels-stage-ico { background: #ece8fb; }
.wels-stage .wels-stage-card:nth-child(6) .wels-stage-ico { background: #e8f6dd; }

/* ---- is-early: the playful end ---- */
.wels-stage.is-early .wels-stage-tag { transform: rotate(-1deg); border-radius: 10px; }
.wels-stage.is-early .wels-stage-card { border-radius: calc(var(--wels-radius) + 4px); }

/* ---- A split panel: a labelled block of text beside a photograph ----
   Used for the Class X board-preparation block on the middle years page, and
   available to any stage that needs to single one thing out. */
.wels-stage-feature {
	display: grid; grid-template-columns: .85fr 1.15fr;
	background: var(--wels-alt-bg); border-radius: var(--wels-radius); overflow: hidden;
}
.wels-stage-feature.has-no-media { grid-template-columns: 1fr; }
/*
 * ...and the same when the media is absent at RUNTIME rather than at build time.
 * [wels_board_result] prints nothing while no poster is set — the state between one
 * year's results and the next — and the has-no-media class above cannot know that,
 * because it is written into the page once and this changes whenever the school
 * clears the field. Without this the section stays a two-column grid with the text
 * squeezed into the first column: the same defect the stream cards had at tablet
 * width, where the body sat in 40% of the card and 60% was blank.
 *
 * :not(:has(...)) takes the specificity of its argument, so this is two classes and
 * outranks the single-class rules both here and inside the breakpoints.
 */
.wels-stage-feature:not(:has(.wels-stage-feature-media)) { grid-template-columns: 1fr; }
/*
 * Belt and braces for the same problem. The filter in functions.php removes empty
 * paragraphs from stage content, but content can also be pasted or edited in ways that
 * put one back, and in a grid or flex container an empty <p> is a full participant — it
 * takes a column. Nothing in this component ever wants one.
 */
.wels-stage p:empty { display: none; }
.wels-stage-media-cap {
	margin: 10px 0 0; font-size: .82rem; line-height: 1.5;
	color: var(--wels-muted); text-align: center;
}
.wels-stage-feature-body {
	padding: clamp(28px, 4vw, 48px);
	display: flex; flex-direction: column; justify-content: center;
}
.wels-stage-feature-body h2 { margin: 0 0 14px; font-size: var(--wels-h2); color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-stage-feature-body h2::after { content: none; }
.wels-stage-feature-body p { margin: 0 0 14px; color: var(--wels-muted); line-height: 1.75; }
.wels-stage-feature-body p:last-child { margin-bottom: 0; }
.wels-stage-feature-media { min-height: 330px; }
.wels-stage-feature-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/*
 * A PORTRAIT picture in this slot — the CBSE results poster, which is 0.84:1.
 *
 * The default above fills the cell and crops, which is right for a photograph used as a
 * backdrop and completely wrong for a notice that has to be READ. Measured, this cell
 * runs from 0.97:1 at 1440px to 3.25:1 at 900px, where it is an 845x260 band; the poster
 * dropped into that would show a quarter of its height with every line sliced.
 *
 * So this modifier stops the cell dictating the height and lets the picture keep its own
 * shape, centred, capped so it cannot tower over the text beside it.
 *
 * On specificity, because this component has caught me out before: every rule here is
 * two classes, so it outranks both the single-class default above AND the single-class
 * `min-height: 260px` inside the 1000px breakpoint. Media queries add no weight of their
 * own, so a one-class rule in a breakpoint loses to a two-class rule outside it — which
 * is what makes this modifier safe without repeating it per breakpoint.
 */
.wels-stage-feature-media.is-portrait { min-height: 0; display: block; }
.wels-stage-feature-media.is-portrait .wels-gallery-item {
	display: block; max-width: 520px; margin-inline: auto; cursor: zoom-in;
}

/*
 * MORE THAN ONE POSTER. [stated] AJ: "what if we have to add another pic? can a scroll
 * be added?" — Grade X and Grade XII arrive separately, and a school may want last
 * year's up beside this year's.
 *
 * Side by side was the obvious answer and the wrong one: this column is about 485px on
 * a desktop, so two portrait posters sharing it are roughly 235px each, which is a
 * thumbnail of a document whose whole purpose is to be read. One at a time, full width,
 * scrolled sideways.
 *
 * Scroll snapping rather than a JavaScript carousel. The browser already does momentum,
 * touch, trackpad, shift-wheel, keyboard once the strip is focusable, and a visible
 * scrollbar that tells you there is more — all of it accessible, none of it to maintain.
 * The theme does own a carousel, but it is built around .wels-card-grid and would have
 * dragged card chrome in with it.
 *
 * The real reading experience is the lightbox, which already handled arrays: every
 * poster carries the whole set, so clicking any one opens it with arrows, a counter,
 * keyboard and swipe.
 */
.wels-stage-feature-media.is-multi .wels-result-strip {
	display: flex; gap: 14px; overflow-x: auto; overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
	padding-bottom: 10px; scrollbar-width: thin;
	/* The cap goes on the STRIP, not on each slide. Capping the slides would make
	   them narrower than the track, so two would show at once and the snap would
	   stop meaning "one poster at a time". Capping the track keeps a second poster
	   exactly the same size as a single one — measured, without this a poster grew
	   from 520px to 845px the moment a second was added, which is a strange thing
	   to happen when you add a picture. */
	max-width: 520px; margin-inline: auto;
}
.wels-stage-feature-media.is-multi .wels-gallery-item {
	flex: 0 0 100%; max-width: 100%; margin-inline: 0; scroll-snap-align: center;
}
.wels-stage-feature-media.is-multi .wels-result-strip:focus-visible {
	outline: 2px solid var(--wels-accent); outline-offset: 4px; border-radius: var(--wels-radius);
}
/*
 * A page's own photographs, as a sideways strip.
 *
 * It borrows .wels-stage-activities for the heading and spacing so it sits in the page
 * like the sections already there — the whole point was to add pictures WITHOUT
 * redesigning anything around them.
 *
 * Slides are min(460px, 82%) rather than 100%: a sliver of the next picture is visible
 * at every width, which is what tells somebody there is more to see. A strip where the
 * first slide fills the frame exactly looks like a single photograph and goes
 * unscrolled. (The result poster opposite is the other case — there one-at-a-time is
 * right, because a document half in frame is just cut off.)
 *
 * aspect-ratio 3/2 on every slide, and the files are cut to 3:2 before upload, so the
 * strip is even whatever a school adds later and the browser crops nothing today.
 */
/*
 * A numbered list of rules — the code of conduct, and any policy like it.
 *
 * Single column on purpose. Two columns fit more on a screen but break the reading
 * order of a numbered list: the eye has no way to know whether 10 follows 9 below it
 * or across from it. A code of conduct is read once, carefully, so legibility beats
 * density.
 *
 * The number is drawn from a counter rather than the browser's own marker so it can be
 * styled and, more usefully, stay aligned when an item runs to several lines — a
 * default marker lets the second line slide under the number.
 */
/*
 * A full-width piece of artwork at the top of a prose page — the code-of-conduct
 * masthead and anything like it.
 *
 * No border-radius: this artwork ends in a rule that runs edge to edge, and rounding
 * the corners clips its ends in a way that reads as a rendering fault rather than a
 * style. Artwork that already has its own frame should not be given a second one.
 */
.wels-page-body .wels-page-figure { margin: 0 0 28px; }
.wels-page-body .wels-page-figure img { display: block; width: 100%; height: auto; }

.wels-rules { list-style: none; margin: 0; padding: 0; counter-reset: wels-rule; }
.wels-rules > li {
	counter-increment: wels-rule; position: relative;
	padding: 0 0 14px 46px; margin: 0 0 14px;
	border-bottom: 1px solid var(--wels-line, rgba(0,0,0,.08));
	line-height: 1.7; color: var(--wels-ink);
}
.wels-rules > li:last-child { border-bottom: 0; margin-bottom: 0; }
.wels-rules > li::before {
	content: counter(wels-rule); position: absolute; left: 0; top: 0;
	width: 30px; height: 30px; border-radius: 50%;
	display: flex; align-items: center; justify-content: center;
	font-size: .82rem; font-weight: 700;
	background: var(--wels-alt-bg, #eef3fa); color: var(--wels-primary-dark, var(--wels-ink));
}
@media (max-width: 620px) {
	.wels-rules > li { padding-left: 40px; }
	.wels-rules > li::before { width: 26px; height: 26px; font-size: .76rem; }
}

/*
 * The newsletter archive — one card per year: cover, year, download.
 *
 * A flex row that scrolls rather than a grid that wraps. With one or two issues the
 * cards simply sit there and nothing looks like an empty shelf; by the fifth year it
 * scrolls instead of pushing the rest of the page down. Same browser-native snapping
 * as the photo strips, so touch, trackpad, keyboard and the scrollbar all behave.
 *
 * COVERS ARE CONTAINED. Cards must share a height or the row looks broken, but a cover
 * cropped to a common shape loses its masthead — the part that identifies the issue.
 * A fixed 3:4 frame with object-fit:contain keeps every cover whole; an odd-shaped one
 * shows a little backdrop, which is tidier than a sliced title.
 */
.wels-newsletters {
	list-style: none; margin: 0; padding: 0 0 12px;
	display: flex; gap: 20px; overflow-x: auto; overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.wels-newsletters:focus-visible {
	outline: 2px solid var(--wels-accent); outline-offset: 4px; border-radius: var(--wels-radius);
}
.wels-newsletter-card {
	flex: 0 0 236px; scroll-snap-align: start;
	display: flex; flex-direction: column;
	background: #fff; border-radius: var(--wels-radius); overflow: hidden;
	box-shadow: var(--wels-shadow-sm);
	transition: transform .18s ease, box-shadow .18s ease;
}
.wels-newsletter-card:hover { transform: translateY(-4px); box-shadow: var(--wels-shadow); }
.wels-newsletter-cover {
	display: block; aspect-ratio: 3 / 4; background: var(--wels-alt-bg, #eef3fa);
	position: relative;
}
.wels-newsletter-cover img { width: 100%; height: 100%; object-fit: contain; display: block; }
.wels-newsletter-nocover {
	position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
	font-weight: 700; color: var(--wels-muted); font-size: 1.1rem;
}
.wels-newsletter-body { padding: 16px 16px 18px; display: flex; flex-direction: column; flex: 1; }
.wels-newsletter-body h3 {
	margin: 0 0 4px; font-size: 1.05rem; color: var(--wels-primary-dark, var(--wels-ink));
}
.wels-newsletter-body p { margin: 0 0 14px; font-size: .82rem; line-height: 1.55; color: var(--wels-muted); }
/* margin-top:auto pins the button to the bottom so a card with a note and one
   without still line their buttons up across the row. */
.wels-newsletter-btn {
	margin-top: auto; align-self: stretch;
	/* Tighter than a page button: at 236px wide a card cannot spare 22px of padding
	   either side, and a full-width button in a narrow card reads better than a small
	   one floating at the left. */
	padding: 10px 14px; font-size: .86rem;
}
@media (prefers-reduced-motion: reduce) {
	.wels-newsletter-card, .wels-newsletter-card:hover { transition: none; transform: none; }
}
@media (max-width: 620px) {
	.wels-newsletter-card { flex: 0 0 200px; }
}

.wels-photo-strip {
	display: flex; gap: 16px; overflow-x: auto; overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
	padding-bottom: 12px; scrollbar-width: thin;
}
.wels-photo-strip .wels-gallery-item {
	flex: 0 0 min(460px, 82%); scroll-snap-align: center; display: block;
	border-radius: var(--wels-radius); overflow: hidden; cursor: zoom-in;
	box-shadow: var(--wels-shadow-sm);
	transition: transform .18s ease, box-shadow .18s ease;
}
.wels-photo-strip .wels-gallery-item:hover { transform: translateY(-4px); box-shadow: var(--wels-shadow); }
.wels-photo-strip img {
	display: block; width: 100%; aspect-ratio: 3 / 2; height: auto;
	object-fit: cover;
}
.wels-photo-strip:focus-visible {
	outline: 2px solid var(--wels-accent); outline-offset: 4px; border-radius: var(--wels-radius);
}
@media (prefers-reduced-motion: reduce) {
	.wels-photo-strip .wels-gallery-item,
	.wels-photo-strip .wels-gallery-item:hover { transition: none; transform: none; }
}

.wels-stage-media-hint {
	margin: 4px 0 0; font-size: .76rem; color: var(--wels-muted);
	text-align: center; opacity: .85;
}
/*
 * width:100% + height:auto, NOT a max-height. Measured, the first attempt at this used
 * `height: auto; max-height: 720px` inside a flex container, and the picture came out
 * 317x447 on a 1920px screen and 219x309 on a phone — the container was a grid item
 * taking its height from the row, and the image was being fitted into that height
 * instead of to the column it sits in. A results poster at 219px across is a thumbnail.
 *
 * Giving the image the full width of its column and letting the height follow the
 * aspect ratio makes the row grow to the picture rather than the picture shrink to the
 * row, which is the right way round for the one element on the page that has to be
 * read. The 520px cap stops it towering over the text on a wide screen.
 */
.wels-stage-feature-media.is-portrait img {
	display: block; width: 100%; height: auto; max-height: none;
	max-width: 520px; margin-inline: auto;
	object-fit: contain; border-radius: var(--wels-radius);
}
.wels-stage-label {
	align-self: start; margin: 0 0 13px; padding: 6px 13px; border-radius: 20px;
	background: #fff; color: var(--wels-primary);
	font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .09em;
}

/* ---- A short row of figures ----
   For the one or two numbers a stage can actually prove. Deliberately plain:
   a figure a school can stand behind needs no decoration. */
.wels-stage-figures { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 14px 28px; }
.wels-stage-figure { border-left: 3px solid var(--wels-accent); padding-left: 14px; }
.wels-stage-figure b {
	display: block; font-family: var(--wels-heading-font); font-size: 1.7rem; line-height: 1.1;
	color: var(--wels-primary-dark, var(--wels-primary));
}
.wels-stage-figure span { font-size: .82rem; color: var(--wels-muted); }

@media (max-width: 1000px) {
	.wels-stage-feature { grid-template-columns: 1fr; }
	.wels-stage-feature-media { min-height: 260px; order: -1; }
}

/* ---- is-primary: a little more ordered ---- */
/* No tilt, one tint rather than six, and a thin rule along the top of each
   card — the first hint of the ruled, sectioned look the senior pages take
   further. */
.wels-stage.is-primary .wels-stage-tag { transform: none; }
.wels-stage.is-primary .wels-stage-card { border-top: 3px solid var(--wels-accent); }

/* ---- is-middle: sober. Rules instead of tints ----
   The step from Primary is a step DOWN in decoration, not up: the filled
   circles become outlined squares, the highlight chip loses its fill, and the
   cards are divided by a rule rather than topped with a colour. Laboratories
   and board preparation are not pastel subjects. */
/* The tints stay — see the note above. What changes is the SHAPE: a softly
   squared container rather than a circle, which is a quieter form without
   being a plainer one. */
.wels-stage.is-middle .wels-stage-tag { transform: none; }
.wels-stage.is-middle .wels-stage-ico { border-radius: 12px; }
.wels-stage.is-middle .wels-stage-card { border-top: 0; }
.wels-stage.is-middle .wels-stage-card h3 {
	padding-bottom: 9px; margin-bottom: 9px; border-bottom: 1px solid rgba(20,40,38,.1);
}

/* ---- Streams: the one decision a Class X student is on the page to make ----
   Full cards rather than the subject grid the other stages use, because three
   choices deserve more room than six subjects do. */
.wels-stage-streams { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.wels-stage-stream {
	background: #fff; border-radius: var(--wels-radius); overflow: hidden;
	box-shadow: var(--wels-shadow-sm); display: flex; flex-direction: column;
	transition: transform .18s ease, box-shadow .18s ease;
}
.wels-stage-stream:hover { transform: translateY(-5px); box-shadow: var(--wels-shadow); }
.wels-stage-stream > img { width: 100%; height: 205px; object-fit: cover; display: block; }
.wels-stage-stream-body { padding: 22px; display: flex; flex-direction: column; flex: 1; }
.wels-stage-stream-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.wels-stage-stream-head .wels-stage-ico { width: 48px; height: 48px; flex: 0 0 48px; margin: 0; }
.wels-stage-stream-head h3 { margin: 0; font-size: 1.22rem; color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-stage-stream-body > p { margin: 0 0 18px; color: var(--wels-muted); font-size: .92rem; line-height: 1.65; }

/* The subject panel. Tinted per stream so the three are told apart at a glance
   without needing to be read. */
.wels-stage-subjects { margin-top: auto; padding: 15px 17px; border-radius: 11px; background: var(--wels-alt-bg); }
.wels-stage-stream.is-science  .wels-stage-subjects,
.wels-stage-stream.is-science  .wels-stage-ico { background: #e6f2fc; }
.wels-stage-stream.is-commerce .wels-stage-subjects,
.wels-stage-stream.is-commerce .wels-stage-ico { background: #fff4da; }
.wels-stage-stream.is-arts     .wels-stage-subjects,
.wels-stage-stream.is-arts     .wels-stage-ico { background: #ffeef2; }
.wels-stage-subjects strong { display: block; margin-bottom: 9px; font-size: .8rem; color: var(--wels-ink); }
.wels-stage-subjects ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; }
.wels-stage-subjects li { position: relative; padding-left: 18px; font-size: .78rem; line-height: 1.45; color: var(--wels-muted); }
.wels-stage-subjects li::before {
	content: ""; position: absolute; left: 0; top: .32em; width: 11px; height: 11px;
	background: var(--wels-primary);
	-webkit-mask: var(--wels-tick) center / contain no-repeat;
	        mask: var(--wels-tick) center / contain no-repeat;
}
.wels-stage-subjects { --wels-tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5.5 5.5L20 6'/%3E%3C/svg%3E"); }
/* No subject list yet: say so in a sentence rather than printing placeholders.
   "Subject Option" on a live page is worse than an honest line. */
.wels-stage-subjects p { margin: 0; font-size: .78rem; line-height: 1.55; color: var(--wels-muted); }

/* ---- A four-up row of icon cards, no photographs ---- */
.wels-stage-grid.is-four { grid-template-columns: repeat(4, 1fr); }
.wels-stage-grid.is-four .wels-stage-card { background: #fff; }
.wels-stage-grid.is-four .wels-stage-card-body { display: block; text-align: left; height: auto; padding: 24px 20px 26px; }
.wels-stage-grid.is-four .wels-stage-card h3 { justify-content: flex-start; }
.wels-stage-grid.is-four .wels-stage-card-body > .wels-stage-ico { margin: 0 0 13px; width: 50px; height: 50px; }

/* ---- A row of small picture tiles with a caption ---- */
.wels-stage-tiles { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; }
.wels-stage-tile {
	background: #fff; border-radius: var(--wels-radius); overflow: hidden;
	box-shadow: var(--wels-shadow-sm); transition: transform .18s ease;
}
.wels-stage-tile:hover { transform: translateY(-4px); }
.wels-stage-tile img { width: 100%; height: 135px; object-fit: cover; display: block; }
.wels-stage-tile h3 { margin: 0; padding: 14px 10px; text-align: center; font-size: .84rem; line-height: 1.4; color: var(--wels-ink); }

/* ---- The split panel, in the school's dark colour ---- */
.wels-stage-feature.is-dark {
	background: linear-gradient(120deg, var(--wels-primary-dark, var(--wels-primary)), var(--wels-primary));
}
.wels-stage-feature.is-dark .wels-stage-feature-body h2 {
	color: #fff; padding-left: 18px; border-left: 4px solid var(--wels-accent);
}
.wels-stage-feature.is-dark .wels-stage-feature-body p { color: rgba(255,255,255,.9); }
.wels-stage-feature.is-dark .wels-stage-label { background: rgba(255,255,255,.14); color: #fff; }
/* The figures take their colour from the brand, which on this band is the band
   itself — dark navy on dark navy. White, and the accent for the rule. */
.wels-stage-feature.is-dark .wels-stage-figure { border-left-color: var(--wels-accent); }
.wels-stage-feature.is-dark .wels-stage-figure b { color: #fff; }
.wels-stage-feature.is-dark .wels-stage-figure span { color: rgba(255,255,255,.78); }
.wels-stage-feature.is-dark .wels-btn,
.wels-stage-feature.is-dark .wels-btn:hover,
.wels-stage-feature.is-dark .wels-btn:focus {
	background: var(--wels-accent); color: var(--wels-ink); border-color: var(--wels-accent);
	align-self: start;
}

/* ---- is-senior: the quietest of the four ---- */
.wels-stage.is-senior .wels-stage-tag { transform: none; }
.wels-stage.is-senior .wels-stage-ico { border-radius: 12px; }
.wels-stage.is-senior .wels-stage-stream-head .wels-stage-ico { border-radius: 50%; }

@media (max-width: 1000px) {
	.wels-stage-streams { grid-template-columns: 1fr; }
	.wels-stage-stream { display: grid; grid-template-columns: .8fr 1.2fr; }
	/*
	 * ...but only a stream that HAS a picture. The two-column grid above is
	 * picture-left / text-right, so with no <img> the body lands in the .8fr column
	 * and the rest of the card is empty. Measured at 900px before this rule existed:
	 * the Commerce and Arts text sat in 309px of a 773px card, 40% of the width, the
	 * other 60% blank. Back to the stacked layout it uses at every other width.
	 */
	.wels-stage-stream:not(:has(> img)) { display: flex; }
	.wels-stage-stream > img { height: 100%; min-height: 280px; }
	.wels-stage-grid.is-four { grid-template-columns: repeat(2, 1fr); }
	.wels-stage-tiles { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 620px) {
	.wels-stage-stream { display: flex; }
	.wels-stage-stream > img { height: 210px; min-height: 0; }
	.wels-stage-subjects ul { grid-template-columns: 1fr; }
	.wels-stage-grid.is-four { grid-template-columns: 1fr; }
	.wels-stage-tiles { grid-template-columns: repeat(2, 1fr); }
}

/* ---- A strip of FOUR rather than six ----
   Same component; some pages have four things to say, not six. */
.wels-stage-points.is-four { grid-template-columns: repeat(4, 1fr); }
.wels-stage-points.is-four .wels-stage-point h3 { font-size: 1rem; }
.wels-stage-points.is-four .wels-stage-point p { font-size: .84rem; }

/* ---- Picture beside copy, with no third column ----
   The approach block without its pull-out card. */
.wels-stage-approach.is-pair { grid-template-columns: 1fr 1fr; gap: clamp(26px, 3.4vw, 42px); }
.wels-stage-approach.is-pair .wels-stage-approach-media img { height: 340px; }

/* ---- Rules: an icon beside its text, four across ----
   Not the card grid: these are things to READ, in order, so they are set as a
   list with the icon to the left rather than as centred tiles. */
.wels-stage-ruleset {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px;
}
.wels-stage-rule {
	display: flex; gap: 14px; padding: 20px 17px;
	background: #fff; border-radius: var(--wels-radius); box-shadow: var(--wels-shadow-sm);
}
.wels-stage-rule .wels-stage-ico { width: 46px; height: 46px; flex: 0 0 46px; margin: 0; }
.wels-stage-rule .wels-stage-ico::before { width: 22px; height: 22px; }
.wels-stage-rule h3 { margin: 2px 0 6px; font-size: .88rem; line-height: 1.35; color: var(--wels-ink); }
.wels-stage-rule p { margin: 0; font-size: .78rem; line-height: 1.6; color: var(--wels-muted); }
/* The six tints repeat down the list, so eight rules do not need eight colours. */
.wels-stage-rule:nth-child(6n+1) .wels-stage-ico { background: #ddf6e9; }
.wels-stage-rule:nth-child(6n+2) .wels-stage-ico { background: #fff2d2; }
.wels-stage-rule:nth-child(6n+3) .wels-stage-ico { background: #ffe9ef; }
.wels-stage-rule:nth-child(6n+4) .wels-stage-ico { background: #e1f2fd; }
.wels-stage-rule:nth-child(6n+5) .wels-stage-ico { background: #ece8fb; }
.wels-stage-rule:nth-child(6n+6) .wels-stage-ico { background: #e8f6dd; }

@media (max-width: 1000px) {
	.wels-stage-points.is-four { grid-template-columns: repeat(2, 1fr); }
	.wels-stage-approach.is-pair { grid-template-columns: 1fr; }
	.wels-stage-ruleset { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
	.wels-stage-ruleset { grid-template-columns: 1fr; }
}

/* ---- A closing band over a photograph ---- */
/* The wash is heavy on purpose: this band carries white text and a button, and
   a photograph underneath it is a background, not a picture to look at. */
.wels-stage-closing.has-photo {
	background-size: cover; background-position: center;
	position: relative; isolation: isolate;
}
.wels-stage-closing.has-photo::before {
	content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
	background: linear-gradient(120deg,
		color-mix(in srgb, var(--wels-primary-dark, var(--wels-primary)) 92%, transparent),
		color-mix(in srgb, var(--wels-primary) 88%, transparent));
}
/* Browsers without color-mix still get a readable band rather than white text
   on a photograph. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
	.wels-stage-closing.has-photo::before { background: rgba(20, 40, 70, .9); }
}

@media (prefers-reduced-motion: reduce) {
	.wels-stage-card { transition: none; }
	.wels-stage-card:hover { transform: none; }
}

@media (max-width: 1000px) {
	.wels-stage-hero-grid { grid-template-columns: 1fr; }
	.wels-stage-hero-media { min-height: 260px; order: -1; }
	.wels-stage-points { grid-template-columns: repeat(3, 1fr); gap: 18px 0; }
	.wels-stage-point { border-left: 0; }
	.wels-stage-approach { grid-template-columns: 1fr 1fr; }
	/* Repeated with the modifier's own specificity. `.wels-stage-approach.has-no-media`
	   is two classes and a media query adds no weight of its own, so the desktop
	   1.4fr .72fr would otherwise hold at every width below this one — which left the
	   prose column 189px wide on a phone. Same trap as the pillar grid. */
	.wels-stage-approach.has-no-media { grid-template-columns: 1fr 1fr; }
	.wels-stage-aside { grid-column: 1 / -1; }
	.wels-stage-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
	.wels-stage-points { grid-template-columns: repeat(2, 1fr); }
	.wels-stage-approach { grid-template-columns: 1fr; }
	.wels-stage-approach.has-no-media { grid-template-columns: 1fr; }
	.wels-stage-aside { grid-column: auto; }
	.wels-stage-grid { grid-template-columns: 1fr; }
	/* No height override here any more: aspect-ratio above holds the shape at every width. */
}

/* ---- The icon set used above ---- */
.wels-stage-ico[data-ico="book"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5.5A1.5 1.5 0 0 1 4.5 4H9a3 3 0 0 1 3 3v12a2.5 2.5 0 0 0-2.5-2.5H3z'/%3E%3Cpath d='M21 5.5A1.5 1.5 0 0 0 19.5 4H15a3 3 0 0 0-3 3v12a2.5 2.5 0 0 1 2.5-2.5H21z'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="spark"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a6 6 0 0 0-3.5 10.9V17h7v-3.1A6 6 0 0 0 12 3z'/%3E%3Cpath d='M9.5 20h5'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="care"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s-7-4.4-7-9.5A3.8 3.8 0 0 1 12 8a3.8 3.8 0 0 1 7 3.5C19 16.6 12 21 12 21z'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="speak"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 11.5a7.5 7.5 0 0 1-10.9 6.7L4 20l1.8-5.1A7.5 7.5 0 1 1 21 11.5z'/%3E%3Cpath d='M9 11h6M9 8h4'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="art"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a9 9 0 1 0 0 18 2 2 0 0 0 2-2 2 2 0 0 1 2-2h1.5A4.5 4.5 0 0 0 22 12.5C22 7.2 17.5 3 12 3z'/%3E%3Ccircle cx='7.5' cy='12' r='1'/%3E%3Ccircle cx='10' cy='8' r='1'/%3E%3Ccircle cx='15' cy='8' r='1'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="sprout"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21v-7'/%3E%3Cpath d='M12 14C12 9.6 15.6 6 20 6c0 4.4-3.6 8-8 8z'/%3E%3Cpath d='M12 16c0-3.3-2.7-6-6-6 0 3.3 2.7 6 6 6z'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="play"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='14.5' cy='4.6' r='1.9'/%3E%3Cpath d='M12.6 9.1L9 11.2l1.9 3.1L9.4 20'/%3E%3Cpath d='M12.6 9.1l3.3 1.6 1.2 3.4 2.9.9'/%3E%3Cpath d='M10.9 14.3l3.6 1.3 1.3 4.4'/%3E%3Cpath d='M8.3 11.5L4.5 12'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="search"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='M16 16l4.5 4.5'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="music"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18V6l10-2v12'/%3E%3Ccircle cx='6.5' cy='18' r='2.5'/%3E%3Ccircle cx='16.5' cy='16' r='2.5'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="blocks"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='12' width='8' height='8' rx='1.5'/%3E%3Crect x='13' y='12' width='8' height='8' rx='1.5'/%3E%3Crect x='8' y='3.5' width='8' height='8' rx='1.5'/%3E%3C/svg%3E"); }

.wels-stage-ico[data-ico="staff"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8' r='3.2'/%3E%3Cpath d='M3 20c0-3.3 2.7-5.5 6-5.5s6 2.2 6 5.5'/%3E%3Ccircle cx='17.5' cy='9.5' r='2.4'/%3E%3Cpath d='M16 14.6c3 .2 5 2.3 5 5.4'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="lab"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 3v6.2L4.8 18A2 2 0 0 0 6.5 21h11a2 2 0 0 0 1.7-3L14 9.2V3'/%3E%3Cpath d='M8.5 3h7'/%3E%3Cpath d='M7.2 15h9.6'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="results"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Ccircle cx='12' cy='12' r='4.5'/%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="maths"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='3' width='16' height='18' rx='2'/%3E%3Cpath d='M8 8h8M8 13h2M14 13h2M8 17h2M14 17h2'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="globe"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M3.5 12h17'/%3E%3Cpath d='M12 3.5c2.4 2.5 2.4 14.5 0 17c-2.4-2.5-2.4-14.5 0-17z'/%3E%3C/svg%3E"); }

.wels-stage-ico[data-ico="shield"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l7.5 2.8v5.5c0 4.3-3 8.3-7.5 9.7-4.5-1.4-7.5-5.4-7.5-9.7V5.8z'/%3E%3Cpath d='M9 12l2.2 2.2L15.2 10'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="bus"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='3.5' width='16' height='13' rx='2.5'/%3E%3Cpath d='M4 11h16'/%3E%3Ccircle cx='8' cy='19' r='1.6'/%3E%3Ccircle cx='16' cy='19' r='1.6'/%3E%3Cpath d='M6.5 16.5v1M17.5 16.5v1M8.5 7h7'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="pin"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s6.5-5.6 6.5-10.2A6.5 6.5 0 0 0 5.5 10.8C5.5 15.4 12 21 12 21z'/%3E%3Ccircle cx='12' cy='10.6' r='2.4'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="clipboard"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='4.5' width='14' height='16' rx='2'/%3E%3Cpath d='M9 4.5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 4.5v1H9z'/%3E%3Cpath d='M8.5 11h7M8.5 15h4.5'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="home"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10.4L12 4l8 6.4'/%3E%3Cpath d='M6 9.4V20h12V9.4'/%3E%3Cpath d='M10 20v-5h4v5'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="calendar"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='5.5' width='16' height='15' rx='2'/%3E%3Cpath d='M4 10h16M9 3.5v4M15 3.5v4'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="ban"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M6 6l12 12'/%3E%3C/svg%3E"); }
.wels-stage-ico[data-ico="rupee"]{ --wels-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 5h8M8 9.2h8M8 5c3.5 0 5.4 1.5 5.4 4.2 0 2.6-1.9 4.2-5.4 4.2h-.2L15 19.5'/%3E%3C/svg%3E"); }

/* ---------------------------------------------------------------------------
 * Flipbook — a hosted flip-book, loaded on request.
 *
 * Everything here styles markup a seed or the school office can actually save:
 * a div, a heading, a paragraph and two links. The frame is created by
 * main.js on click and inserted as .wels-flipbook-frame, so nothing is
 * embedded until somebody asks for it. See the matching comment in main.js.
 * ------------------------------------------------------------------------ */
.wels-flipbook {
	margin: 0 0 28px;
	padding: 26px;
	background: var(--wels-alt-bg, #f6f8f4);
	border-radius: var(--wels-radius, 14px);
}
.wels-flipbook-cover { display: grid; grid-template-columns: 170px 1fr; gap: 26px; align-items: center; }
.wels-flipbook-cover img {
	width: 100%; height: auto; display: block; border-radius: 8px;
	box-shadow: 0 6px 20px rgba(20, 40, 70, .16);
}
.wels-flipbook h3 { margin: 0 0 8px; font-size: 1.3rem; color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-flipbook p { margin: 0 0 16px; color: var(--wels-muted); line-height: 1.7; }
.wels-flipbook-actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* The frame only exists once the visitor has asked for it. 4:3 is close to the
   shape a two-page spread wants; the min-height keeps it usable on a phone,
   where a flip-book is cramped whatever we do. */
.wels-flipbook-stage { margin: 0 0 18px; }
.wels-flipbook-frame {
	width: 100%; aspect-ratio: 4 / 3; min-height: 360px;
	border: 1px solid rgba(20, 40, 70, .14); border-radius: 8px;
	display: block; background: #fff;
}
@supports not (aspect-ratio: 4 / 3) { .wels-flipbook-frame { height: 600px; } }

/* Once it is open the cover has done its job and the frame is the content. */
.wels-flipbook.is-open .wels-flipbook-cover { grid-template-columns: 1fr; }
.wels-flipbook.is-open .wels-flipbook-cover img { display: none; }

@media (max-width: 620px) {
	.wels-flipbook { padding: 20px; }
	.wels-flipbook-cover { grid-template-columns: 1fr; gap: 18px; }
	.wels-flipbook-cover img { max-width: 190px; }
	.wels-flipbook-frame { min-height: 300px; }
}

/* ---- The newsletter index: one card per issue ---- */
.wels-issues { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.wels-issue {
	display: flex; flex-direction: column;
	background: #fff; border: 1px solid rgba(20, 40, 70, .1);
	border-radius: var(--wels-radius, 14px); overflow: hidden;
}
.wels-issue img { width: 100%; height: 300px; object-fit: cover; object-position: top center; display: block; }
.wels-issue-body { padding: 18px 20px 20px; display: flex; flex-direction: column; flex: 1; }
.wels-issue h3 { margin: 0 0 4px; font-size: 1.16rem; color: var(--wels-primary-dark, var(--wels-ink)); }
.wels-issue-meta { margin: 0 0 12px; font-size: .88rem; color: var(--wels-muted); }
.wels-issue .wels-btn { margin-top: auto; align-self: flex-start; }
@media (max-width: 900px) { .wels-issues { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .wels-issues { grid-template-columns: 1fr; } .wels-issue img { height: 260px; } }
