@charset "UTF-8";

/* ==================================================================
   chso2026 — Christian Home School Online Joomla 5/6 site template
   A fork of Paschen Communications' pcom2026 template.
   (C) 2026 Christian Home School Online — GPL-2.0-or-later

   THIS IS THE ONLY STYLESHEET. Edit it and upload it — there is no
   build step, no SCSS, nothing to compile. The file you edit is the
   file the browser loads. (Same architecture pcom2026 moved to in its
   own v1.9 — see that project's CLAUDE.md "Stylesheet: SCSS dropped"
   if you're wondering why this isn't SCSS partials.)

   Plain, FLAT CSS — no nesting, no preprocessor syntax, no minimum
   browser version. Every selector is written out in full, so this file
   works in any browser that understands CSS custom properties.

   Order matters: a rule further down this file beats an identical
   selector further up. Section 9 is last on purpose.

   To re-theme colours, fonts and sizes, edit section 1 only.

   Media queries in this file, and only these four:
     560px   phone     — hamburger menu takes over
     720px   phone/lg  — header switches to the mobile nav toggle
     900px   tablet    — single-column content, sidebars stack
     1280px  desktop   — boxed content max-width, drops left sidebar

   CONTENTS
     1. DESIGN TOKENS  (1a. self-hosted webfonts)
     2. BASE
     3. HEADER
     4. HOME LAYOUT
     5. DEFAULT LAYOUT
     6. CONTENT HELPERS
     7. FOOTER
     8. SYSTEM PAGES
     9. STACKING / Z-INDEX
   ================================================================== */

/* ==================================================================
   1. DESIGN TOKENS  (:root custom properties)
   ================================================================== */

/* ---- 1a. Self-hosted webfonts ----
   Outfit (headings/nav) and Karla (body) are both served by Google as
   variable fonts — a single physical file covers every weight on that
   axis, so each weight below points at the SAME file on purpose; this
   is not a duplication bug. Never re-add a Google Fonts <link> or
   @import: it would leak every visitor's IP + page URL to Google before
   the page paints (GDPR), can't carry an SRI hash, and is render-
   blocking on the error/offline pages. See fonts/OFL.txt for licensing. */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/outfit-variable-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/outfit-variable-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Karla';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/karla-variable-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Karla';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/karla-variable-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Karla';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/karla-variable-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Karla';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/karla-variable-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* ---- Brand colours ----
     Sampled and confirmed against the client's real logo file and live
     site (2026-08): #344E2C is the corrected/authoritative brand green
     — it is what the live hero band and CTA already render at — even
     though the logo artwork itself still measures a slightly different
     green (~#1B6031). Per client direction (2026-08), the logo file is
     NOT recoloured; every UI colour below uses the corrected #344E2C
     family regardless. */
  --color-green: #344E2C; /* PRIMARY brand colour */
  --color-green-dark: #24371E; /* headings, pressed/active state */
  --color-green-hover: #51BE78; /* HOVER accent only — never a resting state */
  --color-green-faint: #E9F1EA; /* pale tint — sidebar module boxes */
  --color-green-faint-line: #CFE3D2;
  --color-brown: #3D3014; /* logo wordmark brown */
  --color-blue-band: #2F4A70; /* background-band colour ONLY */
  --color-blue-band-dark: #22384F; /* footer band */
  --color-cta: #FFAA3A; /* hero call-to-action accent, sampled off the live site */
  --color-cta-dark: #E0901F;
  /* ---- Neutrals ---- */
  --color-ink: #1D2A22; /* body text */
  --color-grey-light: #5C6B62;
  --color-grey-faint: #F0F2EF;
  --color-line: #E3E8E3;
  --color-white: #FFFFFF;
  --color-bg: #F8F9FA;
  /* ---- On-dark text ----
     Every dark band (.t-subfeature, .t-principles, .t-footer) re-scopes
     --color-link / --color-text to these instead of inheriting the brand
     green. This is the fix for the live site's real contrast bug: green
     link text on the dark-blue "About" band was low-contrast and hard to
     read. Never let a dark band inherit the default green link colour. */
  --color-on-dark: #FFFFFF;
  --color-on-dark-muted: #CED9D2;
  /* ---- Functional ---- */
  --color-link: var(--color-green);
  --color-link-hover: var(--color-green-hover);
  /* ---- Alerts ----
     Two tokens per state: --color-<state> is the faint FILL used as the
     alert background, --color-<state>-border is the saturated ACCENT
     used for the 4px left bar. Not interchangeable — see pcom2026's
     TEMPLATE-GUIDE §7 for the full rationale. Bootstrap's standard alert
     palette, on purpose: a Joomla system message should look like one.
     Re-colour in css/local.css, not here — local.css survives upgrades. */
  --color-success: #d4edda;
  --color-success-border: #155724;
  --color-info: #d1ecf1;
  --color-info-border: #0c5460;
  --color-warning: #fff3cd;
  --color-warning-border: #856404;
  --color-danger: #f8d7da;
  --color-danger-border: #721c24;
  /* ---- Typography ---- */
  --font-head: 'Outfit', Arial, Helvetica, sans-serif;
  --font-body: 'Karla', Arial, Helvetica, sans-serif;
  --font-menu: 'Outfit', Arial, Helvetica, sans-serif;
  --fs-300: 0.85rem;
  --fs-400: 1rem;
  --fs-500: 1.15rem;
  --fs-600: 1.3rem;
  --fs-700: 1.5rem;
  --fs-900: 2rem;
  --fs-1200: 2.6rem;
  --fs-1600: 3.4rem;
  /* Oversized display numeral — outside the text scale on purpose. Fluid
     so it doesn't dominate a phone screen. */
  --fs-error-code: clamp(3.5rem, 12vw, 6rem);
  --flh-300: 1.4;
  --flh-400: 1.6;
  --flh-700: 1.2;
  --flh-900: 1.15;
  --flh-1600: 1.08;
  --fw-400: 400;
  --fw-500: 500;
  --fw-600: 600;
  --fw-700: 700;
  --fw-800: 800;
  /* ---- Radius ---- */
  --br-small: 4px;
  --br-std: 8px;
  --br-large: 16px;
  /* ---- Spacing & structure ---- */
  --space-section: 80px;
  --space-gutter: 28px;
  --width-boxed: 1280px;
  --height-header: 92px;
  --height-header-mobile: 72px;
  --height-topbar: 40px;
  /* ---- Effects ---- */
  --shadow-card: 0 18px 40px rgba(24, 44, 32, 0.12);
  --shadow-header: 0 2px 14px rgba(24, 44, 32, 0.08);
  --transition: 0.2s ease;
  /* ---- Layering (z-index scale) ----
     Same published scale pcom2026 uses for its sticky-header fix. High
     values on purpose so third-party module CSS (sliders, page builders,
     pasted Custom HTML) can never scroll over the sticky header. See
     section 9 for the isolation half of the fix. */
  --z-below: -1;
  --z-base: 1;
  --z-sticky: 900;
  --z-header: 1000;
  --z-dropdown: 1010;
  --z-overlay: 1100;
}

