/* ============================================================
   Paul Baker — CV / games portfolio
   Plain CSS, no build step. Dark-first with a light-mode override.
   ============================================================ */

:root {
  --bg:        #0d0f1a;
  --bg-elev:   #141827;
  --bg-card:   #1a1f34;
  --text:      #e9ebf5;
  --text-dim:  #a2a8c4;
  --border:    #2b3250;
  --accent:    #4c8dff;   /* electric blue     */
  --accent-2:  #37d6c4;   /* teal (links)      */
  --accent-3:  #ffcf4d;   /* coin-op yellow    */
  --focus:     #8ab4ff;

  --maxw: 1080px;
  --radius: 14px;
  --shadow: 0 10px 30px -12px rgba(0,0,0,.55);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
          "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg:        #f6f5f2;
    --bg-elev:   #ffffff;
    --bg-card:   #ffffff;
    --text:      #171a24;
    --text-dim:  #565c73;
    --border:    #e0dfda;
    --accent:    #1f5bd6;
    --accent-2:  #0f8f86;
    --accent-3:  #b7860b;
    --focus:     #1f5bd6;
    --shadow: 0 10px 28px -14px rgba(20,20,40,.28);
  }
}

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

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: var(--accent-2); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent); }

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

.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 22px; }

.skip {
  position: absolute; left: -999px; top: 0; z-index: 100;
  background: var(--accent); color: #fff; padding: 10px 16px; border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; color: #fff; }

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.nav__inner { display: flex; align-items: center; justify-content: space-between; min-height: 60px; gap: 12px; }
.nav__brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: 800; letter-spacing: .01em; color: var(--text); text-decoration: none;
}
.nav__mark {                               /* portrait chip; alt="" — the adjacent text names it */
  width: 30px; height: 30px; flex: none;
  border-radius: 22%;                      /* == the favicon's rx 22 on a 100-unit box */
  border: 1px solid var(--border);
}
.nav__menu { display: flex; gap: 22px; }
.nav__menu a { color: var(--text-dim); text-decoration: none; font-weight: 600; font-size: 15px; }
.nav__menu a:hover { color: var(--text); }
.nav__toggle {
  display: none;
  background: var(--bg-card); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 14px; font: inherit; font-weight: 600; font-size: 14px; cursor: pointer;
}

@media (max-width: 720px) {
  .nav__toggle { display: block; }
  .nav__menu {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; gap: 0;
    background: var(--bg-elev); border-bottom: 1px solid var(--border);
  }
  .nav__menu[hidden] { display: none; }
  .nav__menu a { padding: 13px 22px; border-top: 1px solid var(--border); }
}

/* ---------- hero ---------- */
.hero {
  padding: clamp(48px, 9vw, 104px) 0 clamp(40px, 7vw, 76px);
  background:
    radial-gradient(60% 120% at 12% 0%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 60%),
    radial-gradient(50% 120% at 100% 20%, color-mix(in srgb, var(--accent-2) 16%, transparent), transparent 55%);
}
.hero__inner { display: flex; align-items: center; gap: clamp(28px, 5vw, 60px); flex-wrap: wrap; }
.hero__text { flex: 1 1 380px; min-width: 0; }
.hero__photo {
  flex: 0 0 auto; order: 1;
  width: clamp(150px, 24vw, 240px); height: auto;
  aspect-ratio: 1; object-fit: cover; border-radius: 50%;
  border: 3px solid var(--bg-card);
  box-shadow: 0 16px 44px rgba(0, 0, 0, .28);
}
@media (max-width: 620px) {
  .hero__photo { order: -1; width: 128px; }
}
.hero__kicker {
  margin: 0 0 10px; text-transform: uppercase; letter-spacing: .16em;
  font-size: 13px; font-weight: 700; color: var(--accent-2);
}
.hero__name {
  margin: 0 0 .3em; font-size: clamp(2.6rem, 8vw, 4.6rem); line-height: 1.02;
  font-weight: 800; letter-spacing: -.02em;
}
.hero__lead { margin: 0 0 18px; max-width: 60ch; font-size: clamp(1rem, 2.4vw, 1.2rem); color: var(--text-dim); }

.hero__avail {                             /* status line, not another paragraph of prose */
  margin: 0 0 24px;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 7px 15px 7px 13px; border-radius: 999px;
  font-size: 14px; font-weight: 600; color: var(--text);
  background: color-mix(in srgb, var(--accent-2) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-2) 40%, transparent);
}
.hero__avail::before {
  content: ""; flex: none;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-2) 25%, transparent);
}

