/* ==================================================================
   João Vaz — home page
   Flat: a deep ground, a bold grotesque for display, hairline
   dividers instead of panels, and two colours on top of white and grey
   — blue carries the accents, orange is the second voice, used sparingly.
   A project page swaps --accent (and --accent-2 where its brand needs
   it); nothing else changes.
   The movement lives in a few places on purpose — the dot field in the
   hero, the photo reveal, the accordions and the playable trace.
   Every animated state is gated on `.js`, so the document renders
   finished when the scripts do not run.
   ================================================================== */

:root {
  --bg: #0c0e13;
  --surface: #151925;
  --ink: #f3f4f7;
  --dim: #a7adbb;
  --faint: #7b8396;
  --line: rgba(255, 255, 255, 0.09);
  --line-2: rgba(255, 255, 255, 0.2);
  /* the two colours, each with its lighter step. --accent is the main
     colour, --accent-soft its lighter step, and --accent-2 the second
     colour; --on is text on an accent fill. The recruiter view leads with
     blue, the curious view with orange. */
  --blue: #4d7cff;
  --blue-soft: #a9bcff;
  --orange: #ff7a3d;
  --orange-soft: #ffb08a;
  --accent: var(--blue);
  --accent-soft: var(--blue-soft);
  --accent-2: var(--orange);
  --on: #ffffff;
  --c: var(--accent);
  /* an accent as a fill behind --on text, and the second colour's pair.
     The blue fill is a step deeper than the blue, so white on it reads
     (4.6:1); text and lines in blue keep the brighter one */
  --blue-fill: #3268ff;
  --fill: var(--blue-fill);
  --fill-2: var(--orange);
  --on-2: #12151c;
  /* faint fills and the floating bars, derived from the theme's own
     colours so a theme only has to set the ones above */
  --tint: color-mix(in srgb, var(--ink) 4%, transparent);
  --tint-2: color-mix(in srgb, var(--ink) 8%, transparent);
  --glass: color-mix(in srgb, var(--bg) 84%, transparent);
  --glass-2: color-mix(in srgb, var(--surface) 94%, transparent);
  color-scheme: dark;
  --display: "Bricolage Grotesque", "Helvetica Neue", system-ui, sans-serif;
  --sans: "Geist", "Helvetica Neue", system-ui, sans-serif;
  --mono: "Geist Mono", "SF Mono", ui-monospace, monospace;
  --wrap: 1180px;
  --gut: clamp(20px, 5vw, 56px);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --wipe: cubic-bezier(0.7, 0, 0.2, 1);
}

/* the light theme: the same system on a warm paper ground. The accents
   step down so text in them still reads on white. The head script sets
   data-theme before the first paint — a saved choice, else the
   system's; without scripts the page stays dark. */
:root[data-theme="light"] {
  --bg: #f6f5f1;
  --surface: #ffffff;
  --ink: #12151c;
  --dim: #4b5262;
  --faint: #696f7c;
  --line: rgba(18, 21, 28, 0.1);
  --line-2: rgba(18, 21, 28, 0.24);
  --blue: #3461f0;
  --blue-soft: #2a4fd0;
  --orange: #ea5a12;
  --orange-soft: #c2470b;
  --blue-fill: #3461f0;
  /* orange text on paper needs the darker step */
  --accent-2: var(--orange-soft);
  color-scheme: light;
}
/* the curious view leads with orange (text on an orange fill is dark),
   and each view shows only its own parts (data-for). Print is always the
   recruiter CV, so both are for screens only */
@media screen {
  :root[data-mode="curious"] {
    --accent: var(--orange);
    --accent-soft: var(--orange-soft);
    --accent-2: var(--blue);
    --on: #12151c;
    --fill: var(--accent);
    --fill-2: var(--blue-fill);
    --on-2: #ffffff;
  }
  /* on paper the bright orange is too light for small text: the darker
     step leads, with white on it */
  :root[data-theme="light"][data-mode="curious"] {
    --accent: var(--orange-soft);
    --on: #ffffff;
  }
  :root[data-mode="curious"] [data-for="recruiter"],
  :root:not([data-mode="curious"]) [data-for="curious"] { display: none !important; }
}
@media print {
  [data-for="curious"] { display: none !important; }
}
/* a theme switch cross-fades the colours once, then lets go */
.theme-fade, .theme-fade *, .theme-fade *::before, .theme-fade *::after {
  transition: background-color 0.4s ease, color 0.4s ease, border-color 0.4s ease, fill 0.4s ease, stroke 0.4s ease !important;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { overflow-x: clip; scroll-padding-top: 72px; }
/* --c is re-read on the body, where a project page sets its own
   --accent; declared only on :root it would stay the home page's blue */
body {
  --c: var(--accent);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  background: var(--bg);
  color: var(--ink);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--fill); color: var(--on); }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; }
:focus-visible { outline: 1px solid var(--ink); outline-offset: 3px; }

.wrap { width: min(var(--wrap), 100% - 2 * var(--gut)); margin-inline: auto; }
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: fixed; top: 10px; left: 10px; z-index: 100;
  padding: 8px 14px; border-radius: 6px;
  background: var(--fill); color: var(--on); font-size: 14px;
  transform: translateY(-150%);
}
.skip:focus { transform: none; }

/* small uppercase label used for section numbers, captions, kickers */
.meta {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
}
/* the section number sits in a square of the section colour */
.meta b { display: inline-block; padding: 2px 6px; margin-right: 10px; border-radius: 4px; background: var(--fill); color: var(--on); font-weight: 500; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  padding: 0 20px;
  border-radius: 6px;
  font-size: 14.5px;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.12s var(--ease);
}
.btn:active { transform: scale(0.97); }
.btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.3s var(--ease); }
.btn--ink { background: var(--fill); color: var(--on); }
/* hover deepens the fill, so the text on it never loses contrast */
.btn--ink:hover { background: color-mix(in srgb, var(--fill) 86%, #000); }
.btn--line { border: 1px solid var(--line-2); }
.btn--line:hover { border-color: var(--accent); }
.btn--sm { height: 36px; padding: 0 14px; font-size: 13.5px; }
.btn.is-done { background: var(--ink); color: var(--bg); }

/* ---------- Top bar ---------- */
.bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  height: 64px;
  display: flex;
  align-items: center;
  gap: 32px;
  padding: 0 var(--gut);
  background: var(--glass);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.bar.is-scrolled { border-bottom-color: var(--line); }
/* the JV monogram and the name; the mark carries the full stop now */
.bar__name {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  line-height: 1;
  letter-spacing: -0.03em;
  white-space: nowrap;
}
.bar__mark { width: 30px; height: 30px; flex: 0 0 auto; transition: transform 0.4s var(--ease); }
.bar__dot { transform-box: fill-box; transform-origin: center; transition: transform 0.4s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .bar__name:hover .bar__mark { transform: rotate(-8deg); }
  .bar__name:hover .bar__dot { transform: scale(1.35); }
}
.bar__links { display: flex; gap: 28px; margin-left: auto; font-size: 14px; color: var(--dim); }
.bar__links a { position: relative; padding: 6px 0; transition: color 0.2s ease; }
.bar__links a::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--accent);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 0.4s var(--ease);
}
.bar__links a:hover, .bar__links a.is-active { color: var(--ink); }
.bar__links a.is-active::after { transform: none; }
.bar__end { display: flex; align-items: center; gap: 12px; }
.bar__icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 6px; color: var(--dim); transition: color 0.2s ease; }
.bar__icon:hover { color: var(--ink); }
.bar__icon svg { width: 16px; height: 16px; fill: currentColor; }
/* the reading position, as a hairline under the bar */
.bar__progress {
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--accent);
  transform: scaleX(var(--p, 0)); transform-origin: 0 50%;
}

/* ---------- Theme switch ---------- */
/* the icon is the theme you would switch to: a sun on dark, a moon on
   light; one turns out as the other turns in */
html:not(.js) .theme { display: none; }
.theme { position: relative; }
.theme svg {
  position: absolute;
  width: 17px; height: 17px;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  transition: transform 0.35s var(--ease), opacity 0.2s ease;
}
.theme__moon { opacity: 0; transform: rotate(-60deg) scale(0.6); }
:root[data-theme="light"] .theme__sun { opacity: 0; transform: rotate(60deg) scale(0.6); }
:root[data-theme="light"] .theme__moon { opacity: 1; transform: none; }
.theme:active svg { transform: scale(0.9); }

/* ---------- Section index (wide screens) ---------- */
.rail {
  position: fixed;
  left: 24px; top: 50%;
  z-index: 40;
  display: none;
  flex-direction: column;
  gap: 4px;
  transform: translateY(-50%);
}
.rail a {
  position: relative;
  display: grid;
  grid-template-columns: 22px 2px auto;
  align-items: center;
  column-gap: 10px;
  height: 34px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--faint);
  transition: color 0.2s ease;
}
.rail b { font-weight: 500; }
/* the line beside each number fills as its section is read */
.rail i { grid-column: 2; grid-row: 1; height: 100%; background: var(--line); position: relative; overflow: hidden; }
.rail i::after { content: ""; position: absolute; inset: 0; background: var(--c); transform: scaleY(var(--f, 0)); transform-origin: 50% 0; }
.rail span {
  grid-column: 3; grid-row: 1;
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  opacity: 0; transform: translateX(-6px);
  transition: opacity 0.25s ease, transform 0.35s var(--ease);
}
.rail a:hover, .rail a.is-active { color: var(--c); }
/* labels only on hover: at rest the index is just numbers and lines */
.rail:hover span { opacity: 1; transform: none; }
.rail.is-hidden { opacity: 0; pointer-events: none; }
.rail { transition: opacity 0.3s ease; }
@media (min-width: 1400px) { .rail { display: flex; } }

