/* ==========================================================================
   The Japan Times School Guide — static front-end
   Design tokens ported 1:1 from the previous Tailwind theme.
   No third-party requests: system fonts only, no analytics, no cookies.
   ========================================================================== */

/* ---------- 0. Fonts ----------
   Geist, self-hosted from the previous app (src/app/fonts/GeistVF.woff).
   Variable weight 100–900. Served from this site — no third-party request. */
@font-face {
  font-family: "Geist";
  src: url("../fonts/GeistVF.woff") format("woff-variations"),
       url("../fonts/GeistVF.woff") format("woff");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- 1. Tokens ---------- */
:root {
  /* Primary — charcoal scale (was tailwind `primary`) */
  --p-50:  #FAFAFA;
  --p-100: #F0F0F0;
  --p-200: #D6D6D6;
  --p-300: #B0B0B0;
  --p-400: #8A8A8A;
  --p-500: #636363;
  --p-600: #4A4A4A;
  --p-700: #3D3D3D;
  --p-800: #2D2D2D;
  --p-900: #1A1A1A;
  --p-950: #0F0F0F;

  /* Accent — the guide's red (sampled from the approved CTA) */
  --a-50:  #FEF2F2;
  --a-100: #FDE3E3;
  --a-200: #FACACA;
  --a-300: #E04B57;
  --a-400: #C41E24;
  --a-500: #A31A1F;
  --a-600: #8B1419;
  --a-700: #6E1015;

  /* Neutral */
  --n-50:  #FAFAFA;
  --n-100: #F5F5F5;
  --n-200: #E5E5E5;
  --n-300: #D4D4D4;
  --n-400: #A3A3A3;
  --n-500: #737373;
  --n-600: #525252;
  --n-700: #404040;
  --n-800: #262626;
  --n-900: #171717;

  /* Radii */
  --r-sm: 2px;
  --r:    3px;
  --r-md: 4px;
  --r-lg: 6px;
  --r-xl: 8px;
  --r-2xl: 10px;
  --r-3xl: 12px;
  --r-full: 9999px;

  /* Shadows */
  --sh-card: 0 1px 3px rgba(0, 0, 0, 0.08);
  --sh-card-hover: 0 4px 16px rgba(0, 0, 0, 0.10);
  --sh-menu: 0 10px 24px rgba(0, 0, 0, 0.10);

  /* Type */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue",
    "Hiragino Sans", "Noto Sans JP", "Yu Gothic", Meiryo, Arial, sans-serif;
  --font-serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
    "Hiragino Mincho ProN", "Yu Mincho", "MS PMincho", serif;
  /* Masthead navigation — the face used on the old left sidebar. */
  --font-nav: "Geist", -apple-system, BlinkMacSystemFont, "Hiragino Sans",
    "Noto Sans JP", "Yu Gothic", Meiryo, sans-serif;

  /* Layout */
  --shell-max: 1440px;
  --gutter: 24px;

  /* Per-school brand colour; overridden inline on profile pages */
  --brand: var(--p-900);
}

/* ---------- 2. Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body {
  margin: 0;
  background: var(--n-50);
  color: var(--n-800);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  overscroll-behavior-y: none;
}

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

a { color: inherit; text-decoration: none; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}
button { background: none; border: 0; cursor: pointer; padding: 0; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

::selection { background: rgba(196, 30, 36, 0.18); color: var(--p-900); }

:focus-visible {
  outline: 2px solid var(--a-400);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--n-300); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--n-400); }

.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

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

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 100;
  background: var(--p-900); color: #fff; padding: 10px 16px;
  border-radius: var(--r-lg); font-size: 14px; transition: top .2s;
}
.skip-link:focus { top: 12px; }

/* ---------- 3. Layout primitives ---------- */
.shell {
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
@media (min-width: 768px) { .shell { padding-inline: 32px; } }
@media (min-width: 1024px) { .shell { padding-inline: 64px; } }

.shell-wide { max-width: 1600px; margin-inline: auto; padding-inline: 24px; }
@media (min-width: 768px) { .shell-wide { padding-inline: 32px; } }
@media (min-width: 1024px) { .shell-wide { padding-inline: 40px; } }

.section { padding-block: 64px; }
@media (min-width: 1024px) { .section { padding-block: 96px; } }

.section-sm { padding-block: 40px; }
.bg-white { background: #fff; }
.bg-n50 { background: var(--n-50); }

/* ---------- 4. Typography helpers ---------- */
.serif { font-family: var(--font-serif); }

.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--a-400);
}

.display {
  font-family: var(--font-serif);
  font-size: clamp(2rem, 1.3rem + 3vw, 3.75rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--p-900);
  text-wrap: balance;
}

.h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); font-weight: 600; color: var(--p-900); letter-spacing: -0.02em; }
.h2 { font-family: var(--font-serif); font-size: 1.5rem; font-weight: 700; color: var(--p-900); }
.h3 { font-family: var(--font-serif); font-size: 1.25rem; font-weight: 700; color: var(--p-900); }
.h4 { font-family: var(--font-serif); font-size: 1.0625rem; font-weight: 700; color: var(--p-900); }

.lede { font-size: 1.0625rem; line-height: 1.7; color: var(--n-700); }
.muted { color: var(--n-500); font-size: 0.875rem; }
.tiny { font-size: 0.75rem; color: var(--n-500); }

.prose p { margin-bottom: 1.1em; line-height: 1.75; color: var(--n-800); }
.prose p:last-child { margin-bottom: 0; }
.prose h2 { margin: 2em 0 .6em; }
.prose h3 { margin: 1.6em 0 .5em; }
.prose ul { margin: 0 0 1.1em 0; }
.prose ul li {
  position: relative; padding-left: 20px; margin-bottom: .4em;
  color: var(--n-600); line-height: 1.7;
}
.prose ul li::before {
  content: ""; position: absolute; left: 4px; top: .7em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--n-300);
}
.prose blockquote {
  margin: 1.6em 0; padding: 6px 0 6px 24px;
  border-left: 4px solid var(--brand);
}
.prose blockquote p {
  font-size: 1.125rem; font-style: italic; line-height: 1.65; color: var(--p-900);
}

/* ---------- 5. Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 22px;
  border-radius: var(--r-lg);
  font-size: 14px; font-weight: 500; line-height: 1;
  transition: background-color .2s, color .2s, border-color .2s, box-shadow .2s;
  white-space: nowrap;
}
.btn-primary { background: var(--p-900); color: #fff; }
.btn-primary:hover { background: var(--p-800); }

.btn-accent { background: var(--a-400); color: #fff; }
.btn-accent:hover { background: var(--a-500); }

.btn-brand { background: var(--brand); color: #fff; }
.btn-brand:hover { filter: brightness(1.15); }

.btn-outline { border: 1px solid var(--n-200); color: var(--n-700); background: #fff; }
.btn-outline:hover { border-color: var(--n-400); color: var(--p-900); }

.btn-ghost { color: var(--n-600); }
.btn-ghost:hover { color: var(--p-900); background: var(--n-100); }

.btn-block { width: 100%; }
.btn-sm { padding: 8px 16px; font-size: 13px; }
.btn-lg { padding: 14px 28px; font-size: 15px; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14px; font-weight: 500; color: var(--p-900);
}
.link-arrow svg { transition: transform .2s; }
.link-arrow:hover svg { transform: translateX(3px); }

/* ---------- 6. Header / nav ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: saturate(180%) blur(8px);
  /* The masthead meets the page without a drawn line; the edge appears only
     once content actually scrolls beneath it. */
  border-bottom: 1px solid transparent;
  transition: border-color .3s;
}
.site-header.scrolled { border-bottom-color: var(--n-200); }
/* Three-column grid: the middle column is centred on the page, and the nav
   inside it is itself 1fr/auto/1fr — so "Magazine" sits dead-centre. */
.nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  height: 76px;
}
.nav-lead { display: flex; align-items: center; min-width: 0; }

.brand { display: block; min-width: 0; }
.brand img { width: auto; height: 30px; }
@media (max-width: 520px) { .brand img { height: 24px; } }
.brand-footer img {
  height: 30px;
  /* the lockup is dark; invert it for the dark footer */
  filter: invert(1) brightness(1.7) saturate(0);
}

.nav-links { display: none; }
@media (min-width: 1024px) {
  .nav-links {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    column-gap: 28px;
  }
  /* The outer cells are equal width, so the middle item — Magazine — lands on
     the true page centre no matter how many links sit either side of it. */
  .nav-cell.start { justify-self: end; }
  .nav-cell.mid { justify-self: center; }
  .nav-cell.end { justify-self: start; display: flex; gap: 28px; }
}
.nav-link {
  display: inline-block;
  padding: 8px 2px;
  font-family: var(--font-nav);
  font-size: 15px; font-weight: 500; letter-spacing: -0.005em;
  color: var(--p-700); white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color .2s, border-color .2s;
}
.nav-link.has-status {
  display: inline-flex; flex-direction: column; align-items: center; gap: 3px;
}
.nav-link:hover { color: var(--p-900); border-bottom-color: var(--n-300); }
.nav-link[aria-current="page"] {
  color: var(--p-900); font-weight: 600; border-bottom-color: var(--a-400);
}

