/* ==========================================================================
   components.css — site components.
   Mobile-first. Breakpoints: 640px / 768px / 1024px (min-width).
   ========================================================================== */

/* ---- Skip link ---- */
.skip-link {
  position: absolute;
  top: -3.5rem;
  left: var(--space-3);
  z-index: 100;
  background: var(--pine);
  color: var(--white);
  padding: 0.7em 1.1em;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
  border-radius: var(--radius);
  transition: top 0.15s ease;
}
.skip-link:focus {
  top: var(--space-3);
}
@media (prefers-reduced-motion: reduce) { .skip-link { transition: none; } }

/* ---- Site header / nav ---- */
.site-header {
  background: var(--black);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 40;
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-3);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--white);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 500;
}
.brand__mark {
  width: 10px;
  height: 10px;
  background: var(--pine-bright);
  border-radius: 1px;
  flex-shrink: 0;
}
.site-nav__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  background: transparent;
  border: 1px solid var(--muted); /* var(--line) on var(--black) was 1.35:1, failed the
    3:1 control-boundary check; --muted (8.39:1) is used instead */
  color: var(--white);
  padding: 0.5em 0.9em;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-radius: var(--radius);
  cursor: pointer;
}
.site-nav__toggle:hover { border-color: var(--pine-bright); }
.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--step--1);
}
.site-nav__link {
  color: var(--muted);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.site-nav__link:hover,
.site-nav__link[aria-current] {
  color: var(--white);
}
.site-nav__cta { margin-inline-start: var(--space-2); }

/* Below 768px, once JS is running: hide the inline list behind the toggle. */
@media (max-width: 767.98px) {
  .js .site-nav__list {
    display: none;
    position: absolute;
    inset-inline: 0;
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
    background: var(--black);
    border-top: 1px solid var(--line);
    padding: var(--space-4) clamp(1.25rem, 4vw, 2.5rem) var(--space-5);
  }
  .js .site-nav.site-nav--open .site-nav__list { display: flex; }
  .js .site-nav__cta { margin-inline-start: 0; }
}
/* At >=768px the list is always inline and the toggle never shows, JS or not. */
@media (min-width: 768px) {
  .site-nav__toggle { display: none; }
  .site-nav__list { display: flex; position: static; background: none; border: 0; padding: 0; }
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.85em 1.5em;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }
.btn--primary { background: var(--pine); color: var(--white); }
.btn--primary:hover { background: var(--pine-bright); color: var(--black); }
.btn--secondary { background: transparent; color: var(--surface-text); border-color: var(--surface-text); }
.btn--secondary:hover { background: var(--surface-text); color: var(--surface-bg); }
/* White fill / black text — required wherever a filled button sits on --pine-deep,
   since --pine fill on --pine-deep only reaches 2.30:1 (fails the 3:1 UI boundary). */
.btn--light { background: var(--white); color: var(--black); }
.btn--light:hover { background: var(--pine-bright); color: var(--black); }
.btn--small { padding: 0.55em 1.1em; }
.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  color: var(--surface-link);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.text-link span { display: inline-block; transition: transform 0.15s ease; }
.text-link:hover span { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) { .text-link span { transition: none; } }

/* ---- Hero ----
   Two columns on desktop: copy left, one large CAD viewport right, both vertically
   centred, with the key-figure strip closing the same section instead of floating
   in a band of its own. Single column below 1024px, image first-class either way. */
.hero { padding-block: var(--space-7); }
.hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: center;
}
@media (min-width: 1024px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: var(--space-7); }
  .hero { padding-block: var(--space-8); }
}
.hero__copy .lead { margin-top: var(--space-4); max-width: 34rem; }
.hero__copy .btn-row { margin-top: var(--space-6); }
.hero__media { margin: 0; }
.hero__media img { width: 100%; height: auto; }
/* The hero now shows a photo, where a two-line tag would cover the aircraft.
   Keep it on one line by scaling the type down on narrow screens. */
