/* Challenge University — design tokens */
@font-face{font-family:Switzer;src:url(/assets/fonts/switzer-normal.woff2) format("woff2");font-weight:100 900;font-display:swap}
@font-face{font-family:Switzer;src:url(/assets/fonts/switzer-italic.woff2) format("woff2");font-weight:100 900;font-style:italic;font-display:swap}
@font-face{font-family:"Source Serif 4";src:url(/assets/fonts/source-serif-4-regular.woff2) format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Source Serif 4";src:url(/assets/fonts/source-serif-4-600.woff2) format("woff2");font-weight:600;font-display:swap}
:root{
  --navy:#0e2a47;--navy-deep:#0a1f36;--navy-soft:#163c62;
  --gold:#f5b301;--gold-deep:#c98f00;--ink:#16181d;
  --paper:#ffffff;--mist:#f5f7fa;--rule:#e3e8ee;--muted:#5a6572;
  /* teal -- the one supporting accent added on top of navy+gold (v3a "more
     life" pass). #0fa3a3 sits mid-lightness: on --navy-deep/--navy it clears
     4.7:1 (AA, normal text), so it can carry text/rules on the dark bands;
     on --paper it's only ~3.1:1, so on light backgrounds it's reserved for
     large numerals, rules and hovers, never body-sized text -- --teal-deep
     (#0b7f7f, ~4.8:1 on white) is the text-safe variant there. --teal-tint
     is a barely-there wash for a third section background beside
     paper/mist, giving the "left right about sections" rhythm a third tone
     to alternate against. Gold stays the only CTA-adjacent/field-card
     accent; teal is structural (bands, eyebrows-on-dark, rules, hovers) --
     never a button fill. */
  --teal:#0fa3a3;--teal-deep:#0b7f7f;--teal-tint:#e3f5f4;
  --sans:Switzer,system-ui,sans-serif;--serif:"Source Serif 4",Georgia,serif;
  --max:72rem;--pad:clamp(1rem,4vw,2rem);--radius:14px;--radius-sm:10px;
}
*,*::before,*::after{box-sizing:border-box}
body{margin:0;font:400 1.0625rem/1.65 var(--sans);color:var(--ink);background:var(--paper);-webkit-font-smoothing:antialiased}
img,video{max-width:100%;height:auto;display:block}
a{color:inherit}
.wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--pad)}
.skip{position:absolute;left:-999px}.skip:focus{left:1rem;top:1rem;background:var(--gold);padding:.5rem 1rem;z-index:99}
/* type */
h1,h2{font-family:var(--serif);font-weight:600;line-height:1.15;letter-spacing:-.01em;margin:0 0 .5em}
h1{font-size:clamp(2.2rem,5.5vw,3.6rem)}h2{font-size:clamp(1.6rem,3.5vw,2.3rem)}
h3{font-size:1.15rem;margin:0 0 .4em}
.eyebrow{font:600 .78rem/1 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--navy);margin:0 0 1rem}
.eyebrow::before{content:"";display:inline-block;width:1.6rem;height:3px;background:var(--gold);margin-right:.6rem;vertical-align:.18em}
.lede{font-size:1.2rem;color:var(--muted);max-width:44rem}
.post-meta{font:600 .8rem/1 var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin:0 0 2rem}
/* announcement bar -- one config entry in theme.ANNOUNCEMENT drives it.
   Sits ABOVE the sticky header and scrolls away with the page, so it never
   eats viewport height on long reads. Teal band = the one place teal carries
   body-sized text, which it can: #0fa3a3 on --navy-deep clears AA. */