/* Pinned to the third column explicitly. The nav in the middle column is
   display:none below 1024px, which removes it from the grid altogether — so
   without this the language switch and the menu button slide up into the
   middle column and sit adrift with a whole 1fr of empty space to their right. */
.nav-right {
  grid-column: 3;
  display: flex; align-items: center; gap: 8px; justify-self: end; flex-shrink: 0;
}

.lang-switch {
  display: inline-flex; flex-shrink: 0;
  border: 1px solid var(--n-200); border-radius: var(--r-full); overflow: hidden;
}
.lang-switch a {
  padding: 5px 12px; font-size: 12px; font-weight: 600; color: var(--n-500);
  white-space: nowrap;
  transition: background-color .2s, color .2s;
}
@media (max-width: 420px) { .lang-switch a { padding: 5px 9px; font-size: 11px; } }
.lang-switch a:hover { background: var(--n-100); color: var(--p-900); }
.lang-switch a[aria-current="true"] { background: var(--p-900); color: #fff; }

.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--r-lg); color: var(--n-600);
}
.nav-toggle:hover { background: var(--n-100); }
@media (min-width: 1024px) { .nav-toggle { display: none; } }

.mobile-menu {
  display: none; border-top: 1px solid var(--n-200); background: #fff;
  padding: 12px 0 20px;
}
.mobile-menu.open { display: block; }
@media (min-width: 1024px) { .mobile-menu.open { display: none; } }
.mobile-menu a, .mobile-menu > span.has-status {
  display: block; padding: 12px 4px;
  font-family: var(--font-nav); font-size: 16px; font-weight: 500;
  color: var(--p-800); border-bottom: 1px solid var(--n-100);
}
.mobile-menu .has-status {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
}
.mobile-menu .is-soon { color: var(--n-400); }
.mobile-menu a[aria-current="page"] { font-weight: 600; color: var(--p-900); }
.mobile-menu a.minor {
  font-family: var(--font-sans); font-size: 14px; font-weight: 500; color: var(--n-600);
}
.mobile-menu a:last-child { border-bottom: 0; }
.mobile-menu-rule { display: block; height: 1px; background: var(--n-200); margin: 10px 0; }

/* ---------- 7. Footer ---------- */
.site-footer { background: var(--p-900); color: var(--n-300); padding: 56px 0 28px; }
.footer-grid {
  display: grid; gap: 40px;
  grid-template-columns: 1fr;
}
/* A pair of blocks, one at each edge. The empty middle track is the point:
   it is what makes the two ends read as a pair rather than a queue. The two
   right-hand columns are set right so the block has a true edge against the
   page, mirroring the masthead's on the left. */
@media (min-width: 768px) {
  .footer-grid {
    grid-template-columns: minmax(0, 26ch) minmax(0, 22ch) 1fr auto auto;
    gap: 40px 56px;
  }
  .footer-grid > :nth-child(3) { grid-column: 4; }
  .footer-grid > :nth-child(4) { grid-column: 5; }
  .footer-grid > :nth-child(3),
  .footer-grid > :nth-child(4) { text-align: right; }
  .footer-grid > :last-child { justify-self: end; }
}
.footer-desc { margin-top: 16px; font-size: 14px; line-height: 1.7; color: var(--n-400); max-width: 34ch; }
.footer-heading {
  font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--n-500); margin-bottom: 14px;
}
.footer-list li { margin-bottom: 10px; }
.footer-list a { font-size: 14px; color: var(--n-300); transition: color .2s; }
.footer-list a:hover { color: #fff; }
/* One line per thing, with the address given its own space beneath the two
   ways of reaching a person. */
.footer-contact { font-size: 14px; color: var(--n-400); }
.footer-contact p { line-height: 1.6; }
.footer-contact p + p { margin-top: 8px; }
.footer-contact .addr {
  margin-top: 16px; margin-left: auto; max-width: 26ch;
  line-height: 1.85; color: var(--n-500);
}
/* Between the two right-hand columns and the page edge there is nothing, so
   their text sets against it directly. */
@media (min-width: 768px) {
  .footer-grid > :nth-child(3) .footer-list,
  .footer-grid > :nth-child(4) .footer-contact { margin-left: auto; }
}
.footer-contact a { color: var(--n-300); transition: color .2s; }
.footer-contact a:hover { color: #fff; }
/* Sibling Japan Times properties */
.footer-network {
  margin-top: 44px; padding-top: 28px;
  border-top: 1px solid rgba(255, 255, 255, .1);
}
.network-row {
  display: grid; gap: 12px;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .network-row { grid-template-columns: repeat(3, 1fr); } }
.network-item {
  display: flex; flex-direction: column; gap: 3px;
  padding: 16px 18px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .03);
  transition: border-color .2s, background-color .2s;
}
.network-item:hover {
  border-color: rgba(255, 255, 255, .34);
  background: rgba(255, 255, 255, .06);
}

/* Each property supplies a finished banner carrying its own background colour,
   so the container gets out of the way and only sets a common height. */
.network-item.has-logo {
  padding: 0; border: 0; background: none;
  border-radius: var(--r-md); overflow: hidden;
  align-items: flex-start;
  transition: opacity .2s;
}
.network-item.has-logo:hover { background: none; opacity: .82; }
.network-item.has-logo img {
  height: 54px; width: auto; max-width: 100%;
  object-fit: contain; object-position: left center;
}
@media (max-width: 639px) { .network-item.has-logo img { height: 48px; } }
.network-name {
  font-family: var(--font-serif); font-size: 15px; font-weight: 700;
  color: #fff; letter-spacing: -0.01em; line-height: 1.25;
}
.network-note { font-size: 12px; color: var(--n-500); }

.footer-bottom {
  margin-top: 28px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.1);
  display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: center;
  justify-content: space-between; font-size: 13px; color: var(--n-500);
}
.footer-bottom a:hover { color: #fff; }

/* ---------- 8. Badges & chips ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  border-radius: var(--r-full); padding: 4px 12px;
  font-size: 12px; font-weight: 500;
  background: var(--n-100); color: var(--n-700);
}

.badge-brand { background: var(--brand); color: #fff; }

.chip {
  display: inline-flex; align-items: center;
  border: 1px solid var(--n-300); border-radius: var(--r-full);
  padding: 6px 14px; font-size: 14px; font-weight: 500; color: var(--n-700);
}
.chip-solid { border-color: transparent; background: var(--brand); color: #fff; }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---------- 9. Breadcrumb ---------- */
.breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 13px; color: var(--n-500); }
.breadcrumb a:hover { color: var(--p-900); }
.breadcrumb .sep { color: var(--n-300); }
.breadcrumb [aria-current] { color: var(--p-900); font-weight: 500; }

/* ==========================================================================
   10. DIRECTORY — search bar, filters, results  (ported from /findschools)
   ========================================================================== */
.directory-bar {
  position: sticky; top: 76px; z-index: 20;
  border-bottom: 1px solid var(--n-200);
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(6px);
  transition: transform .3s ease-out;
}
.directory-bar.hidden-bar { transform: translateY(-100%); }

.search-row { display: flex; align-items: center; gap: 12px; height: 68px; }
.search-field { position: relative; flex: 1; min-width: 0; }
.search-field svg {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  color: var(--n-400); pointer-events: none;
}
.search-field input {
  width: 100%; padding: 10px 16px 10px 44px;
  border: 1px solid var(--n-200); border-radius: var(--r-full);
  background: #fff; font-size: 14px; color: var(--p-900);
  transition: border-color .2s;
}
.search-field input::placeholder { color: var(--n-400); }
.search-field input:focus { outline: none; border-color: var(--p-900); }

.filter-bar {
  display: flex; align-items: center;
  border-top: 1px solid var(--n-100); padding-block: 8px;
}
.filter-bar > svg { flex-shrink: 0; margin-right: 8px; color: var(--n-400); }
.filter-scroll { display: flex; min-width: 0; align-items: center; overflow-x: auto; }
.filter-sep { flex-shrink: 0; color: var(--n-200); }

.filter-btn {
  display: inline-flex; flex-shrink: 0; align-items: center; gap: 4px;
  white-space: nowrap; padding: 6px 12px;
  font-size: 13px; font-weight: 500; color: var(--n-500);
  transition: color .2s;
}
.filter-btn:hover { color: var(--n-800); }
.filter-btn.active { font-weight: 600; color: var(--p-900); }
.filter-btn .chevron { color: var(--n-400); transition: transform .2s; }
.filter-btn[aria-expanded="true"] .chevron { transform: rotate(180deg); }
.filter-btn .clear-x { color: var(--n-400); }
.filter-btn .clear-x:hover { color: var(--n-700); }