.hero__media .cad-frame__label { white-space: nowrap; font-size: clamp(0.6rem, 2.3vw, 0.85rem); }
.hero__media-caption {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--slate-line);
  font-size: var(--step--1);
  color: var(--slate-muted);
}
/* Small factual chips under the call-to-action row. */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-5);
}
.chip {
  padding: 0.4em 0.85em;
  background: var(--ink-900);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--muted);
  white-space: nowrap;
}

/* ---- CAD viewport frame ---- */
.cad-frame {
  position: relative;
  background: var(--slate);
  border: 1px solid var(--slate-line);
  border-radius: var(--radius);
  padding: var(--space-3);
}
.cad-frame--flush { padding: 0; }
.cad-frame__label {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 2;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--slate-label);
  background: rgba(10, 11, 10, 0.55);
  padding: 0.25em 0.6em;
}
.cad-frame picture,
.cad-frame img { width: 100%; height: auto; display: block; }
.cad-frame__caption {
  margin-top: var(--space-3);
  font-size: var(--step--1);
  color: var(--slate-muted); /* sits on --slate, not on the page surface */
}

/* ---- Status badges ---- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.35em 0.75em;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: transparent;
  border: 1px solid currentColor;
  border-radius: var(--radius);
}
.badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.badge--flight-tested { color: var(--badge-flight); }
.badge--3d-printed { color: var(--badge-printed); }
.badge--active-rnd { color: var(--badge-rnd); }
.badge--concept { color: var(--badge-concept); }
.badge--client { color: var(--badge-client); }
.badge--software { color: var(--badge-rnd); }
.badge--built { color: var(--badge-flight); }
/* Light-surface swap: the dark hues above drop under 3:1 on --paper/--paper-2. */
.surface-light .badge--flight-tested { color: var(--badge-flight-light); }
.surface-light .badge--3d-printed { color: var(--badge-printed-light); }
.surface-light .badge--active-rnd { color: var(--badge-rnd-light); }
.surface-light .badge--concept { color: var(--badge-concept-light); }
.surface-light .badge--client { color: var(--badge-client-light); }
.surface-light .badge--software { color: var(--badge-rnd-light); }
.surface-light .badge--built { color: var(--badge-flight-light); }

/* ---- Spec strip ---- */
.spec-strip {
  display: flex;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--step--1);
}
/* Row gap + column gap instead of per-item dividers: a right-hand rule strands a
   dangling separator at the end of a wrapped line, which no CSS selector can target. */
.spec-strip { gap: var(--space-2) var(--space-6); }
.spec-strip li {
  display: flex;
  gap: 0.5em;
  align-items: baseline;
  white-space: nowrap;
}
.spec-strip__key { color: var(--surface-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.spec-strip__value { color: var(--surface-text); font-weight: 500; }

/* ---- Stat strip ---- */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6) var(--space-5);
}
@media (min-width: 640px) {
  .stat-strip { grid-template-columns: repeat(4, 1fr); }
}
.stat__value {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step-2);
  font-weight: 500;
  color: var(--surface-text);
}
.stat__label {
  display: block;
  margin-top: 0.4em;
  font-size: var(--step--1);
  color: var(--surface-muted);
}

/* ---- Project cards ---- */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}
@media (min-width: 768px) {
  .card-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .card-grid--3 { grid-template-columns: repeat(3, 1fr); }
}
.project-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--ink-900);
  border: 1px solid var(--muted); /* var(--line) on var(--ink-900) was 1.25:1, failed the
    3:1 card-boundary check (the whole card is a single link); --muted (7.75:1) is used
    instead */
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.15s ease;
}
.project-card:hover,
.project-card:focus-within { border-color: var(--pine-bright); }
@media (prefers-reduced-motion: reduce) { .project-card { transition: none; } }
.project-card__media {
  aspect-ratio: 4 / 3;
  background: var(--slate);
  overflow: hidden;
}
.project-card__media img,
.project-card__media picture { width: 100%; height: 100%; }
.project-card__media img { object-fit: cover; }
/* Collage: several small renders tiled inside one card's media slot, used for the
   design-studies card. Images are decorative here (the card text names the work),
   so the wrapper carries aria-hidden and each img has an empty alt. */
