/* ---------- Tokens ---------- */
:root{
  --paper: #F7F7F5;
  --paper-alt: #ECEEEB;
  --ink: #16201C;
  --ink-soft: #5C6B64;
  --accent: #1F6F5C;
  --accent-alt: #B4432B;
  --accent-wash: rgba(31, 111, 92, 0.07);
  --line: #DDE2DD;
  --radius: 3px;
  --font-display: "Fraunces", serif;
  --font-body: "IBM Plex Sans", sans-serif;
  --font-mono: "IBM Plex Mono", monospace;
}

:root[data-theme="dark"]{
  --paper: #0E1310;
  --paper-alt: #171D19;
  --ink: #E9EEE9;
  --ink-soft: #8FA098;
  --accent: #49B092;
  --accent-alt: #E2694F;
  --accent-wash: rgba(73, 176, 146, 0.13);
  --line: #26302A;
}

*{ box-sizing: border-box; }

html{ scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  *{ animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

body{
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  transition: background 0.3s ease, color 0.3s ease;
}

.mono{ font-family: var(--font-mono); }

a{ color: var(--accent); text-decoration-color: var(--line); text-underline-offset: 3px; }
a:hover{ text-decoration-color: currentColor; }

/* ---------- Skip link ---------- */
.skip-link{
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  background: var(--accent);
  color: var(--paper);
  padding: 10px 16px;
  border-radius: var(--radius);
  text-decoration: none;
  font-size: 0.88rem;
}
.skip-link:focus{ left: 16px; top: 16px; }

/* ---------- Utility buttons (print, theme) ---------- */
.utility{
  position: fixed;
  top: 22px;
  right: 22px;
  z-index: 10;
  display: flex;
  gap: 8px;
}
.util-btn{
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.util-btn:hover{ border-color: var(--accent); color: var(--accent); transform: scale(1.06); }
.util-btn:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }
.icon{ width: 17px; height: 17px; }
.icon-moon{ display: none; }
[data-theme="dark"] .icon-sun{ display: none; }
[data-theme="dark"] .icon-moon{ display: block; }

/* ---------- Site layout: nav rail + page ---------- */
.layout{
  display: grid;
  grid-template-columns: 224px minmax(0, 1fr);
  transition: grid-template-columns 0.28s ease;
}
.nav-collapsed .layout{ grid-template-columns: 62px minmax(0, 1fr); }

.site-nav{
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  padding: 44px 26px;
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 34px;
}
.nav-collapsed .site-nav{ padding: 44px 14px; align-items: center; }
.nav-collapsed .site-nav__name,
.nav-collapsed .site-nav__list{ display: none; }

.nav-toggle{
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-soft);
  width: 26px;
  height: 26px;
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.nav-toggle:hover{ border-color: var(--accent); color: var(--accent); }
.nav-toggle:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }
.nav-toggle svg{ width: 14px; height: 14px; transition: transform 0.28s ease; }
.nav-collapsed .nav-toggle svg{ transform: rotate(180deg); }

.site-nav__top{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.nav-collapsed .site-nav__top{ flex-direction: column; gap: 14px; }

.site-nav__brand{
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: var(--ink);
  min-width: 0;
}
.site-nav__mark{
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--paper);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.site-nav__name{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.2;
}
.site-nav__list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.site-nav__link{
  display: block;
  position: relative;
  padding: 7px 0 7px 14px;
  font-size: 0.9rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color 0.2s ease;
}
.site-nav__link::before{
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 0;
  background: var(--accent);
  border-radius: 2px;
  transition: height 0.2s ease;
}
.site-nav__link:hover{ color: var(--ink); }
.site-nav__link:hover::before{ height: 14px; }
.site-nav__link.is-active{ color: var(--accent); }
.site-nav__link.is-active::before{ height: 20px; }
.site-nav__link:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }
/* ---------- Page shell ---------- */
.cv{ max-width: 900px; margin: 0 auto; padding: 76px 48px 64px; }

/* Heading block for the secondary pages. */
.page-head{
  padding-bottom: 28px;
  margin-bottom: 44px;
  border-bottom: 1px solid var(--line);
}
.page-head__title{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.7rem, 3.6vw, 2.2rem);
  letter-spacing: -0.01em;
  margin: 0 0 10px;
  line-height: 1.15;
}
.page-head__lede{
  color: var(--ink-soft);
  margin: 0;
  max-width: 62ch;
}