.directory-actions {
  display: flex; flex-shrink: 0; align-items: center; gap: 8px;
  margin-left: auto; padding-left: 16px;
}

.filter-menu {
  position: absolute; z-index: 60;
  min-width: 200px; max-height: 260px; overflow-y: auto;
  border: 1px solid var(--n-200); border-radius: var(--r-lg);
  background: #fff; padding: 4px 0; box-shadow: var(--sh-menu);
  animation: menuIn .15s ease-out;
}
@keyframes menuIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.filter-menu button {
  display: flex; width: 100%; align-items: center; gap: 8px;
  padding: 8px 12px; text-align: left; font-size: 13px; color: var(--n-600);
  transition: background-color .15s;
}
.filter-menu button:hover { background: var(--n-50); }
.filter-menu button.selected { background: var(--n-50); font-weight: 500; color: var(--p-900); }
.filter-menu button .tick { flex-shrink: 0; color: var(--p-900); }
.filter-menu button .pad { padding-left: 20px; }

.results-head {
  display: flex; flex-direction: column; gap: 12px;
  margin-bottom: 24px;
}
.collection-results-heading {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 24px; margin-bottom: 32px; padding-bottom: 24px;
  border-bottom: 1px solid var(--n-200);
}
.collection-results-heading h1 {
  font-family: var(--font-serif); font-size: clamp(1.6rem, 1.05rem + 1.5vw, 2.25rem);
  font-weight: 700; line-height: 1.15; color: var(--p-900);
}
.collection-results-heading p {
  max-width: 60ch; margin-top: 10px; color: var(--n-600); line-height: 1.65;
}
@media (max-width: 640px) {
  .collection-results-heading { flex-direction: column; }
}
@media (min-width: 640px) {
  .results-head { flex-direction: row; align-items: center; justify-content: space-between; }
}
.results-count { font-size: 14px; color: var(--n-600); }
.sort-group { display: flex; align-items: center; gap: 8px; }
.sort-group label { font-size: 14px; color: var(--n-500); white-space: nowrap; }
.sort-group select {
  border: 1px solid var(--n-200); border-radius: var(--r-lg); background: #fff;
  padding: 7px 12px; font-size: 14px; color: var(--n-700);
}
.sort-group select:focus { outline: none; border-color: var(--a-400); box-shadow: 0 0 0 1px var(--a-400); }

.school-grid {
  display: grid; gap: 32px 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .school-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .school-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1280px) { .school-grid { grid-template-columns: repeat(4, 1fr); } }

/* --- School card: a register entry ---
   Learned from members' registers rather than product grids: the school's
   mark (or a drawn monogram) rendered uniform, the name, one locator line.
   No photography, no badges, no fee marks — those belong to the profile. */
.school-card {
  position: relative; display: flex; flex-direction: column;
  align-items: center; justify-content: flex-start; text-align: center;
  height: 100%; padding: 40px 24px 32px;
}

.card-mark {
  display: flex; align-items: center; justify-content: center;
  height: 72px; margin-bottom: 22px;
}
.card-mark img {
  max-height: 72px; max-width: 120px; width: auto;
  filter: grayscale(1) contrast(1.05); opacity: .85;
  transition: filter .6s, opacity .6s;
}
.school-card:hover .card-mark img { filter: none; opacity: 1; }
.card-mono {
  display: flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border: 1px solid var(--n-300); border-radius: 50%;
  font-family: var(--font-serif); font-size: 1.375rem; font-weight: 600;
  letter-spacing: .04em; color: var(--p-800);
  transition: border-color .3s;
}
.school-card:hover .card-mono { border-color: var(--p-800); }

.card-title {
  font-family: var(--font-serif); font-size: 1.0625rem; font-weight: 700;
  line-height: 1.35; color: var(--p-900); transition: color .3s;
}
.school-card:hover .card-title { color: var(--a-500); }
.card-loc {
  margin-top: 6px; font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--n-500);
}

/* Filtered cards leave the grid completely. */
.school-card.is-hidden { display: none !important; }

/* ---------- 10b. Collection browse — four schools at a time ---------- */
.browse { padding-block: 8px 40px; }

.rail-block { padding-block: 40px; border-bottom: 1px solid var(--n-200); }
.rail-block:first-child { padding-top: 32px; }

.rail-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: 24px;
}
.rail-head h2 {
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 1.05rem + 1.6vw, 2.375rem);
  font-weight: 700; line-height: 1.1; letter-spacing: -0.02em;
  color: var(--p-900);
}
.rail-head p { margin-top: 6px; font-size: 14px; color: var(--n-500); }

.rail-nav { display: flex; flex-shrink: 0; align-items: center; gap: 8px; }
.rail-all {
  margin-right: 4px; font-size: 13px; font-weight: 500; color: var(--n-500);
  white-space: nowrap; border-bottom: 1px solid transparent; transition: color .2s, border-color .2s;
}
.rail-all:hover { color: var(--p-900); border-bottom-color: var(--n-300); }
.rail-btn {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--r-md);
  border: 1px solid var(--n-300); color: var(--p-900);
  transition: border-color .2s, background-color .2s, opacity .2s;
}
.rail-btn:hover:not(:disabled) { background: var(--n-100); border-color: var(--n-400); }
.rail-btn:disabled { opacity: .3; cursor: default; }
@media (max-width: 700px) { .rail-btn { display: none; } }

.rail-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 3 * 20px) / 4);
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding: 2px 2px 6px;
}
.rail-track > .school-card { scroll-snap-align: start; }
@media (max-width: 1100px) { .rail-track { grid-auto-columns: calc((100% - 2 * 20px) / 3); } }
@media (max-width: 820px) { .rail-track { grid-auto-columns: calc((100% - 16px) / 2); gap: 16px; } }
@media (max-width: 520px) { .rail-track { grid-auto-columns: 78%; } }

.browse-all { display: flex; justify-content: center; padding-top: 40px; }

/* ---------- Image slots: what artwork the slot expects ---------- */
.img-spec {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; text-align: center;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 1px 6px rgba(0, 0, 0, .35);
  pointer-events: none;
}
.img-spec .k {
  font-size: 9px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  opacity: .7;
}
.img-spec .d { font-size: 12px; letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.img-spec.compact .d { font-size: 10px; }

/* On the pale card placeholder the text needs a darker ink. */
.card-media .placeholder .img-spec {
  color: rgba(0, 0, 0, .55); text-shadow: none;
}
.card-media .placeholder .img-spec .k { opacity: .55; }

.profile-logo .img-spec { color: var(--n-400); text-shadow: none; }
.article-card .thumb .img-spec { color: var(--n-500); text-shadow: none; }

.browse-head { margin-bottom: 24px; border-bottom: 1px solid var(--n-200); padding-bottom: 12px; }
.browse-head h2 {
  font-family: var(--font-serif); font-size: 1.375rem; font-weight: 700; color: var(--p-900);
}
.browse-head p { margin-top: 4px; font-size: 14px; color: var(--n-500); }

.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  border: 1px dashed var(--n-300); border-radius: var(--r-lg); background: var(--n-50);
  padding: 80px 32px; text-align: center;
}
.empty-state .icon {
  display: flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border-radius: 50%; background: var(--n-200);
  color: var(--n-400); margin-bottom: 16px;
}
.empty-state h3 { font-size: 20px; margin-bottom: 8px; color: var(--p-900); }
.empty-state p { max-width: 34ch; font-size: 14px; color: var(--n-500); margin-bottom: 24px; }

/* ==========================================================================
   11. SCHOOL PROFILE
   ========================================================================== */

/* ---- Media: the school's film (or banner) leads the content column ----
   The film is a facade: nothing loads from YouTube until the visitor
   presses play; once playing, it pins to the corner when scrolled past. */