.collage {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 2px;
  width: 100%;
  height: 100%;
  background: var(--slate-line);
}
.collage__item { display: block; overflow: hidden; background: var(--slate); }
.collage__item--tall { grid-row: span 2; }
/* contain, not cover: these CAD renders have the subject centred in a wide
   frame, so cover crops the mechanism out. The slate matches the render bg. */
.collage__item img { width: 100%; height: 100%; object-fit: contain; background: var(--slate); }

.project-card__body {
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1;
}
.project-card__title { font-size: var(--step-1); margin-top: 0.2em; }
.project-card__link { color: var(--white); text-decoration: none; }
.project-card__link::after { content: ""; position: absolute; inset: 0; }
.project-card__summary { color: var(--muted); }
.project-card--schematic .project-card__schematic {
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-4);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background-color: var(--ink-900);
  background-image: repeating-linear-gradient(135deg, var(--line) 0 1px, transparent 1px 16px);
  border-bottom: 1px solid var(--line);
}

/* ---- Experience timeline ---- */
.timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-left: var(--space-5);
  border-left: 1px solid var(--surface-line);
}
.timeline__item { position: relative; }
.timeline__item::before {
  content: "";
  position: absolute;
  top: 0.35em;
  left: calc(-1 * var(--space-5) - 4px);
  width: 8px;
  height: 8px;
  background: var(--surface-accent);
}
.timeline__date {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--surface-muted);
}
.timeline__title { margin-top: 0.3em; }
.timeline__org { margin-top: 0.2em; color: var(--surface-muted); }
.timeline__body { margin-top: var(--space-3); max-width: var(--measure); }
.timeline__body > * + * { margin-top: var(--space-2); }

/* ---- Skills grid ---- */
.skills-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 640px) {
  .skills-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .skills-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
}
.skills-group__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--surface-accent);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--surface-line);
}
.skills-group__list {
  display: flex;
  flex-direction: column;
  gap: 0.55em;
}

/* ---- About block ---- */
.about {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 768px) {
  .about { grid-template-columns: 320px 1fr; gap: var(--space-7); }
}
.about__media {
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--ink-900);
  border-radius: var(--radius);
}
.about__media img { width: 100%; height: 100%; object-fit: cover; }
.about__facts {
  margin-top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 0.45em;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--surface-muted);
}

/* ---- Contact band ---- */
.contact-band__inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}
.contact-band__title { font-size: var(--step-3); }
.contact-band__inner > p { max-width: var(--measure); color: var(--white); }
.contact-band__actions { margin-top: var(--space-3); }

/* ---- Site footer ---- */
.site-footer {
  background: var(--black);
  border-top: 1px solid var(--line);
  padding-block: var(--space-6);
}
.site-footer__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
@media (min-width: 640px) {
  .site-footer__inner { flex-direction: row; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-4); }
}
.site-footer__name {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--white);
}
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  font-size: var(--step--1);
}
.site-footer__links a { color: var(--muted); text-decoration: underline; text-underline-offset: 0.2em; }
.site-footer__links a:hover { color: var(--pine-bright); }
/* The home page ends with a contact band carrying the same email, LinkedIn, and
   résumé links, so the footer copies are redundant there. Project pages have no
   contact band, so their footer keeps the links as the only contact route. */
body[data-page="home"] .site-footer__links { display: none; }
.site-footer__legal { font-size: var(--step--1); color: var(--muted); }
.site-footer__legal a { color: var(--muted); text-decoration: underline; text-underline-offset: 0.2em; }
.site-footer__legal a:hover { color: var(--pine-bright); }

/* ---- Case study: breadcrumb ---- */
.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.breadcrumb li { display: flex; align-items: center; color: var(--surface-muted); }
.breadcrumb li:not(:last-child)::after {
  content: "/";
  margin-inline: 0.5em;
  color: var(--surface-line);
}
.breadcrumb a { color: var(--surface-muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--surface-link); }
.breadcrumb [aria-current] { color: var(--surface-text); }

