/* ==========================================================================
   St. Michael Academy
   Palette drawn from the school crest (navy + gold) with a brick accent
   sampled from the main hall's masonry.
   ========================================================================== */

/* ── Tokens ──────────────────────────────────────────────────────────────── */
:root {
  /* Brand */
  --ink:         #14243F;
  --ink-deep:    #0B1526;
  --ink-soft:    #263A5C;
  --gold:        #C8A25C;
  --gold-bright: #DDBC7E;
  --brick:       #9A4B34;
  --brick-deep:  #7C3A27;

  /* Surfaces & text */
  --parchment:   #F8F5EF;
  --stone:       #EDE7DB;
  --stone-line:  #DAD1C0;
  --body:        #3A352E;
  --body-muted:  #6A6257;

  /* Semantic roles */
  --page-bg:     var(--parchment);
  --page-fg:     var(--body);
  --page-muted:  var(--body-muted);
  --surface:     #FFFFFF;
  --rule:        var(--stone-line);
  --heading:     var(--ink);
  --accent:      var(--brick);
  --accent-fg:   #FFFFFF;

  /* Type */
  --display: "Fraunces", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --text:    "Karla", "Segoe UI", system-ui, -apple-system, sans-serif;

  --step--1: clamp(0.83rem, 0.80rem + 0.14vw, 0.90rem);
  --step-0:  clamp(1.00rem, 0.96rem + 0.20vw, 1.13rem);
  --step-1:  clamp(1.20rem, 1.12rem + 0.40vw, 1.45rem);
  --step-2:  clamp(1.45rem, 1.30rem + 0.75vw, 1.95rem);
  --step-3:  clamp(1.80rem, 1.50rem + 1.50vw, 2.75rem);
  --step-4:  clamp(2.20rem, 1.60rem + 3.00vw, 4.25rem);

  /* Space — 4/8 rhythm */
  --s-1: 0.5rem;  --s-2: 0.75rem; --s-3: 1rem;   --s-4: 1.5rem;
  --s-5: 2rem;    --s-6: 3rem;    --s-7: 4rem;   --s-8: 6rem;

  --measure: 66ch;
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --container: 76rem;

  --radius: 3px;
  --dur: 240ms;
  --ease: cubic-bezier(0.33, 0.9, 0.3, 1);

  /* Form fields: a navy-tinted rule around a crisp white well. */
  --field-bg: #FFFFFF;
  --field-border: rgba(20, 36, 63, 0.28);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --page-bg:    #0E1826;
    --page-fg:    #DED8CC;
    --page-muted: #9C9486;
    --surface:    #16233A;
    --rule:       #2A3A56;
    --stone:      #142033;
    --heading:    #F0EADF;
    --accent:     #D98B6E;
    --accent-fg:  #1A0F0A;
    /* A white field would glare here, so the well goes darker than the page
       and the navy rule inverts to a light one to stay visible. */
    --field-bg:     #0A1220;
    --field-border: rgba(190, 208, 236, 0.26);
  }
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--page-bg);
  color: var(--page-fg);
  font-family: var(--text);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--display);
  color: var(--heading);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.012em;
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; overflow-wrap: anywhere; }
img { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

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

.skip-link {
  position: absolute; left: var(--s-3); top: var(--s-3);
  z-index: 200; transform: translateY(-200%);
  background: var(--ink); color: #fff;
  padding: var(--s-2) var(--s-4);
  font-weight: 600; text-decoration: none; border-radius: var(--radius);
}
.skip-link:focus-visible { transform: translateY(0); }

/* Available to screen readers, absent from the visual layout. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Layout helpers ──────────────────────────────────────────────────────── */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--narrow { max-width: 52rem; }

.section { padding-block: clamp(3.5rem, 9vw, 7rem); }

.section__head { max-width: 46rem; margin-bottom: var(--s-6); }
.section__title { font-size: var(--step-3); margin-bottom: var(--s-3); }
.section__standfirst {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--page-muted);
  max-width: 42ch;
}
.ital { font-style: italic; font-variation-settings: "SOFT" 40; }

/* Rubric — the small ruled label that opens each section.
   Sentence case on purpose: tracked-out all-caps is the house style of every
   generated page, and this one has a crest to do the formality. */
.rubric {
  font-family: var(--display);
  font-size: var(--step--1);
  font-weight: 600;
  font-style: italic;
  letter-spacing: 0.01em;
  color: var(--accent);
  margin-bottom: var(--s-3);
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.rubric::after {
  content: ""; flex: 1 1 auto; height: 1px; max-width: 5rem;
  background: currentColor; opacity: 0.35;
}
.rubric--gold { color: var(--gold); }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px;
  padding: 0.7rem 1.5rem;
  font-family: var(--text);
  font-size: var(--step-0);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform 0.2s ease,
              box-shadow 0.2s ease;
}
.btn--gold {
  background: var(--gold);
  color: #23180A;
  border-color: var(--gold);
}
.btn--ghost {
  background: transparent;
  color: #F3EEE4;
  border-color: rgba(200, 162, 92, 0.55);
}

/* Lift on hover, press on click. The hover half is gated behind a real
   pointer: on a touch screen :hover latches after a tap and the button would
   sit there raised until something else is touched. */