/* ---------- Letterhead ---------- */
.cv-header{
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-bottom: 44px;
  margin-bottom: 56px;
  border-bottom: 1px solid var(--line);
}
.cv-name{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.9rem, 4.2vw, 2.6rem);
  letter-spacing: -0.01em;
  margin: 0 0 8px;
  line-height: 1.1;
}
.cv-role{
  color: var(--ink-soft);
  margin: 0 0 22px;
  font-size: 1rem;
}
.cv-contact{
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 26px;
  font-size: 0.88rem;
}
.cv-contact li{ display: inline-flex; align-items: center; gap: 7px; color: var(--ink-soft); }
.cv-contact__icon{ width: 15px; height: 15px; flex-shrink: 0; opacity: 0.8; }
.cv-contact a{ color: var(--ink); text-decoration: none; }
.cv-contact a:hover{ color: var(--accent); }
.cv-open{
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0;
  font-style: italic;
}

/* ---------- Body grid: sidebar + main ---------- */
.cv-body{
  display: grid;
  grid-template-columns: 216px 1fr;
}
.cv-sidebar{ padding-right: 48px; }
.cv-main{ padding-left: 48px; border-left: 1px solid var(--line); }

.cv-block + .cv-block{ margin-top: 48px; }
.cv-block__title{
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
  margin: 0 0 22px;
}
.cv-summary{ color: var(--ink-soft); margin: 0; max-width: 62ch; font-size: 1.02rem; }

/* ---------- At-a-glance facts ---------- */
.facts{ margin: 0; display: flex; flex-direction: column; gap: 18px; }
.facts__row dt{
  font-size: 0.74rem;
  color: var(--ink-soft);
  margin-bottom: 4px;
}
.facts__row dd{ margin: 0; font-weight: 500; font-size: 0.9rem; }