/* ---- Case study: title block ---- */
.cs-header { padding-block: var(--space-7); }
.cs-header .badge { margin-top: var(--space-4); }
.cs-header__title { margin-top: var(--space-3); }
.cs-header .lead { margin-top: var(--space-4); color: var(--muted); }

/* ---- Case study: meta row ---- */
.meta-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4) var(--space-6);
  margin-top: var(--space-6);
}
@media (min-width: 640px) {
  .meta-row { grid-template-columns: repeat(4, 1fr); }
}
.meta-row__item dt {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--surface-muted);
}
.meta-row__item dd { margin-top: 0.3em; font-weight: 500; }

/* ---- Case study: summary box ----
   Default (dark ancestor): --ink-900 panel. Inside .surface-light: --paper-2 panel. */
.summary-box {
  background: var(--ink-900);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-5);
  margin-block: var(--space-6);
}
.surface-light .summary-box { background: var(--paper-2); border-color: var(--line-light); }
.summary-box__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--surface-accent);
}
.summary-box__list {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-left: 1.15em;
  list-style: disc;
}
.summary-box__list li::marker { color: var(--surface-accent); }

/* ---- Case study: prose section ---- */
/* flow-root keeps child margins INSIDE the section. Without it the first/last
   child's margin collapses out and the black page background shows through
   between two light sections as a dark bar (worst after a .figure-grid). */
.cs-section { display: flow-root; }
.cs-section + .cs-section { border-top: 1px solid var(--line-light); }

/* ---- Case study: evidence / limitations ---- */
.evidence { margin-top: var(--space-6); display: flex; flex-direction: column; gap: var(--space-5); }
.limitations {
  margin-top: var(--space-5);
  padding-left: var(--space-4);
  border-left: 3px solid var(--surface-accent);
}
.limitations__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--surface-accent);
}
.limitations p:not(.limitations__label) {
  margin-top: 0.4em;
  color: var(--surface-muted);
  max-width: var(--measure);
}

/* ---- Case study: data table ---- */
.table-wrap {
  overflow-x: auto;
  margin-block: var(--space-5);
  border: 1px solid var(--surface-line);
  border-radius: var(--radius);
}
.table-wrap:focus-visible { outline: 2px solid var(--surface-accent); outline-offset: -2px; }
.data-table {
  width: 100%;
  min-width: 480px;
  border-collapse: collapse;
  font-size: var(--step--1);
}
.data-table caption {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--surface-muted);
  border-bottom: 1px solid var(--surface-line);
}
.data-table th,
.data-table td {
  padding: var(--space-2) var(--space-4);
  text-align: left;
  border-bottom: 1px solid var(--surface-line);
}
.data-table thead th {
  font-family: var(--font-mono);
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--surface-muted);
}
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table .num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ---- Case study: figure / figure grid ---- */
.figure { margin-block: var(--space-5); }
.figure-note { margin-top: var(--space-3); font-size: var(--step--1); }
.figure picture,
.figure img { border-radius: var(--radius); }
.figure figcaption { margin-top: var(--space-2); font-size: var(--step--1); color: var(--surface-muted); }
/* A caption the reader needs (e.g. who is who in a group photo): body-size text in
   the main text colour rather than the small muted caption style. */
.figure figcaption.figure__caption--prominent { font-size: var(--step-0); color: var(--surface-text); }
/* .figure--wide: full width of its column by default (matches plain .figure — .prose
   only clamps p/ul/ol/h2/h3 to --measure, so figures already span the reading column).
   At >=1024px inside .container--reading it breaks out to the page's full --container
   (1200px) instead of staying pinned to the 960px reading measure, so a wide
   diagram/photo isn't squeezed narrower than it needs to be.
   The breakout amount is min(2.5rem + 120px, 50vw - 480px):
     - .container--reading's own padding-inline is clamp(1.25rem, 4vw, 2.5rem), which is
       already pinned to its 2.5rem ceiling for every viewport this rule can apply at
       (>=1024px > the ~1000px point where 4vw passes 2.5rem) — so the two outward
       breakout margins exactly cancel that padding and add (1200-960)/2 = 120px more
       per side once there's room for it.
     - 50vw - 480px is how much space actually exists between the (960px, centered)
       reading column's edge and the viewport edge. Taking the min() means the figure
       never asks for more width than the viewport actually has, so it can't force
       horizontal page scroll even in the narrow band just above the 1024px breakpoint
       (checked by hand at the 1024px and 1280px boundary cases). */