/* ==================================================================
   2. BASE  (reset, typography, buttons, layout container)
   ================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body, h1, h2, h3, h4, h5, h6, p, ul, ol, dl, figure { margin: 0; padding: 0; }
body {
  font-family: var(--font-body);
  font-weight: var(--fw-400);
  font-size: var(--fs-400);
  line-height: var(--flh-400);
  color: var(--color-ink);
  background: var(--color-white);
}

/* EVERY heading level gets an explicit size. Levels left unsized fall
   back to the browser default — h5 is 0.83em, h6 is 0.67em, i.e. smaller
   than body text — the first time a third-party module emits a bare
   heading tag. These are bare element selectors (0,0,1) on purpose: a
   page-level class (.t-page-title, .t-sec-head h2) always outranks them. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-head);
  font-weight: var(--fw-700);
  line-height: var(--flh-700);
  color: var(--color-green-dark);
}
h1 { font-size: var(--fs-1200); }
h2 { font-size: var(--fs-900); }
h3 { font-size: var(--fs-700); }
h4 { font-size: var(--fs-600); }
h5 { font-size: var(--fs-500); }
h6 { font-size: var(--fs-400); }

p { margin: 0 0 1em; color: var(--color-ink); }
p:last-child { margin-bottom: 0; }
ul, ol { padding-left: 1.3em; }
ul.t-unstyled, nav ul { list-style: none; padding-left: 0; }
a { color: var(--color-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
a:hover { color: var(--color-link-hover); }
img { max-width: 100%; height: auto; display: block; }
blockquote { margin: 1.4em 0; padding: 0.2em 0 0.2em 1.3em; border-left: 4px solid var(--color-green); color: var(--color-grey-light); font-style: italic; }

/* Boxed content wrapper */
.t-wrap { max-width: var(--width-boxed); margin: 0 auto; padding: 0 var(--space-gutter); }
/* Vertical section rhythm */
.t-section { padding: var(--space-section) 0; }
@media only screen and (max-width: 560px) {
  .t-section { padding: 52px 0; }
}

/* Buttons */
.t-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-head);
  font-weight: var(--fw-600);
  font-size: var(--fs-400);
  padding: 0.85em 1.7em;
  border-radius: var(--br-std);
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition), transform var(--transition);
}
.t-btn-primary { background: var(--color-green); color: var(--color-white); }
.t-btn-primary:hover { background: var(--color-green-hover); color: var(--color-green-dark); }
.t-btn-cta { background: var(--color-cta); color: var(--color-green-dark); }
.t-btn-cta:hover { background: var(--color-cta-dark); color: var(--color-white); }
.t-btn-ghost { border-color: currentColor; color: var(--color-white); background: transparent; }
.t-btn-ghost:hover { background: var(--color-white); color: var(--color-green-dark); }