.stage-media-slot { position: relative; aspect-ratio: 16 / 9; }
.stage-media { position: absolute; inset: 0; overflow: hidden; background: #141414; }
.stage-media .poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.stage-media .poster.field { background: radial-gradient(85% 130% at 62% 38%, #2a3138 0%, #141414 72%); }
.stage-media.empty { display: flex; align-items: center; justify-content: center; }
.stage-media iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.vfacade {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  color: #fff;
}
.stage-media.playing .vfacade { display: none; }
.vplay {
  width: 72px; height: 72px; border: 1px solid rgba(255,255,255,.55); border-radius: 50%;
  display: flex; align-items: center; justify-content: center; color: #fff;
  transition: border-color .3s, background-color .3s;
}
.vplay:hover { border-color: #fff; background: rgba(255,255,255,.08); }
.vplay svg { margin-left: 3px; }
.vcap { font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: rgba(255,255,255,.6); }

/* Once playing and scrolled past, the film pins to the corner. */
.stage-media.mini {
  position: fixed; inset: auto 20px 20px auto;
  width: min(320px, calc(100vw - 40px)); height: auto; aspect-ratio: 16 / 9;
  z-index: 80; box-shadow: 0 14px 44px rgba(0,0,0,.35);
}
.stage-media .vclose { display: none; }
.stage-media.mini .vclose {
  display: flex; position: absolute; top: 6px; right: 6px; z-index: 2;
  width: 28px; height: 28px; align-items: center; justify-content: center;
  color: rgba(255,255,255,.85); background: rgba(0,0,0,.45); border-radius: 50%;
}

/* Sticky tab nav (lives inside the content column) */
/* The tab bar's rule is drawn only while it is doing work — that is, once the
   page has scrolled and text is passing beneath it. At rest the tabs sit on
   open white with the red marker under the current one, which is the only
   thing that needs saying. Same signal as the masthead's edge, so the two
   lines arrive together rather than one at a time. */
.tab-nav {
  position: sticky; top: 76px; z-index: 30;
  border-bottom: 1px solid transparent;
  transition: border-color .3s;
  background: rgba(255, 255, 255, .95); backdrop-filter: blur(10px);
}
html.scrolled .tab-nav { border-bottom-color: var(--n-200); }
/* In-column tab bar, directly under the media. The invisible sentinel that
   drives the mini player must not add a second column gap. */
[data-stage-end] { margin-top: -64px; }
.tab-nav.in-main { margin-top: -40px; }
.tab-nav.in-main nav { height: 56px; }
.tab-nav.in-main .tab-btn { padding-block: 0; display: flex; align-items: center; }
/* Pulled back by one tab's side padding so the first label's glyph — not its
   padding box — lands on the column edge, level with the film above and the
   section headings below. */
.tab-nav nav { display: flex; gap: 4px; overflow-x: auto; margin-inline-start: -20px; }
.tab-btn {
  position: relative; flex-shrink: 0; padding: 16px 20px;
  font-size: 14px; font-weight: 500; color: var(--n-400);
  transition: color .2s; white-space: nowrap;
}
.tab-btn:hover { color: var(--n-600); }
.tab-btn.active { color: var(--p-900); }
.tab-btn.active::after {
  content: ""; position: absolute; inset-inline: 0; bottom: 0;
  height: 3px; border-radius: 2px 2px 0 0; background: var(--brand);
}

/* Two-column body: content (media first) left, card rail right. The rail is
   persistent — it keeps the school's actions in reach while the visitor
   scrolls the film, overview and everything beneath it. */
.profile-body { background: #fff; padding-block: 28px 64px; }
.profile-cols { display: grid; gap: 40px; grid-template-columns: 1fr; align-items: start; }
/* On a phone the rail comes first: a reader arriving on a narrow screen should
   meet the school — mark, name, place, the written line — before the film.
   The DOM keeps the content first for reading order on wide screens, so the
   single column is reordered here rather than in the markup. */
.profile-side { order: -1; }
@media (min-width: 1024px) {
  /* Identity leads: the card rail sits left, content reads to its right.
     Both children are placed explicitly, so `order` no longer applies. */
  .profile-cols { grid-template-columns: 360px minmax(0, 1fr); gap: 56px; }
  .profile-main { grid-column: 2; grid-row: 1; }
  .profile-side { grid-column: 1; grid-row: 1; order: 0; }
}
.profile-main { min-width: 0; display: flex; flex-direction: column; gap: 64px; }
/* The cards' outlines are invisible, so the space between them has to be read
   as one step rather than as card padding + gap + card padding. The gap is
   zero and the 24px of padding on each side of the join does the work. */
.profile-side { display: flex; flex-direction: column; gap: 0; }
@media (min-width: 1024px) {
  /* The crest starts level with the top of the film, and the rail pins under
     the masthead the moment the page moves. The tab bar is in the right-hand
     column, so there is nothing else up there to clear.

     The rail is built to fit: everything from crest to social row is sized so
     the whole of it stands inside a laptop viewport, which is what lets it
     stay still while the content scrolls past. Anything added to it has to be
     paid for out of the same budget. */
  /* 12px of air under the masthead: at 76px the crest sat on the header's
     own bottom rule, which reads as a collision rather than a stack. */
  .profile-side { position: sticky; top: 88px; }
}

.profile-section { scroll-margin-top: 140px; }
.profile-section > h2 { margin-bottom: 32px; }

.stack-10 { display: flex; flex-direction: column; gap: 40px; }
.stack-6 { display: flex; flex-direction: column; gap: 24px; }

/* Highlights */
.highlight-list { display: grid; gap: 12px; }
@media (min-width: 640px) { .highlight-list { grid-template-columns: repeat(2, 1fr); } }
.highlight-list li { display: flex; align-items: flex-start; gap: 12px; padding-left: 0; }
.highlight-list li::before { content: none; }
.highlight-list svg { flex-shrink: 0; margin-top: 2px; color: var(--brand); }
.highlight-list span { font-size: 14px; color: var(--n-800); }

/* Gallery */
.gallery { display: grid; gap: 8px; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 768px) { .gallery { grid-template-columns: repeat(4, 1fr); } }
.gallery button {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: var(--r-lg); background: var(--n-100);
}
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s; }
.gallery button:hover img { transform: scale(1.05); }

.lightbox {
  position: fixed; inset: 0; z-index: 100; display: none;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .92); padding: 24px;
}
.lightbox.open { display: flex; }
.lightbox img { max-height: 86vh; max-width: 100%; object-fit: contain; }
.lightbox button {
  position: absolute; display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(255,255,255,.1); color: #fff;
}
.lightbox button:hover { background: rgba(255,255,255,.2); }
.lightbox .lb-close { top: 20px; right: 20px; }
.lightbox .lb-prev { left: 20px; top: 50%; transform: translateY(-50%); }
.lightbox .lb-next { right: 20px; top: 50%; transform: translateY(-50%); }

/* Fact rows (admissions) */
.fact-rows { border-block: 1px solid var(--n-200); max-width: 42rem; }
.fact-row {
  display: grid; grid-template-columns: 10rem 1fr; gap: 0 24px; padding-block: 12px;
  border-bottom: 1px solid var(--n-200);
}
.fact-row:last-child { border-bottom: 0; }
@media (min-width: 640px) { .fact-row { grid-template-columns: 14rem 1fr; } }
.fact-row dt { font-size: 14px; color: var(--n-500); display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fact-row dd { min-width: 0; font-size: 14px; font-weight: 500; color: var(--p-900); }
.fact-row dd .soft { font-weight: 400; color: var(--n-400); }
.pill-optional {
  border-radius: var(--r-full); background: var(--n-100); padding: 2px 8px;
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--n-500);
}

/* KPI / outcome cards */
.kpi-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .kpi-grid { grid-template-columns: repeat(3, 1fr); } }
.kpi {
  border: 1px solid var(--n-200); border-radius: var(--r-lg);
  background: #fff; padding: 20px;
}
.kpi .k {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--n-500);
}
.kpi .k svg { color: var(--brand); }
.kpi .v { margin-top: 8px; font-size: 30px; font-weight: 300; color: var(--p-900); line-height: 1.1; }
.kpi .sub { margin-top: 2px; font-size: 11px; color: var(--n-400); }

/* Tile lists (universities, awards, alumni, partnerships) */
.tile-grid { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .tile-grid { grid-template-columns: repeat(2, 1fr); } }
.tile-grid.three { grid-template-columns: 1fr; }
@media (min-width: 640px) { .tile-grid.three { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .tile-grid.three { grid-template-columns: repeat(3, 1fr); } }
.tile {
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--n-200); border-radius: var(--r-lg);
  background: #fff; padding: 16px;
}
.tile.top { align-items: flex-start; }
.tile .ico {
  display: flex; flex-shrink: 0; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--r); background: var(--n-100); color: var(--n-400);
}
.tile .name { font-size: 14px; font-weight: 500; color: var(--p-900); }
.tile .sub { font-size: 12px; color: var(--n-500); }

