/* ==========================================================================
   LAAD — London Academy of Art & Design
   Design System v2.0
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. DESIGN TOKENS
   -------------------------------------------------------------------------- */
:root {
    /* Colour — Clean institutional palette, accent-only brand magenta */
    --ink: #1a1a1a;
    --ink-secondary: #4a4a4a;
    /* #767676 gave only 4.29:1 on --surface-warm and 4.03:1 on --surface-tinted.
       #6e6e6e clears WCAG AA (4.5:1) on white, warm and tinted alike. */
    --ink-muted: #6e6e6e;
    --ink-inverse: #ffffff;

    --surface: #ffffff;
    --surface-warm: #faf8f6;
    --surface-tinted: #f5f0f3;
    --surface-dark: #1a1a1a;
    --surface-dark-secondary: #2a2a2a;

    --accent: #ba4a98;
    --accent-dark: #962f7a;
    --accent-light: #f0e0eb;
    --accent-subtle: rgba(186, 74, 152, 0.06);

    --border: #e5e5e5;
    --border-light: #f0f0f0;
    --border-accent: rgba(186, 74, 152, 0.2);

    /* Typography — Editorial hierarchy */
    --font-display: 'Sora', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-md: 1.125rem;
    --text-lg: 1.25rem;
    --text-xl: 1.5rem;
    --text-2xl: 2rem;
    --text-3xl: 2.5rem;
    --text-4xl: clamp(2.5rem, 5vw, 3.5rem);
    --text-5xl: clamp(3rem, 6vw, 4.5rem);
    /* Display scale. Everything above stops at the H1, which is why every page
       previously read at one volume from the hero down. These two carry the
       editorial voice; see the dense/editorial split at §5. */
    --text-6xl: clamp(3.5rem, 7vw, 5.5rem);      /* 56 -> 88px  display: hero H1 and editorial headings */

    /* 64 -> 112px display: SHORT page titles only. This is the second attempt at
       a step above 6xl. The first, a 72->128px token on 2026-07-27, was applied
       to every H1 and measured: the home H1 is 46 characters in a half-width
       column, so at 128px it filled the viewport alone and pushed the hero
       cards, the CTA and everything else below the fold. It was removed.

       What changed is not the size but the gate. This step is opt-in per page
       and only reachable when the title is short enough to survive it — the
       hero template measures the string and adds .hero--short-title at <= 20
       characters, which today is exactly two pages ("Ballet Training",
       "LAAD Programmes"). The home H1 stays at 6xl and cannot reach this. */
    --text-7xl: clamp(4rem, 9vw, 7rem);

    --leading-tight: 1.1;
    --leading-snug: 1.25;
    --leading-normal: 1.6;
    --leading-relaxed: 1.75;
    /* Negative leading. Below 1.0 the lines of a large heading close up and the
       whole thing reads as one graphic object rather than as loose lines. Only
       ever apply this at --text-6xl and above. */
    --leading-display: 0.94;

    --tracking-tight: -0.02em;
    --tracking-normal: 0;
    --tracking-wide: 0.05em;
    --tracking-wider: 0.1em;
    --tracking-display: -0.03em;

    /* Layout */
    --max-width: 1280px;
    --max-width-narrow: 720px;
    --max-width-wide: 1440px;
    --gutter: clamp(1rem, 3vw, 2rem);
    --section-gap: clamp(3rem, 6vw, 5rem);

    /* Radii — sharp. The design-mix pass (2026-07-28) took the whole system from
       institutional-rounded to hard-edged: corners are a decision, and this one
       says "printed matter", not "app". The tokens are kept rather than deleted
       because 26 declarations reference them; retuning here moves all of them at
       once and leaves one place to reverse the decision.

       --radius-sm is the only nonzero step and is reserved for controls a finger
       or a caret lands in (inputs, selects, textareas), where a hairline of
       softening reads as "editable" without reading as "bubbly". Everything
       structural — cards, images, panels, buttons — is square.

       --radius-full is kept but has no callers left: every pill became a
       rectangle in this pass, and the one genuine circle in the system (the
       utility-bar dot at §21) states `50%` directly. It stays defined so that a
       future round object has the token to reach for, and so the pill decision
       is visibly a decision rather than a deletion. */
    --radius-sm: 3px;
    --radius-md: 0;
    --radius-lg: 0;
    --radius-xl: 0;
    --radius-full: 999px;

    /* Shadows — abolished as a surface device. Depth was doing the work that
       borders should do: a soft shadow says "floating card", a 1px rule says
       "this is a block of a grid". Every former shadow step now resolves to
       `none` so the ~13 declarations that reference them go flat without being
       hunted down individually, and the components that need definition state a
       border instead.

       Kept as tokens, not removed, for exactly one reason: `box-shadow` is also
       how the focus rings are drawn, and those must never be flattened. Focus
       tokens are separate and live below. */
    --shadow-sm: none;
    --shadow-md: none;
    --shadow-lg: none;
    --shadow-xl: none;

    /* The bars device — LAAD's structural ornament, adapted from The New School's
       barred wordmark. A heavy rule and a hairline, always paired, always in this
       order top-to-bottom. Used to frame section headers, the footer wordmark and
       the mega-menu lid; replaces three separate one-off accent bars (3px, 4px,
       24x2px) that were doing the same job in three different ways. */
    --rule-heavy: 4px;
    --rule-hairline: 1px;
    --rule-gap: 3px;

    /* Transitions */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --duration-fast: 150ms;
    --duration-base: 250ms;
    --duration-slow: 400ms;
    --duration-reveal: 600ms;

    /* Focus */
    --focus-ring: 0 0 0 3px rgba(186, 74, 152, 0.4);
    --focus-ring-offset: 0 0 0 2px var(--surface);
    /* The magenta ring is invisible against --accent-dark and near-invisible on
       --surface-dark. Anything focusable inside a dark or accent band must use
       this instead; see the scoping rules at the end of §8. */
    --focus-ring-inverse: 0 0 0 3px rgba(255, 255, 255, 0.9);

    /* Header */
    --header-height: 72px;

    /* Footer kept from v1 for reference (now dark) */
    --footer-magenta: #d60db7;
    --footer-base: #6b6675;
    --footer-ink: #ffffff;
    --footer-skyline-opacity: 0.3;
}

/* --------------------------------------------------------------------------
   2. RESET & BASE
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 400;
    line-height: var(--leading-normal);
    color: var(--ink);
    background: var(--surface-warm);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

a {
    color: inherit;
    text-decoration-skip-ink: auto;
}

/* --------------------------------------------------------------------------
   3. ACCESSIBILITY
   -------------------------------------------------------------------------- */

/* Skip Link */
.skip-link {
    position: absolute;
    top: -100px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--ink);
    color: var(--ink-inverse);
    padding: 0.75rem 1.5rem;
    border-radius: var(--radius-md);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--text-sm);
    z-index: 10000;
    transition: top var(--duration-base) var(--ease-out);
}

.skip-link:focus {
    top: 1rem;
    outline: none;
    box-shadow: var(--focus-ring);
}

/* Visually hidden but announced. The curriculum tables use it for their
   <caption>, which names the month a table belongs to for screen-reader users
   who reach the table out of the surrounding heading context. Clip-path rather
   than display:none or width:0, both of which remove it from the a11y tree. */
.screen-reader-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Focus Styles */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-offset), var(--focus-ring);
    border-radius: var(--radius-sm);
}

/* --------------------------------------------------------------------------
   4. LAYOUT
   -------------------------------------------------------------------------- */
.container {
    width: 100%;
    max-width: var(--max-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.container--narrow {
    max-width: var(--max-width-narrow);
}

.container--wide {
    max-width: var(--max-width-wide);
}

/* --------------------------------------------------------------------------
   5. TYPOGRAPHY
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    color: var(--ink);
    /* Long-word safety valve, 2.12.0. WCAG 2.1 1.4.10 Reflow.

       Turkish is agglutinative and routinely produces words English never
       does — "Yapılandırılmış", "Derslerimizden", "yolculuğunuzdaki". At 320px
       a section content box is 288px, and one such word overflows it *without
       widening it*, so no bounding-rect check can see it; only
       scrollWidth vs clientWidth does. Measured 2026-07-29 on the new Turkish
       surface: /tr/ 341>320 and /tr/hobby-programmes/ 335>320.

       2.9.0 solved the same problem for `.section--editorial > h2` and the
       photo-grid headings. Putting the valve on the base heading rule covers
       every heading in both languages instead of waiting for the next page to
       trip over it.

       Deliberately NOT `hyphens: auto` — a hyphenated display word is still
       the thing this type system avoids. This only lets a word that cannot fit
       break rather than break the page. `.hero-banner-title` overrides this
       back to `overflow-wrap: normal` and keeps its no-break behaviour. */
    overflow-wrap: break-word;
}

h1 {
    font-size: var(--text-5xl);
    font-weight: 800;
    letter-spacing: -0.03em;
}

h2 {
    font-size: var(--text-3xl);
}

h3 {
    font-size: var(--text-xl);
}

h4 {
    font-size: var(--text-lg);
}

p {
    margin-block: 0.5em;
    color: var(--ink-secondary);
    line-height: var(--leading-normal);
    /* Same 2.12.0 valve as the headings above. The footer kicker was the body
       -copy case: "Yaratıcı yolculuğunuzdaki" overflowed .page-footer by 13px
       at 320 on every Turkish route. */
    overflow-wrap: break-word;
}

strong {
    color: var(--ink);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   6. HEADER
   -------------------------------------------------------------------------- */
.site-header {
    position: sticky;
    top: 0;
    z-index: 1000;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid transparent;
    transition: border-color var(--duration-base), box-shadow var(--duration-base);
}

.site-header.is-scrolled {
    border-bottom-color: var(--border);
    box-shadow: var(--shadow-sm);
}

/* Utility bar */
.utility-bar {
    background: var(--surface-warm);
    border-bottom: 1px solid var(--border-light);
    font-size: var(--text-xs);
    display: none;
}

.utility-bar .container {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 1.5rem;
    height: 36px;
}

.utility-bar a {
    color: var(--ink-muted);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    font-weight: 500;
    transition: color var(--duration-fast);
}

.utility-bar a:hover {
    color: var(--accent);
}

@media (min-width: 1024px) {
    .utility-bar {
        display: block;
    }
}

/* Main header bar.

   72px is short for an institutional site at 1440px — it leaves the wordmark
   nothing to sit in. It grows to 88px on desktop and collapses back to 64px
   once the page is scrolled, reusing the .is-scrolled class theme.js already
   toggles at scrollY > 8 rather than adding a second scroll listener.

   --header-height is overridden on .site-header, not :root, deliberately: the
   mobile nav overlay pads itself with calc(var(--header-height) + 1rem) and
   must keep reading the static value. */
.header-bar {
    height: var(--header-height);
    transition: height var(--duration-base) var(--ease-out);
}

@media (min-width: 1024px) {
    .site-header {
        --header-height: 88px;
    }

    .site-header.is-scrolled {
        --header-height: 64px;
    }

    .site-header.is-scrolled .brand-logo {
        height: 38px;
    }
}

.brand-logo {
    transition: height var(--duration-base) var(--ease-out);
}

.header-bar .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 100%;
    gap: 1rem;
}

/* Brand / Logo */
.brand {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    text-decoration: none;
    flex-shrink: 0;
}

.brand-logo {
    height: 48px;
    width: auto;
}

.brand-text {
    display: flex;
    flex-direction: column;
}

.brand-name {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 800;
    color: var(--ink);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
}

.brand-descriptor {
    font-size: var(--text-xs);
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    font-weight: 500;
    margin-top: 0.125rem;
}

/* Primary Navigation */
.primary-nav {
    display: none;
    align-items: center;
    gap: 0;
}

@media (min-width: 1024px) {
    .primary-nav {
        display: flex;
    }
}

.primary-nav a,
.primary-nav > .nav-group > button {
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 0.875rem;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-secondary);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    position: relative;
    transition: color var(--duration-fast);
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
}

.primary-nav a:hover,
.primary-nav a:focus-visible,
.primary-nav > .nav-group > button:hover {
    color: var(--ink);
}

/* Nav underline animation */
.primary-nav a::after,
.primary-nav > .nav-group > button::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0.875rem;
    right: 0.875rem;
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--duration-base) var(--ease-out);
}

.primary-nav a:hover::after,
.primary-nav a:focus-visible::after,
.primary-nav > .nav-group > button:hover::after,
.primary-nav a[aria-current="page"]::after {
    transform: scaleX(1);
}

.primary-nav a[aria-current="page"] {
    color: var(--ink);
}

.primary-nav a.active {
    color: var(--ink);
}

.primary-nav a.active::after {
    transform: scaleX(1);
}

/* Mega-menu dropdown */
.nav-group {
    position: relative;
}

.mega-menu {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%) translateY(8px);
    min-width: 480px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xl);
    padding: 1.5rem;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--duration-base) var(--ease-out),
                transform var(--duration-base) var(--ease-out),
                visibility var(--duration-base);
    z-index: 100;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.nav-group:hover .mega-menu,
.nav-group:focus-within .mega-menu,
.nav-group.is-active .mega-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
}

/*
 * Link layout belongs to the concrete §21 menu components below. A generic
 * `.mega-menu a` rule used to outrank those single-class component rules,
 * turning the feature card into a flex column and keeping it visible on
 * mobile. Keep this legacy shell free of descendant-link declarations.
 */

.mega-menu-image {
    grid-column: 2;
    grid-row: 1 / -1;
    border-radius: var(--radius-md);
    overflow: hidden;
}

.mega-menu-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Header CTA */
.header-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.625rem 1.25rem;
    background: var(--accent-dark);   /* white on accent must use accent-dark: 7.04:1 vs 4.64:1 */
    color: var(--ink-inverse);
    font-size: var(--text-sm);
    font-weight: 700;
    text-decoration: none;
    border-radius: 0;
    transition: background var(--duration-fast), border-color var(--duration-fast);
    white-space: nowrap;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
}

/* §21 restates this hover with the ink swap, but only for the properties it
   names. The lift had to be removed *here* — a `transform` left behind in §6 is
   not overridden by a §21 rule that never mentions transform. */
.header-cta:hover {
    background: var(--ink);
}

/* Header actions container */
.header-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* The English home banner owns the page's only logo image. When its redundant
   compact header brand is omitted, keep the remaining actions at the trailing
   edge instead of letting the mobile flex row pull the menu to the left. */
body[data-page="home"] .site-header .header-actions {
    margin-left: auto;
}

/* Mobile menu toggle */
.menu-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: transparent;
    cursor: pointer;
    transition: background var(--duration-fast), border-color var(--duration-fast);
}

.menu-toggle:hover {
    background: var(--surface-warm);
    border-color: var(--ink-muted);
}

.menu-toggle .menu-text {
    position: absolute;
    width: 1px;
    height: 1px;
    clip: rect(0, 0, 0, 0);
    overflow: hidden;
}

