
:root {
    color-scheme: light dark;

    --page:      #f4efe9;   /* warm cream, as before */
    --surface:   #fffdfb;
    --text:      #2b2724;   /* 14.6:1 */
    --muted:     #6d645b;   /*  5.7:1 */
    --link:      #3f7a3a;   /*  5.1:1 -- was #5a9152 at 3.4:1 */
    --link-hover:#a4571d;   /*  5.2:1 -- was #e78a4e at 2.4:1 */
    --heading:   #b8443c;   /*  5.3:1 -- was #ea6962 at 2.9:1 */
    --accent:    #a4571d;
    --badge-bg:  #3f7a3a;
    --badge-fg:  #ffffff;   /*  5.2:1 on the badge */
    --rule:      #e6ded4;
    --rule-firm: #d6cabb;

    /* IBM Plex. A serif for headings reads as academic rather than playful --
       Rubik's rounded terminals were what made the page feel informal. Plex Mono
       on the venue badges makes acronyms line up character-for-character in the
       fixed-width column. */
    --ff-head: "IBM Plex Serif", Georgia, "Times New Roman", serif;
    --ff-body: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system,
               "Segoe UI", sans-serif;
    --ff-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

    --measure: 64rem;
    --radius: 14px;

    /* Every badge is this width, so all publication text starts on the same
       edge regardless of venue. Sized for the longest marker, "USENIX Sec":
       10 characters of IBM Plex Mono at 0.68rem (0.6em advance each) is 6.0em
       of text plus 1em of padding, leaving ~24% headroom. A longer venue name
       means raising this value -- never a clipped badge. */
    --badge-w: 5.75rem;
    --navbar-h: 3.5rem;
}

/* Dark values live in one place and are applied from two selectors: the system
   preference when the visitor has not chosen, and an explicit data-theme when
   they have. The :not() guard is what lets the toggle force light while the OS
   is dark -- without it the media query would keep winning. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --page:      #171615;
        --surface:   #201e1d;
        --text:      #ece5de;   /* 13.3:1 */
        --muted:     #a79c92;   /*  6.2:1 */
        --link:      #8fc47a;   /*  8.2:1 */
        --link-hover:#eda265;   /*  7.9:1 */
        --heading:   #f2938b;   /*  7.4:1 */
        --accent:    #eda265;
        --badge-bg:  #8fc47a;
        --badge-fg:  #16302a;   /*  6.9:1 on the badge */
        --rule:      #2f2b29;
        --rule-firm: #423c38;
    }
}

:root[data-theme="dark"] {
    --page:      #171615;
    --surface:   #201e1d;
    --text:      #ece5de;
    --muted:     #a79c92;
    --link:      #8fc47a;
    --link-hover:#eda265;
    --heading:   #f2938b;
    --accent:    #eda265;
    --badge-bg:  #8fc47a;
    --badge-fg:  #16302a;
    --rule:      #2f2b29;
    --rule-firm: #423c38;
}

*, *::before, *::after { box-sizing: border-box; }

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    /* Top padding clears the fixed bar. */
    padding: calc(var(--navbar-h) + clamp(1rem, 4vw, 2.5rem))
             clamp(0.75rem, 4vw, 2rem) clamp(1rem, 4vw, 3rem);
    background: var(--page);
    color: var(--text);
    font-family: var(--ff-body);
    font-size: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
    line-height: 1.65;
    -webkit-text-size-adjust: 100%;
}

.page {
    max-width: var(--measure);
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    gap: clamp(1rem, 2.5vw, 1.75rem);
}

/* ---------- fixed navigation bar ---------- */

.navbar {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 100;
    height: var(--navbar-h);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding-inline: clamp(0.75rem, 4vw, 2rem);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--rule);
}