.figure--wide { width: 100%; }
@media (min-width: 1024px) {
  .container--reading .figure--wide {
    --figure-wide-bleed: min(calc(2.5rem + 120px), calc(50vw - 480px));
    width: calc(100% + 2 * var(--figure-wide-bleed));
    margin-inline: calc(-1 * var(--figure-wide-bleed));
  }
}
.figure-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  margin-block: var(--space-5);
}
.figure-grid .figure { margin-block: 0; }
@media (min-width: 768px) {
  .figure-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .figure-grid--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .figure-grid--3 { grid-template-columns: repeat(3, 1fr); }
}

/* ---- Case study: compare (before/after) ---- */
.compare {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-block: var(--space-5);
}
@media (min-width: 768px) {
  .compare:not(.compare--enhanced) { flex-direction: row; }
  .compare:not(.compare--enhanced) .compare__item { flex: 1; margin: 0; }
}
.compare__item { margin: 0; }
.compare__item figcaption { margin-top: var(--space-2); font-size: var(--step--1); color: var(--surface-muted); }

/* Enhanced (JS) mode: both figures become `display:contents` so their picture/img
   can share one grid cell (a true overlay) while both figcaptions stay in normal
   flow underneath — no absolute positioning, no markup beyond the spec'd range input. */
.compare--enhanced {
  display: grid;
  grid-template-areas: "stack" "cap-before" "cap-after";
  grid-template-rows: auto auto auto;
  --compare-pos: 50%;
}
.compare--enhanced .compare__item { display: contents; }
.compare--enhanced .compare__item picture,
.compare--enhanced .compare__item img {
  grid-area: stack;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.compare--enhanced .compare__item--before picture,
.compare--enhanced .compare__item--before img { position: relative; height: auto; }
.compare--enhanced .compare__item--after picture,
.compare--enhanced .compare__item--after img {
  clip-path: inset(0 calc(100% - var(--compare-pos)) 0 0);
}
.compare--enhanced .compare__item--before figcaption { grid-area: cap-before; }
.compare--enhanced .compare__item--after figcaption { grid-area: cap-after; }
.compare--enhanced .compare__range {
  grid-area: stack;
  align-self: end;
  justify-self: stretch;
  z-index: 3;
  margin: var(--space-3);
  width: calc(100% - 2 * var(--space-3));
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: ew-resize;
}
/* Track/thumb use the surface-aware vars, not a fixed rgba(white)/--pine-bright pair:
   .compare renders inside .cs-section.surface-light in practice, where the old
   rgba(244,245,242,0.55) track was 1.02:1 on --paper and --pine-bright was 2.23:1 on
   --paper — both failed the 3:1 UI check. --surface-muted / --surface-accent already
   clear >=4.5:1 on every surface so they clear 3:1 too. */
.compare--enhanced .compare__range::-webkit-slider-runnable-track {
  height: 3px;
  background: var(--surface-muted);
  border-radius: var(--radius);
}
.compare--enhanced .compare__range::-moz-range-track {
  height: 3px;
  background: var(--surface-muted);
  border-radius: var(--radius);
}
.compare--enhanced .compare__range::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  margin-top: -12px;
  width: 10px;
  height: 27px;
  background: var(--surface-accent);
  border: 1px solid var(--black);
  border-radius: var(--radius);
}
.compare--enhanced .compare__range::-moz-range-thumb {
  width: 10px;
  height: 27px;
  background: var(--surface-accent);
  border: 1px solid var(--black);
  border-radius: var(--radius);
}
.compare--enhanced .compare__range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--white); outline-offset: 2px; }
.compare--enhanced .compare__range:focus-visible::-moz-range-thumb { outline: 2px solid var(--white); outline-offset: 2px; }