@media (hover: hover) {
  .btn:hover { transform: scale(1.02); }
  .btn--gold:hover {
    background: var(--gold-bright);
    border-color: var(--gold-bright);
    box-shadow: 0 6px 20px rgba(200, 162, 92, 0.35);
  }
  .btn--ghost:hover {
    border-color: var(--gold);
    background: rgba(200, 162, 92, 0.12);
    box-shadow: 0 6px 20px rgba(6, 13, 26, 0.45);
  }
}

/* Keyboard users get the same elevation the mouse gets, alongside the ring. */
.btn--gold:focus-visible { box-shadow: 0 6px 20px rgba(200, 162, 92, 0.35); }
.btn--ghost:focus-visible { box-shadow: 0 6px 20px rgba(6, 13, 26, 0.45); }

/* Declared after the hover block so it wins at equal specificity: pressing
   settles the button back down rather than leaving it raised. */
.btn:active {
  transform: scale(0.98);
  box-shadow: none;
}

/* ── Notice bar ──────────────────────────────────────────────────────────── */
.notice {
  background: var(--ink-deep);
  color: #E8E1D2;
  font-size: var(--step--1);
  border-bottom: 1px solid rgba(200, 162, 92, 0.28);
}
.notice[hidden] { display: none !important; }
.notice__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: 0.6rem var(--gutter);
  display: flex; align-items: center; gap: var(--s-3);
}
.notice__tag {
  font-family: var(--display);
  font-style: italic;
  font-weight: 600;
  color: var(--gold);
  flex: none;
}
.notice__text { flex: 1 1 auto; min-width: 0; }
/* 44px hit area; the visible hover disc is drawn smaller via ::before so the
   target can meet the minimum without looking oversized. */
.notice__close {
  flex: none;
  position: relative;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  background: transparent; border: 0;
  color: #C9C1B2; cursor: pointer;
  transition: color var(--dur) var(--ease);
}
.notice__close::before {
  content: ""; position: absolute; inset: 6px;
  border-radius: 50%; background: transparent;
  transition: background-color var(--dur) var(--ease);
}
.notice__close svg { position: relative; }
.notice__close:hover { color: #fff; }
.notice__close:hover::before { background: rgba(255, 255, 255, 0.12); }

/* ── Masthead ────────────────────────────────────────────────────────────── */
.masthead {
  position: sticky; top: 0; z-index: 100;
  background: var(--ink);
  border-bottom: 1px solid rgba(200, 162, 92, 0.3);
}
.masthead__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--s-2) var(--gutter);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
}

/* The crest is navy-and-gold artwork on a white ground, so it cannot sit
   directly on navy chrome — the mount stays. But it is a padded plaque, not a
   circular mask: a roundel crops the scrollwork, laurel tips and ribbon tails,
   which is most of what makes the device worth showing.
   The source is pre-cropped to the device (assets/crest-device.jpg) so the
   wordmark beneath it is not reduced to mush beside the text that repeats it. */
/* Circular badge. Padding can be this tight because the asset was rebuilt for
   it: crest-device.jpg is a square centred on the crest's own enclosing circle
   (radius 792 in an 1648px square), with the wordmark masked out. The ink
   therefore reaches only 0.481 of the box, so it stays inside the circular clip
   at any padding — the earlier 8px was compensating for white margin baked into
   the file rather than for the mask. */
.badge {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3px;
  background: #FFFFFF;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(200, 162, 92, 0.85);
}
.badge img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* The masthead is sticky. At the full 80px the bar stands 104px tall on every
   screen; 68px holds it to 80px while still showing a larger crest than before.
   Padding stays 3px — the clearance scales with the badge. */
.badge--sm { width: 68px; height: 68px; }
.badge--lg { margin-bottom: var(--s-4); }

.brand { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; }
.brand__text { display: flex; flex-direction: column; line-height: 1.15; }
.brand__name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  color: #F5F1E8;
}
.brand__motto {
  font-family: var(--display);
  font-style: italic;
  font-size: 0.74rem;
  color: var(--gold);
}

/* Nav — mobile panel first */
.nav-toggle {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: 44px; padding: 0.5rem 0.75rem;
  background: transparent;
  border: 1px solid rgba(200,162,92,0.4);
  border-radius: var(--radius);
  color: #F0EADF; font-family: var(--text); font-size: 0.9rem; font-weight: 600;
  cursor: pointer;
}
.nav-toggle__bars { display: grid; gap: 4px; width: 18px; }
.nav-toggle__bars i {
  display: block; height: 2px; background: currentColor; border-radius: 2px;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav {
  position: absolute; inset: 100% 0 auto 0;
  background: var(--ink-deep);
  border-bottom: 1px solid rgba(200,162,92,0.3);
  padding: var(--s-3) var(--gutter) var(--s-5);
  display: none;
}
.nav.is-open { display: block; }

.nav__list { list-style: none; margin: 0 0 var(--s-4); padding: 0; }
.nav__list a {
  display: block;
  padding: 0.85rem 0;
  min-height: 44px;
  font-weight: 500;
  color: #E4DDCE;
  text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  transition: color var(--dur) var(--ease);
}
.nav__list a:hover { color: var(--gold); }
.nav__cta { width: 100%; }

/* 68rem, not 60rem: the brand, five links and the "Become a Michaelian Now!"
   button need about 1030px laid out in a row. Below that the button wrapped to
   three lines and pushed the masthead to 91px tall, so the panel is held until
   the row genuinely fits. */
@media (min-width: 68rem) {
  .nav-toggle { display: none; }
  .nav {
    position: static; display: flex; align-items: center; gap: var(--s-5);
    background: none; border: 0; padding: 0;
  }
  .nav__list { display: flex; gap: 1.6rem; margin: 0; }
  .nav__list a {
    position: relative;
    padding: 0.35rem 0 0.5rem;
    border: 0;
    font-size: 0.95rem;
    white-space: nowrap;
  }
  /* The rule is always present and always full width — only its horizontal
     scale animates, so it wipes out from the centre instead of the width
     being animated, which would relayout on every frame. */
  .nav__list a::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 2px;
    background: var(--gold);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }
  .nav__list a:hover::after,
  .nav__list a:focus-visible::after,
  .nav__list a.is-current::after,
  .nav__list a.active::after { transform: scaleX(1); }

  /* The current page keeps its colour shift as well as the rule, so the state
     is never carried by one signal alone. */
  .nav__list a.is-current,
  .nav__list a.active { color: var(--gold); }
  .nav__cta {
    width: auto; min-height: 42px;
    padding: 0.5rem 1rem; font-size: 0.92rem;
    white-space: nowrap;
  }
  .brand__name { font-size: 1.15rem; }
  .brand__motto { font-size: 0.8rem; }
}

