    :root { --bg: #fafafa; --fg: #111111; --muted: #5c5c5c; --accent: #2f6f4f; --rule: #dddddd; --font: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", Menlo, Consolas, monospace; --content-w: 34rem; --index-w: 2.75rem; --gutter: clamp(1.25rem, 4vw, 1.75rem); --section-gap: clamp(2.5rem, 6vw, 3.5rem); }
    @media (prefers-color-scheme: dark) { :root { --bg: #0a0a0a; --fg: #eeeeee; --muted: #9a9a9a; --accent: #4fae82; --rule: #262626; } }
    h1, h2 { font-family: var(--font); font-weight: 700; margin: 0; }
    p { margin: 0 0 1em 0; }
    p:last-child { margin-bottom: 0; }
    .wrap { max-width: calc(var(--index-w) + var(--content-w) + 1.25rem); margin: 0 auto; padding: 0 var(--gutter); }
    .topbar-controls { display: flex; align-items: baseline; gap: 1rem; }
    /* Now an <a>, so it needs the link styles undone: no underline, and
       underline colour that does not reappear on hover. font-size and
       font-family still have to be set explicitly — a <button> does not
       inherit them, but an <a> does, so without these it rendered at the
       body's 16px instead of matching the toggle beside it. */
    .print-link { font-family: var(--font); font-size: 0.85rem; color: var(--muted); text-decoration: none; text-decoration-color: transparent; }
    .print-link:hover, .print-link:focus-visible { color: var(--accent); text-decoration-color: transparent; }
    .print-link:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; }
    main { padding: 2rem 0 5rem; }
    section { display: grid; grid-template-columns: var(--index-w) 1fr; gap: 1.25rem; align-items: start; padding: var(--section-gap) 0; border-top: 1px solid var(--rule); }
    section:first-child { border-top: none; padding-top: 0.5rem; }
    /* Motion.
       Opacity and transform only: neither triggers layout, so the cascade
       costs no reflow. It adds no network request either — this is inside a
       stylesheet the page already downloads. Scoped to
       prefers-reduced-motion: no-preference, so a reader who has asked for
       less motion gets none of it, and print.css clears what remains. */

    @keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: no-preference) { body { transition: background-color 200ms ease, color 200ms ease; } }
    /* Everything below the fold fades in. The hero is excluded on purpose:
       it is above the fold and holds the Largest Contentful Paint element,
       and a fade would start it at opacity 0. LCP only counts a paint with
       visible pixels, so animating it added the full duration to every load's
       LCP for no visual gain worth having. */
    @media (prefers-reduced-motion: no-preference) { main > section:not(.hero) { animation: rise 350ms ease-out; } }
    @media (prefers-reduced-motion: no-preference) { main > section:nth-of-type(2) { animation-delay: 55ms; } }
    @media (prefers-reduced-motion: no-preference) { main > section:nth-of-type(3) { animation-delay: 110ms; } }
    @media (prefers-reduced-motion: no-preference) { main > section:nth-of-type(4) { animation-delay: 165ms; } }
    @media (prefers-reduced-motion: no-preference) { main > section:nth-of-type(5) { animation-delay: 220ms; } }
    .num { font-weight: 600; color: var(--muted); padding-top: 0.2rem; }
    h2 { font-size: 1rem; margin: 0 0 1.25rem; }
    @media (max-width: 560px) { section { grid-template-columns: 1fr; gap: 0.4rem; } }
    @media (max-width: 560px) { .num { padding-top: 0; } }
    /* hero */

    .hero h1 { font-size: clamp(1.6rem, 4.5vw, 2.1rem); line-height: 1.25; margin: 0 0 0.75rem; }
    .hero .tagline { color: var(--muted); max-width: 30rem; }
    /* about */

    .about-body p { color: var(--fg); }
    /* experience */

    .job-list { list-style: none; padding: 0; margin: 0; }
    .job { padding: 1.25rem 0; }
    .job:first-child { padding-top: 0; }
    .job + .job { border-top: 1px solid var(--rule); }
    .row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
    .role { font-weight: 700; color: var(--fg); }
    .period { font-size: 0.85rem; color: var(--muted); white-space: nowrap; }
    .titles { list-style: none; padding: 0 0 0 1rem; margin: 0.75rem 0 0; border-left: 1px solid var(--rule); }
    .titles li { margin-bottom: 0.75rem; }
    .titles li:last-child { margin-bottom: 0; }
    .title-row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
    .title-role { font-weight: 600; color: var(--fg); font-size: 0.95rem; }
    .title-period { font-size: 0.8rem; color: var(--muted); white-space: nowrap; }
    .title-department { font-size: 0.85rem; color: var(--muted); margin-top: 0.1rem; }
    .title-notes { list-style: none; margin: 0.35rem 0 0; padding: 0; font-size: 0.88rem; color: var(--muted); }
    .title-notes li { padding-left: 1em; text-indent: -1em; }
    .title-notes li::before { content: '- '; }
    .title-notes li + li { margin-top: 0.15rem; }
    /* skills */

    .skills-list { list-style: none; padding: 0; margin: 0; }
    .skill { margin-bottom: 0.85rem; }
    .skill:last-child { margin-bottom: 0; }
    .skill-category { display: block; font-weight: 600; color: var(--fg); font-size: 0.95rem; margin-bottom: 0.2rem; }
    .skill-items { display: block; color: var(--muted); font-size: 0.92rem; }
    .inline-link { color: inherit; }
    /* contact */

    .links { list-style: none; padding: 0; margin: 0; }
    .links li { margin-bottom: 0.5rem; }
    .links li:last-child { margin-bottom: 0; }
    .links a { display: inline-flex; align-items: baseline; gap: 0.75em; text-decoration: none; }
    .key { color: var(--muted); min-width: 5.5em; }
    .value { text-decoration: underline; text-decoration-color: var(--rule); text-underline-offset: 0.25em; }
    .links a:hover .value, .links a:focus-visible .value { color: var(--accent); text-decoration-color: var(--accent); }
  