.hero__links { list-style: none; margin: 0 0 22px; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
.hero__links a {
  display: inline-block; padding: 9px 16px; border-radius: 999px;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--text); text-decoration: none; font-weight: 600; font-size: 14px;
}
.hero__links a:hover { border-color: var(--accent); color: var(--accent); }
.hero__links a.hero__links--primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.hero__links a.hero__links--primary:hover { filter: brightness(1.08); color: #fff; }

.hero__stats { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px 28px; color: var(--text-dim); font-size: 14px; }
.hero__stats strong { color: var(--text); font-size: 18px; margin-right: 6px; }

/* ---------- sections ---------- */
.section { padding: clamp(48px, 8vw, 88px) 0; border-top: 1px solid var(--border); }
.section--alt { background: var(--bg-elev); }
.section__label {
  margin: 0 0 6px; text-transform: uppercase; letter-spacing: .16em;
  font-size: 12px; font-weight: 700; color: var(--accent);
}
.section__title { margin: 0 0 28px; font-size: clamp(1.6rem, 4.5vw, 2.4rem); font-weight: 800; letter-spacing: -.015em; }
.subhead {
  margin: 40px 0 16px; font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .14em; color: var(--text-dim);
}
.subhead:first-of-type { margin-top: 8px; }

/* ---------- filter ---------- */
.filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.filter__label { font-size: 12px; text-transform: uppercase; letter-spacing: .14em; color: var(--text-dim); margin-right: 4px; }
.filter__count { font-size: 13px; color: var(--text-dim); margin-left: 4px; }
.chip {
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  padding: 7px 14px; border-radius: 999px;
  background: var(--bg-card); color: var(--text-dim); border: 1px solid var(--border);
}
.chip:hover { color: var(--text); }
.chip.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ---------- game grid ---------- */
.grid {
  display: grid; gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.game {
  display: flex; flex-direction: column;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.game:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); box-shadow: var(--shadow); }
@media (prefers-reduced-motion: reduce) { .game, .game:hover { transform: none; transition: none; } }

.game__art {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #0b0e18;
}
.game__art::before {                       /* blurred fill derived from the art itself */
  content: "";
  position: absolute;
  inset: -8%;
  background-image: var(--art, none);
  background-size: cover;
  background-position: center;
  filter: blur(24px) brightness(.5) saturate(1.25);
}
.game__art > img {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 16px;
  filter: drop-shadow(0 10px 24px rgba(0, 0, 0, .5));
}
/* Trailer play affordance. The anchor is a real link to YouTube, so with JS off
   (or if the swap fails) clicking still works — main.js upgrades it to play inline. */
.game__play {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center;
  text-decoration: none;
  background: linear-gradient(180deg, rgba(0,0,0,.05), rgba(0,0,0,.28));
  transition: background .18s ease;
}
.game__play::before {                       /* the disc */
  content: "";
  width: 58px; height: 58px; border-radius: 50%;
  background: rgba(12, 14, 24, .62);
  border: 2px solid rgba(255, 255, 255, .92);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .45);
  transition: transform .18s ease, background .18s ease;
}
.game__play::after {                        /* the triangle, optically centred */
  content: "";
  position: absolute;
  margin-left: 5px;
  border-left: 17px solid #fff;
  border-top: 11px solid transparent;
  border-bottom: 11px solid transparent;
}
.game__play:hover { background: linear-gradient(180deg, rgba(0,0,0,.15), rgba(0,0,0,.4)); }
.game__play:hover::before { transform: scale(1.08); background: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .game__play, .game__play::before { transition: none; }
  .game__play:hover::before { transform: none; }
}

.game__art iframe {                         /* the swapped-in player */
  position: absolute; inset: 0; z-index: 3;
  width: 100%; height: 100%; border: 0; background: #000;
}

.game__art--photo::before {                 /* softer blur so the photo still reads */
  inset: 0;
  filter: blur(10px) brightness(.62) saturate(1.05);
}

.ph {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid; place-items: center; padding: 14px; text-align: center;
}
.ph--photo {                               /* title text over the parent's blurred --art */
  background-image:
    linear-gradient(0deg, rgba(0, 0, 0, .5), rgba(0, 0, 0, .2)),
    repeating-linear-gradient(0deg, rgba(255,255,255,.05) 0 1px, transparent 1px 22px),
    repeating-linear-gradient(90deg, rgba(255,255,255,.05) 0 1px, transparent 1px 22px);
}
.ph span {
  font-weight: 800; letter-spacing: .02em; color: #fff;
  font-size: clamp(1rem, 3.4vw, 1.4rem); line-height: 1.15;
  text-shadow: 0 2px 10px rgba(0,0,0,.45);
}