/* ---------- Dock (phones) ---------- */
.dock {
  position: fixed;
  left: 50%; bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 50;
  display: none;
  gap: 2px;
  padding: 5px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: var(--glass-2);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  transform: translateX(-50%);
  transition: transform 0.4s var(--ease), opacity 0.3s ease;
}
.dock a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 62px;
  padding: 7px 6px 6px;
  border-radius: 8px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--dim);
  transition: background-color 0.25s ease, color 0.25s ease;
}
.dock b { font-family: var(--mono); font-size: 9.5px; font-weight: 400; color: var(--faint); transition: color 0.25s ease; }
.dock a.is-active { background: var(--fill); color: var(--on); }
.dock a.is-active b { color: var(--on); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  padding: 120px 0 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.hero__field { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: end;
  gap: clamp(32px, 6vw, 96px);
}
.hero__copy { padding-bottom: 8px; }
/* the contact line is for paper only (see Print) */
.hero__print { display: none; }
.hero__name {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(76px, 12.4vw, 196px);
  line-height: 0.88;
  letter-spacing: -0.055em;
  margin: 22px 0 30px;
}
/* the J and the z descend well below the baseline: the mask is padded
   down to hold them, and the margin gives the space back */
.line { display: block; overflow: hidden; padding-bottom: 0.22em; margin-bottom: -0.16em; }
.line:nth-child(2) { padding-left: 0.42em; }
.name-dot { color: var(--accent); }
.hero__line {
  font-size: clamp(20px, 2.1vw, 27px);
  line-height: 1.35;
  letter-spacing: -0.01em;
  max-width: 22em;
  margin-bottom: 18px;
}
/* the two numbers, bold, each underlined in blue once the line lands */
.hero__line b { position: relative; font-weight: 600; white-space: nowrap; }
.hero__line b::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -0.06em;
  height: 0.1em; border-radius: 2px;
  background: var(--accent);
  transform-origin: 0 50%;
}
.js .hero__line b::after { transform: scaleX(0); }
.js .hero__line.is-in b::after { transform: none; transition: transform 0.8s var(--ease) 1.15s; }
.js .hero__line.is-in b:last-child::after { transition-delay: 1.4s; }
.hero__line b:last-child::after { background: var(--accent-2); }
.hero__pitch { max-width: 31em; color: var(--dim); font-size: 16.5px; margin-bottom: 34px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* a flat block of colour sits behind the photo, offset, and leans
   against the pointer (js/home.js writes --bx and --by) */
.hero__photo { position: relative; margin: 0; isolation: isolate; --off: 20px; }
.hero__photo::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  z-index: -1;
  aspect-ratio: 4 / 5;
  border-radius: 6px;
  background: var(--accent);
  transform: translate(calc(var(--off) + var(--bx, 0) * 1px), calc(var(--off) + var(--by, 0) * 1px));
  transition: transform 0.6s var(--ease);
}
/* a small orange square pinned to the photo's top corner; it leans the
   other way from the blue block */
.hero__photo::after {
  content: "";
  position: absolute; top: calc(var(--off) * -1.4); right: calc(var(--off) * -1.4);
  z-index: 2;
  width: clamp(44px, 5vw, 72px);
  aspect-ratio: 1;
  border-radius: 4px;
  background: var(--accent-2);
  transform: translate(calc(var(--bx, 0) * -0.6px), calc(var(--by, 0) * -0.6px));
  transition: transform 0.6s var(--ease);
}
.js .hero__photo::after { transform: scale(0.6); opacity: 0; }
.js .hero__photo.is-in::after {
  transform: translate(calc(var(--bx, 0) * -0.6px), calc(var(--by, 0) * -0.6px));
  opacity: 1;
  transition: transform 0.6s var(--ease) 1.3s, opacity 0.4s ease 1.3s;
}
.js .hero__photo.is-in.is-settled::after { transition: transform 0.6s var(--ease); }
.js .hero__photo::before { clip-path: inset(100% 0 0 0); }
.js .hero__photo.is-in::before { clip-path: inset(0 0 0 0); transition: clip-path 1.1s var(--wipe) 0.3s, transform 0.6s var(--ease); }
.hero__frame {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 6px;
  background: var(--surface);
}
.hero__frame img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 28%; will-change: transform; }
.hero__photo figcaption { margin-top: calc(var(--off) + 14px); font-size: 11px; }
/* the photo is wiped in from the bottom and settles from a slight zoom */
.js .hero__photo .hero__frame { clip-path: inset(100% 0 0 0); }
.js .hero__photo.is-in .hero__frame { clip-path: inset(0 0 0 0); transition: clip-path 1.3s var(--wipe) 0.5s; }
.js .hero__photo .hero__frame img { transform: scale(1.24); }
/* it settles at 1.1, not 1: the overscan is the room the scroll drift moves in */
.js .hero__photo.is-in .hero__frame img { transform: scale(1.1) translateY(var(--py, 0px)); transition: transform 1.8s var(--ease) 0.5s; }
.js .hero__photo.is-in.is-settled .hero__frame img { transition: none; }

/* six numbers in a strip under the hero */
.figures {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  margin-top: clamp(56px, 9vh, 96px);
}
.figures::before, .section::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 1px; background: var(--line);
  transform-origin: 0 50%;
}
.figures > div { padding: 22px 18px 26px; border-left: 1px solid var(--line); }
.figures > div:first-child { border-left: 0; padding-left: 0; }
.figures dt {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(34px, 3.4vw, 50px);
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 10px;
}
.figures dd { font-size: 13px; line-height: 1.45; color: var(--dim); }


/* ---------- Sections ---------- */
.section { position: relative; padding: clamp(72px, 11vh, 120px) 0; }
.head { margin-bottom: clamp(40px, 6vh, 64px); }
.head h2, .contact__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(38px, 5.4vw, 78px);
  line-height: 1.02;
  letter-spacing: -0.045em;
  max-width: 15em;
  margin-top: 18px;
}
.head h2 em, .contact__title em { font-style: normal; color: var(--c); }
.contact__title em { color: var(--accent-2); }
.head__intro { max-width: 40em; margin-top: 24px; font-size: 17px; color: var(--dim); }

/* ---------- Tags ---------- */
.tag {
  justify-self: end;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 4px 10px;
  border-radius: 999px;
  color: var(--dim);
  background: var(--tint-2);
}
/* tags stay grey; the open row's tag turns blue */
.is-open .tag { color: var(--accent-soft); background: color-mix(in srgb, var(--accent) 14%, transparent); }

/* ---------- Accordion ---------- */
.acc { border-top: 1px solid var(--line); }
.acc__item { position: relative; }
.acc__item::before, .contact__row::before {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 1px; background: var(--line);
  transform-origin: 0 50%;
}
/* a hairline of ink draws along the row under the pointer, and stays
   under the open one */
.acc__item::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--c);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 0.6s var(--ease);
}
.acc__item:hover::after, .acc__item.is-open::after { transform: none; }
.acc h3 { font: inherit; }
.acc__head {
  width: 100%;
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto 22px;
  align-items: center;
  gap: 20px;
  padding: 26px 0;
  text-align: left;
}
.acc__n { font-family: var(--mono); font-size: 12px; color: var(--faint); transition: color 0.25s ease; }
.acc__title {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(22px, 2.7vw, 36px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  transition: transform 0.5s var(--ease), color 0.25s ease;
}
.acc__title small {
  display: block;
  margin-top: 6px;
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0;
  color: var(--dim);
}
.acc__when { font-family: var(--mono); font-size: 12px; color: var(--faint); white-space: nowrap; }
.acc__head:hover .acc__n, .is-open .acc__n { color: var(--c); }
.is-open .acc__icon::before, .is-open .acc__icon::after { background: var(--c); }
/* a plus that turns into a minus */
.acc__icon { position: relative; width: 22px; height: 22px; }
.acc__icon::before, .acc__icon::after {
  content: "";
  position: absolute; left: 3px; right: 3px; top: 50%;
  height: 1.5px; margin-top: -0.75px;
  background: var(--ink);
  transition: transform 0.45s var(--ease);
}
.acc__icon::after { transform: rotate(90deg); }
.is-open .acc__icon::after { transform: rotate(0deg); }

.acc__panel { display: grid; grid-template-rows: 1fr; }
.js .acc__panel { transition: grid-template-rows 0.55s var(--ease); }
.js .acc__item:not(.is-open) .acc__panel { grid-template-rows: 0fr; }
.acc__body { min-height: 0; overflow: hidden; padding-left: 92px; }
.acc__body > :last-child { margin-bottom: 34px; }
.js .acc__body > * { opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.5s var(--ease); }
.js .is-open .acc__body > * { opacity: 1; transform: none; transition-delay: 0.12s; }
.acc__body p { max-width: 44em; font-size: 16.5px; color: var(--dim); }
.keys { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.keys li {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  padding: 4px 9px;
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--dim);
}
.acc--roles .acc__head { grid-template-columns: 72px minmax(0, 1fr) auto 22px; }
/* ---------- Roles: outcomes and deliveries ---------- */
/* a role opens into two columns: what changed, as numbers in the
   accent, and what shipped, one line each in the second colour */
.role__sum { max-width: 44em; font-size: 16px; color: var(--dim); margin-bottom: 22px; }
.role {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: start;
}
.role__k {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}
.role__k::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
.role__col--ships .role__k { color: var(--accent-2); }
/* the outcome tiles share hairlines: the gap shows the frame's colour */
.wins {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--line);
  overflow: hidden;
}
.wins > div { padding: 16px 16px 18px; background: var(--bg); }
.wins > div:only-child, .wins > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
.wins dt {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(30px, 3vw, 42px);
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  margin-bottom: 8px;
}
.wins dd { font-size: 13px; line-height: 1.4; color: var(--dim); }
.ships li {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr);
  column-gap: 10px;
  padding: 13px 0 14px;
  border-top: 1px solid var(--line);
}
.ships li:first-child { border-top: 0; padding-top: 2px; }
.ships li::before {
  content: "";
  grid-row: 1 / 3;
  width: 8px; height: 8px;
  margin-top: 7px;
  border-radius: 2px;
  background: var(--accent-2);
}
.ships b { font-weight: 600; font-size: 15.5px; line-height: 1.35; color: var(--ink); }
.ships span { grid-column: 2; margin-top: 3px; font-size: 14px; line-height: 1.5; color: var(--dim); }
/* the tiles and the lines land one after another as a role opens */
.js .acc__item :is(.wins > div, .ships li) { opacity: 0; transform: translateY(8px); transition: opacity 0.35s ease, transform 0.5s var(--ease); }
.js .acc__item.is-open :is(.wins > div, .ships li) { opacity: 1; transform: none; }
.js .is-open :is(.wins > div, .ships li):nth-child(1) { transition-delay: 0.14s; }
.js .is-open :is(.wins > div, .ships li):nth-child(2) { transition-delay: 0.2s; }
.js .is-open :is(.wins > div, .ships li):nth-child(3) { transition-delay: 0.26s; }
.js .is-open :is(.wins > div, .ships li):nth-child(4) { transition-delay: 0.32s; }
.js .is-open :is(.wins > div, .ships li):nth-child(5) { transition-delay: 0.38s; }
.js .is-open :is(.wins > div, .ships li):nth-child(6) { transition-delay: 0.44s; }
.photos {
  display: grid;
  grid-template-columns: 1.3fr 0.8fr 1.3fr;
  gap: 8px;
  margin-top: 22px;
}
.photos img { width: 100%; height: clamp(150px, 19vw, 250px); object-fit: cover; border-radius: 4px; }
.photos img:nth-child(2) { object-position: 50% 20%; }

