/* =============================================================================
   University of Toronto — Machine Learning Group
   Shared stylesheet for all pages.

   Design decisions (locked in after design-previewer feedback):
     • Palette ........ Sand (warm off-white surfaces)
     • Type ........... Headers = Bembo (serif), Body = Trade Gothic Next (sans)
     • Accent ......... U of T Blue #1E3765 ONLY. All "variations" are opacity
                        steps of the same hue — no off-brand blues anywhere.
     • Width .......... Responsive in-between: fluid up to a 1360px cap so large
                        screens don't read as empty, but it still breathes.
   The standalone design previewer is preserved under /design-options/.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. Web fonts
   - Trade Gothic Next (body) via Adobe Typekit — U of T's designated sans.
   - Bembo (headlines) via Adobe Typekit — U of T's designated serif.
   Both load through licensed kit CSS in each page's <head>:
       <link rel="preconnect" href="https://use.typekit.net" crossorigin>
       <link rel="stylesheet" href="https://use.typekit.net/rwd3ahf.css">  (trade-gothic-next)
       <link rel="stylesheet" href="https://use.typekit.net/kpp6qjy.css">  (bembo)
   NOTE: do not add local @font-face rules named "Bembo" — family matching is
   case-insensitive, so they'd override the kit's "bembo" faces and break it.
   - EB Garamond remains as a fallback serif behind Bembo; final fallback is
     Times New Roman (U of T's stated digital substitute for Bembo).
   -------------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&display=swap');

/* -----------------------------------------------------------------------------
   2. Design tokens
   -------------------------------------------------------------------------- */
:root {
    /* ---- U of T Blue: one hue, opacity-only variations -------------------- */
    --uoft-blue: #1E3765;            /* official #1E3765 = rgb(30,55,101)      */
    --uoft-blue-rgb: 30, 55, 101;
    --blue-90: rgba(30, 55, 101, 0.90);
    --blue-70: rgba(30, 55, 101, 0.70);
    --blue-55: rgba(30, 55, 101, 0.55);
    --blue-40: rgba(30, 55, 101, 0.40);
    --blue-25: rgba(30, 55, 101, 0.25);
    --blue-15: rgba(30, 55, 101, 0.15);
    --blue-08: rgba(30, 55, 101, 0.08);
    --blue-04: rgba(30, 55, 101, 0.04);

    /* ---- Semantic colour roles (Sand palette) ----------------------------- */
    --color-primary:        var(--uoft-blue);
    --color-primary-hover:  var(--blue-90);   /* subtle opacity step on hover  */
    --color-link:           var(--uoft-blue);
    --color-text:           #1a1a2e;          /* near-black for body copy       */
    --color-text-light:     #44485a;
    --color-text-muted:     #5f6373;          /* ≥4.5:1 on sand and white (WCAG AA) */
    --color-background:     #f0efee;          /* sand                           */
    --color-background-alt: #ffffff;
    --color-surface-tint:   var(--blue-08);
    --color-border:         #e2ddd3;
    --color-white:          #ffffff;

    /* ---- Type ------------------------------------------------------------- */
    --font-serif: 'bembo', 'EB Garamond', Georgia, 'Times New Roman', serif;
    --font-sans:  'trade-gothic-next', 'Trade Gothic Next', 'Helvetica Neue', Arial, sans-serif;

    --font-size-xs:  0.75rem;
    --font-size-sm:  0.875rem;
    --font-size-base:1rem;
    --font-size-lg:  1.125rem;
    --font-size-xl:  1.25rem;
    --font-size-2xl: 1.5rem;
    --font-size-3xl: 2rem;
    --font-size-4xl: 2.75rem;

    /* ---- Spacing ---------------------------------------------------------- */
    --spacing-xs:  0.25rem;
    --spacing-sm:  0.5rem;
    --spacing-md:  1rem;
    --spacing-lg:  1.5rem;
    --spacing-xl:  2rem;
    --spacing-2xl: 3rem;
    --spacing-3xl: 4rem;
    --spacing-4xl: 6rem;
    --spacing-5xl: 8rem;
    /* Vertical rhythm: space at the top and bottom of every section, and
       between a section's header and its content. */
    --section-space: 4rem;
    --block-gap: 2.5rem;

    /* ---- Layout ----------------------------------------------------------- */
    /* Responsive in-between width: fluid (uses the viewport) but capped at
       1360px so wide monitors never feel sparse the way the 1600px full-width
       option did, while still reading much wider than the 1100px "regular". */
    --container-max: 1360px;
    --container-padding: clamp(1.25rem, 4vw, 3rem);
    --header-h: 103px;   /* height of .site-header; the sticky hero graphic sits below it */
    --notice-h: 0px;     /* height of .notice-band when shown; site.js sets it */

    --transition-fast: 150ms ease;
    --transition-base: 250ms ease;
    --radius: 2px;
}

/* -----------------------------------------------------------------------------
   3. Reset & base elements
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    font-size: 100%;   /* respect the reader's browser font-size setting */
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Body copy — Trade Gothic Light. (The loaded kit ships 400/700/800; 300
   gracefully renders at the nearest available weight until a Light face is
   added.) */
body {
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    font-weight: 300;
    line-height: 1.7;
    color: var(--color-text);
    background-color: var(--color-background);
}

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

a {
    color: var(--color-link);
    text-decoration: none;
    text-underline-offset: 0.15em;
    transition: color var(--transition-fast), opacity var(--transition-fast);
}
a:hover { color: var(--color-primary-hover); }
/* Plain text links (contact details, footer credit, photo credits): U of T
   Blue, underlined on hover and keyboard focus. Cards and buttons style
   their own hover. */
a:not([class]):hover, a:not([class]):focus-visible,
a.tl-credit:hover, a.tl-credit:focus-visible { text-decoration: underline; }
/* One clear keyboard focus ring everywhere (white on the dark timeline captions). */
:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.tl-cap :focus-visible { outline-color: var(--color-white); }