.sub-head { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
.sub-head svg { color: var(--brand); }

/* Ideal-for / considerations */
.two-col { display: grid; gap: 32px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .two-col { grid-template-columns: repeat(2, 1fr); } }
.tick-list li { display: flex; align-items: flex-start; gap: 10px; padding-left: 0; margin-bottom: 10px; }
.tick-list li::before { content: none; }
.tick-list svg { flex-shrink: 0; margin-top: 3px; }
.tick-list span { font-size: 14px; color: var(--n-800); line-height: 1.6; }
/* No rule above the crest, and no space where one used to be: the crest's top
   edge is the rail's top edge, level with the top of the film beside it. Two
   columns that begin on the same line read as one page; 27px of inherited
   padding made them read as two. */
.profile-side { padding-top: 0; }

/* ---- Profile rail ----
   A guide's entry rather than a data card: identity, one written line, then the
   handful of facts the line cannot carry. No boxes, no icons, no rules — the
   only rule is the brand edge at the top, and that is drawn on scroll. */
.pr-mark { display: block; height: 56px; width: auto; }
.pr-id > :first-child { margin-top: 0; }
.pr-name {
  margin-top: 14px; font-family: var(--font-serif); font-size: 1.3125rem; font-weight: 700;
  line-height: 1.4; letter-spacing: -.01em; color: var(--p-900);
}
.pr-place { margin-top: 7px; font-size: 12px; letter-spacing: .02em; color: var(--n-500); }
.pr-sentence { margin-top: 16px; font-size: 14px; line-height: 1.8; color: var(--n-800); }
/* Founding year rides the place line: provenance, not a fact worth its own row. */
.pr-founded { display: block; margin-top: 3px; color: var(--n-400); }
/* One grid for the whole list, not one per row: rows are `display: contents`
   so every label and every value shares a single pair of columns. With a grid
   per row the column width is computed per row, and a long label in one row
   pushes only that row's value across — a two-pixel error at best, a ragged
   list at worst. The label column takes the width of the longest label and no
   more, which is why Japanese and English both sit right without a switch. */
.pr-facts {
  margin: 18px 0 0; display: grid; gap: 8px 16px;
  grid-template-columns: minmax(4.5em, max-content) minmax(0, 1fr);
}
.pr-row { display: contents; }
.pr-row dt { font-size: 12px; line-height: 1.75; color: var(--n-500); }
.pr-row dd { margin: 0; font-size: 13px; line-height: 1.75; color: var(--p-900); }
.pr-tags { display: flex; flex-wrap: wrap; gap: 5px; padding-top: 3px; }
.pr-tags span {
  padding: 1px 9px; border: 1px solid var(--n-200); border-radius: var(--r-full);
  font-size: 12px; line-height: 1.7; color: var(--p-800); white-space: nowrap;
}
.pr-addr { margin-top: 14px; font-size: 12px; line-height: 1.7; color: var(--n-500); }
.pr-brochure { margin-top: 18px; font-size: 13px; }

/* ---- Admissions ----
   Blocks rather than a table: every answer here runs to a sentence or two, and
   a fact table would either truncate them or leave a column of ragged prose. */
.adm { max-width: 44rem; margin-bottom: 40px; }
.adm-row + .adm-row { margin-top: 26px; }
.adm-row h3 {
  font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--n-400);
}
.adm-row p { margin-top: 7px; font-size: 14px; line-height: 1.85; color: var(--n-800); }
.adm-fees { margin: 10px 0 0; display: grid; gap: 8px 24px; grid-template-columns: minmax(6em, max-content) minmax(0, 1fr); }
.adm-fees > div { display: contents; }
.adm-fees dt { font-size: 13px; color: var(--n-500); }
.adm-fees dd { margin: 0; font-size: 14px; font-weight: 500; color: var(--p-900); font-variant-numeric: tabular-nums; }
/* The one thing that catches families out. Red because it costs money or a
   place if it is missed — the only use of the accent in this section. */
.adm-caution {
  margin-bottom: 30px; padding-left: 16px; border-left: 2px solid var(--a-400);
  font-size: 14px; line-height: 1.85; color: var(--p-900);
}
@media (max-width: 639px) { .adm-row h3 { letter-spacing: .06em; } }
/* The label column holds at every width — it was stacking below 640px, which
   turned a tidy two-column list into a ragged one exactly where the screen is
   narrowest. The column sizes itself to the longest label rather than to a
   fixed measure, so Japanese (short labels) and English (long ones) each get
   what they need without a locale switch. */

/* The school's own pages, set as quietly as the guide can manage: grey marks
   in hairline circles, coming forward only under the cursor. The website is
   first and a shade darker — it is the one link the guide exists to hand over
   — but it is not a button. */
.side-links { margin-top: 16px; }
.social-row { display: flex; flex-wrap: wrap; gap: 8px; }
.social-row a {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--n-200); color: var(--n-500);
  transition: border-color .25s, color .25s;
}
.social-row a:hover { border-color: var(--n-400); color: var(--p-900); }
.social-row a.is-site { border-color: var(--n-300); color: var(--p-800); }
.social-row a.is-site:hover { border-color: var(--p-900); color: var(--p-900); }

/* Contact list */
.contact-list { display: flex; flex-direction: column; gap: 2px; }
.contact-list a, .contact-list div.row {
  display: flex; align-items: center; gap: 12px; padding: 12px 0;
  border-bottom: 1px solid var(--n-200); font-size: 14px; color: var(--n-700);
}
.contact-list a:last-child, .contact-list div.row:last-child { border-bottom: 0; }
.contact-list svg { flex-shrink: 0; color: var(--n-400); }
.contact-list a:hover { color: var(--a-500); }