/* ---------- Toolkit ---------- */
/* skills in groups, each skill a tag, on the same hairline grid as the
   outcome tiles; agentic AI leads, wide and in the accent */
.kit { margin-top: clamp(56px, 8vh, 84px); }
.kit__title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}
.kit__title::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
.kit__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--line);
  overflow: hidden;
}
.kit__group { padding: 20px 20px 22px; background: var(--bg); }
.kit__group--lead { grid-column: 1 / -1; background: color-mix(in srgb, var(--accent) 6%, var(--bg)); }
.kit__group h4 {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: 12px;
}
.tags { display: flex; flex-wrap: wrap; gap: 6px; }
.tags li {
  padding: 5px 11px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  font-size: 13px;
  line-height: 1.4;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.kit__group--lead .tags li {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent-soft);
}
@media (hover: hover) and (pointer: fine) {
  .tags li:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
}
/* each group's tags land one after another as it arrives */
.js .kit__group.rv .tags li { opacity: 0; transform: translateY(6px); }
.js .kit__group.rv.is-in .tags li {
  opacity: 1;
  transform: none;
  transition: opacity 0.35s ease, transform 0.5s var(--ease), border-color 0.2s ease, background-color 0.2s ease;
  transition-delay: calc(var(--t, 0) * 35ms + 150ms), calc(var(--t, 0) * 35ms + 150ms), 0s, 0s;
}
/* education and languages: two plain facts under the grid */
.kit__cv { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 12px; }
.kit__cv > div { display: grid; gap: 8px; align-content: start; padding: 16px 20px 18px; border: 1px solid var(--line); border-radius: 10px; }
.kit__cv dt { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--faint); }
.kit__cv dd { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.kit__cv b { font-size: 15.5px; font-weight: 600; }
.kit__cv span { font-size: 13.5px; color: var(--dim); }

.concepts > div { position: relative; }
.concepts > div::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 1px; background: var(--line);
  transform-origin: 0 50%;
}

/* ---------- AI: the playable trace ---------- */
.ai {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.trace {
  position: sticky;
  top: 96px;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  font-family: var(--mono);
  overflow: hidden;
}
.trace__chrome {
  display: flex; align-items: center; gap: 6px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  font-size: 11px; color: var(--faint);
}
.trace__chrome i { width: 9px; height: 9px; border-radius: 50%; background: var(--line-2); }
.trace__chrome span { margin-left: 10px; }
.trace__asks { display: flex; flex-wrap: wrap; gap: 6px; padding: 14px 16px 0; }
.trace__asks button {
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.trace__asks button:hover { border-color: var(--line-2); color: var(--ink); }
.trace__asks button[aria-selected="true"] { background: var(--fill); border-color: var(--fill); color: var(--on); }
.trace__run { padding: 20px 18px 6px; min-height: 388px; }
.trace__q, .trace__a { font-family: var(--sans); }
.trace__q { font-family: var(--display); font-weight: 600; font-size: 21px; line-height: 1.25; letter-spacing: -0.02em; margin-bottom: 10px; }
.trace__q span, .trace__a span {
  display: block;
  margin-bottom: 4px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}
.trace__spans li {
  position: relative;
  display: flex; justify-content: space-between; gap: 12px;
  padding: 9px 0 13px;
  font-size: 12px;
  color: var(--dim);
  border-bottom: 1px dashed var(--line);
}
.trace__spans em { font-style: normal; color: var(--faint); flex: 0 0 auto; }
/* each span's bar on a shared 0–100 timeline */
.trace__spans li::after {
  content: "";
  position: absolute;
  left: calc(var(--s) * 1%); bottom: 4px;
  width: calc(var(--w) * 1%); min-width: 6px;
  height: 3px; border-radius: 2px;
  background: var(--accent);
  transform-origin: 0 50%;
}
.trace__spans .is-tool::after { background: var(--accent-soft); }
.trace__spans .is-check::after { background: var(--ink); }
.trace__spans .is-check span { color: var(--ink); }
.trace__spans .is-human::after { background: var(--accent-2); }
.trace__spans .is-human span { color: var(--accent-2); }
.trace__spans .is-stop::after { background: var(--accent-2); }
.trace__spans .is-stop span { color: var(--accent-2); }
.trace__a {
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 6px;
  background: var(--tint);
  font-size: 14.5px;
  line-height: 1.55;
}
.trace__a span { color: var(--accent-soft); }
.trace__evals { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.trace__evals li {
  font-size: 11px;
  padding: 4px 9px;
  border-radius: 999px;
  color: var(--accent-soft);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.trace__evals li::before { content: "✓ "; }
.trace figcaption {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 16px;
  padding: 12px 18px 16px;
  font-size: 11px; color: var(--faint);
}
.trace__again { font-family: var(--mono); font-size: 11.5px; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.trace__again[hidden] { display: none; }
/* the run plays step by step: js/home.js adds .on to each part in turn */
.js .trace .st { opacity: 0; transform: translateY(6px); transition: opacity 0.4s ease, transform 0.5s var(--ease); }
.js .trace .st.on { opacity: 1; transform: none; }
.js .trace__spans li.st::after { transform: scaleX(0); transition: transform 0.7s var(--ease) 0.1s; }
.js .trace__spans li.st.on::after { transform: none; }

.concepts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
.concepts > div { position: relative; padding: 18px 0 22px; }
.concepts dt { font-family: var(--display); font-weight: 600; font-size: 19px; line-height: 1.2; letter-spacing: -0.02em; margin-bottom: 8px; }
.concepts dt::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 10px; border-radius: 2px; background: var(--c); vertical-align: 0.1em; }
.concepts dd { font-size: 14px; line-height: 1.55; color: var(--dim); }

/* ---------- Projects ---------- */
/* flat cards that invert to ink under the pointer */
.projects { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.project {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 250px;
  padding: 28px 28px 26px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.35s ease, border-color 0.35s ease;
}
.project::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: var(--pc, var(--fill));
  clip-path: inset(100% 0 0 0);
  transition: clip-path 0.55s var(--wipe);
}
.project:hover { color: var(--pc-on, var(--on)); border-color: var(--pc, var(--fill)); }
/* blue and orange in a checkerboard */
.project:nth-child(2), .project:nth-child(3) { --pc: var(--fill-2); --pc-on: var(--on-2); }
.project:hover::before { clip-path: inset(0 0 0 0); }
.project h3 { font-family: var(--display); font-weight: 700; font-size: clamp(30px, 3vw, 40px); line-height: 1; letter-spacing: -0.04em; margin: 28px 0 12px; }
.project p { color: var(--dim); font-size: 15px; max-width: 30em; transition: color 0.35s ease; }
.project:hover p, .project:hover .meta { color: color-mix(in srgb, var(--on) 82%, transparent); }
.project .meta { transition: color 0.35s ease; }
.project__go { margin-top: auto; padding-top: 28px; font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; }
.project__go i { display: inline-block; font-style: normal; transition: transform 0.4s var(--ease); }

/* ---------- Contact ---------- */
.section--contact { padding-bottom: 96px; }
.contact__title { font-weight: 800; font-size: clamp(48px, 8.4vw, 128px); line-height: 0.95; letter-spacing: -0.055em; max-width: 10em; margin-bottom: clamp(40px, 7vh, 72px); }
.contact__rows { border-top: 1px solid var(--line); }
.contact__row {
  position: relative;
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px;
  padding: 24px 0;
}
.contact__row strong { font-family: var(--display); font-weight: 600; font-size: clamp(24px, 3vw, 40px); letter-spacing: -0.03em; line-height: 1.1; overflow-wrap: anywhere; transition: transform 0.5s var(--ease); }
.contact__row i { font-style: normal; font-size: 22px; transition: transform 0.4s var(--ease); }
.contact__row:hover strong { color: var(--c); }
.contact__row::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--c);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 0.6s var(--ease);
}
.contact__row:hover::after { transform: none; }

.foot {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
  padding: 28px 0 40px;
  border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 12px; color: var(--faint);
}

/* ==================================================================
   Reveals — the finished state is the default. Only `.js` hides
   anything, and js/home.js puts it back as the reading position
   arrives, with a three-second failsafe behind it.
   ================================================================== */
.js .rv { opacity: 0; transform: translateY(14px); }
.js .rv.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s ease, transform 0.9s var(--ease);
  /* a run of siblings lands 70ms apart; the hero sets its own --delay */
  transition-delay: var(--delay, calc(var(--i, 0) * 70ms));
}
/* the photo has its own wipe; it must not also slide */
.js .hero__photo.rv { transform: none; opacity: 1; }
/* the name rises letter by letter out of its line */
.ch { display: inline-block; white-space: pre; }
.js [data-split] .ch, .js .name-dot { transform: translateY(135%); }
.js .is-lit .ch { animation: rise 1s var(--ease) both; animation-delay: calc(var(--d, 0) * 45ms + 250ms); }
@keyframes rise { from { transform: translateY(135%); } to { transform: none; } }

/* ==================================================================
   Motion
   One pass on arrival, then everything waits for the reading position.
   Curves: --ease (a strong ease-out) for anything entering, --wipe (an
   ease-in-out) for things crossing the screen, linear for the strip.
   ================================================================== */

/* the load sequence: the bar drops in, the label, the name letter by
   letter, the line, the pitch, the buttons; the colour block, then the
   photo; then the figures, left to right */
.js .bar { animation: barIn 0.8s var(--ease) 0.05s both; }
@keyframes barIn { from { transform: translateY(-100%); } to { transform: none; } }
.hero .meta.rv { --delay: 0.15s; }
.hero__line.rv { --delay: 0.75s; }
.hero__pitch.rv { --delay: 0.85s; }
.hero__actions.rv { --delay: 0.95s; }
.figures > .rv { --delay: calc(1.1s + var(--i, 0) * 70ms); }

/* headings rise word by word out of their own masks (js/home.js wraps
   each word); the heading itself does not fade */
.js .rv.h-split { opacity: 1; transform: none; }
.w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.w > span { display: inline-block; }
.js .h-split .w > span { transform: translateY(115%); }
.js .h-split.is-in .w > span { transform: none; transition: transform 0.9s var(--ease); transition-delay: calc(var(--wi, 0) * 45ms + 60ms); }

/* dividers draw from the left as their row arrives */
.js :is(.acc__item, .contact__row, .concepts > div).rv::before { transform: scaleX(0); }
.js :is(.acc__item, .contact__row, .concepts > div).rv.is-in::before {
  transform: none;
  transition: transform 1s var(--ease) calc(var(--i, 0) * 70ms + 100ms);
}
.js .section::before, .js .figures::before { transform: scaleX(0); transition: transform 1.2s var(--wipe); }
.js .section:has(.is-in)::before, .js .figures:has(.is-in)::before { transform: none; }

/* small moves under a mouse only: a tap would leave them stuck */
@media (hover: hover) and (pointer: fine) {
  .btn:hover svg { transform: translateX(3px); }
  .acc__head:hover .acc__title { transform: translateX(10px); }
  .project:hover .project__go i { transform: translateX(6px); }
  .contact__row:hover strong { transform: translateX(10px); }
  .contact__row:hover i { transform: translateX(6px); }
}

/* ---------- The strip ---------- */
/* one band of big type between the hero and the work; js/home.js runs
   it sideways and speeds it up with the scroll */
.strip {
  position: relative;
  overflow: hidden;
  padding: clamp(18px, 3vh, 30px) 0;
  border-top: 1px solid var(--line);
  user-select: none;
}
.strip__track {
  display: flex;
  align-items: center;
  width: max-content;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(44px, 7vw, 108px);
  line-height: 1;
  letter-spacing: -0.045em;
  white-space: nowrap;
  will-change: transform;
}
/* items carry their own trailing space, so one set is exactly half the
   track and the loop has no seam */
.strip__track > * { margin-right: 0.36em; }
.strip__track span:nth-of-type(even) { color: transparent; -webkit-text-stroke: 1.5px var(--faint); }
.strip__track b { font-weight: 800; font-size: 0.6em; color: var(--accent-2); }

/* ---------- Easter eggs ---------- */
/* the note a find shows: a small flat card, bottom left, above the dock */
.toast {
  position: fixed;
  left: 20px; bottom: 20px;
  z-index: 80;
  max-width: min(360px, calc(100vw - 40px));
  padding: 14px 16px 15px;
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--accent-2);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 12px 32px -16px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.35s var(--ease);
}
.toast.is-on { opacity: 1; transform: none; }
.toast span { display: block; margin-bottom: 4px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent-2); }
.toast p { font-size: 14px; line-height: 1.45; }
.confetti { position: fixed; inset: 0; z-index: 85; width: 100vw; height: 100vh; pointer-events: none; }
/* the footer's count, shown only after the first find */
.eggs b { color: var(--accent-2); font-weight: 500; }
.eggs[hidden] { display: none; }
/* five clicks: the mark turns once and the dot pops */
.bar__name.is-spun .bar__mark { animation: markSpin 0.9s var(--ease); }
.bar__name.is-spun .bar__dot { animation: dotPop 0.9s var(--ease); }
@keyframes markSpin { from { transform: rotate(0deg) scale(1); } 45% { transform: rotate(200deg) scale(1.15); } to { transform: rotate(360deg) scale(1); } }
@keyframes dotPop { 0%, 40% { transform: scale(1); } 70% { transform: scale(1.9); } to { transform: scale(1); } }