/* "Skip to main content": off-screen until focused with the keyboard. */
.skip-link {
    position: absolute;
    top: var(--spacing-sm);
    left: var(--spacing-sm);
    z-index: 1001;   /* above the sticky header */
    padding: var(--spacing-sm) var(--spacing-md);
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-white);
    background-color: var(--color-primary);
    border-radius: var(--radius);
    transform: translateY(-200%);
}
.skip-link:focus { transform: none; color: var(--color-white); }

/* Headlines & subheads — Bembo (serif), per the locked-in type direction.
   Weight 600 targets the Semibold cut; serif normal gets -0.5px tracking to
   match the quote/stat voice. Sans labels (.section-label, .where-aside h3,
   .contact-info h3) override this locally and stay Trade Gothic. */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-serif);
    font-weight: 600;
    letter-spacing: -0.03em;
    line-height: 1.2;
    color: var(--color-primary);
}

/* Deck — page intros above the fold and short one-line subheadings, in
   Trade Gothic Bold. Longer section descriptions stay at body weight. */
.deck, .page-hero > .container > p { font-weight: 700; }

/* Quote & Stats — the serif voice (Bembo, falling back to EB Garamond).
   Tracking: serif italic → 0; serif normal/bold → -0.5px. */
.quote, blockquote, .stat {
    font-family: var(--font-serif);
    font-weight: 400;
}
.stat { letter-spacing: -0.03em; }            /* serif normal */
.quote, blockquote { font-style: italic; letter-spacing: 0; }  /* serif italic */
h1 { font-size: var(--font-size-4xl); }
h2 { font-size: var(--font-size-3xl); }
h3 { font-size: var(--font-size-xl); }

ul, ol { list-style: none; }

/* -----------------------------------------------------------------------------
   4. Layout helpers
   -------------------------------------------------------------------------- */
.container {
    width: 100%;
    max-width: min(92vw, var(--container-max));
    margin-inline: auto;
    padding-inline: var(--container-padding);
}

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

.section-label {
    font-family: var(--font-sans);
    font-size: var(--font-size-xs);
    font-weight: 700;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    line-height: 1.2;   /* tight, so a section's first ink sits on its padding */
    margin-bottom: var(--spacing-sm);
}

.section-header { margin-bottom: var(--block-gap); }
.section-header.center { text-align: center; }
.section-header h2 { margin-bottom: var(--spacing-md); }

.section-description {
    max-width: 640px;
    color: var(--color-text-light);
    font-size: var(--font-size-lg);
}
.section-header.center .section-description { margin-inline: auto; }

/* -----------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
    display: inline-block;
    padding: 0.7rem 1.6rem;
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-align: center;
    border-radius: var(--radius);
    border: 1px solid transparent;
    cursor: pointer;
    transition: all var(--transition-fast);
}
.btn-primary {
    background-color: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}
.btn-primary:hover {
    background-color: var(--blue-90);
    border-color: var(--blue-90);
    color: var(--color-white);
    transform: translateY(-2px);
}
.btn-secondary {
    background-color: transparent;
    color: var(--color-primary);
    border-color: var(--blue-40);
}
.btn-secondary:hover {
    background-color: var(--blue-08);
    border-color: var(--color-primary);
    color: var(--color-primary);
    transform: translateY(-2px);
}

/* Announcement band — a time-limited notice above the header on every page.
   It scrolls away with the page (the header below is sticky). site.js
   inserts it from SITE_NOTICE and stops showing it after the expiry date. */
