/* ---------- typefaces ----------
   Outfit and Playfair Display, self-hosted. Loading these from Google's CDN
   sends every visitor's IP address to a US server before the page paints and
   before any consent is asked for, which is the point the Munich court ruled
   on; served from our own origin, no third party sees the request at all.
   Latin and latin-ext subsets only. Both are variable fonts, so several
   weights share one file.
   ---------------------------------------------------------------- */
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(../fonts/outfit-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(../fonts/outfit-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/outfit-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/outfit-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fonts/outfit-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fonts/outfit-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/outfit-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/outfit-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/outfit-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/outfit-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600i-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600i-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(../fonts/playfairdisplay-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================
   Al-Fajr Academia
   Two palettes: sage on cream by day, luminous sage on charcoal by night.
   Commissioned graphic illustrations and accessible diagrams explain the content.
   Design variance 6 / motion intensity 3 / visual density 4.
   Native CSS evolves the existing static site; no framework dependency.
   Radius rule: surfaces / buttons / inputs = 4px. Tags = full pill. Nothing else.
   ============================================================ */

:root {
  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-ui: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --paper: #f7f2eb;
  /* palette: cream */
  --surface: #ffffff;
  --surface-2: #eae2d6;
  /* palette: warm beige */
  --ink: #1a1a1a;
  /* palette: midnight */
  --ink-2: #4a4740;
  --ink-3: #656156;
  --brand: #55643a;
  /* palette: sage, darkened to read as a link */
  --brand-2: #3f4b2a;
  --accent: #8b9a6e;
  /* palette: sage */
  --accent-ink: #1a1a1a;
  --accent-text: #55643a;

  /* Solid buttons and the nav underline. Kept apart from --accent because on a
     dark ground the sage sinks into the background, where the warm paper tone
     carries the same weight the sage has in daylight. */
  --highlight: #8b9a6e;
  --highlight-ink: #1a1a1a;
  /* What a button throws on hover. Opposite in value to the page it sits on,
     so the change is unmistakable without the control moving. */
  --btn-glow:
    0 2px 6px color-mix(in srgb, var(--ink) 18%, transparent),
    0 8px 22px -6px color-mix(in srgb, var(--ink) 30%, transparent);
  --line: rgba(26, 26, 26, 0.2);
  --line-soft: rgba(26, 26, 26, 0.1);
  --shade: rgba(26, 26, 26, 0.12);

  /* frosted surfaces read the current theme rather than a fixed white */
  --glass: color-mix(in srgb, var(--surface) 82%, transparent);
  --glass-line: color-mix(in srgb, var(--ink) 18%, transparent);
  --grain: 0.055;

  /* ---------- depth ----------
     One elevation scale, so raised things agree with each other instead of
     each carrying its own invented shadow. Every step pairs a tight contact
     shadow with a broad ambient one: that pairing is what reads as an object
     off the page, where a single soft blur just reads as fog. --sheen is the
     hairline of light along a raised top edge. */
  --lift-1:
    0 1px 2px color-mix(in srgb, var(--shade) 65%, transparent),
    0 8px 18px -10px var(--shade);
  --lift-2:
    0 2px 4px color-mix(in srgb, var(--shade) 60%, transparent),
    0 22px 44px -20px var(--shade);
  --lift-3:
    0 3px 7px color-mix(in srgb, var(--shade) 55%, transparent),
    0 40px 80px -30px var(--shade);
  --sheen: inset 0 1px 0 rgba(255, 255, 255, 0.55);

  /* Letterpress relief for display headings: a lit edge along the top of each
     stroke, a hard contact edge under it, then a soft cast shadow down and to
     the right. Light from the top-left is what makes type read as raised off
     the paper rather than blurred against it. */
  --type-relief:
    0 -1px 0 rgba(255, 255, 255, 0.75),
    0 1px 0 color-mix(in srgb, var(--shade) 45%, transparent),
    2px 3px 5px color-mix(in srgb, var(--shade) 55%, transparent);

  /* The same light, at reading size. Body copy is set in the same relief as
     the headings but shallower: at 1rem the full cast shadow closes up the
     counters and the text stops being crisp. */
  --type-relief-soft:
    0 -1px 0 rgba(255, 255, 255, 0.6),
    0 1px 1px color-mix(in srgb, var(--shade) 32%, transparent);

  --radius: 4px;
  --nav-h: 68px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section-y: clamp(4.5rem, 9vw, 7.5rem);
  --measure: 62ch;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: light;
}

/* An explicit attribute records a visitor's choice. With no saved choice the
   page stays light. */
:root[data-theme="dark"] {
  /* Warm dark, not a cool green-black: the grounds are pulled towards the same
     brown the paper tone comes from, so the page reads as a lamp-lit desk
     rather than a screen tinted the colour of its own text. */
  --paper: #15120d;
  --surface: #1e1a14;
  --surface-2: #2a251c;
  --ink: #f4f0e8;
  --ink-2: #cec9bf;
  --ink-3: #aaa69c;
  --brand: #c5d3a2;
  --brand-2: #dae4bd;
  --accent: #9cac78;
  --accent-ink: #11150f;
  --accent-text: #bdcc98;
  --line: rgba(244, 240, 232, 0.22);
  --line-soft: rgba(244, 240, 232, 0.11);
  --shade: rgba(0, 0, 0, 0.44);
  --grain: 0.038;
  /* On a dark ground the lit edge is what separates surfaces, more than the
     shadow underneath them. */
  --sheen: inset 0 1px 0 rgba(244, 240, 232, 0.09);
  /* the light theme's paper tone, which reads as the brightest thing on a dark page */
  --highlight: #eae2d6;
  --highlight-ink: #16190f;
  /* On the dark theme the glow is light: a shadow would vanish into the ground. */
  --btn-glow:
    0 2px 8px rgba(234, 226, 214, 0.18),
    0 10px 26px -8px rgba(234, 226, 214, 0.26);
  /* Pale type on a dark ground: the lit edge does the lifting, and the cast
     shadow goes deeper and softer instead of darker at the contact line. */
  --type-relief:
    0 -1px 0 rgba(244, 240, 232, 0.14),
    2px 4px 10px rgba(0, 0, 0, 0.6);
  --type-relief-soft:
    0 -1px 0 rgba(244, 240, 232, 0.09),
    0 1px 2px rgba(0, 0, 0, 0.45);
  color-scheme: dark;
}

/* ---------- base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 1rem);
}

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 1rem;
  line-height: 1.72;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Two fixed layers behind everything, both blurred by the frosted panels.
   ::before is a restrained colour field -- a tint on the stock, not wallpaper.
   ::after is the paper grain; --grain is its strength knob. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(46rem 32rem at 10% -10%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 72%),
    radial-gradient(38rem 30rem at 94% 6%, color-mix(in srgb, var(--brand) 10%, transparent), transparent 72%),
    radial-gradient(44rem 34rem at 72% 98%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 74%),
    radial-gradient(125% 95% at 50% 38%, transparent 52%, var(--shade) 100%);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: var(--grain);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)'/%3E%3C/svg%3E"),
    repeating-linear-gradient(90deg, var(--ink) 0 1px, transparent 1px 5px);
}

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

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.008em;
  margin: 0;
  color: var(--ink);
}

h1 {
  font-size: clamp(2.3rem, 5vw, 3.9rem);
}

h2 {
  font-size: clamp(1.8rem, 3.4vw, 2.7rem);
}

h3 {
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
}

p {
  margin: 0 0 1rem;
  max-width: var(--measure);
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--brand);
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
}

a:hover {
  color: var(--accent-text);
}

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 4px;
  border-radius: 2px;
}

.wrap {
  width: min(1200px, 100% - (var(--gutter) * 2));
  margin-inline: auto;
}

.lede {
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: clamp(1.08rem, 1.6vw, 1.28rem);
  line-height: 1.6;
  letter-spacing: 0.002em;
  color: var(--ink-2);
}

.section {
  padding-block: var(--section-y);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.75rem 1.25rem;
  font-weight: 600;
}

.skip:focus {
  left: 1rem;
  top: 1rem;
}

/* ---------- nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: var(--paper);
  border-bottom: 1px solid var(--line-soft);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.brand {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.3rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.brand span {
  color: var(--accent-text);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.4vw, 2.2rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__links a {
  position: relative;
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 500;
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding-block: 0.4rem;
  transition: color 0.25s var(--ease);
}

.nav__links a:hover {
  color: var(--ink);
}

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

.nav__actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.theme-toggle,
.nav__toggle {
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}

.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 2.65rem;
  height: 2.65rem;
  padding: 0;
  transition: color 0.25s var(--ease), background-color 0.25s var(--ease),
    border-color 0.25s var(--ease), transform 0.2s var(--ease);
}

.theme-toggle:hover {
  color: var(--accent-text);
  background: var(--surface-2);
  border-color: var(--accent);
}

.theme-toggle:active {
  transform: scale(0.94);
}

.theme-toggle__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.nav__toggle {
  display: none;
  /* A comfortable target, not the 34px the glyph and its padding came to: this
     is the only way to the menu on a phone. */
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0.45rem 0.6rem;
}

@media (max-width: 760px) {
  .nav__toggle {
    display: block;
  }

  .nav__links {
    position: absolute;
    inset: var(--nav-h) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: 0.25rem var(--gutter) 0.9rem;
    box-shadow: 0 18px 40px var(--shade);
  }

  .nav__links[hidden] {
    display: none;
  }

  .nav__links a {
    /* block, not inline: an inline anchor only draws its rule under the label,
       which is what left the ragged part-lines between items. */
    display: block;
    text-align: center;
    padding: 1rem 0;
    border-bottom: 0;
    font-size: 0.9rem;
    letter-spacing: 0.1em;
  }

  /* the divider belongs to the row, so it spans the full menu width */
  .nav__links li+li {
    border-top: 1px solid var(--line-soft);
  }

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

@media (max-width: 760px) and (prefers-reduced-motion: no-preference) {
  .nav__links:not([hidden]) {
    animation: menu-in 0.26s var(--ease) both;
  }
}

@keyframes menu-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.6rem;
  border-radius: var(--radius);
  font-family: var(--font-ui);
  font-size: 0.95rem;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  border: 1.5px solid transparent;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease), color 0.25s var(--ease);
}

.btn--solid {
  background: var(--accent);
  color: var(--accent-ink);
}

.btn--solid:hover {
  background: color-mix(in srgb, var(--accent) 82%, #fff);
  color: var(--accent-ink);
}

.btn--line {
  border-color: var(--line);
  color: var(--ink);
  background: transparent;
}

.btn--line:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}

.btn--sm {
  padding: 0.6rem 1.1rem;
  font-size: 0.88rem;
}

.tag {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 0.4rem;
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--brand) 13%, transparent);
  color: var(--brand);
}