/* ==================================================================
   Side quests — the personal side, full screen. The same system with a
   little more play: a loading bar, a player card, quest cards with a
   status, and a photo log waiting for its photos.
   ================================================================== */
html:has(.quests[open]) { overflow: hidden; }
.quests {
  position: fixed;
  inset: 0;
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  margin: 0; padding: 0;
  border: 0;
  background: var(--bg);
  color: var(--ink);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.quests::backdrop { background: var(--bg); }
.quests__inner { padding: clamp(24px, 5vh, 48px) 0 80px; }
.quests__top { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-bottom: 26px; }
.quests__top kbd {
  margin-left: 8px; padding: 1px 6px;
  border: 1px solid var(--line-2); border-radius: 4px;
  font-family: var(--mono); font-size: 10.5px; color: var(--dim);
}
.quests__title {
  max-width: 14em;
  margin-bottom: 32px;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(40px, 6vw, 84px);
  line-height: 1;
  letter-spacing: -0.05em;
}
.quests__title em { font-style: normal; color: var(--accent-2); }

/* the player card */
.player {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: 24px;
  align-items: center;
  margin-bottom: 16px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
}
.player__img { width: 132px; height: 132px; object-fit: cover; object-position: 50% 20%; border-radius: 8px; }
.player h3 { margin: 4px 0 10px; font-family: var(--display); font-weight: 700; font-size: 30px; letter-spacing: -0.04em; }
.player__class { display: grid; gap: 4px; margin-bottom: 14px; }
.player__class div { display: flex; gap: 10px; font-size: 14px; }
.player__class dt { min-width: 110px; padding-top: 2px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); }
.player__stats { display: flex; flex-wrap: wrap; gap: 8px; }
.player__stats li { padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font-size: 13px; }
.player__stats b { color: var(--accent); font-weight: 700; }

/* the quests, numbered Q01 to Q09 on the hairline grid */
.quests__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--line);
  overflow: hidden;
  counter-reset: q;
}
.quest { position: relative; padding: 20px 20px 34px; background: var(--bg); counter-increment: q; transition: background-color 0.25s ease; }
.quest::after { content: "Q" counter(q, decimal-leading-zero); position: absolute; right: 18px; bottom: 14px; font-family: var(--mono); font-size: 10.5px; color: var(--faint); }
.quest__top { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 18px; }
.quest__ic { width: 30px; height: 30px; fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.4s var(--ease); }
.quest__status {
  padding: 3px 9px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}
.quest--daily .quest__status { border-color: var(--accent); color: var(--accent); }
.quest--new .quest__status { border-color: var(--accent-2); color: var(--accent-2); }
/* a quest with a photo of me doing it: a small frame in the corner, the
   photo large on a click */
.quest__shot {
  position: absolute; right: 20px; top: 62px;
  width: 56px; height: 70px;
  overflow: hidden;
  border-radius: 6px;
  box-shadow: 0 0 0 1px var(--line);
  cursor: zoom-in;
}
.quest__shot img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; transition: transform 0.5s var(--ease); }
.quest__shot:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.quest:has(.quest__shot) :is(h4, p) { margin-right: 68px; }
.quest h4 { margin-bottom: 6px; font-family: var(--display); font-weight: 600; font-size: 20px; letter-spacing: -0.02em; }
.quest p { max-width: 26em; font-size: 14px; line-height: 1.5; color: var(--dim); }
.quest a { color: var(--accent); }
@media (hover: hover) and (pointer: fine) {
  .quest:hover { background: var(--tint); }
  .quest:hover .quest__ic { transform: rotate(-8deg) scale(1.08); }
  .quest__shot:hover img { transform: scale(1.08); }
}

/* the photo log: each album a reel that slides sideways */
.photolog { margin-top: 40px; }
.photolog__row { margin-top: 22px; }
.photolog__head { display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; margin-bottom: 12px; }
.photolog__row h4 { font-family: var(--display); font-weight: 600; font-size: 17px; }
.photolog__row h4 span { margin-left: 8px; font-family: var(--sans); font-weight: 400; font-size: 13px; color: var(--faint); }
.reel__nav { display: none; flex: 0 0 auto; align-items: center; gap: 6px; }
.js .reel__nav { display: flex; }
.reel__count { margin-right: 6px; white-space: nowrap; }
.reel__nav .btn { width: 36px; padding: 0; justify-content: center; }
.reel__nav .btn:disabled { opacity: 0.35; cursor: default; }
.reel__nav .btn:disabled:hover { border-color: var(--line-2); }
@media (hover: none) { .reel__nav .btn { display: none; } }
/* the reel: one row of photos at one height, each as wide as its own
   shape, snapping to the photo at the left edge. It fades out on the
   side where more photos wait */
