/* Personal Page — component styles. Load after tokens.css.
   Type sizes are not set here: put the token classes (display, heading, title,
   lead, body, small, meta, label) in the markup beside each pp- class. */

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* a link to a section glides there instead of jumping; readers who ask for less motion get the jump */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; font-family: var(--font-sans); -webkit-font-smoothing: antialiased; }
/* a data-theme on any element repaints that subtree: this is how the gallery goes dark */
body, [data-theme] { background: var(--paper); color: var(--ink); }
h1, h2, h3, p, ol, ul, figure, fieldset, pre { margin: 0; padding: 0; }
ol, ul { list-style: none; }
fieldset { border: 0; min-width: 0; }
img { display: block; max-width: 100%; height: auto; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
/* data lines: figures keep one width, so dates and counts line up */
.meta, .label { font-variant-numeric: tabular-nums; }
.label { text-transform: uppercase; }

.pp-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ---------- layout ---------- */
.pp-page { width: 100%; max-width: var(--page-max); margin-inline: auto; padding-inline: var(--gutter); }
/* the one grid: rail for data, then the reading column */
.pp-rail { display: grid; grid-template-columns: var(--rail) minmax(0, var(--measure)); column-gap: var(--space-12); }
.pp-rail__main { grid-column: 2; min-width: 0; }
.pp-section { padding-block: var(--space-16); border-top: var(--line) solid var(--hairline); }
.pp-section > * + * { margin-top: var(--space-8); }

/* ---------- SiteHeader ---------- */
.pp-header { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2) var(--space-6); padding-block: var(--space-6); }
.pp-header__name { display: inline-flex; align-items: baseline; color: var(--ink); font-weight: 600; letter-spacing: -0.01em; text-decoration: none; }
/* the name in its own script, after the wordmark: regular weight, so it does not outweigh the Latin,
   and set off by a rule with the same space on both sides */
.pp-header__native { margin-left: var(--space-3); padding-left: var(--space-3); border-left: var(--line) solid var(--border); font-weight: 400; line-height: 1.1; letter-spacing: 0; }
.pp-header__nav { display: flex; flex-wrap: wrap; gap: 0 var(--space-6); }
.pp-header__nav a { padding-block: var(--space-1); color: var(--ink-muted); text-decoration: none; transition: color 150ms ease-out; }
.pp-header__nav a:hover { color: var(--ink); }
.pp-header__nav a[aria-current] { color: var(--ink); text-decoration: underline; text-decoration-thickness: var(--line); text-underline-offset: 0.4em; }

/* ---------- TextLink ---------- */
.pp-link, .pp-prose a { color: var(--link); text-decoration: underline; text-decoration-color: var(--border); text-decoration-thickness: var(--line); text-underline-offset: 0.2em; transition: text-decoration-color 150ms ease-out; }
.pp-link:visited, .pp-prose a:visited { color: var(--ink-muted); }
.pp-link:hover, .pp-prose a:hover { color: var(--link); text-decoration-color: currentColor; }
.pp-link--external::after { content: "\00a0\2197"; content: "\00a0\2197" / ""; }

/* ---------- LinkChip ---------- */
.pp-chip { display: inline-block; padding: var(--space-1) 0; border: 0; background: none; color: var(--ink); text-decoration: none; white-space: nowrap; cursor: pointer; }
.pp-chip::before, .pp-chip::after { display: inline-block; color: var(--ink-muted); transition: color 150ms ease-out; }
.pp-chip::before { content: "["; content: "[" / ""; }
.pp-chip::after { content: "]"; content: "]" / ""; }
.pp-chip:hover { text-decoration: underline; text-decoration-thickness: var(--line); text-underline-offset: 0.3em; }
.pp-chip:hover::before, .pp-chip:hover::after { color: var(--ink); }
summary.pp-chip { list-style: none; }
summary.pp-chip::-webkit-details-marker { display: none; }
.pp-chip__toggle::before { content: "\00a0+"; }
details[open] > summary .pp-chip__toggle::before { content: "\00a0\2212"; }