.menu-icon {
    display: flex;
    flex-direction: column;
    gap: 5px;
    width: 18px;
}

.menu-icon span {
    display: block;
    height: 2px;
    background: var(--ink);
    border-radius: 1px;
    transition: transform var(--duration-base) var(--ease-out),
                opacity var(--duration-fast);
}

.menu-toggle[aria-expanded="true"] .menu-icon span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
}

.menu-toggle[aria-expanded="true"] .menu-icon span:nth-child(2) {
    opacity: 0;
}

.menu-toggle[aria-expanded="true"] .menu-icon span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
}

@media (min-width: 1024px) {
    .menu-toggle {
        display: none;
    }
}

/* Mobile nav overlay */
.mobile-nav {
    position: fixed;
    inset: 0;
    z-index: 999;
    background: var(--surface);
    padding: calc(var(--header-height) + 1rem) var(--gutter) 2rem;
    overflow-y: auto;
    display: none;
    flex-direction: column;
    gap: 0.25rem;
}

.mobile-nav.is-open {
    display: flex;
}

.mobile-nav a {
    display: flex;
    align-items: center;
    padding: 1rem 0;
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--ink);
    text-decoration: none;
    border-bottom: 1px solid var(--border-light);
    transition: color var(--duration-fast);
}

.mobile-nav a:hover {
    color: var(--accent);
}

.mobile-nav .mobile-nav-group-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 0;
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--ink);
    border-bottom: 1px solid var(--border-light);
    cursor: pointer;
    background: none;
    border-left: none;
    border-right: none;
    border-top: none;
    width: 100%;
    font-family: inherit;
}

.mobile-nav .mobile-nav-children {
    display: none;
    padding-left: 1rem;
}

.mobile-nav .mobile-nav-children.is-open {
    display: block;
}

.mobile-nav .mobile-nav-children a {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--ink-secondary);
    padding: 0.75rem 0;
}

/* Old class compat: .site-nav used by laad_render_primary_navigation() */
.site-nav {
    display: none;
}

@media (min-width: 1024px) {
    .site-nav {
        display: flex;
        align-items: center;
        gap: 0;
    }
}

/*
 * The current navigation has four distinct link primitives: .nav-home,
 * .mega-menu-overview, .mega-menu-column > a and .mega-menu-feature. Their
 * complete styles live in §21. The former generic `.site-nav a` declarations
 * had higher specificity and silently overrode those component contracts.
 */

/* Dropdown menu from existing nav */
.site-nav .nav-item {
    position: relative;
}

.site-nav .nav-item.has-dropdown {
    padding-bottom: 12px;
    margin-bottom: -12px;
}

.site-nav .dropdown-menu {
    position: absolute;
    top: calc(100% - 4px);
    left: 50%;
    transform: translateX(-50%) translateY(8px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xl);
    padding: 0.5rem;
    min-width: 240px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--duration-base) var(--ease-out),
                transform var(--duration-base) var(--ease-out),
                visibility var(--duration-base);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.site-nav .nav-item:hover .dropdown-menu,
.site-nav .nav-item:focus-within .dropdown-menu,
.site-nav .nav-item.is-active .dropdown-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
}

.site-nav .dropdown-menu a {
    width: 100%;
    height: auto;
    min-height: 42px;
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
    text-align: left;
    justify-content: flex-start;
    padding: 0.625rem 0.875rem;
    font-size: var(--text-sm);
    text-transform: none;
    letter-spacing: normal;
    font-weight: 500;
    white-space: normal;
}

.site-nav .dropdown-menu a:hover,
.site-nav .dropdown-menu a:focus-visible {
    background: var(--accent-subtle);
    color: var(--accent-dark);
}

.site-nav .dropdown-menu a::after {
    display: none;
}

/* Active states for programme sub-pages */
body[data-page="sections"] .site-nav .nav-item > a[data-page*="sections"],
body[data-page="interior"] .site-nav .nav-item > a[data-page*="sections"],
body[data-page="fashion"] .site-nav .nav-item > a[data-page*="sections"],
body[data-page="painting"] .site-nav .nav-item > a[data-page*="sections"],
body[data-page="foundation"] .site-nav .nav-item > a[data-page*="sections"],
body[data-page="portfolio"] .site-nav .nav-item > a[data-page*="sections"],
body[data-page="hobby"] .site-nav .nav-item > a[data-page*="sections"] {
    color: var(--ink);
}

body[data-page="sections"] .site-nav .nav-item > a[data-page*="sections"]::after,
body[data-page="interior"] .site-nav .nav-item > a[data-page*="sections"]::after,
body[data-page="fashion"] .site-nav .nav-item > a[data-page*="sections"]::after,
body[data-page="painting"] .site-nav .nav-item > a[data-page*="sections"]::after,
body[data-page="foundation"] .site-nav .nav-item > a[data-page*="sections"]::after,
body[data-page="portfolio"] .site-nav .nav-item > a[data-page*="sections"]::after,
body[data-page="hobby"] .site-nav .nav-item > a[data-page*="sections"]::after {
    transform: scaleX(1);
}

body[data-page="interior"] .site-nav .dropdown-menu a[data-page*="interior"],
body[data-page="fashion"] .site-nav .dropdown-menu a[data-page*="fashion"],
body[data-page="painting"] .site-nav .dropdown-menu a[data-page*="painting"],
body[data-page="foundation"] .site-nav .dropdown-menu a[data-page*="foundation"],
body[data-page="portfolio"] .site-nav .dropdown-menu a[data-page*="portfolio"],
body[data-page="hobby"] .site-nav .dropdown-menu a[data-page*="hobby"] {
    background: var(--accent-subtle);
    color: var(--accent-dark);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   7. HERO SECTION
   -------------------------------------------------------------------------- */
.hero {
    position: relative;
    overflow: hidden;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.hero .container {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
    padding-block: var(--section-gap);
    align-items: center;
}

@media (min-width: 768px) {
    .hero .container {
        grid-template-columns: 1.15fr 0.85fr;
        gap: 3rem;
    }
}

.hero-copy {
    position: relative;
    z-index: 1;
}

/* The display spec, taken from The New School's type rules and applied to every
   hero H1: ALL CAPS, flush left, tracking at ~0, leading under 1.0, and no
   hyphenation. The tracking matters most — at this size a -0.03em pull was
   drawn for mixed case and closes uppercase counters up until the word reads as
   a block. -0.01em is the whole permitted range at caps.

   `hyphens: none` is explicit rather than assumed: a broken display word is the
   one thing this system must never show, and the browser default varies by
   language attribute. */
.hero-copy h1,
.hero-copy h2 {
    margin: 0;
    font-size: var(--text-5xl);
    font-weight: 800;
    line-height: 0.98;
    letter-spacing: -0.01em;
    text-transform: uppercase;
    text-align: left;
    hyphens: none;
    /* The escape valve `hyphens: none` removes. It fires only when a single
       word genuinely cannot fit its box, so ordinary rendering never sees it —
       but without it a long cap-set word overflows its own box and forces the
       whole page to scroll sideways. See §9 for the measurements. */
    overflow-wrap: break-word;
    color: var(--ink);
}

/* The home hero H1 is sized in §21, which redeclares this same selector later
   in the file and therefore wins. Do not add a competing rule here. */

.hero-sub {
    margin-top: 0.75rem;
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent);
}

.hero-copy p {
    margin-top: 1.25rem;
    font-size: var(--text-md);
    color: var(--ink-secondary);
    max-width: 48ch;
    line-height: var(--leading-relaxed);
}

.hero-cta {
    margin-top: 2rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* Square media, hard border. The 16px-radius frame was the last soft object in
   the hero and it read as a photo widget rather than as a plate. */
.hero-media {
    margin: 0;
    border: 1px solid var(--ink);
    border-radius: 0;
    overflow: hidden;
    position: relative;
    aspect-ratio: 4 / 5;
}

/* A page with no hero photograph still renders the figure wrapper; collapse it
   rather than leaving an empty framed box beside the copy. */
.hero-media:not(:has(img)) {
    display: none;
}

@media (min-width: 768px) {
    .hero-media {
        aspect-ratio: 3 / 4;
    }
}

.hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hero-media figcaption {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0.5rem 0.75rem;
    /* The caption sits on an arbitrary photo, so the scrim must guarantee
       contrast on its own. A transparent-to-0.5 ramp left white text at 1.0:1
       over the light parts of some images; a 0.6 floor holds >=5.7:1 even over
       pure white. */
    background: linear-gradient(to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.6));
    color: var(--ink-inverse);
    font-size: var(--text-xs);
}

/* Homepage hero — left column houses copy + image, right houses cards */
.hero-home {
    background: var(--surface);
}

.hero-home .container {
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .hero-home .container {
        grid-template-columns: 1.15fr 0.85fr;
    }
}

.hero-left {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    position: relative;
    z-index: 1;
}

.hero-home .hero-media {
    aspect-ratio: 16 / 10;
    min-height: 280px;
    border-radius: var(--radius-xl);
}

.hero-right {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    position: relative;
    z-index: 1;
}

/* --------------------------------------------------------------------------
   8. BUTTONS
   -------------------------------------------------------------------------- */
/* Rectangles, not pills. The pill was the single most "template" object on the
   site — it read as a web app's affordance, and at 999px radius it fought the
   flush-left typography everywhere it sat.

   The hover rule changed with it: hover is now a COLOUR SWAP, never a lift.
   `translateY(-2px)` plus a shadow made every button restate the same generic
   micro-interaction; swapping the fill to ink is louder, costs nothing to paint,
   and survives `prefers-reduced-motion` without a special case. */
.cta-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.875rem 1.75rem;
    border-radius: 0;
    text-decoration: none;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--text-sm);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    transition: background var(--duration-fast),
                color var(--duration-fast),
                border-color var(--duration-fast);
    cursor: pointer;
    border: 2px solid transparent;
    min-height: 44px;
    min-width: 44px;
}

/* Primary: accent fill -> ink fill. White on --accent is 4.64:1 (AA for the
   14px/700 label, which is large text at this weight); white on --ink is
   15.9:1. Both directions clear AA, so the swap is safe in either state. */
.cta-button.primary {
    background: var(--accent);
    color: var(--ink-inverse);
    border-color: var(--accent);
}

.cta-button.primary:hover,
.cta-button.primary:focus-visible {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--ink-inverse);
}

/* Secondary: 2px ink outline -> filled ink. The outline weight matches the
   primary's border so the two sit on one baseline of stroke. */
.cta-button.secondary {
    background: transparent;
    color: var(--ink);
    border-color: var(--ink);
}

.cta-button.secondary:hover,
.cta-button.secondary:focus-visible {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--ink-inverse);
}

/* --------------------------------------------------------------------------
   9. SECTIONS
   -------------------------------------------------------------------------- */
.section {
    padding-block: var(--section-gap);
    border-bottom: 1px solid var(--border-light);
}

.section:last-of-type {
    border-bottom: none;
}

/* Full-bleed wrapper for uneditable post_content sections */
.section:not(:has(> .container)),
.hero:not(:has(> .container)) {
    display: grid;
    grid-template-columns: 
        minmax(var(--gutter), 1fr) 
        min(var(--max-width), 100% - (var(--gutter) * 2)) 
        minmax(var(--gutter), 1fr);
}

.section:not(:has(> .container)) > *,
.hero:not(:has(> .container)) > * {
    grid-column: 2;
}

/* Layout for post_content hero (no container) */
.hero:not(:has(> .container)) {
    padding-block: var(--section-gap);
    gap: 2rem;
}

@media (min-width: 768px) {
    .hero:not(:has(> .container)) {
        grid-template-columns: 
            minmax(var(--gutter), 1fr)
            min(calc(var(--max-width) * 0.55 - 1.5rem), calc(50% - var(--gutter) - 1.5rem))
            min(calc(var(--max-width) * 0.45 - 1.5rem), calc(50% - var(--gutter) - 1.5rem))
            minmax(var(--gutter), 1fr);
        gap: 0 3rem;
        align-items: center;
    }
    
    .hero:not(:has(> .container)) > .hero-copy { grid-column: 2; }
    .hero:not(:has(> .container)) > .hero-cta { grid-column: 2; margin-top: 1.5rem; }
    .hero:not(:has(> .container)) > .hero-media { grid-column: 3; grid-row: 1 / span 2; }
}

.kicker {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    font-size: var(--text-xs);
    font-weight: 700;
    font-family: var(--font-display);
}

/* The bars device, small form. Two stacked rules — heavy over hairline — instead
   of the single 24x2px dash. Same idea as the footer lid and the mega-menu lid,
   at kicker scale, so the ornament reads as one system rather than three
   unrelated accent marks. Drawn with a border pair on a fixed-height box so it
   stays crisp at any zoom. */
.kicker::before {
    content: '';
    display: inline-block;
    width: 28px;
    height: calc(var(--rule-heavy) + var(--rule-gap) + var(--rule-hairline));
    border-top: var(--rule-heavy) solid var(--accent);
    border-bottom: var(--rule-hairline) solid var(--accent);
    border-radius: 0;
    /* The rules are drawn as borders, so the box's own content area is the gap.
       Nothing paints there. */
    box-sizing: border-box;
}

/* --- The two-scale rule ---------------------------------------------------
   Weight carries information density; size carries editorial voice. Dense
   sections are small and heavy; gallery and closing sections are huge and
   light. Before this, every section h2 was 40px/700 and every h3 24px/700 on
   every page, which is what made the pages read flat regardless of their role.

   Dense is the default and editorial is opt-in, deliberately: the body prose of
   all 17 pages lives in wp_posts.post_content, so a rule that needed a class on
   each section would mean rewriting 17 rows of the database to change type. The
   nine pages carrying a .photo-grid pick up the editorial scale from their own
   structure, and .section--editorial is there for the template-rendered
   modules. No post_content is touched by any of this. */

.section h2 {
    margin: 0.5rem 0 1rem;
    font-size: var(--text-2xl);
    font-weight: 800;
    line-height: var(--leading-snug);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    max-width: 30ch;
}

/* Editorial H2s take the same display spec as the hero H1s: caps, flush left,
   tracking at the caps range, leading under 1.0, no hyphenation. They were the
   one place left where a 88px display line ran sentence-case, which read as a
   magazine pull-quote rather than as part of this system.

   Weight stays 400. The size carries the voice here; adding weight as well
   would collapse the distinction with the dense 32px/800 default and lose the
   two-scale rule this section exists to express. */