.notice-band {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.35rem var(--spacing-md);
    padding: 0.6rem var(--container-padding);
    background-color: var(--color-primary);
    color: var(--color-white);
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    text-align: center;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--transition-fast);
}
.notice-band:is(:hover, :focus-visible, :active) { color: var(--color-white); }
.notice-band:focus-visible { outline: 3px solid var(--blue-40); outline-offset: -3px; }
.notice-band-tag {
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 0.1rem 0.45rem;
    border: 1px solid rgba(255, 255, 255, 0.6);
    border-radius: var(--radius);
}
.notice-band-text { font-weight: 700; }
.notice-band-cta { font-weight: 700; white-space: nowrap; }
.notice-band-cta-label { text-decoration: underline; text-underline-offset: 0.2em; }
.notice-band-cta svg { width: 1rem; height: 1rem; vertical-align: -0.2em; }
@media (hover: hover) { .notice-band:hover { background-color: #2a4a82; } }
.notice-band:active { background-color: #2a4a82; }
/* Phones: one line of running text instead of three columns —
   "Now open: Fall 2027 … December 1, 2026. Learn more ›" (dates are kept
   whole by site.js). */
@media (max-width: 48em) {
    .notice-band { display: block; padding-block: 0.65rem; line-height: 1.45; }
    .notice-band-tag { padding: 0; border: 0; font-size: inherit; text-transform: none; letter-spacing: 0; }
    .notice-band-tag::after { content: ":\00a0"; }
    .notice-band-text { font-weight: 400; }
    .notice-band-text::after { content: "."; }
    .notice-band-cta { margin-left: 0.25em; }
}
#graduate { scroll-margin-top: var(--spacing-md); }

/* -----------------------------------------------------------------------------
   6. Header & navigation
   -------------------------------------------------------------------------- */
.site-header {
    /* Scrolls away with the page, then re-reveals when the user scrolls up.
       JS toggles .site-header--hidden; sticky keeps it pinned while visible. */
    position: sticky;
    top: 0;
    z-index: 1000;
    background-color: var(--color-background);
    border-bottom: 1px solid var(--color-border);
    backdrop-filter: saturate(180%) blur(6px);
    transition: transform var(--transition-base);
    will-change: transform;
}
.site-header--hidden { transform: translateY(-100%); }

.main-nav {
    width: 100%;
    max-width: min(92vw, var(--container-max));
    margin-inline: auto;
    padding: var(--spacing-md) var(--container-padding);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-xl);
}

/* Logo — black-on-white source recoloured to U of T Blue via SVG filter.
   Rendered as a real <img> at 70px tall so it isn't shrunk to fit a box;
   width follows the image's ~7.2:1 aspect ratio. */
/* Logo never shrinks (keeps its true aspect ratio); SVGs are pre-coloured. */
.brand { display: inline-flex; align-items: center; flex-shrink: 0; }
.logo {
    display: block;
    height: 70px;
    width: auto;
    flex-shrink: 0;
}
.logo--simple { display: none; }   /* swapped in when space is tight */

.nav-list {
    display: flex;
    align-items: center;
    gap: clamp(0.85rem, 1.9vw, 2rem);
}
.nav-link {
    display: inline-block;
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    font-weight: 500;
    color: var(--color-text-light);
    /* Horizontal padding gives the hover tint block breathing room around
       the text; the matching negative margin cancels it out of the layout,
       so link spacing and header edge alignment stay exactly as before. */
    padding: var(--spacing-sm) 0.75rem;
    margin: 0 -0.75rem;
    border-radius: var(--radius);
    white-space: nowrap;
    transition: color var(--transition-base), background-color var(--transition-base);
}

/* Hover — the link's block softly tints blue (an opacity step of the one
   brand blue), mirroring the mobile menu's hover treatment. */
.nav-link:hover,
.nav-link:focus-visible {
    color: var(--color-primary);
    background-color: var(--blue-08);
}

.nav-link.active {
    color: var(--color-primary);
    font-weight: 700;   /* bold the current page */
    /* background-color: var(--blue-04); */
}
.nav-link.active:hover,
.nav-link.active:focus-visible {
    background-color: var(--blue-08);
}

@media (prefers-reduced-motion: reduce) {
    .nav-link { transition: none; }
}

/* Mobile menu toggle */
.nav-toggle {
    display: none;
    width: 40px; height: 40px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: transparent;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    color: var(--color-primary);
}
.nav-toggle svg { width: 20px; height: 20px; overflow: visible; }
/* Three bars that fold into an X while the menu is open: the outer bars move
   to the centre line and rotate, the middle one fades out. */
.nav-toggle-bar {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    transform-box: view-box;
    transform-origin: 12px 12px;
    transition: transform var(--transition-base), opacity var(--transition-fast);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: rotate(45deg) translateY(5px); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: rotate(-45deg) translateY(-5px); }
@media (prefers-reduced-motion: reduce) {
    .nav-toggle-bar { transition: none; }
}

/* -----------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */
/* Desktop hero: text in a wide column, the graphic in a narrow one beside it.
   The graphic is sized to fit on screen below the header and stays put
   (sticky) while longer text scrolls past; the section then scrolls away. */
.hero {
    /* Fill the first screen below the notice band and header. */
    min-height: calc(100svh - var(--header-h) - var(--notice-h));
    /* A minimum gap only: min-height + centring set the real spacing, so the
       text still fits the first screen on shorter laptops. */
    padding: var(--spacing-2xl) 0;
    overflow: clip;   /* clip the graphic's overhang without breaking sticky */
    background-color: var(--color-background);
}
.hero .container {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);   /* graphic ~40% of the row */
    column-gap: var(--spacing-3xl);
    align-items: center;
}

.hero h1 {
    font-size: clamp(2.4rem, 5.2vw, 3.5rem);
    font-weight: 600;
    /* letter-spacing: -0.03em; */
    line-height: 1.08;
    margin-bottom: var(--spacing-xl);
}
.hero-description {
    font-size: var(--font-size-base);
    line-height: 1.75;
    color: var(--color-text-light);
    margin-bottom: var(--spacing-md);
}
.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-md);
    margin-top: var(--spacing-xl);
}

/* Hero graphic shell. The SVG stack is injected by JS and sized to this box:
   as wide as the column, compressed (then shrunk) to fit its height. */
.hero-graphic {
    position: sticky;
    top: var(--header-h);
    align-self: center;   /* centred on the text when the text is the taller */
    /* Span the hero's full height: bleed through its top/bottom padding and
       fill the first screen below the notice band and header. */
    height: calc(100svh - var(--header-h) - var(--notice-h));
    margin-block: calc(-1 * var(--spacing-2xl));
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    overflow: visible;
}
.hero-graphic svg { display: block; }

/* -----------------------------------------------------------------------------
   8. Generic page sections
   -------------------------------------------------------------------------- */
/* One vertical rhythm: 96px between a section's edge and its content (64px on
   phones), 48px between a section header and what follows, and no stray
   bottom margin on a section's last block. */
.section { padding: var(--section-space) 0; }
.section > .container > :last-child { margin-bottom: 0; }
.section--tint { background-color: var(--color-background-alt); }
.section--sand { background-color: var(--color-background); }
/* Divider line between two same-coloured sections. */
.section--divider-top { border-top: 1px solid var(--color-border); }

.page-hero {
    padding: var(--section-space) 0;   /* same rhythm as .section */
    border-bottom: 1px solid var(--color-border);
}
.page-hero h1 {
    font-size: clamp(2.2rem, 4.5vw, 3rem);
    margin-bottom: var(--spacing-md);
}
.page-hero p {
    max-width: 60ch;
    font-size: var(--font-size-lg);
    color: var(--color-text-light);
}
/* Keep the eyebrow label at the standard .section-label size, not the
   enlarged page-hero paragraph size. */
.page-hero p.section-label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* Vertical timeline (adapted from the originui-vue timeline pattern):
   a marker rail down the left with dot + connector, content to the right. */