/* Eyebrow / kicker */
.t-eyebrow {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: var(--fw-700);
  font-size: var(--fs-300);
  color: var(--color-green);
  font-family: var(--font-head);
}

/* ==================================================================
   3. HEADER  (top bar, logo, nav, hamburger, mobile drawer)
   ================================================================== */

/* ---- Top bar ---- */
.t-topbar { background: var(--color-blue-band-dark); color: var(--color-on-dark-muted); font-size: var(--fs-300); isolation: isolate; }
.t-topbar .t-wrap { display: flex; justify-content: space-between; align-items: center; min-height: var(--height-topbar); flex-wrap: wrap; gap: 4px 20px; }
.t-topbar a { color: var(--color-on-dark-muted); text-decoration: none; }
.t-topbar a:hover { color: var(--color-white); }
.t-topbar-start, .t-topbar-end { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

/* ---- Header ---- */
.t-header { position: sticky; top: 0; z-index: var(--z-header); background: var(--color-white); box-shadow: var(--shadow-header); }
.t-header-inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: var(--height-header); }

/* Drive logo size from max-height and let the width follow, so the global
   img{max-width:100%} reset never squashes it horizontally on a narrow
   header row. Never pin a fixed height here. */
.t-logo { flex: 0 0 auto; }
.t-logo img { max-height: 52px; width: auto; height: auto; display: block; }

/* ---- Main navigation (module output) ---- */
.t-nav { flex: 1 1 auto; }
.t-nav ul { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; list-style: none; padding: 0; margin: 0; }
.t-nav li { position: relative; }
.t-nav > ul > li > a {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-menu);
  font-weight: var(--fw-600);
  font-size: var(--fs-400);
  color: var(--color-green-dark);
  text-decoration: none;
  padding: 10px 14px;
  border-radius: var(--br-small);
}
.t-nav > ul > li > a:hover,
.t-nav > ul > li.active > a,
.t-nav > ul > li.current > a { background: var(--color-green); color: var(--color-white); }

/* Non-clickable menu items — Menu Item Type "Heading" (or "Separator")
   with no link target of its own. Joomla's own mod_menu core markup
   renders these as <span class="mod-menu__heading nav-header"> instead
   of <a>, so without this rule they fall back to unstyled inline text
   that looks broken sitting next to real nav links.

   TWO cases, confirmed against live markup — a heading behaves differently
   depending on whether it has children:
     - No children (rare/pointless in a nav, but technically legal): the
       span is a direct child of <li>. It must carry the FULL box model
       itself here, exactly matching .t-nav > ul > li > a (padding,
       display:flex, etc.) since there's no wrapping element to carry it.
     - HAS children — the only kind seen in practice, since a heading with
       nothing under it serves no purpose in a nav: Joomla core wraps it in
       <button class="mod-menu__toggle-sub">, making the span a GRANDCHILD
       of <li> (li > button > span). Here the BUTTON carries the box model
       (see the button rule below) and the span only needs typography —
       giving the span its own padding too would double up with the
       button's and misalign the mobile drawer's 48px tap rows. */
.t-nav > ul > li > .mod-menu__heading {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-menu);
  font-weight: var(--fw-600);
  font-size: var(--fs-400);
  color: var(--color-green-dark);
  padding: 10px 14px;
  cursor: default;
}
.t-nav > ul > li > button.mod-menu__toggle-sub > .mod-menu__heading {
  font-family: var(--font-menu);
  font-weight: var(--fw-600);
  font-size: var(--fs-400);
  color: var(--color-green-dark);
  cursor: default;
}
.t-nav ul ul .mod-menu__heading {
  display: block;
  padding: 10px 14px;
  color: var(--color-green-faint);
  font-size: var(--fs-300);
  font-weight: var(--fw-600);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  cursor: default;
}

/* A top-level item that HAS children gets its label wrapped by Joomla in
   <button class="mod-menu__toggle-sub"> — for a "Heading" type the whole
   label sits inside the button (which is why it carries the same padding/
   flex box model as .t-nav > ul > li > a below — it IS the visible row
   for that case); for a linked type it's a separate button right after
   the <a> (padding overridden further down for that narrower case). */