.section--editorial > h2,
.section:has(> .photo-grid) > h2 {
    font-size: var(--text-6xl);
    font-weight: 400;
    line-height: var(--leading-display);
    letter-spacing: -0.01em;
    text-transform: uppercase;
    text-align: left;
    hyphens: none;
    /* WCAG 2.1 1.4.10 Reflow, measured 2026-07-29 at 320x844.
       Four routes scrolled sideways and no bounding-rect check could see it,
       because inline content overflows its box without widening it — only
       scrollWidth vs clientWidth exposes it. In every case the offender was
       this rule: at 320px --text-4xl floors at 40px, leaving a 288px content
       box that one long cap-set word cannot fit.

         /interior-design/        "INTERNATIONAL-STANDARD ... READINESS"  +69px
         /certificate-programs/                                          +48px
         /portfolio-preparation/  "RECOMMENDED TIMELINE: 9-12 MONTHS"     +47px
         /about/                  "ACADEMIC AND PROFESSIONAL ADVANCEMENT" +35px

       The fix is one rule here rather than four page-level patches: a valve for
       the extreme case, plus a smaller step below 480px so the valve almost
       never has to fire. `hyphens: none` stays — a broken display word is still
       the thing this system avoids; it is simply no longer allowed to break the
       page instead. */
    overflow-wrap: break-word;
    color: var(--accent);
    max-width: 18ch;
    margin-block: 0.25rem 1.5rem;
}

/* The matching size step lives in the existing @media (max-width: 479px) block
   near the end of this file, NOT here. A copy here would be dead code: the
   768px override of this same selector appears later in source order at equal
   specificity and would win at every width it matches. */

.section h3 {
    margin: 0.25rem 0 0.5rem;
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: var(--leading-snug);
}

.section p {
    margin-block: 0.5em;
    font-size: var(--text-base);
    color: var(--ink-secondary);
    max-width: 65ch;
}

.section strong {
    color: var(--ink);
}

.section ul,
.section ol {
    margin: 0.5rem 0;
    padding-left: 1.25rem;
    font-size: var(--text-base);
    color: var(--ink-secondary);
    display: grid;
    gap: 0.375rem;
}

.section .list-tight {
    gap: 0.2rem;
}

/* --- Inverse surfaces ------------------------------------------------------
   One near-black section per long page, to break the unbroken warm white. Text
   colours are restated rather than inherited because --ink-secondary and
   --ink-muted are tuned for light surfaces and disappear here. The focus ring
   is swapped for the same reason: the magenta ring at 0.4 alpha is invisible
   against both of these backgrounds, which would be a 2.4.7 failure that no
   automated colour check catches, because it only shows up under keyboard
   focus. */

.section--dark {
    background: var(--surface-dark);
    border-bottom: none;
    color: var(--ink-inverse);
}

.section--dark h2,
.section--dark h3,
.section--dark strong {
    color: var(--ink-inverse);
}

/* #c9c9c9 on #1a1a1a is 9.7:1; #b0b0b0 is 6.9:1. Both clear AA with room. */
.section--dark p,
.section--dark li {
    color: #c9c9c9;
}

.section--dark .kicker,
.section--dark .kicker::before {
    color: #e2a8d1;
    background-color: currentColor;
}

.section--dark .kicker {
    background-color: transparent;
}

.section--dark a:focus-visible,
.section--dark button:focus-visible,
.cta-block a:focus-visible,
.cta-block button:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-inverse);
}

/* Features section - a darker contrast section */
.features-section {
    background: var(--surface);
}

.features-section .container {
    max-width: var(--max-width);
}

/* --------------------------------------------------------------------------
   10. CARDS
   -------------------------------------------------------------------------- */

/* Hero cards (programme teasers on homepage) */
.hero-card {
    flex: 1 1 0;
    background: var(--surface);
    /* 1px ink border, not --border grey. The card is now defined by its rule
       rather than by a shadow, so the rule has to be visible enough to do that
       job on its own. */
    border: 1px solid var(--ink);
    border-radius: 0;
    padding: 1.25rem;
    color: var(--ink);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    transition: border-color var(--duration-base) var(--ease-out),
                background var(--duration-base) var(--ease-out);
}

/* Colour swap, no lift, no shadow — see the note on .cta-button in §8. */
.hero-card:hover {
    border-color: var(--accent);
    background: var(--accent-subtle);
}

.hero-card h2,
.hero-card h3 {
    margin: 0;
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--ink);
    line-height: var(--leading-snug);
}

.hero-card p {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--ink-secondary);
    line-height: var(--leading-normal);
}

.hero-card .card-link {
    margin-top: auto;
    padding-top: 0.5rem;
    color: var(--accent);
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    transition: gap var(--duration-fast), color var(--duration-fast);
}

.hero-card .card-link:hover {
    color: var(--accent-dark);
    gap: 0.5rem;
}

.hero-card-image {
    margin: 0.25rem 0;
    border-radius: 0;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    background: var(--surface-warm);
}

.hero-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s var(--ease-out);
}

.hero-card:hover .hero-card-image img {
    transform: scale(1.03);
}

/* General cards */
.card-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.card {
    background: var(--surface);
    border: 1px solid var(--ink);
    border-radius: 0;
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    height: 100%;
    transition: border-color var(--duration-base) var(--ease-out),
                background var(--duration-base) var(--ease-out);
    color: var(--ink);
}

.card:hover {
    border-color: var(--accent);
    background: var(--accent-subtle);
}

.card:focus-within {
    box-shadow: var(--focus-ring-offset), var(--focus-ring);
}

.card-grid .card h3 {
    margin: 0 0 0.5rem;
    font-size: var(--text-lg);
    color: var(--ink);
}

.card-grid .card p {
    margin: 0;
    flex-grow: 1;
    color: var(--ink-secondary);
    font-size: var(--text-sm);
}

.card-grid .card ul {
    margin: 0.5rem 0 0;
    padding-left: 1.125rem;
    color: var(--ink-secondary);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    display: grid;
    gap: 0.25rem;
    flex-grow: 1;
}

.card-grid .card-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 1rem;
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--text-sm);
    transition: gap var(--duration-fast), color var(--duration-fast);
}

.card-grid .card-link:hover,
.card-grid .card-link:focus-visible {
    gap: 0.5rem;
    color: var(--accent-dark);
}

/* Feature grid ("The LAAD Difference") */
.feature-grid {
    display: grid;
    gap: 1.5rem;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    margin-top: 2rem;
}

.feature-item {
    background: var(--surface);
    border: 1px solid var(--ink);
    border-radius: 0;
    padding: 2rem 1.75rem;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    transition: border-color var(--duration-base) var(--ease-out),
                background var(--duration-base) var(--ease-out);
}

.feature-item:hover {
    border-color: var(--accent);
    background: var(--accent-subtle);
}

.feature-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    background: var(--accent-light);
    color: var(--accent);
    margin-bottom: 0.25rem;
}

.feature-item h3 {
    margin: 0;
    font-size: var(--text-lg);
    color: var(--ink);
}

.feature-item p {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--ink-secondary);
    line-height: var(--leading-normal);
}

/* Quick links grid */
.link-grid {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.quick-link {
    text-decoration: none;
    border: 1px solid var(--ink);
    border-radius: 0;
    padding: 1.25rem;
    background: var(--surface);
    transition: border-color var(--duration-base) var(--ease-out),
                background var(--duration-base) var(--ease-out);
}

.quick-link:hover,
.quick-link:focus-visible {
    border-color: var(--accent);
    background: var(--accent-subtle);
}

.quick-link strong {
    display: block;
    font-size: var(--text-sm);
    font-weight: 700;
    color: var(--ink);
}

.quick-link span {
    display: block;
    margin-top: 0.25rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* Split layout */
.split {
    display: grid;
    gap: 1.5rem;
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .split {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Photo grid */
.photo-grid {
    display: grid;
    gap: 1rem;
}

.photo-grid.grid-2 { grid-template-columns: repeat(2, 1fr); }
.photo-grid.grid-3 { grid-template-columns: repeat(3, 1fr); }
.photo-grid.grid-4 { grid-template-columns: repeat(4, 1fr); }

.photo-card {
    margin: 0;
    border: 1px solid var(--ink);
    border-radius: 0;
    overflow: hidden;
    background: var(--surface);
    transition: border-color var(--duration-slow) var(--ease-out);
}

.photo-card:hover {
    border-color: var(--accent);
}

.photo-card img {
    width: 100%;
    /* NOT height: 100%. That resolved against the card's definite height and beat
       the aspect-ratio, so the image ate the whole card and pushed the caption
       42px past the bottom edge — where `overflow: hidden` above deleted it. The
       caption text on every photo card on the site was invisible at both 390px
       and 1440px, in the DOM but never painted. Measured 2026-07-27. */
    height: auto;
    object-fit: cover;
    aspect-ratio: 4 / 3;
    transition: transform 0.6s var(--ease-out);
}

.photo-card:hover img {
    transform: scale(1.04);
}

.photo-card.tall img {
    aspect-ratio: 3 / 4;
}

.photo-card figcaption {
    padding: 0.625rem 0.875rem;
    border-top: 1px solid var(--border-light);
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* --------------------------------------------------------------------------
   10b. DESIGN-UPLIFT MODULES (2026-07-27)
   --------------------------------------------------------------------------
   Rendered by template parts from _laad_layout, never from post_content.
   -------------------------------------------------------------------------- */

/* --- Full-bleed image band ------------------------------------------------ */
/* Two classes, not one: §9's `.section:not(:has(> .container))` is (0,2,0)
   because :not()/:has() take the specificity of their argument, so a bare
   `.image-band` loses to it and the figure gets parked in the centre column at
   --max-width. This is the module that has to break the 1280px cage. */
.section.image-band {
    padding-block: 0;
    border-bottom: none;
    display: block;
}

/* Height is a clamp, not aspect-ratio + max-height: an element with both
   shrinks its WIDTH to honour the ratio at the clamped height (1440px viewport
   → 1120px-wide "full-bleed" band, measured). The img inside is object-fit:
   cover with explicit dimensions, so nothing here depends on the ratio. */
.image-band__figure {
    position: relative;
    margin: 0;
    height: clamp(320px, 40vw, 560px);
    overflow: hidden;
}

.image-band__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The caption sits on an arbitrary photograph, so the scrim has to guarantee
   contrast by itself rather than relying on the image being dark. 0.35 at the
   top was measured at 3.72:1 on the 12px kicker over a pale crop — the ramp now
   matches the .hero-media figcaption, whose 0.6 floor is already proven to hold
   white above 4.5:1 over pure white. This is exactly the case Lighthouse does
   not look at, so it is measured on rendered pixels by
   qa-scripts/contrast.mjs instead. */
.image-band__caption {
    position: absolute;
    inset: auto 0 0 0;
    display: grid;
    gap: 0.5rem;
    padding: clamp(1.5rem, 4vw, 3rem);
    background: linear-gradient(to top, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.62));
    color: var(--ink-inverse);
}

.image-band__kicker {
    font-family: var(--font-display);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
}

.image-band__line {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 700;
    line-height: var(--leading-snug);
    letter-spacing: var(--tracking-tight);
    max-width: 28ch;
}

/* --- Programme grid ------------------------------------------------------- */
.programme-section__intro {
    max-width: 60ch;
    font-size: var(--text-md);
}

.programme-grid {
    list-style: none;
    margin: 2.5rem 0 0;
    padding: 0;
    display: grid;
    gap: 1.5rem;
    grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 1024px) and (min-width: 769px) {
    .programme-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

.programme-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--surface);
    border: 1px solid var(--ink);
    border-radius: 0;
    overflow: hidden;
    text-decoration: none;
    color: var(--ink);
    transition: border-color var(--duration-base) var(--ease-out),
                background var(--duration-base) var(--ease-out);
}

.programme-card__media {
    display: block;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: var(--surface-tinted);
}

.programme-card__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--duration-slow) var(--ease-out);
}

/* Ballet Training has no photography. Rather than an empty grey frame, the slot
   becomes a typographic panel — deliberate while the gap lasts, and a drop-in
   slot the moment the owner supplies a photograph. */
.programme-card--no-photo .programme-card__media {
    display: grid;
    place-items: center;
    background: var(--accent-light);
}

.programme-card__index {
    font-family: var(--font-display);
    font-size: var(--text-5xl);
    font-weight: 800;
    line-height: 1;
    color: var(--accent);
    opacity: 0.55;
}

.programme-card__body {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding: 1.5rem 1.5rem 1.75rem;
    flex: 1 1 auto;
}

.programme-card__kicker {
    font-family: var(--font-display);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--accent-dark);
}

.programme-card__title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    line-height: var(--leading-snug);
    letter-spacing: var(--tracking-tight);
}

.programme-card__meta {
    margin-top: auto;
    padding-top: 0.75rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* Whole card is the hit area and the focus target — one tab stop per
   programme, and every hover state has a keyboard equivalent. The image scale
   is capped at 1.03: anything more and the crop visibly shifts. */
.programme-card:hover,
.programme-card:focus-visible {
    border-color: var(--accent);
    background: var(--accent-subtle);
}

.programme-card:hover .programme-card__img,
.programme-card:focus-visible .programme-card__img {
    transform: scale(1.03);
}

.programme-card:hover .programme-card__title,
.programme-card:focus-visible .programme-card__title {
    color: var(--accent-dark);
}

/* The ring stands alone. It used to be `var(--focus-ring), var(--shadow-lg)`;
   with --shadow-lg now resolving to `none` that list would be invalid at
   computed-value time and the whole declaration — the focus ring included —
   would be dropped. A keyboard user would lose the card outline entirely. */
.programme-card:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* The card itself no longer moves in any state — hover is a colour swap — so the
   only motion left to suppress is the image scale. */
@media (prefers-reduced-motion: reduce) {
    .programme-card,
    .programme-card__img {
        transition: none;
    }

    .programme-card:hover .programme-card__img,
    .programme-card:focus-visible .programme-card__img {
        transform: none;
    }
}

/* --- Stat row ------------------------------------------------------------- */
.stat-row__grid {
    display: grid;
    gap: clamp(2rem, 5vw, 4rem);
    grid-template-columns: 1.35fr 1fr;
    align-items: center;
}

.stat-row__media {
    margin: 0;
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.stat-row__img {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
}

.stat-list {
    display: grid;
    gap: 1.75rem;
    margin-top: 2.5rem;
    grid-template-columns: repeat(3, auto);
    justify-content: start;
}

.stat-list__item {
    padding-right: 2rem;
    border-right: 1px solid rgba(255, 255, 255, 0.18);
}

.stat-list__item:last-child {
    border-right: none;
    padding-right: 0;
}

.stat-list__value {
    font-family: var(--font-display);
    font-size: var(--text-4xl);
    font-weight: 800;
    line-height: 1;
    letter-spacing: var(--tracking-display);
    color: var(--ink-inverse);
}

.stat-list__label {
    margin: 0.625rem 0 0;
    max-width: 22ch;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    color: #c9c9c9;
}

/* --- Curriculum tables ---------------------------------------------------- */
/* The week-by-week syllabus is tabular data — week, subject, materials, process
   — and was previously flattened into a <ul>, which threw the materials column
   away entirely. The wrapper scrolls rather than the page: at 390px the body
   must never scroll sideways, and it never has. */
.table-scroll {
    overflow-x: auto;
    margin: 1rem 0 1.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    -webkit-overflow-scrolling: touch;
}

/* A scroll container must be reachable by keyboard (WCAG 2.1.1). The template
   sets tabindex="0"; this makes the focus visible when it lands. */
.table-scroll:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-color: var(--accent);
}

.curriculum-table {
    width: 100%;
    min-width: 40rem;
    border-collapse: collapse;
    font-size: var(--text-sm);
    text-align: left;
}

.curriculum-table th,
.curriculum-table td {
    padding: 0.75rem 1rem;
    vertical-align: top;
    border-bottom: 1px solid var(--border-light);
}

.curriculum-table thead th {
    position: sticky;
    top: 0;
    background: var(--surface-tinted);
    font-family: var(--font-display);
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--ink);
    border-bottom: 1px solid var(--border);
}