/* backdrop-filter is not universal; fall back to a solid bar so text on it is
   never sitting on a semi-transparent background it cannot be read against. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .navbar { background: var(--surface); }
}

.navbar-inner {
    width: 100%;
    max-width: var(--measure);
    margin-inline: auto;
    display: flex;
    align-items: center;
    gap: clamp(0.5rem, 2vw, 1.5rem);
}

.brand {
    font-family: var(--ff-head);
    font-weight: 600;
    font-size: 1rem;
    color: var(--heading);
    border-bottom: 0;
    margin-right: auto;
    white-space: nowrap;
}

.brand:hover { color: var(--link-hover); }

.navlinks {
    display: flex;
    align-items: center;
    gap: clamp(0.65rem, 2vw, 1.4rem);
    min-width: 0;
}

.navlinks a {
    font-size: 0.9rem;
    color: var(--muted);
    border-bottom: 0;
    white-space: nowrap;
}

.navlinks a:hover { color: var(--link); }

/* The bar is identical on both pages, so mark which one you are on. */
.navlinks a[aria-current="page"] {
    color: var(--text);
    font-weight: 500;
    box-shadow: inset 0 -2px 0 var(--link);
}

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    flex: none;
    padding: 0;
    font-size: 0.95rem;
    color: var(--muted);
    background: transparent;
    border: 1px solid var(--rule-firm);
    border-radius: 999px;
    cursor: pointer;
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.theme-toggle:hover {
    color: var(--link);
    border-color: var(--link);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--link);
    outline-offset: 3px;
}

/* Show the icon for the theme the button switches *to*. */
.theme-toggle .icon-dark { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-dark { display: inline; }
:root[data-theme="dark"] .theme-toggle .icon-light { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .theme-toggle .icon-dark { display: inline; }
    :root:not([data-theme="light"]) .theme-toggle .icon-light { display: none; }
}

/* Anchor targets must clear the fixed bar. */
:target,
[id] {
    scroll-margin-top: calc(var(--navbar-h) + 0.75rem);
}

.card {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: clamp(1.25rem, 3.5vw, 2.5rem);
}

/* ---------- typography ---------- */

h1, h2 {
    font-family: var(--ff-head);
    color: var(--heading);
    font-weight: 600;
    line-height: 1.2;
    text-wrap: balance;
}

h1 {
    font-size: clamp(1.9rem, 1.5rem + 1.8vw, 2.6rem);
    margin: 0;
    /* Serifs need less negative tracking than the geometric sans did. */
    letter-spacing: -0.008em;
}

h2 {
    font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.55rem);
    margin: 0 0 0.35em;
}

/* Sans, not serif: this is a short metadata line, and a serif at this size
   next to a serif h1 muddles the hierarchy. */
.role {
    font-family: var(--ff-body);
    font-size: 1.0625rem;
    font-weight: 500;
    color: var(--accent);
    margin: 0.35rem 0 1.1rem;
}

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

em {
    font-style: italic;
    color: var(--text);
}

a {
    color: var(--link);
    text-decoration: none;
    font-weight: 500;
    border-bottom: 1px solid color-mix(in srgb, var(--link) 35%, transparent);
    transition: color 0.2s ease, border-color 0.2s ease;
}

a:hover {
    color: var(--link-hover);
    border-bottom-color: color-mix(in srgb, var(--link-hover) 55%, transparent);
}

a:focus-visible {
    outline: 2px solid var(--link);
    outline-offset: 3px;
    border-radius: 3px;
}

/* ---------- header ---------- */

.intro {
    display: grid;
    grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
    gap: clamp(1.25rem, 3.5vw, 2.5rem);
    align-items: start;
}

.portrait { text-align: center; }

.portrait img {
    width: 100%;
    height: auto;
    border-radius: 12px;
    display: block;
}