.timeline { position: relative; max-width: 760px; }
.timeline-item {
    position: relative;
    padding-left: 2.75rem;
    padding-bottom: var(--spacing-2xl);
}
.timeline-item:last-child { padding-bottom: 0; }
/* connector line */
.timeline-item::before {
    content: "";
    position: absolute;
    left: 9px;
    top: 1.7rem;
    bottom: -0.4rem;
    width: 2px;
    background-color: var(--blue-15);
    transition: background-color 350ms ease;
}
.timeline-item:last-child::before { display: none; }
/* dot marker */
.timeline-item::after {
    content: "";
    position: absolute;
    left: 0;
    top: 0.4rem;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: var(--color-background);
    border: 2px solid var(--color-primary);
    box-shadow: 0 0 0 4px var(--color-background);
    transition: background-color 350ms ease, box-shadow 350ms ease;
}
.timeline--tint .timeline-item::after { box-shadow: 0 0 0 4px var(--color-background-alt); }

/* Active state (set by JS as you scroll, or on click): the rail fills up to
   the active event, its dot fills in, and a tinted highlight slides behind it. */
.timeline--interactive .timeline-item { cursor: pointer; }
.timeline-item.is-past::before { background-color: var(--color-primary); }
.timeline-item.is-past::after,
.timeline-item.is-active::after { background-color: var(--color-primary); }
.timeline-item.is-active::after { box-shadow: 0 0 0 4px var(--blue-25); }
.timeline-indicator {
    position: absolute;
    top: 0;
    left: -0.75rem;
    right: 0;
    height: 0;
    border-radius: var(--radius);
    background-color: var(--blue-08);
    pointer-events: none;
    transition: transform 400ms cubic-bezier(0.22, 1, 0.36, 1),
                height 400ms cubic-bezier(0.22, 1, 0.36, 1);
}
.timeline-indicator.is-instant { transition: none; }
.timeline-date {
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--color-primary);
}
.timeline-title {
    font-size: var(--font-size-xl);
    color: var(--color-text-light);
    margin: 0.15rem 0 0.45rem;
    transition: color 350ms ease;
}
/* The title's button looks exactly like the heading text. */
.timeline-trigger {
    font: inherit;
    letter-spacing: inherit;
    color: inherit;
    text-align: left;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}
.timeline-item.is-active .timeline-title,
.timeline--interactive .timeline-item:hover .timeline-title { color: var(--color-primary); }
@media (prefers-reduced-motion: reduce) {
    .timeline-item::before, .timeline-item::after,
    .timeline-title, .timeline-indicator, .tl-media { transition: none; }
}
.timeline-body {
    color: var(--color-text-light);
    font-size: var(--font-size-base);
    max-width: 60ch;
}

/* Two-column timeline: events on the left, a sticky image stage on the right
   that swaps as you scroll. On mobile the stage is hidden and each event
   carries its own image inline (see .tl-inline below). */
.timeline-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--spacing-3xl);
    align-items: start;
}
.timeline-media-sticky {
    position: sticky;
    top: 120px;
}
.timeline-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    border-radius: var(--radius);
    overflow: hidden;
    background-color: var(--blue-08);
}
/* A media panel: either an <img> or a styled placeholder. Stacked and
   cross-faded inside the stage; shown inline (static) on mobile. */
.tl-media {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: var(--spacing-lg);
    /* Solid U of T blue — a per-event shade is applied inline by JS (no gradients). */
    background-color: var(--uoft-blue);
    opacity: 0;
    visibility: hidden;
    transition: opacity 450ms ease, visibility 0s linear 450ms;
}
.timeline-stage .tl-media.is-active { opacity: 1; visibility: visible; transition-delay: 0s; }
/* With a photo: the image fills the panel above a solid caption band. */
.tl-media--photo { padding: 0; }
.tl-media--photo::before { display: none; }
.tl-media img {
    flex: 1 1 0;
    min-height: 0;
    width: 100%;
    object-fit: cover;
}
/* Diagrams and logos: shown whole on white rather than cropped. */
.tl-media--contain img {
    object-fit: contain;
    padding: var(--spacing-lg);
    background-color: var(--color-white);
}
/* Graphics with their own text: shown whole, letterboxed on the panel colour. */
.tl-media--letterbox img { object-fit: contain; }
.tl-media--photo .tl-cap {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: var(--spacing-md);
    align-items: baseline;
    padding: var(--spacing-md) var(--spacing-lg);
    text-shadow: none;
}
.tl-media--photo .tl-year { font-size: var(--font-size-2xl); }
.tl-media--photo .tl-caption { margin-top: 0; }
.tl-credit {
    grid-column: 1 / -1;
    margin-top: var(--spacing-xs);
    font-family: var(--font-sans);
    font-size: 0.7rem;
    color: rgba(255, 255, 255, 0.72);
}
a.tl-credit:hover { color: var(--color-white); }
.tl-cap { position: relative; z-index: 1; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.28); }

/* "placeholder" corner badge — shown on every placeholder image (not avatars). */
.tl-media::before,
.photo-fallback::before,
.placeholder-box::before {
    content: "placeholder";
    position: absolute;
    top: var(--spacing-sm);
    left: var(--spacing-sm);
    z-index: 3;
    font-family: var(--font-sans);
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--uoft-blue);
    background-color: rgba(255, 255, 255, 0.9);
    padding: 0.12rem 0.45rem;
    border-radius: 2px;
}
.photo-fallback, .placeholder-box { position: relative; }
.tl-year {
    font-family: var(--font-sans);
    font-size: var(--font-size-4xl);
    line-height: 1;
    color: var(--color-white);
}
.tl-caption {
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: rgba(255, 255, 255, 0.92);
    margin-top: var(--spacing-xs);
}
/* Inline media wrapper inside each event — desktop hides it (the sticky
   stage handles imagery); mobile shows it grouped with its event. */
.tl-inline {
    display: none;
    margin-top: var(--spacing-md);
}
.tl-inline .tl-media {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius);
    overflow: hidden;
    opacity: 1;
    visibility: visible;
}
.tl-inline .tl-media--photo { aspect-ratio: 4 / 3; }