.curriculum-table tbody th[scope="row"] {
    white-space: nowrap;
    font-weight: 700;
    color: var(--ink);
    width: 1%;
}

.curriculum-table td {
    color: var(--ink-secondary);
}

/* Subject column carries the week's title; keep it readable as the anchor. */
.curriculum-table td:first-of-type {
    color: var(--ink);
    font-weight: 600;
    min-width: 12rem;
}

.curriculum-table tbody tr:last-child th,
.curriculum-table tbody tr:last-child td {
    border-bottom: none;
}

.curriculum-table tbody tr:nth-child(even) th,
.curriculum-table tbody tr:nth-child(even) td {
    background: var(--surface-warm);
}

/* --------------------------------------------------------------------------
   11. DETAILS / ACCORDION
   -------------------------------------------------------------------------- */
.details-box {
    margin: 1.25rem 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    overflow: hidden;
}

.details-box summary {
    padding: 1rem 1.25rem;
    font-weight: 600;
    font-size: var(--text-base);
    cursor: pointer;
    list-style: none;
    color: var(--ink);
    transition: background var(--duration-fast);
    position: relative;
    padding-right: 3rem;
}

.details-box summary::-webkit-details-marker {
    display: none;
}

.details-box summary:hover {
    background: var(--accent-subtle);
}

.details-box summary::after {
    content: '+';
    position: absolute;
    right: 1.25rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.25rem;
    font-weight: 300;
    color: var(--ink-muted);
    transition: transform var(--duration-base) var(--ease-out);
}

.details-box[open] summary::after {
    transform: translateY(-50%) rotate(45deg);
}

.details-body {
    padding: 1.25rem;
    border-top: 1px solid var(--border);
}

.details-body h3 {
    margin-top: 0;
    font-size: var(--text-lg);
    color: var(--accent);
}

.details-body h3:not(:first-child) {
    margin-top: 1rem;
}

.details-body ul {
    margin-bottom: 1rem;
}

.details-body ul:last-child {
    margin-bottom: 0;
}

/* Note block */
.note {
    border: 1px solid var(--border-accent);
    border-radius: var(--radius-lg);
    background: var(--accent-light);
    padding: 1rem 1.25rem;
    margin-top: 1rem;
}

/* --------------------------------------------------------------------------
   12. FOOTER
   -------------------------------------------------------------------------- */
.page-footer {
    background: var(--surface-dark);
    color: var(--ink-inverse);
    padding: var(--section-gap) 0 2rem;
    margin-top: var(--section-gap);
}

.page-footer .container {
    max-width: var(--max-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.footer-top {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2.5rem;
    padding-bottom: 2.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

@media (min-width: 768px) {
    .footer-top {
        grid-template-columns: 1.5fr 1fr 1fr 1fr;
        gap: 2rem;
    }
}

.footer-brand .footer-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 800;
    color: var(--ink-inverse);
    margin: 0 0 0.5rem;
}

.footer-brand p {
    font-size: var(--text-sm);
    color: rgba(255, 255, 255, 0.6);
    margin: 0;
    line-height: var(--leading-normal);
    max-width: 36ch;
}

.footer-col h4 {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: rgba(255, 255, 255, 0.4);
    margin: 0 0 1rem;
    font-weight: 600;
}

.footer-col a,
.footer-links a {
    display: block;
    color: rgba(255, 255, 255, 0.7);
    text-decoration: none;
    font-size: var(--text-sm);
    padding: 0.25rem 0;
    transition: color var(--duration-fast);
}

.footer-col a:hover,
.footer-links a:hover {
    color: var(--ink-inverse);
}

/* Backward compat: old footer classes */
.footer-content {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
    margin-bottom: 1.5rem;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

@media (min-width: 768px) {
    .footer-content {
        grid-template-columns: 2fr 1fr;
    }
}

.footer-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--text-lg);
    margin: 0 0 0.5rem;
    color: var(--ink-inverse);
}

.footer-info p {
    margin: 0;
    font-size: var(--text-sm);
    color: rgba(255, 255, 255, 0.6);
}

.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-content: flex-start;
}

.footer-bottom {
    padding-top: 1.5rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}

.footer-legal {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
}

.footer-legal a {
    font-size: var(--text-xs);
    color: rgba(255, 255, 255, 0.4);
    text-decoration: none;
    transition: color var(--duration-fast);
}

.footer-legal a:hover {
    color: rgba(255, 255, 255, 0.8);
}

.foot-line {
    margin-top: 0.5rem;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    font-size: var(--text-xs);
    color: rgba(255, 255, 255, 0.4);
}

.foot-contact {
    margin-top: 0.5rem;
    font-size: var(--text-sm);
    color: rgba(255, 255, 255, 0.6);
    line-height: var(--leading-normal);
}

.foot-contact a {
    color: var(--ink-inverse);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.foot-contact a:hover {
    text-decoration-thickness: 2px;
}

.copyright {
    margin-top: 0.75rem;
    font-size: var(--text-xs);
    color: rgba(255, 255, 255, 0.4);
}

/* Focus visible in footer */
.page-footer a:focus-visible,
.page-footer button:focus-visible {
    box-shadow: 0 0 0 2px var(--surface-dark), 0 0 0 4px rgba(255, 255, 255, 0.8);
    border-radius: var(--radius-sm);
}

/* Old skyline footer (commented out — preserved for rollback)
.page-footer::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    aspect-ratio: 1054 / 240;
    max-height: 78%;
    background: url('../images/ui/london_skyline.png') center bottom / 100% 100% no-repeat;
    opacity: var(--footer-skyline-opacity);
    pointer-events: none;
    z-index: -1;
}
*/

/* --------------------------------------------------------------------------
   13. BREADCRUMBS
   -------------------------------------------------------------------------- */
.breadcrumb {
    padding: 1rem 0;
    font-size: var(--text-sm);
}

.breadcrumb ol {
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin: 0;
    padding: 0;
    gap: 0.5rem;
    align-items: center;
}

.breadcrumb li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--ink-muted);
}

.breadcrumb li:not(:last-child)::after {
    content: '/';
    color: var(--border);
    font-weight: 400;
}

.breadcrumb a {
    color: var(--ink-secondary);
    text-decoration: none;
    font-weight: 500;
    transition: color var(--duration-fast);
}

.breadcrumb a:hover,
.breadcrumb a:focus-visible {
    color: var(--accent);
}

.breadcrumb li[aria-current="page"] {
    color: var(--ink);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   14. CONTACT FORM
   -------------------------------------------------------------------------- */
.contact-info address {
    font-style: normal;
    margin: 1rem 0;
}

.contact-info p {
    margin: 0.5rem 0;
}

.contact-info a {
    /* These links sit on --surface-warm, where --accent is only 4.38:1.
       --accent-dark gives 6.64:1. */
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 600;
}

.contact-info a:hover {
    text-decoration: underline;
}

.contact-hours {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
}

.contact-form {
    margin-top: 2rem;
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    margin-bottom: 1rem;
}

@media (min-width: 640px) {
    .form-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

.form-group {
    margin-bottom: 1rem;
}

.form-grid .form-group {
    margin-bottom: 0;
}

.form-group label {
    display: block;
    margin-bottom: 0.375rem;
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--ink);
}

.form-group label span[aria-label="required"] {
    /* Required markers render on --surface-warm; --accent is 4.38:1 there. */
    color: var(--accent-dark);
}

/* --radius-sm (3px), not 0: this is the one family of objects a caret lands in,
   and a hairline of softening is what distinguishes "type here" from the square
   structural blocks around it. The border goes to ink so the field edge is as
   definite as every other rule on the page. */
.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 0.75rem 1rem;
    border: 1px solid var(--ink);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-family: inherit;
    font-size: var(--text-base);
    color: var(--ink);
    transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(186, 74, 152, 0.12);
}

.form-group textarea {
    resize: vertical;
    min-height: 120px;
}

.form-group select {
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%234a4a4a' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    padding-right: 2.5rem;
}

.form-actions {
    margin-top: 1.5rem;
}

.form-note {
    margin-top: 1rem;
    color: var(--ink-muted);
    font-size: var(--text-sm);
}

.form-status {
    margin: 1rem 0 0;
    padding: 0.75rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
}

.form-status.is-success {
    border-color: rgba(36, 140, 86, 0.3);
    background: rgba(36, 140, 86, 0.06);
    color: #155f3f;
}

.form-status.is-info {
    border-color: var(--border-accent);
    background: var(--accent-subtle);
    color: var(--accent-dark);
}

/* --------------------------------------------------------------------------
   15. CTA BLOCK
   -------------------------------------------------------------------------- */
/* --- Closing accent CTA ----------------------------------------------------
   --accent-dark, not --accent: white on #ba4a98 is 4.64:1, which passes AA with
   no margin at all and fails the moment anything shifts. White on #962f7a is
   7.04:1 — AA, and AAA at large sizes.

   Two forms, because the twelve pages that already carry a .cta-block in their
   post_content do not agree on where it sits:

     - the five pages generated on 2026-07-27 give it a <section> of its own;
     - the seven older pages append it inside the curriculum section, next to
       the <details> and the notes.

   So the background CANNOT be hung on `.section:has(> .cta-block)`. Doing
   exactly that painted whole curriculum sections magenta on 2026-07-27 —
   160 contrast failures, black body text on #962f7a at 1.26:1. The :only-child
   test is what distinguishes the two, and the panel form keeps the accent
   without ever touching content that is not the CTA. */

/* Band form — the block is the whole section, so the section can go full-bleed. */
.section:has(> .cta-block:only-child) {
    background: var(--accent-dark);
    border-bottom: none;
    padding-block: clamp(3.5rem, 7vw, 5.5rem);
}

.section:has(> .cta-block:only-child) + .section {
    border-top: none;
}

.cta-block {
    margin-top: 0;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    text-align: center;
    /* Set on the block, not just on the children, so anything in post_content
       that does not match a selector here still lands white on the accent.
       /hobby-programmes/ carries an inline `color: var(--muted)` on its intro
       paragraph; --muted has not existed since the v2 redesign, so that
       declaration is invalid at computed-value time and the property falls back
       to the inherited colour — which was --ink, i.e. near-black on magenta at
       2.47:1. Inheriting white from here fixes it without an !important and
       without editing post_content on twelve pages. */
    color: var(--ink-inverse);
}

/* Panel form — the block is one of several children of a content section. */
.section > .cta-block:not(:only-child) {
    margin-top: 3.5rem;
    padding: clamp(2.5rem, 5vw, 3.5rem) clamp(1.5rem, 4vw, 3rem);
    background: var(--accent-dark);
    border-radius: var(--radius-lg);
}

/* The `color` on .cta-block above is set so children INHERIT white. That works
   for elements with no colour of their own, but not for <p>: the global
   `p { color: var(--ink-secondary) }` is an explicit declaration, and an
   explicit value always beats an inherited one no matter how specific the
   ancestor rule is. So a CTA body paragraph rendered #4a4a4a on #962f7a —
   1.26:1, the same ratio as the 2026-07-27 incident described above.

   It stayed invisible because no English page currently supplies a body for its
   contact block; the Turkish pages added on 2026-07-28 do, and the sweep caught
   it on all four at both viewports. White on --accent-dark is 7.04:1. */
.cta-block p {
    color: var(--ink-inverse);
}

.cta-block h3 {
    color: var(--ink-inverse);
    margin-bottom: 2rem;
    font-size: var(--text-4xl);
    font-weight: 800;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-display);
}

.cta-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.cta-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1.25rem;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: var(--radius-md);
    transition: background var(--duration-base) var(--ease-out),
                border-color var(--duration-base) var(--ease-out),
                transform var(--duration-fast);
    text-decoration: none;
    color: var(--ink-inverse);
}

.cta-item:hover,
.cta-item:focus-visible {
    background: rgba(0, 0, 0, 0.22);
    border-color: var(--ink-inverse);
}

.cta-item:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-inverse);
}

.cta-icon {
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
}

.cta-label {
    font-weight: 700;
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
}

/* #e6cfe0 on --accent-dark is 5.14:1 — a legible step down from white without
   dropping under AA for small text. Do not reach for an alpha here: a
   translucent foreground measures as whatever sits behind it. */
.cta-value {
    font-size: var(--text-sm);
    color: #e6cfe0;
    margin-top: 0.375rem;
}

/* Outlined white rectangle on the accent band — the "TAKE THE NEXT STEP" idiom.
   Both states clear AA comfortably: white on --accent-dark is 7.04:1 at rest,
   and --accent-dark on white is the same 7.04:1 when the fill inverts on hover.

   Markup note: this button lives inside twelve pages' post_content, so it can
   only ever be restyled from here — never by editing the pages. */
.cta-main-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    color: var(--ink-inverse);
    border: 2px solid var(--ink-inverse);
    padding: 1rem 2.5rem;
    border-radius: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--text-sm);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    transition: background var(--duration-fast), color var(--duration-fast);
}

.cta-main-button:hover,
.cta-main-button:focus-visible {
    background: var(--ink-inverse);
    color: var(--accent-dark);
}

.cta-main-button:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-inverse);
}

/* --------------------------------------------------------------------------
   16. REVEAL ANIMATIONS
   -------------------------------------------------------------------------- */

/* Default: visible (motion disabled) */
[data-reveal] {
    opacity: 1;
    transform: none;
}