.tag--accent {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-text);
}

/* ---------- hero ---------- */
/* The hero illustration connects the academy's three dimensions of mastery. */
.hero {
  padding-block: clamp(2rem, 5vw, 4rem);
  border-bottom: 1px solid var(--line-soft);
}

.hero__grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: 1fr 1.15fr;
  align-items: center;
}

.hero__title {
  font-size: clamp(2rem, 3.8vw, 3.4rem);
  max-width: 21ch;
  margin-bottom: 1.4rem;
  line-height: 1.12;
}

.hero .lede {
  max-width: 42ch;
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2rem;
}

.hero__figure {
  margin: 0;
}

.hero__figure img {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}

@media (max-width: 767px) {
  .hero__grid {
    grid-template-columns: 1fr;
  }

  .hero__title {
    font-size: clamp(2rem, 6vw, 2.8rem);
    max-width: 23ch;
  }

  .hero__figure img {
    height: auto;
    aspect-ratio: 3 / 2;
  }

  .hero__cta {
    margin-top: 1.5rem;
  }
}

/* ---------- section headers ---------- */
/* A rule over every section head, with a heavier accent stub on it -- the
   printed-page device that makes a page read as set rather than laid out. */
.head {
  position: relative;
  max-width: 40ch;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(1.1rem, 2vw, 1.7rem);
}

.head::before {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  width: 4.5rem;
  height: 3px;
  background: var(--accent);
}

.head p {
  margin-top: 0.9rem;
}

