/* deeprochoudhury.github.io: the Monograph design (FINAL_SPEC.md).
   One serif (Newsreader), warm paper, one accent. Variants come from three
   attributes on <html>, set from site.yml: data-cover (paper|band),
   data-accent (oxblood|green), data-hero-figure (false|true).
   Sections: 1 fonts, 2 tokens, 3 base, 4 grid, 5 header, 6 hero and link
   rows, 7 sections and Research, 8 publications, 9 rows (news, projects, CV)
   and the two-column lower page, 10 contact and footer, 11 band variants,
   12 interaction, touch and small screens, 13 print. */

/* 1. Fonts: @fontsource/newsreader 5.3.0, unmodified woff2 (SIL OFL 1.1). */
@font-face{font-family:"Newsreader";font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/newsreader-latin-400-normal.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Newsreader";font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/newsreader-latin-ext-400-normal.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Newsreader";font-style:normal;font-weight:600;font-display:swap;
  src:url(../fonts/newsreader-latin-600-normal.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Newsreader";font-style:italic;font-weight:400;font-display:swap;
  src:url(../fonts/newsreader-latin-400-italic.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* Metric-matched fallback: Times New Roman scaled to Newsreader's mean advance
   over about.md, with Newsreader's typo ascent/descent (0.735/0.265 em, no gap). */
@font-face{font-family:"Newsreader Fallback";font-style:normal;font-weight:400;
  src:local("Times New Roman"),local("TimesNewRomanPSMT");
  size-adjust:105.48%;ascent-override:69.68%;descent-override:25.12%;line-gap-override:0%}
@font-face{font-family:"Newsreader Fallback";font-style:normal;font-weight:600;
  src:local("Times New Roman Bold"),local("TimesNewRomanPS-BoldMT");
  size-adjust:103.96%;ascent-override:70.70%;descent-override:25.49%;line-gap-override:0%}
@font-face{font-family:"Newsreader Fallback";font-style:italic;font-weight:400;
  src:local("Times New Roman Italic"),local("TimesNewRomanPS-ItalicMT");
  size-adjust:98.99%;ascent-override:74.25%;descent-override:26.77%;line-gap-override:0%}

/* 2. Tokens. Light is the default. Every dark or accent override is scoped to
   @media screen, so print never has to beat it. The 20Q figure reads the same
   names (--bg --surface --text --muted --accent --line). */
:root{
  color-scheme:light dark;
  --bg:#f8f5ef;--surface:#f0eadf;--text:#1e1b16;--muted:#5e584f;--line:#d8d0c2;
  --accent:#8b2a1d;--me-wash:transparent;
  --plate-line:var(--line);--plate-filter:none;
  --serif:"Newsreader","Newsreader Fallback",Georgia,serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --fs:clamp(1.1875rem,1.1rem + .25vw,1.25rem);
  --tw:calc(var(--fs) * 29);          /* the text measure, 29em of body text */
  --pad:clamp(20px,5vw,48px);
  --mt:15rem;                         /* the margin track (wider in P3) */
  --cols:[all-start gut-start text-start wide-start] minmax(0,var(--tw)) [gut-end text-end wide-end all-end];
  --pw:var(--tw);                     /* page width, for the two-column lower grids */
  --bq-font:var(--serif);--bq-num-font:var(--serif);--bq-size:15px;--bq-radius:3px;
  --bq-surface:color-mix(in srgb,var(--surface) 60%,var(--bg));
}
/* Band tokens (P2, P3): the same forest in both schemes (screen only, like
   every other override, so print's black-on-white always wins). */
@media screen{
  :root[data-cover="band"]{--band:#12302a;--band-surface:#183a33;--band-text:#f3eee2;--band-muted:#b7c3b6;
    --band-accent:#8fd98f;--band-line:#2d4d45;--band-edge:#12302a}
  :root[data-accent="green"]{--accent:#1c731c;--me-wash:#e3f0e1}
  :root[data-theme="light"]{color-scheme:light}
}
@media screen and (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){color-scheme:dark;
    --bg:#161412;--surface:#201d19;--text:#ebe5da;--muted:#a69f93;--line:#3a352e;--accent:#e8a08e;
    --plate-line:color-mix(in srgb,var(--muted) 40%,transparent);--plate-filter:brightness(.9)}
  :root[data-accent="green"]:not([data-theme="light"]){--accent:#7ccf7c;--me-wash:#1c3322}
  :root[data-cover="band"]:not([data-theme="light"]){--band-text:#ece8dc;--band-muted:#aebaae;--band-edge:#3a352e}
}
@media screen{
  :root[data-theme="dark"]{color-scheme:dark;
    --bg:#161412;--surface:#201d19;--text:#ebe5da;--muted:#a69f93;--line:#3a352e;--accent:#e8a08e;
    --plate-line:color-mix(in srgb,var(--muted) 40%,transparent);--plate-filter:brightness(.9)}
  :root[data-theme="dark"][data-accent="green"]{--accent:#7ccf7c;--me-wash:#1c3322}
  :root[data-theme="dark"][data-cover="band"]{--band-text:#ece8dc;--band-muted:#aebaae;--band-edge:#3a352e}
}

/* 3. Base. */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;background:var(--bg);scroll-padding-top:16px}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--serif);font-size:var(--fs);
  line-height:1.5;font-weight:400;font-synthesis:none;font-kerning:normal;font-variant-numeric:tabular-nums;
  text-rendering:optimizeLegibility;hyphens:manual}
h1,h2,h3{margin:0;font-weight:600;text-wrap:balance}
p{margin:0;text-wrap:pretty}
ul,ol,dl,dd,figure{margin:0;padding:0}
ul{list-style:none}
b,strong{font-weight:600}
i,em{font-style:italic}
.nw{white-space:nowrap}
a{color:var(--text);text-decoration:underline 1px var(--muted);text-underline-offset:.2em;text-decoration-skip-ink:auto}
button{font:inherit;color:inherit;letter-spacing:inherit}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:1px}
main:focus{outline:none}
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.skip{position:absolute;left:var(--pad);top:8px;z-index:9;display:inline-flex;align-items:center;min-height:44px;
  padding:8px 12px;background:var(--surface);color:var(--text);transform:translateY(-200%)}
[data-cover="band"] .skip:focus-visible{outline-color:var(--band-accent)}
.skip:focus{transform:none}
::selection{background:color-mix(in srgb,var(--accent) 22%,var(--bg))}

/* 4. Grid. One column below 64rem; a 7rem date gutter from 64rem; the margin
   column from 75rem. Rows repeat the page template, so gutter, text and
   margin line up across sections. */
.g{display:grid;grid-template-columns:var(--cols);justify-content:center;padding-inline:var(--pad)}
.c-text{grid-column:text}
.c-wide{grid-column:wide}
.g>.sh,.g>.rows,.g>.row,.g>.more,.g>.cvb{grid-column:all}
.row>.gut,.row>.txt{display:block}
.gut{font-size:.8em;line-height:1.45;color:var(--muted)}
@media (min-width:64rem){
  :root{--cols:[all-start gut-start] 7rem [gut-end text-start wide-start] var(--tw) [text-end] minmax(0,8rem) [wide-end all-end];
    --pw:calc(15rem + var(--tw))}
  .row{display:grid;grid-template-columns:var(--cols);align-items:baseline}
  .row>.gut{grid-column:gut;padding-right:1rem}
  .row>.txt{grid-column:text;min-width:0}
}
@media (min-width:75rem){
  :root{--cols:[all-start gut-start] 7rem [gut-end text-start wide-start] var(--tw) [text-end] 3rem [mar-start] var(--mt) [mar-end wide-end all-end];
    --pw:calc(10rem + var(--tw) + 15rem)}
  :root[data-hero-figure="true"]{--mt:minmax(15rem,25.75rem);--pw:72rem}
}

/* 5. Header. Four section links (gaps only) and the fixed-width text toggle.
   Nothing is fixed or sticky. */
.site{padding-top:28px}
.bar{grid-column:wide;display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;
  gap:.35rem 1.5rem;font-size:.8em;line-height:1.4}
.bar ul{display:flex;flex-wrap:wrap;column-gap:1.1em}
.bar a{text-decoration:none}
.tt{display:inline-flex;align-items:center;gap:.4em;padding:0;border:0;background:none;cursor:pointer;color:var(--text)}
.tt::before{content:"";flex:none;width:.7em;height:.7em;border:1.5px solid currentColor;border-radius:50%;
  background:linear-gradient(90deg,currentColor 50%,transparent 50%)}
.tt-lab{display:inline-grid}
.tt-lab>span{grid-area:1/1}
.tt-l{visibility:hidden}
:root[data-theme="dark"] .tt-d{visibility:hidden}
:root[data-theme="dark"] .tt-l{visibility:visible}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .tt-d{visibility:hidden}
  :root:not([data-theme="light"]) .tt-l{visibility:visible}
}
html:not(.js) .tt{visibility:hidden}

/* 6. Hero: the sentence, three one-fact lines, the link row. */
.hero{padding-top:40px}
.hero h1{grid-column:wide;max-width:20em;font-size:clamp(1.75rem,1.2rem + 1.6vw,2.25rem);line-height:1.2;
  font-weight:400;letter-spacing:-.01em}
.hero h1 .me{font-weight:600}
.lead{grid-column:wide;max-width:28em;margin-top:14px;font-size:clamp(1.125rem,1.05rem + .35vw,1.3rem);line-height:1.45;text-wrap:pretty}
.facts{grid-column:wide;max-width:36em;margin-top:18px;line-height:1.45}
.fact{text-wrap:pretty}
.fact+.fact{margin-top:.35em}
.hero .links{grid-column:wide;margin-top:20px}

/* Link rows: plain words separated by gaps, never dots. The email control
   is a button that reads like the links beside it; without JS it is hidden. */
.links{display:flex;flex-wrap:wrap;align-items:baseline;gap:.15em 1.1em;font-size:.9em;line-height:1.5}
.email{padding:0;border:0;background:none;cursor:pointer;text-align:left;color:var(--text);
  text-decoration:underline 1px var(--muted);text-underline-offset:.2em}
html:not(.js) .em{display:none}
.est{margin-left:.6em;font-size:.85em;color:var(--muted)}
.est:empty{display:none}

.contact>noscript{grid-column:text}
.nojs{grid-column:text;margin-top:10px;font-size:.8em;line-height:1.45;color:var(--muted)}

/* Meta-line separators: <span class="sep">&nbsp;</span>. The dot is drawn
   before the no-break space, after another one, so it is glued to both
   neighbours. Under a coarse pointer or below 40rem the dot goes and a plain,
   breakable gap (a generated space) takes its place. */
.sep::before{content:"\a0·";content:"\a0·"/"";color:var(--muted)}
@media (pointer:coarse),(max-width:39.99rem){
  .sep{padding-left:.3em}
  .sep::before{content:none}
  .sep::after{content:" ";content:" "/""}
}

/* 7. Sections: a hairline, then the accent numeral hanging in the gutter
   (inline before the heading where there is no gutter). Contact has none. */
.sec{margin-top:56px}
.sh{display:flex;align-items:baseline;gap:.55em;margin-bottom:22px;padding-top:24px;border-top:1px solid var(--line)}
.sh h2{font-size:1.2em;line-height:1.25}
.num{font-size:.8em;font-weight:600;color:var(--accent)}
@media (min-width:64rem){
  #research>.sh,#publications>.sh,.contact>.sh{display:grid;grid-template-columns:var(--cols);gap:0}
  #research>.sh .num,#publications>.sh .num{grid-column:gut}
  #research>.sh h2,#publications>.sh h2,.contact>.sh h2{grid-column:text}
}
.prose{min-width:0}
.prose p+p{margin-top:.75em}
.prose+.prose{margin-top:.75em}
.fig1{margin:20px 0 28px}
.fig1 .bq-lab{font-weight:400;font-style:italic}

/* Source notes. Below 75rem, and under a coarse pointer at any width, a
   note reads inline as a parenthesis. From 75rem it moves to the margin,
   level with the line that calls it, with an accent numeral on the claim
   and on the note (absolute position at the static position: no floats). */
.nref,.sn-n{display:none}
.sn{font-size:.8em;line-height:1.45;color:var(--muted)}
.sn::before{content:" (";content:" ("/""}
.sn::after{content:")";content:")"/""}
@media (min-width:75rem) and (not (pointer:coarse)){
  .nref{display:inline;margin-left:.06em;font-size:.62em;line-height:0;vertical-align:.62em;font-weight:600;color:var(--accent)}
  .prose{position:relative}
  .sn{position:absolute;left:calc(100% + 3rem);width:15rem;margin-top:.28em;text-wrap:pretty}
  .sn::before,.sn::after{content:none}
  .sn-n{display:inline;margin-right:.3em;font-weight:600;color:var(--accent)}
}

/* 8. Publications. One list, newest first. Gutter: year (+ "Featured").
   Card: kicker, title, authors, TL;DR, highlight, links, disclosures. The
   flagship's card is a surface panel whose text stays on the column. */
.g>.pub{grid-column:all}
.pub+.pub{margin-top:28px}
.pub>.gut{display:none}
.card{min-width:0}
.kick{margin-bottom:6px;font-size:13px;line-height:1.3;font-weight:600;color:var(--muted)}
.kl{text-transform:uppercase;letter-spacing:.08em}
.kf .ki{color:var(--accent);font-style:italic;font-weight:400}
.pub h3{font-size:1em;line-height:1.35}
.au{margin-top:4px;font-size:.8em;line-height:1.45;color:var(--muted)}
.an{white-space:nowrap}
.eq{display:block;margin-top:1px}
.au .me{font-weight:600;color:var(--text);background:var(--me-wash);border-radius:2px;box-shadow:0 0 0 .12em var(--me-wash)}
.tldr{margin-top:8px;max-width:30.5em;font-size:.9em;line-height:1.5}
.hl{margin-top:6px;max-width:30.5em;font-size:.9em;line-height:1.5}
.hl strong{color:var(--accent)}
.hl-src{color:var(--muted)}
.plinks,.xl{display:flex;flex-wrap:wrap;column-gap:1.1em;font-size:.8em;line-height:1.5}
.plinks{margin-top:10px}
.feat>.card{margin-inline:-20px;padding:20px;background:var(--surface);border-radius:3px}
.plate{display:none}
.allbib{margin-top:28px;font-size:.8em;line-height:1.45}
@media (min-width:64rem){
  .pub>.gut{display:block;padding-right:1.5rem}
  .pub>.card{grid-column:text}
  .kf{display:none}
  .yr{display:block;font-weight:600;color:var(--text)}
  .flag{display:block;margin-top:1px;font-style:italic;color:var(--accent)}
  .feat>.gut{padding-right:calc(20px + 1rem)}
}
@media (min-width:75rem){
  /* Card grid: text | gap | margin. A secondary paper's links stand in the
     margin as a column; the flagship's margin (gap + margin) holds the plate.
     The open Abstract/BibTeX panel spans text + gap + margin, below both. */
  .pub>.card{grid-column:text-start/mar-end;display:grid;align-items:start;
    grid-template-columns:[t-start] var(--tw) [t-end] 3rem [m-start] minmax(0,1fr) [m-end]}
  .card>.txt{grid-column:t;grid-row:1}
  .card>.plinks{grid-column:m;grid-row:1;flex-direction:column;align-items:flex-start;margin-top:0;
    padding-top:calc(13px * 1.3 + 6px)}
  .card>.disc{grid-column:t-start/m-end;grid-row:2}
  .feat>.card{margin-right:0}
  .feat>.card>.txt{padding-right:1.25rem}
  .feat>.card>.plinks{grid-column:t;grid-row:2;flex-direction:row;padding-top:0;margin-top:10px}
  .feat>.card>.plate{display:block;grid-column:t-end/m-end;grid-row:1/span 2}
  .feat>.card>.disc{grid-row:3}
}
.plate img{display:block;width:100%;height:auto;aspect-ratio:16/10;padding:6px;background:#fff;
  border:1px solid var(--plate-line);border-radius:3px;filter:var(--plate-filter)}
.plate figcaption{margin-top:8px;font-size:.7em;line-height:1.4;font-style:italic;color:var(--muted);text-wrap:pretty}

/* Abstract and BibTeX: two exclusive <details>. With ::details-content the
   two summaries share one row and the open panel spans below them; without
   it they stack. A closed panel keeps a box in the grid cell, so it is kept
   out of hit-testing (the click-swallowing bug). */
.disc{margin-top:8px;font-size:.8em;line-height:1.5}
.disc summary,.more>summary{display:inline-flex;align-items:center;gap:.45em;min-height:1.9em;cursor:pointer;list-style:none;color:var(--text)}
.disc summary::-webkit-details-marker,.more>summary::-webkit-details-marker{display:none}
.disc summary::after,.more>summary::after{content:"";width:.42em;height:.42em;margin-top:-.1em;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg)}
.disc details[open]>summary::after,.more[open]>summary::after{transform:rotate(45deg);margin-top:-.3em}
@supports selector(::details-content){
  .disc{display:grid;grid-template-columns:auto auto minmax(0,1fr);column-gap:1.5em}
  .disc details{display:contents}
  .disc summary{grid-row:1}
  .disc details::details-content{grid-column:1/-1;grid-row:2;align-self:start;min-width:0}
  .disc details+details::details-content{grid-row:3}
  .disc details:not([open])::details-content{pointer-events:none;visibility:hidden}
}
.panel{margin-top:8px;padding:14px 16px;background:var(--surface);border-radius:3px;overflow-wrap:break-word}
.feat .panel{background:var(--bg)}
.abs{font-size:1.125em;line-height:1.5}
.abs>p,.pnote{max-width:30em}
.abs p+p,.pnote{margin-top:.6em}
.pnote{color:var(--muted);font-size:.9em}
.tools{display:flex;flex-wrap:wrap;align-items:center;gap:.5em .75em}
.copy{padding:4px 12px;border:1px solid var(--muted);border-radius:3px;background:none;cursor:pointer;color:var(--text);line-height:1.4}
.st{color:var(--muted)}
.cite{margin:10px 0;overflow-wrap:anywhere}
.cite .lab{font-weight:600}
.bib pre{margin:0;overflow-x:auto;white-space:pre;font-family:var(--mono);font-size:13px;line-height:1.5;tab-size:2;color:var(--text)}

/* 9. Rows: news, projects and the CV share the gutter grammar. */
.rows>li+li{margin-top:14px}
.nrow>.txt{font-size:.8em;line-height:1.45;color:var(--muted)}
.row>.gut time{white-space:nowrap}
.more{margin-top:14px}
.more>summary{font-size:.8em;line-height:1.45}
.more[open]>summary{margin-bottom:12px}
.prow+.prow{margin-top:20px}
.prow h3{font-size:1em;line-height:1.35}
.gloss{margin-top:2px;max-width:31em;font-size:.8em;line-height:1.45;font-style:italic;color:var(--muted)}
.award{margin-top:4px;font-size:.8em;line-height:1.45}
.meta{margin-top:4px;font-size:.8em;line-height:1.45;color:var(--muted)}
.txt>.xl{margin-top:4px}
.files{margin-top:2px}
.files>summary{font-size:.8em}
.files[open]>summary{margin-bottom:2px}
.files .xl{font-size:.8em}
.sub{margin:30px 0 12px;font-size:13px;line-height:1.3;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.cv-edu>.sub{margin-top:0}
.crow+.crow{margin-top:16px}
.hd{font-weight:600;line-height:1.35}
.at{font-size:.8em;line-height:1.45}
.gl{margin-top:1px;max-width:31em;font-size:.8em;line-height:1.45;color:var(--muted)}
.honours{font-size:.8em;line-height:1.45;color:var(--muted)}
.honours li+li{margin-top:8px}
.hn{font-weight:600;color:var(--text)}
.ay{white-space:nowrap}
#news .cv-talks .hd{font-size:.8em;line-height:1.45}
#news .cv-talks .at{margin-top:1px}

/* The lower page from 64rem: News beside Projects, and the CV as Education
   + Honours beside Experience + Talks. The sections and blocks stay in source
   order; grid-column/grid-row place them. From 75rem each column keeps its
   own date gutter (7rem on the left, on the page gutter; 5.5rem on the
   right). From 64 to 75rem the gutters drop: News keeps a narrow one, and
   Projects and CV rows carry their date at the end of the head line. */
@media (min-width:64rem){
  .duo,.cv{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:3rem;align-items:start;
    max-width:calc(var(--pw) + 2 * var(--pad));margin-inline:auto;padding-inline:var(--pad)}
  .duo{margin-top:56px}
  .duo>.sec{margin-top:0;padding-inline:0;justify-content:stretch}
  #news{--gw:5.5rem;--cols:[all-start gut-start] var(--gw) [gut-end text-start wide-start] minmax(0,1fr) [text-end wide-end all-end]}
  #projects,.cvb{--gw:0px;--cols:[all-start gut-start text-start wide-start] minmax(0,1fr) [gut-end text-end wide-end all-end]}
  #news .more>summary{margin-left:var(--gw)}
  .cv>.sh{grid-column:1/-1}
  .cv>.cv-edu{grid-column:1;grid-row:2}
  .cv>.cv-exp{grid-column:2;grid-row:2/span 2}
  .cv>.cv-hon{grid-column:1;grid-row:3}
  .cv>.cv-talks{grid-column:2;grid-row:4}
  /* Honours spans two rows only when Talks is in the CV: two spanning items
     sharing a row make the grid overgrow that row. */
  .cv:has(>.cv-talks)>.cv-hon{grid-row:3/span 2}
  .cv>.cv-exp>.sub{margin-top:0}
  #news>.cvb{--gw:5.5rem;--cols:[all-start gut-start] var(--gw) [gut-end text-start wide-start] minmax(0,1fr) [text-end wide-end all-end]}
  .cvb>.sub,.cvb>.honours,.cvb>.more{margin-left:var(--gw)}
}
@media (min-width:75rem){
  #news,#news>.cvb,.cv-edu,.cv-hon{--gw:7rem}
  #projects,.cv-exp,.cv-talks{--gw:6.75rem}
  .cv .gut time{display:block}
  #news,#projects,.cvb{--cols:[all-start gut-start] var(--gw) [gut-end text-start wide-start] minmax(0,1fr) [text-end wide-end all-end]}
  .duo .sh,.cv>.sh{display:grid;grid-template-columns:[gut-start] var(--gw,7rem) [gut-end text-start] minmax(0,1fr);gap:0}
  .duo .sh .num,.cv>.sh .num{grid-column:gut}
  .duo .sh h2,.cv>.sh h2{grid-column:text}
  #projects .row>.gut,.cv-exp .row>.gut,.cv>.cv-talks .row>.gut{padding-right:1rem}
}

/* 10. Contact and footer. */
.clinks{grid-column:wide;align-items:center;gap:.4em 1.4em}
.btn{padding:.3em .9em;border:1px solid var(--text);border-radius:3px;text-decoration:none;line-height:1.35}
.po{display:none}
@media (min-width:64rem){.clinks{grid-column:text-start/all-end}}
.site-foot{margin-top:56px;padding-bottom:40px}
.colo{grid-column:all;padding-top:18px;border-top:1px solid var(--line);font-size:.8em;line-height:1.45;color:var(--muted)}
@media (min-width:64rem){.colo{padding-left:7rem}}
.lost{grid-column:wide;max-width:36em;margin-top:16px}

/* 11. Band variants (data-cover="band": P2, P3). The <header> and the hero
   section paint the band themselves (background, plus a border-image fill
   for full bleed), so the hero text has the band as a real ancestor
   background. No pseudo-elements, shadows or clip paths. In dark, a 1px page
   rule closes the band (the last pixel of the border-image gradient). */
html[data-cover="band"]{overflow-x:clip}
[data-cover="band"] .site,[data-cover="band"] .hero,[data-cover="band"] .site-foot{
  --bg:var(--band);--surface:var(--band-surface);--text:var(--band-text);--muted:var(--band-muted);
  --accent:var(--band-accent);--line:var(--band-line);
  background:var(--band);color:var(--band-text);border-image:linear-gradient(var(--band) 0 0) fill 0//0 100vmax}
[data-cover="band"] .bar{padding-bottom:10px;border-bottom:1px solid var(--band-line)}
[data-cover="band"] .hero{padding-bottom:40px;
  border-image:linear-gradient(to bottom,var(--band) calc(100% - 1px),var(--band-edge) 0) fill 0//0 100vmax}
[data-cover="band"] #research{margin-top:0;padding-top:40px}
[data-cover="band"] #research>.sh{border-top:0;padding-top:0}
[data-cover="band"] .site-foot{padding-block:22px 30px}
[data-cover="band"] .colo{padding-top:0;border-top:0}

/* P3 (data-hero-figure="true"): from 75rem one grid holds the hero,
   Research and the figure (in that DOM order); the figure is lifted into row
   1, beside the hero, and reading-flow keeps Tab in visual order. The page
   grid widens to 72rem so the hero starts on the page gutter edge. Below
   75rem the figure sits under the Research text. */
.figrow .fig1{margin:32px 0 0}
@media (min-width:75rem){
  [data-hero-figure="true"] .bar{grid-column:all}
  .cover{display:grid;grid-template-columns:[hero-start] minmax(0,1fr) [hero-end] 3rem [fig-start] 35rem [fig-end];
    max-width:calc(72rem + 2 * var(--pad));margin-inline:auto;padding-inline:var(--pad);reading-flow:grid-rows}
  .cover>.hero{grid-column:hero;grid-row:1;padding-inline:0;
    --cols:[all-start gut-start text-start wide-start] minmax(0,1fr) [gut-end text-end wide-end all-end]}
  .cover>#research{grid-column:hero-start/fig-end;grid-row:2;padding-inline:0}
  .cover>.figrow{grid-column:fig;grid-row:1;align-self:center;display:block;padding:24px 0 32px}
  .cover>.figrow .fig1{margin:0}
  .cover .bq{--bq-bg:var(--band-surface);--bq-surface:var(--band-surface);--bq-fg:var(--band-text);
    --bq-muted:var(--band-muted);--bq-accent:var(--band-accent);--bq-line:var(--band-line);color:var(--band-text)}
}

/* 12. Interaction. Colour and underline changes only; no lifts. */
@media (hover:hover){
  a:hover,.email:hover{text-decoration-color:var(--accent);text-decoration-thickness:1.5px}
  .bar a:hover{text-decoration:underline 1.5px var(--accent);text-underline-offset:.2em}
  .tt:hover,summary:hover{color:var(--accent)}
  .btn:hover,.copy:hover{border-color:var(--accent)}
}
@media (prefers-reduced-motion:no-preference){
  a,.email,.tt,summary{transition:color .15s ease,text-decoration-color .15s ease}
  .disc summary::after,.more>summary::after{transition:transform .15s ease,margin .15s ease}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}
/* Touch: every control at least 44x44 (links inside running sentences are
   exempt, WCAG 2.5.8). Inline hit areas use vertical padding, so the text
   does not move. */
@media (pointer:coarse){
  .bar a,.tt,.links a,.email,.plinks a,.xl a,.disc summary,.more>summary,.copy,.btn{display:inline-flex;align-items:center;min-height:44px;min-width:44px}
  .links,.plinks,.xl{column-gap:1.25em}
  .bar ul{column-gap:clamp(.7em,4vw - 2px,1.25em)}
  .bar a{justify-content:center}
  .clinks>li{display:flex;align-items:center;gap:.25em;min-height:44px}
  .clinks>.po{display:none}
  .pub h3 a,.prow h3 a{padding-block:13px}
  .at a,.gl a,.allbib a,.hl-src,.sn a{padding-block:15px}
  .at a{padding-inline:4px;margin-inline:-4px}
  .cv-talks .at,#news .cv-talks .at{margin-top:16px}
  .card>.plinks{row-gap:0}
}
@media (max-width:39.99rem),(pointer:coarse){
  .at>span{display:block}
  .at>.sep{display:none}
}
@media (max-width:39.99rem){
  body{line-height:1.45}
  .sec{margin-top:48px}
  .site{padding-top:12px}
  .hero{padding-top:28px}
  [data-cover="band"] .hero{padding-bottom:36px}
  [data-cover="band"] #research{padding-top:36px}
  .fig1{margin:16px 0 24px}
  .pub+.pub{margin-top:24px}
  .prow+.prow{margin-top:20px}
  .crow+.crow{margin-top:14px}
  .sub{margin-top:24px}
}

/* 13. Print: one A4 page of CV-lite. The hero, Publications (with URLs),
   Projects (titles and glosses), the two-column CV and Contact (with URLs).
   Hidden: nav, toggle, skip link, figure, News, Research, notes, abstracts,
   disclosure summaries and the plate. The screen-only dark tokens never
   apply here, so these light values always win. The email address never
   exists in the HTML, so the site address prints in its place. */
@media print{
  :root{color-scheme:light;--bg:#fff;--surface:#fff;--text:#000;--muted:#333;--accent:#000;--line:#999;--me-wash:transparent;
    --band:#fff;--band-surface:#fff;--band-text:#000;--band-muted:#333;--band-accent:#000;--band-line:#999;--band-edge:#fff;
    --tw:100%;--pw:100%;--cols:[all-start gut-start text-start wide-start] minmax(0,1fr) [gut-end text-end wide-end all-end]}
  @page{size:A4;margin:10mm 12mm;background:#fff}
  html,body{background:#fff}
  body{font-size:8.8pt;line-height:1.28;color:#000}
  .site,.skip,.tt,.hero .links,#research,.figrow,#news>:not(.cvb),.disc,.more,.nref,.sn,.plate,.plinks,.tldr,.hl,
  .xl,.files,.tags,.meta,.em,.nojs,.allbib,.bq,.cvb .gl{display:none!important}
  .g,.duo,.cv{padding-inline:0;max-width:none}
  [data-cover="band"] .hero,[data-cover="band"] .site-foot{background:none;border-image:none;color:#000}
  .hero,[data-cover="band"] .hero,.cover>.hero{padding:0}
  .cover{display:block;padding:0}
  .hero h1{max-width:none;font-size:14pt;line-height:1.2}
  .lead{max-width:none;margin-top:2pt;font-size:10pt;line-height:1.3}
  .facts{max-width:none;margin-top:3pt;line-height:1.3}
  .fact+.fact{margin-top:0}
  .sec,.duo{margin-top:7pt}
  .sh{display:block!important;margin-bottom:3pt;padding-top:3pt}
  .sh h2{font-size:11pt}
  .num{display:none}
  .row,.g>.pub{display:block}
  .pub>.gut,.prow>.gut{display:none}
  .pub+.pub{margin-top:4pt}
  .kf{display:none}
  .kick{margin-bottom:0;font-size:7pt}
  .pub h3,.prow h3{font-size:9.2pt;line-height:1.25}
  .feat>.card{margin:0;padding:0;background:none}
  .au{margin-top:0;font-size:8.3pt}
  #publications h3 a::after,.clinks a[href^="http"]::after{content:" " attr(href);font-weight:400;font-size:7.5pt;color:#333;word-break:break-all}
  a{text-decoration:none}
  .duo{display:block}
  .prow+.prow{margin-top:3pt}
  .prow h3{display:inline}
  .gloss{display:inline;margin-left:.4em;font-size:8.3pt}
  .award{font-size:8.3pt;margin-top:0}
  .cv{display:grid;grid-template-columns:1fr 1fr;column-gap:16pt;align-items:start}
  .cv>.sh{grid-column:1/-1}
  .cv>.cv-edu{grid-column:1;grid-row:2}.cv>.cv-exp{grid-column:2;grid-row:2/span 2}
  .cv>.cv-hon{grid-column:1;grid-row:3/span 2}.cv>.cv-talks{grid-column:2;grid-row:4}
  .cvb>.sub,.cvb>.honours{margin-left:0}
  #news{margin-top:0}
  #news>.cvb>.sub{margin-top:6pt}
  .sub{margin:5pt 0 2pt;font-size:7pt}
  .cv-edu>.sub,.cv-exp>.sub{margin-top:0}
  .cvb .row{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:6pt;align-items:baseline}
  .cvb .row>.txt{display:contents}
  .cvb .row>.gut{grid-column:2;grid-row:1;font-size:8pt;text-align:right}
  .cvb .txt>*{grid-column:1/-1}
  .cvb .txt>:first-child{grid-column:1;grid-row:1}
  .crow+.crow{margin-top:3pt}
  .hd{font-size:9.2pt;line-height:1.25}
  .at,.gl{font-size:8.3pt;line-height:1.25}
  .honours{font-size:8.3pt;line-height:1.25}
  .honours li+li{margin-top:2pt}
  .clinks{display:block;columns:3;column-gap:12pt;font-size:8pt}
  .clinks>li{display:block}
  .po{display:block}
  .site-foot,[data-cover="band"] .site-foot{margin-top:8pt;padding:0}
  .colo{padding:3pt 0 0;font-size:7pt}
  .pub,.prow,.crow,.honours li{break-inside:avoid}
  .sh{break-after:avoid}
}