/* ---- Case study: prev/next pager ---- */
.cs-pager {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-block: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid var(--surface-line);
}
@media (min-width: 640px) {
  .cs-pager { grid-template-columns: 1fr 1fr; }
}
.cs-pager__link {
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  padding: var(--space-4);
  border: 1px solid var(--surface-muted); /* var(--surface-line) resolved to var(--line) on
    var(--black) at 1.35:1, failing the 3:1 card-boundary check for this clickable card;
    var(--surface-muted) already clears >=4.5:1 on every surface */
  border-radius: var(--radius);
  color: var(--surface-text);
  text-decoration: none;
  transition: border-color 0.15s ease;
}
.cs-pager__link:hover,
.cs-pager__link:focus-visible { border-color: var(--surface-accent); }
@media (prefers-reduced-motion: reduce) { .cs-pager__link { transition: none; } }
/* "Next" always sits on the right: right-aligned text at every width, and pinned to the
   second grid column so it stays right even on a page with no "Previous" link. */
.cs-pager__link--next { align-items: flex-end; text-align: right; }
@media (min-width: 640px) {
  .cs-pager__link--prev { grid-column: 1; }
  .cs-pager__link--next { grid-column: 2; }
}
.cs-pager__dir {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--surface-muted);
}
.cs-pager__title { font-weight: 500; }

/* ---- Placeholder figure ----
   Must never read as a photo: dashed border + diagonal hatch, real (non-CSS) tag text.
   Toggle: set --placeholder-display: none in tokens.css to hide every instance. */
.placeholder { display: var(--placeholder-display); margin-block: var(--space-5); }
.placeholder__frame {
  position: relative;
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  text-align: center;
  border: 1px dashed var(--surface-line);
  border-radius: var(--radius);
  background-color: var(--surface-bg);
  background-image: repeating-linear-gradient(
    45deg,
    var(--surface-line) 0,
    var(--surface-line) 1px,
    transparent 1px,
    transparent 12px
  );
}
.placeholder--wide .placeholder__frame { aspect-ratio: 16 / 9; }
.placeholder__tag {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--surface-muted);
  background: var(--surface-bg);
  border: 1px solid var(--surface-line);
  padding: 0.45em 0.85em;
}
.placeholder__caption { margin-top: var(--space-2); font-size: var(--step--1); color: var(--surface-muted); }
.placeholder__file {
  font-family: var(--font-mono);
  background: var(--surface-line);
  padding: 0.1em 0.4em;
  border-radius: 2px;
  word-break: break-all;
}

/* ---- Lightbox ---- */
.lightbox {
  position: fixed;
  inset: 0;
  margin: auto;
  max-width: 92vw;
  max-height: 92vh;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: var(--black);
  color: var(--white);
}
.lightbox::backdrop { background: rgba(10, 11, 10, 0.85); }
.lightbox__img { display: block; max-width: 92vw; max-height: 78vh; width: auto; height: auto; margin-inline: auto; }
.lightbox__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 2.25rem;
  height: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  line-height: 1;
  background: var(--ink-900);
  color: var(--white);
  border: 1px solid var(--muted); /* var(--line) on var(--ink-900) was 1.25:1, failed the
    3:1 button-boundary check; --muted (7.75:1) is used instead */
  border-radius: var(--radius);
  cursor: pointer;
}
.lightbox__close:hover { border-color: var(--pine-bright); color: var(--pine-bright); }
.lightbox__caption {
  padding: var(--space-3) var(--space-4);
  text-align: center;
  font-size: var(--step--1);
  color: var(--muted);
}