/* ---------- pillars (asymmetric bento, 3 cells) ---------- */
.pillars {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.pillar {
  background: var(--surface);
  padding: clamp(1.75rem, 3vw, 2.75rem);
}

.pillar--lead {
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  position: relative;
  overflow: hidden;
  min-height: 340px;
  padding: clamp(1.75rem, 3vw, 2.75rem);
  background: var(--surface-2);
}

.pillar__motif {
  position: absolute;
  z-index: 0;
  right: -5%;
  top: -6%;
  font-size: clamp(9rem, 22vw, 15rem);
  line-height: 1;
  color: var(--brand);
  opacity: 0.09;
  pointer-events: none;
}

.pillar--lead>*:not(.pillar__motif) {
  position: relative;
  z-index: 2;
}

.pillar__n {
  font-family: var(--font-display);
  font-size: 1.6rem;
  color: var(--accent-text);
  display: block;
  margin-bottom: 0.6rem;
}

.pillar h3 {
  margin-bottom: 0.6rem;
}

.pillar p {
  color: var(--ink-2);
  font-size: 0.96rem;
}

@media (max-width: 820px) {
  .pillars {
    grid-template-columns: 1fr;
  }

  .pillar--lead {
    grid-row: auto;
  }
}

/* ---------- purpose (editorial statement) ---------- */
.purpose {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.purpose h2 {
  max-width: 20ch;
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

.purpose__lead {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.4rem, 3vw, 2.15rem);
  line-height: 1.32;
  color: var(--ink);
  max-width: 36ch;
  padding-left: clamp(1rem, 2vw, 1.5rem);
  border-left: 3px solid var(--accent);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.purpose__cols {
  display: grid;
  gap: 1rem;
}

.purpose__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}

.purpose__figure {
  margin: 0;
}

.purpose__content {
  min-width: 0;
}

.purpose__cols p {
  color: var(--ink-2);
  font-size: 1.02rem;
  max-width: 46ch;
  margin: 0;
}

@media (max-width: 760px) {
  .purpose__cols {
    grid-template-columns: 1fr;
  }
}

/* ---------- feature band ---------- */
.band {
  background: var(--surface);
  border-block: 1px solid var(--line-soft);
}

/* ---------- cards ---------- */
/* Course index, modernist: no card box. The poster carries the weight, the type
   sits under it on the page ground, and a hairline separates the meta line.
   Columns are sized by content width, not by a fixed count -- two courses no
   longer stretch to half the page each. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: clamp(1.75rem, 3vw, 2.75rem) clamp(1.25rem, 2.5vw, 2rem);
}

.card {
  background: none;
  border: 0;
  border-radius: 0;
  display: flex;
  flex-direction: column;
}

.card>a {
  display: block;
}

.card .poster {
  transition: opacity 0.3s var(--ease);
}

.card:hover .poster,
.card:focus-within .poster {
  opacity: 0.86;
}

.card__body {
  padding: 0.95rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
}

.card__body h3 {
  font-size: 1.1rem;
  line-height: 1.25;
}

.card__body h3 a {
  color: inherit;
  text-decoration: none;
}

.card__body h3 a:hover {
  color: var(--accent-text);
}

.card__body p {
  font-size: 0.9rem;
  color: var(--ink-2);
}

.card__foot {
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.8rem;
  color: var(--ink-3);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.card--empty {
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 2rem 1.5rem;
  color: var(--ink-3);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}

.card--empty i {
  font-size: 1.7rem;
  color: var(--ink-3);
  margin-bottom: 0.5rem;
}

.meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
  font-size: 0.9rem;
  color: var(--ink-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.meta li {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.meta i {
  color: var(--accent-text);
  font-size: 1.05rem;
}

/* ---------- syllabus (module tree) ---------- */
.syllabus {
  display: grid;
  gap: 1rem;
}

.module {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.module>summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.25rem;
  padding: clamp(1.2rem, 2.5vw, 1.75rem);
  transition: background-color 0.25s var(--ease);
}

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

.module>summary:hover {
  background: var(--surface-2);
}

.module__n {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--accent-text);
  min-width: 2.2rem;
}

.module__t h3 {
  margin-bottom: 0.25rem;
}

.module__t p {
  font-size: 0.93rem;
  color: var(--ink-2);
  margin: 0;
}

.module__chev {
  color: var(--ink-3);
  font-size: 1.4rem;
  transition: transform 0.3s var(--ease);
}

.module[open] .module__chev {
  transform: rotate(180deg);
}

.module__units {
  border-top: 1px solid var(--line-soft);
  padding: 0.5rem 0;
}

.unit {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.25rem;
  padding: 1.1rem clamp(1.2rem, 2.5vw, 1.75rem);
}

.unit+.unit {
  border-top: 1px solid var(--line-soft);
}

.unit__i {
  color: var(--brand);
  font-size: 1.15rem;
  padding-top: 0.15rem;
}

.unit h4 {
  font-family: var(--font-ui);
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.3rem;
}

.unit p {
  font-size: 0.92rem;
  color: var(--ink-2);
  margin: 0 0 0.6rem;
}

.unit ul {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--ink-3);
  font-size: 0.88rem;
}

.unit li {
  margin-bottom: 0.2rem;
}

@media (max-width: 620px) {
  .module>summary {
    grid-template-columns: auto 1fr;
    gap: 0.9rem;
  }

  .module__chev {
    grid-column: 2;
    justify-self: end;
    margin-top: -1.6rem;
  }
}

/* ---------- course detail ---------- */
.chero {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

.chero__grid {
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.chero .poster {
  aspect-ratio: 3 / 2;
}

.crumb {
  font-size: 0.88rem;
  color: var(--ink-3);
  margin-bottom: 1rem;
}

.crumb a {
  color: var(--ink-2);
  text-decoration: none;
}

.crumb a:hover {
  color: var(--accent-text);
}

@media (max-width: 900px) {
  .chero__grid {
    grid-template-columns: 1fr;
  }
}

.split {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}

@media (max-width: 900px) {
  .split {
    grid-template-columns: 1fr;
  }
}

.aside {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.6rem;
  position: sticky;
  top: calc(var(--nav-h) + 1.5rem);
}

.aside h3 {
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 1rem;
}

.aside dl {
  margin: 0 0 1.4rem;
  display: grid;
  gap: 0.85rem;
}

.aside dt {
  font-size: 0.8rem;
  color: var(--ink-3);
}

.aside dd {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 500;
}

@media (max-width: 900px) {
  .aside {
    position: static;
  }
}

/* ---------- outcomes ---------- */
.outcomes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.5rem 2.5rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.outcomes li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.85rem;
  font-size: 0.96rem;
  color: var(--ink-2);
}

.outcomes i {
  color: var(--brand);
  font-size: 1.2rem;
}

/* ---------- method rows ---------- */
.method {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}

.method__row {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: clamp(1rem, 4vw, 3rem);
  padding-block: clamp(1.6rem, 3vw, 2.4rem);
  border-bottom: 1px solid var(--line);
}

.method__row p {
  color: var(--ink-2);
  margin: 0;
}

@media (max-width: 760px) {
  .method__row {
    grid-template-columns: 1fr;
    gap: 0.6rem;
  }
}

/* ---------- projects ---------- */
.project {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform 0.35s var(--ease), border-color 0.3s var(--ease), box-shadow 0.35s var(--ease);
}

.project:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 20px 45px var(--shade);
}

.project {
  border-top: 2px solid var(--accent);
}

.project__body {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  flex: 1;
}

.project__body p {
  font-size: 0.93rem;
  color: var(--ink-2);
}

.project__by {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 999px;
  flex: none;
  background: var(--accent);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  font-size: 0.8rem;
  font-weight: 700;
}

.project__by strong {
  font-size: 0.9rem;
  font-weight: 600;
  display: block;
}

.project__by span {
  font-size: 0.8rem;
  color: var(--ink-3);
}

/* ---------- cta ---------- */
.cta {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(2.5rem, 6vw, 4.5rem);
  text-align: center;
}

.cta p {
  margin-inline: auto;
  color: var(--ink-2);
}

.cta__row {
  display: flex;
  gap: 0.85rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 1.8rem;
}

/* One column: every field runs the full width. Fields are divs on purpose --
   `.cta p` centres and shrinks any paragraph in here. */
.form {
  max-width: 38rem;
  margin-inline: auto;
  margin-top: 2.25rem;
  text-align: left;
  display: grid;
  gap: 1.3rem;
}

.field {
  display: grid;
  align-content: start;
  gap: 0.45rem;
  margin: 0;
  min-width: 0;
  max-width: none;
}

.field label {
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.field input,
.field select,
.field textarea {
  font: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  width: 100%;
  min-width: 0;
  height: auto;
  transition: border-color 0.25s var(--ease);
}

.field ::placeholder {
  color: var(--ink-3);
  opacity: 1;
}

.field select {
  appearance: none;
  cursor: pointer;
  padding-right: 2.2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%), linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: right 1.05rem center, right 0.8rem center;
  background-size: 5px 5px;
  background-repeat: no-repeat;
}