.t-nav > ul > li > button.mod-menu__toggle-sub {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  margin: 0;
  padding: 10px 14px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
/* .t-nav > ul > li > a is display:flex, which is block-level — without
   this the sibling toggle button below would drop to its own line under
   every linked parent that has children. Making the <li> itself the flex
   row keeps <a> and the button on one line and gives the button its own
   tap/click target distinct from the link text. */
.t-nav > ul > li:has(> a + button.mod-menu__toggle-sub) {
  display: flex;
  align-items: stretch;
}
.t-nav > ul > li > a + button.mod-menu__toggle-sub {
  padding: 10px 14px 10px 0;
}

/* Dropdown indicator — styles Joomla's own <span class="icon-chevron-down">,
   which core mod_menu already prints inside every top-level
   mod-menu__toggle-sub button (for BOTH linked and heading-type parents).
   It renders as an empty, invisible span today because this template
   loads no icon font; giving it a CSS-only arrow shape here means the
   indicator works for every parent type without guessing from markup.
   Gated on the menuCaret template style param — see templateDetails.xml
   and TEMPLATE-GUIDE.md. Off by default to match pcom2026/mmpark2026. */
.menu-caret .t-nav .icon-chevron-down {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.7;
  margin: 0 2px 2px 4px;
}
/* Deeper (level 2+) flyout parents get no button/chevron from Joomla core
   at all — startLevel-only per mod_menu's own template. :has() is used
   elsewhere in this file already (section 9's overlay escape hatch), so
   it carries no extra browser-support cost. */
.menu-caret .t-nav ul ul li:has(> ul) > a::after,
.menu-caret .t-nav ul ul li:has(> ul) > .mod-menu__heading::after {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  opacity: 0.7;
  margin-left: 6px;
}

/* Drop-downs are kept in the DOM and toggled with visibility/opacity,
   opening on hover AND :focus-within so keyboard users can reach them.
   If you restyle drop-downs, keep both selectors.

   display:block is REQUIRED here, not cosmetic: Joomla core's own
   mod_menu.menu web-asset preset (loaded unconditionally by the
   unmodified core mod_menu layout — this template has no mod_menu
   override) ships `:where(.mod-menu__sub[aria-hidden="true"]) { display:
   none }`, and its JS sets aria-hidden="true" on every submenu on load.
   :where() carries zero specificity, but display:none still wins over
   opacity/visibility unless something here sets an explicit display
   value with real specificity — this rule is that override. Without it
   the menu stays display:none regardless of hover/:focus-within, which
   is why dropdowns silently failed to open at all. */
.t-nav ul ul {
  position: absolute;
  top: 100%;
  left: 0;
  display: block;
  min-width: 210px;
  background: var(--color-green);
  border-radius: 0 0 var(--br-std) var(--br-std);
  box-shadow: var(--shadow-card);
  padding: 6px;
  list-style: none;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--transition), transform var(--transition), visibility var(--transition);
  z-index: var(--z-dropdown);
}
.t-nav li:hover > ul, .t-nav li:focus-within > ul { opacity: 1; visibility: visible; transform: translateY(0); }
.t-nav ul ul a {
  display: block;
  padding: 10px 14px;
  color: var(--color-white);
  font-size: var(--fs-400);
  font-weight: var(--fw-500);
  border-radius: var(--br-small);
  text-decoration: none;
}
.t-nav ul ul a:hover { background: var(--color-green-hover); color: var(--color-green-dark); }

.t-header-end { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }

/* Optional social-link pills for the header-end position (see
   module-content/header-social.html). Not required — header-end works
   with any content, styled or not. */
.t-social { display: flex; gap: 8px; flex-wrap: wrap; }
.t-social a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-head);
  font-size: var(--fs-300);
  font-weight: var(--fw-600);
  color: var(--color-white);
  background: var(--color-green);
  padding: 7px 12px;
  border-radius: 999px;
  text-decoration: none;
}
.t-social a.t-social-fb { background: var(--color-blue-band); }
.t-social a:hover { opacity: 0.85; color: var(--color-white); }

/* ---- Hamburger toggle ---- */
.t-nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--br-small);
  border: 2px solid var(--color-green);
  background: var(--color-white);
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
}
.t-nav-toggle span { display: block; width: 20px; height: 2px; background: var(--color-green-dark); }

/* ---- Responsive: tablet ----
   Tighten nav item padding before the drawer takes over, so a medium
   viewport doesn't wrap the desktop nav mid-row. */
@media only screen and (max-width: 900px) {
  .t-nav > ul > li > a,
  .t-nav > ul > li > .mod-menu__heading,
  .t-nav > ul > li > button.mod-menu__toggle-sub { padding: 10px 10px; font-size: var(--fs-300); }
  /* Wrapped heading (see section 3) — the button above carries the
     padding, this only needs to shrink the text to match. */
  .t-nav > ul > li > button.mod-menu__toggle-sub > .mod-menu__heading { font-size: var(--fs-300); }
  .t-topbar { font-size: var(--fs-400); }
  .t-topbar .t-wrap { justify-content: center; text-align: center; }
}