.contact {
    margin: 0.85rem 0 0.6rem;
    font-size: 0.9rem;
    color: var(--accent);
    font-weight: 500;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

.social {
    display: flex;
    justify-content: center;
    gap: 1rem;
}

.social a {
    color: var(--link);
    border-bottom: 0;
    font-size: 1.35rem;
    line-height: 1;
}

.social a:hover { color: var(--link-hover); }

/* ---------- publications ---------- */

.lead {
    color: var(--muted);
    font-size: 0.95rem;
    margin-bottom: 1.4rem;
}

.pubs {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 1.15rem;
}

/* One fixed track for every badge, so each publication body starts at the same
   x and nothing is indented differently from its neighbours. The width is a
   variable rather than a magic number: it is set to fit the longest marker, so
   a longer venue name only means bumping --badge-w, never clipped text. */
.pubs li {
    display: grid;
    grid-template-columns: var(--badge-w) minmax(0, 1fr);
    gap: 0 1rem;
    align-items: start;
}

.pubs li::before {
    content: attr(data-marker);
    width: 100%;
    box-sizing: border-box;
    text-align: center;
    /* Monospace so ISPASS / MICRO / USENIX Sec share a common rhythm. */
    font-family: var(--ff-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--badge-fg);
    background: var(--badge-bg);
    padding: 0.42em 0.5em;
    border-radius: 999px;
    margin-top: 0.3em;
}

.pub-body { min-width: 0; }

.pub-body a { overflow-wrap: anywhere; }

.pub-sep {
    border: 0;
    border-top: 1px solid var(--rule-firm);
    margin: 0.5rem 0;
}

/* ---------- publications page ---------- */

.page-title {
    font-family: var(--ff-head);
    color: var(--heading);
    font-size: clamp(1.9rem, 1.5rem + 1.8vw, 2.6rem);
    font-weight: 600;
    letter-spacing: -0.008em;
    margin: 0 0 0.25rem;
}

/* Jump links per year. These used to live in the nav bar; the bar is now
   identical across pages, so they sit with the content they navigate. */
.yearnav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
}

.yearnav a {
    font-family: var(--ff-mono);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--muted);
    border: 1px solid var(--rule-firm);
    border-bottom: 1px solid var(--rule-firm);
    border-radius: 999px;
    padding: 0.3em 0.85em;
    transition: color 0.2s ease, border-color 0.2s ease;
}

.yearnav a:hover {
    color: var(--link);
    border-color: var(--link);
}

.year {
    font-family: var(--ff-head);
    color: var(--heading);
    font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem);
    font-weight: 600;
    margin: 0 0 1.1rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--rule-firm);
}

.pub-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 1.6rem;
}

.pub-list > li {
    padding-left: 1rem;
    border-left: 2px solid var(--rule);
    transition: border-color 0.2s ease;
}

.pub-list > li:hover { border-left-color: var(--link); }

/* The venue statement is wrapped in <i> in every entry. */
.pub-list i { color: var(--muted); }

/* Award lines are hard-coded <font color="red">, which is unreadable on the
   dark surface. Route them through the contrast-checked heading colour. */
.pub-list font[color="red"],
.pub-list font { color: var(--heading) !important; }

.backlink {
    text-align: center;
    padding-top: 0.5rem;
}

/* ---------- talks ---------- */

.talks {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1rem;
}

.talks iframe {
    width: 100%;
    aspect-ratio: 16 / 9;
    height: auto;
    border: 0;
    border-radius: 10px;
    display: block;
    background: var(--rule);
}

/* ---------- footer ---------- */

.updated {
    text-align: right;
    color: var(--muted);
    font-size: 0.875rem;
    padding: 0.25rem clamp(1.25rem, 3.5vw, 2.5rem);
}

/* ---------- narrow screens ---------- */

@media (max-width: 640px) {
    .intro {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        text-align: left;
    }
    .portrait {
        width: min(200px, 60%);
    }
    .pubs li {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.45rem 0;
    }
    .pubs li::before {
        justify-self: start;
        margin-top: 0;
    }
}

@media (max-width: 460px) {
    .brand { font-size: 0.9rem; }
    .navlinks a { font-size: 0.82rem; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { transition: none !important; }
}