/* ---- System diagram (SVG) ---- */
.diagram { margin-block: var(--space-6); }
.diagram__canvas {
  overflow-x: auto;
  padding: var(--space-4);
  background: var(--surface-bg);
  border: 1px solid var(--surface-line);
  border-radius: var(--radius);
}
.diagram__canvas svg { display: block; width: 100%; height: auto; min-width: 480px; }
.diagram figcaption { margin-top: var(--space-2); font-size: var(--step--1); color: var(--surface-muted); }
.diagram-node rect { fill: var(--surface-bg); stroke: var(--surface-text); stroke-width: 1.5; }
.diagram-node--in-design rect { stroke: var(--surface-muted); stroke-dasharray: 4 3; }
.diagram-node--in-design .diagram-label,
.diagram-node--in-design .diagram-tag { fill: var(--surface-muted); }
.diagram-label {
  fill: var(--surface-text);
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.diagram-tag {
  fill: var(--surface-accent);
  font-family: var(--font-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.diagram-edge { stroke: var(--surface-text); stroke-width: 1.5; fill: none; }
.diagram-edge-label {
  fill: var(--surface-muted);
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.diagram-arrow { fill: currentColor; color: var(--surface-text); }

/* ---- Certifications (home, under Skills) ----
   Its own block below the skills grid: a hairline and heading separate it from
   the skill lists, and each credential is a card that can carry a verify link. */
.certifications {
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid var(--surface-line);
}
.certifications__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--surface-accent);
}
.cert-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
@media (min-width: 768px) { .cert-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cert {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
  background: var(--black);
  border: 1px solid var(--surface-line);
  border-left: 3px solid var(--pine);
  border-radius: var(--radius);
}
.cert__issuer {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.cert__name { font-size: var(--step-1); font-weight: 600; color: var(--white); }
.cert__dates { font-size: var(--step--1); color: var(--muted); }
.cert .text-link { margin-top: var(--space-2); align-self: flex-start; }

/* Trademark notice required by OpenCFD's trade mark policy on pages detailing an
   OpenFOAM-based project: body-size text (the policy's minimum), set apart by a rule. */
.trademark-notice {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--surface-line);
  font-size: var(--step-0);
  color: var(--surface-muted);
}

/* Section header: small eyebrow label, a headline that says something, one line of context. */
.section-head { margin-bottom: var(--space-6); max-width: 46rem; }
.section-head .eyebrow { margin: 0 0 var(--space-2); }
.section-head h2 { margin: 0; }
.section-head__lead { margin-top: var(--space-3); font-size: var(--step-1); color: var(--surface-muted); }

/* Home-page section headings: display-scale so each section reads as a clear chapter. */
.section > .container > h2,
.section-head h2 { font-size: var(--step-4); line-height: 1.1; letter-spacing: -0.01em; }
.section > .container > h2 { margin-bottom: var(--space-6); }
.contact-band__title { font-size: var(--step-4); line-height: 1.1; }

/* ---- Talos card cover: typographic wordmark ----
   Text only on a plain background (crisp at any size). Decorative, so aria-hidden in
   the markup; the card title below carries the name for assistive tech. */
.project-card--schematic .talos-cover {
  position: relative;
  padding: var(--space-5);
  background: var(--black);
  overflow: hidden;
}
.talos-cover__mark {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  text-transform: none;
  letter-spacing: normal;
}
.talos-cover__name {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(2.6rem, 8vw, 4.4rem);
  line-height: 0.95;
  letter-spacing: 0.22em;
  margin-right: -0.22em; /* balance trailing tracking so the word centres optically */
  text-transform: uppercase;
  color: var(--white);
}
.talos-cover__sub {
  font-family: var(--font-mono);
  font-size: clamp(0.8rem, 2.2vw, 1.05rem);
  letter-spacing: 0.42em;
  margin-right: -0.42em;
  text-transform: uppercase;
  color: var(--pine-bright);
}

/* ---- "View project" affordance on cards ----
   The whole card is a link (title link stretched over the card); this label makes that
   visible. aria-hidden in the markup so screen readers hear the title link only once. */
.project-card__cta {
  margin-top: auto;
  padding-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--pine-bright);
}
.project-card__cta span { display: inline-block; transition: transform 0.15s ease; }
.project-card:hover .project-card__cta span,
.project-card:focus-within .project-card__cta span { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) { .project-card__cta span { transition: none; } }