.game__body { display: flex; flex-direction: column; gap: 8px; padding: 16px 16px 18px; flex: 1; }
.game__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.game__title { margin: 0; font-size: 1.06rem; font-weight: 700; line-height: 1.25; }
.game__year { flex: none; font-size: 13px; font-weight: 700; color: var(--accent-3); }
.game__meta { margin: 0; font-size: 13px; color: var(--text-dim); }
.game__note { margin: 4px 0 0; font-size: 14px; color: var(--text); }
/* awards / nominations — shares the accent-3 "honours" language with .edu__hon.
   Only the short status is a chip; the award name flows as text, so a long
   title wraps normally instead of inflating a two-line pill. */
.awards { list-style: none; margin: 4px 0 0; padding: 0; }
.awards li {
  font-size: 12.5px; line-height: 1.5; color: var(--text-dim);
  margin-top: 4px; text-indent: -0.25em;
}
.hon {
  display: inline-block; margin-right: 5px; text-indent: 0;
  font-size: 10px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px;
  color: var(--accent-3);
  background: color-mix(in srgb, var(--accent-3) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-3) 40%, transparent);
}
.hon--win {                                /* a win outranks a nomination — say so visually */
  background: color-mix(in srgb, var(--accent-3) 24%, transparent);
  border-color: color-mix(in srgb, var(--accent-3) 72%, transparent);
}

.game__quote {                             /* press pull-quote inside a card */
  margin: 2px 0 0; padding: 0 0 0 12px;
  border-left: 2px solid color-mix(in srgb, var(--accent-2) 55%, transparent);
}
.game__quote blockquote { margin: 0; font-size: 13.5px; font-style: italic; color: var(--text-dim); }
.game__quote figcaption {
  margin-top: 4px; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent-2);
}
.game__quote figcaption a {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--accent-2) 40%, transparent);
}
.game__quote figcaption a:hover { color: var(--accent); border-bottom-color: currentColor; }

.game__links { margin: auto 0 0; padding-top: 6px; font-size: 14px; font-weight: 600; }