/* ---------- Button ---------- */
.pp-button { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--control); padding: 0 var(--space-4); border: var(--line) solid var(--border); border-radius: var(--radius-sm); background: var(--paper); color: var(--ink); font-family: var(--font-sans); font-weight: 500; text-decoration: none; cursor: pointer; transition: background-color 150ms ease-out, border-color 150ms ease-out, opacity 150ms ease-out; }
.pp-button:hover { background: var(--paper-sunk); border-color: var(--ink); }
.pp-button:active { background: var(--hairline); }
.pp-button--solid { background: var(--fill-solid); border-color: var(--fill-solid); color: var(--on-solid); }
.pp-button--solid:hover { background: var(--fill-solid); border-color: var(--fill-solid); opacity: 0.85; }
.pp-button--solid:active { background: var(--fill-solid); opacity: 0.7; }
.pp-button:disabled, .pp-button[aria-disabled="true"] { background: var(--paper); border-color: var(--hairline); color: var(--ink-muted); opacity: 1; cursor: not-allowed; }

/* ---------- Tag ---------- */
.pp-tag { display: inline-flex; align-items: center; padding: 2px var(--space-2); border: var(--line) solid var(--border); border-radius: var(--radius-sm); color: var(--ink); white-space: nowrap; }
.pp-tag--solid { background: var(--fill-solid); border-color: var(--fill-solid); color: var(--on-solid); }

/* ---------- FilterChips ---------- */
.pp-filter { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pp-filter__chip { position: relative; display: inline-flex; cursor: pointer; }
.pp-filter__chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.pp-filter__chip span { padding: var(--space-1) var(--space-3); border: var(--line) solid var(--border); border-radius: var(--radius-sm); color: var(--ink); transition: background-color 150ms ease-out, border-color 150ms ease-out, color 150ms ease-out; }
.pp-filter__chip:hover span { border-color: var(--ink); }
.pp-filter__chip input:checked + span { background: var(--fill-solid); border-color: var(--fill-solid); color: var(--on-solid); }
.pp-filter__chip input:focus-visible + span { outline: 2px solid var(--ring); outline-offset: 2px; }

/* ---------- placeholder (until a real image is supplied) ---------- */
.pp-placeholder { display: flex; align-items: center; justify-content: center; width: 100%; aspect-ratio: var(--ar, 1.5); background: var(--paper-sunk); color: var(--ink-muted); }

/* ---------- Intro ---------- */
/* portrait and news in the rail, the introduction beside them */
.pp-intro { display: grid; grid-template-columns: var(--rail) minmax(0, var(--measure)); grid-template-rows: auto 1fr; grid-template-areas: "portrait body" "news body"; column-gap: var(--space-12); row-gap: var(--space-8); align-items: start; padding-block: var(--space-24) var(--space-16); }
.pp-intro__portrait { grid-area: portrait; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; background: var(--paper-sunk); }
.pp-intro__body { grid-area: body; min-width: 0; }
.pp-intro__news { grid-area: news; min-width: 0; }
.pp-intro__news > * + * { margin-top: var(--space-4); }
/* set by bundle.js once the items that fit are chosen: the list ends level with the introduction */
.pp-intro__news.is-fitted { display: flex; flex-direction: column; align-self: stretch; }
.pp-intro__news.is-fitted > .pp-news { flex: 1 1 auto; align-content: space-between; }
.pp-intro__bio + .pp-intro__bio { margin-top: var(--space-4); }
.pp-notice + .pp-intro__bio { margin-top: var(--space-6); }

/* ---------- Notice ---------- */
.pp-notice { padding: var(--space-4) var(--space-6); background: var(--notice); color: var(--on-notice); }
/* on the band a link keeps the band's text colour, visited or not; the underline alone marks it.
   The band is the same in every theme, so the underline is a fixed grey that holds 3:1 on it */
.pp-notice .pp-link, .pp-notice .pp-link:visited, .pp-notice .pp-link:hover { color: inherit; }
.pp-notice .pp-link { text-decoration-color: var(--gray-600); }
.pp-notice .pp-link:hover { text-decoration-color: currentColor; }
.pp-notice :focus-visible { outline-color: var(--on-notice); }
.pp-intro__links { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); margin-top: var(--space-6); }