/* Only animate when user hasn't requested reduced motion */
@media (prefers-reduced-motion: no-preference) {
    [data-reveal] {
        opacity: 0;
        transform: translateY(24px);
        transition: opacity var(--duration-reveal) var(--ease-out),
                    transform var(--duration-reveal) var(--ease-out);
    }

    [data-reveal].in-view {
        opacity: 1;
        transform: translateY(0);
    }

    /* Staggered children */
    [data-reveal].in-view .card,
    [data-reveal].in-view .quick-link,
    [data-reveal].in-view .photo-card,
    [data-reveal].in-view .feature-item,
    [data-reveal].in-view .hero-card {
        opacity: 0;
        transform: translateY(16px);
        animation: revealChild 0.5s var(--ease-out) forwards;
    }

    [data-reveal].in-view :nth-child(1) { animation-delay: 0ms; }
    [data-reveal].in-view :nth-child(2) { animation-delay: 80ms; }
    [data-reveal].in-view :nth-child(3) { animation-delay: 160ms; }
    [data-reveal].in-view :nth-child(4) { animation-delay: 240ms; }
    [data-reveal].in-view :nth-child(5) { animation-delay: 320ms; }
    [data-reveal].in-view :nth-child(6) { animation-delay: 400ms; }
    [data-reveal].in-view :nth-child(7) { animation-delay: 480ms; }

    @keyframes revealChild {
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    /* Accordion slide */
    @keyframes slideDown {
        from { opacity: 0; transform: translateY(-8px); }
        to { opacity: 1; transform: translateY(0); }
    }

    .details-body {
        animation: slideDown 0.3s var(--ease-out);
    }
}

/* --------------------------------------------------------------------------
   17. RESPONSIVE
   -------------------------------------------------------------------------- */

@media (max-width: 1023px) {
    .site-nav {
        display: none;
        flex-direction: column;
        align-items: stretch;
        padding: 1rem;
    }

    .site-nav.is-open {
        display: flex;
    }

    .site-nav .nav-item.has-dropdown {
        padding-bottom: 0;
        margin-bottom: 0;
    }

    .site-nav .dropdown-menu {
        position: static;
        transform: none;
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        box-shadow: none;
        border: none;
        background: var(--surface-warm);
        margin: 0;
        padding: 0;
        min-width: 0;
        display: none;
        border-radius: 0;
    }

    .site-nav .nav-item.is-active .dropdown-menu,
    .site-nav .nav-item:focus-within .dropdown-menu {
        display: flex;
    }

    .site-nav .dropdown-menu a {
        padding-left: 2rem;
        border-radius: 0;
    }

    .brand-text {
        display: none;
    }

    .brand-logo {
        height: 40px;
    }
}

@media (max-width: 767px) {
    .hero .container {
        grid-template-columns: 1fr;
        padding-block: 2rem;
    }

    .hero-home .container {
        grid-template-columns: 1fr;
    }

    .hero-copy h1,
    .hero-copy h2 {
        font-size: var(--text-4xl);
    }

    .cta-button {
        width: 100%;
    }

    .hero-media {
        aspect-ratio: 4 / 3;
    }

    .card-grid {
        grid-template-columns: 1fr;
    }

    .feature-grid {
        grid-template-columns: 1fr;
    }

    .link-grid {
        grid-template-columns: 1fr;
    }

    .split {
        grid-template-columns: 1fr;
    }

    .photo-grid.grid-2,
    .photo-grid.grid-3,
    .photo-grid.grid-4 {
        grid-template-columns: 1fr;
    }

    /* Design-uplift modules at <=768px */
    .programme-grid {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    .stat-row__grid {
        grid-template-columns: 1fr;
    }

    .stat-list {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }

    .stat-list__item {
        padding-right: 0;
        padding-bottom: 1.5rem;
        border-right: none;
        border-bottom: 1px solid rgba(255, 255, 255, 0.18);
    }

    .stat-list__item:last-child {
        padding-bottom: 0;
        border-bottom: none;
    }

    .image-band__figure {
        height: clamp(260px, 60vw, 400px);
    }

    .image-band__line {
        font-size: var(--text-xl);
    }

    /* 88px display type does not belong on a 390px screen; the editorial
       heading steps down but keeps its weight and colour so the dense/editorial
       distinction survives the breakpoint. */
    .section--editorial > h2,
    .section:has(> .photo-grid) > h2 {
        font-size: var(--text-4xl);
        max-width: 100%;
    }

    .photo-card img,
    .photo-card.tall img {
        aspect-ratio: 16 / 10;
    }

    .footer-top {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 479px) {
    :root {
        --gutter: 1rem;
    }

    .hero-copy h1,
    .hero-copy h2 {
        font-size: var(--text-3xl);
    }

    /* §9's reflow step. It must live here, after the 768px override of the same
       selector, or source order makes it dead code.
       28px at 320, 31px at 390, 38px at 479 — enough for the longest real
       heading to wrap normally instead of tripping the break-word valve. */
    .section--editorial > h2,
    .section:has(> .photo-grid) > h2 {
        font-size: clamp(1.75rem, 8vw, 2.5rem);
    }

    .brand-logo {
        height: 36px;
    }
}

/* --------------------------------------------------------------------------
   18. HIGH CONTRAST MODE
   -------------------------------------------------------------------------- */
@media (prefers-contrast: high) {
    :root {
        --ink: #000000;
        --ink-secondary: #000000;
        --surface: #ffffff;
        --surface-warm: #ffffff;
        --border: #000000;
        --accent: #800080;
    }

    .hero,
    .section,
    .card,
    .hero-card,
    .feature-item,
    .details-box {
        border-width: 2px;
    }

    .page-footer {
        background: #000000;
        color: #ffffff;
    }

    .page-footer a,
    .footer-title,
    .footer-info p,
    .footer-links a,
    .foot-line,
    .foot-contact,
    .foot-contact a,
    .copyright {
        color: #ffffff !important;
    }
}

/* --------------------------------------------------------------------------
   19. PRINT
   -------------------------------------------------------------------------- */
@media print {
    .site-header,
    .utility-bar,
    .hero-cta,
    .card-link,
    .cta-button,
    .cta-block,
    .menu-toggle,
    .mobile-nav {
        display: none !important;
    }

    body {
        background: white !important;
        color: black !important;
        font-size: 12pt;
    }

    .hero,
    .section,
    .card,
    .page-footer {
        background: white !important;
        color: black !important;
        box-shadow: none !important;
        border: 1px solid #ccc;
    }

    .page-footer a,
    .footer-title,
    .footer-info p,
    .copyright {
        color: black !important;
    }

    .section {
        break-inside: avoid;
    }
}

/* --------------------------------------------------------------------------
   20. LEGACY COMPATIBILITY
   --------------------------------------------------------------------------
   Classes used in post_content that must continue to work.
   These map old class names to the new design system.
   -------------------------------------------------------------------------- */

/* The old .site-shell wrapper is being removed from templates,
   but post_content might still emit it. Make it transparent. */
.site-shell {
    width: 100%;
    max-width: var(--max-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

/* Old top-announcement bar — hidden in redesign */
.top-announcement {
    display: none;
}

/* Old header-panel — transparent fallback */
.header-panel {
    border: none;
    box-shadow: none;
    background: transparent;
    border-radius: 0;
    overflow: visible;
}

/* Old header brand classes */
.top-band {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.875rem var(--gutter);
}

.brand-wrap {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    text-decoration: none;
    color: inherit;
}

.brand-emblem {
    display: block;
    width: auto;
    max-height: 48px;
    flex-shrink: 0;
}

.brand-kicker,
.brand-abbr,
.brand-full,
.brand-meta {
    display: none;
}

.header-link {
    display: none;
}

/* --------------------------------------------------------------------------
   21. PRODUCTION SHELL — EDITORIAL NAVIGATION & FOOTER
   -------------------------------------------------------------------------- */
::selection {
    color: var(--ink);
    background: var(--accent-light);
}

.site-header {
    background: rgba(255, 255, 255, 0.98);
}

.utility-bar {
    color: var(--ink-secondary);
    background: var(--ink);
    border-bottom: 0;
}

.utility-bar .container {
    justify-content: space-between;
    height: 34px;
    gap: 2rem;
}

.audience-nav,
.utility-actions {
    display: flex;
    align-items: center;
    min-width: 0;
}

.audience-nav {
    gap: clamp(0.85rem, 1.8vw, 1.5rem);
}

.utility-actions {
    gap: 1.25rem;
}

.utility-label {
    color: #b9b9b9;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.utility-bar a {
    position: relative;
    min-height: 34px;
    display: inline-flex;
    align-items: center;
    padding: 0;
    color: #f4f4f4;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: none;
}

.utility-bar a::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 6px;
    left: 0;
    height: 1px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--duration-base) var(--ease-out);
}

.utility-bar a:hover,
.utility-bar a:focus-visible {
    color: #ffffff;
}

.utility-bar a:hover::after,
.utility-bar a:focus-visible::after {
    transform: scaleX(1);
}

.utility-actions a:last-child {
    color: #ffffff;
}

.utility-actions a:last-child::before {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    margin-right: 0.45rem;
    border-radius: 50%;
    background: var(--accent);
}

.header-bar .container {
    position: relative;
    --nav-brush-mask: url("../images/ui/nav-brush.png");
}

/*
 * 15.5rem (248px) until 2.25.0. That figure existed to reserve a stable box for
 * the two-line brand text — mark + "LAAD" + "London Academy of Art & Design" —
 * so the navigation beside it did not shuffle between routes.
 *
 * 2.25.0 removes the descriptor line, leaving 104px of content inside a 248px
 * reservation: 144px of empty space in a header bar that has none to spare. The
 * measurement that found it: .brand reported width 248 while its children summed
 * to 33 + 14 + 57.
 *
 * The stability that min-width bought is now provided by the mark's own fixed
 * height and the fixed-width nav controls (2.20.0), so the reservation is not
 * replaced with a smaller one — it is removed.
 */
.brand-logo {
    object-fit: contain;
}

.brand-name {
    font-size: 1.3rem;
    letter-spacing: -0.035em;
}

.brand-descriptor {
    max-width: 18rem;
    color: #666666;
    font-size: 0.66rem;
    letter-spacing: 0.08em;
}

.site-nav {
    flex: 1 1 auto;
    justify-content: center;
}

.site-nav-inner {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.site-nav .nav-home,
.site-nav .nav-trigger {
    position: relative;
    z-index: 0;
    isolation: isolate;
    width: 10rem;
    flex: 0 0 10rem;
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    padding: 0.5rem 0.8rem;
    border: 0;
    border-radius: 0;
    color: var(--ink-secondary);
    background: transparent;
    font-family: var(--font-body);
    font-size: 0.78rem;
    font-weight: 650;
    line-height: 1;
    letter-spacing: 0.055em;
    text-decoration: none;
    text-transform: uppercase;
    cursor: pointer;
    transition: color var(--duration-fast);
}

.site-nav .nav-home::before,
.site-nav .nav-trigger::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 0.5rem -0.2rem 0.45rem;
    background: var(--accent);
    opacity: 0.18;
    pointer-events: none;
    -webkit-mask-image: var(--nav-brush-mask);
    mask-image: var(--nav-brush-mask);
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    transition:
        background-color var(--duration-fast),
        opacity var(--duration-fast);
}

.site-nav .nav-home:hover,
.site-nav .nav-home:focus-visible,
.site-nav .nav-trigger:hover,
.site-nav .nav-trigger:focus-visible,
.site-nav .nav-home.is-current,
.site-nav .nav-item.is-current > .nav-trigger,
.site-nav .nav-item.is-active > .nav-trigger {
    color: var(--ink);
}

.site-nav .nav-home:hover::before,
.site-nav .nav-home:focus-visible::before,
.site-nav .nav-trigger:hover::before,
.site-nav .nav-trigger:focus-visible::before,
.site-nav .nav-home.is-current::before,
.site-nav .nav-item.is-current > .nav-trigger::before,
.site-nav .nav-item.is-active > .nav-trigger::before {
    background: var(--accent);
    opacity: 0.55;
}

.nav-chevron {
    width: 0.42rem;
    height: 0.42rem;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: translateY(-0.12rem) rotate(45deg);
    transition: transform var(--duration-base) var(--ease-out);
}

.nav-item.is-active .nav-chevron {
    transform: translateY(0.12rem) rotate(225deg);
}

.site-nav .nav-item {
    position: static;
}

.site-nav .nav-item.has-dropdown {
    margin: 0;
    padding: 0;
}

.site-nav .mega-menu {
    position: absolute;
    top: 100%;
    right: var(--gutter);
    left: var(--gutter);
    width: auto;
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(11rem, 0.7fr) minmax(28rem, 2fr) minmax(14rem, 0.85fr);
    gap: clamp(1rem, 2vw, 2rem);
    padding: clamp(1.25rem, 2.2vw, 2rem);
    /* The bars device, menu form: the heavy accent rule is the panel's top
       border, the hairline is drawn just inside it by the ::before below. The
       drop shadow is gone with every other shadow in the system — a 1px ink
       border does the separating now, which is legible on any background
       instead of only on light ones. */
    border: 1px solid var(--ink);
    border-top: var(--rule-heavy) solid var(--accent);
    border-radius: 0;
    background: var(--surface);
    box-shadow: none;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: none;
    /*
     * Visibility changes immediately. Transitioning it left the links hidden
     * for the first rendered frame, so a fast Enter then Tab could skip the
     * newly opened panel even though aria-expanded was already true.
     */
    transition: opacity var(--duration-base) var(--ease-out);
    z-index: 1200;
}

/* The hairline half of the pair. Inset by --rule-gap from the heavy border
   above it; `pointer-events: none` so it never intercepts a click meant for a
   menu link. */
.site-nav .mega-menu::before {
    content: "";
    position: absolute;
    top: var(--rule-gap);
    right: 0;
    left: 0;
    height: var(--rule-hairline);
    background: var(--accent);
    pointer-events: none;
}

.site-nav .nav-item.is-active .mega-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
}

/*
 * The trigger is vertically centred in the desktop header. Stretching its
 * owning item to the full header height makes the route from trigger to panel
 * one continuous hit area instead of a 23px dead hover corridor. Short
 * viewports get an independently scrollable panel so the final links remain
 * reachable while the sticky header stays in place.
 */
@media (min-width: 1024px) {
    .site-nav,
    .site-nav-inner,
    .site-nav .nav-item.has-dropdown {
        height: 100%;
    }

    .site-nav .nav-item.has-dropdown {
        display: flex;
        align-items: center;
    }

    .site-nav .mega-menu {
        /* Size against the space that actually remains below the header, not
           against an assumption that the header is pinned at viewport top.
           --laad-header-bottom is published by initStickyHeader() on scroll,
           resize and orientationchange.

           The fallback is the old constant, so the panel is still contained if
           the custom property never arrives: --header-height + the 35px utility
           bar is exactly where the header ends on an internal page at scroll 0.
           The 8px keeps the panel's lower rule off the viewport edge. */
        max-height: calc(100vh - var(--laad-header-bottom, calc(var(--header-height) + 35px)) - 8px);
        max-height: calc(100dvh - var(--laad-header-bottom, calc(var(--header-height) + 35px)) - 8px);
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior: contain;
    }
}

.mega-menu-intro {
    padding-right: clamp(0.5rem, 1.5vw, 1.5rem);
    border-right: 1px solid var(--border);
}

.mega-menu-kicker,
.mega-menu-column-title {
    margin: 0 0 0.7rem;
    color: var(--accent-dark);
    font-size: 0.7rem;
    font-weight: 750;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.mega-menu-intro > p:not(.mega-menu-kicker) {
    margin: 0;
    color: var(--ink-secondary);
    font-size: 0.92rem;
    line-height: 1.55;
}

.site-nav .mega-menu-overview {
    display: inline-flex;
    flex-direction: row;
    min-width: 0;
    min-height: 44px;
    align-items: center;
    gap: 0.45rem;
    margin-top: 1rem;
    padding: 0;
    color: var(--ink);
    font-size: 0.78rem;
    font-weight: 750;
    letter-spacing: 0.03em;
    text-decoration: none;
    text-transform: none;
}

.mega-menu-links {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
}

.mega-menu-column {
    min-width: 0;
}

.mega-menu-column > a {
    width: 100%;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: 0.58rem 0.7rem;
    border-left: 2px solid transparent;
    border-radius: 0;
    color: var(--ink);
    letter-spacing: normal;
    text-align: left;
    text-decoration: none;
    text-transform: none;
    transition:
        border-color var(--duration-fast),
        background var(--duration-fast),
        transform var(--duration-fast);
}

.mega-menu-column > a::after {
    display: none;
}

.mega-menu-column > a:hover,
.mega-menu-column > a:focus-visible,
.mega-menu-column > a[aria-current="page"] {
    border-left-color: var(--accent);
    color: var(--ink);
    background: var(--accent-subtle);
    transform: translateX(0.2rem);
}

.mega-menu-column .menu-label {
    color: var(--ink);
    font-size: 0.84rem;
    font-weight: 700;
    line-height: 1.3;
}

.mega-menu-column .menu-desc {
    margin-top: 0.18rem;
    color: var(--ink-muted);
    font-size: 0.72rem;
    font-weight: 450;
    line-height: 1.4;
}

.site-nav .mega-menu-feature {
    min-width: 0;
    min-height: 0;
    display: grid;
    grid-template: minmax(13rem, 1fr) / 1fr;
    align-content: stretch;
    align-items: stretch;
    justify-items: stretch;
    padding: 0;
    border: 0;
    border-radius: var(--radius-md);
    overflow: hidden;
    color: #ffffff;
    background: var(--ink);
    text-align: left;
    text-decoration: none;
    text-transform: none;
}

.mega-menu-feature::after {
    display: none;
}

.mega-menu-feature img {
    grid-area: 1 / 1;
    width: 100%;
    height: 100%;
    min-height: 13rem;
    object-fit: cover;
    opacity: 0.58;
    transition:
        transform var(--duration-slow) var(--ease-out),
        opacity var(--duration-slow) var(--ease-out);
}

.mega-menu-feature-copy {
    grid-area: 1 / 1;
    align-self: end;
    position: relative;
    display: block;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.62);
}

.mega-menu-feature-copy strong,
.mega-menu-feature-copy span {
    display: block;
    color: #ffffff;
}

.mega-menu-feature-copy strong {
    font-family: var(--font-display);
    font-size: 0.92rem;
}

.mega-menu-feature-copy span {
    margin-top: 0.28rem;
    font-size: 0.72rem;
    line-height: 1.45;
}

.mega-menu-feature:hover img,
.mega-menu-feature:focus-visible img {
    opacity: 0.72;
    transform: scale(1.035);
}

.mobile-nav-actions {
    display: none;
}

.header-actions {
    flex-shrink: 0;
}

.header-text-action {
    color: var(--ink);
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.25;
    text-align: right;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.25rem;
}

.header-text-action:hover,
.header-text-action:focus-visible {
    color: var(--accent-dark);
}

.header-cta {
    position: relative;
    z-index: 0;
    isolation: isolate;
    border: 0;
    border-radius: 0;
    padding: 0.75rem 1.25rem;
    color: var(--ink);
    background: transparent;
    box-shadow: none;
}

.header-cta::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 0.42rem -0.15rem;
    background: var(--accent);
    opacity: 0.65;
    pointer-events: none;
    -webkit-mask-image: var(--nav-brush-mask);
    mask-image: var(--nav-brush-mask);
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    transition:
        background-color var(--duration-fast),
        opacity var(--duration-fast);
}

.header-cta:hover,
.header-cta:focus-visible {
    color: var(--ink);
    background: transparent;
}

.header-cta:hover::before,
.header-cta:focus-visible::before {
    background: var(--accent-dark);
    opacity: 0.55;
}

/* Editorial refinements */
.hero {
    border-bottom: 0;
}

.hero-home .container {
    position: relative;
    align-items: start;
}

/* Direct child only. `.hero-home .container` also matches .hero-banner's own
   container, so an unscoped selector drew this accent rule down the side of the
   centred banner — where it read as an alignment mistake — and applied
   --section-gap padding to it as well. */
.hero-home > .container::before {
    content: "";
    position: absolute;
    top: var(--section-gap);
    bottom: var(--section-gap);
    left: var(--gutter);
    width: 3px;
    background: var(--accent);
}

.hero-home .hero-left {
    padding-left: clamp(1rem, 2vw, 2rem);
}

/* The home hero is the one place on the site that gets the top of the scale.
   This is the rule that applies — §7 declares the same selector earlier and is
   overridden here. */
/* The home hero keeps 6xl — 46 characters is already the longest H1 on the site
   and the reason the 7xl experiment failed in July. Tracking is relaxed from
   --tracking-display (-0.03em) to the caps range for the same reason as §7. */
.hero-home .hero-copy h1 {
    max-width: 16ch;
    font-size: var(--text-6xl);
    line-height: var(--leading-display);
    letter-spacing: -0.01em;
}

/* Below 480px the home title has to be sized to the longest WORD, not to the
   line. Measured 2026-07-29 in Sora 800 caps at the live tracking:

       "CULTIVATING"   56px -> 392px   48px -> 337px   40px -> 280px   36px -> 253px
       hero-copy box    479px -> 431    390px -> 342    320px -> 272

   So 56px fits at 479 and nowhere below it. Left at 56px the break-word valve
   in §7 fires and splits the word as "CULTIVATI / NG" — which is precisely the
   thing the display spec exists to prevent. The valve is the last resort for
   copy nobody has measured; the right answer for copy we HAVE measured is to
   make the word fit.

   11.5vw keeps ~15px of slack at 320 and ~28px at 390. It must stay after the
   rule above: same specificity, so source order is what carries it.
   Placed here rather than in the shared 479px block near the end of the file,
   because that block's .hero-copy h1 is less specific and would lose anyway. */
@media (max-width: 479px) {
    .hero-home .hero-copy h1 {
        font-size: clamp(2.125rem, 11.5vw, 3.5rem);
    }
}

/* Short titles only, set from the template by character count. Everything about
   this rule is measured, not assumed: if 112px pushes the hero media below the
   fold or overflows the column on either viewport, it goes back to 6xl. */
.hero--short-title .hero-copy h1 {
    font-size: var(--text-7xl);
    line-height: var(--leading-display);
}

.hero-right {
    counter-reset: route-card;
}

@media (min-width: 1100px) {
    .hero-right {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-content: start;
    }
}

.hero-card {
    counter-increment: route-card;
    position: relative;
    padding-left: clamp(1.25rem, 2vw, 1.75rem);
}

.hero-card::before {
    content: "0" counter(route-card);
    position: absolute;
    top: 1.3rem;
    right: 1.2rem;
    color: var(--accent);
    font-family: var(--font-display);
    font-size: 0.72rem;
    font-weight: 750;
    letter-spacing: 0.08em;
}

.hero-card h2,
.hero-card h3 {
    padding-right: 2.5rem;
}

.contact-form {
    max-width: 58rem;
}

.form-status.is-error {
    border-color: rgba(158, 34, 34, 0.35);
    background: rgba(158, 34, 34, 0.07);
    color: #7d1717;
}

/* Institutional footer */
.page-footer {
    position: relative;
    isolation: isolate;
    margin: var(--section-gap) 0 0;
    padding: 0 0 1.4rem;
    overflow: hidden;
    color: #ffffff;
    background: var(--surface-dark);
}

/* The bars device, full-width form — the lid of the footer. Heavy rule, gap,
   hairline; the gap shows the dark surface through, so the pair reads as two
   rules rather than one thick one. */
.page-footer::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: calc(var(--rule-heavy) + var(--rule-gap) + var(--rule-hairline));
    border-top: var(--rule-heavy) solid var(--accent);
    border-bottom: var(--rule-hairline) solid var(--accent);
    box-sizing: border-box;
    z-index: 2;
}