.reel {
  --fl: 0px;
  --fr: 0px;
  display: flex;
  gap: 10px;
  height: clamp(260px, 46vh, 440px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fl), #000 calc(100% - var(--fr)), transparent);
  mask-image: linear-gradient(to right, transparent, #000 var(--fl), #000 calc(100% - var(--fr)), transparent);
}
.reel::-webkit-scrollbar { display: none; }
.has-before > .reel { --fl: 48px; }
.has-after > .reel { --fr: 48px; }
.reel__line { display: none; position: relative; height: 2px; margin-top: 12px; overflow: hidden; border-radius: 1px; background: var(--line); }
.js .reel__line { display: block; }
.reel__line b { position: absolute; inset: 0; background: var(--accent); transform: scaleX(var(--p, 0)); transform-origin: 0 50%; transition: transform 0.5s var(--ease); }
.reel__shot {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  overflow: hidden;
  border-radius: 10px;
  background: var(--surface);
  cursor: zoom-in;
  scroll-snap-align: start;
}
.reel__shot img { display: block; width: auto; height: 100%; transition: transform 0.6s var(--ease); }
.reel__shot::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--line);
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .reel__shot:hover img { transform: scale(1.04); }
}
.reel__shot:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* the viewer: one album as a full-screen carousel, a filmstrip under it */
.lightbox {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  margin: 0; padding: 0;
  border: 0;
  background: #08090c;
  color: #f3f4f7;
}
.lightbox[open] { display: grid; grid-template-rows: minmax(0, 1fr) auto auto; }
.lightbox::backdrop { background: transparent; }
.lightbox__track {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.lightbox__track::-webkit-scrollbar { display: none; }
.lightbox__slide {
  flex: 0 0 100%;
  display: grid;
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  place-items: center;
  margin: 0;
  padding: 28px 28px 12px;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}
.lightbox__slide img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; }
.lightbox__film { display: flex; gap: 6px; padding: 6px 24px; overflow-x: auto; scrollbar-width: none; }
.lightbox__film::-webkit-scrollbar { display: none; }
.lightbox__film:empty { display: none; }
/* the filmstrip sits centred while it fits and scrolls once it does not */
.lightbox__thumb:first-child { margin-left: auto; }
.lightbox__thumb:last-child { margin-right: auto; }
.lightbox__thumb {
  flex: 0 0 auto;
  width: 42px; height: 54px;
  overflow: hidden;
  border-radius: 5px;
  opacity: 0.4;
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: opacity 0.2s ease, outline-color 0.2s ease;
}
.lightbox__thumb img { width: 100%; height: 100%; object-fit: cover; }
.lightbox__thumb:hover { opacity: 0.8; }
.lightbox__thumb.is-on { opacity: 1; outline-color: var(--accent); }
.lightbox__bar {
  display: flex; justify-content: center; align-items: center; gap: 10px;
  padding: 10px 16px max(18px, env(safe-area-inset-bottom));
}
.lightbox__bar .btn { color: #f3f4f7; border-color: rgba(255, 255, 255, 0.25); }
.lightbox__bar .meta { min-width: 60px; text-align: center; color: rgba(255, 255, 255, 0.6); }
.lightbox__bar kbd { margin-left: 6px; font-family: var(--mono); font-size: 10.5px; color: rgba(255, 255, 255, 0.6); }
.lightbox[open] .lightbox__track { animation: lbIn 0.35s var(--ease); }
.lightbox.is-single :is([data-lb-prev], [data-lb-next], [data-lb-count]) { display: none; }
@keyframes lbIn { from { opacity: 0; transform: scale(0.97); } to { opacity: 1; transform: none; } }

/* opening plays a short loading bar, then everything lands in a run */
.quests__load {
  position: fixed; inset: 0; z-index: 3;
  display: grid; place-content: center; justify-items: center; gap: 14px;
  background: var(--bg);
  opacity: 0;
  pointer-events: none;
}
.quests__load span { font-family: var(--mono); font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--dim); }
.quests__load i { position: relative; display: block; width: 220px; height: 4px; overflow: hidden; border-radius: 2px; background: var(--line); }
.quests__load i::after { content: ""; position: absolute; inset: 0; background: var(--accent); transform: scaleX(0); transform-origin: 0 50%; }
.quests.is-playing .quests__load { animation: loadFade 1.1s ease both; }
.quests.is-playing .quests__load i::after { animation: loadBar 0.75s var(--ease) both; }
@keyframes loadFade { 0%, 72% { opacity: 1; } 100% { opacity: 0; } }
@keyframes loadBar { from { transform: scaleX(0); } to { transform: none; } }
.quests.is-playing :is(.quests__title, .player, .quest, .photolog) { animation: questIn 0.6s var(--ease) both; }
.quests.is-playing .quests__title { animation-delay: 0.8s; }
.quests.is-playing .player { animation-delay: 0.88s; }
.quests.is-playing .quest { animation-delay: calc(0.95s + var(--q, 0) * 50ms); }
.quests.is-playing .photolog { animation-delay: 1.45s; }
@keyframes questIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* a way in from the contact section */
.offclock { margin-top: 28px; font-size: 15px; color: var(--dim); }
.offclock button { color: var(--accent-2); font-weight: 600; }
.offclock button:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- The recruiter's tools ---------- */
/* for a recruiter with one question (js/recruiter.js): the skill finder,
   quick answers in Contact, and a link to each role and product */
.bar__find svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
/* the way in under the hero's buttons; it needs the script */
.hero__more { display: none; margin-top: 18px; font-size: 14.5px; color: var(--dim); }
.js .hero__more { display: block; }
.hero__more.rv { --delay: 1.05s; }
.hero__more :is(button, a) { color: var(--accent); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.hero__more :is(button, a):hover { text-decoration-thickness: 2px; }

/* the finder: a wider panel, skills as chips, then the places */
.finder__intro { margin: -4px 0 16px; font-size: 14.5px; color: var(--dim); }
.finder__skills { display: flex; flex-wrap: wrap; gap: 6px; }
.finder__skill {
  padding: 6px 12px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  font-size: 13.5px;
  line-height: 1.4;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.finder__skill:hover { border-color: var(--accent); }
.finder__skill[aria-pressed="true"] { border-color: var(--fill); background: var(--fill); color: var(--on); }
.finder__paste { display: grid; gap: 8px; margin-top: 18px; }
.finder__paste .meta { font-size: 11px; }
.finder__paste textarea {
  width: 100%;
  min-height: 76px;
  resize: vertical;
  padding: 10px 12px;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  line-height: 1.5;
}
.finder__paste textarea::placeholder { color: var(--faint); }
.finder__paste textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.finder__sum { min-height: 1.5em; margin: 16px 0 8px; font-size: 14px; color: var(--dim); }
.finder__sum a { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.finder__list li { border-top: 1px solid var(--line); }
.finder__hit { display: grid; gap: 3px; margin: 0 -8px; padding: 11px 8px 12px; border-radius: 6px; transition: background-color 0.2s ease; }
.finder__hit:hover { background: var(--tint-2); }
.finder__hit .meta { font-size: 10.5px; }
.finder__hit b { font-size: 14.5px; font-weight: 600; line-height: 1.35; }
.finder__line {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.45;
  color: var(--dim);
}
.finder__hit i { font-style: normal; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.04em; color: var(--accent-soft); }
.finder__note { margin-top: 14px; font-size: 12px; color: var(--faint); }

/* the part the finder or a link points at, marked for a moment */
.is-found { animation: found 2.6s ease; }
:is(li, p, .concepts > div).is-found { border-radius: 6px; }
/* the mark reaches 8px past a part; an accordion's body clips, so it
   keeps that much room on its right, outside its content */
.acc__body { padding-right: 10px; margin-right: -10px; }
@keyframes found {
  from, 60% {
    background-color: color-mix(in srgb, var(--accent) 14%, var(--bg));
    box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 14%, var(--bg));
  }
}

/* "copy a link" at the foot of an open role or product */
.acc__body .share { display: flex; justify-content: flex-end; max-width: none; margin-top: 10px; }
.share button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  transition: color 0.2s ease;
}
.share button:hover { color: var(--accent-soft); }
.share svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* quick answers: plain facts on hairlines, three to a row */
.answers { margin-top: clamp(48px, 7vh, 72px); }
.answers__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 32px; }
.answers__grid > div { display: grid; gap: 4px; align-content: start; padding: 14px 0 18px; border-top: 1px solid var(--line); }
.answers__grid dt { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--faint); }
.answers__grid dd { font-size: 15.5px; font-weight: 600; line-height: 1.4; }
/* a placeholder answer: hidden on the live site, marked on a local
   preview so it is plain what is still to fill in */
.answers__grid > [data-todo] { display: none; }
.is-preview .answers__grid > [data-todo] { display: grid; }
.is-preview [data-todo] dd { justify-self: start; padding: 1px 8px; border: 1px dashed var(--accent-2); border-radius: 4px; font-weight: 400; color: var(--dim); }
.is-preview [data-todo] dd::before { content: "To fill · "; font-family: var(--mono); font-size: 11px; color: var(--accent-2); }

/* ---------- Responsive ---------- */
/* ==================================================================
   The two views — recruiter and curious
   ================================================================== */
/* the switch over the hero shows both views, the current one under a
   thumb in that view's colour. The other one slides the thumb across and
   the page wipes into that view; the question never asks again. data-on
   says where the thumb is (js/home.js sets it from the view) */
.mode-switch {
  --thumb: var(--blue-fill);
  --thumb-on: #ffffff;
  display: none;
  align-items: center;
  gap: 14px;
  margin-bottom: 26px;
}
.mode-switch[data-on="curious"] { --thumb: var(--orange); --thumb-on: #12151c; }
:root[data-theme="light"] .mode-switch[data-on="curious"] { --thumb: var(--orange-soft); --thumb-on: #ffffff; }
.js .mode-switch { display: flex; }
.hero .mode-switch.rv { --delay: 0.05s; }
.mode-switch__label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
}
.mode-switch__track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 4px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--glass-2);
}
.mode-switch__thumb {
  position: absolute;
  top: 4px; bottom: 4px; left: 4px;
  width: calc(50% - 4px);
  border-radius: 999px;
  background: var(--thumb);
  box-shadow: 0 8px 22px -8px var(--thumb);
  transition: transform 0.5s var(--ease), background-color 0.35s ease, box-shadow 0.35s ease;
}
.mode-switch[data-on="curious"] .mode-switch__thumb { transform: translateX(100%); }
.mode-switch a {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 20px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--dim);
  transition: color 0.3s ease;
}
.mode-switch svg { width: 17px; height: 17px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mode-switch[data-on="recruiter"] [data-mode-switch="recruiter"],
.mode-switch[data-on="curious"] [data-mode-switch="curious"] { color: var(--thumb-on); cursor: default; }
/* the other view leans the thumb towards it */
.mode-switch:not([data-going]) a:not([aria-current]):hover { color: var(--ink); }
.mode-switch[data-on="recruiter"]:not([data-going]):has([data-mode-switch="curious"]:hover) .mode-switch__thumb { transform: translateX(8px); }
.mode-switch[data-on="curious"]:not([data-going]):has([data-mode-switch="recruiter"]:hover) .mode-switch__thumb { transform: translateX(calc(100% - 8px)); }
.mode-switch a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* then the screen wipes up with an edge in the new view's colour, as the
   question's does, and the page starts over in that view */
.mode-wipe {
  position: fixed; inset: 0;
  z-index: 200;
  pointer-events: none;
  background: var(--bg);
  box-shadow: 0 -6px 0 var(--blue);
  transform: translateY(105%);
  transition: transform 0.42s var(--wipe);
}
.mode-wipe[data-to="curious"] { box-shadow: 0 -6px 0 var(--orange); }
.mode-wipe.is-on { transform: none; }
.foot__mode { display: none; color: var(--dim); text-decoration: underline; text-underline-offset: 3px; }
.js .foot__mode { display: inline; }
.foot__mode:hover { color: var(--ink); }

/* the curious view's side quests sit on the page */
.quests-inline .player { margin-bottom: 16px; }
.figures--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: clamp(32px, 5vh, 48px); }
.dayjob__cta { margin-top: 36px; }

/* ==================================================================
   The game — the curious view only (js/game.js). Quiet on purpose:
   the controller in the bar is the one thing that stays on screen
   ================================================================== */
/* once there is any XP, the controller carries the level and a small
   XP bar */
.xp { position: relative; }
.xp__lv, .xp__bar { display: none; }
.xp.has-xp .xp__lv {
  display: block;
  position: absolute; top: 2px; right: 0;
  min-width: 15px; height: 15px; padding: 0 4px;
  border-radius: 8px;
  background: var(--fill);
  color: var(--on);
  font: 600 9.5px/15px var(--mono);
  text-align: center;
}
.xp.has-xp .xp__bar {
  display: block;
  position: absolute; left: 9px; right: 9px; bottom: 4px;
  height: 2px; border-radius: 1px;
  background: var(--line-2);
  overflow: hidden;
}
.xp__bar i { display: block; height: 100%; background: var(--accent); transform: scaleX(var(--xp, 0)); transform-origin: 0 50%; transition: transform 0.6s var(--ease); }