/* ---- Responsive: mobile nav ---- */
@media only screen and (max-width: 720px) {
  .t-header-inner { min-height: var(--height-header-mobile); }
  .t-header-end > *:not(.t-nav-toggle) { display: none; }
  .t-nav-toggle { display: inline-flex; }

  /* Rendered INSIDE <header>, which is position:sticky and therefore this
     panel's containing block — position:absolute + top:100% pins the
     drawer under the header at any scroll offset. If the nav is ever
     moved out to a header sibling it drops back into normal flow at the
     top of the document and the toggle appears dead at any scroll
     position except the very top. Keep it inside <header>. */
  .t-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-white);
    box-shadow: var(--shadow-card);
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--transition);
    z-index: var(--z-dropdown);
  }
  .t-nav.is-open { max-height: calc(100dvh - var(--height-header-mobile)); overflow-y: auto; }
  .t-nav > ul { flex-direction: column; align-items: stretch; padding: 8px; gap: 0; }

  /* display:flex + min-height:48px on purpose — padding alone does not
     guarantee a tap target; a short label in a display:block anchor
     collapses to the line box. Re-stated on ul ul a and the heading/
     toggle-sub rules below, which are more specific. */
  .t-nav > ul > li > a,
  .t-nav > ul > li > .mod-menu__heading,
  .t-nav > ul > li > button.mod-menu__toggle-sub { display: flex; min-height: 48px; padding: 0 14px; width: 100%; text-align: left; justify-content: flex-start; }

  /* A linked parent with children gets Joomla's toggle button as a
     SEPARATE sibling after the <a> (unlike a heading parent, where the
     button wraps the whole label — handled by the width:100% rule
     above). Put the <li> itself in a row so the link fills the space
     and the toggle button sits at the end as its own tap target. */
  .t-nav > ul > li:has(> a + button.mod-menu__toggle-sub) { display: flex; align-items: stretch; }
  .t-nav > ul > li > a + button.mod-menu__toggle-sub { width: auto; min-height: 48px; padding: 0 14px; margin: 0; flex: 0 0 auto; }
  .t-nav > ul > li:has(> a + button.mod-menu__toggle-sub) > a { flex: 1 1 auto; min-width: 0; width: auto; }
  .t-nav ul ul {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    box-shadow: none;
    background: var(--color-green-faint);
    display: none;
  }
  .t-nav li.is-open > ul { display: block; }
  .t-nav ul ul a { color: var(--color-green-dark); min-height: 44px; display: flex; align-items: center; }
  .t-nav ul ul .mod-menu__heading { color: var(--color-green-dark); min-height: 44px; display: flex; align-items: center; }

  /* Toggle button rotates 180° while its submenu is open — a plain
     transform on the icon Joomla core already prints, no extra markup. */
  .t-nav li.is-open > button.mod-menu__toggle-sub .icon-chevron-down,
  .t-nav li.is-open > a + button.mod-menu__toggle-sub .icon-chevron-down { transform: rotate(180deg); }
}

/* ==================================================================
   4. HOME LAYOUT  (hero, features, sub-feature, principles, news, CTA)
   ================================================================== */

/* ---- Hero ---- */
.t-hero { background: var(--color-green); color: var(--color-white); }
.t-hero > .mod-wrapper, .t-hero > div, .t-hero .t-wrap { padding-top: 68px; padding-bottom: 68px; }
.t-hero h1, .t-hero h2 { color: var(--color-white); font-size: var(--fs-1600); margin-bottom: 0.4em; }
.t-hero p { color: var(--color-on-dark-muted); font-size: var(--fs-500); max-width: 30em; }

/* Optional helper for hero content placed in a Custom HTML module: a
   2-column grid (copy + illustration/art), collapsing to 1 column. */
.t-hero-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 40px; align-items: center; }
.t-hero-art { justify-self: end; }
.t-hero-art img, .t-hero-art svg { width: 100%; max-width: 380px; height: auto; }

/* ---- Section heading (centered eyebrow + title + intro) ---- */
.t-sec-head { text-align: center; max-width: 40em; margin: 0 auto 48px; }
.t-sec-head .t-eyebrow { display: block; margin-bottom: 0.6em; }
.t-sec-head h2 { margin: 0; }
.t-sec-head p { color: var(--color-grey-light); font-size: var(--fs-500); margin-top: 0.6em; }

/* ---- Feature (card grid) ---- */
.t-feature { background: var(--color-white); }
.t-feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-gutter); }
.t-card {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--br-large);
  padding: 32px 28px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: box-shadow var(--transition), transform var(--transition);
}
.t-card:hover { box-shadow: var(--shadow-card); transform: translateY(-4px); }
.t-card-ico { width: 56px; height: 56px; border-radius: 50%; background: var(--color-green-faint); color: var(--color-green); display: grid; place-items: center; margin-bottom: 18px; }
.t-card-ico svg { width: 28px; height: 28px; }
.t-card-title { margin-bottom: 0.5em; }
.t-card p { color: var(--color-grey-light); margin-bottom: 1.2em; }
.t-card .t-btn { margin-top: auto; }

/* ---- "About" band (sub-feature) ----
   The dark-blue split band. --color-link is re-scoped to white here —
   this is the fix for the live site's green-on-blue contrast bug. */
