/* =====================================================================
 * M3A (Issue #115 `5807030002`) — reference-replica shell + section rhythm.
 *
 * Implements the approved education-commerce layout: utility row + sticky
 * header + multi-column mega menu, a main column beside a sticky consultation
 * rail, a persistent desktop quick rail, a mobile bottom conversion bar, and
 * the card grids the long sales page is built from.
 *
 * RULES THIS FILE KEEPS
 *   - NO marketing image is declared here. Every photographic surface is an
 *     <img> built by media-surface.js from an editable media record; this file
 *     only sizes the box. The single gradient below is an abstract empty-state
 *     tint, not a picture.
 *   - Interactive targets are >= 44px; :focus-visible is always drawn.
 *   - Every transition is disabled under prefers-reduced-motion.
 *   - Sizes are rem/ch-based so 200% text zoom reflows instead of clipping.
 * ===================================================================== */

:root {
  /* M3A-V3-R2 — measured, not chosen: the reference's content column is
   * 1248px at a 1440 viewport (1200 grid + 24px gutters). Ours was 1200, so
   * every row was 48px narrower than the thing it is being compared with. */
  --m3-max: 1248px;
  --m3-rail: 320px;
  --m3-gap: 28px;
  --m3-ink: #111827;
  --m3-muted: #4b5563;
  --m3-line: #e5e7eb;
  --m3-brand: #1d4ed8;
  --m3-brand-ink: #1e3a8a;
  --m3-bg-soft: #f8fafc;
  --m3-radius: 12px;
  --m3-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 8px 24px rgba(15, 23, 42, .06);
}

/* ── utility row ─────────────────────────────────────────────────────── */
.site-utility { border-bottom: 1px solid var(--m3-line); background: #fff; }
.site-utility .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 44px; }
.site-utility-brand { margin: 0; font-size: .8125rem; color: var(--m3-muted); }
.site-utility-links { display: flex; gap: 14px; margin: 0; padding: 0; list-style: none; }
.site-utility-links a { font-size: .8125rem; color: var(--m3-muted); text-decoration: none; line-height: 44px; min-height: 44px; }
.site-utility-links a:hover { color: var(--m3-brand-ink); text-decoration: underline; }
@media (max-width: 899px) { .site-utility { display: none; } }

/* ── mega menu ───────────────────────────────────────────────────────── */
.mega-panel {
  position: absolute; left: 0; right: 0; z-index: 60;
  background: #fff; border-top: 1px solid var(--m3-line); border-bottom: 1px solid var(--m3-line);
  box-shadow: var(--m3-shadow);
}
.mega-panel[hidden] { display: none; }
/* M3A-V3-R2 — geometry taken from the reference panel at 1440 (inner 1248px,
 * padding 28/24/34, 24px column gap, 15px course rows). The column COUNT comes
 * from the records via `--mega-cols`, so adding or archiving a field in admin
 * re-grids the menu instead of stretching six fixed tracks. */
.mega-inner { max-width: var(--m3-max); margin: 0 auto; padding: 28px 24px 34px; }
.mega-cols {
  display: grid;
  grid-template-columns: repeat(var(--mega-cols, 6), minmax(0, 1fr));
  gap: 24px;
}
.mega-col { min-width: 0; }
.mega-col-head { display: block; text-decoration: none; color: inherit; padding: 6px 0; min-height: 44px; }
.mega-col-title { display: block; font-weight: 800; font-size: .9375rem; color: var(--m3-ink); }
.mega-col-blurb { display: block; font-size: .75rem; color: var(--m3-muted); margin-top: 2px; word-break: keep-all; }
.mega-col-all { display: inline-block; margin-top: 6px; font-size: .75rem; font-weight: 700; color: var(--m3-brand); }
.mega-col-media { display: block; margin: 8px 0; }
.mega-col-list { list-style: none; margin: 8px 0 0; padding: 0; border-top: 1px solid var(--m3-line); }
.mega-col-list li { border-bottom: 1px dashed var(--m3-line); }
.mega-col-list a {
  display: block; padding: 9px 0; font-size: .8125rem; line-height: 1.35; color: var(--m3-muted);
  text-decoration: none; min-height: 44px; word-break: keep-all;
}
.mega-col-list a:hover { color: var(--m3-brand-ink); text-decoration: underline; }
/* The reference sets course rows at 15px / 34px. Matching it is what makes a
 * column read as a course LIST rather than as a paragraph of links. */