.field textarea {
  resize: vertical;
  min-height: 8.5rem;
  line-height: 1.6;
}

.field input:hover,
.field select:hover,
.field textarea:hover,
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--accent);
}

.field [aria-invalid="true"] {
  border-color: var(--brand);
}

.field__hint,
.field__err {
  font-size: 0.78rem;
  line-height: 1.45;
}

.field__hint {
  color: var(--ink-3);
}

.field__err {
  color: var(--brand-2);
}

.field__err:empty {
  display: none;
}

.form .cta__row {
  margin-top: 0.4rem;
}

.form .form__note {
  margin: 0;
  max-width: none;
  font-size: 0.88rem;
  color: var(--ink-2);
}

/* ---------- glass ----------
   Frosted only where blur is actually supported; without it the panels stay
   opaque rather than turning into low-contrast washes. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {

  .nav,
  .cta,
  .aside,
  .module,
  .showcase {
    background: var(--glass);
    -webkit-backdrop-filter: blur(14px) saturate(118%);
    backdrop-filter: blur(14px) saturate(118%);
  }

  .cta,
  .aside,
  .module {
    border-color: var(--glass-line);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--surface) 55%, transparent) inset,
      0 18px 40px -28px var(--shade);
  }

  /* form controls sit on glass, so they lighten to match instead of punching holes */
  .field input,
  .field select,
  .field textarea {
    background-color: color-mix(in srgb, var(--surface) 72%, transparent);
  }
}

/* ---------- blogs ----------
   An index of rules, not cards: date in the margin, the piece beside it. Same
   editorial device as the course heads, so the two pages read as one site. */
.posts {
  display: grid;
  border-top: 1px solid var(--line);
}

.posts:has(.card--empty) {
  border-top: 0;
}

.post-row {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr);
  gap: clamp(0.75rem, 3vw, 2.5rem);
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--line);
  margin: 0;
}

.post-row__date {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: 0.35rem;
}

.post-row h2 {
  font-size: clamp(1.3rem, 2.2vw, 1.75rem);
  margin-bottom: 0.55rem;
}

.post-row h2 a {
  color: inherit;
  text-decoration: none;
}

.post-row h2 a:hover {
  color: var(--accent-text);
}

.post-row p {
  color: var(--ink-2);
  font-size: 0.97rem;
  margin: 0;
  max-width: 62ch;
}

.post-row__meta {
  margin-top: 0.7rem;
  font-size: 0.85rem;
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

@media (max-width: 700px) {
  .post-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.45rem;
  }

  .post-row__date {
    padding-top: 0;
  }
}

.post {
  max-width: var(--measure);
}

.post .head {
  max-width: none;
}

.post .post-row__meta {
  margin-top: 0.9rem;
}

.post__body p {
  color: var(--ink-2);
  margin: 0 0 1.2rem;
}

.post__body p:last-child {
  margin-bottom: 0;
}

.post__more {
  margin-top: clamp(3rem, 6vw, 4.5rem);
}

.post__more .showcase__sub {
  margin-bottom: 0.4rem;
}

/* ---------- back to top ----------
   Square, per the radius rule. Hidden with visibility so it leaves the tab
   order entirely rather than sitting invisible and focusable. */
.to-top {
  position: fixed;
  z-index: 60;
  right: clamp(1rem, 3vw, 2.25rem);
  bottom: clamp(1rem, 3vw, 2.25rem);
  width: 2.9rem;
  height: 2.9rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 12px 28px -12px var(--shade);
  visibility: hidden;
  opacity: 0;
  translate: 0 8px;
  transition: opacity 0.3s var(--ease), translate 0.3s var(--ease),
    background-color 0.25s var(--ease), visibility 0s linear 0.3s;
}

.to-top.is-on {
  visibility: visible;
  opacity: 1;
  translate: 0;
  transition-delay: 0s;
}

.to-top:hover {
  background: color-mix(in srgb, var(--accent) 82%, #fff);
}

.to-top i {
  font-size: 1.15rem;
}

/* ---------- footer ---------- */
.foot {
  border-top: 1px solid var(--line);
  padding-block: 3rem 2rem;
  margin-top: var(--section-y);
}

.foot__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 2rem;
}

.foot h4 {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.9rem;
}

.foot ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.foot a {
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.93rem;
}

.foot a:hover {
  color: var(--accent-text);
}

.foot__bar {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.85rem;
  color: var(--ink-3);
}

@media (max-width: 760px) {
  .foot__grid {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
}

/* ---------- featured project ----------
   Case-study order: the student's work leads, the prose explains it.
   Everything resolves through the theme tokens. */
.showcase {
  background: var(--surface);
  color: var(--ink);
  border-block: 1px solid var(--line);
  padding-block: clamp(3.5rem, 8vw, 6rem);
}

.showcase__inner {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
}

.showcase__head {
  display: grid;
  gap: 0.6rem;
  max-width: 46ch;
}

.showcase__eyebrow {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0;
}

.showcase__title {
  font-size: clamp(2rem, 4.5vw, 3.2rem);
  margin: 0;
  color: var(--ink);
}

.showcase__by {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-2);
}

.showcase__by .avatar {
  background: var(--accent);
  color: var(--accent-ink);
}

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

/* the drawings, at a size worth looking at: the reason the section exists */
.plates {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.plates:not(:has(.plate:not([hidden]))) {
  display: none;
}

/* nothing added yet */
.plate {
  margin: 0;
  display: grid;
  gap: 0.85rem;
}

.plate[hidden] {
  display: none;
}

.plate__open {
  position: relative;
  padding: 0;
  display: block;
  line-height: 0;
  cursor: zoom-in;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}

.plate__open:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--brand) 60%, transparent);
  box-shadow: 0 18px 40px var(--shade);
}

.plate__open img {
  width: 100%;
  height: auto;
  display: block;
}

.plate__zoom {
  position: absolute;
  right: 0.8rem;
  bottom: 0.8rem;
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 1rem;
  opacity: 0;
  transition: opacity 0.25s var(--ease);
}

.plate__open:hover .plate__zoom,
.plate__open:focus-visible .plate__zoom {
  opacity: 1;
}

.plate figcaption {
  font-size: 0.88rem;
  color: var(--ink-2);
  line-height: 1.55;
  max-width: 52ch;
}

.plate__n {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.3rem;
}

.showcase__text {
  max-width: var(--measure);
}

.showcase__text p {
  color: var(--ink-2);
  margin: 0 0 1rem;
}

.showcase__text p:last-child {
  margin-bottom: 0;
}

.showcase__text>p:first-of-type::first-letter,
.purpose__cols>p:first-of-type::first-letter,
.post__body>p:first-of-type::first-letter {
  float: left;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 3.2em;
  line-height: 0.8;
  color: var(--ink);
  padding: 0.08em 0.1em 0 0;
}

/* the video is support material, not the headline */
.showcase__watch {
  display: grid;
  gap: 0.9rem;
}