@media (max-width: 48em) {
    .timeline-layout { grid-template-columns: 1fr; gap: 0; }
    .timeline-media-sticky { display: none; }
    .tl-inline { display: block; }
}

/* Research-areas / feature columns */
.feature-columns {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--spacing-2xl);
    margin-bottom: var(--block-gap);
}
/* About (Mission / History / Excellence): serif headings. */
.feature-card h2 { font-size: var(--font-size-2xl); margin-bottom: var(--spacing-md); }
/* Research areas: small sans labels. */
.feature-card h3 {
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-primary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: var(--spacing-md);
}
.feature-card p {
    color: var(--color-text-light);
    font-size: var(--font-size-base);
}

/* Large feature image / team photo */
.feature-image img,
.feature-image .photo-fallback {
    width: 100%;
    height: clamp(320px, 42vw, 520px);
    object-fit: cover;
    background-color: var(--blue-08);
    border-radius: var(--radius);
}
/* Caption matches the .section-label eyebrow style. */
.feature-image figcaption {
    padding-top: var(--spacing-md);
    font-family: var(--font-sans);
    font-size: var(--font-size-xs);
    font-weight: 700;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

/* Reusable placeholder image block (solid U of T blue, badge via ::before). */
.placeholder-box {
    background-color: var(--blue-15);
    border-radius: var(--radius);
}

/* Section header with a placeholder image at the top-right. */
.section-with-media {
    display: flex;
    gap: var(--spacing-2xl);
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: var(--spacing-2xl);
}
.section-with-media .section-header { flex: 1; margin-bottom: 0; }
.section-corner-media {
    flex-shrink: 0;
    width: clamp(200px, 26vw, 320px);
    aspect-ratio: 4 / 3;
}
@media (max-width: 48em) {
    .section-with-media { flex-direction: column; }
    .section-corner-media { width: 100%; aspect-ratio: 16 / 9; }
}

/* -----------------------------------------------------------------------------
   9. People grid (faculty / students)
   -------------------------------------------------------------------------- */
/* ---- Tile variant (home page): square cards, à la design-options -------- */
/* Flex rather than grid so a short last row sits centred under the others. */
.people-grid--tile {
    --cols: 5;
    --gap: var(--spacing-4xl);
    max-width: 66rem;
    margin: var(--spacing-3xl) auto 0;   /* more air under the section intro than the usual header gap */
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--spacing-3xl) var(--gap);
}
.people-grid--tile > * { flex: 0 0 calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols)); }
@media (max-width: 64em) { .people-grid--tile { --cols: 4; --gap: var(--spacing-2xl); row-gap: var(--spacing-2xl); } }
.person-tile {
    display: flex;
    flex-direction: column;
}
.person-tile .tile-img { margin-bottom: var(--spacing-md); }
/* Linked people (home tiles, People cards) lift and underline the name on
   hover; the card opens their homepage. */
.person-tile, .person-profile { transition: transform var(--transition-fast); }
.person-tile[href]:hover, .person-profile.is-linked:hover { transform: translateY(-3px); }
.person-tile[href]:hover .person-name,
.person-profile.is-linked:hover .pp-name { text-decoration: underline; }
.tile-img {
    width: 100%;
    aspect-ratio: 1;
    border-radius: var(--radius);          /* essentially square */
    background-color: var(--blue-08);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-serif);
    font-size: var(--font-size-4xl);
    color: var(--blue-40);
    transition: background-color var(--transition-base), color var(--transition-base);
}
.person-tile:hover .tile-img { background-color: var(--blue-15); color: var(--blue-55); }
/* Faculty photos: shown as a uniform U of T Blue monotone (grayscale under a
   blue "color" blend), switching to full colour on hover. The look is set by
   the --photo-* variables below; open index.html?tune or people.html?tune
   for a live tuner (tuner.js, /dev only) that writes out a new set. */
:root {
    --photo-grayscale: 1;
    --photo-contrast: 0.9;
    --photo-brightness: 1.1;
    --photo-saturate: 1;
    --photo-sepia: 0;
    --photo-tint: var(--uoft-blue);
    --photo-tint-opacity: 0.35;
    --photo-tint-blend: color;
    --photo-hover-filter: none;          /* or the same filter, to keep the look on hover */
    --photo-hover-tint-opacity: 0;
}
.tile-img,
.person-profile .avatar { position: relative; overflow: hidden; }
.tile-img img,
.person-profile .avatar img {
    width: 100%; height: 100%;
    object-fit: cover;
    filter: grayscale(var(--photo-grayscale)) contrast(var(--photo-contrast)) brightness(var(--photo-brightness)) saturate(var(--photo-saturate)) sepia(var(--photo-sepia));
    transition: filter var(--transition-base);
}
.tile-img:has(img)::after,
.person-profile .avatar:has(img)::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--photo-tint);
    mix-blend-mode: var(--photo-tint-blend);
    opacity: var(--photo-tint-opacity);
    pointer-events: none;
    transition: opacity var(--transition-base);
}
.person-tile:hover .tile-img img,
.person-tile:focus-visible .tile-img img,
.person-profile:hover .avatar img { filter: var(--photo-hover-filter); }
.person-tile:hover .tile-img::after,
.person-tile:focus-visible .tile-img::after,
.person-profile:hover .avatar::after { opacity: var(--photo-hover-tint-opacity); }
.person-tile .person-name {
    line-height: 1.3;   /* name sits right on its role, as on the People page */
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-primary);
    text-align: center;
}
.person-tile .person-role {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    text-align: center;
}

/* ---- Profile variant (people.html): photo + tags + social links --------- */
.people-grid--profile {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--spacing-2xl);
}
.person-profile {
    position: relative;
    display: flex;
    gap: var(--spacing-lg);
    align-items: flex-start;
}
/* The name is the card's link; its ::after stretches over the whole card so
   the card is clickable, while the social icons sit above it. */