.t-subfeature {
  background: var(--color-blue-band);
  color: var(--color-on-dark-muted);
  --color-link: var(--color-white);
  --color-link-hover: var(--color-green-hover);
}
.t-subfeature .t-wrap { padding: 64px var(--space-gutter); }
.t-subfeature h2, .t-subfeature h3 { color: var(--color-white); }
.t-subfeature p { color: var(--color-on-dark-muted); }
.t-subfeature a { color: var(--color-white); font-weight: var(--fw-600); }
.t-subfeature a:hover { color: var(--color-green-hover); }

/* Split helper for content placed inside the sub-feature module: a large
   heading column + a copy column. */
.t-split { display: grid; grid-template-columns: 0.9fr 1.5fr; gap: 48px; align-items: start; }
.t-split h2 { font-size: var(--fs-1200); line-height: 1.05; }

/* ---- Philosophy | Academics | Success (principles) ----
   Exact visual replica of the client's existing section: dark tinted
   photo background, 3 columns of icon + title + text. Fonts/spacing are
   modernised to the new type system; the icon/title/text/background
   CONTENT and concept are unchanged per spec. */
.t-principles {
  position: relative;
  color: var(--color-on-dark-muted);
  --color-link: var(--color-white);
  --color-link-hover: var(--color-green-hover);
  background:
    linear-gradient(rgba(6, 10, 8, 0.86), rgba(6, 10, 8, 0.9)),
    url('../images/principles-bg.jpg') center / cover no-repeat;
}
.t-principles-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }
.t-principle-ico { width: 46px; height: 46px; color: var(--color-green-hover); margin-bottom: 18px; }
.t-principle-ico svg { width: 100%; height: 100%; }
.t-principles h3 { color: var(--color-white); margin-bottom: 0.5em; }
.t-principles p { color: var(--color-on-dark-muted); }

/* ---- News & Updates ---- */
.t-news { background: var(--color-bg); }
.t-news-body { }
.t-news-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-gutter); align-items: start; }
.t-news-feature { display: grid; grid-template-columns: 140px 1fr; gap: 18px; background: var(--color-white); border: 1px solid var(--color-line); border-radius: var(--br-std); padding: 18px; }
.t-news-feature img { border-radius: var(--br-small); aspect-ratio: 4 / 3; object-fit: cover; }
.t-news-feature h4 { margin-bottom: 0.3em; }
.t-news-list { list-style: none; padding: 0; margin: 0; }
.t-news-list li { display: flex; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--color-line); }
.t-news-list li:first-child { padding-top: 0; }
.t-news-list img { width: 64px; height: 64px; object-fit: cover; border-radius: var(--br-small); flex: 0 0 auto; }
.t-news-list h4 { margin-bottom: 0.2em; font-size: var(--fs-500); }
.t-news time { display: block; font-size: var(--fs-300); color: var(--color-grey-light); margin-bottom: 0.4em; }

/* ---- Home main content (component/article output between the feature
   grid and the sub-feature band) ---- */
.t-main-home { position: relative; }
.t-main-home > .t-wrap { padding: var(--space-section) var(--space-gutter); }
.t-main-home:empty, .t-main-home > .t-wrap:empty { padding: 0; }

/* ---- Call to action ---- */
.t-cta { background: var(--color-cta); color: var(--color-green-dark); text-align: center; --color-link: var(--color-green-dark); }
.t-cta > .mod-wrapper, .t-cta > div, .t-cta .t-wrap { padding: 56px var(--space-gutter); }
.t-cta h2 { color: var(--color-green-dark); }

/* ---- Responsive ---- */
@media only screen and (max-width: 900px) {
  .t-hero-grid { grid-template-columns: 1fr; text-align: center; }
  .t-hero-art { justify-self: center; order: -1; max-width: 260px; }
  .t-feature-grid { grid-template-columns: 1fr; }
  .t-split { grid-template-columns: 1fr; gap: 20px; }
  .t-principles-grid { grid-template-columns: 1fr; gap: 32px; text-align: center; }
  .t-principle-ico { margin-left: auto; margin-right: auto; }
  .t-news-grid { grid-template-columns: 1fr; }
  .t-news-feature { grid-template-columns: 100px 1fr; }
}

/* ==================================================================
   5. DEFAULT LAYOUT  (page banner, content/sidebar grid, modules)
   ================================================================== */

/* ---- Page banner ----
   Off by default for this template (pageBanner defaults to "never" — see
   templateDetails.xml): the approved design has no coloured banner band,
   the page heading is simply the article/component's own <h1>. The rule
   is kept so a future page/style can switch pageBanner to auto/always
   without any template code changing. */
.t-page-banner { background: var(--color-blue-band); color: var(--color-white); }
.t-page-banner .t-wrap { padding: 44px var(--space-gutter) 40px; }
.t-page-title { color: var(--color-white); margin: 0; }
.t-crumbs, .t-crumbs-bare { font-size: var(--fs-300); }
.t-crumbs { margin-top: 14px; color: var(--color-on-dark-muted); }
.t-crumbs a { color: var(--color-on-dark-muted); }
.t-crumbs-bare { padding-top: 24px; color: var(--color-grey-light); }
.t-crumbs ul, .t-crumbs-bare ul { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; padding: 0; margin: 0; }
.t-crumbs li:not(:last-child)::after, .t-crumbs-bare li:not(:last-child)::after { content: '/'; margin-left: 6px; opacity: 0.6; }