.page-footer::after {
    content: "";
    position: absolute;
    right: -4%;
    bottom: 0;
    width: min(78rem, 96vw);
    aspect-ratio: 1054 / 240;
    background: url("../images/ui/london_skyline.png") right bottom / contain no-repeat;
    /* 0.09 -> 0.15. At 0.09 the skyline was a rumour; the demo carried it as a
       full white silhouette. This is the disciplined middle — legible as a
       silhouette, still clearly behind the type, and it never sits under body
       copy (z-index -1, bottom-right, behind the footer grid). */
    opacity: 0.15;
    pointer-events: none;
    z-index: -1;
}

.footer-cta-panel {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(20rem, 0.8fr);
    gap: clamp(1.5rem, 4vw, 4rem);
    align-items: end;
    padding: clamp(2.5rem, 6vw, 5rem) 0 clamp(2rem, 4vw, 3.5rem);
    border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}

.footer-kicker {
    margin: 0 0 0.75rem;
    color: #f2a7da;
    font-size: 0.7rem;
    font-weight: 750;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.footer-cta-panel h2 {
    max-width: 18ch;
    margin: 0;
    color: #ffffff;
    font-size: clamp(1.8rem, 3.5vw, 3.25rem);
    line-height: 1.08;
}

.footer-cta-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.65rem;
}

.footer-cta-actions a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.7rem 0.9rem;
    border: 1px solid rgba(255, 255, 255, 0.52);
    color: #ffffff;
    background: transparent;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.045em;
    text-decoration: none;
    text-transform: uppercase;
    transition:
        color var(--duration-fast),
        border-color var(--duration-fast),
        background var(--duration-fast),
        transform var(--duration-fast);
}

.footer-cta-actions a:hover,
.footer-cta-actions a:focus-visible {
    color: var(--ink);
    border-color: #ffffff;
    background: #ffffff;
}

.footer-cta-actions a.is-primary {
    border-color: var(--accent);
    background: var(--accent);
}

.footer-cta-actions a.is-primary:hover,
.footer-cta-actions a.is-primary:focus-visible {
    color: #ffffff;
    border-color: var(--accent-dark);
    background: var(--accent-dark);
}

.footer-grid {
    display: grid;
    grid-template-columns: minmax(16rem, 1.4fr) repeat(2, minmax(9rem, 0.7fr)) minmax(13rem, 0.9fr);
    gap: clamp(1.5rem, 3.5vw, 3.5rem);
    padding: clamp(2.5rem, 5vw, 4rem) 0;
}

.footer-mark {
    display: inline-flex;
    flex-direction: column;
    color: #ffffff;
    text-decoration: none;
}

.footer-mark > span {
    font-family: var(--font-display);
    font-size: 2.1rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.045em;
}