.pp-name::after { content: ""; position: absolute; inset: 0; }
.pp-name:focus-visible { outline: none; }
.person-profile:has(.pp-name:focus-visible) { outline: 2px solid var(--color-primary); outline-offset: 4px; }
/* Square image, matching the home-page people tiles (not a circle). */
.person-profile .avatar {
    width: 92px; height: 92px;
    flex-shrink: 0;
    border-radius: var(--radius);
    overflow: hidden;
    background-color: var(--blue-08);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-serif);
    font-size: var(--font-size-3xl);
    color: var(--blue-40);
}
.pp-body { min-width: 0; }
.pp-body > :last-child { margin-bottom: 0; }
.pp-name {
    display: block;
    width: fit-content;
    margin-top: -0.1875em;   /* cancel the line's leading so the name's ink starts level with the photo */
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    font-weight: 700;
    color: var(--color-primary);
    line-height: 1.3;
}
.pp-role {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    margin-bottom: var(--spacing-sm);
}
.pp-tags {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-sm);
}
.pp-social { position: relative; z-index: 1; display: flex; gap: var(--spacing-md); }
.pp-social a { display: inline-flex; color: var(--color-text-muted); }
.pp-social a:hover { color: var(--color-primary); }
.pp-social svg { width: 18px; height: 18px; }

/* -----------------------------------------------------------------------------
   10. Research / publication cards
   -------------------------------------------------------------------------- */
.work-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--spacing-lg);
}
/* Each publication is a bordered block, matching .link-card (Contact quick
   links, Join Us CTAs). The article stretches so cards in a row match height. */
.work-card { display: flex; }
.work-type {
    display: inline-block;
    font-family: var(--font-sans);
    font-size: var(--font-size-xs);
    font-weight: 700;
    color: var(--color-primary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--spacing-sm);
}
.work-card h3 {
    font-size: var(--font-size-lg);
    line-height: 1.35;
    margin-bottom: var(--spacing-xs);
}
/* Bordered link cards — publications here, the Join Us / Contact call-outs
   (.link-card) below. The whole card is one link: hover or focus lifts it
   and underlines its arrow. */
.work-card-link, .link-card {
    display: flex;
    flex-direction: column;
    padding: var(--spacing-lg);
    background-color: var(--color-background-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    color: inherit;
    transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.work-card-link { flex: 1; }
:is(.work-card-link, .link-card):is(:hover, :focus-visible) { border-color: var(--blue-40); transform: translateY(-2px); }
.work-card-link h3 { color: var(--color-text); transition: color 0.2s ease; }
.work-card-link:hover h3, .work-card-link:focus-visible h3 { color: var(--color-primary); }
.work-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-md);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-sm);
}
.work-meta .publication { font-weight: 700; color: var(--color-primary); }
.work-excerpt {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    margin-bottom: var(--spacing-sm);
    flex: 1;
}
/* "Read paper →", "Visit →", "Contact us →" */
.read-more, .link-arrow {
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-primary);
}
.read-more { display: inline-block; }
.work-card-link .read-more, .link-arrow { margin-top: var(--spacing-sm); }
.read-more:hover,
:is(.work-card-link, .link-card):is(:hover, :focus-visible) :is(.read-more, .link-arrow) { text-decoration: underline; }

/* -----------------------------------------------------------------------------
   11. Courses
   -------------------------------------------------------------------------- */
.course-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--spacing-md);
}
.course-card {
    display: grid;
    grid-template-columns: 130px 1fr auto;
    gap: var(--spacing-lg);
    align-items: baseline;
    padding: var(--spacing-lg) var(--spacing-xl);
    background-color: var(--color-background-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.course-card:hover {
    border-color: var(--blue-40);
    transform: translateY(-2px);
}
.course-code {
    font-family: var(--font-sans);
    font-weight: 700;
    color: var(--color-primary);
    letter-spacing: 0.03em;
}
.course-body h3 {
    font-size: var(--font-size-lg);
    margin-bottom: var(--spacing-xs);
}
.course-body p {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}
.course-term {
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* -----------------------------------------------------------------------------
   12. Open positions / Join us
   -------------------------------------------------------------------------- */
.positions-list {
    display: grid;
    gap: var(--spacing-lg);
}
.position-card {
    padding: var(--spacing-xl);
    background-color: var(--color-background-alt);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-primary);
    border-radius: var(--radius);
}
.position-card h3 { font-size: var(--font-size-xl); margin-bottom: var(--spacing-sm); }
.position-card .position-meta {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-md);
}
.position-card p { color: var(--color-text-light); }

/* -----------------------------------------------------------------------------
   13. Contact & forms
   -------------------------------------------------------------------------- */
/* Map — light, minimal basemap (Carto Positron) that stays in the background. */
.map-embed {
    position: relative;
    width: 100%;
    aspect-ratio: 24 / 9;
    margin-bottom: var(--spacing-2xl);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    background-color: var(--blue-08);
}
.map-embed #contact-map,
.map-embed iframe { width: 100%; height: 100%; border: 0; display: block; }
@media (max-width: 48em) { .map-embed { aspect-ratio: 4 / 3; } }
/* When the map sits below the details, move its spacing above it. */
.map-embed--below { margin-top: var(--spacing-2xl); margin-bottom: 0; }

/* Balanced contact details (3 columns, no form). */
.contact-details {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--spacing-2xl);
}
@media (max-width: 48em) { .contact-details { grid-template-columns: 1fr; gap: var(--spacing-lg); } }