.mega-col-list a { font-size: .9375rem; line-height: 1.5; }
.mega-col-empty { font-size: .75rem; color: #6b7280; margin: 10px 0 0; }
.mega-foot { margin: 16px 0 0; font-size: .75rem; color: var(--m3-muted); border-top: 1px solid var(--m3-line); padding-top: 10px; }
@media (max-width: 1023px) { .mega-panel { display: none !important; } }

/* ── current / selected state ────────────────────────────────────────── */
/* Selected on the attribute the screen reader already uses, so the visual and
 * the announced state can never drift apart. Colour is not the only signal:
 * the underline carries it for a reader who cannot separate the two hues. */
header.site #main-nav a[aria-current="page"],
.site-utility-links a[aria-current="page"],
.drawer-families a[aria-current="page"] {
  color: var(--m3-brand-ink);
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.mega-col-head[aria-current="page"] .mega-col-title { color: var(--m3-brand-ink); text-decoration: underline; text-underline-offset: 4px; }

/* ── mobile drawer enrichment ────────────────────────────────────────── */
.drawer-families { display: none; }
@media (max-width: 899px) {
  .drawer-families { display: block; border-top: 1px solid var(--m3-line); margin-top: 8px; padding-top: 8px; }
  .drawer-head { margin: 10px 0 4px; font-size: .75rem; font-weight: 800; color: var(--m3-muted); letter-spacing: .04em; }
  .drawer-families ul { list-style: none; margin: 0; padding: 0; }
  .drawer-families a {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    min-height: 44px; padding: 4px 2px; text-decoration: none; color: var(--m3-ink); font-size: .9375rem;
  }
  .drawer-count { font-size: .75rem; color: var(--m3-muted); }
  /* 분야 → 과정 disclosure. 44px rows because this is the phone surface, and a
   * marker that rotates so the open/closed state is visible without colour. */
  .drawer-fam > details > summary {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    min-height: 44px; padding: 0 2px; cursor: pointer;
    font-size: .9375rem; font-weight: 700; color: var(--m3-ink);
    list-style: none;
  }
  .drawer-fam > details > summary::-webkit-details-marker { display: none; }
  .drawer-fam > details > summary::after {
    content: ''; width: 9px; height: 9px; flex: none; margin-left: auto;
    border-right: 2px solid var(--m3-muted); border-bottom: 2px solid var(--m3-muted);
    transform: rotate(45deg); transition: transform .15s ease;
  }
  .drawer-fam > details[open] > summary::after { transform: rotate(-135deg); }
  .drawer-courses { list-style: none; margin: 0 0 6px; padding: 0 0 0 10px; border-left: 2px solid var(--m3-line); }
  .drawer-courses a { min-height: 44px; display: flex; align-items: center; font-size: .875rem; color: var(--m3-muted); }
  .drawer-courses .drawer-all { font-weight: 700; color: var(--m3-brand); }
  @media (prefers-reduced-motion: reduce) {
    .drawer-fam > details > summary::after { transition: none; }
  }
}

/* ── two-column body (main + sticky rail) ────────────────────────────── */
.m3-shell { max-width: var(--m3-max); margin: 0 auto; padding: 0 20px; }
.m3-cols { display: grid; grid-template-columns: minmax(0, 1fr) var(--m3-rail); gap: var(--m3-gap); align-items: start; }
/* The sticky CONSULTATION aside. This kept its original name; a blanket rename
 * had briefly given it to the horizontal rail below, which then inherited
 * `position: sticky` and grew the section it lives in from 1.7 to 7 viewports. */
.m3-rail { position: sticky; top: 96px; }
@media (max-width: 1023px) { .m3-cols { grid-template-columns: minmax(0, 1fr); } .m3-rail { position: static; } }

.rail-card { border: 1px solid var(--m3-line); border-radius: var(--m3-radius); padding: 16px; background: #fff; box-shadow: var(--m3-shadow); }
.rail-title { margin: 0 0 10px; font-size: 1rem; }
.rail-phones { list-style: none; margin: 0 0 8px; padding: 0; }
.rail-phones li { display: flex; align-items: center; justify-content: space-between; gap: 10px; border-bottom: 1px dashed var(--m3-line); }
.rail-campus { font-size: .8125rem; color: var(--m3-muted); }
/* M3A-C1 P1-2: the capture harness measured this link at 19px tall — the only
   target this Wave added below 44px. It is a phone number on a conversion rail,
   so it is exactly the wrong control to make hard to hit. */
.rail-phone { font-weight: 800; font-size: 1rem; color: var(--m3-brand-ink); text-decoration: none; min-height: 44px; display: inline-flex; align-items: center; }
.rail-hours { margin: 8px 0 12px; font-size: .75rem; color: var(--m3-muted); }
.rail-actions { display: grid; gap: 8px; }
.rail-btn {
  display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 14px;
  border: 1px solid var(--m3-brand); border-radius: 8px; color: var(--m3-brand); background: #fff;
  font-weight: 700; text-decoration: none; font-size: .9375rem;
}
.rail-btn--primary { background: var(--m3-brand); color: #fff; }
.rail-links { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 2px; }
.rail-links a { display: block; min-height: 44px; line-height: 44px; font-size: .8125rem; color: var(--m3-muted); text-decoration: none; }
.rail-links a:hover { color: var(--m3-brand-ink); text-decoration: underline; }

/* NO FLOATING DOCK AND NO FIXED BOTTOM BAR ARE DECLARED IN THIS FILE.
   quick-dock.js (>=1280px) and the accepted `.mobile-sticky` bar already own
   those two layers. A second of either would be clutter rather than
   convenience, so the reference sites' quick menu and bottom bar are satisfied
   by those accepted surfaces — see docs/fullsite/M3A_REFERENCE_PARITY_MATRIX.md.
   This file therefore declares `position: fixed` nowhere, which a gate asserts. */

/* ── media frames (the ONLY way an image renders) ────────────────────── */
.ms-frame {
  display: block; position: relative; overflow: hidden; border-radius: 10px;
  background: linear-gradient(135deg, #eef2f7, #e2e8f0);
}
.ms-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ms-empty {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: .75rem; color: #64748b; padding: 8px; text-align: center;
}
.ms-placeholder-mark {
  position: absolute; left: 6px; bottom: 6px; z-index: 1;
  background: rgba(17, 24, 39, .78); color: #fff; font-size: .625rem; line-height: 1;
  padding: 4px 6px; border-radius: 4px; letter-spacing: .02em;
}

/* ── section rhythm ──────────────────────────────────────────────────── */
.m3-sec { margin: 44px 0; }
.m3-sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.m3-sec-title { margin: 0; font-size: 1.375rem; letter-spacing: -.01em; }
.m3-sec-title small { display: block; font-size: .8125rem; font-weight: 500; color: var(--m3-muted); margin-top: 4px; }
.m3-sec-more { font-size: .8125rem; font-weight: 700; color: var(--m3-brand); text-decoration: none; min-height: 44px; display: inline-flex; align-items: center; }
/* The section link is three or four words; letting it wrap at a phone width
 * breaks it mid-word and reads as a layout fault, so it holds one line and
 * the title beside it takes the remaining room. */
.m3-sec-more { white-space: nowrap; flex: none; }
.m3-sec-head > :first-child { min-width: 0; }
.m3-empty { border: 1px dashed var(--m3-line); border-radius: var(--m3-radius); padding: 22px; text-align: center; color: var(--m3-muted); font-size: .875rem; }

/* family tabs */
.m3-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.m3-tab {
  min-height: 44px; padding: 0 14px; border: 1px solid var(--m3-line); background: #fff; color: var(--m3-ink);
  border-radius: 999px; font-size: .875rem; cursor: pointer;
}
.m3-tab[aria-selected="true"] { background: var(--m3-ink); color: #fff; border-color: var(--m3-ink); font-weight: 700; }

/* course cards */
.m3-course-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 14px; list-style: none; margin: 0; padding: 0; }
.m3-course-card { border: 1px solid var(--m3-line); border-radius: var(--m3-radius); overflow: hidden; background: #fff; display: flex; flex-direction: column; }
.m3-course-card a { text-decoration: none; color: inherit; display: flex; flex-direction: column; height: 100%; }
.m3-course-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.m3-course-fam { font-size: .6875rem; font-weight: 800; color: var(--m3-brand); }
.m3-course-title { font-size: .875rem; font-weight: 700; line-height: 1.35; word-break: keep-all; margin: 0; }
.m3-course-sum { font-size: .75rem; color: var(--m3-muted); line-height: 1.45; margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.m3-course-meta { margin-top: auto; font-size: .6875rem; color: #6b7280; }
@media (max-width: 1023px) { .m3-course-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 599px) { .m3-course-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* promo strip */
.m3-promo { display: block; border-radius: var(--m3-radius); overflow: hidden; text-decoration: none; color: inherit; border: 1px solid var(--m3-line); }
.m3-promo-body { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; background: #fff; }
.m3-promo-copy { font-size: .9375rem; font-weight: 700; margin: 0; word-break: keep-all; }
.m3-promo-cta { font-size: .8125rem; font-weight: 700; color: var(--m3-brand); white-space: nowrap; }

/* portfolio / facility / seminar grids */
.m3-tile-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; list-style: none; margin: 0; padding: 0; }
.m3-tile { border: 1px solid var(--m3-line); border-radius: var(--m3-radius); overflow: hidden; background: #fff; }
.m3-tile a, .m3-tile > div { text-decoration: none; color: inherit; display: block; }
.m3-tile-body { padding: 10px 12px 12px; }
/* M3A-V1 — these are <span>s carrying block spacing, so without an explicit
   display they ran together on one line: "AI 업무 자동화 화면 구성AI·데이터 & 마케팅".
   Found by looking at the filled tiles at page scale, which is what the image
   work made possible. Spacing only; the type scale and colours are unchanged. */
.m3-tile-title { display: block; font-size: .8125rem; font-weight: 700; margin: 0 0 2px; word-break: keep-all; }
.m3-tile-sum { display: block; font-size: .75rem; color: var(--m3-muted); margin: 0; line-height: 1.45; }
@media (max-width: 1023px) { .m3-tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 599px) { .m3-tile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* M3A-V2 — the learner-story card styles were REMOVED, not kept "for later".
   Nothing rendered them: no HTML carried .m3-story, no renderer produced one,
   and the four media records they were waiting for became learning scenes,
   which reuse .m3-tile-grid. A selector with no markup reads as a surface that
   exists, and that is exactly the confusion V1 shipped. When B5 (a verified
   learner interview with recorded consent) unblocks, its card gets designed
   then — against the layout of that day, not this one. */

/* trust strip */
.m3-trust { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; list-style: none; margin: 0; padding: 0; }
.m3-trust li { border: 1px solid var(--m3-line); border-radius: var(--m3-radius); padding: 14px; text-align: center; background: var(--m3-bg-soft); }
.m3-trust strong { display: block; font-size: .9375rem; }
.m3-trust span { display: block; font-size: .75rem; color: var(--m3-muted); margin-top: 4px; word-break: keep-all; }
@media (max-width: 899px) { .m3-trust { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* sub-page header (course/campus detail) */
.m3-subhead { position: sticky; top: 64px; z-index: 40; background: #fff; border-bottom: 1px solid var(--m3-line); }
.m3-subhead-inner { max-width: var(--m3-max); margin: 0 auto; padding: 10px 20px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.m3-subhead-title { margin: 0; font-size: 1rem; font-weight: 800; word-break: keep-all; }
.m3-subhead-actions { display: flex; gap: 8px; }
.m3-subhead-actions a { min-height: 44px; display: inline-flex; align-items: center; padding: 0 12px; border-radius: 8px; border: 1px solid var(--m3-brand); color: var(--m3-brand); text-decoration: none; font-size: .8125rem; font-weight: 700; white-space: nowrap; }
.m3-subhead-actions a.is-primary { background: var(--m3-brand); color: #fff; }
@media (max-width: 899px) { .m3-subhead { top: 56px; } .m3-subhead-title { font-size: .875rem; } }
/* M3A-C2 — on a phone the course name is long and the two enquiry actions are
   the point of the bar, so the actions keep their width and the title takes
   what is left (it wraps to at most two lines rather than squeezing them). */
@media (max-width: 599px) {
  .m3-subhead-inner { padding: 8px 16px; gap: 8px; }
  .m3-subhead-title { font-size: .8125rem; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .m3-subhead-actions { flex: 0 0 auto; }
  .m3-subhead-actions a { padding: 0 10px; font-size: .75rem; }
}

/* news card thumbnails — DECORATION of the existing excerpt rows, so the
   accepted #news-guide-excerpts markup keeps its own layout and only gains a
   reserved image box above the meta line. */
.m3-news-thumb { display: block; margin: 0 0 10px; }
.m3-news-thumb .ms-frame { border-radius: 10px; }

/* section hosts added by M3A (each is removable when it has nothing to show) */
.m3-sec-host > .wrap { padding-top: 8px; padding-bottom: 8px; }
.m3-main { min-width: 0; }
.m3-sec-host .m3-sec:first-child { margin-top: 0; }

/* ── M3A-C2: course detail sales blocks ───────────────────────────────────
   The long course page's at-a-glance block, its deliverables and its class
   format. Declares NO fixed layer (the sticky course sub-header above is
   `position: sticky`, in the layout) and NO image of its own — every
   photographic surface on this site is an admin-replaceable media record. */
.cds-section { padding: 28px 0; border-top: 1px solid var(--m3-line); }
.cds-section--alt { background: var(--m3-bg-soft); }
.cds-section--glance { padding-top: 0; border-top: 0; }
.cds-h2 { margin: 0 0 14px; font-size: 1.25rem; font-weight: 800; color: var(--m3-ink); word-break: keep-all; }
.cds-glance { border: 1px solid var(--m3-line); border-radius: var(--m3-radius); background: #fff; box-shadow: var(--m3-shadow); padding: 20px; margin-top: -18px; }
.cds-glance-title { margin: 0 0 14px; font-size: 1.0625rem; font-weight: 800; color: var(--m3-ink); word-break: keep-all; }
.cds-glance-rows { margin: 0; }
.cds-glance-row { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); gap: 12px; padding: 12px 0; border-top: 1px solid var(--m3-line); }
.cds-glance-rows .cds-glance-row:first-child { border-top: 0; padding-top: 0; }
.cds-glance-row dt { margin: 0; font-size: .8125rem; font-weight: 700; color: var(--m3-muted); }
.cds-glance-row dd { margin: 0; min-width: 0; font-size: .875rem; color: var(--m3-ink); }
.cds-value { margin: 0; font-size: .875rem; font-weight: 700; color: var(--m3-ink); }
.cds-note { margin: 8px 0 0; font-size: .8125rem; line-height: 1.6; color: var(--m3-muted); }
.cds-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.cds-chip { border: 1px solid var(--m3-line); border-radius: 999px; padding: 5px 11px; font-size: .8125rem; background: #fff; color: var(--m3-ink); }
.cds-chip--cert { border-color: var(--m3-brand); color: var(--m3-brand-ink); font-weight: 700; }
.cds-chip--link { padding: 0; border: 0; }
.cds-chip--link a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; border: 1px solid var(--m3-line); border-radius: 999px; font-size: .8125rem; color: var(--m3-brand-ink); text-decoration: none; }
.cds-chip--link a:hover { border-color: var(--m3-brand); text-decoration: underline; }
.cds-gains { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.cds-gains > li { display: grid; gap: 6px; }
.cds-gains strong { font-size: .8125rem; color: var(--m3-muted); font-weight: 700; }
.cds-lines { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.cds-lines > li { display: flex; flex-wrap: wrap; gap: 8px; font-size: .875rem; }
.cds-lines strong { color: var(--m3-ink); }
.cds-lines span { color: var(--m3-muted); }
/* The 미정 state. Deliberately plain and legible: an unknown fact is stated as
   unknown and handed to a consultation, never dressed up as an answer. */
.cds-undecided { margin: 0; font-size: .875rem; color: var(--m3-muted); line-height: 1.7; }
.cds-undecided-tag { display: inline-block; margin-right: 8px; padding: 2px 8px; border-radius: 4px; background: #eef2f7; color: #334155; font-size: .75rem; font-weight: 700; }
.cds-undecided a { color: var(--m3-brand); font-weight: 700; }
.cds-glance-cta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.cds-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 18px; border-radius: 10px; border: 1px solid var(--m3-brand); color: var(--m3-brand); background: #fff; font-size: .875rem; font-weight: 700; text-decoration: none; }
.cds-btn--primary { background: var(--m3-brand); border-color: var(--m3-brand); color: #fff; }
.cds-btn:hover { text-decoration: underline; }
@media (max-width: 767px) {
  .cds-glance { margin-top: 0; padding: 16px; }
  .cds-glance-row { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .cds-btn { width: 100%; }
}

/* focus + motion */
.mega-col-head:focus-visible, .mega-col-list a:focus-visible, .rail-btn:focus-visible,
.m3-tab:focus-visible, .m3-tile a:focus-visible, .m3-sec-more:focus-visible,
.site-utility-links a:focus-visible, .rail-links a:focus-visible, .rail-phone:focus-visible,
.cds-btn:focus-visible, .cds-chip--link a:focus-visible, .cds-undecided a:focus-visible,
.m3-subhead-actions a:focus-visible {
  outline: 3px solid #b91c1c; outline-offset: 2px; border-radius: 6px;
}
@media (prefers-reduced-motion: reduce) {
  .mega-panel, .m3-tab, .m3-tile, .rail-btn { transition: none !important; animation: none !important; }
}

/* ── M3A-V3 — gallery, campus contact, campaign band ──────────────────────
   Measured against the reference at 1440: it gives 49% of its page area to
   images and leads its work section with one large plate. This page was at
   29% with eight identical tiles, which reads as a contact sheet rather than
   a gallery. */
.m3-tile-grid--gallery { grid-auto-flow: dense; }
.m3-tile--feature { grid-column: span 2; grid-row: span 2; }
/* The feature tile's picture has to fill the taller cell, not sit at the top
   of it; its body stays the same size so the type scale does not jump. */
.m3-tile--feature > a { display: grid; grid-template-rows: 1fr auto; height: 100%; }
.m3-tile--feature .ms-frame { height: 100%; }
.m3-tile--feature .ms-img { height: 100%; }
.m3-tile--feature .m3-tile-title { font-size: 1rem; }

/* A room photograph with no way to reach that branch is not a conversion
   surface. The number is a control of its own, never part of the card link. */
.m3-tile--space { display: flex; flex-direction: column; }
.m3-tile--space > a { flex: 1; }
.m3-space-contact {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 12px 10px; border-top: 1px solid var(--m3-line);
}
.m3-space-tel { font-size: .8125rem; font-weight: 700; color: var(--m3-brand); text-decoration: none;
  font-variant-numeric: tabular-nums; min-height: 44px; display: inline-flex; align-items: center; }
.m3-space-visit { font-size: .75rem; color: var(--m3-muted); text-decoration: none;
  min-height: 44px; display: inline-flex; align-items: center;
  /* M3A-V3-R4 — a real touch target, not a 44px-tall sliver.
   *
   * The R4 phone rails made each campus tile 62vw wide, and this link — the
   * last item in a `justify-content: space-between` row next to a longer phone
   * number — was squeezed to TEN pixels wide while keeping its 44px height.
   * The evidence gate measures width as well as height and caught 70 of them.
   * `min-width` and `white-space: nowrap` mean it keeps a tappable width; the
   * row wraps instead of crushing it. */
  min-width: 72px; white-space: nowrap; justify-content: flex-end; }
.m3-space-contact { flex-wrap: wrap; row-gap: 0; }
.m3-space-tel:hover, .m3-space-visit:hover { text-decoration: underline; }

/* The promotion reads as a campaign: the artwork carries the strip and the
   copy sits on it, instead of a thin band with a caption underneath. */
.m3-promo--campaign { position: relative; display: block; }
.m3-promo--campaign .ms-frame { aspect-ratio: 1200 / 300; }
.m3-promo--campaign .m3-promo-body {
  position: absolute; inset: auto 0 0 0;
  /* A flat translucent plate, not a gradient. The reference stylesheet is held
     to "no marketing image in CSS", and gradients are the proxy that rule uses;
     loosening it to fit a scrim would weaken a real check for a cosmetic
     reason. A solid overlay reads the same at this size. */
  background: rgba(8,12,24,.72);
  color: #fff; padding: 26px 22px 18px; align-items: flex-end;
}
.m3-promo--campaign .m3-promo-copy { font-size: 1.125rem; color: #fff; }
.m3-promo--campaign .m3-promo-cta { color: #fff; }
@media (max-width: 599px) {
  .m3-promo--campaign .ms-frame { aspect-ratio: 4 / 3; }
  .m3-tile--feature { grid-column: span 2; grid-row: span 1; }
}

/* M3A-V3 — THREE columns, not four, on the photographic grids.
   The reference gives 49% of its page area to images; four columns at this
   container width put each picture at 258×145, which is a thumbnail. Three
   columns make it 363×204 — the same eight records, seen. The coursework
   feature tile keeps its 2×2 cell, so the gallery still steps down from one
   large plate. */
@media (min-width: 1024px) {
  .m3-tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
}

/* M3A-V3-R1 — the short credibility band.
   Four surfaces moved off the homepage to the pages that own them. This row is
   the home's single, visible path to all four, so the compression never turns
   into a dead end. */
.trust-links { list-style: none; margin: 18px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.trust-links a {
  display: flex; flex-direction: column; gap: 2px; min-height: 60px; justify-content: center;
  padding: 10px 14px; border: 1px solid var(--m3-line); border-radius: var(--m3-radius);
  background: #fff; text-decoration: none; color: inherit;
}
.trust-links a:hover, .trust-links a:focus-visible { border-color: var(--m3-brand); background: #f6f9ff; }
.trust-links b { font-size: .875rem; }
.trust-links span { font-size: .75rem; color: var(--m3-muted); }
@media (max-width: 899px) { .trust-links { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* M3A-V3-R1 — the home's "starting soon" strip.
   The order asks for the nearest few as short cards or a single-line list; the
   full schedule is on /openings/. One row = one line: title and facts on the
   left, status and action on the right, everything on a single baseline. The
   dedicated page keeps the tall card. */
#openings .opening-list { display: grid; grid-template-columns: 1fr; gap: 6px; }
#openings .opening-card {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  padding: 10px 14px; min-height: 0;
}
#openings .opening-card h3 { font-size: .9375rem; margin: 0; flex: 1 1 260px; min-width: 0; }
#openings .opening-card .meta { font-size: .75rem; margin: 0; flex: 2 1 320px; min-width: 0; }
#openings .opening-card .meta br { display: none; }
#openings .opening-card .meta::before { content: ''; }
#openings .opening-card .badge { margin: 0; order: 3; }
#openings .opening-card .apply { margin: 0; order: 4; white-space: nowrap; }
#openings .opening-not-real { flex: 1 1 100%; order: 5; font-size: .6875rem; margin: 0; }
@media (max-width: 599px) {
  #openings .opening-card h3, #openings .opening-card .meta { flex: 1 1 100%; }
}

/* M3A-V3-R1 — the learning-scene row is four across at desktop.
   The coursework gallery keeps its asymmetry (one feature plate, the order
   names that as a thing to preserve); the learning scenes are a uniform row of
   four and do not need two rows of three to say so. One row instead of two is
   ~330px of page back, with the same four pictures at the same size. */
@media (min-width: 1024px) {
  #m3-learning .m3-tile-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
}

/* M3A-V3-R1 — tighter vertical rhythm on the homepage.
   The reference runs its sections close together; this page inherited a 44px
   gap between every block plus each section's own padding, which across
   thirteen surfaces is most of a viewport of air. The gap is cut, not the
   content: nothing is removed and no picture changes size, so the image share
   rises because the page stops being taller than what it shows. */
.m3-sec { margin: 12px 0; }
.m3-sec-host { padding-top: 6px; padding-bottom: 6px; }

/* The homepage's own section padding. The global rule is 52px top and bottom,
   which is right for a reading page; on a home that alternates picture rows it
   doubles into 104px of air between every one of them. Scoped to the home so no
   other page's rhythm changes. */
body.is-home main > section { padding: 14px 0; }
body.is-home main > section#home { padding-top: 0; }

/* The section headers on the home are labels for a row of pictures, not the
   opening of an essay: the lead paragraph under each one repeated what the
   pictures and the cards already say. Kept on every other page. */
body.is-home main > section > .wrap > h2 { margin-bottom: 6px; }
body.is-home main > section > .wrap > .lead { margin-top: 0; margin-bottom: 14px; font-size: .8125rem; }
body.is-home main > section > .wrap > .section-tag { margin-bottom: 6px; }

/* M3A-V3-R1 — the AI finder under the hero, compacted.
   The order puts the photographic hero and the consultation panel in the first
   screen; the finder is the next thing, not a second hero. It kept a hero-sized
   block of padding and a two-row textarea, which pushed the six family cards
   further down than the reference puts them. Same control, same behaviour,
   less air. */
body.is-home #home .finder-layout { margin-top: 18px; }
body.is-home #home .finder-box { padding: 16px 18px; }
body.is-home #home .finder-label { font-size: .875rem; margin-bottom: 8px; }
body.is-home #home #finder-input { min-height: 46px; }
body.is-home #home .finder-example { margin: 8px 0 0; font-size: .75rem; }
body.is-home #home .quick-actions { margin-top: 12px; }
body.is-home #home .utility-shortcuts { margin-top: 14px; }

/* M3A-V3-R1 — final compaction pass on the homepage.
   Every value here is spacing or type scale; no control, record or picture is
   removed. The target is the reference's density: it fits the same kind of
   content into roughly half the scroll, and the difference is almost entirely
   air around headings and inside cards. */
body.is-home .m3-sec-head { margin-bottom: 10px; }
body.is-home .m3-sec-title { font-size: 1.25rem; }
body.is-home .m3-sec-title small { margin-top: 2px; }
body.is-home .m3-tile-body { padding: 8px 10px 10px; }
body.is-home .m3-tile-sum { line-height: 1.35; }
body.is-home #openings .lead { display: none; }
body.is-home #openings .opening-card { padding: 8px 12px; }
body.is-home #catalogue .lead { font-size: .75rem; margin-bottom: 10px; }
body.is-home #trust .why-grid { gap: 8px; }
body.is-home #trust .why-card { padding: 10px 12px; }
body.is-home #trust .lead { display: none; }
body.is-home .trust-links { margin-top: 12px; }
body.is-home #login { padding: 14px 0; }
body.is-home #cta-mid { padding: 18px 0; }

/* M3A-V3-R1 — the campus gallery goes back to four across.
   Eight rooms in three columns is three rows; in four it is exactly two, which
   is ~350px of page for the same eight photographs. The coursework gallery
   stays at three so its feature plate keeps the asymmetry the order asks to
   preserve. */
@media (min-width: 1024px) {
  #m3-spaces .m3-tile-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
}

/* M3A-V3-R1 — the coursework gallery at four columns.
   The feature plate still spans 2x2, so the asymmetry the order asks to keep is
   intact; the other seven sit at tile size beside it. Same eight records, one
   row of page height less. */
@media (min-width: 1024px) {
  #m3-portfolio .m3-tile-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
}

/* M3A-V3-R1 — the news row on the home is a card, not an article.
   Two lines of summary is what a thumbnail card carries; the full excerpt is on
   /news/, which the section already links to. */
body.is-home #news-guide-excerpts .ed-summary { -webkit-line-clamp: 1; }
body.is-home #news-guide-excerpts .ed-row { padding-bottom: 6px; }
body.is-home .sc-bridge { padding: 10px 0; }
body.is-home .sc-facts li { padding: 6px 0; }

/* The last stretch: the closing surfaces do not need a full section's air each.
   #login is a two-line notice and #catalogue's CTA row is the page's final
   control, so the page ends where the content ends. */
body.is-home #login { padding: 8px 0 10px; }
body.is-home #catalogue { padding-bottom: 10px; }
body.is-home #campuses { padding-bottom: 12px; }

/* M3A-V3-R1 — the closing surfaces, compacted.
   The consultation form came back to the homepage (several accepted contracts
   are written against it living here), so the space it needs is taken from the
   air around it rather than from any other surface. Spacing only: every field,
   label, consent control and notice is untouched. */
body.is-home #consultation { padding: 18px 0 20px; }
body.is-home #consultation .lead { font-size: .8125rem; margin-bottom: 12px; }
body.is-home #consultation .form-grid { gap: 10px; }
body.is-home #consultation label { margin-bottom: 2px; }
body.is-home #consultation input, body.is-home #consultation select, body.is-home #consultation textarea { margin-bottom: 6px; }
body.is-home #news-guide-excerpts { padding-top: 12px; }
body.is-home #funding { padding: 16px 0; }
body.is-home #funding .section-tag { margin-bottom: 4px; }
body.is-home #catalogue { padding-top: 12px; }

/* M3A-V3-R1 — final pass over the text surfaces on the homepage.
   Spacing and type scale only. Every control, field, label, notice and record
   is untouched; what is removed is the air these blocks inherited from a
   reading-page stylesheet while they sit between rows of pictures. */
body.is-home main > section { padding: 12px 0; }
body.is-home #home { padding-top: 0; }
body.is-home .wrap > h2 { font-size: 1.25rem; }
body.is-home #catalogue .detail-cta-row,
body.is-home #openings .detail-cta-row,
body.is-home #funding .detail-cta-row { margin-top: 10px; }
body.is-home #campuses .lead { display: none; }
body.is-home #cta-mid .lead { margin-bottom: 10px; }
body.is-home #consultation .form-grid { gap: 8px; }
body.is-home #login p { margin: 4px 0; }
body.is-home #trust .why-card .num { font-size: 1.25rem; }

/* ── M3A-V3-R2 — picture-first tiles ──────────────────────────────────────
   The ratio that matters is picture area per pixel of page, and the constant
   working against it is the text block under every tile. The reference gives
   each card a title and one line; this page was giving them a title, a line,
   padding and the section's own rhythm on top.
   Nothing is removed — the title and its line stay — they are simply set at
   the size a caption needs, so the photograph gets the rest. */
body.is-home .m3-tile-body { padding: 6px 8px 8px; }
body.is-home .m3-tile-title { font-size: .75rem; margin-bottom: 1px; }
body.is-home .m3-tile-sum { font-size: .6875rem; line-height: 1.3; }
body.is-home .m3-sec-head { margin-bottom: 8px; }

/* Rooms and news at 4:3 rather than 16:9: the same photographs, a third more
   picture for the same column width. */
body.is-home #m3-spaces .ms-frame { aspect-ratio: 4 / 3 !important; }
body.is-home #news-guide-excerpts .ms-frame { aspect-ratio: 4 / 3 !important; }

/* The campus contact cards carry their photograph at the same weight. */
body.is-home .campus-card-media { margin-bottom: 8px; }
body.is-home .campus-card-media img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }

/* M3A-V3-R2 — the course line-up at three columns on desktop.
   Eleven cards at five-up are 200px wide; the reference runs its line-up at a
   size where the course artwork is legible. Three columns is the same eleven
   cards with two and a half times the picture area each. */
@media (min-width: 1024px) {
  body.is-home .m3-course-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
}

/* M3A-V3-R2 — the last of the air, so the taller course cards fit inside the
   7–10 viewport budget. Spacing only. */
body.is-home main > section { padding: 10px 0; }
body.is-home .m3-sec { margin: 10px 0; }
body.is-home #news-guide-excerpts .ed-row { padding-top: 4px; }
body.is-home #catalogue .lead { display: none; }
body.is-home #openings h2, body.is-home #catalogue h2, body.is-home #funding h2 { font-size: 1.125rem; }

/* M3A-V3-R2 — the one icon style. Every icon in js/icon-set.js is drawn on
   this rule, which matches the pre-existing quick-dock convention exactly
   (24 viewBox, currentColor strokes, 1.8, round). An icon never sets its own
   weight or colour; a control sizes it with a class if it must. */
.tp-icon { width: 20px; height: 20px; display: inline-block; vertical-align: middle;
  stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* M3A-V3-R2 — state modifiers on the ONE icon shape. A filled star and an
 * empty star are the same path with a different fill, which is why a 2-star row
 * and a 5-star row now line up; the ★/☆ character pair never could. */
/* Inline with a text label: sized to the type, not to the 20px control size. */
.tp-icon--inline { width: 1em; height: 1em; vertical-align: -.12em; }
.tp-icon--on { fill: currentColor; }
.tp-icon--off { fill: none; opacity: .38; }
.stars { display: inline-flex; align-items: center; gap: 2px; color: #f59e0b; }
.stars .tp-icon { width: 16px; height: 16px; }
.tp-icon--sm { width: 16px; height: 16px; }
.tp-icon--lg { width: 24px; height: 24px; }

/* ── M3A-V3-R3 — the photo-editorial surfaces ─────────────────────────────
 * Three new layouts, all of them there to raise picture density WITHOUT making
 * the page longer. The first version of this change shipped the markup and not
 * the stylesheet, and the measurement said exactly what that costs: the
 * homepage went from 10.1 to 17.4 viewports because a promo row and two rails
 * fell back to stacked list items. Length is measured, not assumed. */

/* A horizontal rail: the browser scrolls it, no script, one row of height.
 *
 * The class is `m3-hrail`. The obvious name, `m3-rail`, was already taken by
 * the sticky CONSULTATION aside — so the first version of this rule turned that
 * aside into a horizontally scrolling grid. Naming collisions in a shared
 * stylesheet do not announce themselves; this one showed up as a section whose
 * picture share refused to move no matter what was changed.
 *
 * `scroll-snap` makes it feel deliberate on a phone; `overscroll-behavior`
 * stops a sideways flick from dragging the whole page with it. */
.m3-hrail {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(230px, 1fr);
  gap: 14px; list-style: none; margin: 0; padding: 0 2px 8px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scrollbar-width: thin;
}
.m3-hrail > li { scroll-snap-align: start; min-width: 0; }
.m3-hrail:focus-visible { outline: 3px solid var(--m3-brand); outline-offset: 3px; }
.m3-hrail-item > div { display: block; border: 1px solid var(--m3-line); border-radius: var(--m3-radius); overflow: hidden; background: #fff; height: 100%; }
@media (max-width: 599px) { .m3-hrail { grid-auto-columns: minmax(72vw, 1fr); } }
@media (prefers-reduced-motion: reduce) { .m3-hrail { scroll-behavior: auto; } }

/* The promotion row: three banners side by side, not three stacked bands. */
.m3-promo-row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px; list-style: none; margin: 0; padding: 0;
}
.m3-promo-row > li { min-width: 0; }
.m3-promo-row .m3-promo--campaign .ms-frame { aspect-ratio: 4 / 3; }
.m3-promo-row .m3-promo-copy { font-size: 1rem; }
@media (max-width: 899px) { .m3-promo-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 599px) { .m3-promo-row { grid-template-columns: 1fr; } }

/* The course line-up is now eleven PHOTOGRAPHIC cards. Five across at 1440 is
 * three rows of pictures where the old text cards were; the tile body is
 * two lines, because the order's rule for this page is a caption, not a
 * paragraph. */
body.is-home .m3-course-card .m3-course-sum { display: none; }
body.is-home .m3-course-body { padding: 8px 10px 10px; }
body.is-home .m3-course-title { font-size: .875rem; line-height: 1.35; }
body.is-home .m3-course-meta { font-size: .6875rem; }

/* ── M3A-V3-R3 — PICTURE SHARE, band by band ──────────────────────────────
 * Measured per section (qa-report.json `density.sections`), then fixed where
 * the measurement pointed. Before: sc-programs 31.7% of its own height was
 * picture, the course line-up 25.6%, the campus band 27.1% — the pictures were
 * there, and the padding around them was bigger than they were. */

/* The six family cards: picture first, two lines under it. */
body.is-home .sc-program-media { aspect-ratio: 4 / 3; }
body.is-home .sc-program--feature .sc-program-media { aspect-ratio: 16 / 10; min-height: 0; }
body.is-home .sc-program-body { padding: 10px 12px 12px; }
body.is-home .sc-program-body h3 { font-size: 1rem; margin: 2px 0 0; }
body.is-home .sc-programs { padding: 26px 0 28px; }
body.is-home .sc-programs-head--brief { margin-bottom: 12px; }

/* The promotion banners are wide, not tall: at 4/3 three of them cost 0.6 of a
 * viewport for three lines of copy. */
.m3-promo-row .m3-promo--campaign .ms-frame { aspect-ratio: 16 / 9; }
@media (max-width: 599px) { .m3-promo-row .m3-promo--campaign .ms-frame { aspect-ratio: 16 / 10; } }

/* Campus spaces: the photograph is the point, the address is the caption. */
body.is-home #m3-spaces .m3-tile-body { padding: 6px 8px 8px; }
body.is-home #m3-spaces .m3-tile-sum { display: none; }

/* The bands that carry NO picture are the ones that decide whether the page is
 * seven viewports or ten. None of them loses a control or a link — they lose
 * the air around it. */
body.is-home #finder,
body.is-home #catalogue,
body.is-home #openings,
body.is-home #cta-mid,
body.is-home #funding,
body.is-home #trust,
body.is-home #login { padding-top: 6px; padding-bottom: 8px; }
body.is-home #finder .m3-sec-head,
body.is-home #catalogue .m3-sec-head,
body.is-home #openings .m3-sec-head { margin-bottom: 8px; }
body.is-home #login { font-size: .8125rem; }

/* ── M3A-V3-R3 — THE CONTENT COLUMN, and why it caps everything ───────────
 * Measured: on the homepage `.wrap` resolved to a 1080px content box inside a
 * 1440 viewport. Image share is measured against the VIEWPORT, so a 1080 column
 * caps what any band can reach at 75% before a single pixel of padding — which
 * is why the campus band read 28% while its own tiles were 62% picture.
 * The reference's column measures 1248 at this width, which the Hero already
 * uses; the rest of the homepage now uses the same one. */
body.is-home .wrap { max-width: var(--m3-max); }

/* The six family cards were laid out picture-BESIDE-text: a 347px card with a
 * 191x120 picture in it. On the homepage this row is a set of bookmarks, so the
 * picture goes on top and spans the card. */
body.is-home .sc-program { display: block; }
body.is-home .sc-program .sc-program-media { width: 100%; aspect-ratio: 4 / 3; min-height: 0; }
body.is-home .sc-program--feature .sc-program-media { aspect-ratio: 16 / 10; min-height: 0; }

/* ── M3A-V3-R3 — the picture-less bands, measured and then squeezed ───────
 * Seven bands on the homepage carry no photograph at all: finder, catalogue,
 * openings, cta-mid, funding, trust, login. Together they were 1.83 of the
 * page's 10.79 viewports — and since the length target is a RATIO's
 * denominator as well as a target of its own, every viewport they give back
 * counts twice.
 *
 * Nothing is removed. Every heading, control, row and link these bands carry is
 * still there and still reachable; what goes is the air around them, which is
 * what made a four-row list read as a section. */
body.is-home #finder,
body.is-home #catalogue,
body.is-home #openings,
body.is-home #cta-mid,
body.is-home #funding,
body.is-home #trust,
body.is-home #login { padding-top: 2px; padding-bottom: 4px; }
body.is-home #finder > .wrap,
body.is-home #catalogue > .wrap,
body.is-home #openings > .wrap,
body.is-home #cta-mid > .wrap,
body.is-home #funding > .wrap,
body.is-home #trust > .wrap,
body.is-home #login > .wrap { padding-top: 0; padding-bottom: 0; }
body.is-home #finder h2,
body.is-home #catalogue h2,
body.is-home #openings h2,
body.is-home #cta-mid h2,
body.is-home #funding h2,
body.is-home #trust h2 { font-size: 1.25rem; margin: 0 0 6px; }
/* The section subtitle under a heading in a picture-less band is the one piece
 * of copy that repeats what the heading already said. */
body.is-home #finder .m3-sec-title small,
body.is-home #catalogue .m3-sec-title small,
body.is-home #openings .m3-sec-title small { display: none; }
body.is-home #openings li,
body.is-home #catalogue li { padding-top: 4px; padding-bottom: 4px; }
body.is-home #trust .trust-links { margin: 4px 0 0; }
body.is-home #login p { margin: 2px 0; }

/* ── M3A-V3-R3 — the six fields are ONE ROW of shortcuts ──────────────────
 * Measured: as a 3x2 grid of 389px cards this band was 1.12 viewports for six
 * links. It is a bookmark row — the reader picks a field and leaves — so at
 * 1200px and up it becomes a single row of six. Same six cards, same pictures,
 * same destinations; roughly 0.85 of a viewport returned to the page.
 * The feature/flip treatment is switched off with it: a "wide editorial
 * moment" has no meaning inside a row of equals. */
@media (min-width: 1200px) {
  body.is-home .sc-program-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; }
  body.is-home .sc-program--feature { grid-column: auto; }
  body.is-home .sc-program--feature .sc-program-media { aspect-ratio: 4 / 3; }
  body.is-home .sc-program-body { padding: 8px 9px 10px; }
  body.is-home .sc-program-body h3 { font-size: .875rem; line-height: 1.3; }
  body.is-home .sc-program-fam { font-size: .625rem; }
  body.is-home .sc-program-foot { font-size: .6875rem; }
}

/* The last few dozen pixels. The page kept landing just over the order's
 * ceiling by less than one screen-height of padding, so the padding is what
 * gives — twice, measured each time rather than estimated. */
body.is-home main > section { padding: 4px 0; }
body.is-home .m3-sec { margin: 4px 0; }
body.is-home #m3-spaces .m3-tile-sum { display: none; }
body.is-home #m3-spaces .m3-tile-body { padding: 6px 8px 8px; }
/* The notice markers rendered as icons (js/icon-set.js decorateMarkers). */
.tp-marker { display: inline-flex; vertical-align: -.18em; margin-right: 4px; }
.tp-marker .tp-icon { width: 1.05em; height: 1.05em; }

/* ── M3A-V3-R3 — the news band as CARDS, not as six stacked rows ──────────
 * Six notices now carry a photograph. Stacked, that band cost 0.43 of a
 * viewport more than the three-row version it replaced — the pictures were
 * added and the page paid for them twice, in length and in a lower ratio.
 * Three across is two rows, the same six cards, the same links. */
@media (min-width: 900px) {
  body.is-home #news-guide-excerpts .ed-list {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; align-items: start;
  }
  body.is-home #news-guide-excerpts .ed-row {
    padding: 0 0 6px; border-bottom: 0; min-width: 0;
  }
  body.is-home #news-guide-excerpts .m3-news-thumb { margin-bottom: 6px; }
}
@media (min-width: 600px) and (max-width: 899px) {
  body.is-home #news-guide-excerpts .ed-list {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start;
  }
  body.is-home #news-guide-excerpts .ed-row { padding: 0 0 6px; border-bottom: 0; min-width: 0; }
}
/* The learning-guide rows under it are text; three of them stacked were a
   third band's worth of height for three links. */
body.is-home #home-learn-excerpts h2 { margin-top: 14px; font-size: 1.125rem; }
body.is-home #news-guide-excerpts .section-more { margin-top: 6px !important; }

/* NOTE: the course card's picture shape is NOT set here. media-surface writes
   aspect-ratio as an INLINE style, which no stylesheet rule can override, so
   the shape is decided at the call site in js/home-reference.js. A rule here
   would look like it worked and change nothing — which is exactly what the
   first attempt did. */

/* ══ M3A-V3-R4 — PHONE LENGTH ════════════════════════════════════════════
 * Measured at 375: the page was 16,867px (20.77 viewports) against an order
 * ceiling of 15. The five bands below were 11,325px of it. None of them loses
 * a card, a link or a destination — the long ones become horizontally
 * scrollable rails, which is what the order asks for, and the six field
 * shortcuts stop being one card per row. */
@media (max-width: 767px) {
  /* six field shortcuts: two columns, not six stacked cards (2,351 -> ~800px) */
  body.is-home .sc-program-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
}
/* At tablet width three across is two rows, which is what keeps the course
   line-up inside the order's 2-viewport ceiling at 704. */
@media (min-width: 600px) and (max-width: 767px) {
  body.is-home .sc-program-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  body.is-home .sc-program--feature { grid-column: auto; }
  body.is-home .sc-program .sc-program-media,
  body.is-home .sc-program--feature .sc-program-media { aspect-ratio: 4 / 3; min-height: 0; }
  body.is-home .sc-program-body { padding: 8px 10px 10px; }
  body.is-home .sc-program-body h3 { font-size: .875rem; line-height: 1.3; margin: 2px 0 0; }
  body.is-home .sc-program-body p { display: none; }
  body.is-home .sc-programs { padding: 14px 0 16px; }
  body.is-home .sc-programs-head--brief h2 { font-size: 1.25rem; }
  body.is-home .sc-programs-head--brief .sc-kicker { font-size: .625rem; }

  /* the course line-up becomes a rail: all eleven cards, one row of height */
  body.is-home .m3-course-grid {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(62vw, 1fr);
    /* M3A-V3-R4-R1 — `grid-template-columns: none` IS THE LOAD-BEARING LINE.
     *
     * Independent audit P1: the first two to three cards of every phone rail
     * laid out at 0–2px wide. `grid-auto-flow: column` does NOT replace an
     * explicit template — it governs the tracks the grid creates for items
     * that do not fit the declared ones. The base rule for these grids sets
     * `grid-template-columns: repeat(N, minmax(0, 1fr))`, so on a phone the
     * first N items went into N explicit tracks that were squeezed to 0px by
     * the rail's own horizontal overflow, and the remaining items got the
     * healthy auto columns. Computed: `0px 0px 232.5px 232.5px …`.
     *
     * Every gate passed: the cards were all present, all counted, all with
     * their pictures loaded — and two pixels wide. Clearing the template is
     * what makes every item an auto column. */
    grid-template-columns: none;
    gap: 10px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; padding-bottom: 6px;
  }
  body.is-home .m3-course-grid > li { scroll-snap-align: start; min-width: 0; }

  /* coursework and campus rooms: same treatment */
  body.is-home #m3-portfolio .m3-tile-grid,
  body.is-home #m3-spaces .m3-tile-grid {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(62vw, 1fr);
    grid-template-columns: none;      /* see the note on .m3-course-grid above */
    gap: 10px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; padding-bottom: 6px;
  }
  body.is-home #m3-portfolio .m3-tile-grid > li,
  body.is-home #m3-spaces .m3-tile-grid > li { scroll-snap-align: start; min-width: 0; }
  body.is-home .m3-tile--feature { grid-column: auto; grid-row: auto; }

  /* news + guides: a rail of cards instead of six stacked rows */
  body.is-home #news-guide-excerpts .ed-list {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(70vw, 1fr);
    grid-template-columns: none;      /* see the note on .m3-course-grid above */
    gap: 10px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; padding-bottom: 6px; align-items: start;
  }
  body.is-home #news-guide-excerpts .ed-row {
    scroll-snap-align: start; min-width: 0; padding: 0 0 6px; border-bottom: 0;
  }
  body.is-home #news-guide-excerpts .ed-row p { display: -webkit-box; -webkit-line-clamp: 2;
    -webkit-box-orient: vertical; overflow: hidden; }

  /* campus contact block: the four campuses side by side */
  body.is-home #campuses .campus-grid,
  body.is-home #campuses > .wrap > div:not(.m3-sec-head) {
    display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  }

  /* card copy is a caption on this page, never a paragraph */
  body.is-home .m3-tile-sum, body.is-home .m3-course-sum {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  body.is-home #openings li:nth-child(n+4) { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  body.is-home .m3-course-grid,
  body.is-home #m3-portfolio .m3-tile-grid,
  body.is-home #m3-spaces .m3-tile-grid,
  body.is-home #news-guide-excerpts .ed-list { scroll-behavior: auto; }
}

/* ── M3A-V3-R4 — the one remaining text band, compressed ──────────────────
 * After the reorder the only picture-less stretch left on the homepage is
 * finder → catalogue → mid-page CTA. Measured at 1440 it was 1.19 viewports of
 * section height and a 1.44-viewport gap between photographs, against the
 * standing rule that no text run may exceed one screen.
 *
 * The order allows these surfaces to be "moved below the line-up or folded to
 * a short CTA". They are neither removed nor folded: every control, link and
 * row is still rendered. What goes is the editorial framing they were given
 * when they opened the page — a tag line, a headline and a lead paragraph for
 * a search box the reader has already scrolled past four photographic bands to
 * reach. */
body.is-home #finder .section-tag,
body.is-home #catalogue .section-tag { display: none; }
body.is-home #finder h2,
body.is-home #catalogue h2 { font-size: 1.125rem; margin: 0 0 4px; }
body.is-home #finder .lead,
body.is-home #catalogue .lead { font-size: .8125rem; margin: 0 0 8px; }
body.is-home #finder .finder-label { font-size: .9375rem; margin: 0 0 6px; }
body.is-home #finder .finder-box { padding: 12px; }
body.is-home #finder .finder-example { margin: 6px 0 0; font-size: .75rem; }
body.is-home #finder .quick-actions { margin: 8px 0 0; }
body.is-home #finder .utility-shortcuts { margin: 8px 0 0; }
/* The worked example under the search box is a teaching aid for a reader who
   has just arrived. By this point on the page they have scrolled past four
   photographic bands to reach a search box they chose to use; the placeholder
   inside the box still shows the same example. It remains on courses.html,
   where the finder is the subject of the page. */
body.is-home #finder .finder-example { display: none; }
/* On the HOMEPAGE the finder is a tool the reader reaches after four
 * photographic bands, so it is presented as a tool: the label on the box, the
 * box, and the shortcuts. The section headline and lead paragraph that framed
 * it when it opened the page are hidden here and kept in full on
 * courses.html, where the finder is the subject. Nothing is unreachable:
 * #finder-input, #finder-btn, #finder-results and every shortcut render
 * exactly as before. */
body.is-home #finder > .wrap > h2,
body.is-home #finder > .wrap > .lead { display: none; }
body.is-home #finder #finder-input { min-height: 44px; height: 44px; }
body.is-home #finder .finder-box { padding: 10px; }
body.is-home #finder .lead,
body.is-home #catalogue .lead {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
body.is-home #catalogue .detail-cta-row { margin-top: 8px !important; }
/* the standing-certificate rows are a list, not a set of cards, on this page */
body.is-home #catalogue #evergreen-catalogue li,
body.is-home #catalogue #evergreen-catalogue > div > div { padding-top: 4px; padding-bottom: 4px; }
body.is-home #catalogue #evergreen-catalogue p { margin: 0; }
body.is-home #catalogue #evergreen-more-note { margin-top: 6px !important; }