/* Profile CTA band */
.cta-band { position: relative; overflow: hidden; background: var(--brand); padding-block: 72px; text-align: center; }
.cta-band .glow { position: absolute; inset: 0; opacity: .12; }
.cta-band .glow i {
  position: absolute; top: -80px; left: 50%; transform: translateX(-50%);
  width: 384px; height: 384px; border-radius: 50%; background: var(--a-400); filter: blur(64px);
}
.cta-band .inner { position: relative; z-index: 1; }
.cta-band h2 { font-size: clamp(1.5rem, 1rem + 2vw, 2.25rem); font-weight: 600; color: #fff; letter-spacing: -.02em; text-wrap: balance; }
.cta-band p { margin: 16px auto 0; max-width: 40ch; font-size: 17px; color: var(--n-300); }
.cta-band .actions { margin-top: 32px; display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

/* ==========================================================================
   12. HOME + CONTENT PAGES
   ========================================================================== */
/* ---------- Feature hero ----------
   Built the way the Michelin Guide builds theirs, and for the same reasons:

   1. The photograph is an OBJECT placed on the page, not wallpaper. On a wide
      window it is anchored to the right edge and sized by the hero's HEIGHT,
      keeping its own aspect ratio. Window width only decides how much of its
      left side is visible — it never re-crops vertically, so the image does
      not "move" as the window resizes.
   2. The field behind it matches the artwork's own black — carried per slide
      via --hero-field, set inline at build time and updated by the swap
      script. The photo simply ends and the field continues; no seam.
   3. No dimming overlay, ever. The copy sits on the field, never on the
      photograph, so nothing has to be greyed down to stay legible.
   4. Below 1200px the SAME construction stacks instead of cropping: copy on
      the field, then the photograph shown whole, then the credit. The
      artwork is never cropped and never sits under text at any width.
   5. The left column — headline, search, credit — keeps one inset and one
      vertical rhythm at every width. */
.hero-feature {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--hero-field, #01050F);
}

/* One slide per visit, picked at random before first paint. Only the chosen
   one is painted; there is nothing to fade between. */
.hero-slide { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.hero-slide.is-current { opacity: 1; pointer-events: auto; }

.hero-content { position: relative; z-index: 1; width: 100%; }
.hero-foot { position: relative; z-index: 1; width: 100%; }

/* Side by side wherever the copy column fits (≥900px): photo floats right of
   the copy. Between 900 and 1200 both columns tighten rather than stacking —
   stacking that early strands a small photo in a wide empty field. */
@media (min-width: 900px) {
  /* The hero's height follows the WIDTH as well as the window height. The
     photo is capped at 56% of the width, so on narrower windows a purely
     vh-driven hero leaves the width-limited photo floating in the middle of
     a too-tall field, far above the credit. 45vw keeps the 4:3 artwork at
     ~92% of the hero's height at every width, so the composition holds. */
  .hero-feature { min-height: clamp(500px, min(80vh, 45vw), 900px); }
  .hero-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
  .hero-media img {
    position: absolute;
    top: 50%; right: 0;
    transform: translateY(-50%);
    height: 92%;
    width: auto;
    /* Hard stop so it cannot reach across into the copy column. */
    max-width: 56%;
    object-fit: contain;
    object-position: right center;
    /* Safety net. The real feather is baked into the artwork by
       tools/blend-hero.py; this catches anything dropped in unprocessed so a
       hard rectangle never appears on the page. */
    -webkit-mask-image: radial-gradient(ellipse 88% 88% at 50% 50%, #000 68%, rgba(0,0,0,0) 100%);
    mask-image: radial-gradient(ellipse 88% 88% at 50% 50%, #000 68%, rgba(0,0,0,0) 100%);
  }
  /* Two auto margins split the free space: the headline block settles near
     the optical centre and the credit pins to the bottom, at every height. */
  .hero-content { margin-top: auto; padding-top: 48px; }
  .hero-foot { margin-top: auto; padding-bottom: 48px; }
}
@media (min-width: 900px) and (max-width: 1199px) {
  .hero-feature { min-height: clamp(440px, min(68vh, 40vw), 700px); }
  .hero-feature .hero-inner { max-width: 23rem; }
  .hero-media img { max-width: 48%; height: 86%; }
}

/* Below 900px the copy column no longer fits beside the photo, so the same
   object-on-field idea stacks: the photo keeps its own aspect ratio inside a
   full-width band of the field — whole, uncropped, never underneath the copy.
   No scrim exists at any width. */
@media (max-width: 899px) {
  .hero-content { order: 1; padding-top: 44px; }
  .hero-media {
    order: 2;
    position: relative;
    height: min(72vw, 540px);
    margin-top: 32px;
  }
  .hero-media img { width: 100%; height: 100%; object-fit: contain; object-position: center; }
  .hero-foot { order: 3; padding-block: 20px 32px; }
}

.hero-empty {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(90% 120% at 78% 45%, #3d4750 0%, rgba(61,71,80,0) 62%),
    linear-gradient(120deg, #101418 0%, #1d242b 58%, #2b343d 100%);
}
@media (min-width: 900px) {
  .hero-empty { left: auto; width: 52%; }
}

.hero-feature .hero-inner { max-width: 30rem; }

/* The kicker names the product so the headline is free to invite. */
.hero-kicker {
  margin-bottom: 18px;
  font-size: 11px; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(var(--hero-ink, 255, 255, 255), .55);
}

/* Restrained by design: the headline sits at reading scale, not poster scale,
   so the artwork carries the frame rather than the type.
   All hero text draws from --hero-ink (an R,G,B triple set per slide), so a
   light field gets charcoal copy and a dark field gets white — automatically. */
.hero-title {
  font-family: var(--font-serif);
  font-size: clamp(1.625rem, 1rem + 1.35vw, 2.375rem);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.015em;
  color: rgb(var(--hero-ink, 255, 255, 255));
  text-wrap: balance;
}

/* Featured-school credit: a single lockup — mark beside the name — under a
   small standing label that explains what the position is. */
.hero-credits { padding-top: 24px; }
.hero-credits .feat {
  display: block; margin-bottom: 14px;
  font-size: 10px; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: rgba(var(--hero-ink, 255, 255, 255), .45);
}
/* Slides stack in the same spot; only the current one is painted. */
.credit-stack { position: relative; }
.hero-credit {
  display: flex; align-items: center; gap: 16px;
  color: rgba(var(--hero-ink, 255, 255, 255), .9);
  opacity: 0;
}
.hero-credit:not(:first-child) { position: absolute; inset: 0 0 auto 0; }
.hero-credit.is-current { opacity: 1; }

.hero-credit .who { min-width: 0; }
.hero-credit .name { display: inline-block; }
@media (min-width: 900px) { .hero-credit .name { white-space: nowrap; } }

.hero-credit .mark {
  display: block; flex: none;
  width: auto; height: 64px;
}
@media (max-width: 767px) { .hero-credit .mark { height: 52px; } }
.hero-credit .who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.hero-credit .name { font-size: 15px; font-weight: 500; color: rgb(var(--hero-ink, 255, 255, 255)); }
a.hero-credit .name:hover, .hero-credit a.name:hover { text-decoration: underline; text-underline-offset: 3px; }
.hero-credit .place { font-size: 14px; color: rgba(var(--hero-ink, 255, 255, 255), .72); }
.hero-credit .copy { margin-top: 2px; font-size: 11px; color: rgba(var(--hero-ink, 255, 255, 255), .42); }

.hero-feature .search-field input {
  padding-block: 14px;
  font-size: 15px;
  border-color: transparent;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .28);
}
.hero-feature .search-field svg { left: 18px; }
.hero-feature .search-field input { padding-left: 48px; }

/* The credit sits at one end of the hero's foot and the way in at the other,
   both on the same baseline. Set in the hero's own ink so it holds on a light
   photograph and a dark one alike — the rule under it is what makes it read
   as an action rather than a caption. */
.hero-foot {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px 40px; flex-wrap: wrap;
}
/* The credit takes the room; the link asks for none of it. Without this the
   credit shrinks to whatever is left and the school's name wraps. */
.hero-credits { flex: 1 1 auto; min-width: 0; max-width: 42rem; }
.hero-cta { flex: 0 0 auto; }
.hero-cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding-bottom: 2px; border-bottom: 1px solid rgba(var(--hero-ink, 255, 255, 255), .3);
  font-size: 15px; font-weight: 500;
  color: rgba(var(--hero-ink, 255, 255, 255), .9);
  transition: border-color .2s ease, color .2s ease;
}
.hero-cta:hover {
  color: rgba(var(--hero-ink, 255, 255, 255), 1);
  border-bottom-color: rgba(var(--hero-ink, 255, 255, 255), .8);
}
.hero-cta svg { transition: transform .2s ease; }
.hero-cta:hover svg { transform: translateX(3px); }
@media (max-width: 640px) { .hero-foot { align-items: flex-start; } }
/* The bar is filters alone now, so it does not need the room two rows took. */
.directory-bar .filter-bar { margin-top: 0; }
.hero-actions { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 12px; }

.stat-row {
  display: grid; gap: 24px; margin-top: 56px;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 768px) { .stat-row { grid-template-columns: repeat(4, 1fr); } }
.stat .n { font-family: var(--font-serif); font-size: 32px; font-weight: 700; color: var(--p-900); line-height: 1; }
.stat .l { margin-top: 6px; font-size: 13px; color: var(--n-500); }

/* ---------- 12b. FRONT PAGE ----------
   Three editorial bands under the hero. The register borrows what makes a
   curated index feel curated — few items in view, no chrome competing with
   content, one line of metadata per item, slow motion — expressed entirely
   in this site's own tokens. */

/* Magazine: lead article + latest column. */
.front-mag { background: #fff; padding-block: 72px; }
.mag-wrap { display: grid; gap: 48px; grid-template-columns: 1fr; }
@media (min-width: 1000px) { .mag-wrap { grid-template-columns: 1.6fr 1fr; gap: 64px; } }
.mag-lead { display: block; }
.mag-lead .thumb {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 16/9; margin-bottom: 24px;
  background: linear-gradient(135deg, var(--n-100), var(--n-200));
  overflow: hidden;
}
.mag-lead .thumb .img-spec { color: var(--n-500); text-shadow: none; }
.mag-lead .kicker {
  font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--a-400); margin-bottom: 10px;
}
.mag-lead h2 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  font-weight: 700; line-height: 1.15; letter-spacing: -.02em; color: var(--p-900);
  transition: color .3s;
}
.mag-lead:hover h2 { color: var(--a-500); }
.mag-lead .ex { margin-top: 14px; font-size: 1.0625rem; line-height: 1.7; color: var(--n-700); max-width: 56ch; }
.mag-lead .m { margin-top: 12px; font-size: 12px; color: var(--n-400); }

.mag-col-h {
  font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--n-500); padding-bottom: 12px; border-bottom: 2px solid var(--p-900); margin-bottom: 4px;
}
.mag-item { display: block; padding: 18px 0; border-bottom: 1px solid var(--n-200); }
.mag-item .k {
  font-size: 10px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--a-400); margin-bottom: 6px;
}
.mag-item h3 { font-family: var(--font-serif); font-size: 1.125rem; font-weight: 700; line-height: 1.35; color: var(--p-900); transition: color .2s; }
.mag-item:hover h3 { color: var(--a-500); }
.mag-item .m { margin-top: 6px; font-size: 12px; color: var(--n-400); }
.mag-col > .link-arrow { margin-top: 20px; }

/* The guide band: school entries. Three in view where the grid could hold
   four — the space is the point. Same ground as the bands around it; only a
   hairline marks the change of subject. */
.front-guide { background: #fff; padding-block: 96px 104px; }
.front-guide .section-head { margin-bottom: 40px; }

.entry-track {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: calc((100% - 2 * 40px) / 3);
  gap: 40px;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  padding-bottom: 8px;
}
@media (max-width: 1100px) { .entry-track { grid-auto-columns: calc((100% - 32px) / 2); gap: 32px; } }
@media (max-width: 640px) { .entry-track { grid-auto-columns: 82%; gap: 24px; } }

.school-entry { display: block; scroll-snap-align: start; }
.entry-media { display: block; overflow: hidden; }
.entry-media img, .entry-ph {
  display: flex; align-items: center; justify-content: center;
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  transition: transform 1.2s cubic-bezier(.2, .6, .2, 1), filter .8s ease;
}
/* The treated photograph: every school's artwork renders in one muted
   monochrome, so different photographers still produce one collection.
   Colour returns on hover — the school answers when addressed. */
.entry-media img { filter: grayscale(1) contrast(.92) brightness(1.04); }
.school-entry:hover .entry-media img { filter: none; }
.school-entry:hover .entry-media img, .school-entry:hover .entry-ph { transform: scale(1.04); }
.entry-name {
  display: block; margin-top: 18px;
  font-family: var(--font-serif); font-size: 1.1875rem; font-weight: 700;
  letter-spacing: -.01em; line-height: 1.3; color: var(--p-900);
  transition: color .3s;
}
.school-entry:hover .entry-name { color: var(--a-500); }
.entry-loc {
  display: block; margin-top: 6px;
  font-size: 11px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--n-500);
}

/* Ways into the guide: bare words, generously spaced. The underline exists
   only when addressed. */
.entry-cats { margin-top: 48px; display: flex; flex-wrap: wrap; gap: 12px 36px; align-items: baseline; }
.entry-cats a {
  font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  color: var(--n-500); padding-bottom: 3px; border-bottom: 1px solid transparent;
  transition: color .3s, border-color .3s;
}
.entry-cats a:hover { color: var(--p-900); border-color: var(--n-400); }

/* School-side call, on the same ground as everything else: the change of
   audience is carried by the copy and the accent button, not by a plate. */
.front-cta { background: #fff; padding-block: 8px 112px; }

/* Diary: the sections still growing, listed plainly. */
/* --- front page: the fairs -------------------------------------------------
   A schedule. The date is the largest thing in the row because a fair is a
   date before it is anything else, and beneath the line sit the marks of the
   schools who will be in the room — small enough to read as a footnote, large
   enough to recognise. */
.front-fairs { background: #fff; padding-block: 8px 96px; }
.front-fairs .section-head { margin-bottom: 34px; }
.fair-list { border-top: 1px solid var(--n-200); }
.fair-row {
  display: grid; grid-template-columns: 1fr; gap: 10px;
  padding-block: 30px; border-bottom: 1px solid var(--n-200);
}
@media (min-width: 760px) {
  .fair-row { grid-template-columns: 150px minmax(0, 1fr) auto; gap: 40px; align-items: start; }
}
/* The date on one line and the weekday under it: two complete statements,
   not three fragments. Tabular figures so the numerals stack cleanly down a
   column of fairs, and the whole block aligned to the same left edge as the
   title beside it — a date is read from its first character, so that is the
   edge that matters. */
.fair-row .when { line-height: 1.2; }
.fair-row .dt {
  display: block;
  font-family: var(--font-serif); font-size: 1.5rem; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
  color: var(--p-900); white-space: nowrap;
}
.fair-row .wd {
  display: block; margin-top: 6px;
  font-size: 13px; color: var(--n-500);
}
/* Only printed when the fair is not in the current year. */
.fair-row .yr { margin-left: 8px; font-variant-numeric: tabular-nums; color: var(--n-400); }
.fair-row .next {
  display: inline-block; margin-bottom: 9px; padding: 2px 9px; border-radius: var(--r-full);
  background: var(--brand); color: #fff; font-size: 10px; font-weight: 600; letter-spacing: .1em;
}
.fair-row .ttl {
  display: block; font-family: var(--font-serif); font-size: 1.25rem; font-weight: 700;
  color: var(--p-900); transition: color .2s;
}
.fair-row .ttl .city { margin-left: 12px; font-size: 13px; font-weight: 400; color: var(--n-500); }
.fair-row:hover .ttl { color: var(--a-500); }
.fair-row .sub { display: block; margin-top: 7px; font-size: 13.5px; line-height: 1.7; color: var(--n-600); }
.fair-row .state {
  font-size: 13px; font-weight: 500; color: var(--n-500); white-space: nowrap; transition: color .2s;
}
.fair-row:hover .state { color: var(--p-900); }

/* The schools, at footnote size. One box each so a wordmark and a shield read
   as the same object, the way they do on the fair page itself. */
.fair-who { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 16px; }
.fair-who .m {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; opacity: .75; transition: opacity .2s;
}
.fair-row:hover .fair-who .m { opacity: 1; }
.fair-who .m img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.fair-who .m .mono {
  font-family: var(--font-serif); font-size: 11px; font-weight: 700;
  letter-spacing: .03em; color: var(--n-300);
}
.fair-who .more { font-size: 11px; color: var(--n-400); }

.front-diary { background: #fff; padding-block: 8px 96px; }
.diary { max-width: 56rem; }
.diary-row {
  display: grid; grid-template-columns: 10rem 1fr auto; gap: 24px;
  align-items: baseline; padding: 22px 0; border-bottom: 1px solid var(--n-200);
}
@media (max-width: 640px) { .diary-row { grid-template-columns: 1fr; gap: 6px; } }
.diary-row .w {
  font-size: 11px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--a-400);
}
.diary-row h3 { font-family: var(--font-serif); font-size: 1.25rem; font-weight: 700; color: var(--p-900); }
.diary-row p { margin-top: 4px; font-size: 14px; color: var(--n-500); }
.diary-row .go { font-size: 13px; font-weight: 500; color: var(--n-500); white-space: nowrap; transition: color .2s; }
.diary-row:hover .go { color: var(--p-900); }

.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 32px; }
.section-head .h2 { font-size: 1.75rem; }
.section-head p { margin-top: 8px; font-size: 15px; color: var(--n-500); max-width: 52ch; }

.rail { display: grid; gap: 24px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .rail { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .rail { grid-template-columns: repeat(3, 1fr); } }

.article-card {
  display: flex; flex-direction: column; height: 100%;
  overflow: hidden; border-radius: var(--r-lg); background: #fff;
  box-shadow: var(--sh-card); transition: box-shadow .3s;
}
.article-card:hover { box-shadow: var(--sh-card-hover); }
.article-card .thumb {
  aspect-ratio: 16 / 9; background: linear-gradient(135deg, var(--n-100), var(--n-200));
  display: flex; align-items: center; justify-content: center; color: var(--n-400);
}
.article-card .body { display: flex; flex: 1; flex-direction: column; padding: 20px; }
.article-card .kicker {
  font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--a-400); margin-bottom: 8px;
}
.article-card h3 { font-family: var(--font-serif); font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--p-900); }
.article-card p { margin-top: 8px; font-size: 14px; line-height: 1.6; color: var(--n-500); }
.article-card .foot { margin-top: auto; padding-top: 16px; font-size: 12px; color: var(--n-400); }

.feature-grid { display: grid; gap: 24px; grid-template-columns: 1fr; }
@media (min-width: 768px) { .feature-grid { grid-template-columns: repeat(3, 1fr); } }
.feature {
  border: 1px solid var(--n-200); border-radius: var(--r-lg); background: #fff; padding: 28px;
}
.feature .ico {
  display: flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: var(--r-lg);
  background: var(--a-50); color: var(--a-400); margin-bottom: 16px;
}
.feature h3 { font-family: var(--font-serif); font-size: 18px; font-weight: 700; color: var(--p-900); }
.feature p { margin-top: 8px; font-size: 14px; line-height: 1.7; color: var(--n-500); }

/* Pricing */
.price-grid { display: grid; gap: 24px; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 900px) { .price-grid { grid-template-columns: repeat(3, 1fr); } }
.price-card {
  border: 1px solid var(--n-200); border-radius: var(--r-lg); background: #fff; padding: 32px;
}
.price-card.featured { border-color: var(--a-400); box-shadow: 0 8px 28px rgba(196,30,36,.08); }
.price-card .tier { font-size: 12px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--n-500); }
.price-card .amount { margin-top: 12px; font-family: var(--font-serif); font-size: 34px; font-weight: 700; color: var(--p-900); }
.price-card .amount small { font-family: var(--font-sans); font-size: 14px; font-weight: 400; color: var(--n-400); }
.price-card .desc { margin-top: 8px; font-size: 14px; color: var(--n-500); }
.price-card ul { margin: 24px 0; display: flex; flex-direction: column; gap: 10px; }
.price-card ul li { display: flex; gap: 10px; font-size: 14px; color: var(--n-600); }
.price-card ul li svg { flex-shrink: 0; margin-top: 3px; color: var(--a-400); }

/* Static/legal page */
.doc { max-width: 46rem; }
.doc h1 { font-family: var(--font-serif); font-size: 2rem; font-weight: 700; color: var(--p-900); margin-bottom: 8px; }
.doc .updated { font-size: 13px; color: var(--n-400); margin-bottom: 40px; }

.notice {
  display: flex; gap: 12px; border-radius: var(--r-lg);
  border: 1px solid var(--n-200); background: #fff; padding: 16px 18px;
}
.notice svg { flex-shrink: 0; margin-top: 2px; color: var(--a-400); }
.notice p { font-size: 14px; line-height: 1.65; color: var(--n-800); }

/* ---------- 13. Animation ---------- */
/* Scoped to .js so content stays visible if JavaScript is unavailable. */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal { opacity: 0; transform: translateY(20px); }
  .js .reveal.in { opacity: 1; transform: none; transition: opacity .6s ease-out, transform .6s ease-out; }
}