/* Quick links to U of T offices. */
.links-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--spacing-lg);
}
/* Two-up (2x2) variant — used on the Join Us and Contact pages. */
.links-grid--2col { grid-template-columns: repeat(2, 1fr); }
.link-card { gap: var(--spacing-xs); }
.link-card h3 { font-size: var(--font-size-lg); margin-bottom: var(--spacing-xs); }
.link-card p { font-size: var(--font-size-sm); color: var(--color-text-light); flex: 1; }
@media (max-width: 48em) { .links-grid { grid-template-columns: 1fr; } }

/* Join Us — prose sections (DGP-style), each closing with one clear CTA. */
.join-prose { max-width: 70ch; }
.join-prose p {
    color: var(--color-text-light);
    margin-bottom: var(--spacing-md);
}
.join-prose ul {
    list-style: disc;
    padding-left: 1.4rem;
    color: var(--color-text-light);
    margin-bottom: var(--spacing-md);
}
.join-prose li { margin-bottom: var(--spacing-xs); }
.join-prose > :last-child { margin-bottom: 0; }
/* Each Join Us stage: heading across the top, prose on the left and the CTA
   card in a sticky right rail (2fr / 1fr, like "Where we are"). Below
   laptop width it stacks: heading, prose, CTA. */
@media (min-width: 64em) {
    .join-split {
        display: grid;
        grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
        grid-template-areas: "head head" "prose cta";
        column-gap: var(--spacing-4xl);
        align-items: start;
    }
    .join-split > .section-header { grid-area: head; }
    .join-split > .join-prose { grid-area: prose; max-width: none; }
    .join-split > .cta-single {
        grid-area: cta;
        margin-top: 0;
        max-width: none;
        position: sticky;
        top: calc(var(--header-h) + var(--spacing-xl));
    }
}

/* Applications notice inside the Join Us "Apply to graduate studies" card
   (filled from SITE_NOTICE): a badge styled like the announcement band's
   tag, beside the heading, and the deadline sentence appended to the card's
   description (date in bold). */
.notice-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.45rem;
    border: 1px solid var(--blue-55);
    border-radius: var(--radius);
    color: var(--color-primary);
    font-family: var(--font-sans);
    font-size: var(--font-size-xs);
    font-weight: 700;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    vertical-align: 0.15em;
    white-space: nowrap;
}
.link-card p strong { font-weight: 700; color: var(--color-text); }
.cta-single {
    display: grid;
    gap: var(--spacing-md);
    max-width: 520px;
    margin-top: var(--block-gap);
}

.contact-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-3xl);
}
.contact-info h3 { font-family: var(--font-sans); font-size: var(--font-size-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-primary); margin-bottom: var(--spacing-xs); }
/* Links in these paragraphs aren't underlined, so they're told apart by
   colour alone: text a shade lighter (#707484, 4.65:1 on white) and links a
   deeper U of T navy (#132548), 3.26:1 against the text (WCAG 1.4.1). */
.contact-info p { color: #707484; margin-bottom: var(--spacing-lg); }
.contact-info p a { color: #132548; }

.form-field { margin-bottom: var(--spacing-lg); }
.form-field label {
    display: block;
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-text);
    margin-bottom: var(--spacing-xs);
}
.form-field input,
.form-field textarea {
    width: 100%;
    padding: 0.7rem var(--spacing-md);
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    color: var(--color-text);
    background-color: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.form-field input:focus,
.form-field textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--blue-15);
}
.form-field textarea { resize: vertical; min-height: 140px; }

/* -----------------------------------------------------------------------------
   14. Newsletter & footer
   -------------------------------------------------------------------------- */
.newsletter {
    text-align: center;
    padding: var(--spacing-4xl) 0;
    border-top: 1px solid var(--color-border);
}
.newsletter h2 { font-size: var(--font-size-2xl); margin-bottom: var(--spacing-lg); }
.newsletter-form {
    display: flex;
    gap: var(--spacing-sm);
    max-width: 480px;
    margin: 0 auto;
}
.newsletter-form input[type="email"] {
    flex: 1;
    padding: 0.7rem var(--spacing-md);
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background-color: var(--color-white);
}
.newsletter-form input[type="email"]:focus { outline: none; border-color: var(--color-primary); }

/* "Where we are" — shared across index.html and about.html.
   Two columns: 2/3 intro text, 1/3 address + contact link. */
.where-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: var(--spacing-3xl);
    align-items: start;
}
.where-grid .where-text .section-description { margin-top: var(--spacing-md); font-size: var(--font-size-base); }
.where-aside h3 {
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-primary);
    margin-bottom: var(--spacing-xs);
}
.where-aside p { color: var(--color-text-light); }
.where-aside .where-contact { margin-top: var(--spacing-md); }
@media (max-width: 48em) {
    .where-grid { grid-template-columns: 1fr; gap: var(--spacing-xl); }
}

.site-footer {
    background-color: var(--color-background);
    border-top: 1px solid var(--color-border);
    padding: var(--spacing-2xl) 0;
    font-family: var(--font-sans);
    font-weight: 400;
}
/* Three-part footer: copyright (left) · version (middle) · credit (right) */
.footer-inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--spacing-md) var(--spacing-lg);
}
.footer-inner .copyright {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}
.footer-inner .credit {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    text-align: right;
    margin-left: auto;
}
.footer-inner .build-timestamp {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--font-size-xs);
    color: var(--blue-55);
    background-color: var(--blue-08);
    padding: 0.15rem 0.55rem;
    border-radius: var(--radius);
}

/* -----------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */
/* Swap to the narrower logo when the full wordmark + nav no longer fit. */
@media (max-width: 68.75em) {
    .logo--full { display: none; }
    .logo--simple { display: block; }
}
@media (max-width: 37.5em) {
    .logo { height: 50px; }
}