/* ---------- NewsList ---------- */
.pp-news { display: grid; row-gap: var(--space-3); }
.pp-news__item { display: grid; grid-template-columns: var(--date-col) minmax(0, 1fr); column-gap: var(--space-3); align-items: baseline; }
.pp-news__date { color: var(--ink-muted); }
.pp-news__earlier { margin-top: var(--space-3); }
.pp-news__earlier > summary { margin-left: calc(var(--date-col) + var(--space-3)); }
.pp-news__earlier[open] > summary { margin-bottom: var(--space-3); }
.pp-news__empty { color: var(--ink-muted); }

/* ---------- PublicationEntry ---------- */
.pp-pub { align-items: start; }
/* the teaser: a white 16:9 card with a hairline edge. A figure of any shape sits whole inside it,
   never cropped; a clip fills it. White in every theme, because paper figures are drawn on white */
.pp-pub__thumb { width: 100%; aspect-ratio: 16 / 9; object-fit: contain; padding: var(--space-2); background: var(--gray-0); outline: var(--line) solid var(--hairline); outline-offset: calc(-1 * var(--line)); }
.pp-pub__thumb--fill, .pp-pub__thumb--clip { object-fit: cover; padding: 0; }
.pp-pub__thumb--clip { cursor: pointer; }
.pp-pub__thumb--clip > video { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.pp-pub__thumb.pp-placeholder { padding: 0; background: var(--paper-sunk); }
.pp-pub__when { color: var(--ink-muted); }
.pp-pub__title a { color: var(--ink); text-decoration: none; }
.pp-pub__title a:hover { text-decoration: underline; text-decoration-thickness: var(--line); text-underline-offset: 0.2em; }
.pp-pub__authors { margin-top: var(--space-1); color: var(--ink-muted); }
.pp-pub__me { color: var(--ink); font-weight: 600; }
.pp-pub__tags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); margin-top: var(--space-2); }
.pp-pub__links { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-3); margin-top: var(--space-1); }
.pp-pub__more[open] { flex-basis: 100%; }
.pp-pub__abstract { margin-block: var(--space-1) var(--space-3); font-family: var(--font-sans); color: var(--ink); }
.pp-pub__note { margin-top: var(--space-1); color: var(--ink-muted); }

/* ---------- code block (BibTeX) ---------- */
.pp-code { position: relative; margin-block: var(--space-1) var(--space-3); background: var(--paper-sunk); color: var(--ink); }
/* the one place a fixed-width face is kept: a BibTeX record has to line up */
.pp-code pre { padding: var(--space-4); overflow-x: auto; font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace); white-space: pre; tab-size: 2; }
.pp-code__copy { position: absolute; top: var(--space-2); right: var(--space-3); padding-left: var(--space-2); background: var(--paper-sunk); }

/* ---------- PublicationList ---------- */
.pp-pubs > * + * { margin-top: var(--space-8); }
.pp-pubs__list { display: grid; row-gap: var(--space-8); }

/* ---------- gallery mode ---------- */
.pp-gallery { padding-block: var(--space-24); }
/* the heading and each series run to the window edges, less the gutter */
.pp-gallery > .pp-section-heading, .pp-gallery__series { padding-inline: var(--gutter); }
.pp-gallery > * + * { margin-top: var(--space-12); }

/* a series: its name has the left column to itself, and every row of its photographs starts on one edge beside it */
.pp-gallery__series { display: grid; grid-template-columns: var(--photo-row) minmax(0, 1fr); column-gap: var(--space-2); align-items: start; }
/* SeriesHeader */
.pp-series { padding-right: var(--space-4); }
.pp-series__meta { margin-top: var(--space-1); color: var(--ink-muted); }

/* GalleryGrid: justified rows, every photo at its own aspect ratio */
.pp-grid { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2); --pp-row: var(--photo-row); }
.pp-grid::after { content: ""; flex-grow: 1000000; }