/* the quest log and the puzzle: small panels over a dimmed page */
.qlog, .chess, .finder {
  width: min(440px, 100vw - 24px);
  max-height: calc(100dvh - 24px);
  margin: auto;
  padding: 20px 22px 18px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.6);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.qlog::backdrop, .chess::backdrop, .finder::backdrop { background: color-mix(in srgb, var(--bg) 60%, transparent); }
.qlog[open], .chess[open], .finder[open] { animation: panelIn 0.35s var(--ease); }
@keyframes panelIn { from { opacity: 0; transform: translateY(-8px) scale(0.98); } }
.qlog__head, .chess__head, .finder__head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 16px; }
.qlog__head kbd, .chess__head kbd, .finder__head kbd { margin-left: 6px; font-family: var(--mono); font-size: 10.5px; color: var(--faint); }
.qlog__title, .chess__title, .finder__title { margin-bottom: 14px; font-family: var(--display); font-weight: 700; font-size: 28px; line-height: 1.1; letter-spacing: -0.03em; }
.qlog__title em, .chess__title em, .finder__title em { font-style: normal; color: var(--accent); }
.qlog__xp { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.qlog__xp i { flex: 1; height: 6px; border-radius: 3px; background: var(--tint-2); overflow: hidden; }
.qlog__xp b { display: block; height: 100%; background: var(--accent); transform: scaleX(var(--k, 0)); transform-origin: 0 50%; transition: transform 0.8s var(--ease) 0.15s; }
.qlog__xp .meta { font-size: 11px; white-space: nowrap; }
.qlog__list { list-style: none; border-top: 1px solid var(--line); }
.qrow { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 12px; align-items: start; padding: 11px 0; border-bottom: 1px solid var(--line); }
.qrow > i { display: grid; place-items: center; width: 22px; height: 22px; border: 1px dashed var(--line-2); border-radius: 50%; font-style: normal; font-size: 12px; color: var(--on); }
.qrow.is-done > i { border: 0; background: var(--fill); }
.qrow b { display: block; font-size: 14.5px; font-weight: 600; }
.qrow:not(.is-done) b { color: var(--dim); }
.qrow span { display: block; font-size: 13px; line-height: 1.45; color: var(--dim); }
.qrow .qrow__side { padding-top: 2px; font-family: var(--mono); font-size: 11px; white-space: nowrap; color: var(--faint); }
.qrow.is-done .qrow__side { color: var(--accent); }
.qlog__note { margin-top: 14px; font-size: 12px; color: var(--faint); }

/* the puzzle: a board of buttons, tap a piece, then a square */
.chess { width: min(460px, 100vw - 24px); }
.finder { width: min(620px, 100vw - 24px); }
.chess__board {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  border: 1px solid var(--line-2);
  border-radius: 6px;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
}
.sq {
  position: relative;
  display: grid; place-items: center;
  aspect-ratio: 1;
  font-family: "Apple Symbols", "Segoe UI Symbol", "Noto Sans Symbols 2", "DejaVu Sans", serif;
  font-size: min(40px, 8.4vw);
  line-height: 1;
  color: #12151c;
  touch-action: manipulation;
}
.sq--light { background: #e9e7e1; }
.sq--dark { background: #a3abba; }
.sq.is-white { color: #ffffff; text-shadow: 0 1px 0 #12151c, 0 -1px 0 #12151c, 1px 0 0 #12151c, -1px 0 0 #12151c, 0 2px 3px rgba(0, 0, 0, 0.25); }
.sq.is-last { box-shadow: inset 0 0 0 100px color-mix(in srgb, var(--orange) 26%, transparent); }
.sq.is-pick { box-shadow: inset 0 0 0 3px var(--orange); }
.sq.is-to::after { content: ""; position: absolute; width: 26%; height: 26%; border-radius: 50%; background: rgba(18, 21, 28, 0.32); }
.sq.is-to:not(:empty)::after { width: 84%; height: 84%; background: none; border: 3px solid rgba(18, 21, 28, 0.32); }
.sq.is-mate { box-shadow: inset 0 0 0 100px color-mix(in srgb, #e5484d 55%, transparent); }
.sq:focus-visible { outline: 3px solid var(--orange); outline-offset: -3px; }
.chess__status { min-height: 1.5em; margin: 14px 0 12px; font-size: 14.5px; }
.chess__foot { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.chess__foot .meta { font-size: 10.5px; line-height: 1.5; }
.quest__play { margin-top: 12px; font-size: 14px; font-weight: 600; color: var(--accent); }
.quest__play:hover { text-decoration: underline; text-underline-offset: 3px; }

/* the run card: the end screen at Contact, once the visitor gets there */
.runcard[hidden] { display: none; }
.runcard {
  max-width: 640px;
  margin-top: 40px;
  padding: 22px 22px 20px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: var(--surface);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s ease, transform 0.7s var(--ease);
}
.runcard.is-in { opacity: 1; transform: none; }
.runcard__stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 20px; margin: 18px 0 20px; }
.runcard__stats [hidden] { display: none; }
.runcard__stats dt { margin-bottom: 4px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--faint); }
.runcard__stats dd { font-family: var(--display); font-size: 20px; font-weight: 600; letter-spacing: -0.02em; }
.runcard__actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* the viewer: how many photos are collected, and where one was taken */
.lightbox__bar .lightbox__got { position: absolute; top: max(10px, env(safe-area-inset-top)); left: 12px; min-width: 0; padding: 4px 8px; border-radius: 4px; background: rgba(8, 9, 12, 0.72); text-align: left; font-size: 11px; color: rgba(255, 255, 255, 0.8); }
.lightbox__quiz[hidden] { display: none; }
.lightbox__quiz { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; padding: 10px 16px 0; }
.lightbox__quiz .meta { width: 100%; text-align: center; color: rgba(255, 255, 255, 0.7); }
.lightbox__quiz .btn { color: #f3f4f7; border-color: rgba(255, 255, 255, 0.25); }
.lightbox__quiz .btn:disabled { opacity: 0.45; }
.lightbox__quiz .btn.is-right { opacity: 1; border-color: var(--orange); color: var(--orange); }

/* quest cards that turn over, once their facts exist */
.quest__back { display: none; position: absolute; inset: 0; z-index: 1; flex-direction: column; justify-content: center; gap: 8px; padding: 20px 20px 34px; background: var(--bg); }
.quest.is-flipped .quest__back { display: flex; }
.quest .quest__back .meta { font-size: 11px; color: var(--accent); }
.quest .quest__back p:not(.meta) { max-width: none; font-family: var(--display); font-size: 19px; font-weight: 600; line-height: 1.3; letter-spacing: -0.02em; color: var(--ink); }
.quest__turn { position: absolute; left: 20px; bottom: 12px; z-index: 2; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); }
.quest.is-turning { animation: questTurn 0.44s var(--ease); }
@keyframes questTurn { 50% { transform: perspective(800px) rotateY(90deg); } }

/* ==================================================================
   The question — a character select on a first visit
   ================================================================== */
.onboard {
  --pc-load: var(--accent);
  position: fixed; inset: 0;
  z-index: 200;
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  margin: 0; padding: 0;
  border: 0;
  background: var(--bg);
  color: var(--ink);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* shown from the first paint while the page asks, before any script */
.onboard[open], :root[data-mode="ask"] .onboard { display: grid; }
.onboard::backdrop { background: var(--bg); }
/* the ground: the hero's dots, a blue glow and an orange glow; the one
   on the side of the card in focus grows */
.onboard::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  background-image: radial-gradient(color-mix(in srgb, var(--ink) 16%, transparent) 1.1px, transparent 1.4px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse at 50% 45%, #000 25%, transparent 78%);
  mask-image: radial-gradient(ellipse at 50% 45%, #000 25%, transparent 78%);
}
.onboard__inner::before, .onboard__inner::after {
  content: "";
  position: fixed;
  top: 20%; width: 60vmax; height: 60vmax;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0.12;
  filter: blur(40px);
  transition: opacity 0.6s ease, transform 0.9s var(--ease);
}
.onboard__inner::before { left: -22vmax; background: var(--blue); }
.onboard__inner::after { right: -22vmax; background: var(--orange); }
.onboard[data-hover="recruiter"] .onboard__inner::before,
.onboard[data-hover="curious"] .onboard__inner::after { opacity: 0.28; transform: scale(1.08); }
/* on paper-white the glows need far less */
:root[data-theme="light"] .onboard__inner::before, :root[data-theme="light"] .onboard__inner::after { opacity: 0.06; }
:root[data-theme="light"] .onboard[data-hover="recruiter"] .onboard__inner::before,
:root[data-theme="light"] .onboard[data-hover="curious"] .onboard__inner::after { opacity: 0.14; }
.onboard__inner {
  position: relative;
  width: min(1040px, 100% - 2 * var(--gut));
  margin: auto;
  padding: 24px 0 36px;
}
.onboard__inner > * { position: relative; z-index: 1; }
.onboard__top { display: flex; align-items: center; gap: 14px; margin-bottom: clamp(28px, 8vh, 80px); }
.onboard__mark { width: 30px; height: 30px; flex: 0 0 auto; }
.onboard__boot { flex: 1; display: flex; align-items: center; gap: 5px; min-width: 0; white-space: nowrap; overflow: hidden; }
.onboard__boot i { width: 7px; height: 13px; background: var(--accent); animation: obCaret 1s steps(1) infinite; }
@keyframes obCaret { 50% { opacity: 0; } }
.onboard kbd {
  display: inline-block;
  min-width: 20px;
  padding: 1px 6px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  font-family: var(--mono);
  font-size: 10.5px;
  text-align: center;
  color: var(--dim);
}
.onboard__kicker { margin-bottom: 12px; }
.onboard__title {
  margin-bottom: clamp(24px, 5vh, 44px);
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(44px, 7.4vw, 100px);
  line-height: 0.95;
  letter-spacing: -0.05em;
}
.onboard__title em {
  font-style: normal;
  background: linear-gradient(90deg, var(--blue), var(--orange));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* the two cards */
.onboard__picks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; perspective: 1200px; }
.pick {
  --pc: var(--blue);
  --pc-fill: var(--blue-fill);
  --pc-on: #ffffff;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 22px 24px 24px;
  border: 1px solid var(--line-2);
  border-radius: 16px;
  background: color-mix(in srgb, var(--surface) 72%, transparent);
  text-align: left;
  cursor: pointer;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.5s var(--ease), border-color 0.25s ease, background-color 0.25s ease, box-shadow 0.35s ease, opacity 0.4s ease;
}
.pick--cur { --pc: var(--orange); --pc-fill: var(--orange); --pc-on: #12151c; }
.pick.is-on {
  border-color: var(--pc);
  background: color-mix(in srgb, var(--pc) 9%, var(--surface));
  box-shadow: 0 0 0 1px var(--pc), 0 30px 70px -30px color-mix(in srgb, var(--pc) 70%, transparent);
  transform: translateY(-4px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
}
/* the selection is the focus mark: the pointer and the keys move it together */
.pick:focus-visible { outline: none; }
.pick__top { display: flex; justify-content: space-between; align-items: center; width: 100%; margin-bottom: 18px; }
.pick__ic { width: 42px; height: 42px; margin-bottom: 14px; fill: none; stroke: var(--pc); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.5s var(--ease); }
.pick.is-on .pick__ic { transform: scale(1.12) rotate(-6deg); }
/* the card colour pulled a little towards the text colour, so it reads
   on the tinted card in both themes */
.pick__class { margin-bottom: 6px; color: color-mix(in srgb, var(--pc) 75%, var(--ink)); }
.pick__name { margin-bottom: 6px; font-family: var(--display); font-weight: 700; font-size: clamp(28px, 3.4vw, 40px); line-height: 1.05; letter-spacing: -0.04em; }
.pick__line { margin-bottom: 20px; font-size: 15px; color: var(--dim); }
/* stats as five-segment bars, like a character sheet; a card in focus
   charges them up */
.pick__stats { display: grid; gap: 9px; width: 100%; margin-bottom: 18px; }
.stat { display: grid; grid-template-columns: 112px minmax(0, 1fr); align-items: center; gap: 12px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--dim); }
.stat i { position: relative; height: 8px; background: repeating-linear-gradient(to right, var(--line-2) 0 calc(20% - 3px), transparent calc(20% - 3px) 20%); }
.stat i::after {
  content: "";
  position: absolute; inset: 0;
  background: repeating-linear-gradient(to right, var(--pc) 0 calc(20% - 3px), transparent calc(20% - 3px) 20%);
  clip-path: inset(0 calc(100% - var(--v) * 20%) 0 0);
  opacity: 0.45;
  transition: opacity 0.3s ease;
}
.pick.is-on .stat i::after { opacity: 1; animation: obCharge 0.55s steps(5, end) backwards; }
.pick.is-on .stat:nth-child(2) i::after { animation-delay: 0.08s; }
.pick.is-on .stat:nth-child(3) i::after { animation-delay: 0.16s; }
@keyframes obCharge { from { clip-path: inset(0 100% 0 0); } }
.pick__perks { margin-bottom: 20px; font-size: 13px; color: var(--dim); }
.pick__go {
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px;
  margin-top: auto;
  padding: 0 16px;
  border-radius: 6px;
  background: var(--tint-2);
  font-size: 14px;
  font-weight: 600;
  transition: background-color 0.25s ease, color 0.25s ease;
}
.pick.is-on .pick__go { background: var(--pc-fill); color: var(--pc-on); }
.pick.is-on .pick__go i { animation: obNudge 1.1s var(--ease) infinite; }
@keyframes obNudge { 50% { transform: translateX(4px); } }

/* the foot: the keys until a choice, then the loading bar in their place */
.onboard__foot { display: grid; margin-top: 24px; }
.onboard__hint, .onboard__load { grid-area: 1 / 1; transition: opacity 0.3s ease, transform 0.4s var(--ease); }
.onboard__hint { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.onboard__hint kbd:nth-of-type(2) { margin-right: 4px; }
.onboard__hint kbd:nth-of-type(3) { margin-left: 8px; margin-right: 4px; }
.onboard__load {
  display: flex; align-items: center; gap: 14px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  opacity: 0;
  transform: translateY(6px);
}
.onboard__load i { position: relative; flex: 1; height: 4px; overflow: hidden; border-radius: 2px; background: var(--line); }
.onboard__load b { position: absolute; inset: 0; background: var(--pc-load); transform: scaleX(var(--load, 0)); transform-origin: 0 50%; }
.onboard__pct { min-width: 40px; text-align: right; color: var(--ink); }
.onboard[data-picked="recruiter"] { --pc-load: var(--blue); }
.onboard[data-picked="curious"] { --pc-load: var(--orange); }

/* a choice: the other card steps back, the chosen one forward */
.onboard.is-picked .pick { cursor: default; }
.onboard.is-picked .pick.is-out { opacity: 0.12; transform: scale(0.95) translateY(8px); }
.onboard.is-picked .pick.is-chosen { transform: translateY(-8px) scale(1.02); }
.onboard.is-picked .onboard__hint { opacity: 0; transform: translateY(-6px); }
.onboard.is-picked .onboard__load { opacity: 1; transform: none; }
/* then the screen wipes up in the chosen colour, and the page starts */
.onboard::after {
  content: "";
  position: fixed; inset: 0;
  z-index: 5;
  pointer-events: none;
  background: var(--bg);
  box-shadow: 0 -6px 0 var(--pc-load);
  transform: translateY(105%);
}
.onboard.is-leaving::after { transform: none; transition: transform 0.42s var(--wipe); }

/* opening plays the entrance once */
.onboard.is-playing :is(.onboard__kicker, .onboard__title, .pick, .onboard__foot) { animation: obIn 0.7s var(--ease) backwards; }
.onboard.is-playing .onboard__kicker { animation-delay: 0.08s; }
.onboard.is-playing .onboard__title { animation-delay: 0.16s; }
.onboard.is-playing .pick:nth-child(1) { animation-delay: 0.3s; }
.onboard.is-playing .pick:nth-child(2) { animation-delay: 0.4s; }
.onboard.is-playing .onboard__foot { animation-delay: 0.58s; }
@keyframes obIn { from { opacity: 0; transform: translateY(18px); } }

@media (max-width: 1080px) {
  .quests__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* five figures: three over two, each row filling the width */
  .figures { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .figures > div { grid-column: span 2; }
  .figures > div:nth-child(n + 4) { grid-column: span 3; }
  .figures > div:nth-child(4) { border-left: 0; padding-left: 0; }
  .figures > div:nth-child(n + 4) { border-top: 1px solid var(--line); }
  .ai { grid-template-columns: minmax(0, 1fr); }
  .trace { position: relative; top: auto; }
}
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .hero__photo { max-width: 460px; }
  .projects { grid-template-columns: minmax(0, 1fr); }
  .kit__grid, .kit__cv { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 767px) {
  body { padding-bottom: 88px; }
  .toast { bottom: 96px; left: 12px; max-width: calc(100vw - 24px); }
  .hero__photo { --off: 12px; }
  .bar { height: 56px; gap: 12px; }
  .bar__links { display: none; }
  .bar__end { margin-left: auto; }
  .dock { display: flex; }
  .hero { padding-top: 92px; min-height: 0; }
  .acc__head, .acc--roles .acc__head { grid-template-columns: 34px minmax(0, 1fr) 20px; gap: 12px; padding: 22px 0; }
  .acc__head .tag, .acc__when { display: none; }
  .acc__body { padding-left: 46px; }
  .concepts { grid-template-columns: minmax(0, 1fr); }
  .role { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .quests__grid { grid-template-columns: minmax(0, 1fr); }
  .player { grid-template-columns: 88px minmax(0, 1fr); gap: 16px; }
  .player__img { width: 88px; height: 88px; }
  .player__class div { flex-direction: column; gap: 0; }
  .photolog__row h4 span { display: block; margin: 2px 0 0; }
  /* the bar keeps room for the controller: LinkedIn lives in Contact */
  .bar__end a.bar__icon[href*="linkedin"] { display: none; }
  .contact__row { grid-template-columns: minmax(0, 1fr) auto; }
  .contact__row .meta { grid-column: 1 / -1; }
  .trace__run { min-height: 0; }
}
/* Phones on screen only: a printed page is narrower than 767px too, and
   the print CV must not pick these up */
@media screen and (max-width: 767px) {
  /* targets a thumb can hit: 44px for the icons and the controls */
  .bar__end { gap: 4px; }
  .bar__icon { width: 44px; height: 44px; }
  .bar__name { padding-block: 7px; }
  .bar .btn--sm { height: 40px; }
  .trace__asks button { min-height: 44px; padding: 10px 14px; }
  .offclock button { padding: 10px 0; }
  .hero__more button { padding: 6px 0; }
  .finder__skill { min-height: 40px; }
  .share button { min-height: 44px; }
  .answers__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 20px; }
  .answers__wide { grid-column: 1 / -1; }

  /* the agent concepts: a row of cards to swipe through, the next one
     peeking in from the edge */
  .concepts {
    display: flex;
    gap: 10px;
    margin-inline: calc(-1 * var(--gut));
    padding: 4px var(--gut) 10px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gut);
    scrollbar-width: none;
  }
  .concepts::-webkit-scrollbar { display: none; }
  .concepts > div {
    flex: 0 0 min(82%, 320px);
    scroll-snap-align: start;
    padding: 18px 18px 20px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--tint);
  }
  .concepts > div::before { display: none; }

  .kit__group { padding: 16px 16px 18px; }

  /* side quests: the way back stays at the top while the panel scrolls */
  .quests__inner { padding-top: 0; }
  .quests__top {
    position: sticky; top: 0; z-index: 2;
    margin: 0 calc(-1 * var(--gut)) 20px;
    padding: 8px var(--gut);
    background: var(--glass);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--line);
  }
  .quests__top .meta { white-space: nowrap; }
  .quests__top .btn { height: 44px; }
  .quests__top kbd, .lightbox__bar kbd { display: none; }
  /* each quest a compact row: the icon on the left, the status over the
     title, the number in the corner */
  .quest {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    column-gap: 14px;
    align-content: start;
    padding: 16px 18px 18px;
  }
  .quest__top { display: contents; }
  .quest__ic { grid-row: 1 / span 3; }
  .quest__status { grid-column: 2; justify-self: start; margin-bottom: 8px; }
  .quest h4, .quest p { grid-column: 2; }
  .quest::after { top: 20px; bottom: auto; }
  .quest__shot { top: 46px; right: 18px; }
  /* a reel runs to the edges of the screen; the viewer fits above the
     browser's own toolbar */
  .reel { height: min(78vw, 360px); margin-inline: calc(-1 * var(--gut)); padding-inline: var(--gut); scroll-padding-inline: var(--gut); }
  /* a wide photo shows its middle, so the next one still peeks in */
  .reel__shot { max-width: 80vw; }
  .reel__shot img { position: relative; left: 50%; transform: translateX(-50%); }
  .lightbox { height: 100dvh; }
  .lightbox__slide { padding: 14px 8px 8px; }
  .lightbox__bar .btn { height: 44px; min-width: 44px; justify-content: center; }

  /* the view switch runs across the column, each half a thumb target */
  .mode-switch__track { flex: 1 1 auto; max-width: 380px; }
  .mode-switch a { height: 44px; padding: 0 8px; gap: 7px; }
  .foot__mode { padding: 12px 0; }
  /* the question on a phone: the cards stack and lose the extras */
  .onboard__inner { padding: 14px 0 28px; }
  .onboard__top { margin-bottom: 26px; }
  .onboard__title { font-size: clamp(40px, 12vw, 56px); margin-bottom: 22px; }
  .onboard__picks { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .pick { padding: 16px 18px 18px; }
  .pick__top { margin-bottom: 0; }
  .onboard .pick__key, .onboard__skip kbd { display: none; }
  .pick__ic { position: absolute; top: 18px; right: 18px; width: 34px; height: 34px; margin: 0; }
  .pick__name { font-size: 30px; }
  .pick__line { margin-bottom: 14px; font-size: 14px; }
  .pick__stats { gap: 7px; margin-bottom: 14px; }
  .stat { grid-template-columns: 100px minmax(0, 1fr); font-size: 10.5px; }
  .pick__perks { display: none; }
  .pick__go { height: 40px; }
  .onboard__hint { display: none; }
}
/* the game's panels give the board and the list more room on a phone */
@media screen and (max-width: 560px) {
  .qlog, .chess { padding: 16px 14px 14px; }
  .runcard { padding: 18px 16px 16px; }
  .runcard__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* on the narrowest phones the switch needs the label's room */
/* a narrow phone's bar has no room for the finder: the hero's line
   under the buttons opens it */
@media screen and (max-width: 400px) {
  .bar__find { display: none; }
}
/* phones: the skills in one row to swipe, so the places show sooner */
@media screen and (max-width: 560px) {
  .finder__skills { flex-wrap: nowrap; overflow-x: auto; margin-inline: -22px; padding: 2px 22px; scrollbar-width: none; }
  .finder__skills::-webkit-scrollbar { display: none; }
  .finder__skill { flex: none; }
}
@media screen and (max-width: 374px) {
  .mode-switch__label { display: none; }
}
@media (max-width: 560px) {
  .figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .figures > div:nth-child(n) { grid-column: auto; border-left: 1px solid var(--line); padding-left: 16px; }
  .figures > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .figures > div:nth-child(odd) { border-left: 0; padding-left: 0; }
  .figures > div:nth-child(n + 3) { border-top: 1px solid var(--line); }
  .photos { grid-template-columns: 1fr 1fr; }
  .photos img:nth-child(2) { display: none; }
  .acc__body { padding-left: 0; }
  .dock a { min-width: 0; flex: 1; padding-inline: 4px; }
  .dock { width: calc(100% - 24px); }
}

/* ==================================================================
   Reduced motion — a different branch, not a shorter animation.
   Everything renders at its end state, and nothing moves on its own.
   ================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation: none !important; }
  .js .rv, .js .rv.is-in { opacity: 1; transform: none; }
  .js [data-split] .ch, .js .name-dot { transform: none; }
  .js .hero__photo .hero__frame, .js .hero__photo::before { clip-path: none; }
  .js .hero__photo::after { transform: none; opacity: 1; }
  .js .hero__photo .hero__frame img { transform: none; }
  .js .h-split .w > span, .js .hero__line b::after { transform: none; }
  .js :is(.acc__item, .contact__row, .concepts > div).rv::before { transform: none; }
  .js .section::before, .js .figures::before { transform: none; }
  .js .trace .st { opacity: 1; transform: none; }
  .js .acc__item :is(.wins > div, .ships li) { opacity: 1; transform: none; }
  .js .kit__group.rv .tags li { opacity: 1; transform: none; }
  .quests__load { display: none; }
  .js .trace__spans li.st::after { transform: none; }
  .is-found {
    background-color: color-mix(in srgb, var(--accent) 14%, var(--bg));
    box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 14%, var(--bg));
  }
}

/* ==================================================================
   Print — the page becomes a clean CV on paper: black on white, no
   navigation, no motion, every role and product open, no games.
   ================================================================== */
@media print {
  :root, :root[data-theme] {
    --bg: #fff; --surface: #fff; --ink: #111; --dim: #333; --faint: #666;
    --line: #d6d6d6; --line-2: #bbb; --accent: #2a52d6; --accent-soft: #2a52d6; --accent-2: #c94d14;
    --fill: #2a52d6;
  }
  @page { margin: 12mm 13mm 14mm; }
  html { font-size: 9pt; }
  body { background: #fff; color: #111; padding: 0; font-size: 9pt; line-height: 1.45; }
  .bar, .rail, .dock, .skip, .hero__field, .strip, .hero__actions, .hero__photo, .trace, .photos,
  .acc__icon, .toast, .confetti, .eggs, .quests, .lightbox, .offclock, .keys, .head__intro, .project__go,
  .onboard, .mode-switch, .foot__mode, .mode-wipe, .contact__row--cv,
  .qlog, .chess, .runcard, .quest__play, .quest__back, .quest__turn,
  .hero__more, .finder, .share, .answers,
  .section--contact .contact__title { display: none !important; }
  /* the side projects print as a compact list */
  .projects { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6pt; }
  .project { min-height: 0; padding: 6pt 8pt; color: var(--ink) !important; }
  .project::before { display: none; }
  .project h3 { font-size: 11pt; margin: 2pt 0 3pt; }
  .project p { font-size: 8pt; color: var(--dim) !important; }
  .js .rv, .js .rv.is-in, .js [data-split] .ch, .js .name-dot, .js .h-split .w > span,
  .js .acc__body > *, .js .acc__item :is(.wins > div, .ships li), .js .kit__group .tags li {
    opacity: 1 !important; transform: none !important; animation: none !important; transition: none !important;
  }
  .js .acc__item .acc__panel { grid-template-rows: 1fr !important; }
  .acc__item::before, .section::before, .figures::before, .concepts > div::before, .contact__row::before { transform: none !important; }
  .acc__item::after, .contact__row::after { display: none; }
  .wrap { width: 100%; }
  .hero { min-height: 0; padding: 0; display: block; }
  .hero__grid { display: block; }
  .hero__name { font-size: 26pt; margin: 4pt 0 6pt; }
  .hero__name .line { display: inline-block; padding: 0 0.12em 0 0; margin: 0; }
  .line:nth-child(2) { padding-left: 0; }
  .hero__line { font-size: 12pt; margin-bottom: 4pt; }
  .hero__pitch { font-size: 9.5pt; margin-bottom: 0; }
  .figures { grid-template-columns: repeat(5, minmax(0, 1fr)); margin-top: 5mm; }
  .figures > div:nth-child(n) { grid-column: auto !important; padding: 5pt 6pt 6pt; border-top: 0 !important; border-left: 1px solid var(--line) !important; }
  .figures > div:first-child { border-left: 0 !important; padding-left: 0; }
  .figures dt { font-size: 14pt; margin-bottom: 3pt; }
  .figures dd { font-size: 7.5pt; }
  .section { padding: 5mm 0 0; }
  .head { margin-bottom: 2mm; }
  .head h2, .contact__title { font-size: 13pt; margin-top: 3pt; max-width: none; }
  .meta { font-size: 7.5pt; }
  .acc__head { padding: 4pt 0; grid-template-columns: 26pt minmax(0, 1fr) auto; gap: 8pt; }
  .acc__title { font-size: 11pt; }
  .acc__title small { font-size: 8.5pt; margin-top: 1pt; }
  .tag, .acc__when { font-size: 7pt; }
  .acc__body { padding-left: 34pt; }
  .acc__body p, .role__sum { font-size: 9pt; margin-bottom: 4pt; }
  .acc__body > :last-child { margin-bottom: 5pt; }
  /* "copy a link" does not print: the part above it ends the body */
  .acc__body > :has(+ .share:last-child) { margin-bottom: 5pt; }
  .role { gap: 10pt; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); }
  .wins > div { padding: 5pt 7pt; }
  .wins dt { font-size: 12pt; margin-bottom: 2pt; }
  .wins dd { font-size: 7.5pt; }
  .ships li { padding: 3pt 0; }
  .ships b { font-size: 9pt; }
  .ships span { font-size: 8pt; margin-top: 0; }
  .ai { display: block; }
  .concepts { grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: 10pt; }
  .concepts > div { padding: 5pt 0; }
  .concepts dt { font-size: 9.5pt; margin-bottom: 2pt; }
  .concepts dd { font-size: 7.5pt; }
  .kit { margin-top: 5mm; }
  .kit__group { padding: 6pt 8pt; }
  .kit__group h4 { font-size: 9.5pt; margin-bottom: 4pt; }
  .tags { gap: 3pt; }
  .tags li { font-size: 7.5pt; padding: 1pt 6pt; }
  .kit__cv > div { padding: 6pt 8pt; }
  .contact__row { padding: 4pt 0; grid-template-columns: 60pt minmax(0, 1fr); }
  /* a printed page is phone-narrow: keep the label beside the address,
     not above it */
  .contact__row .meta { grid-column: auto; }
  .contact__row strong { font-size: 11pt; }
  .contact__row i { display: none; }
  /* the way to reach João, under the name on the first page */
  .hero__print { display: block; margin: 0 0 6pt; font-family: var(--mono); font-size: 8pt; letter-spacing: 0.02em; color: #333; }
  .hero__print a { color: inherit; }
  .acc__item, .kit__group, .concepts > div, .wins, .ships li, .role { break-inside: avoid; }
  a[href^="http"]:not(.bar__icon):not(.contact__row):not(.hero__print a)::after { content: " (" attr(href) ")"; font-size: 7.5pt; color: #555; }
  .foot { padding: 3mm 0 0; font-size: 7.5pt; }
}