@media (max-width: 64em) {
    .feature-columns { grid-template-columns: 1fr; gap: var(--spacing-xl); }
    .work-grid { grid-template-columns: 1fr; }

    /* Below laptop size, the hero stacks (text first) so the graphic gets a
       full-width, short band — which the horizontal stack variant fills.
       The JS swaps the vertical stack for the horizontal one at this width. */
    .hero { min-height: 0; padding: var(--section-space) 0; }
    .hero .container { display: flex; flex-direction: column; }
    .hero-content { max-width: 100%; order: 1; }
    /* Graphic sits ABOVE the hero text on stacked layouts, and matches the
       container so it lines up with the section content. */
    .hero-graphic {
        position: relative;
        top: auto;
        order: -1;
        width: 100%;
        height: auto;
        margin: 0 auto var(--spacing-2xl);
        justify-content: center;
    }
    .hero-graphic svg { width: 100%; height: auto; }
}

@media (max-width: 48em) {
    /* Breathing room before and after the graphic, in the hero's paragraph rhythm. */
    .hero { padding: var(--spacing-lg) 0 var(--section-space); }
    .hero-graphic { margin-top: var(--spacing-md); margin-bottom: var(--spacing-lg); }
    /* Text runs a step smaller on phones (xs stays at 12px for legibility). */
    :root {
        --section-space:  3rem;
        --font-size-sm:   0.8125rem;
        --font-size-base: 0.9375rem;
        --font-size-lg:   1.0625rem;
        --font-size-xl:   1.125rem;
        --font-size-2xl:  1.375rem;
        --font-size-3xl:  1.6rem;
        --font-size-4xl:  2rem;
    }
    /* Narrower page margins on phones (about half the desktop-derived
       92vw + padding), so content gets more of the width. */
    :root { --container-padding: 1.125rem; }
    .container, .main-nav { max-width: 100%; }
    .nav-toggle { display: inline-flex; }
    .nav-list {
        position: absolute;
        top: 100%; left: 0; right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background-color: var(--color-background-alt);
        border-bottom: 1px solid var(--color-border);
        box-shadow: 0 8px 20px var(--blue-15);
        padding: var(--spacing-sm) 0;
        display: flex;
        /* Closed: clipped to nothing at its top edge and hidden from focus.
           Open: the clip opens downward (sides and bottom extend to keep the
           shadow), so the panel slides down from under the header, and the
           links drift down into place. visibility waits for the close to finish. */
        clip-path: inset(0 -24px 100% -24px);
        visibility: hidden;
        transition: clip-path 300ms cubic-bezier(0.2, 0.7, 0.2, 1), visibility 0s linear 300ms;
    }
    .nav-list.open {
        clip-path: inset(0 -24px -24px -24px);
        visibility: visible;
        transition: clip-path 300ms cubic-bezier(0.2, 0.7, 0.2, 1), visibility 0s;
    }
    .nav-list li {
        opacity: 0;
        transform: translateY(-8px);
        transition: opacity 200ms ease, transform 300ms cubic-bezier(0.2, 0.7, 0.2, 1);
    }
    .nav-list.open li { opacity: 1; transform: none; }
    /* The links must be block-level here: as inline <a>, their vertical padding
       and borders bled into neighbouring rows, which read as stray sand-coloured
       lines striking through the text. Block layout gives each its own row. */
    .nav-list li { width: 100%; }
    /* Same tint treatment as desktop, but on full-width rows: reset the
       desktop's negative margin and radius so the tint spans edge to edge. */
    .nav-list .nav-link {
        display: block;
        width: 100%;
        padding: var(--spacing-md) var(--container-padding);
        margin: 0;
        border-radius: 0;
    }
    .nav-list li + li .nav-link { border-top: 1px solid var(--color-border); }
    @media (prefers-reduced-motion: reduce) {
        .nav-list, .nav-list.open, .nav-list li { transition: none; }
    }

    /* Dropdown children are always visible in the mobile menu, as indented
       rows beneath their parent link. */

    .contact-grid { grid-template-columns: 1fr; gap: var(--spacing-xl); }
    .course-card { grid-template-columns: 1fr; gap: var(--spacing-xs); }
    .course-term { order: -1; }
    .footer-inner { flex-direction: column; align-items: flex-start; }
    .footer-inner .credit { text-align: left; margin-left: 0; }
    .newsletter-form { flex-direction: column; }
    /* Home tiles stay two-up; People profiles go single-column on mobile. */
    .people-grid--tile { --cols: 2; --gap: var(--spacing-xl); row-gap: var(--spacing-xl); }
    .people-grid--profile { grid-template-columns: 1fr; }
}

@media (max-width: 28.75em) {
    .feature-columns { grid-template-columns: 1fr; }
}

/* Respect reduced-motion preferences for the hero reveal & transitions */
@media (prefers-reduced-motion: reduce) {
    * { scroll-behavior: auto !important; }
}

/* ---- Phones: compact "Where we are" details and footer ---------------- */
@media (max-width: 48em) {
    /* One gap between detail blocks (not gap + paragraph margin). */
    .contact-info p:last-child { margin-bottom: 0; }
    /* Department and Email side by side. */
    .contact-info:has(h3 + p + h3) {
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: auto auto;
        grid-auto-flow: column;
        column-gap: var(--spacing-lg);
    }
    .contact-info:has(h3 + p + h3) p { margin-bottom: 0; }
    /* Taller touch areas for the standalone links, same look. */
    .contact-info:has(h3 + p + h3) p a { display: inline-block; padding: 10px 0; margin: -10px 0; }

    /* Footer: copyright left, credit right, on one row. */
    .site-footer { padding: var(--spacing-lg) 0 var(--spacing-xl); }
    .footer-inner { flex-direction: row; flex-wrap: nowrap; align-items: center; justify-content: space-between; gap: var(--spacing-md); }
    .footer-inner .copyright, .footer-inner .credit { font-size: var(--font-size-xs); }
    .footer-inner .credit { margin-left: auto; text-align: right; white-space: nowrap; }
}
/* site.js adds .is-short once the full copyright would wrap to two lines. */
.copyright.is-short .copyright-dept { display: none; }