/* ---------- 14. Print ---------- */
@media print {
  .site-header, .site-footer, .tab-nav, .directory-bar, .profile-side, .cta-band { display: none !important; }
  body { background: #fff; }
}


/* ---- Design-mode placeholders ----
   Visible only while SHOW_EMPTY is on. Deliberately unlike real content: a
   dashed outline, a monospace label, no serif and no black. Nothing here
   should ever be mistaken for something a school has supplied. */
.slot {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  margin: 12px 0; padding: 10px 14px;
  border: 1px dashed var(--n-300); border-radius: var(--r-md);
  background: repeating-linear-gradient(135deg, transparent, transparent 7px, rgba(0,0,0,.015) 7px, rgba(0,0,0,.015) 14px);
}
.slot-k {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--n-500);
}
.slot-n {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px; line-height: 1.6; color: var(--n-400);
}
/* Compact in the rail: scaffolding must not be what pushes real content below
   the fold. */
.profile-side .slot { margin: 8px 0; padding: 5px 11px; }
.profile-side .slot-n { display: none; }

.slot-inline {
  display: inline-block; padding: 0 6px;
  border: 1px dashed var(--n-300); border-radius: var(--r-sm, 3px);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--n-400);
}

/* ---- Accreditation marks ----
   A mark and a name. The mark is the thing people recognise, so it is given
   real room and a quiet frame; until the artwork arrives the slot states what
   it expects, like every other image slot on the site. */