/* On the mobile panel the marker is a gold rule in the margin, since the
   underline device does not read in a stacked list. */
.nav__list a.is-current { color: var(--gold); }
@media (max-width: 67.99rem) {
  .nav__list a.is-current { box-shadow: inset 3px 0 0 var(--gold); padding-left: var(--s-3); }
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  background: var(--ink);
  color: #EFEADF;
  overflow: hidden;
}
/* A faint heraldic wash so the navy isn't a flat slab */
.hero::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 12% 0%, rgba(200,162,92,0.16), transparent 60%),
    radial-gradient(90% 80% at 100% 100%, rgba(11,21,38,0.85), transparent 55%);
  pointer-events: none;
}
.hero__inner {
  position: relative;
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(2.5rem, 7vw, 5rem) var(--gutter) 0;
  display: grid;
  gap: clamp(2rem, 5vw, 3rem);
}

.hero__eyebrow {
  font-family: var(--display);
  font-style: italic;
  font-size: var(--step-0);
  color: var(--gold);
  margin-bottom: var(--s-4);
  display: flex; align-items: center; gap: var(--s-3);
}
.hero__eyebrow::before {
  content: ""; width: 2.5rem; height: 1px;
  background: currentColor; opacity: 0.6; flex: none;
}

.hero__motto {
  font-size: var(--step-4);
  font-weight: 400;
  font-variation-settings: "SOFT" 30, "WONK" 1;
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: #FBF7EE;
  margin-bottom: var(--s-4);
}
.hero__motto em {
  font-style: italic;
  color: var(--gold);
  font-size: 0.62em;
  vertical-align: 0.06em;
  padding-inline: 0.1em;
}

.hero__translation {
  font-size: var(--step-1);
  line-height: 1.45;
  color: #D5CDBC;
  max-width: 34ch;
  margin-bottom: var(--s-5);
}

.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* The photographs as a mounted plate, gold-ruled like a prospectus mount */
.hero__plate {
  margin: 0;
  position: relative;
  border-top: 1px solid rgba(200,162,92,0.5);
  border-left: 1px solid rgba(200,162,92,0.5);
  padding: 10px 0 0 10px;
  border-top-left-radius: 4px;
}

/* ── Hero carousel ───────────────────────────────────────────────────────── */
.carousel { position: relative; width: 100%; }

.carousel__viewport {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-top-left-radius: 2px;
  background: var(--ink-deep);
}

/* Slides sit side by side on one track that slides horizontally. Only the
   track's transform animates, so the movement stays on the compositor and
   never triggers layout. The track's own width is one viewport, so each
   -100% step advances by exactly one slide. */
.carousel__track {
  display: flex;
  height: 100%;
  transform: translateX(0);
  transition: transform 0.8s ease-in-out;
  will-change: transform;
}
.carousel__slide {
  position: relative;
  flex: 0 0 100%;
  min-width: 0;
  margin: 0;
}
.carousel__slide img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
}
/* The desktop column crops to about 1.24:1, narrower than any of these
   photographs. The leadership shot is the widest (1.88:1) and its speaker
   stands near the left edge, so its crop is pulled left to keep her face in. */
.carousel__slide--leadership img { object-position: 35% 42%; }

/* Each slide carries its own scrim, so it slides with its caption. The dark
   stop is fixed in rem, not a percentage: on a phone the slide is only ~200px
   tall, so a percentage stop left the label in the light part of the fade —
   measured as low as 2.15:1 over the bright classroom photo. Holding at least
   72% navy through the bottom 6rem, where the label and dots sit, gives
   6.8:1 even over pure white, at every slide height. */
.carousel__slide::after {
  content: "";
  position: absolute; inset: auto 0 0 0;
  height: max(58%, 10rem);
  background: linear-gradient(to top,
    rgba(11, 21, 38, 0.88) 0,
    rgba(11, 21, 38, 0.72) 6rem,
    rgba(11, 21, 38, 0) 100%);
  pointer-events: none;
  z-index: 0;
}

/* The label sits above the dot row rather than beside it: six dots and the
   pause button take 280px, which leaves no room for a label alongside them
   on a phone. */