.showcase__sub {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0;
}

.player {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 720px;
  margin: 0;
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  background: var(--surface-2);
  border: 1px solid var(--line);
}

.player__play {
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  cursor: pointer;
  padding: 0.9rem 1.5rem;
  border: none;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font: inherit;
  font-weight: 700;
  font-size: 1rem;
  box-shadow: 0 14px 34px var(--shade);
  transition: transform 0.25s var(--ease), background-color 0.25s var(--ease);
}

.player:hover .player__play {
  transform: scale(1.05);
  background: color-mix(in srgb, var(--accent) 82%, #fff);
}

.player__play i {
  font-size: 1.2rem;
}

.player iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.lightbox {
  border: none;
  padding: 0;
  background: transparent;
  max-width: 94vw;
  max-height: 94vh;
}

.lightbox::backdrop {
  background: color-mix(in srgb, var(--ink) 88%, transparent);
}

.lightbox img {
  display: block;
  max-width: 94vw;
  max-height: 90vh;
  border-radius: var(--radius);
}

.lightbox button {
  position: fixed;
  top: 1.2rem;
  right: 1.4rem;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  cursor: pointer;
  background: var(--surface);
  color: var(--ink);
  font-size: 1.5rem;
  line-height: 1;
}

/* ---------- compass loader ----------
   The course and project lists are rendered by JS, so the containers are empty
   until that runs. This stands in: skeleton cards with a compass needle hunting
   for north over them. JS replaces the whole block when it writes the real
   cards, so there is nothing to tear down. */
.loading {
  grid-column: 1 / -1;
  display: grid;
  gap: 1.25rem;
  place-items: center;
  padding-block: clamp(2.5rem, 6vw, 4rem);
}

.loading__label {
  font-size: 0.9rem;
  color: var(--ink-3);
  letter-spacing: 0.02em;
}

.compass {
  position: relative;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
}

.compass::before {
  /* the fixed tick at north */
  content: '';
  position: absolute;
  top: 5px;
  left: 50%;
  translate: -50% 0;
  width: 2px;
  height: 6px;
  border-radius: 1px;
  background: var(--ink-3);
}

.compass::after {
  /* the pivot */
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-3);
}

.compass__needle {
  position: absolute;
  inset: 0;
  animation: compass-hunt 2.4s cubic-bezier(0.5, 0, 0.3, 1) infinite;
}

.compass__needle::before,
.compass__needle::after {
  content: '';
  position: absolute;
  left: 50%;
  translate: -50% 0;
  width: 0;
  border-inline: 4.5px solid transparent;
}

.compass__needle::before {
  top: 9px;
  border-bottom: 20px solid var(--accent);
}

.compass__needle::after {
  bottom: 9px;
  border-top: 20px solid var(--ink-3);
}

/* a needle does not sweep evenly: it overshoots north, swings back, settles */
@keyframes compass-hunt {
  0% {
    rotate: 0deg;
  }

  45% {
    rotate: 400deg;
  }

  62% {
    rotate: 348deg;
  }

  76% {
    rotate: 372deg;
  }

  100% {
    rotate: 720deg;
  }
}

/* the skeleton cards underneath */
.skeleton {
  width: 100%;
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.skeleton__card {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}

.skeleton__poster {
  aspect-ratio: 3 / 2;
}

.skeleton__line {
  height: 0.7rem;
  border-radius: 3px;
  margin: 0.75rem 1.25rem;
}

.skeleton__line:first-of-type {
  width: 45%;
  margin-top: 1.25rem;
}

.skeleton__line:last-of-type {
  width: 70%;
  margin-bottom: 1.4rem;
}

.skeleton__poster,
.skeleton__line {
  background: linear-gradient(100deg, var(--surface-2) 20%, color-mix(in srgb, var(--surface-2) 60%, var(--ink-3)) 40%, var(--surface-2) 60%);
  background-size: 300% 100%;
  animation: skeleton-sweep 1.6s ease-in-out infinite;
}

@keyframes skeleton-sweep {
  to {
    background-position: -150% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .compass__needle {
    animation: none;
    rotate: 24deg;
  }

  .skeleton__poster,
  .skeleton__line {
    animation: none;
  }
}

/* ---------- motion ----------
   Entrance states live inside no-preference on purpose: the global reduce rule
   kills transitions, so an opacity:0 baked into the base style would strand
   content invisible. */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
  }

  .reveal.is-in {
    opacity: 1;
    transform: none;
  }

  /* grid children arrive in sequence rather than as one block */
  .cards>.reveal:nth-child(2),
  .plates>.reveal:nth-child(2),
  .posts>.reveal:nth-child(2),
  .purpose__grid>.reveal:nth-child(2),
  .split>.reveal:nth-child(2),
  .chero__grid>.reveal:nth-child(2) {
    transition-delay: 70ms;
  }

  .cards>.reveal:nth-child(3),
  .posts>.reveal:nth-child(3),
  .syllabus>.reveal:nth-child(2) {
    transition-delay: 140ms;
  }

  .cards>.reveal:nth-child(4),
  .syllabus>.reveal:nth-child(3) {
    transition-delay: 210ms;
  }

  .syllabus>.reveal:nth-child(n+4) {
    transition-delay: 280ms;
  }

  /* the poster drifts up under the pointer */
  .card .poster {
    transition: opacity 0.35s var(--ease), transform 0.5s var(--ease);
  }

  .card:hover .poster,
  .card:focus-within .poster {
    transform: scale(1.012);
  }

  /* Buttons do not move: they answer with the glow set further down. The
     toggle still turns toward its new state. */
  .tag {
    transition: background-color 0.25s var(--ease), color 0.25s var(--ease);
  }

  /* The argument map tells a sequence, so its rail draws before the three
     decisions settle into place. The map remains fully visible without motion. */
  .definition-map.is-in .definition-map__steps::before {
    animation: rail-draw 0.72s var(--ease) 0.12s both;
    transform-origin: top;
  }

  .definition-map.is-in .definition-map__steps li>i {
    animation: step-settle 0.48s var(--ease) both;
  }

  .definition-map.is-in .definition-map__steps li:nth-child(1)>i {
    animation-delay: 0.18s;
  }

  .definition-map.is-in .definition-map__steps li:nth-child(2)>i {
    animation-delay: 0.34s;
  }

  .definition-map.is-in .definition-map__steps li:nth-child(3)>i {
    animation-delay: 0.5s;
  }

  /* Opening a syllabus module reveals its contents from the summary edge. */
  .module[open] .module__units {
    animation: module-open 0.36s var(--ease) both;
    transform-origin: top;
  }

  /* Editorial rows answer the pointer with a small reading-direction shift. */
  .post-row>div {
    transition: transform 0.32s var(--ease);
  }

  .post-row:hover>div,
  .post-row:focus-within>div {
    transform: translateX(5px);
  }

  /* Images move inside their frames; layout and captions remain anchored. */
  .plate__open img {
    transition: transform 0.7s var(--ease);
  }

  .plate__open:hover img,
  .plate__open:focus-visible img {
    transform: scale(1.025);
  }
}