/* ---------- Languages ---------- */
.langs{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.langs li{
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 0.9rem;
}
.langs__name{ font-weight: 500; }
.langs__level{ font-size: 0.78rem; color: var(--ink-soft); }

/* ---------- Skills ---------- */
.skills{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 20px; }
.skill__row{
  --delay: 0s;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "name pct" "track track";
  gap: 6px 10px;
}
.js .skill__row{
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease var(--delay), transform 0.5s ease var(--delay);
}
.js .skill__row.is-visible{ opacity: 1; transform: translateY(0); }
.skill__row:nth-child(1){ --delay: 0s; }
.skill__row:nth-child(2){ --delay: 0.07s; }
.skill__row:nth-child(3){ --delay: 0.14s; }
.skill__row:nth-child(4){ --delay: 0.21s; }
.skill__row:nth-child(5){ --delay: 0.28s; }
.skill__row:nth-child(6){ --delay: 0.35s; }
.skill__name{ grid-area: name; font-size: 0.88rem; font-weight: 500; }
.skill__note{ display: block; font-size: 0.72rem; font-weight: 400; color: var(--ink-soft); margin-top: 2px; }
.skill__track{
  display: block;
  grid-area: track;
  height: 4px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.skill__fill{
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: 2px;
  transition: width 1s cubic-bezier(.2,.7,.3,1);
}
.skill__pct{
  grid-area: pct;
  font-size: 0.78rem;
  color: var(--ink-soft);
  align-self: start;
}

/* ---------- Timeline ---------- */
.timeline{
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 36px;
}
.timeline__item{
  --delay: 0s;
  position: relative;
  padding-left: 28px;
}
.js .timeline__item{
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.5s ease var(--delay), transform 0.5s ease var(--delay);
}
.js .timeline__item.is-visible{ opacity: 1; transform: translateX(0); }
.timeline__item:nth-child(1){ --delay: 0s; }
.timeline__item:nth-child(2){ --delay: 0.09s; }
.timeline__item:nth-child(3){ --delay: 0.18s; }
.timeline__item:nth-child(4){ --delay: 0.27s; }
.timeline__marker{
  position: absolute;
  left: -4.5px;
  top: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}
.timeline__period{
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink-soft);
  display: block;
  margin-bottom: 6px;
}
.timeline__title{ margin: 0 0 8px; font-weight: 600; font-size: 1.02rem; }
.timeline__desc{ margin: 0; color: var(--ink-soft); max-width: 60ch; }
.timeline__bullets{
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 60ch;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.timeline__bullets li{
  position: relative;
  padding-left: 16px;
  color: var(--ink-soft);
}
.timeline__bullets li::before{
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-soft);
}

/* ---------- Coursework chips ---------- */
.courses{ margin-top: 14px; }
.courses__label{
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-bottom: 10px;
}
.courses__list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.courses__list li{ display: flex; }
.course{
  display: inline-flex;
  align-items: baseline;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 3px 9px;
  font-size: 0.76rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: border-color 0.2s ease, color 0.2s ease,
              background-color 0.2s ease, transform 0.2s ease;
}
/* Everything responds to the cursor, but only a chip that actually
   goes somewhere lights up in the accent colour. */
.course:hover{
  border-color: var(--ink-soft);
  color: var(--ink);
  background: var(--paper-alt);
  transform: translateY(-1px);
}
.course--link:hover{
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-wash);
}
.course--link:focus-visible{
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.course--in-progress{ border-style: dashed; }
.course__note{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  color: var(--accent);
  margin-left: 7px;
}

/* ---------- Projects ---------- */
.projects{ display: flex; flex-direction: column; }
.project{
  --delay: 0s;
  padding: 26px 0;
  border-top: 1px solid var(--line);
  position: relative;
}
.js .project{
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease var(--delay), transform 0.5s ease var(--delay);
}
.projects .project:last-child{ padding-bottom: 0; }
.js .project.is-visible{ opacity: 1; transform: translateY(0); }
.project:nth-child(1){ --delay: 0s; }
.project:nth-child(2){ --delay: 0.09s; }
.project:nth-child(3){ --delay: 0.18s; }
.project:nth-child(4){ --delay: 0.27s; }
.project::before{
  content: "";
  position: absolute;
  left: -20px;
  top: 26px;
  bottom: 26px;
  width: 2px;
  background: var(--accent);
  border-radius: 2px;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.project:hover::before{ opacity: 1; }
.project__head{ display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.project__title{ margin: 0; font-weight: 600; font-size: 1.02rem; }
.project__tag{
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--accent);
}
.project__desc{ color: var(--ink-soft); margin: 10px 0 0; max-width: 62ch; }
.project__actions{ display: flex; align-items: center; gap: 20px; margin-top: 12px; flex-wrap: wrap; }
.project__link{ font-size: 0.88rem; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.project__link:hover{ text-decoration-color: currentColor; }

.project__toggle{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: var(--ink-soft);
  transition: color 0.2s ease;
}
.project__toggle:hover{ color: var(--accent); }
.project__toggle:focus-visible{ outline: 2px solid var(--accent); outline-offset: 3px; border-radius: var(--radius); }
.project__chevron{ width: 14px; height: 14px; transition: transform 0.3s ease; }
.project__toggle.is-open .project__chevron{ transform: rotate(180deg); }

/* Animates open without measuring heights in JS. */
.project__detail{
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s ease;
}
.project__detail.is-open{ grid-template-rows: 1fr; }
.project__detail-inner{ overflow: hidden; min-height: 0; }

.project__stack{
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.project__stack li{
  font-size: 0.72rem;
  color: var(--accent);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 2px 8px;
  transition: border-color 0.2s ease, background-color 0.2s ease,
              transform 0.2s ease;
}
.project__stack li:hover{
  border-color: var(--accent);
  background: var(--accent-wash);
  transform: translateY(-1px);
}
.project__points{
  list-style: none;
  margin: 14px 0 4px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
  max-width: 62ch;
}
.project__points li{
  position: relative;
  padding-left: 16px;
  color: var(--ink-soft);
  font-size: 0.94rem;
}
.project__points li::before{
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-soft);
}

/* ---------- Live DCF model ---------- */
.model__lede{
  color: var(--ink-soft);
  margin: 0 0 24px;
  max-width: 62ch;
  font-size: 0.92rem;
}
.model{
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 28px;
  align-items: start;
}
.model__controls{ display: flex; flex-direction: column; gap: 16px; }
.model__field{ display: flex; flex-direction: column; gap: 6px; cursor: pointer; }
.model__label{
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 0.8rem;
  color: var(--ink-soft);
}
.model__value{ font-size: 0.78rem; color: var(--ink); }
.model__field input[type="range"]{
  width: 100%;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.model__field input[type="range"]:focus-visible{
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

.model__figure{ margin: 0; }
.model__chart{ width: 100%; height: auto; display: block; overflow: visible; }
.model__bar-nominal{ fill: var(--line); }
.model__bar-value{ fill: var(--accent); }
.model__baseline{ stroke: var(--line); stroke-width: 1; }
.model__axis{
  fill: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: 7px;
}
.model__result{
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.model__result-label{ font-size: 0.78rem; color: var(--ink-soft); }
.model__npv{ font-size: 1.05rem; font-weight: 500; color: var(--accent); }

.cv-more{ margin: 22px 0 0; font-size: 0.9rem; }

/* ---------- Beta regression ---------- */
/* Proportional scaling, so the points stay circular at any width
   and the slope is not visually distorted. */
.beta__chart{ width: 100%; height: auto; display: block; }
.beta__axis{ stroke: var(--line); stroke-width: 1; }
.beta__point{ fill: var(--accent); fill-opacity: 0.55; }
.beta__residual{ stroke: var(--ink-soft); stroke-width: 1; stroke-opacity: 0.28; }
.beta__fit{ stroke: var(--accent); stroke-width: 2.5; }
.beta__true{ stroke: var(--ink-soft); stroke-width: 1.5; stroke-dasharray: 6 5; }

.beta__check{
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
  color: var(--ink-soft);
  cursor: pointer;
}
.beta__check input{ accent-color: var(--accent); cursor: pointer; margin: 0; }

.beta__legend{
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 12px;
  font-size: 0.74rem;
  color: var(--ink-soft);
}
.beta__key{ display: inline-flex; align-items: center; gap: 7px; }
.beta__key::before{
  content: "";
  width: 18px;
  height: 0;
  border-top-width: 2px;
  border-top-style: solid;
  flex-shrink: 0;
}
.beta__key--fit::before{ border-color: var(--accent); }
.beta__key--true::before{ border-color: var(--ink-soft); border-top-style: dashed; }
.beta__key--axis::before{ display: none; }

/* ---------- Monte Carlo ---------- */
.sim{ margin-top: 40px; padding-top: 28px; border-top: 1px solid var(--line); }
.sim__title{
  font-size: 0.98rem;
  font-weight: 600;
  margin: 0 0 8px;
}
.sim__lede{
  color: var(--ink-soft);
  margin: 0 0 22px;
  max-width: 62ch;
  font-size: 0.92rem;
}
.sim__controls{
  display: flex;
  align-items: flex-end;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.sim__field{ flex: 1 1 180px; max-width: 260px; }
.sim__resample{
  border: 1px solid var(--line);
  background: none;
  color: var(--ink-soft);
  border-radius: var(--radius);
  padding: 7px 14px;
  font-family: var(--font-body);
  font-size: 0.8rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.sim__resample:hover{ border-color: var(--accent); color: var(--accent); }
.sim__resample:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

.sim__chart{ width: 100%; height: 190px; display: block; }
.sim__path{ fill: none; stroke: var(--accent); stroke-opacity: 0.11; stroke-width: 1; }
[data-theme="dark"] .sim__path{ stroke-opacity: 0.15; }
.sim__median{ fill: none; stroke: var(--accent); stroke-width: 2; }
.sim__baseline{ stroke: var(--line); stroke-width: 1; }
.sim__axis{
  fill: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: 9px;
}

.sim__stats{
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  display: flex;
  gap: 32px;
  flex-wrap: wrap;
}
.sim__stat dt{
  font-size: 0.72rem;
  color: var(--ink-soft);
  margin-bottom: 4px;
}
.sim__stat dd{ margin: 0; font-size: 0.92rem; }
.sim__stat--median dd{ color: var(--accent); font-weight: 500; }
.sim__note{
  margin: 20px 0 0;
  color: var(--ink-soft);
  font-size: 0.88rem;
  max-width: 62ch;
}

/* ---------- Skills page ---------- */
.skill-group__items{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px;
}
.skill-card{
  --delay: 0s;
  border-top: 1px solid var(--line);
  padding-top: 16px;
}
.js .skill-card{
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease var(--delay), transform 0.5s ease var(--delay);
}
.js .skill-card.is-visible{ opacity: 1; transform: translateY(0); }
.skill-card:nth-child(2){ --delay: 0.07s; }
.skill-card:nth-child(3){ --delay: 0.14s; }
.skill-card:nth-child(4){ --delay: 0.21s; }
.skill-card__name{ margin: 0 0 8px; font-size: 0.98rem; font-weight: 600; }
.skill-card__summary{ margin: 0; color: var(--ink-soft); font-size: 0.92rem; }
.skill-card__evidence{ margin-top: 14px; }
.skill-card__evidence-label{
  display: block;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.skill-card__links{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* ---------- Grouped project sections ---------- */
.project-group + .project-group{ margin-top: 52px; }
.project-group__note{
  color: var(--ink-soft);
  margin: -8px 0 20px;
  font-size: 0.88rem;
  max-width: 62ch;
}

/* ---------- 404 ---------- */
.notfound{
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 620px;
}
.notfound__code{
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin: 0 0 14px;
}
.notfound__title{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 4vw, 2.2rem);
  line-height: 1.15;
  margin: 0 0 16px;
}
.notfound__body{ color: var(--ink-soft); margin: 0 0 24px; max-width: 48ch; }
.notfound__link{ font-size: 0.92rem; }

/* ---------- Footer ---------- */
.cv-footer{
  margin-top: 64px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.8rem;
  text-align: center;
}
.cv-footer p{ margin: 0; }
.cv-footer a{ color: var(--ink-soft); text-decoration-color: var(--line); }
.cv-footer a:hover{ color: var(--accent); text-decoration-color: currentColor; }

/* ---------- Responsive ---------- */
/* Below this the rail becomes a bar across the top. */
@media (max-width: 940px){
  .layout{ grid-template-columns: 1fr; }
  .site-nav{
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
    padding: 18px 20px;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .site-nav__name{ font-size: 0.85rem; }
  .site-nav__list{ flex-direction: row; gap: 4px; flex-wrap: wrap; }
  .site-nav__link{ padding: 6px 10px; }
  .site-nav__link::before{
    top: auto;
    bottom: 0;
    left: 10px;
    right: 10px;
    width: auto;
    height: 2px;
    transform: none;
    transition: opacity 0.2s ease;
    opacity: 0;
  }
  .site-nav__link:hover::before,
  .site-nav__link.is-active::before{ height: 2px; opacity: 1; }
  .cv{ padding: 48px 28px 56px; }
  /* Collapsing is a desktop affordance; the bar is already compact. */
  .nav-toggle{ display: none; }
  .nav-collapsed .layout{ grid-template-columns: 1fr; }
  .nav-collapsed .site-nav{ padding: 18px 20px; align-items: center; }
  .nav-collapsed .site-nav__name,
  .nav-collapsed .site-nav__list{ display: revert; }
  .nav-collapsed .site-nav__list{ display: flex; }
  .nav-collapsed .site-nav__top{ flex-direction: row; }
}

@media (max-width: 780px){
  .cv-body{ grid-template-columns: 1fr; }
  .cv-sidebar{ padding-right: 0; padding-bottom: 40px; margin-bottom: 40px; border-bottom: 1px solid var(--line); }
  .cv-main{ padding-left: 0; border-left: none; }
  .project::before{ left: -24px; }
  .model{ grid-template-columns: 1fr; gap: 22px; }
}

@media (max-width: 560px){
  .cv{ padding: 64px 20px 48px; }
  .utility{ top: 14px; right: 14px; }
  .project::before{ left: -20px; }
}

/* ---------- Print / save as PDF ---------- */
/* ---------- Beyond the CV ---------- */

/* Three interests, three columns: the grouping is the point, so it
   should not break into a 2 + 1 row with a hole in it. */
.interest-grid{ grid-template-columns: repeat(auto-fit, minmax(175px, 1fr)); }
.pick-grid{ grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); }
.pick{
  border-top: 1px solid var(--line);
  padding-top: 16px;
}
.js .pick{
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.js .pick.is-visible{ opacity: 1; transform: translateY(0); }
.pick__label{
  display: block;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.pick__title{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  margin: 0 0 4px;
  line-height: 1.2;
}
.pick__meta{ margin: 0 0 10px; font-size: 0.75rem; color: var(--ink-soft); }
.pick__note{ margin: 0; color: var(--ink-soft); font-size: 0.9rem; }

.interest__list{ margin-top: 14px; }

.work-list{ list-style: none; margin: 0; padding: 0; }
.work + .work{
  margin-top: 26px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.js .work{
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.js .work.is-visible{ opacity: 1; transform: translateY(0); }
.work__claim{ margin: 0 0 7px; font-weight: 600; font-size: 1rem; }
.work__detail{ margin: 0; color: var(--ink-soft); max-width: 68ch; }
.work__link{ margin-top: 12px; }

.mbti__head{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 24px;
}
.mbti__type{
  font-size: 1.1rem;
  font-weight: 500;
  color: var(--accent);
  border: 1px solid var(--accent);
  background: var(--accent-wash);
  border-radius: var(--radius);
  padding: 4px 11px;
}
.mbti__name{ color: var(--ink-soft); font-size: 0.92rem; }

.mbti__axes{ list-style: none; margin: 0; padding: 0; }
.mbti__axis{ padding: 0 0 22px; }
.js .mbti__axis{
  opacity: 0;
  transition: opacity 0.5s ease;
}
.js .mbti__axis.is-visible{ opacity: 1; }

.mbti__value{
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin: 0 0 9px;
  font-size: 0.95rem;
}
.mbti__letter{ font-size: 0.74rem; color: var(--accent); }
.mbti__pct{ font-weight: 500; color: var(--ink); }
.mbti__mine{ color: var(--ink); font-weight: 500; }

/* A spectrum between two labelled poles, not a meter. 50% is no
   preference, so the bar grows out of the centre and its length is how
   far the answer leans. The named trait is on the left and the marker
   sits at (100 - pct), so a stronger score pulls the marker toward its
   own trait, which is the direction the questionnaire draws it. */
.mbti__track{
  display: block;
  position: relative;
  height: 5px;
  border-radius: 3px;
  background: var(--line);
}
.mbti__mid{
  display: block;
  position: absolute;
  top: -5px;
  bottom: -5px;
  left: 50%;
  width: 1px;
  background: var(--ink-soft);
  opacity: 0.55;
}
.mbti__fill{
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 3px;
  background: var(--accent);
}
.mbti__dot{
  display: block;
  position: absolute;
  top: 50%;
  width: 11px;
  height: 11px;
  margin-left: -5.5px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  background: var(--paper);
  transform: translateY(-50%);
}
.mbti__poles{
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.mbti__note{
  margin: 24px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.88rem;
  max-width: 68ch;
}

@media (max-width: 620px){
  .mbti__axis{
    grid-template-columns: 22px 1fr;
    row-gap: 4px;
  }
  .mbti__track{ grid-column: 2; }
  .mbti__other{ grid-column: 2; }
}

@media print{
  /* Always print on light paper, whatever the on-screen theme is. */
  :root, :root[data-theme="dark"]{
    --paper: #FFFFFF;
    --paper-alt: #FFFFFF;
    --ink: #000000;
    --ink-soft: #333333;
    --accent: #1F6F5C;
    --line: #BBBBBB;
  }

  @page{ margin: 14mm; }

  /* No animation on paper: a print snapshot must never catch an
     element mid-fade. */
  *{ transition: none !important; animation: none !important; }

  body{ background: #fff; font-size: 10.5pt; line-height: 1.45; }
  .cv{ max-width: none; padding: 0; }

  /* Screen-only affordances. Sliders are inert on paper, but the
     charts and the numbers they produced still say something, so
     those stay. */
  .utility, .skip-link, .project__toggle, .site-nav,
  .model__controls, .sim__controls{ display: none !important; }
  .layout{ display: block; }
  .model{ grid-template-columns: 1fr; }

  /* Scroll-reveal items must never print blank, whether or not the
     reader scrolled them into view first. */
  .js .timeline__item,
  .js .project,
  .js .skill-card,
  .js .work,
  .js .pick,
  .js .mbti__axis,
  .js .skill__row{
    opacity: 1 !important;
    transform: none !important;
  }

  /* Keep the teal skill fills rather than letting the browser drop
     backgrounds to save ink. */
  .skill__track, .skill__fill, .timeline__marker{
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .cv-header{ padding-bottom: 20px; margin-bottom: 24px; }
  .cv-body{ grid-template-columns: 190px 1fr; }
  .cv-sidebar{ padding-right: 28px; }
  .cv-main{ padding-left: 28px; }
  .cv-block + .cv-block{ margin-top: 26px; }
  .timeline{ gap: 20px; }
  .project{ padding: 16px 0; }
  /* Keep the tag next to its title instead of stranded at the far
     edge of the page. */
  .project__head{ justify-content: flex-start; gap: 12px; }

  /* Don't split an entry across two pages. */
  .timeline__item, .project, .skill__row, .cv-block__title{
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .cv-block__title{ break-after: avoid; page-break-after: avoid; }

  /* The project links say "View on GitHub" on screen; on paper the
     reader needs the actual URL. Contact links already show theirs. */
  .project__link::after{
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #555;
  }

  a{ text-decoration: none; }
  .cv-footer{ margin-top: 28px; padding-top: 12px; font-size: 8pt; }
}