.announce{background:var(--navy-deep);border-bottom:1px solid rgb(255 255 255/.12);color:#eaf6f6}
/* Text is centred on the WRAP, not merely centred in the space left over
   beside the close button -- the button is taken out of flow so the message
   sits on the true horizontal centre. Inline padding keeps long copy from
   sliding under the button on narrow screens. */
.announce .wrap{position:relative;padding-block:.6rem}
.announce-text{margin:0;font-size:.92rem;line-height:1.4;text-align:center;padding-inline:2.25rem}
.announce-text a{color:var(--teal);font-weight:600;text-decoration:none;white-space:nowrap}
.announce-text a:hover{text-decoration:underline}
.announce-close{position:absolute;right:var(--pad);top:50%;transform:translateY(-50%);
  background:none;border:0;color:#9fb3c4;font-size:1.35rem;
  line-height:1;padding:.15rem .4rem;cursor:pointer;border-radius:6px}
.announce-close:hover{color:#fff;background:rgb(255 255 255/.1)}
@media (max-width:560px){
  .announce-text{font-size:.85rem}
  .announce-text a{white-space:normal}
}
/* header */
.site-head{position:sticky;top:0;background:rgba(255,255,255,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--rule);z-index:50}
/* three columns with equal-weight sides: the nav sits at the true page centre
   regardless of how wide the logo or the Apply now button are */
.site-head .wrap{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:1.5rem;min-height:4.25rem}
.site-head .logo{justify-self:start}
.head-actions{justify-self:end;display:flex;align-items:center;gap:.75rem}
.logo{display:flex;align-items:center;gap:.6rem;font-weight:700;text-decoration:none;font-size:1.05rem}
.logo img{height:36px;width:auto}
.nav{display:flex;gap:1.4rem;justify-self:center;align-items:center}
.nav a{text-decoration:none;font-weight:500;font-size:.95rem;padding:.35rem 0;border-bottom:2px solid transparent}
.nav a:hover,.nav a[aria-current=page]{border-bottom-color:var(--gold)}
.menu-btn{display:none;margin-left:auto;background:none;border:1px solid var(--rule);border-radius:8px;padding:.5rem .7rem;cursor:pointer}
@media (max-width:820px){
  /* logo | Apply now | menu toggle -- one row, never wraps */
  .site-head .wrap{grid-template-columns:auto 1fr auto;gap:.75rem}
  .head-actions{order:2;justify-self:end}
  .head-actions .btn{padding:.6rem 1.05rem;font-size:.85rem}
  .menu-btn{order:3;display:block;margin-left:0}
  .nav{display:none;position:absolute;inset:100% 0 auto;background:#fff;flex-direction:column;align-items:flex-start;padding:1rem var(--pad) 1.5rem;border-bottom:1px solid var(--rule);gap:.9rem}
  .nav.open{display:flex}
}
@media (max-width:400px){
  .site-head .logo img{width:118px;height:auto}
  .head-actions .btn{padding:.55rem .9rem}
}
/* buttons -- .btn-primary/.btn-ghost only; gold is an accent, never a CTA fill */
.btn{display:inline-block;font:600 .95rem/1 var(--sans);text-decoration:none;border-radius:999px;
  padding:.85rem 1.7rem;border:0;cursor:pointer;
  transition:transform .15s ease,box-shadow .15s ease,background .15s ease,color .15s ease,border-color .15s ease}
.btn-primary{background:var(--navy);color:#fff}
.btn-primary:hover{background:var(--navy-soft);transform:translateY(-1px);box-shadow:0 8px 22px rgb(14 42 71/.18)}
.btn-ghost{background:transparent;border:1.5px solid var(--rule);color:var(--ink)}
.btn-ghost:hover{border-color:var(--navy);color:var(--navy);transform:translateY(-1px)}
/* dark-background inversion: hero / page-hero / cta-band / .section.deep
   (mission-band, impact-band) -- any full-bleed dark band needs this or a
   .btn-ghost renders var(--ink) text on navy, effectively invisible */
.hero .btn-primary,.page-hero .btn-primary,.cta-band .btn-primary,.section.deep .btn-primary{background:#fff;color:var(--navy)}
.hero .btn-primary:hover,.page-hero .btn-primary:hover,.cta-band .btn-primary:hover,.section.deep .btn-primary:hover{background:#eef2f6}
.hero .btn-ghost,.page-hero .btn-ghost,.cta-band .btn-ghost,.section.deep .btn-ghost{border-color:rgb(255 255 255/.45);color:#fff}
.hero .btn-ghost:hover,.page-hero .btn-ghost:hover,.cta-band .btn-ghost:hover,.section.deep .btn-ghost:hover{border-color:#fff;color:#fff}
/* sections -- three tones now alternate down a page (paper/mist/teal-tint)
   instead of two, plus .section.deep for full-bleed dark bands (mission,
   impact) that aren't a cta-band call-to-action */
.section{padding:clamp(3rem,8vw,5.5rem) 0}
.section.tint{background:var(--mist)}
.section.wash{background:var(--teal-tint)}
.section.deep{background:var(--navy-deep);color:#fff}
.section.deep h2{color:#fff}
.section.deep .eyebrow{color:var(--teal)}
.section.deep .lede{color:#d7dfe8}
/* .btn-ghost is transparent by default (fine on white); on a tint (mist)
   section that reads as no button at all, so give it an explicit paper
   background there to keep the raised-pill look. Scoped to .section.tint
   only -- the dark hero/page-hero/cta-band usages carry their own
   inversion rules above and are never inside .section.tint. */
.section.tint .btn-ghost{background:var(--paper)}
/* home hero (video) -- v3a: substantially taller (~72-80vh desktop) to
   carry the in-hero program picker; flex-centered since picker height
   varies. Mobile drops the min-height (a forced 80vh on a phone would
   mostly be empty space above/below a short hero) and lets content set
   natural height instead. */
.hero{position:relative;color:#fff;background:var(--navy-deep);overflow:hidden;
  min-height:80vh;display:flex;align-items:center}
.hero video,.hero>img.bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.55}
.hero::after{content:"";position:absolute;inset:0;background:linear-gradient(100deg,rgb(10 20 35/.88) 0%,rgb(10 20 35/.72) 32%,rgb(10 20 35/.32) 68%,rgb(10 20 35/.55) 100%)}
.hero .wrap{position:relative;z-index:1;padding-block:clamp(4rem,10vw,6rem);max-width:56rem;width:100%}
.hero h1{text-shadow:0 2px 24px rgb(0 0 0/.35)}
.hero .lede{color:#d7dfe8;text-shadow:0 1px 12px rgb(0 0 0/.3)}
@media (max-width:700px){.hero{min-height:0}}
/* program picker -- "What excites you most?" x "Your main interest" ->
   Find your program. Progressive enhancement, same pattern as .tabs/
   .js-tabs: default state is the no-JS fallback (plain links to the three
   program pages); JS adds .js-picker to swap in the real two-step form. */
.program-picker{margin-top:2.25rem;max-width:40rem}
.picker-fallback-label{font:600 .85rem/1 var(--sans);letter-spacing:.04em;color:#d7dfe8;margin:0 0 .75rem}
.picker-fallback p:not(.picker-fallback-label){margin:0}
.picker-fallback .btn{margin:0 .6rem .6rem 0}
.picker-form{display:none}
.js-picker .picker-fallback{display:none}
.js-picker .picker-form{display:grid;gap:1.1rem;background:rgb(255 255 255/.07);
  border:1px solid rgb(255 255 255/.2);border-radius:var(--radius);padding:1.5rem;
  backdrop-filter:blur(6px)}
@media (min-width:640px){.js-picker .picker-form{grid-template-columns:1fr 1fr auto;align-items:end;gap:1rem}}
.picker-step label{display:block;font:600 .74rem/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--teal);margin:0 0 .55rem}
.picker-step select{width:100%;font:600 1rem/1.3 var(--sans);padding:.85rem 1rem;
  border-radius:var(--radius-sm);border:1.5px solid rgb(255 255 255/.35);background:rgb(255 255 255/.08);color:#fff}
.picker-step select:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.picker-step select option{color:var(--ink)}
.picker-submit{width:100%}
@media (min-width:640px){.picker-submit{width:auto;white-space:nowrap}}
/* mission band -- quiet, serif, full-bleed navy-deep; the corpus mission
   statement verbatim, not a CTA (see cta-band) and not a testimonial
   (see .pullquote) */
.mission-band{text-align:center}
.mission-band .wrap{max-width:46rem}
.mission-band blockquote{margin:0 0 1.75rem;font-family:var(--serif);font-weight:400;
  font-size:clamp(1.4rem,3vw,2.1rem);line-height:1.5;color:#fff}
.mission-band blockquote p{margin:0 0 .75em}
.mission-band blockquote p:last-child{margin-bottom:0}
.mission-band .eyebrow{justify-content:center}
/* mission video (v3e) -- 16:9 responsive container, video as the band's
   ONLY content. The mission words are delivered by the video's own burned-in
   subtitles + captions track; the full statement additionally lives in the
   video's VideoObject JSON-LD transcript (seo.video_jsonld) and as plain
   visible body copy on /mission-and-vision/. The band no longer repeats the
   text underneath (owner: "it's on top the subtitles") -- see
   theme.mission_video_band(). */
.mission-video{max-width:42rem;margin:0 auto 1.75rem;border-radius:var(--radius);
  overflow:hidden;aspect-ratio:16/9;background:#000;box-shadow:0 20px 48px rgb(0 0 0/.35)}
.mission-video video{width:100%;height:100%;object-fit:cover}
/* impact band -- the corpus's own program figures (ECTS/duration), styled
   with real punch: large serif numerals, a teal top rule per tile (distinct
   from the field-card's gold rule) on a dark full-bleed band. Meant to be
   the most energetic section on the page. */
.impact-band .eyebrow{color:var(--teal)}
.impact-grid{display:grid;gap:2rem 1.75rem;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));margin-top:2.5rem}
.impact-figure{border-top:2px solid var(--teal);padding-top:1.15rem}
.impact-figure .value{font-family:var(--serif);font-weight:600;font-size:clamp(1.9rem,4vw,2.75rem);color:#fff;line-height:1.1;margin:0}
.impact-figure .label{font:600 .74rem/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--teal);margin:.9rem 0 .3rem}
.impact-figure .note{font:400 .92rem/1.5 var(--sans);color:#c9d3dd;margin:0}
/* interior page hero band -- answers "no hero images"; img may be absent
   (navy-only band is still valid) */
.page-hero{position:relative;color:#fff;background:var(--navy-deep);overflow:hidden}
.page-hero img.bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.55}
.page-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(100deg,rgb(10 31 54/.92) 0%,rgb(10 31 54/.72) 45%,rgb(10 31 54/.35) 100%)}
.page-hero .wrap{position:relative;z-index:1;padding-block:clamp(3.5rem,9vw,6rem);max-width:56rem}
.page-hero h1{text-shadow:0 2px 24px rgb(0 0 0/.35)}
.page-hero .lede{color:#d7dfe8;text-shadow:0 1px 12px rgb(0 0 0/.3);margin-bottom:0}
.page-hero .eyebrow{color:var(--gold)}
/* cards */
.grid{display:grid;gap:1.5rem}
@media (min-width:700px){.grid.cols-3{grid-template-columns:repeat(3,1fr)}.grid.cols-2{grid-template-columns:repeat(2,1fr)}}
.card{background:#fff;border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column;transition:box-shadow .2s,transform .2s;text-decoration:none}
.card:hover{box-shadow:0 14px 40px rgb(14 42 71/.12);transform:translateY(-3px)}
.card img{aspect-ratio:16/10;object-fit:cover;transition:transform .4s ease}
.card:hover img{transform:scale(1.04)}
.card .pad{padding:1.25rem 1.4rem 1.5rem}
.card h3{font-size:1.2rem}
.card p{margin:.3rem 0 0;color:var(--muted);font-size:.95rem}
/* live-challenges carousel (homepage) -- full-bleed horizontal scroller.
   Structure mirrors ewance.com's ChallengePreview component: header block
   stays on the normal .wrap rail, the track itself breaks out to the full
   viewport width via the same calc(50%-50vw) trick Tailwind's
   lg:mx-[calc(50%-50vw)] uses (percentage margins resolve against the
   containing block's width, so this works regardless of the section's own
   nesting), then re-applies inline padding so cards realign to the rail on
   wide screens while the next card still peeks in from the right edge. */
.challenge-carousel .lede{margin-top:.5rem}
.carousel-bleed{margin-inline:calc(50% - 50vw);margin-top:2.25rem}
.carousel-track{display:flex;gap:1.25rem;margin:0;padding:0 var(--pad) 1rem;list-style:none;
  overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;
  scrollbar-width:none}
.carousel-track::-webkit-scrollbar{display:none}
@media (min-width:1180px){
  .carousel-track{padding-inline:max(2rem, calc(50vw - 36rem + var(--pad)))}
}
.carousel-item{flex:0 0 82%;scroll-snap-align:start}
@media (min-width:600px){.carousel-item{flex-basis:58%}}
@media (min-width:900px){.carousel-item{flex-basis:42%}}
@media (min-width:1180px){.carousel-item{flex-basis:31%}}
.challenge-tile{height:100%}
.tile-cover{aspect-ratio:16/9;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,var(--tile-a,var(--navy)),var(--tile-b,var(--navy-soft)));color:rgb(255 255 255/.8)}
.tile-cover svg{width:30px;height:30px}
.tile-badges{display:flex;flex-wrap:wrap;gap:.4rem;margin:0 0 .65rem}
.badge{display:inline-block;font:600 .7rem/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;
  padding:.32rem .6rem;border-radius:999px;background:var(--teal-tint);color:var(--teal-deep)}
.badge-level{background:var(--mist);color:var(--muted);border:1px solid var(--rule)}
.carousel-swipe-hint{margin:0 0 .5rem;font:600 .75rem/1 var(--sans);letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);text-align:center}
.carousel-controls{display:flex;align-items:center;justify-content:flex-end;gap:1.25rem}
.carousel-arrows{display:none}
.carousel-browse{font-weight:600;text-decoration:underline;text-decoration-color:var(--rule);
  text-underline-offset:4px;color:var(--ink)}
.carousel-browse:hover{color:var(--navy);text-decoration-color:var(--navy)}
.carousel-attribution{margin:1rem 0 0;color:var(--muted);font-size:.9rem}
.carousel-attribution a{color:var(--teal-deep);font-weight:600;text-decoration:underline}
@media (min-width:900px){
  .carousel-swipe-hint{display:none}
  .carousel-controls{justify-content:space-between}
  .carousel-arrows{display:flex;gap:.6rem}
  .carousel-arrow{display:grid;place-items:center;width:2.5rem;height:2.5rem;border-radius:50%;
    border:1px solid var(--rule);background:var(--paper);color:var(--ink);cursor:pointer;
    transition:border-color .15s,color .15s,transform .15s}
  .carousel-arrow svg{width:20px;height:20px}
  .carousel-arrow:hover{border-color:var(--navy);color:var(--navy);transform:translateY(-1px)}
  .carousel-arrow:disabled{opacity:.3;cursor:not-allowed;transform:none}
}
/* field card -- the signature device: program facts, tuition packages,
   admissions steps, challenge briefs, homepage stats all reuse this */
/* align-items:stretch (the default) is deliberate: cards must be EQUAL
   height regardless of note length -- `start` made every tile shrink to its
   own text, which read as broken alignment. Cards are flex columns so the
   value/note stack sits consistently. */
.field-grid{display:grid;gap:1.15rem;grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.field-card{display:flex;flex-direction:column}
/* headline variant: the four "model" statements on the homepage -- bigger
   value, Lucide mark in a tinted disc, stronger hover. */
.field-grid-feature .field-card{padding:1.75rem 1.5rem 1.9rem;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.field-grid-feature .field-card:hover{transform:translateY(-4px);box-shadow:0 16px 40px rgb(14 42 71/.13);border-color:#cfd9e4}
.field-grid-feature .field-value{font-size:clamp(1.6rem,2.7vw,2.15rem)}
.field-icon{display:inline-flex;align-items:center;justify-content:center;width:2.75rem;height:2.75rem;
  border-radius:50%;background:var(--teal-tint);color:var(--teal-deep);margin:0 0 1.1rem}
.field-icon svg{width:22px;height:22px}
.field-grid-feature .field-card:nth-child(2) .field-icon{background:#fdf3d8;color:var(--gold-deep)}
.field-grid-feature .field-card:nth-child(4) .field-icon{background:#fdf3d8;color:var(--gold-deep)}
.field-card{background:var(--paper);border:1px solid var(--rule);border-radius:var(--radius);
  padding:1.5rem 1.4rem 1.6rem;border-top:2px solid var(--gold)}
.field-label{font:600 .72rem/1 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:0 0 .6rem}
.field-value{font-family:var(--serif);font-weight:600;font-size:clamp(1.5rem,2.4vw,2rem);color:var(--navy);line-height:1.15;margin:0}
.field-note{font:400 .9rem/1.5 var(--sans);color:var(--muted);margin:.5rem 0 0}
/* field-card variant carrying a bullet list + CTA link (tuition tiers) */
.field-card ul{list-style:none;margin:.9rem 0 0;padding:0;display:grid;gap:.5rem}
.field-card ul li{font:400 .92rem/1.4 var(--sans);color:var(--muted);padding-left:1.1em;position:relative}
.field-card ul li::before{content:"";position:absolute;left:0;top:.55em;width:.4em;height:.4em;background:var(--gold);border-radius:50%}
.field-card .btn{margin-top:1.25rem}
/* feature grid -- inline icon + h3 + one-sentence body */
.feature-grid{display:grid;gap:2rem 1.75rem;grid-template-columns:1fr}
@media (min-width:700px){.feature-grid{grid-template-columns:repeat(2,1fr)}}
@media (min-width:980px){
  .feature-grid{grid-template-columns:repeat(3,1fr)}
  /* Exactly 4 items in a fixed 3-col grid leaves a lone orphan alone on a
     near-empty second row -- force a clean 2x2 instead. */
  .feature-grid:has(> :nth-child(4):last-child){grid-template-columns:repeat(2,1fr)}
}
.feature{display:flex;flex-direction:column;gap:.75rem}
.feature svg{color:var(--navy)}
.feature h3{font:600 1.1rem/1.3 var(--sans);margin:0;color:var(--ink)}
.feature p{margin:0;color:var(--muted);font-size:.95rem}
/* split band -- image one side, prose the other, alternates via .reverse */
.split{display:grid;gap:2.5rem;align-items:center}
@media (min-width:900px){
  .split{grid-template-columns:1fr 1fr}
  .split.reverse .split-media{order:2}
}
.split-media img{border-radius:var(--radius);aspect-ratio:4/3;object-fit:cover;width:100%}
/* CTA band */
.cta-band{background:var(--navy);color:#fff;text-align:center}
.cta-band h2{color:#fff}
.cta-band .lede{color:#d7dfe8}
/* jump-nav -- sticky-under-header anchor bar, horizontally scrollable at
   every width (chosen over hiding it on mobile: one code path, and a jump
   bar earns its keep most on a long page read on a phone) */
[id]{scroll-margin-top:5.5rem}
/* Pages with a jump-nav stack a second sticky bar under the header, so
   5.5rem (header-only clearance) leaves the target heading's top ~40px
   under the jump-nav on click. Give those pages the fuller offset. */
main:has(.jump-nav) [id]{scroll-margin-top:9rem}
.jump-nav{position:sticky;top:4.25rem;z-index:40;background:rgb(255 255 255/.94);backdrop-filter:blur(8px);border-bottom:1px solid var(--rule)}
.jump-nav ul{display:flex;gap:1.75rem;list-style:none;margin:0;padding:.85rem 0;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.jump-nav ul::-webkit-scrollbar{display:none}
.jump-nav a{white-space:nowrap;text-decoration:none;font:600 .85rem/1 var(--sans);letter-spacing:.02em;color:var(--muted);padding-bottom:.4rem;border-bottom:2px solid transparent;display:inline-block}
.jump-nav a:hover{color:var(--navy)}
.jump-nav a[aria-current="true"]{color:var(--navy);border-bottom-color:var(--gold)}
/* tabs -- progressive enhancement: default state IS the <700px accordion
   look (every panel stacked, its label a heading, tablist hidden); JS adds
   .js-tabs, which only takes effect >=700px, to switch to real tabs */
.tabs{margin-top:1.5rem}
.tabs .tablist{display:none}
.tabs .tabpanel{padding-block:1.25rem;border-top:1px solid var(--rule)}
.tabs .tabpanel:first-child{border-top:0;padding-top:0}
.tabs .tab-label{font:600 1.05rem/1.3 var(--sans);color:var(--navy);margin:0 0 .5rem}
.tabs .tabpanel .prose{max-width:none}
.tabs .tabpanel .prose p{margin:0}
@media (min-width:700px){
  /* A fixed-count tablist (e.g. industrial-phd's six panels) can outgrow
     even a 1440px row -- flex-wrap left an orphan tab alone on a near-empty
     second row, the least tidy element on the site. One row, always:
     nowrap + horizontal scroll (same hidden-scrollbar treatment as
     .jump-nav) with a soft mask-image fade at each edge so a scrollable
     tablist reads as an intentional device, not a cut-off. Tablists short
     enough to fit (bachelors/master's/MBA's four tabs) simply never
     scroll -- .tablist.scrolls (see the tabs script) is the only thing
     that turns the fade on, so those pages are pixel-identical to before.*/
  .tabs.js-tabs .tablist{display:flex;flex-wrap:nowrap;gap:.5rem 2rem;border-bottom:1px solid var(--rule);
    margin-bottom:1.75rem;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .tabs.js-tabs .tablist::-webkit-scrollbar{display:none}
  .tabs.js-tabs .tablist.scrolls{mask-image:linear-gradient(to right,transparent 0,#000 1.5rem,#000 calc(100% - 1.5rem),transparent 100%);
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 1.5rem,#000 calc(100% - 1.5rem),transparent 100%)}
  .tabs.js-tabs .tab{flex:none;white-space:nowrap;background:none;border:0;font:600 .95rem/1 var(--sans);letter-spacing:.02em;color:var(--muted);
    padding:.25rem 0 .9rem;cursor:pointer;border-bottom:2px solid transparent;transition:color .15s,border-color .15s}
  .tabs.js-tabs .tab:hover{color:var(--navy)}
  .tabs.js-tabs .tab[aria-selected="true"]{color:var(--navy);border-bottom-color:var(--gold)}
  .tabs.js-tabs .tabpanel{display:none;border-top:0;padding-block:0}
  .tabs.js-tabs .tabpanel.is-active{display:block}
  .tabs.js-tabs .tab-label{position:absolute;left:-9999px}
}
/* pull-quote -- testimonial treatment: Source Serif 4, larger size, a gold
   vertical rule on the left (ties to the field-card's gold top rule) */
.pullquote{margin:2rem 0;padding-left:1.5rem;border-left:3px solid var(--gold)}
.pullquote p{font-family:var(--serif);font-weight:400;font-size:clamp(1.15rem,2vw,1.4rem);
  color:var(--navy);line-height:1.5;margin:0 0 .75em}
.pullquote p:last-of-type{margin-bottom:0}
.pullquote cite{display:block;margin-top:1rem;font:600 .85rem/1 var(--sans);
  font-style:normal;font-variant:small-caps;letter-spacing:.03em;color:var(--muted)}
/* prose (content + blog pages) */
.prose{max-width:44rem}
.prose h2{margin-top:2.2em}
.prose p{margin:1em 0}
.prose li{margin:.4em 0}
.prose img{border-radius:var(--radius);margin:1.5rem 0}
/* FAQ (details/summary) -- one accordion language, theme.faq_items(). Cards
   rather than plain border-top rules (the earlier, plainer treatment read as
   an undesigned list of text): each question is its own bordered, rounded
   tile with a rotating Lucide "plus" toggle, so the section reads as a
   designed component even before any item is opened. */
.faq{margin-top:2em;display:grid;gap:.85rem}
.faq-item{background:var(--paper);border:1px solid var(--rule);border-radius:var(--radius-sm);
  overflow:hidden;transition:border-color .2s ease,box-shadow .2s ease}
.faq-item:hover{border-color:#cfd9e4}
.faq-item[open]{border-color:var(--teal);box-shadow:0 10px 28px rgb(14 42 71/.1)}
.faq-item summary{list-style:none;cursor:pointer;display:flex;align-items:center;
  justify-content:space-between;gap:1rem;padding:1.05em 1.3em;
  font:600 1.02rem/1.4 var(--sans);color:var(--ink)}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::marker{content:""}
.faq-icon{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:1.9rem;height:1.9rem;border-radius:50%;background:var(--teal-tint);color:var(--teal-deep);
  transition:transform .25s ease,background .2s ease,color .2s ease}
.faq-icon svg{width:18px;height:18px}
.faq-item[open] .faq-icon{transform:rotate(45deg);background:var(--gold);color:var(--navy)}
.faq-a{padding:0 1.3em 1.2em;color:var(--muted);font-size:.98rem}
.faq-a p{margin:0}
/* dark-band variant (homepage FAQ sits on a .tint section by default, but
   guard the deep/navy case too since faq_section() accepts any cls) */
.section.deep .faq-item{background:rgb(255 255 255/.06);border-color:rgb(255 255 255/.16)}
.section.deep .faq-item summary{color:#fff}
.section.deep .faq-a{color:#d7dfe8}
/* forms */
.form{display:grid;gap:1rem;max-width:32rem}
.form label{font-weight:600;font-size:.9rem}
.form input,.form select,.form textarea{width:100%;font:inherit;padding:.8rem 1rem;border:1.5px solid var(--rule);border-radius:var(--radius-sm);background:#fff}
.form input:focus,.form textarea:focus{outline:2px solid var(--gold);outline-offset:1px;border-color:var(--navy)}
.hp{position:absolute;left:-5000px}    /* honeypot */
/* footer -- sections own their spacing now; navy meets content edge cleanly */
.site-foot{background:var(--navy-deep);color:#c9d3dd;font-size:.92rem}
.site-foot .wrap{display:grid;gap:2rem;padding-block:3.5rem}
@media (min-width:700px){.site-foot .wrap{grid-template-columns:2fr 1fr 1fr 1fr}}
.site-foot a{color:#fff;text-decoration:none}.site-foot a:hover{text-decoration:underline}
.site-foot .motto{position:relative;padding-top:1.15rem;font-family:var(--serif);font-size:1.25rem;color:#fff}
.site-foot .motto::before{content:"";position:absolute;top:0;left:0;width:3rem;height:2px;background:var(--gold)}
.foot-bottom{border-top:1px solid rgb(255 255 255/.12)}
.foot-bottom .wrap{display:flex;flex-wrap:wrap;gap:1rem;justify-content:space-between;padding-block:1.2rem}
/* motion -- one orchestrated behaviour, not scattered effects */
.reveal{opacity:0;transform:translateY(16px);
  transition:opacity .6s cubic-bezier(.2,.7,.3,1),transform .6s cubic-bezier(.2,.7,.3,1);
  /* Capped at 6 steps (420ms) -- long grids (24 sample-challenge cards, etc.)
     otherwise accumulate an uncapped per-item delay (i*70ms) that leaves
     later items sitting at opacity:0, genuinely invisible, for well over a
     second after they've already scrolled into view. */
  transition-delay:calc(min(var(--i,0),6)*70ms)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .reveal{opacity:1!important;transform:none!important}
  .hero video{display:none}
}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