.footer-mark > small {
    margin-top: 0.35rem;
    font-size: 0.66rem;
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.footer-brand > p {
    max-width: 38ch;
    margin: 1.25rem 0 0;
    color: #d9d9d9;
    font-size: 0.82rem;
    line-height: 1.65;
}

.footer-brand .footer-company {
    color: #bdbdbd;
    font-size: 0.72rem;
}

.footer-nav-title {
    margin: 0 0 0.85rem;
    color: #f2a7da;
    font-size: 0.68rem;
    font-weight: 750;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.footer-nav-group a,
.footer-contact > a {
    width: fit-content;
    min-height: 34px;
    display: flex;
    align-items: center;
    padding: 0.2rem 0;
    color: #f2f2f2;
    font-size: 0.8rem;
    line-height: 1.35;
    text-decoration-color: transparent;
    text-underline-offset: 0.25rem;
    transition:
        color var(--duration-fast),
        text-decoration-color var(--duration-fast);
}

.footer-nav-group a:hover,
.footer-nav-group a:focus-visible,
.footer-contact > a:hover,
.footer-contact > a:focus-visible {
    color: #ffffff;
    text-decoration-color: var(--accent);
}

.footer-contact .footer-contact-emphasis {
    color: #ffffff;
    font-weight: 700;
}

.footer-contact address {
    max-width: 28ch;
    margin-top: 1rem;
    color: #d9d9d9;
    font-size: 0.76rem;
    font-style: normal;
    line-height: 1.6;
}

.footer-contact address span {
    display: block;
    color: #ffffff;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.footer-bottom {
    padding-top: 1.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.page-footer .copyright {
    margin: 0;
    color: #c8c8c8;
    font-size: 0.7rem;
}

.footer-legal a {
    min-height: 32px;
    display: inline-flex;
    align-items: center;
    color: #e2e2e2;
    font-size: 0.7rem;
}

.page-footer a:focus-visible {
    box-shadow: 0 0 0 2px var(--surface-dark), 0 0 0 4px #ffffff;
}

@media (max-width: 1510px) {
    .header-text-action {
        display: none;
    }
}

@media (max-width: 1180px) {
    /*
     * `.brand { min-width: auto }` and `.brand-descriptor { display: none }`
     * stood here until 2.25.0. Both are dead now: the base min-width they were
     * undoing has been removed, and the descriptor is no longer in the markup.
     *
     * The gap drops from 0.75rem to 0.5rem to clear a PRE-EXISTING overflow.
     * Between 1024 and 1180 the bar runs five 9.5rem nav controls and needed
     * 1033px inside a 1024px container — 9px of horizontal page scroll that
     * predates this change set and was never caught, because the standing gate
     * measures 320/390/1440 and never samples 1024.
     */
    .header-bar .container {
        gap: 0.5rem;
    }

    .brand {
        gap: 0.625rem;
    }

    /*
     * Turkish overflows here where English does not. At 1024 the Turkish
     * header CTA is wide enough to push .header-actions 10px past the viewport
     * — measured on /tr/about/ and /tr/international-applicants/, clean on
     * every English route. Trimming the horizontal padding buys 12px and costs
     * nothing visually; the control keeps its 44px minimum target.
     */
    .header-cta {
        padding-inline: 0.875rem;
    }

    .site-nav-inner {
        gap: 0.1rem;
    }

    .site-nav .nav-home,
    .site-nav .nav-trigger {
        width: 9.5rem;
        flex-basis: 9.5rem;
        padding-inline: 0.45rem;
        font-size: 0.68rem;
        letter-spacing: 0.025em;
    }
}

@media (max-width: 1023px) {
    .site-header {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    .utility-bar {
        display: none;
    }

    .header-bar {
        height: var(--header-height);
    }

    .header-bar .container {
        gap: 0.75rem;
    }

    .brand-text {
        display: flex;
    }

    .brand-descriptor {
        display: none;
    }

    .site-nav {
        position: fixed;
        inset: var(--header-height) 0 0;
        display: none;
        overflow-y: auto;
        overscroll-behavior: contain;
        padding: 1rem var(--gutter) 2rem;
        color: var(--ink);
        background: var(--surface);
        border-top: 1px solid var(--border);
        z-index: 1150;
    }

    .site-nav.is-open {
        display: block;
    }

    .site-nav-inner {
        width: 100%;
        max-width: 46rem;
        margin-inline: auto;
        display: block;
    }

    .site-nav .nav-home,
    .site-nav .nav-trigger {
        width: 100%;
        flex-basis: auto;
        min-height: 54px;
        justify-content: space-between;
        padding: 0.75rem 0.25rem 0.75rem 2.25rem;
        border-bottom: 1px solid var(--border);
        font-family: var(--font-display);
        font-size: 1.12rem;
        font-weight: 700;
        letter-spacing: -0.01em;
        text-transform: none;
    }

    .site-nav .nav-home::before,
    .site-nav .nav-trigger::before {
        top: 0.7rem;
        right: auto;
        bottom: 0.7rem;
        left: -0.25rem;
        width: min(18rem, calc(100% - 2.5rem));
    }

    .site-nav .nav-item.has-dropdown {
        border-bottom: 0;
    }

    .site-nav .mega-menu {
        position: static;
        width: 100%;
        display: none;
        grid-template-columns: 1fr;
        gap: 1rem;
        padding: 1rem 0 1.5rem;
        border: 0;
        border-bottom: 1px solid var(--border);
        border-radius: 0;
        box-shadow: none;
        opacity: 1;
        visibility: visible;
        transform: none;
    }

    .site-nav .nav-item.is-active .mega-menu {
        display: grid;
    }

    .mega-menu-intro {
        padding: 0;
        border: 0;
    }

    .mega-menu-intro > p:not(.mega-menu-kicker) {
        max-width: 48ch;
    }

    .mega-menu-links {
        gap: 0.5rem;
    }

    .mega-menu-column > a {
        border-left: 2px solid var(--border);
    }

    .site-nav .mega-menu-feature {
        display: none;
    }

    .mobile-nav-actions {
        display: grid;
        gap: 0.6rem;
        margin-top: 1.25rem;
    }

    .mobile-nav-actions a {
        min-height: 48px;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0.75rem 1rem;
        border: 1px solid var(--ink);
        color: var(--ink);
        font-size: 0.74rem;
        font-weight: 750;
        letter-spacing: 0.05em;
        text-align: center;
        text-decoration: none;
        text-transform: uppercase;
    }

    .mobile-nav-actions .mobile-nav-primary {
        color: #ffffff;
        border-color: var(--accent);
        background: var(--accent);
    }

    .header-cta {
        display: none;
    }

    .menu-toggle {
        border-radius: 0;
    }

    body.menu-open {
        overflow: hidden;
    }

    .footer-cta-panel,
    .footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .footer-cta-actions {
        justify-content: flex-start;
    }

    .footer-brand,
    .footer-contact {
        grid-column: 1 / -1;
    }
}

@media (max-width: 680px) {
    .brand-text {
        display: none;
    }

    .hero-home .container,
    .hero-home .hero-left,
    .hero-home .hero-right,
    .hero-home .hero-card {
        min-width: 0;
    }

    .hero-home .hero-media {
        min-height: 0;
    }

    .hero-home .container::before {
        top: 2rem;
        bottom: 2rem;
    }

    .hero-home .hero-left {
        padding-left: 1rem;
    }

    .mega-menu-links,
    .footer-cta-panel,
    .footer-grid {
        grid-template-columns: 1fr;
    }

    .mega-menu-column + .mega-menu-column {
        padding-top: 0.75rem;
        border-top: 1px solid var(--border);
    }

    .footer-cta-actions {
        display: grid;
    }

    .footer-cta-actions a {
        width: 100%;
    }

    .footer-brand,
    .footer-contact {
        grid-column: auto;
    }

    .footer-bottom {
        align-items: flex-start;
        flex-direction: column;
    }
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    .mega-menu-feature img,
    .hero-media img {
        transform: none !important;
    }
}

@media (prefers-contrast: high) {
    .utility-bar,
    .page-footer {
        background: #000000;
    }

    .site-nav .mega-menu {
        border: 2px solid #000000;
        border-top-width: 4px;
    }

    .footer-cta-actions a,
    .footer-nav-group a,
    .footer-contact > a,
    .footer-brand > p,
    .footer-contact address,
    .page-footer .copyright {
        color: #ffffff;
    }
}

/* --------------------------------------------------------------------------
   19. GENERIC PAGE PROSE
   Used by page.php, the fallback template for pages without a bespoke
   template. One readable measure rather than the two-column .split grid.
   -------------------------------------------------------------------------- */
.page-prose {
    max-width: 68ch;
}

.page-prose > :first-child {
    margin-top: 0;
}

/* --------------------------------------------------------------------------
   22. LOCALE-ROOT BRAND + HOME BANNER (2.10.0)
   --------------------------------------------------------------------------
   The 2.9.0 centred stack made the unresolved credential wording look like the
   page title and repeated the brand four times. 2.10.0 restores editorial
   hierarchy: one asymmetric grid, the real H1 dominant, the credential retained
   verbatim as a supporting information rail, and no banner photograph while
   the available imagery is stock.

   The English root embeds the mark inside .home-banner. /tr/ has no approved
   banner wording and keeps .brand-masthead as a standalone brand surface.
   -------------------------------------------------------------------------- */
.brand-masthead {
    padding-block: clamp(1.75rem, 3.5vw, 3rem);
    background: var(--surface-warm);
    border-bottom: 1px solid var(--ink);
}

.brand-masthead .container {
    display: flex;
    align-items: center;
    justify-content: center;
}

.masthead-mark,
.home-banner__brand-link {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2vw, 1.75rem);
    max-width: 100%;
    color: inherit;
    text-decoration: none;
}

/* Compact/internal lockups remain below the 250x400 source's native size. */
.masthead-logo {
    width: 125px;
    height: 200px;
    aspect-ratio: 250 / 400;
    flex-shrink: 0;
    object-fit: contain;
}

.masthead-word {
    display: flex;
    flex-direction: column;
    padding-bottom: 0.35rem;
}

.masthead-abbr {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 5vw, 3.75rem);
    font-weight: 800;
    line-height: 0.9;
    letter-spacing: -0.035em;
}

.masthead-full {
    max-width: 16ch;
    margin-top: 0.5rem;
    color: var(--ink-secondary);
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.home-banner {
    background: var(--surface-warm);
    border-bottom: 1px solid var(--ink);
}

/* Unique component selector: generic .hero .container rules must not turn this
   nested banner container back into the body hero's 1.15/0.85 grid. */
.hero-home .home-banner__grid {
    display: grid;
    grid-template-columns: 14.0625rem minmax(0, 1fr) minmax(16.25rem, 0.65fr);
    grid-template-areas:
        "brand headline credential"
        "brand headline details";
    gap: 2rem clamp(1.5rem, 3.5vw, 3.5rem);
    align-items: start;
    padding-block: clamp(2.25rem, 3.5vw, 3rem);
}

.home-banner__brand {
    grid-area: brand;
    align-self: start;
}

.home-banner__brand .masthead-logo {
    width: 225px;
    height: 360px;
}

.home-banner__brand-link {
    flex-direction: column;
    align-items: flex-start;
    width: fit-content;
    gap: 0;
}

/* The paired heavy/hairline rules are the only ornament. The fixed flag column
   prevents the flag becoming a detached badge on a line of its own. */
.home-banner__credential {
    position: relative;
    display: grid;
    grid-area: credential;
    grid-template-columns: 80px minmax(0, 1fr);
    gap: clamp(0.875rem, 1.5vw, 1.25rem);
    align-items: center;
    width: 100%;
    padding-top: 1.25rem;
}

.home-banner__credential::before,
.home-banner__credential::after {
    content: "";
    position: absolute;
    right: 0;
    left: 0;
}

.home-banner__credential::before {
    top: 0;
    height: var(--rule-heavy);
    background: var(--accent);
}

.home-banner__credential::after {
    top: calc(var(--rule-heavy) + var(--rule-gap));
    height: var(--rule-hairline);
    background: var(--ink);
}

.hero-credential {
    min-width: 0;
    margin: 0;
    color: var(--ink);
    font-family: var(--font-display);
    font-size: clamp(1rem, 1.4vw, 1.25rem);
    font-weight: 700;
    line-height: 1.18;
    letter-spacing: 0.02em;
    text-align: left;
    text-transform: uppercase;
    hyphens: none;
}

.hero-credential-flag {
    width: 80px;
    height: 40px;
    border: 1px solid rgba(26, 26, 26, 0.35);
}

.home-banner__headline {
    grid-area: headline;
    align-self: start;
    min-width: 0;
}

.hero-banner-title {
    max-width: 12ch;
    margin: 0;
    color: var(--ink);
    font-family: var(--font-display);
    /*
     * 76px is the measured ceiling in the desktop centre column: at the old
     * 88px ceiling CULTIVATING exceeded its own box by 69px even though the
     * hero's overflow clipping hid the defect from page-width checks.
     */
    font-size: clamp(3.5rem, 5.3vw, 4.75rem);
    font-weight: 800;
    line-height: 0.92;
    letter-spacing: -0.01em;
    text-align: left;
    text-transform: uppercase;
    hyphens: none;
    overflow-wrap: normal;
}

.home-banner__title-prefix {
    display: block;
    margin-bottom: clamp(0.65rem, 1.2vw, 1rem);
    color: var(--accent-dark);
    font-size: clamp(0.75rem, 1.1vw, 0.9375rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.14em;
}

.home-banner__title-statement {
    display: block;
}

.home-banner__details {
    grid-area: details;
    align-self: end;
    width: 100%;
    max-width: 34rem;
}

.hero-banner-sub {
    max-width: 34ch;
    margin: 0;
    color: var(--ink-secondary);
    font-size: var(--text-md);
    font-weight: 600;
    line-height: 1.5;
    text-wrap: balance;
}

.home-banner__actions {
    display: grid;
    gap: 0.75rem;
    width: 100%;
    margin-top: clamp(1.5rem, 2.5vw, 2rem);
}

.home-banner__actions .cta-button {
    width: 100%;
    max-width: 100%;
    padding-inline: 1rem;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

.home-banner__actions .cta-button.primary {
    background: var(--accent-dark);
    border-color: var(--accent-dark);
}

/* The third action is available without competing with the two decisions that
   move a visitor through the information architecture. */
.home-banner__actions .cta-button:nth-child(3) {
    justify-content: flex-start;
    width: fit-content;
    padding: 0.5rem 0;
    color: var(--accent-dark);
    background: transparent;
    border-color: transparent;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.3rem;
}

.home-banner__actions .cta-button:nth-child(3):hover,
.home-banner__actions .cta-button:nth-child(3):focus-visible {
    color: var(--ink);
    background: transparent;
    border-color: transparent;
}

/* The locale-root lockup already names the academy; repeating the header's text
   block immediately above it is visual noise. The linked mark remains. */
@media (min-width: 1024px) {
    body[data-locale-root] .site-header .brand-text {
        display: none;
    }
}

/* The three-column cover needs the full desktop measure. At the navigation's
   1024px desktop edge, use a 2-column editorial spread so neither the title nor
   the action labels are squeezed into false overflow. */
@media (min-width: 768px) and (max-width: 1199px) {
    .hero-home .home-banner__grid {
        grid-template-columns: minmax(0, 1fr) minmax(18rem, 20rem);
        grid-template-areas:
            "brand credential"
            "headline details";
        gap: 2rem clamp(2rem, 4vw, 3rem);
    }

    .home-banner__brand-link {
        flex-direction: row;
        align-items: center;
    }

    .home-banner__brand .masthead-logo {
        width: 175px;
        height: 280px;
    }

    .hero-banner-title {
        max-width: 13ch;
    }
}

@media (max-width: 1023px) {
    .masthead-logo {
        width: 93.75px;
        height: 150px;
    }

    .masthead-abbr {
        font-size: clamp(2rem, 6vw, 2.75rem);
    }
}

@media (min-width: 768px) and (max-width: 899px) {
    .hero-banner-title {
        font-size: 3.25rem;
    }
}

@media (max-width: 767px) {
    .hero-home .home-banner__grid {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "brand"
            "credential"
            "headline"
            "details";
        gap: clamp(1.5rem, 4vw, 2.5rem);
        padding-block: clamp(2.25rem, 6vw, 3.5rem);
    }

    .home-banner__brand-link {
        flex-direction: row;
        align-items: center;
        gap: clamp(1rem, 3vw, 1.75rem);
    }

    .home-banner__brand .masthead-logo {
        width: 150px;
        height: 240px;
    }

    .home-banner__credential,
    .home-banner__details {
        max-width: 36rem;
    }

    .hero-banner-title {
        max-width: 13ch;
        font-size: clamp(3.5rem, 9vw, 4.5rem);
    }
}

@media (max-width: 767px) {
    .hero-home .home-banner__grid {
        padding-block: 2.25rem;
    }

    .home-banner__credential {
        grid-template-columns: 56px minmax(0, 1fr);
    }

    .hero-credential-flag {
        width: 56px;
        height: 28px;
    }
}

@media (max-width: 479px) {
    .brand-masthead .masthead-mark {
        flex-direction: column;
        gap: 0.75rem;
        text-align: center;
    }

    .brand-masthead .masthead-word {
        align-items: center;
        padding-bottom: 0;
        text-align: center;
    }

    .brand-masthead .masthead-full {
        max-width: none;
    }

    .masthead-logo {
        width: 77.5px;
        height: 124px;
    }

    .home-banner__brand .masthead-logo {
        width: 125px;
        height: 200px;
    }

    .hero-home .home-banner__grid {
        gap: 1.25rem;
        padding-block: 1.75rem;
    }

    .home-banner__credential {
        grid-template-columns: 48px minmax(0, 1fr);
        gap: 0.75rem;
        padding-top: 1rem;
    }

    .hero-credential {
        font-size: 1rem;
    }

    .hero-credential-flag {
        width: 48px;
        height: 24px;
    }

    .hero-banner-title {
        max-width: 12ch;
        font-size: clamp(2rem, 10vw, 3rem);
    }

    .hero-banner-sub {
        font-size: 0.9375rem;
    }

    .home-banner__actions {
        gap: 0.625rem;
        margin-top: 1.25rem;
    }

    .home-banner__actions .cta-button:nth-child(3) {
        width: fit-content;
    }
}

@media (max-width: 359px) {
    .home-banner__actions .cta-button {
        padding-inline: 0.5rem;
        font-size: 0.75rem;
        letter-spacing: 0.03em;
    }
}

/* --------------------------------------------------------------------------
   23. EDUCATION CALENDAR
   --------------------------------------------------------------------------
   Owner decision L7 (2026-07-27), "Eğitim takvimi eklenecek" (01:33:26).
   Renders only when real dates exist; see the template part.

   Follows the 2.5.0 design mix: flat colour, square corners, no shadow, and a
   hairline rule per row rather than a card. Deliberately not a stat row — the
   owners rejected that treatment on the home page for looking derivative.
   -------------------------------------------------------------------------- */
.calendar-list {
    display: grid;
    gap: 0;
    margin: 2.5rem 0 0;
    max-width: 44rem;
    border-top: var(--rule-heavy) solid var(--accent);
}

.calendar-list__item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
    padding: 1rem 0;
    border-bottom: var(--rule-hairline) solid rgba(26, 26, 26, 0.16);
}

.calendar-list__label {
    margin: 0;
    font-weight: 600;
    color: var(--ink);
}

.calendar-list__value {
    margin: 0;
    font-family: var(--font-display);
    font-variant-numeric: tabular-nums;
    color: var(--accent-dark);
}

.calendar-note {
    margin-top: 1.25rem;
    font-size: var(--text-sm);
}

@media (max-width: 599px) {
    .calendar-list__item {
        flex-direction: column;
        gap: 0.25rem;
    }
}

/* --------------------------------------------------------------------------
   24. CURRICULUM DETAIL
   Course-and-lesson depth inside .details-box, introduced with the Interior
   Design certificate curriculum in 2.7.0.

   .details-body h3 (§ above) already renders the course title in the accent at
   --text-lg. The unit label sits between that and the lesson list, so it has to
   read quieter than the course above it — h4's global --text-lg would make the
   two the same size. Stepped down to --text-sm in --ink-muted: #6e6e6e on the
   white .details-box surface is 5.10:1, clear of the 4.5:1 AA floor for text
   this size. Do not swap it for #767676, which the token comment at the top of
   this file already records as failing.
   ------------------------------------------------------------------------ */
.details-body h4 {
    margin: 1.15rem 0 0.4rem;
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.details-body h4:first-child {
    margin-top: 0.5rem;
}

.details-body .course-meta {
    margin: 0 0 0.6rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* --------------------------------------------------------------------------
   25. LANGUAGE SWITCHER
   Rebuilt in 2.25.0. Both locales render at all times — the current one as an
   inert <span aria-current="true">, the other as the link — so the control's
   width is set by its content and does not change when it is used. The old
   single-link form swapped "English" for "Türkçe" and reflowed the utility bar
   on every switch.

   Two placements, mutually exclusive by width:
     .lang-switch--header  in the dark utility bar, >=1024px only
     .lang-switch--mobile  in the navigation drawer, <1024px only

   Colours are solid, not rgba over a backdrop-filtered bar: the contrast gate
   samples rendered pixels and translucent text over a blurred surface is not
   reliably measurable.
   ------------------------------------------------------------------------ */
.lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
}

.lang-switch__option {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.375rem 0.55rem;
    border: 1px solid transparent;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
}

/* The utility bar gives every descendant <a> an underline sweep at §21; the
   switcher is a segmented control, not a link list, so it opts out. */
.lang-switch__option::after {
    display: none !important;
}

.lang-switch__flag {
    flex-shrink: 0;
    width: 20px;
    height: 14px;
    /* Union Flag is 1:2 and the Türkiye flag 3:2. `cover` keeps both icons at
       one identical size without distorting either national flag; letterboxing
       or stretching would do one or the other. */
    object-fit: cover;
    border: 1px solid rgba(128, 128, 128, 0.45);
}

/* Compact form is the default; the full language name is exposed to assistive
   technology at every width and becomes visible where there is room. */
.lang-switch__name {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/*
 * The utility bar decorates its LAST action link with an accent dot and forces
 * it white (.utility-actions a:last-child + ::before). That rule was written
 * when the final action was a single link. The switcher is now a segmented
 * group whose second option is that last child, so the dot landed INSIDE the
 * control, between EN and TR, and the white override erased the distinction
 * between the active and inactive language.
 *
 * Scoped out here rather than by editing the original rule, which still does
 * its job for the consultation link when the switcher is absent.
 */
.utility-actions .lang-switch a::before,
.utility-actions .lang-switch a::after {
    content: none;
}

.utility-actions .lang-switch a.lang-switch__option {
    color: #c9c9c9;
}

.utility-actions .lang-switch a.lang-switch__option:hover,
.utility-actions .lang-switch a.lang-switch__option:focus-visible {
    color: #ffffff;
}

/* --- header variant, dark utility bar ------------------------------------ */
.lang-switch--header .lang-switch__option {
    color: #c9c9c9;                    /* 10.3:1 on --ink */
    border-color: rgba(244, 244, 244, 0.35);
}

.lang-switch--header .lang-switch__option.is-current {
    color: #ffffff;                    /* 17.4:1 on --ink */
    border-color: #ffffff;
    background: rgba(244, 244, 244, 0.14);
}

.lang-switch--header a.lang-switch__option:hover,
.lang-switch--header a.lang-switch__option:focus-visible {
    color: #ffffff;
    border-color: #ffffff;
    background: rgba(244, 244, 244, 0.12);
}

@media (min-width: 1200px) {
    .lang-switch--header .lang-switch__code {
        display: none;
    }

    .lang-switch--header .lang-switch__name {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        clip: auto;
    }
}

/* --- mobile variant, light navigation drawer ----------------------------- */
.lang-switch--mobile {
    display: none;
}

@media (max-width: 1023px) {
    .lang-switch--mobile {
        display: flex;
        gap: 0.5rem;
        margin-top: 1rem;
        padding-top: 1rem;
        border-top: 1px solid var(--border);
    }

    .lang-switch--mobile .lang-switch__option {
        flex: 1 1 0;
        justify-content: center;
        /* 48px is the drawer's own touch-target floor (.mobile-nav-actions a). */
        min-height: 48px;
        border-color: var(--ink);
        color: var(--ink);
        font-size: 0.74rem;
        font-weight: 750;
    }

    .lang-switch--mobile .lang-switch__option.is-current {
        background: var(--ink);
        color: var(--ink-inverse);
    }

    .lang-switch--mobile .lang-switch__code {
        display: none;
    }

    .lang-switch--mobile .lang-switch__name {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        clip: auto;
    }
}

/* --------------------------------------------------------------------------
   26. BRAND CLUSTER AND İGSA PARTNERSHIP LOCKUP  (2.25.0)
   LAAD stays the primary identity everywhere: its mark leads the cluster, the
   partner mark follows behind a hairline rule and a smaller optical weight.
   ------------------------------------------------------------------------ */
.brand-cluster {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    min-width: 0;
    flex-shrink: 0;
}

.partner-lockup {
    display: flex;
    min-width: 0;
}

.partner-lockup__label {
    color: var(--ink-muted);
    font-size: 0.625rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.partner-lockup__logo {
    width: auto;
    height: auto;
    object-fit: contain;
}

/* --- header variant ------------------------------------------------------- */
.partner-lockup--header {
    flex-direction: column;
    gap: 0.25rem;
    align-items: flex-start;
    padding-left: 0.875rem;
    border-left: 1px solid var(--border);
}

.partner-lockup--header .partner-lockup__logo {
    width: 118px;
    /* 118 / (700/221) — declared so the box is reserved before the PNG lands. */
    height: 37px;
}

/*
 * Below 1024px the sticky header is 72px tall and already carries the LAAD
 * mark, the menu toggle and (to 680px) the brand text. A second institutional
 * logo fits arithmetically but reads as co-branding once the explanatory label
 * is dropped for space — the opposite of the hierarchy the owners asked for.
 * The drawer and the footer carry it at a legible size instead.
 */
@media (max-width: 1279px) {
    /*
     * Raised from 1023px to 1279px, and the figure is measured, not chosen.
     *
     * At 1280 the container caps at --max-width and the bar needs exactly
     * 1216px of its 1216px: brand 104 + gap 14 + lockup 144 + nav 816 +
     * actions 106 + gaps 32. It fits, with nothing to spare.
     *
     * Between 1181 and 1279 it does NOT fit. The container is narrower than
     * 1280 while the navigation has already switched to its wide 160px
     * variant (816px total), leaving ~182px for a brand cluster that needs
     * 262px — about 50px of real horizontal page scroll, confirmed at 1200.
     *
     * Below 1024 the bar is over its container by ~9px even without any of
     * this, a pre-existing defect the standing 320/390/1440 gate never sampled.
     * That is fixed separately in the <=1180 block.
     *
     * Under 1280 the drawer and the footer carry the partnership instead.
     */
    .site-header .partner-lockup--header {
        display: none;
    }
}

@media (max-width: 1180px) {
    .brand-cluster {
        gap: 0.625rem;
    }

    .partner-lockup--header {
        padding-left: 0.625rem;
    }

    .partner-lockup--header .partner-lockup__logo {
        width: 104px;
        height: 33px;
    }
}

/* The locale roots place the lockup under the banner mark, where the column is
   14.0625rem wide and there is room for the horizontal artwork at full size. */
.home-banner__brand .partner-lockup--header {
    margin-top: clamp(1rem, 2vw, 1.5rem);
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--border);
    padding-top: 0.75rem;
    display: flex;
}

.home-banner__brand .partner-lockup--header .partner-lockup__logo {
    width: 150px;
    height: 47px;
}

@media (max-width: 767px) {
    .home-banner__brand .partner-lockup--header .partner-lockup__logo {
        width: 132px;
        height: 42px;
    }
}

/* --- footer variant ------------------------------------------------------- */
.partner-lockup--footer {
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.partner-lockup--footer .partner-lockup__label {
    /* Solid, and the same value .page-footer .copyright already uses: #c8c8c8
       on --surface-dark #1a1a1a is 10.1:1. Translucent white here would sample
       differently per backdrop and the contrast gate reads rendered pixels. */
    color: #c8c8c8;
    font-size: 0.6875rem;
}

.partner-lockup--footer .partner-lockup__logo {
    width: 180px;
    height: 57px;
}

@media (max-width: 479px) {
    .partner-lockup--footer .partner-lockup__logo {
        width: 152px;
        height: 48px;
    }
}

/* --- drawer placement ------------------------------------------------------
   Reuses the footer variant's geometry inside the navigation drawer, which is
   a LIGHT surface — so the two colour declarations the dark footer sets have
   to be undone here or the label is near-white on near-white. */
.mobile-nav-partner {
    display: none;
}

@media (max-width: 1023px) {
    .mobile-nav-partner {
        display: block;
    }

    .mobile-nav-partner .partner-lockup--footer {
        margin-top: 1rem;
        padding-top: 1rem;
        border-top-color: var(--border);
    }

    .mobile-nav-partner .partner-lockup__label {
        color: var(--ink-muted);
    }
}

/* --------------------------------------------------------------------------
   27. AUDIENCE PAGES  (2.25.0)
   Prospective Students / Current Students / International Applicants. One
   template, four section primitives. Everything obeys §21: radius 0, no
   shadow, no lift, hover is a colour swap.
   ------------------------------------------------------------------------ */

/* --- numbered process ----------------------------------------------------- */
.audience-steps {
    display: grid;
    gap: 1px;
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
    background: var(--border);
    border: 1px solid var(--border);
}

.audience-steps__item {
    position: relative;
    padding: 1.25rem 1.25rem 1.25rem 3.75rem;
    background: var(--surface);
    counter-increment: audience-step;
}

.audience-steps {
    counter-reset: audience-step;
}

.audience-steps__item::before {
    content: counter(audience-step);
    position: absolute;
    top: 1.25rem;
    left: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    background: var(--accent);
    color: var(--ink-inverse);
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 800;
    line-height: 1;
}

.audience-steps__item h3 {
    margin: 0 0 0.35rem;
    font-size: var(--text-md);
}

.audience-steps__item p {
    margin: 0;
    color: var(--ink-secondary);
}

/* --- checklist ------------------------------------------------------------ */
.audience-checklist {
    display: grid;
    gap: 0.875rem;
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
}

.audience-checklist li {
    position: relative;
    padding-left: 1.875rem;
    font-weight: 650;
}

/* Not a bare tick glyph: a check mark alone carries meaning by symbol only.
   The item text states the point; this is decoration beside it. */
.audience-checklist li::before {
    content: "";
    position: absolute;
    top: 0.55em;
    left: 0;
    width: 0.75rem;
    height: 0.75rem;
    background: var(--accent);
}

.audience-checklist li span {
    display: block;
    margin-top: 0.2rem;
    color: var(--ink-secondary);
    font-weight: 400;
}

/* --- resource links ------------------------------------------------------- */
.audience-links {
    display: grid;
    gap: 0;
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--border);
}

.audience-links__item {
    display: grid;
    gap: 0.2rem;
    padding: 0.9375rem 0;
    border-bottom: 1px solid var(--border);
}

a.audience-links__label {
    justify-self: start;
    color: var(--ink);
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.25rem;
    /* 44px comfortable target without stretching the row */
    padding-block: 0.35rem;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

a.audience-links__label:hover,
a.audience-links__label:focus-visible {
    color: var(--accent-dark);
}

span.audience-links__label {
    font-weight: 700;
    color: var(--ink-secondary);
}

.audience-links__text {
    color: var(--ink-secondary);
    font-size: var(--text-sm);
}

/* An item whose destination is not confirmed says so in words. It is NOT a
   link, so it cannot be tabbed to or tapped — better than href="#". */
.audience-links__status {
    justify-self: start;
    margin-top: 0.15rem;
    padding: 0.15rem 0.5rem;
    border: 1px solid var(--ink-muted);
    color: var(--ink-secondary);
    font-size: 0.6875rem;
    font-weight: 650;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* --- qualifying note ------------------------------------------------------ */
.audience-note {
    margin-top: 1.25rem;
    padding: 0.875rem 1rem;
    border-left: var(--rule-heavy) solid var(--accent);
    background: var(--surface-warm);
    color: var(--ink-secondary);
    font-size: var(--text-sm);
}

.audience-note a {
    color: var(--ink);
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2rem;
}

/* --- FAQ ------------------------------------------------------------------ */
.audience-faq {
    display: grid;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

@media (max-width: 767px) {
    .audience-steps__item {
        padding: 1rem 1rem 1rem 3.25rem;
    }

    .audience-steps__item::before {
        top: 1rem;
        left: 1rem;
    }
}

/* --------------------------------------------------------------------------
   28. TOUCH-TARGET FLOOR  (2.25.0)
   The nine-width audit measured .card-link rendering 22px tall on every card
   across every route and breakpoint — under the 24x24 CSS px floor WCAG 2.5.8
   (AA) sets for pointer targets. The link is a standalone control at the foot
   of a card, not a link inside a sentence, so the sentence exemption does not
   apply to it.

   Fixed with min-height rather than padding: these links sit at `margin-top:
   auto` inside flex cards, so adding padding would move the baseline and
   change every card's height. min-height on an already inline-flex,
   centre-aligned box grows the hit area and leaves the text where it was.
   ------------------------------------------------------------------------ */
.card-link {
    min-height: 24px;
}