.t-default-main { padding: 56px 0 var(--space-section); }
.t-default-main h1 { margin-bottom: 0.9em; }
.t-content h2 { margin-top: 1.7em; margin-bottom: 0.5em; }
.t-content h2:first-child { margin-top: 0; }
.t-content p { max-width: 62em; }
.t-content ul, .t-content ol { max-width: 62em; }

/* Column widths for the content/sidebar grid. Collapses cleanly when a
   sidebar has no module assigned — index.php only prints t-has-l/t-has-r
   when countModules() found one. */
.t-layout { display: grid; grid-template-columns: 1fr; gap: 48px; }
.t-layout.t-has-r { grid-template-columns: 1fr 300px; align-items: start; }
.t-layout.t-has-l { grid-template-columns: 260px 1fr; align-items: start; }
.t-layout.t-has-lr { grid-template-columns: 260px 1fr 300px; align-items: start; }

/* Sidebar module box — pale green on brand (chso2026 default; pcom2026's
   equivalent .t-module is pale blue). */
.t-module { background: var(--color-green-faint); border: 1px solid var(--color-green-faint-line); border-radius: var(--br-std); padding: 24px; margin-bottom: var(--space-gutter); }
.t-module:last-child { margin-bottom: 0; }
.t-module-title { color: var(--color-green-dark); margin-bottom: 0.6em; font-size: var(--fs-500); }
.t-module-body p:last-child { margin-bottom: 0; }

/* Example Module Class Suffix variant — proves the Advanced > Module Class
   field reaches the rendered markup via chso_module.php (see that chrome
   file's $sfx handling). Enter "t-module--center" in a module's Advanced >
   Module Class field to centre that one box, e.g. the "Invite Friends" promo
   box — see module-content/sidebar-invite-friends.html. */
.t-module.t-module--center { text-align: center; }

@media only screen and (max-width: 1280px) {
  .t-layout.t-has-lr { grid-template-columns: 1fr 300px; }
}
@media only screen and (max-width: 900px) {
  .t-layout.t-has-r, .t-layout.t-has-l, .t-layout.t-has-lr { grid-template-columns: 1fr; }
}

/* ==================================================================
   6. CONTENT HELPERS  (reusable .c- structural classes)
   ================================================================== */
.c-grid { display: grid; gap: var(--space-gutter); }
.c-grid--2 { grid-template-columns: repeat(2, 1fr); }
.c-grid--3 { grid-template-columns: repeat(3, 1fr); }
.c-grid--4 { grid-template-columns: repeat(4, 1fr); }
.c-grid--auto { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
@media only screen and (max-width: 900px) {
  .c-grid--3, .c-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media only screen and (max-width: 560px) {
  .c-grid--2, .c-grid--3, .c-grid--4 { grid-template-columns: 1fr; }
}

.c-row { display: flex; flex-wrap: wrap; gap: var(--space-gutter); }
.c-row--middle { align-items: center; }
.c-row--between { justify-content: space-between; }
.c-row--center { justify-content: center; }
.c-row--equal > * { flex: 1 1 0; }

.c-stack > * + * { margin-top: var(--space-gutter); }
.c-stack--lg > * + * { margin-top: var(--space-section); }

.c-narrow { max-width: 62em; }
.c-center { text-align: center; }

/* Add new reusable structural classes below this line — keep them
   namespaced .c-, keep values in the section 1 tokens, and write media
   queries longhand (custom properties can't be used in a media condition). */

/* ==================================================================
   7. FOOTER
   ================================================================== */
.t-footer {
  background: var(--color-blue-band-dark);
  color: var(--color-on-dark-muted);
  --color-link: var(--color-white);
  --color-link-hover: var(--color-green-hover);
}
.t-footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--space-gutter); padding: 56px 0 32px; }
.t-footer-col p { color: var(--color-on-dark-muted); max-width: 32em; }
.t-footer-logo img { max-height: 40px; width: auto; margin-bottom: 18px; }
.t-footer-module + .t-footer-module { margin-top: 22px; }
.t-footer-title { color: var(--color-white); font-size: var(--fs-500); margin-bottom: 0.8em; }
.t-footer-body a { display: block; padding: 4px 0; color: var(--color-on-dark-muted); text-decoration: none; }
.t-footer-body a:hover { color: var(--color-white); }
.t-footer-bottom { border-top: 1px solid rgba(255, 255, 255, 0.14); padding: 20px 0; }
.t-footer-meta { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; font-size: var(--fs-300); color: var(--color-on-dark-muted); }
.t-footer-meta a { color: var(--color-on-dark-muted); }