.accred-grid { display: grid; gap: 14px; grid-template-columns: 1fr; margin-top: 4px; }
@media (min-width: 640px) { .accred-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.accred {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 16px; border: 1px solid var(--n-200); border-radius: var(--r-lg); background: #fff;
}
.accred-mark {
  display: grid; place-items: center; flex-shrink: 0;
  width: 96px; aspect-ratio: 2 / 1; overflow: hidden;
  background: var(--n-50); border-radius: var(--r-md);
}
.accred-mark img { max-width: 100%; max-height: 100%; object-fit: contain; }
.accred-mark .img-spec { color: var(--n-500); text-shadow: none; }
.accred-body { min-width: 0; }
.accred-body .name { display: block; font-size: 14px; font-weight: 600; line-height: 1.45; color: var(--p-900); }
.accred-body .sub { display: block; margin-top: 3px; font-size: 12px; color: var(--n-500); }
/* The level a school holds with the body — accredited, recognised, member. */
.accred-status {
  display: inline-block; margin-top: 5px; padding: 1px 8px;
  border: 1px solid var(--n-300); border-radius: var(--r-full);
  font-size: 11px; font-weight: 500; letter-spacing: .02em; color: var(--p-800);
}

/* ---- Destination cards ----
   The directory's register card at a smaller size: same mark, same name, same
   locator line, narrower and quieter, so a list of leavers' schools reads as
   part of the guide rather than as a table of names. */
.dest-grid { display: grid; gap: 24px 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 4px; }
@media (min-width: 640px) { .dest-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .dest-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.school-card.mini { padding: 0; text-align: center; }
.school-card.mini .card-mark { height: 48px; margin-bottom: 12px; }
.school-card.mini .card-mark img { max-height: 48px; max-width: 80px; }
.school-card.mini .card-mono { width: 44px; height: 44px; font-size: 1rem; }
.school-card.mini .card-title { font-size: .9375rem; line-height: 1.35; }
.school-card.mini .card-loc { margin-top: 5px; font-size: 9px; letter-spacing: .12em; }

/* ---- Profile gallery ----
   Its own band between Overview and Admissions. The lead photograph takes two
   columns and two rows; the rest flow around it, so the arrangement holds at
   six pictures or at ten without a special case for each count. */
.profile-gallery { margin: 8px 0 64px; }
.profile-gallery .gallery {
  display: grid; gap: 10px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 700px) {
  .profile-gallery .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
  .profile-gallery .gallery > button:first-child { grid-column: span 2; grid-row: span 2; }
}
.profile-gallery .gallery > button {
  display: block; padding: 0; border: 0; overflow: hidden; cursor: zoom-in;
  background: var(--n-100); aspect-ratio: 4 / 3;
}
.profile-gallery .gallery img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .6s cubic-bezier(.2,.6,.2,1), filter .6s;
}
.profile-gallery .gallery > button:hover img { transform: scale(1.03); }
.profile-gallery .gallery > button:focus-visible { outline: 2px solid var(--p-900); outline-offset: 2px; }

/* ---- Entrance tests ----
   One block per test: what it is, who sits it, and what clears the bar. The
   benchmark line is always drawn, because "no minimum published" is the answer
   more often than a number is, and a family needs to know that. */
.adm-tests { margin-top: 12px; display: grid; gap: 18px; }
@media (min-width: 700px) { .adm-tests { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 28px; } }
.adm-test { padding-left: 14px; border-left: 1px solid var(--n-200); }
.adm-test .tname { font-size: 14px; font-weight: 600; color: var(--p-900); }
.adm-test .tgloss { margin-top: 5px; font-size: 12.5px; line-height: 1.75; color: var(--n-500); }
/* Label and value form one grid across both rows of a card, so a value that
   wraps stays in its own column instead of running back under its label.
   Same contents-in-a-grid pattern as .pr-facts on the profile rail. */
.adm-test .tmetas {
  margin-top: 7px;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 10px;
  row-gap: 7px;
}
.adm-test .tmeta { display: contents; }
.adm-test .tmeta > span:first-child {
  font-size: 11px; letter-spacing: .04em; line-height: 1.9;
  color: var(--n-400); white-space: nowrap;
}
.adm-test .tmeta > span + span { font-size: 13px; line-height: 1.7; color: var(--n-800); }


/* --- imported series: what a piece is, and where it came from -------------
   A sponsored piece says so on the card and again at the top of the article.
   The draft mark is loud on purpose: nothing carrying it has been cleared. */
.tag-sponsored, .tag-draft {
  display: inline-block; margin-left: 10px; padding: 2px 8px;
  border-radius: var(--r-full); font-size: 10px; font-weight: 600;
  letter-spacing: .06em; text-transform: none; vertical-align: 1px;
}
.tag-sponsored { background: var(--n-100); color: var(--n-500); }
.tag-draft { background: #FDECEC; color: var(--a-500); }
.art-flags { margin-top: 18px; }
.art-flags .tag-sponsored { margin-left: 0; }

/* The data box the original carried, replaced by the school itself. */
.art-school { margin-top: 48px; padding-top: 28px; border-top: 1px solid var(--n-200); }
.art-school .k {
  font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--n-500); margin-bottom: 14px;
}
.art-school-card {
  display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 18px;
  align-items: center; padding: 18px 20px;
  border: 1px solid var(--n-200); background: #fff;
  transition: border-color .2s, background-color .2s;
}
@media (min-width: 640px) { .art-school-card { grid-template-columns: 56px minmax(0, 1fr) auto; } }
.art-school-card:hover { border-color: var(--n-400); background: var(--n-50); }
.art-school-card .mark {
  display: flex; align-items: center; justify-content: center; width: 56px; height: 56px;
}
.art-school-card .mark img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.art-school-card .mark .mono {
  font-family: var(--font-serif); font-size: 18px; font-weight: 700; color: var(--n-300);
}
.art-school-card .nm {
  display: block; font-family: var(--font-serif); font-size: 1.0625rem;
  font-weight: 700; line-height: 1.4; color: var(--p-900);
}
.art-school-card:hover .nm { color: var(--a-500); }
.art-school-card .pl { display: block; margin-top: 4px; font-size: 12.5px; color: var(--n-500); }
.art-school-card .go {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 500; color: var(--n-500); white-space: nowrap;
}

.art-source { margin-top: 26px; font-size: 13px; line-height: 1.8; color: var(--n-500); }
.art-source a { color: var(--a-400); text-decoration: underline; text-underline-offset: 3px; }

/* Said once, above the text, rather than repeated down the page. */
.art-note {
  margin-top: 22px; padding: 12px 16px;
  border-left: 2px solid var(--n-300); background: var(--n-50);
  font-size: 13px; line-height: 1.75; color: var(--n-600);
}


/* --- magazine: filter by series ------------------------------------------
   The same bar as the school guide: it is the same action on the same kind
   of page, so it is the same object. Only the band's offset differs, because
   the magazine has no search row above it. */
.mag-bar { top: 76px; }
.mag-filters { border-top: 0; }
.mag-empty { margin-top: 8px; font-size: 14px; line-height: 1.7; color: var(--n-500); }

/* Sections still to come keep their release note below the navigation label. */
.nav-link.is-soon { color: var(--n-400); cursor: default; }
.nav-link.is-soon:hover { color: var(--n-400); }
.nav-link.is-soon::after { display: none; }
.has-status .soon {
  padding: 2px 7px; border-radius: var(--r-full);
  background: var(--n-100); color: var(--n-500);
  font-size: 10px; font-weight: 600; line-height: 1.2; letter-spacing: .04em;
}