@keyframes rail-draw {
  from {
    transform: scaleY(0);
  }
}

@keyframes step-settle {
  from {
    opacity: 0;
    transform: scale(0.72) rotate(-8deg);
  }
}

@keyframes module-open {
  from {
    opacity: 0;
    transform: scaleY(0.96) translateY(-8px);
  }
}


/* nav underline grows from the left instead of snapping on. Outside the motion
   query so the current-page marker still shows with reduced motion. */
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}

.nav__links a:hover::after,
.nav__links a[aria-current="page"]::after {
  transform: scaleX(1);
}

/* Must follow the rule above, not sit in an earlier media block -- a media query
   adds no specificity, so an earlier override loses on source order. The sliding
   underline is a desktop device: stacked full-width links turned it into rules
   running through the labels below. */
@media (max-width: 760px) {
  .nav__links a::after {
    content: none;
  }
}

/* ---------- course poster ----------
   Portrait poster: dark ground, ghosted motif glyph, title split over two lines
   with a rule beneath. Sized in container query units so the same markup works
   at hero scale and at card scale. Set `poster.image` in data.js to drop a
   photograph in behind the wordmark.
*/
.poster {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  container-type: inline-size;
  aspect-ratio: 4 / 5;
  border: 1px solid rgba(234, 226, 214, 0.22);
  border-radius: var(--radius);
  background: #3b4437;
  /* Flex, not grid align-content: this centres the lockup as one block rather
     than centring its rows, and keeps every line ranged left. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  text-align: left;
  padding: 8cqi;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent);
  --poster-type: 18cqi;
  /* ceiling: 'The Terms' wraps at 19cqi */
}

/* in a card the poster is a thumbnail, not the feature: landscape, half the height.
   Type is in cqi so it rescales with the box; hero + course detail keep 4/5. */
.card .poster {
  aspect-ratio: 3 / 2;
  --poster-type: 23cqi;
}

/* ceiling: 'Foundation' clips at 24cqi */
.poster__motif {
  position: absolute;
  z-index: 0;
  right: -14cqi;
  bottom: -12cqi;
  font-size: 72cqi;
  line-height: 1;
  color: #f7f2eb;
  opacity: 0.1;
  pointer-events: none;
}

.poster>*:not(.poster__motif):not(img) {
  position: relative;
  z-index: 1;
}

.poster__l1,
.poster__l2 {
  font-family: var(--font-ui);
  font-weight: 700;
  text-transform: uppercase;
  /* Fit to the longest word: the cqi ceiling is the design size, the second term
     is what that many caps can actually be without overrunning the plate.
     --poster-ch comes from app.js. 0.46 is the calibration knob: Outfit bold's
     average uppercase advance, measured off 'CRITICAL' fitting at 20cqi and
     rounded up for wider strings. Nudge it up if a title ever still overruns. */
  font-size: min(var(--poster-type), calc(86cqi / var(--poster-ch, 8) / 0.46));
  line-height: 0.94;
  letter-spacing: -0.02em;
  display: block;
  align-self: flex-start;
  max-width: 100%;
}

.poster__l1 {
  color: #fdfbf6;
}

.poster__l2 {
  color: #eae2d6;
}

.poster__rule {
  width: 22cqi;
  height: 0.9cqi;
  background: #eae2d6;
  margin-top: 4cqi;
  flex: none;
}

/* the house name sits above the mark: tracked, quiet, never competing with the title */
.poster__eyebrow {
  font-family: var(--font-ui);
  font-weight: 500;
  text-transform: uppercase;
  font-size: max(10px, 3.4cqi);
  letter-spacing: 0.2em;
  line-height: 1.2;
  color: #eae2d6;
  opacity: 0.85;
  margin-bottom: 3cqi;
  max-width: 100%;
}

.poster img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* Photograph behind the wordmark. Stack, back to front: photo, scrim, type,
   frame. The scrim is what keeps the mark legible over any exposure; the inset
   hairline is what makes it read as a stamped trademark rather than a caption. */
.poster.poster--image {
  /* doubled class on purpose: `.card .poster` above is two classes, so a plain
     .poster--image loses the cascade and the card kept the 23cqi ceiling. */
  aspect-ratio: 3 / 2;
  /* the type runs to the card's own edge; the frame opens on the left to let it */
  padding: 7cqi 7cqi 7cqi 1.5cqi;
  --poster-type:13cqi;
}

/* One card per row on a phone means a much wider plate, so the same cqi reads
   far larger. Pull the ceiling down to keep the lockup the size it looks on the grid. */
@media (max-width: 767px) {
  .poster.poster--image {
    --poster-type: 9cqi;
  }
}

.poster--image::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(175deg, rgba(14, 17, 12, 0.28) 0%, rgba(14, 17, 12, 0.55) 45%, rgba(14, 17, 12, 0.82) 100%);
}

.poster--image::after {
  content: "";
  position: absolute;
  inset: 3.5cqi;
  z-index: 3;
  pointer-events: none;
  border: 1px solid rgba(247, 242, 235, 0.34);
  /* open on the left, so the wordmark sits beside the frame instead of across it */
  border-left: 0;
}

.poster--image>*:not(img) {
  z-index: 2;
}

/* the mark is set tighter and wider-tracked than the plain poster: trademark, not title */
.poster--image .poster__l1,
.poster--image .poster__l2 {
  letter-spacing: 0.01em;
  text-shadow: 0 1px 12px rgba(14, 17, 12, 0.5);
}

.poster--image .poster__rule {
  height: 0.7cqi;
}

.card--empty {
  background: transparent;
  border-color: var(--line);
}

/* The teaching method is a connected visual sequence. */
.learning {
  display: block;
}

.learning .head {
  margin-bottom: 2.5rem;
}

.method {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 0;
  gap: 2.5rem;
}

.method__row {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding-block: 0;
  border-bottom: 0;
}

.method__row p {
  font-size: 0.96rem;
}

.method__graphic {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 3px solid var(--accent);
  padding-top: 1.5rem;
  margin-bottom: 0.75rem;
}

.method__graphic>i:first-child {
  font-size: 4rem;
  color: var(--ink);
}

.method__graphic>i:last-child {
  font-size: 1.7rem;
  color: var(--accent-text);
}

.showcase {
  border-color: var(--line-soft);
}

.foot .brand {
  color: var(--ink);
  font-size: 1.3rem;
}

/* Every grid must fit small phones, including loading and image states. */
@media (max-width: 767px) {

  .cards,
  .learning,
  .plates,
  .purpose__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .purpose__figure {
    order: 1;
  }

  .learning__content {
    min-width: 0;
  }

  .method {
    grid-template-columns: minmax(0, 1fr);
  }

  .method__graphic>.ph-arrow-right {
    transform: rotate(90deg);
  }

  .skeleton {
    grid-template-columns: minmax(0, 1fr);
  }

  .chero__grid,
  .split,
  .outcomes {
    min-width: 0;
  }

  .showcase__by {
    align-items: flex-start;
  }

  .player__play {
    padding: 0.75rem 1rem;
    font-size: 0.88rem;
    white-space: nowrap;
  }
}

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* Artwork and labels form one designed composition; labels remain real text. */
.graphic-art {
  background: #3b4437;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent);
}