.carousel__caption {
  position: absolute;
  left: clamp(1rem, 3vw, 1.75rem);
  right: 1rem;
  bottom: 3.25rem;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.15;
  color: #FBF7EE;
  text-shadow: 0 1px 14px rgba(6, 13, 26, 0.6);
  pointer-events: none;
}
.carousel__caption::before {
  content: "";
  flex: none;
  width: 1.75rem;
  height: 2px;
  background: var(--gold);
}

.carousel__controls {
  position: absolute;
  right: var(--s-2);
  bottom: var(--s-1);
  z-index: 2;
  display: flex;
  align-items: center;
}

/* 40px hit area carrying a 9px dot — the target is expanded well beyond the
   visual mark rather than the mark being drawn large. */
.carousel__dot,
.carousel__toggle {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  padding: 0; border: 0;
  background: transparent;
  color: var(--gold);
  cursor: pointer;
}
.carousel__dot::before {
  content: "";
  width: 9px; height: 9px;
  border-radius: 50%;
  border: 1.5px solid var(--gold);
  background: transparent;
  transition: background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.carousel__dot:hover::before { background: rgba(200, 162, 92, 0.55); }
.carousel__dot[aria-current="true"]::before {
  background: var(--gold);
  transform: scale(1.3);
}
.carousel__toggle { margin-left: 2px; opacity: 0.85; }
.carousel__toggle:hover { opacity: 1; }

.carousel__dot:focus-visible,
.carousel__toggle:focus-visible { outline: 3px solid var(--gold); outline-offset: -6px; }

/* Without JS the controls are never built and the track never moves, so the
   first slide simply stands as a static image — which is why it carries the
   descriptive alt. A sliding track is a lot of motion, so reduced-motion
   users get the cut rather than the travel. */
@media (prefers-reduced-motion: reduce) {
  .carousel__track { transition-duration: 1ms; }
}

@media (min-width: 60rem) {
  /* The plate runs to the window edge. Rather than pulling it out with a
     negative margin against 100vw — which counts the scrollbar and leaves a
     few stray pixels — the hero drops its right padding and pads the left to
     wherever .wrap's text column starts, so the grid itself ends at the edge. */
  .hero__inner {
    max-width: none;
    margin-inline: 0;
    padding-left: max(var(--gutter), calc((100% - var(--container)) / 2 + var(--gutter)));
    padding-right: 0;
    padding-bottom: 0;
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    align-items: center;
    gap: clamp(2rem, 4vw, 4rem);
  }
  .hero__word { padding-block: clamp(3rem, 6vw, 5.5rem); }
  .hero__plate { align-self: stretch; display: flex; }
  .carousel { display: flex; }
  .carousel__viewport { aspect-ratio: auto; flex: 1; min-height: 30rem; }
}

/* ── Welcome ─────────────────────────────────────────────────────────────── */
.section--welcome { padding-block: clamp(3rem, 7vw, 5.5rem); }
.lede { max-width: 60ch; }
.lede__text {
  font-family: var(--display);
  font-size: var(--step-2);
  font-weight: 400;
  line-height: 1.42;
  color: var(--heading);
  text-wrap: pretty;
}

/* ── About ───────────────────────────────────────────────────────────────── */
.section--about { background: var(--stone); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .section--about { background: var(--stone); }
}

.pledge { display: grid; gap: var(--s-5); }
.pledge__item {
  padding-top: var(--s-4);
  border-top: 2px solid var(--ink);
  max-width: var(--measure);
}
.pledge__title { font-size: var(--step-2); margin-bottom: var(--s-3); }

@media (min-width: 48rem) {
  .pledge { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
}

/* ── The MICHAEL acrostic — the one loud element on the page ─────────────── */
.section--values {
  background: var(--ink);
  color: #DFD8C9;
}
.section--values .section__title { color: #F7F2E8; }
.section--values .section__standfirst { color: #B0A794; }

.acrostic { list-style: none; margin: 0; padding: 0; counter-reset: none; }

.acrostic__row {
  display: grid;
  grid-template-columns: minmax(2.6rem, auto) 1fr;
  align-items: baseline;
  gap: var(--s-3);
  padding-block: var(--s-4);
  border-top: 1px solid rgba(200, 162, 92, 0.26);
}
.acrostic__row:last-child { border-bottom: 1px solid rgba(200, 162, 92, 0.26); }

.acrostic__letter {
  font-family: var(--display);
  font-size: clamp(2.6rem, 7vw, 4.6rem);
  font-weight: 400;
  font-variation-settings: "SOFT" 20, "WONK" 1;
  line-height: 0.8;
  color: var(--gold);
  text-align: center;
  user-select: none;
}
.acrostic__name {
  font-size: var(--step-2);
  color: #F7F2E8;
  margin-bottom: 0.35rem;
}
.acrostic__gloss {
  color: #B4AB98;
  max-width: 58ch;
  line-height: 1.6;
}

@media (min-width: 48rem) {
  .acrostic__row {
    grid-template-columns: 6rem minmax(12rem, 15rem) 1fr;
    align-items: center;
    gap: var(--s-5);
    padding-block: var(--s-4);
  }
  .acrostic__body { display: contents; }
  .acrostic__name { margin-bottom: 0; }
}

/* ── Ledger tables ───────────────────────────────────────────────────────── */
.table-frame { margin-top: var(--s-5); }
.table-scroll { overflow-x: auto; }
.table-scroll:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

.ledger {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  text-align: left;
}
.ledger__caption {
  font-family: var(--display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--heading);
  text-align: left;
  padding-bottom: var(--s-3);
}
.ledger th, .ledger td {
  padding: 0.85rem var(--s-3);
  border-bottom: 1px solid var(--rule);
}
.ledger thead th {
  font-family: var(--text);
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--page-muted);
  border-bottom: 2px solid var(--ink);
  padding-bottom: var(--s-2);
}
.ledger tbody th {
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--heading);
  white-space: nowrap;
}
.ledger .num { text-align: right; white-space: nowrap; }
.ledger thead th.num { text-align: right; }
.ledger td:last-child, .ledger th:last-child { padding-right: 0; }
.ledger th:first-child, .ledger td:first-child { padding-left: 0; }
.ledger tbody tr:hover td, .ledger tbody tr:hover th { background: rgba(154, 75, 52, 0.05); }

.ledger__fail th, .ledger__fail td { color: var(--accent); }
.ledger__fail tbody th { color: var(--accent); }
.ledger .total { font-weight: 700; color: var(--heading); }

.table-note {
  font-size: var(--step--1);
  color: var(--page-muted);
  margin-top: var(--s-3);
  max-width: var(--measure);
}

/* ── Curriculum ──────────────────────────────────────────────────────────── */
.curriculum {
  display: grid; gap: var(--s-5);
  margin-top: clamp(3rem, 7vw, 5rem);
}
.curriculum__part {
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
  max-width: var(--measure);
}
.curriculum__stage {
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--accent);
  margin-bottom: var(--s-1);
}
.curriculum__title { font-size: var(--step-2); margin-bottom: var(--s-3); }

@media (min-width: 48rem) {
  .curriculum { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
}

/* ── The Michaelian Journey ──────────────────────────────────────────────── */
.section--journey {
  background: var(--ink);
  color: #DFD8C9;
}
.section--journey .section__title { color: #F7F2E8; }
.section--journey .section__standfirst { color: #B0A794; }

/* Written single-column first: that is the honest base for a timeline, and the
   alternating desktop arrangement is the enhancement laid over it. Done the
   other way round, the mobile rules end up fighting the desktop ones with
   !important. */
.timeline {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
}
.timeline::before {
  content: "";
  position: absolute;
  left: 27px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(200, 162, 92, 0.22);
}

.timeline__stop {
  position: relative;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  align-items: start;
  gap: var(--s-4);
  padding-block: var(--s-5);
}

.timeline__marker {
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #16233A;
  border: 1px solid rgba(200, 162, 92, 0.3);
  color: rgba(226, 217, 199, 0.55);
  position: relative;   /* lifts the disc clear of the line behind it */
  z-index: 1;
  transition: background-color 450ms var(--ease),
              border-color 450ms var(--ease),
              color 450ms var(--ease),
              transform 450ms var(--ease),
              box-shadow 450ms var(--ease);
}

/* Lit. Dark ink on the gold rather than white — the same 8.3:1 the buttons and
   chat widget use, since white on this gold is about 2.1:1. */
.timeline__stop.timeline-active .timeline__marker {
  background: #D4AF37;
  border-color: #D4AF37;
  color: #23180A;
  transform: scale(1.1);
  box-shadow: 0 0 0 6px rgba(212, 175, 55, 0.14),
              0 0 28px rgba(212, 175, 55, 0.45);
}

.timeline__card { max-width: 32rem; }
.timeline__years {
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--gold);
  margin-bottom: var(--s-1);
}
.timeline__title {
  font-size: var(--step-2);
  color: #F7F2E8;
  margin-bottom: var(--s-2);
  transition: color 450ms var(--ease);
}
.timeline__text {
  color: #A79E8B;
  line-height: 1.65;
  transition: color 450ms var(--ease);
}
.timeline__text em { font-style: italic; color: #C4BBA6; }
.timeline__stop.timeline-active .timeline__text { color: #C6BDA9; }

@media (min-width: 48rem) {
  .timeline::before { left: 50%; transform: translateX(-50%); }
  .timeline__stop {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: var(--s-6);
    padding-block: var(--s-6);
  }
  .timeline__marker { grid-column: 2; grid-row: 1; }
  .timeline__card   { grid-column: 3; grid-row: 1; }
  /* Even stops cross to the far side and set their text against the line. */
  .timeline__stop:nth-child(even) .timeline__card {
    grid-column: 1;
    text-align: right;
    margin-left: auto;
  }
}

/* The lighting is information, so it stays; only the movement goes. */
@media (prefers-reduced-motion: reduce) {
  .timeline__stop.timeline-active .timeline__marker { transform: none; }
  .timeline__marker { transition-duration: 1ms; }
}

/* ── Admissions steps ────────────────────────────────────────────────────── */
.section--admissions { background: var(--stone); }

.steps {
  list-style: none; margin: 0 0 clamp(3rem, 7vw, 5rem); padding: 0;
  display: grid; gap: 0;
  scroll-margin-top: 7rem;
}
.steps__item {
  display: grid;
  grid-template-columns: 3.25rem 1fr;
  gap: var(--s-3);
  align-items: baseline;
  padding-block: var(--s-4);
  border-top: 1px solid var(--stone-line);
}
.steps__item:last-child { border-bottom: 1px solid var(--stone-line); }
.steps__ord { margin: 0; }
.steps__ord-num {
  font-family: var(--display);
  font-size: 1.9rem;
  font-weight: 400;
  color: var(--accent);
  line-height: 1;
}
.steps__text {
  font-family: var(--display);
  font-size: var(--step-1);
  line-height: 1.45;
  color: var(--heading);
  max-width: 46ch;
}

@media (min-width: 48rem) {
  /* One column, so the steps read straight down as a single sequence.
     The two border rules that lived here went with the second column: they
     existed to close the top and bottom rows of a 2x2 grid, and in one column
     nth-last-child(-n+2) would give items 3 and 4 a bottom rule each, doubling
     against the following item's top rule. The base rules already handle a
     single column correctly.
     Capping at 46rem matches .section__head above, so the dividers line up
     with the heading instead of running the full container on a wide screen. */
  .steps {
    grid-template-columns: 1fr;
    max-width: 46rem;
  }
}

/* Desktop: every step on a single line.
   The longest step ("Attend an interview with the Guidance Counselor or
   Department Head.") measures 761px set on one line at the largest size the
   type reaches (23.2px, from about 1100px up), but a 46rem block leaves the
   text column only 668px, and the text is separately capped at 46ch. Both
   limits are lifted here: 54rem gives a 796px text column, clearing the
   longest step by about 35px so a slightly wider fallback font cannot push it
   out, and still fits inside the ~908px content area at a 1024px viewport.
   Below 1024px the steps wrap as before; the non-breaking spaces in the
   markup keep "Grade 1", "Department Head" and "official registration"
   together. */
@media (min-width: 1024px) {
  .steps { max-width: 54rem; }
  .steps__text {
    max-width: none;
    white-space: nowrap;
  }
}

.table-frame--fees { margin-top: 0; }

/* ── Colophon ────────────────────────────────────────────────────────────── */
.colophon {
  background: var(--ink-deep);
  color: #B9B1A2;
  padding-block: clamp(3rem, 7vw, 5rem) var(--s-5);
  font-size: var(--step--1);
}
.colophon__top { display: grid; gap: var(--s-6); }
.colophon__name {
  font-family: var(--display); font-size: 1.3rem; font-weight: 600; color: #F2ECE1;
}
.colophon__motto { font-family: var(--display); font-style: italic; color: var(--gold); }

.colophon__cols { display: grid; gap: var(--s-5); }

/* Contact lines. The icons sit beside visible text, so they are decorative and
   hidden from the accessibility tree; a visually-hidden label carries the
   meaning instead, since "St. Michael Academy" alone does not announce that it
   is a Messenger handle. */
.colophon__contact { list-style: none; margin: 0; padding: 0; }
.colophon__contact li {
  display: flex; align-items: center; gap: var(--s-2);
  padding-block: 3px;
}
.colophon__contact .ico { flex: none; color: var(--gold); opacity: 0.9; }
.colophon__contact a,
.colophon__contact li > span:not(.vh) {
  display: inline-flex; align-items: center;
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color var(--dur) var(--ease);
}
.colophon__contact a:hover { color: var(--gold); }
.colophon__email { font-size: 0.94em; }
.colophon__head {
  font-family: var(--display); font-style: italic; font-size: 1rem; font-weight: 600;
  color: var(--gold); margin: 0 0 var(--s-3);
}
.colophon__addr { font-style: normal; line-height: 1.8; }
.colophon__list { list-style: none; margin: 0; padding: 0; }
/* Block-level so the target spans the whole column: a 220x31 hit area is far
   easier to hit than the 54x44 one a text-width inline link would give, and it
   lets the list keep the address block's 24.5px line rhythm instead of forcing
   a 44px step that visibly loosened this column against the others. */
.colophon__list a {
  display: block;
  padding-block: 3px;
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.colophon__list a:hover { color: var(--gold); }

.colophon__legal {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: var(--s-4);
  border-top: 1px solid rgba(200,162,92,0.22);
  color: #8B8474;
}

/* Three columns now, so they flow on available width rather than on a fixed
   count — two up at tablet, three up once there is room for the email. */
@media (min-width: 34rem) {
  .colophon__cols { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
}
@media (min-width: 48rem) {
  .colophon__top { grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.8fr); gap: var(--s-6); }
  .colophon__cols { gap: var(--s-5); }
}

/* Desktop: keep the address on one line.
   It measures 224px set on a single line, but three equal columns leave its
   text only 151px here, so it breaks across "gmail.com". white-space: nowrap
   on its own would just convert that wrap into horizontal overflow, so the
   Contact column is widened to hold the full string first — the three columns
   stop being equal and the brand block yields a little of its share. */
@media (min-width: 1024px) {
  .colophon__top { grid-template-columns: minmax(0, 0.62fr) minmax(0, 2fr); }
  .colophon__cols {
    grid-template-columns: 1fr 1.7fr 1fr;   /* Visit | Contact | Explore */
    gap: var(--s-4);
  }
  .colophon__email {
    white-space: nowrap;
    overflow-wrap: normal;   /* the anywhere-break is what allowed the split */
  }
}

.colophon__legal a {
  color: inherit;
  text-underline-offset: 0.18em;
  transition: color var(--dur) var(--ease);
}
.colophon__legal a:hover { color: var(--gold); }

/* ── Privacy notice (privacy.html) ───────────────────────────────────────
   A page to be read, not sold: a compact navy header, then the notice at
   reading measure with its contents list beside it on wide screens. */
.doc-head {
  background: var(--ink);
  color: #DFD8C9;
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
}
.doc-head__title { font-size: var(--step-4); color: #F7F2E8; margin-bottom: var(--s-3); }
.doc-head__standfirst {
  font-size: var(--step-1);
  line-height: 1.55;
  color: #C9C1B0;
  max-width: 46ch;
}
.doc-head__meta { margin-top: var(--s-4); font-size: var(--step--1); color: #A69D8B; }

.doc { padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.doc__grid { display: grid; gap: var(--s-6); }

.doc__toc { font-size: var(--step--1); }
.doc__toc-head {
  font-family: var(--display);
  font-style: italic;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: var(--s-2);
}
.doc__toc ul { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--rule); }
.doc__toc a {
  display: block;
  padding: 0.3rem 0 0.3rem var(--s-3);
  color: var(--page-fg);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.doc__toc a:hover { color: var(--accent); }

.doc__body { max-width: var(--measure); min-width: 0; }
.doc__section + .doc__section {
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
}
/* The masthead is sticky, so a jump from the contents list would otherwise
   land each heading underneath it. */
.doc__body h2 { font-size: var(--step-2); margin-bottom: var(--s-3); scroll-margin-top: 6.5rem; }
.doc__body h3 { font-size: var(--step-1); margin: var(--s-5) 0 var(--s-3); }
.doc__body p + p,
.doc__body p + ul,
.doc__body ul + p,
.doc__body .facts + p { margin-top: var(--s-3); }
.doc__body ul { padding-left: 1.2rem; margin: var(--s-2) 0 0; }
.doc__body li + li { margin-top: 0.4rem; }
.doc__body li::marker { color: var(--accent); }
.doc__body a { color: var(--accent); text-underline-offset: 0.18em; overflow-wrap: anywhere; }
.doc__body strong { color: var(--heading); font-weight: 600; }

/* Every collection point answers the same three questions, so each is set as
   one label/answer list rather than a paragraph that buries the answers. */
.facts { margin: 0; border-top: 1px solid var(--rule); }
.facts__row {
  display: grid;
  gap: 0.15rem;
  padding-block: var(--s-3);
  border-bottom: 1px solid var(--rule);
}
.facts dt { font-size: var(--step--1); font-weight: 700; color: var(--page-muted); }
.facts dd { margin: 0; }

.doc__note {
  padding-left: var(--s-3);
  border-left: 3px solid var(--gold);
  color: var(--page-muted);
}

.doc__body .doc__contact { list-style: none; padding: 0; }
.doc__label {
  display: block;
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--page-muted);
}

@media (min-width: 40rem) {
  .facts__row { grid-template-columns: 9rem minmax(0, 1fr); gap: var(--s-4); }
}
@media (min-width: 60rem) {
  .doc__grid {
    grid-template-columns: 14rem minmax(0, 1fr);
    gap: var(--s-7);
    align-items: start;
  }
  .doc__toc { position: sticky; top: 6.5rem; }
}

/* ── Motion: one orchestrated arrival, then nothing uninvited ────────────── */
@media (prefers-reduced-motion: no-preference) {
  .hero__eyebrow, .hero__motto, .hero__translation, .hero__actions, .hero__plate {
    animation: rise 700ms var(--ease) both;
  }
  .hero__motto      { animation-delay: 70ms; }
  .hero__translation{ animation-delay: 140ms; }
  .hero__actions    { animation-delay: 210ms; }
  .hero__plate      { animation-delay: 120ms; animation-duration: 900ms; }

  @keyframes rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ── Scroll-triggered reveals ────────────────────────────────────────────
   Every rule here is scoped to .js, set by an inline script in the document
   head. Unscoped, a failed or blocked main.js would leave the page at
   opacity 0 with nothing left to reveal it — the content would simply be
   gone, with no error to explain why. */
.js .animate-on-scroll {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}
.js .animate-on-scroll.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Tables settle into focus instead of travelling — a wide data block sliding
   upward drags the eye far more than the figures deserve. */
.js .animate-on-scroll--scale { transform: scale(0.98); }
.js .animate-on-scroll--scale.is-visible { transform: scale(1); }

/* The MICHAEL principles arrive in reading order, so the acrostic spells
   itself down the column rather than landing all at once. */
.js .acrostic__row.animate-on-scroll:nth-child(1) { transition-delay: 50ms; }
.js .acrostic__row.animate-on-scroll:nth-child(2) { transition-delay: 100ms; }
.js .acrostic__row.animate-on-scroll:nth-child(3) { transition-delay: 150ms; }
.js .acrostic__row.animate-on-scroll:nth-child(4) { transition-delay: 200ms; }
.js .acrostic__row.animate-on-scroll:nth-child(5) { transition-delay: 250ms; }
.js .acrostic__row.animate-on-scroll:nth-child(6) { transition-delay: 300ms; }
.js .acrostic__row.animate-on-scroll:nth-child(7) { transition-delay: 350ms; }

/* Smaller sequences get a shorter ladder of their own. */
.js .steps__item.animate-on-scroll:nth-child(2)   { transition-delay: 60ms; }
.js .steps__item.animate-on-scroll:nth-child(3)   { transition-delay: 120ms; }
.js .steps__item.animate-on-scroll:nth-child(4)   { transition-delay: 180ms; }
.js .steps__item.animate-on-scroll:nth-child(5)   { transition-delay: 240ms; }
.js .pledge__item.animate-on-scroll:nth-child(2),
.js .curriculum__part.animate-on-scroll:nth-child(2) { transition-delay: 90ms; }

/* Reduced motion keeps every piece of feedback — the colour shift, the glow,
   the underline — and drops only the movement carrying it. Removing the cue
   entirely would leave these controls feeling dead rather than calm. */
@media (prefers-reduced-motion: reduce) {
  .btn:hover, .btn:active { transform: none; }
  .nav__list a::after { transition: none; }

  /* Reveals resolve to their finished state at once. Note this must restate
     opacity and transform, not merely kill the transition: without it the
     elements would sit permanently at opacity 0 for exactly the people least
     able to work around it. */
  .js .animate-on-scroll,
  .js .animate-on-scroll.is-visible {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
    will-change: auto;
  }
}

/* ── n8n chat widget ─────────────────────────────────────────────────────
   @n8n/chat is themed entirely through these custom properties; createChat()
   takes no theme argument. Names follow the package's own --chat--* scheme. */
:root {
  --chat--color-primary: #D4AF37;
  --chat--color-primary-shade-50: #C39F2C;
  --chat--color-primary-shade-100: #B18F22;
  --chat--color-secondary: #14243F;
  --chat--color-secondary-shade-50: #0B1526;

  --chat--font-family: "Karla", "Segoe UI", system-ui, -apple-system, sans-serif;
  --chat--border-radius: 3px;

  --chat--window--width: 380px;
  --chat--window--height: 560px;
  --chat--window--bottom: 24px;
  --chat--window--right: 24px;
  --chat--window--border-radius: 6px;
  /* Above the sticky masthead (100) but below the skip link (200). */
  --chat--window--z-index: 120;

  /* The header takes navy, not gold. Light text on #D4AF37 measures about
     2.1:1 — far under the 4.5:1 floor — so a gold header bar would make its
     own title unreadable. Navy against parchment text is 14.3:1. */
  --chat--header--background: #14243F;
  --chat--header--color: #F5F1E8;

  /* Every gold surface therefore carries dark ink (8.3:1) rather than white. */
  --chat--toggle--background: #D4AF37;
  --chat--toggle--hover--background: #E0BE55;
  --chat--toggle--active--background: #C39F2C;
  --chat--toggle--color: #23180A;
  --chat--toggle--size: 60px;

  --chat--input--send--button--background: #D4AF37;
  --chat--input--send--button--background-hover: #E0BE55;
  --chat--input--send--button--color: #23180A;

  --chat--button--background--primary: #D4AF37;
  --chat--button--color--primary: #23180A;

  --chat--message--user--background: #14243F;
  --chat--message--user--color: #F5F1E8;
  --chat--message--bot--background: #FFFFFF;
  --chat--message--bot--color: #3A352E;
  --chat--body--background: #F8F5EF;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --chat--body--background: #0E1826;
    --chat--message--bot--background: #16233A;
    --chat--message--bot--color: #DED8CC;
    --chat--input--background: #0A1220;
    --chat--input--text-color: #DED8CC;
  }
}

/* The package's colour variable for the send glyph does not reach it, so its
   default light grey stays — and light grey on this gold measures 1.4:1,
   effectively invisible. The icons are set directly instead. */
#n8n-chat .chat-input-send-button,
#n8n-chat .chat-window-toggle {
  color: #23180A;
}
#n8n-chat .chat-input-send-button svg,
#n8n-chat .chat-window-toggle svg {
  fill: currentColor;
  stroke: none;
}

/* ── Arch, the assistant's portrait ──────────────────────────────────────
   @n8n/chat takes no avatar option, so the image is applied here. These are
   backgrounds rather than <img> elements, so background-size: contain does
   the work object-fit would — same result, and it needs no extra markup. */
#n8n-chat .chat-window-toggle {
  background-color: #FFFFFF;
  background-image: url("assets/arch-avatar.png");
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 50%;
  box-shadow: 0 0 0 2px #D4AF37, 0 6px 18px rgba(6, 13, 26, 0.35);
}
#n8n-chat .chat-window-toggle svg { display: none; }

/* Open, the button's job changes from "talk to Arch" to "close this". The
   portrait steps aside and the chevron returns — leaving Arch's face there
   would make the only exit unmarked. */
#n8n-chat[data-chat-open] .chat-window-toggle {
  background-color: #D4AF37;
  background-image: none;
  box-shadow: 0 6px 18px rgba(6, 13, 26, 0.35);
}
#n8n-chat[data-chat-open] .chat-window-toggle svg { display: block; }

#n8n-chat .chat-header {
  position: relative;
  padding-left: 88px;
}
#n8n-chat .chat-header::before {
  content: "";
  position: absolute;
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: #FFFFFF url("assets/arch-avatar.png") center / contain no-repeat;
  box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.9);
}

/* The toggle floats over the bottom-right corner, which is where the
   copyright line ends on a narrow screen. Keep the text clear of it. */
@media (max-width: 40rem) {
  .colophon__legal { padding-right: 5.5rem; }
}

/* ── Print ───────────────────────────────────────────────────────────────── */
@media print {
  #n8n-chat { display: none !important; }
  .masthead, .notice, .hero__actions, .nav-toggle { display: none !important; }
  body { background: #fff; color: #000; }
  .hero, .section--values, .colophon { background: #fff !important; color: #000 !important; }
  .acrostic__name, .section__title, .acrostic__letter { color: #000 !important; }
}