/* platform badges */
.badges { list-style: none; margin: 2px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.pf {
  font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--pf-c, var(--text-dim)) 55%, transparent);
  color: var(--pf-c, var(--text-dim));
  background: color-mix(in srgb, var(--pf-c, var(--text-dim)) 14%, transparent);
}
.pf--wii     { --pf-c: #7bd0ff; }
.pf--ps2     { --pf-c: #9d8bff; }
.pf--ps3     { --pf-c: #8ba0ff; }
.pf--x360    { --pf-c: #74d68a; }
.pf--gc      { --pf-c: #b69bff; }
.pf--pc      { --pf-c: #ffd166; }
.pf--steam   { --pf-c: #66c0f4; }
.pf--mac     { --pf-c: #cfd3dc; }
.pf--linux   { --pf-c: #f5b942; }
.pf--ios     { --pf-c: #d0d3db; }
.pf--android { --pf-c: #7ede9b; }
.pf--wp      { --pf-c: #4fb3ff; }
.pf--web     { --pf-c: #b98cff; }
.pf--cloud   { --pf-c: #9fb0c9; }
.pf--edge     { --pf-c: #6fd6b8; }
.pf--embedded { --pf-c: #c9a87c; }
.pf--edge    { --pf-c: #8fc9b6; }
.pf--embedded{ --pf-c: #c9a98f; }

/* ---------- CV timeline ---------- */
.cv { list-style: none; margin: 0; padding: 0; }
.cv__item {
  display: grid; grid-template-columns: 170px 1fr; gap: 24px;
  padding: 22px 0; border-top: 1px solid var(--border);
}
.cv__item:first-child { border-top: 0; }
.cv__when { font-size: 14px; font-weight: 700; color: var(--text-dim); padding-top: 3px; }
.cv__what h3 { margin: 0 0 3px; font-size: 1.12rem; font-weight: 700; }
.cv__co { display: block; font-size: .95rem; font-weight: 600; color: var(--accent-2); }
.cv__loc { margin: 0 0 10px; font-size: 13px; color: var(--text-dim); }
.cv__what ul { margin: 0; padding-left: 1.1em; }
.cv__what li { margin: 6px 0; font-size: 15px; }

@media (max-width: 640px) {
  .cv__item { grid-template-columns: 1fr; gap: 8px; }
}

/* ---------- skills ---------- */
.skills { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.skills__group h3 {
  margin: 0 0 12px; font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; color: var(--text-dim);
}
.skills__group ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.skills__group li {
  font-size: 14px; font-weight: 600;
  padding: 6px 12px; border-radius: 8px;
  background: var(--bg-card); border: 1px solid var(--border);
}

/* ---------- honours ---------- */
.hons { list-style: none; margin: 0; padding: 0; }
.hons li {
  display: grid;
  grid-template-columns: 106px 1fr auto;   /* wide enough for the longest chip ("Tournament") */
  align-items: baseline; gap: 6px 14px;
  padding: 13px 0; border-top: 1px solid var(--border);
}
.hons li:first-child { border-top: 0; }
.hons .hon { justify-self: start; }        /* chip sizes to its text, not the column */
.hons__what { font-size: 15px; }

/* a sourced honour links to its evidence; unsourced ones stay plain text */
.hons__what a, .awards a {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--accent-2) 45%, transparent);
}
.hons__what a:hover, .awards a:hover { color: var(--accent-2); border-bottom-color: currentColor; }
.hons__ctx {
  font-size: 13px; font-style: italic; color: var(--text-dim); white-space: nowrap;
}
@media (max-width: 640px) {
  .hons li { grid-template-columns: 1fr; gap: 5px; }
  .hons__ctx { white-space: normal; }
}

/* ---------- quotes ---------- */
.quotes { display: grid; gap: 20px; grid-template-columns: repeat(2, 1fr); }
@media (max-width: 620px) { .quotes { grid-template-columns: 1fr; } }
.quote {
  margin: 0; padding: 22px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: var(--radius);
}
.quote blockquote { margin: 0 0 14px; font-size: 15px; }
.quote figcaption { font-size: 13px; color: var(--text-dim); }
.quote figcaption strong { color: var(--text); }
.quote figcaption span { display: block; margin-top: 2px; opacity: .8; }

/* ---------- education ---------- */
.edu { list-style: none; margin: 0; padding: 0; }
.edu li { display: grid; grid-template-columns: 170px 1fr; gap: 24px; padding: 18px 0; border-top: 1px solid var(--border); }
.edu li:first-child { border-top: 0; }
.edu__when { font-size: 14px; font-weight: 700; color: var(--text-dim); }
.edu h3 { margin: 0 0 3px; font-size: 1.05rem; }
.edu p { margin: 0; font-size: 14px; color: var(--text-dim); }
.edu__hon {
  display: inline-block;
  margin-left: 8px;
  vertical-align: middle;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
  color: var(--accent-3);
  background: color-mix(in srgb, var(--accent-3) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-3) 45%, transparent);
}
@media (max-width: 640px) { .edu li { grid-template-columns: 1fr; gap: 6px; } }

/* ---------- contact ---------- */
.contact__lead { margin: 0 0 20px; font-size: 1.1rem; color: var(--text-dim); }
.contact__email { margin: 0 0 24px; font-size: 1.5rem; font-weight: 700; letter-spacing: -0.01em; }
.contact__links { display: flex; flex-wrap: wrap; gap: 10px 24px; font-weight: 700; font-size: 1.05rem; }

/* ---------- filter hidden state ---------- */
.game[hidden] { display: none; }
.grid[hidden], .subhead[hidden] { display: none; }

/* ============================================================
   Print — also the source for assets/paul-baker-cv.pdf, which is
   generated from this page with headless Chrome --print-to-pdf.
   Regenerate the PDF whenever page content changes.
   ============================================================ */
@media print {
  /* The dark palette lives on bare :root, so it must be overridden
     wholesale here — otherwise print inks a dark background. */
  :root {
    --bg: #fff; --bg-elev: #fff; --bg-card: #fff;
    --text: #000; --text-dim: #333; --border: #bbb;
    --accent: #1a4fb4; --accent-2: #0b6f68; --accent-3: #6b4c00;
    --shadow: none;
  }

  @page { margin: 12mm 10mm; }

  body { font-size: 10pt; line-height: 1.38; background: #fff; color: #000; }

  /* chrome and interactive affordances have no meaning on paper */
  /* the CV link is circular inside the CV itself */
  .nav, .skip, .filter, .hero__links, .game__art, a[href$=".pdf"] { display: none; }

  /* ---- print-only cuts: the page is a portfolio, this has to be a CV ----
     All of this is said again elsewhere on the page, so on paper it is pure
     repetition. Every honour is restated in Experience or Education. Every
     card note's contribution sentence is restated, often verbatim, in the
     Experience bullet for that role — so the cards print as a credits list
     (title / year / role / platforms) and Experience carries the detail.
     See the "CV PDF" section in README.md for the full mapping. */
  #honours { display: none; }
  .hero__stats { display: none; }          /* restates the lead paragraph */
  .game__note, .game__links, .awards { display: none; }
  .game__quote { display: none; }          /* the References section is the testimony */

  .hero { padding: 0 0 10pt; background: none; }
  .hero__inner { gap: 18pt; }
  .hero__photo { width: 78px; border: 1px solid var(--border); box-shadow: none; }
  .hero__name { font-size: 26pt; margin-bottom: .15em; }
  .hero__lead { font-size: 10.5pt; margin-bottom: 8pt; max-width: none; }
  .hero__avail { background: none; border: 1px solid var(--border); padding: 3pt 9pt; }
  .hero__avail::before { box-shadow: none; }

  .section { padding: 8pt 0 0; border-top: 1px solid var(--border); background: none; }
  .section--alt { background: none; }
  .section__title { font-size: 15pt; margin-bottom: 10pt; }
  .wrap { max-width: none; padding: 0; }

  /* With the art and the note gone, a card is just a credit: title, year,
     role and platforms. Print it as one full-width row per title — sixteen
     of them cost ~18 lines here versus a little over a page as boxes, which
     is the difference between a four- and a five-page CV. Single column: the
     row already uses the full measure, so there is nothing to pack beside it. */
  .grid { display: block; columns: 1; column-gap: 0; }
  .game {
    display: block; break-inside: avoid;
    margin: 0; padding: 0; border: 0; box-shadow: none;
  }
  /* .game__body is `flex-direction: column` on screen — it must be reset to a
     row explicitly, or the credit stacks over three lines and costs more than
     the boxes did. */
  .game__body {
    display: flex; flex-direction: row; align-items: baseline;
    gap: 8pt; padding: 1.6pt 0; border-bottom: .4pt solid var(--border);
  }
  .game__body > * + * { margin-top: 0; }
  .game__head { flex: 0 0 38%; justify-content: space-between; gap: 6pt; padding-right: 4pt; }
  .game__title { font-size: 9.5pt; line-height: 1.2; }
  .game__year { font-size: 8.5pt; }
  .game__meta { flex: 1 1 auto; margin: 0; font-size: 8.5pt; }
  .badges { flex: 0 0 auto; margin: 0; gap: 3pt; flex-wrap: nowrap; }

  .pf {
    border: 1px solid var(--border); background: none;
    font-size: 6.5pt; font-weight: 700; padding: 0 2.5pt; border-radius: 3pt;
  }

  /* chips cost a line each on paper — run them as comma-separated text */
  .skills { display: block; columns: 2; column-gap: 18pt; }
  .skills__group { break-inside: avoid; margin-bottom: 8pt; }
  .skills__group h3 { margin-bottom: 3pt; }
  .skills__group ul { display: block; }
  .skills__group li {
    display: inline; border: none; background: none; padding: 0;
    font-size: 9.5pt; font-weight: 400;
  }
  .skills__group li:not(:last-child)::after { content: " · "; color: var(--text-dim); }
  .quote { border: 1px solid var(--border); border-left-width: 3px; padding: 7pt; }
  .quote blockquote { font-size: 9pt; }
  .quotes { display: block; columns: 2; column-gap: 10pt; }
  .quote { margin: 0 0 10pt; }
  /* On screen this is a 170px date column beside the content. On paper that
     column is mostly empty and costs ~30% of the text width, so float the
     date onto the role line and let the bullets run the full measure. */
  .cv__item { display: block; padding: 8pt 0; }
  .cv__when { float: right; padding: 0; font-size: 9.5pt; }
  .cv__loc { margin-bottom: 5pt; }
  .cv__what li { font-size: 9.5pt; margin: 2.5pt 0; }
  .edu li { padding: 6pt 0; }

  /* never split an entry across a page boundary */
  .game, .cv__item, .quote, .edu li, .skills__group, .hons li { break-inside: avoid; }
  /* never strand a heading at the foot of a page, away from its content */
  .section__label, .section__title, .subhead { break-after: avoid; }
  .section__label { break-before: auto; }

  /* the reader can't click paper — spell out the destinations that matter.
     Deliberately not on .game__links: a URL after every card is noise. */
  .contact__links { gap: 4pt 18pt; font-size: 10pt; }
  .contact__links a[href^="http"]::after {
    content: " (" attr(href) ")"; font-weight: 400; font-size: 8.5pt; color: var(--text-dim);
  }
}