.graphic-art img {
  display: block;
  width: 100%;
  height: auto;
}

/* The mark sits on the plate, not on the figure -- the figcaption is a sibling,
   so an overlay on the figure itself would have to dodge it. cqi units mean the
   type tracks the image width at any breakpoint. */
.graphic-art__plate {
  position: relative;
  display: block;
  line-height: 0;
  container-type: inline-size;
}

.graphic-art__plate::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(190deg, rgba(14, 17, 12, 0.22) 0%, rgba(14, 17, 12, 0.5) 48%, rgba(14, 17, 12, 0.8) 100%);
}

.graphic-art__plate::after {
  content: "";
  position: absolute;
  inset: 3cqi;
  z-index: 3;
  pointer-events: none;
  border: 1px solid rgba(247, 242, 235, 0.32);
}

.graphic-art__eyebrow {
  position: absolute;
  left: 7cqi;
  top: 12cqi;
  z-index: 2;
  font-family: var(--font-ui);
  font-weight: 500;
  text-transform: uppercase;
  font-size: max(10px, 2.4cqi);
  letter-spacing: 0.2em;
  line-height: 1.2;
  color: #eae2d6;
  opacity: 0.85;
  text-shadow: 0 1px 14px rgba(14, 17, 12, 0.55);
}

.graphic-art__mark {
  position: absolute;
  left: 7cqi;
  top: 30cqi;
  z-index: 2;
  font-family: var(--font-ui);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 9cqi;
  line-height: 0.95;
  letter-spacing: 0.01em;
  color: #fdfbf6;
  text-shadow: 0 1px 14px rgba(14, 17, 12, 0.55);
}

.graphic-art figcaption {
  margin: 0;
  padding: 1rem 1.4rem;
  border-top: 1px solid #4c5646;
  color: #f7f2eb;
  font-size: 0.92rem;
  font-weight: 600;
}

.pillar__symbol {
  display: block;
  font-size: 2.7rem;
  color: var(--accent-text);
  margin-bottom: 1.2rem;
}

.pillar__motif {
  opacity: 0.13;
}

/* A labelled argument diagram communicates what the academy teaches. */
.definition-map {
  padding: clamp(1.4rem, 3vw, 2.2rem);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.definition-map>figcaption {
  color: var(--ink);
  font-weight: 600;
  font-size: 0.96rem;
  margin-bottom: 1.8rem;
}

.definition-map__steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 1.7rem;
  position: relative;
}

/* One rail for the whole sequence rather than a stub per row: rows differ in
   height, so fixed-height stubs cannot reach between centred tiles. The inset
   ends the rail behind the first and last tile, which are opaque. */
.definition-map__steps::before {
  content: "";
  position: absolute;
  left: 23px;
  top: 24px;
  bottom: 24px;
  border-left: 2px solid var(--accent);
}

.definition-map__steps li {
  position: relative;
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 1rem;
  /* centre, not start: step two carries an extra line, so a top-pinned tile
     drifts away from the text it labels. */
  align-items: center;
}

.definition-map__steps li>i {
  position: relative;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 1.6rem;
  border-radius: var(--radius);
}

.definition-map__steps span {
  display: block;
  color: var(--ink-3);
  font-size: 0.8rem;
  margin-bottom: 0.3rem;
}

.definition-map__steps strong {
  display: block;
  color: var(--ink);
  font-size: clamp(1.05rem, 1.8vw, 1.4rem);
  line-height: 1.3;
}

.definition-map__steps p {
  color: var(--ink-2);
  font-size: 0.88rem;
  margin-top: 0.5rem;
}

@media (max-width: 767px) {
  .definition-map {
    padding: 1.25rem;
  }

  .definition-map__steps li {
    grid-template-columns: 42px 1fr;
    gap: 0.8rem;
  }

  .definition-map__steps li>i {
    width: 42px;
    height: 42px;
  }

  .definition-map__steps::before {
    left: 20px;
    top: 21px;
    bottom: 21px;
  }
}
/* ---------- shared modifiers ----------
   These replace what used to be inline style attributes in the markup and in
   the rendered templates, so every visual decision lives in this file. */
.wrap--centred {
  text-align: center;
}

.head--narrow {
  max-width: 46ch;
}

.head--full {
  max-width: none;
}

.section__sub {
  font-size: clamp(1.4rem, 2.4vw, 1.8rem);
  margin-bottom: 1.25rem;
}

.section__sub--spaced {
  margin: 3rem 0 1.5rem;
}

.chero__title {
  margin: 0.9rem 0 1.1rem;
}

.notfound__lead {
  margin: 1rem auto 2rem;
}

.cta__lead {
  max-width: 52ch;
}

.card--empty__title {
  font-family: var(--font-ui);
  font-size: 1rem;
}

.card--empty__text {
  font-size: 0.9rem;
}

.btn--block {
  width: 100%;
  justify-content: center;
}

.aside__text {
  font-size: 0.9rem;
  color: var(--ink-2);
  margin-bottom: 1.2rem;
}

.aside .btn--block {
  margin-bottom: 1.5rem;
}

.foot__blurb {
  margin-top: 0.9rem;
  color: var(--ink-2);
  font-size: 0.93rem;
  max-width: 34ch;
}

.cta__row--centred {
  justify-content: center;
}

/* ---------- contact form card ----------
   The form is the page's main object here, so it sits on its own surface and
   fills its column rather than keeping the narrow centred measure. */
.form-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.4rem, 3vw, 2.4rem);
  box-shadow: 0 1px 3px var(--line-soft);
}

.form-card .form {
  max-width: none;
  margin-top: 0;
}

@media (max-width: 900px) {
  .form-card {
    padding: 1.25rem;
  }
}

/* ---------- motion ----------
   Everything here is inside no-preference: the reduce rule elsewhere must be
   able to strip motion without leaving content stranded invisible. */
@media (prefers-reduced-motion: no-preference) {

  /* the hero arrives in reading order rather than all at once */
  .hero__title,
  .hero .lede,
  .hero__cta {
    animation: rise-in 0.7s var(--ease) both;
  }

  .hero .lede {
    animation-delay: 90ms;
  }

  .hero__cta {
    animation-delay: 180ms;
  }

  /* the bar lifts off the page once you leave the top of it */
  .nav {
    transition: box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
  }

  .nav.is-stuck {
    box-shadow: 0 1px 20px var(--shade);
    border-bottom-color: var(--line);
  }

  /* sequenced, like the course cards above */
  .pillars>.reveal:nth-child(2),
  .method>.reveal:nth-child(2) {
    transition-delay: 80ms;
  }

  .pillars>.reveal:nth-child(3),
  .method>.reveal:nth-child(3) {
    transition-delay: 160ms;
  }

  /* the accordion opens and closes on the same curve as its chevron */
  .module__chev {
    transition: transform 0.3s var(--ease);
  }

  .module>summary {
    transition: background-color 0.25s var(--ease);
  }

  .field input,
  .field textarea,
  .field select {
    transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
  }

  .field input:focus,
  .field textarea:focus {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

/* A section that follows a page's intro heading: the intro's bottom padding
   already provides the gap, so a second one doubles it. */
.section--flush {
  padding-top: 0;
}

/* ---------- legal pages ----------
   Privacy policy and terms. Long prose that has to be *read*, so: one column
   at the text measure, headings that mark structure plainly, and none of the
   editorial flourishes the blog gets -- no drop cap, no reveal animation.
   Transparency is the brief here: concise, clear, plain language, and not a
   wall of grey that nobody reads. */
.legal {
  max-width: var(--measure);
}

.legal__updated {
  font-family: var(--font-ui);
  font-size: 0.86rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 2.5rem;
}

.legal h2 {
  font-size: clamp(1.3rem, 2.4vw, 1.6rem);
  margin: 3rem 0 0.9rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line-soft);
}

.legal h2:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.legal h3 {
  font-family: var(--font-ui);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--ink);
  margin: 1.8rem 0 0.5rem;
}