/* PhotoTile */
.pp-tile { position: relative; display: block; flex: var(--ar, 1.5) 1 calc(var(--ar, 1.5) * var(--pp-row)); aspect-ratio: var(--ar, 1.5); overflow: hidden; background: var(--paper-sunk); color: var(--ink); text-decoration: none; cursor: zoom-in; }
.pp-tile > img, .pp-tile > .pp-placeholder { width: 100%; height: 100%; object-fit: cover; }
.pp-tile__caption { position: absolute; inset: auto 0 0 0; padding: var(--space-2) var(--space-3); background: var(--paper); opacity: 0; transition: opacity 150ms ease-out; }
.pp-tile:hover .pp-tile__caption, .pp-tile:focus-visible .pp-tile__caption, .pp-tile.is-captioned .pp-tile__caption { opacity: 1; }
.pp-tile:focus-visible { z-index: 1; }

/* PhotoCaption */
.pp-caption { display: grid; gap: 2px; min-width: 0; }
.pp-caption__title { color: var(--ink); }
.pp-tile__caption .pp-caption > span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.pp-caption__meta { color: var(--ink-muted); }
/* on a tile the second line is the camera settings; it wraps on a narrow photo */
.pp-tile__caption .pp-caption > .pp-caption__meta { white-space: normal; }

/* Lightbox */
.pp-lightbox { position: fixed; inset: 0; display: none; grid-template-rows: auto minmax(0, 1fr) auto; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; }
.pp-lightbox[open], .pp-lightbox--static { display: grid; }
.pp-lightbox--static { position: relative; inset: auto; height: 520px; }
.pp-lightbox__bar { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--gutter); color: var(--ink-muted); }
.pp-lightbox__stage { display: flex; align-items: center; justify-content: center; min-height: 0; padding-inline: var(--gutter); cursor: zoom-out; }
.pp-lightbox__stage > img { max-width: 100%; max-height: 100%; object-fit: contain; cursor: default; }
.pp-lightbox__stage > .pp-placeholder { width: min(100%, calc((100vh - 200px) * var(--ar, 1.5))); cursor: default; }
.pp-lightbox--static .pp-lightbox__stage > .pp-placeholder { width: min(100%, calc(360px * var(--ar, 1.5))); }
.pp-lightbox__foot { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-2) var(--space-6); padding: var(--space-4) var(--gutter) var(--space-6); }
.pp-lightbox__nav { display: flex; gap: var(--space-4); }

/* ---------- Footer ---------- */
.pp-footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-6); padding-block: var(--space-6) var(--space-12); border-top: var(--line) solid var(--hairline); color: var(--ink-muted); }
.pp-footer a { color: inherit; text-decoration-color: var(--border); text-underline-offset: 0.3em; }
.pp-footer a:hover { color: var(--ink); }

/* ---------- preview helpers (the design system's own cards) ---------- */
.pp-stage { padding: var(--space-6); }
.pp-stage--fill { min-height: 100vh; }
.pp-stack > * + * { margin-top: var(--space-6); }
.pp-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }

/* ---------- two-column rows stack: image above text ---------- */
@media (max-width: 820px) {
  .pp-intro { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; grid-template-areas: "portrait" "body" "news"; }
  .pp-intro__portrait { max-width: 480px; }
  .pp-rail { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-3); }
  .pp-rail__main { grid-column: 1; }
  .pp-pub__thumb { max-width: 480px; }
  .pp-gallery__series { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-3); }
  .pp-series { padding-right: 0; }
}

/* ---------- phone ---------- */
@media (max-width: 640px) {
  .pp-page { padding-inline: var(--gutter-phone); }
  .pp-section { padding-block: var(--space-12); }
  .pp-section > * + * { margin-top: var(--space-6); }
  .pp-header__nav { gap: 0 var(--space-4); }
  .pp-header__native { margin-left: var(--space-2); padding-left: var(--space-2); }
  .pp-intro { padding-block: var(--space-12); }
  .pp-gallery { padding-block: var(--space-16); }
  .pp-gallery > .pp-section-heading, .pp-gallery__series { padding-inline: var(--gutter-phone); }
  .pp-grid { --pp-row: 140px; }
  .pp-lightbox__bar, .pp-lightbox__stage { padding-inline: var(--gutter-phone); }
  .pp-lightbox__foot { padding-inline: var(--gutter-phone); }
}

/* captions cannot be hovered on touch screens: the lightbox shows them instead */
@media (hover: none) {
  .pp-tile__caption { display: none; }
  .pp-tile.is-captioned .pp-tile__caption { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0s !important; }
}