@media only screen and (max-width: 900px) { .t-footer-grid { grid-template-columns: 1fr 1fr; } }
@media only screen and (max-width: 560px) { .t-footer-grid { grid-template-columns: 1fr; } }

/* ==================================================================
   8. SYSTEM PAGES  (error / offline / messages / print)
   ================================================================== */
.t-error-main, .t-offline-main { min-height: 60vh; display: flex; align-items: center; justify-content: center; padding: var(--space-section) 0; }
.t-error-box { text-align: center; max-width: 40em; margin: 0 auto; }
.t-error-code { font-family: var(--font-head); font-weight: var(--fw-800); font-size: var(--fs-error-code); color: var(--color-green); line-height: 1; margin-bottom: 0.2em; }
.t-error-title { margin-bottom: 0.5em; }
.t-error-msg { color: var(--color-grey-light); margin-bottom: 1.6em; }
.t-error-footer .t-footer-bottom { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; }
.t-error-footer .t-footer-logo img { max-height: 32px; }
.t-copyright { font-size: var(--fs-300); color: var(--color-on-dark-muted); }

.t-offline-box { max-width: 26em; margin: 0 auto; text-align: center; padding: 0 var(--space-gutter); }
.t-offline-logo { max-height: 56px; width: auto; margin: 0 auto 24px; }
.t-offline-msg { color: var(--color-grey-light); margin-bottom: 1.6em; }
.t-offline-form { text-align: left; display: flex; flex-direction: column; gap: 14px; }
.t-field label { display: block; font-weight: var(--fw-600); margin-bottom: 4px; font-size: var(--fs-300); }
.t-field input {
  width: 100%;
  padding: 0.7em 0.9em;
  border: 1px solid var(--color-line);
  border-radius: var(--br-small);
  font-size: var(--fs-400); /* 16px floor — never smaller, or iOS Safari zooms the page on focus */
  font-family: var(--font-body);
}

/* Joomla system messages */
.alert { border-radius: var(--br-small); border-left: 4px solid var(--color-green); background: var(--color-green-faint); color: var(--color-ink); padding: 14px 18px; margin: 0 0 var(--space-gutter); }
.alert-success { background: var(--color-success); border-left-color: var(--color-success-border); }
.alert-info { background: var(--color-info); border-left-color: var(--color-info-border); }
.alert-warning { background: var(--color-warning); border-left-color: var(--color-warning-border); }
.alert-danger, .alert-error { background: var(--color-danger); border-left-color: var(--color-danger-border); }

/* Screen-reader-only text. Joomla core mod_menu markup relies on this
   exact class name existing — the deeper-parent toggle button (see
   section 3's .mod-menu__toggle-sub rules) prints
   <span class="visually-hidden">More about: X</span> alongside its
   visible label, assuming the site loads Bootstrap's utility CSS, which
   this template deliberately doesn't. Without this rule that "invisible"
   text renders as plain visible text next to every dropdown toggle. This
   is the standard hide-visually-but-not-from-assistive-tech pattern (same
   one Bootstrap's own .visually-hidden and WordPress's .screen-reader-text
   use) — not display:none, which screen readers also skip. */
.visually-hidden,
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

@media print {
  .t-header, .t-topbar, .t-nav-toggle, .t-footer, .t-sidebar { display: none !important; }
  body { color: #000; background: #fff; }
  a { color: #000; text-decoration: underline; }
}

/* ==================================================================
   9. STACKING / Z-INDEX
   ================================================================== */
/* Keeps the sticky header above module content. The header sits at
   --z-header (1000); every region that renders module or component
   output gets isolation:isolate, so a z-index:99999 inside a module only
   competes with the other elements *inside that same region* — the
   region as a whole still paints below the header. This is the permanent
   fix, not an arms race with the next module's z-index.

   If you add a new module region to index.php, add its wrapper class to
   BOTH selector lists below. */
.t-topbar, .t-hero, .t-feature, .t-subfeature, .t-principles, .t-news, .t-cta,
.t-page-banner, .t-layout, .t-default-main, .t-main-home, .t-footer {
  isolation: isolate;
}

/* Escape hatch: a module that genuinely needs to cover the page
   (lightbox, cookie bar, off-canvas) gets class="t-overlay-escape" on a
   wrapper element inside it; its region stops isolating and the element
   is placed above the header at --z-overlay. */
.t-topbar:has(.t-overlay-escape), .t-hero:has(.t-overlay-escape),
.t-feature:has(.t-overlay-escape), .t-subfeature:has(.t-overlay-escape),
.t-principles:has(.t-overlay-escape), .t-news:has(.t-overlay-escape),
.t-cta:has(.t-overlay-escape), .t-page-banner:has(.t-overlay-escape),
.t-layout:has(.t-overlay-escape), .t-default-main:has(.t-overlay-escape),
.t-main-home:has(.t-overlay-escape), .t-footer:has(.t-overlay-escape) {
  isolation: auto;
}
.t-overlay-escape { z-index: var(--z-overlay); }