.legal p,
.legal li {
  color: var(--ink-2);
}

.legal p {
  margin: 0 0 1.1rem;
}

.legal ul {
  margin: 0 0 1.1rem;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.5rem;
}

.legal li::marker {
  color: var(--accent-text);
}

/* Each processing purpose as a term and its detail: what, why, on what basis,
   for how long. A definition list, because that is exactly what this is. */
.legal dl {
  margin: 0 0 1.4rem;
  display: grid;
  gap: 0.9rem;
}

.legal dl > div {
  display: grid;
  grid-template-columns: minmax(9rem, 12rem) 1fr;
  gap: 0.3rem 1.4rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--line-soft);
}

.legal dl > div:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.legal dt {
  font-family: var(--font-ui);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: 0.15em;
}

.legal dd {
  margin: 0;
  color: var(--ink-2);
}

@media (max-width: 620px) {
  .legal dl > div {
    grid-template-columns: 1fr;
    gap: 0.15rem;
  }
}

/* The bottom bar now carries the legal links beside the copyright. Wrapping,
   not a fixed row: on a narrow screen they drop under it rather than squeeze. */
.foot__bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem 1.5rem;
}

.foot__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
}

.foot__legal a {
  color: var(--ink-3);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.foot__legal a:hover,
.foot__legal a:focus-visible {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

/* The data-protection line under the enquiry fields. Quiet, but present at the
   moment the data is actually handed over, which is where Article 13 wants it. */
.form__privacy {
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--ink-3);
  margin: 0 0 1.4rem;
}

.form__privacy a {
  color: var(--accent-text);
}

/* ---------- nav: log in, and where the theme control sits ----------
   Order in the bar is links / log in / theme, the theme control last because
   it is a setting rather than a destination. On a narrow screen there is no
   room for it there, so initNav moves the same button into the menu panel. */
.nav__login {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55rem 1rem;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

.nav__login i {
  font-size: 1.05em;
}

/* The row the theme button occupies once it is inside the menu. It is not a
   link, so .nav__links a does not reach it and it says so itself. */
.nav__theme-row {
  display: block;
}

.nav__theme-row .theme-toggle {
  width: 100%;
  height: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 1rem 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* the label is a screen-reader affordance in the bar, and visible in the menu */
.nav__theme-row .theme-toggle__label {
  position: static;
  width: auto;
  height: auto;
  margin: 0;
  clip: auto;
  clip-path: none;
  overflow: visible;
  white-space: normal;
}

@media (max-width: 420px) {
  /* the glyph carries it once the bar gets tight */
  .nav__login span {
    display: none;
  }

  .nav__login {
    padding: 0.55rem 0.7rem;
  }
}

/* ---------- depth, applied ----------
   Home page first. Three things are lifted and one is deliberately not: the
   lead pillar stays recessed on its darker ground, so the row has a near and
   a far surface rather than everything floating at once. */

/* The hero plate is the page's anchor, so it sits highest. The inset hairline
   is kept -- it is what makes the art read as a stamped plate. */
.hero__figure {
  border-radius: var(--radius);
  box-shadow:
    var(--lift-3),
    inset 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent);
}

/* The reasoning diagram is a card on the desk, not a panel in the page. */
.definition-map {
  background: var(--surface);
  box-shadow: var(--lift-2), var(--sheen);
}

.pillars {
  box-shadow: var(--lift-2), var(--sheen);
}

/* Course posters rise a little when pointed at. The shadow sits on the link
   rather than the poster itself, which already owns its own transition. */
.card>a {
  border-radius: var(--radius);
  box-shadow: var(--lift-1);
  transition: box-shadow 0.35s var(--ease);
}

.card:hover>a,
.card:focus-within>a {
  box-shadow: var(--lift-2);
}

@media (prefers-reduced-motion: reduce) {
  .card>a { transition: none; }
}

/* Headings carry the relief; body copy stays flat and crisp. The larger the
   type, the more depth it holds before the strokes begin to close up, so the
   display sizes take the full shadow and the subheadings a shallower one. */
h1,
h2 {
  text-shadow: var(--type-relief);
}

h3,
h4,
.eyebrow,
.showcase__sub,
.section__sub {
  text-shadow: var(--type-relief-soft);
}

/* Artwork already carries its own shadow for legibility, and a second one over
   it only smears. :where() keeps this at zero specificity, so a component's
   own shadow still wins. */
:where(.poster, .graphic-art) :where(*) {
  text-shadow: none;
}

/* ---------- buttons: pressed, not recoloured ----------
   A shade of background change is easy to miss, and on the dark theme it was
   almost invisible. These answer the pointer by moving instead: the button
   rises a little under the cursor and goes down under the click, which is the
   one signal nobody has to look twice at. Colour still shifts, but it is now
   the second cue rather than the only one. */
.btn {
  transition:
    box-shadow 0.22s var(--ease),
    background-color 0.25s var(--ease),
    border-color 0.25s var(--ease),
    color 0.25s var(--ease);
}

/* The button stays put and throws light instead. */
.btn:hover {
  box-shadow: var(--btn-glow);
}

/* Under the finger the glow goes in, so a click still reads as a press. */
.btn:active {
  box-shadow: inset 0 2px 5px color-mix(in srgb, var(--shade) 85%, transparent);
  transition-duration: 0.06s;
}

/* The filled button takes the paper tone in the dark theme, where sage on a
   near-black ground reads as a dim patch rather than a control. */
.btn--solid,
.nav__login {
  background: var(--highlight);
  color: var(--highlight-ink);
  border-color: transparent;
}

.btn--solid:hover,
.nav__login:hover {
  background: color-mix(in srgb, var(--highlight) 86%, #fff);
  color: var(--highlight-ink);
}

/* The outlined button fills on hover, so the change is a surface appearing
   rather than a border changing colour by a shade. */
.btn--line:hover {
  background: var(--surface);
  border-color: var(--highlight);
  color: var(--ink);
}

/* The nav underline is the same mark as the filled button, so it takes the
   same colour in both themes. */
.nav__links a::after {
  background: var(--highlight);
}
