/* Gabriel Márquez: page styles.
   scrollcraft.css is the mechanism and stays untouched; everything here is
   this page's own markup and its theme. */

@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}

/* ------------------------------------------------------------------ theme --
   Apple dialect: system SF on Apple devices, Geist everywhere else. Two
   grounds that hard-cut, one blue at two lightnesses (one per ground). */
:root {
  --sc-font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Geist", "Segoe UI", system-ui, sans-serif;
  --sc-font-text: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Geist", "Segoe UI", system-ui, sans-serif;

  --sc-canvas: #f5f5f7;  --sc-surface: #ffffff;
  --sc-ink: #1d1d1f;     --sc-ink-soft: #5f5f64;
  --sc-accent: #0066cc;  --sc-accent-ink: #ffffff;
  --sc-shadow-color: 240 6% 20%;
  --hair: rgb(0 0 0 / 0.14);

  --btn: #0066cc;        --btn-hover: #0077ed;
  --bar-h: 3rem;
  --radius-photo: 28px;
  --radius-tile: 22px;
}

.ground--light {
  --sc-canvas: #f5f5f7; --sc-surface: #ffffff;
  --sc-ink: #1d1d1f;    --sc-ink-soft: #5f5f64;
  --sc-accent: #0066cc; --sc-accent-ink: #ffffff;
  --hair: rgb(0 0 0 / 0.14);
  background: var(--sc-canvas); color: var(--sc-ink);
}
.ground--white {
  --sc-canvas: #ffffff; --sc-surface: #f5f5f7;
  --sc-ink: #1d1d1f;    --sc-ink-soft: #5f5f64;
  --sc-accent: #0066cc; --sc-accent-ink: #ffffff;
  --hair: rgb(0 0 0 / 0.12);
  background: var(--sc-canvas); color: var(--sc-ink);
}
.ground--dark {
  --sc-canvas: #0b0b0d; --sc-surface: #161618;
  --sc-ink: #f5f5f7;    --sc-ink-soft: #a1a1a6;
  --sc-accent: #2997ff; --sc-accent-ink: #0b0b0d;
  --hair: rgb(255 255 255 / 0.14);
  background: var(--sc-canvas); color: var(--sc-ink);
  /* Light type on dark: one notch more tracking and leading. */
  letter-spacing: 0;
}

/* The fixed bar must never cover an anchored heading or a focused link. */
html { scroll-padding-top: calc(var(--bar-h) + 0.5rem); }
[id] { scroll-margin-top: calc(var(--bar-h) + 0.5rem); }
@media (pointer: fine) { html { overscroll-behavior: none; } }

body { font-feature-settings: "kern"; }
a { -webkit-tap-highlight-color: transparent; }
h1, h2, h3, h4 { font-family: var(--sc-font-display); font-weight: 600; margin: 0; }
p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
strong, b { font-weight: 600; }

.vh {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: fixed; left: 1rem; top: 1rem; z-index: 100;
  padding: 0.6rem 1rem; border-radius: 999px;
  background: var(--sc-ink); color: var(--sc-canvas); text-decoration: none;
  transform: translateY(-200%);
}
.skip:focus-visible { transform: none; }

/* Content Gabriel still has to supply or confirm. check-placeholders.mjs
   blocks a production deploy while any of these remain. */
mark.tbd {
  background: #ffe48a; color: #3d2e00; border-radius: 4px;
  padding: 0.05em 0.25em; box-decoration-break: clone; -webkit-box-decoration-break: clone;
}

/* ------------------------------------------------------------- controls -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem; padding: 0.7rem 1.35rem;
  border-radius: 999px;
  background: var(--btn); color: #fff;
  font-size: 1.0625rem; font-weight: 400; line-height: 1.2; letter-spacing: -0.01em;
  text-decoration: none; white-space: nowrap;
  transition: background-color 160ms var(--sc-ease-out), transform 120ms var(--sc-ease-out);
  touch-action: manipulation;
}
.btn:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--btn-hover); }
}
.btn--sm { min-height: 2rem; padding: 0.35rem 0.9rem; font-size: 0.8125rem; }
/* Secondary action: same shape, outlined, so LinkedIn stays the first choice. */
.btn--line { background: transparent; color: var(--btn); box-shadow: inset 0 0 0 1.5px var(--btn); }
@media (hover: hover) and (pointer: fine) {
  .btn--line:hover { background: color-mix(in srgb, var(--btn) 8%, transparent); }
}

/* An outbound text link: accent, with an arrow that says "leaves the page". */
.out, .role__link, .tile__link {
  color: var(--sc-accent); text-decoration: none;
  touch-action: manipulation;
}
.role__link::after, .tile__link::after { content: " ↗" / ""; font-size: 0.9em; }
.role__link:active, .tile__link:active { opacity: 0.7; }
@media (hover: hover) and (pointer: fine) {
  .role__link:hover, .tile__link:hover { text-decoration: underline; text-underline-offset: 0.2em; }
  .bar__name:hover { opacity: 0.8; }
}

.ctas { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.5rem; }
.ctas--center { justify-content: center; }

/* ------------------------------------------------------------ the bar -- */
.bar {
  position: fixed; inset: 0 0 auto 0; z-index: var(--sc-z-chrome);
  height: var(--bar-h);
  display: flex; align-items: center; justify-content: space-between;
  padding-left: max(var(--sc-gutter), env(safe-area-inset-left));
  padding-right: max(var(--sc-gutter), env(safe-area-inset-right));
  background: rgb(22 22 23 / 0.82);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  color: #f5f5f7;
  --sc-accent: #2997ff;
  opacity: 0; visibility: hidden;
  transition: opacity 240ms var(--sc-ease-out), visibility 0s linear 240ms;
}
.bar.is-on { opacity: 1; visibility: visible; transition: opacity 240ms var(--sc-ease-out), visibility 0s; }
html:not(.js) .bar { display: none; }
.bar__name {
  font-family: var(--sc-font-display); font-weight: 600; font-size: 1rem;
  letter-spacing: -0.01em; text-decoration: none; color: inherit;
}

/* --------------------------------------------------------------- 1 hero -- */
.hero {
  min-height: 100vh; min-height: 100svh;
  display: flex; align-items: center;
  padding: clamp(1.25rem, 4vh, 3rem) var(--sc-gutter);
}
.hero__grid {
  width: 100%; max-width: var(--sc-maxw); margin-inline: auto;
  display: grid; gap: 0 clamp(2rem, 5vw, 5rem);
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "text photo";
  align-items: center;
}
.hero__text { grid-area: text; }
.hero__photo { grid-area: photo; align-self: center; }

.hero__name {
  font-size: min(clamp(3.4rem, 1.2rem + 7.4vw, 8.5rem), 12.2vh);
  line-height: 0.92;
  letter-spacing: -0.045em;
  text-wrap: balance;
}
.hero__name span { display: block; }
.hero__role {
  margin-top: clamp(0.9rem, 2.2vh, 1.6rem);
  max-width: 22ch;
  font-family: var(--sc-font-display);
  font-size: clamp(1.4rem, 1rem + 1.4vw, 2.4rem);
  font-weight: 600; line-height: 1.12; letter-spacing: -0.028em;
  color: var(--sc-ink);
  text-wrap: balance;
}
.hero .ctas { margin-top: clamp(1rem, 2.6vh, 1.75rem); }

.hero__photo img {
  width: auto; height: min(72vh, 46rem); max-height: 72svh;
  aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: var(--radius-photo);
  box-shadow: var(--sc-e2);
}

/* Areas of strength under the value statement: a small label, then three
   areas read across. */
.proofs__label {
  margin-top: clamp(1.5rem, 4vh, 2.75rem);
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.proofs {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem clamp(1.25rem, 3vw, 2.5rem);
  margin-top: 0.6rem; padding-top: clamp(1rem, 2.5vh, 1.5rem);
  border-top: 1px solid var(--hair); max-width: 44rem;
}
.proofs li { display: grid; align-content: start; gap: 0.15rem; }
.proofs strong {
  font-family: var(--sc-font-display); font-weight: 600;
  font-size: clamp(1.25rem, 0.95rem + 0.8vw, 1.6rem); line-height: 1.1; letter-spacing: -0.025em;
}
@media (min-width: 760px) { .proofs strong { white-space: nowrap; } }
.proofs span { font-size: 0.875rem; line-height: 1.35; color: var(--sc-ink-soft); max-width: 13rem; text-wrap: balance; }
.hero .ctas { margin-top: clamp(1.25rem, 3.5vh, 2.25rem); }

/* -------------------------------------------------------------- 2 route -- */
.route__stage {
  display: grid;
  grid-template-columns: minmax(18rem, 36%) minmax(0, 1fr);
  grid-template-areas: "text map";
  gap: 0 clamp(1.5rem, 4vw, 4rem);
  padding: calc(var(--bar-h) + clamp(1.5rem, 5vh, 3.5rem)) var(--sc-gutter) clamp(1.5rem, 5vh, 3.5rem);
}
.route__text { grid-area: text; align-self: center; }
.route__statement {
  font-family: var(--sc-font-display); font-weight: 600;
  font-size: clamp(1.45rem, 0.75rem + 1.75vw, 2.4rem);
  line-height: 1.17; letter-spacing: -0.025em;
  text-wrap: pretty;
}
.route__statement .w { transition: opacity 120ms linear, color 240ms var(--sc-ease-out); }
.route__statement [data-stop].is-hit .w { color: var(--sc-accent); }

.route__map-wrap { grid-area: map; position: relative; min-height: 0; overflow: hidden; }
.route__map {
  position: absolute; inset: 0; width: 100%; height: 100%;
  /* Land fades out at the panel edges instead of stopping in a straight line. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent), linear-gradient(to bottom, transparent, #000 7%, #000 93%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent), linear-gradient(to bottom, transparent, #000 7%, #000 93%, transparent);
  mask-composite: intersect;
}

/* The edge is the fill colour: it closes the hairline seams between
   neighbouring countries in the GISCO outlines without drawing borders. */
.land { fill: #34343c; stroke: #34343c; stroke-width: 1; stroke-linejoin: round; }
.land--fine, .land--ultra { opacity: 0; }
/* A fine grain over the whole act, so the solid land reads as a surface.
   It covers the full frame, so it never draws a box of its own. */
.route__stage::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.07; mix-blend-mode: overlay; z-index: 2;
}
.leg {
  fill: none; stroke: var(--sc-accent); stroke-width: 2.5;
  stroke-linecap: round; stroke-linejoin: round;
}
/* main.js sets the dash from each leg's measured length and reveals it. */
.js .leg { visibility: hidden; }
.leg__head { fill: #fff; opacity: 0; }
.stop { opacity: 0; }
.stop__ring { fill: rgb(41 151 255 / 0.24); }
.stop__dot { fill: #fff; }

/* City labels: they stay on their city once the line has passed it. */
.route__labels { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.chip {
  position: absolute; left: 0; top: 0;
  display: grid; gap: 0.05rem;
  max-width: 13.5rem; padding: 0.45rem 0.65rem 0.5rem;
  border-radius: 12px;
  background: rgb(28 28 31 / 0.9);
  box-shadow: 0 1px 0 rgb(255 255 255 / 0.06) inset, 0 6px 18px -6px rgb(0 0 0 / 0.6);
  font-size: 0.75rem; line-height: 1.3; color: #d1d1d6;
  opacity: 0; will-change: transform, opacity;
}
.chip strong { font-size: 0.8125rem; color: #f5f5f7; letter-spacing: -0.005em; }
.chip small { margin-top: 0.1rem; font-size: 0.6875rem; color: #e5e5ea; white-space: nowrap; }
html:not(.js) .route__labels { position: static; display: grid; gap: 0.5rem; padding: 1rem 0; }
html:not(.js) .chip { position: static; opacity: 1; }
html:not(.js) .stop { opacity: 1; }

/* ------------------------------------------------------- 3 work experience */
.section-title {
  font-size: clamp(3rem, 1.6rem + 6vw, 7rem);
  line-height: 0.95; letter-spacing: -0.045em;
  padding-bottom: 0.08em;
  text-wrap: balance;
}
.work { padding-block: var(--sc-section) calc(var(--sc-section) * 0.5); }
.work .section-title { margin-bottom: clamp(2rem, 5vw, 4rem); }

.work__grid {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(2rem, 5vw, 5rem);
}

/* The media column holds still while the roles scroll past it. */
.work__media {
  position: sticky; top: calc(var(--bar-h) + 2rem); align-self: start;
  display: grid; gap: 1.25rem;
}
.media-stack {
  position: relative; aspect-ratio: 4 / 3; max-height: calc(100svh - var(--bar-h) - 10rem);
  border-radius: var(--radius-photo); overflow: hidden; background: #e8e8ed;
  box-shadow: var(--sc-e2);
}
.media {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  opacity: 0; transition: opacity 420ms var(--sc-ease-out);
}
.media.is-active { opacity: 1; }
.media[data-company="anticimex"] { background: #e6efe4; }
.media[data-company="verisure"]  { background: #f2e6e6; }
.media[data-company="tetrapak"]  { background: #e3ebf6; }
.media[data-company="siemens"]   { background: #e1efef; }
.media__photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* With a photo: the logo sits on a white plate, the tag on a scrim that only
   darkens the strip the text sits on. */
.media--photo { place-items: start; }
.media__plate {
  position: absolute; left: 1rem; top: 1rem; z-index: 2;
  display: grid; place-items: center;
  height: 3rem; padding: 0.55rem 0.8rem;
  border-radius: 12px; background: #fff;
  box-shadow: 0 6px 18px -6px rgb(0 0 0 / 0.45);
}
.media__plate { grid-auto-flow: column; gap: 0.7rem; }
.media__plate img { width: auto; height: 1.9rem; max-width: 9rem; object-fit: contain; }
.media__scrim {
  position: absolute; inset: auto 0 0 0; height: 38%; z-index: 1;
  background: linear-gradient(to top, rgb(0 0 0 / 0.62), rgb(0 0 0 / 0));
}
.media--photo .media__tag { z-index: 2; color: #fff; }
/* Product renders on white need no scrim; their caption goes dark. */
.media[data-company="tetrapak"] .media__scrim { display: none; }
.media[data-company="tetrapak"] .media__tag { color: #3a3a3f; }

/* Early career: two employers, so two half-width pictures, each with its own logo. */
.media--duo { grid-template-columns: 1fr 1fr; gap: 3px; place-items: stretch; background: #fff; }
.duo { position: relative; overflow: hidden; }
.duo .media__plate { left: 0.75rem; top: 0.75rem; height: 2.75rem; }
.duo .media__plate img { height: 1.7rem; max-width: 6.5rem; }
.duo .media__tag { left: 1rem; right: 1rem; bottom: 1rem; z-index: 2; color: #fff; font-size: 0.8125rem; }

/* On phones each role carries its own picture; the sticky band shows logos. */
.role__media { display: none; }
.media__mark {
  font-family: var(--sc-font-display); font-weight: 600;
  font-size: clamp(2.25rem, 1rem + 3vw, 4rem); letter-spacing: -0.045em; color: #1d1d1f;
}
.media__logo { width: 46%; height: auto; max-height: 28%; object-fit: contain; }
.media__tag {
  position: absolute; left: 1.25rem; bottom: 1.1rem; right: 1.25rem;
  font-size: 0.875rem; font-weight: 600; color: #3a3a3f;
}

/* Tenure ruler: July 2013 to today, every employer drawn to scale. */
.tenure { display: grid; gap: 0.5rem; }
html:not(.js) .tenure { display: none; }
.tenure__track { position: relative; height: 0.5rem; border-radius: 999px; background: var(--hair); }
.tenure__seg {
  position: absolute; top: 0; bottom: 0; min-width: 4px; border-radius: 999px;
  background: #b9b9c0; transition: background-color 240ms var(--sc-ease-out);
}
.tenure__seg.is-active { background: var(--sc-accent); }
.tenure__axis { position: relative; height: 1rem; font-size: 0.6875rem; color: var(--sc-ink-soft); font-variant-numeric: tabular-nums; }
.tenure__axis span { position: absolute; top: 0; transform: translateX(-50%); }
.tenure__readout { font-size: 0.875rem; color: var(--sc-ink-soft); font-variant-numeric: tabular-nums; min-height: 1.3em; }
.tenure__readout b { color: var(--sc-ink); }

.role {
  min-height: 62svh;
  padding-block: clamp(2.5rem, 6vh, 4.5rem);
  border-top: 1px solid var(--hair);
  font-size: var(--sc-t-base); line-height: 1.6;
}
.role:first-child { border-top: 0; padding-top: 0; }
.role > p + p { margin-top: 0.9rem; }
.role__head { margin-bottom: 1.25rem; }
.role__logo { display: block; width: auto; height: 1.75rem; max-width: 9rem; object-fit: contain; object-position: left center; margin-bottom: 0.9rem; }
/* Square or stacked marks need more height to read at the same weight. */
.role__logo[data-tall] { height: 3rem; }
/* Early career holds two employers, each line led by its own logo. */
.role__logo--sub { margin: 1.75rem 0 0.6rem; }
.role__co { font-size: clamp(2rem, 1.2rem + 2.4vw, 3.4rem); line-height: 1.02; letter-spacing: -0.04em; text-wrap: balance; }
.role__title {
  margin-top: 0.6rem;
  font-family: var(--sc-font-display); font-weight: 600;
  font-size: var(--sc-t-lg); line-height: 1.3; letter-spacing: -0.015em;
}
.role__title + .role__title { margin-top: 0.35rem; }
.role__dates { display: block; font-family: var(--sc-font-text); font-weight: 400; font-size: var(--sc-t-sm); color: var(--sc-ink-soft); letter-spacing: 0; }
.role__meta { margin-top: 0.4rem; font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }
.role__span { white-space: nowrap; }
.role__link { display: inline-block; margin-top: 0.4rem; font-size: var(--sc-t-sm); }
.role__label {
  margin-top: 1.75rem; margin-bottom: 0.75rem;
  font-size: var(--sc-t-sm); font-weight: 600; color: var(--sc-ink-soft); letter-spacing: 0;
}
.role__wins { display: grid; gap: 0.75rem; }
.role__wins li { position: relative; padding-left: 1.25rem; text-wrap: pretty; }
.role__wins li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 0.4rem; height: 0.4rem; border-radius: 50%; background: var(--sc-accent);
}

/* ---------------------------------------------------------- 4 background -- */
.background { padding-block: var(--sc-section); }
.background__title-wrap { padding-bottom: 0.1em; margin-bottom: clamp(1rem, 3vw, 2rem); }
.group-title {
  margin: clamp(2.5rem, 5vw, 3.5rem) 0 1rem;
  font-size: var(--sc-t-xl); letter-spacing: -0.02em; line-height: 1.2;
}
.group-title--in { margin: 0 0 1.25rem; font-size: var(--sc-t-lg); }
.tiles { display: grid; gap: 1rem; }
.tiles--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tiles--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tiles--split { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.tile {
  --tile-pad: clamp(1.25rem, 2.2vw, 1.75rem);
  display: flex; flex-direction: column; gap: 0.35rem;
  padding: var(--tile-pad);
  border-radius: var(--radius-tile);
  background: var(--sc-surface);
  box-shadow: var(--sc-edge);
}
/* Logos keep their own colours on a small white plate rather than being
   recoloured for the dark ground (some brand rules forbid that). */
.tile__mark {
  align-self: flex-start; display: grid; place-items: center;
  width: 3.75rem; height: 3.75rem; margin-bottom: 0.9rem; padding: 0.45rem;
  border-radius: 14px; background: #fff; box-shadow: 0 0 0 1px var(--hair);
}
.tile__mark img { width: 100%; height: 100%; object-fit: contain; }
.tile__logo {
  align-self: flex-start; display: grid; place-items: center;
  height: 2.75rem; margin-bottom: 0.75rem; padding: 0.45rem 0.7rem;
  border-radius: 10px; background: #fff;
}
.tile__logo img { width: auto; height: 1.85rem; max-width: 8rem; object-fit: contain; }
.tile__seal { width: 4.5rem; height: 4.5rem; margin-bottom: 0.5rem; object-fit: contain; }
.tile__kicker { font-size: var(--sc-t-sm); color: var(--sc-accent); font-variant-numeric: tabular-nums; }
.tile__name { font-size: var(--sc-t-lg); line-height: 1.25; letter-spacing: -0.015em; text-wrap: balance; }
.tile__sub { color: var(--sc-ink-soft); line-height: 1.45; text-wrap: pretty; }
.tile__link { margin-top: auto; padding-top: 0.75rem; font-size: var(--sc-t-sm); line-height: 1.4; }
/* Other highlights open with a photo or gallery that runs to the tile's edges. */
.tile__photo {
  margin: calc(-1 * var(--tile-pad)) calc(-1 * var(--tile-pad)) 0.9rem;
  aspect-ratio: 3 / 2; overflow: hidden;
  border-radius: var(--radius-tile) var(--radius-tile) 0 0; background: #e8e8ed;
}
.tile__photo img { width: 100%; height: 100%; object-fit: cover; }
/* Highlight galleries: a native swipe strip that snaps one photo at a time.
   Touch swipes, trackpads and arrow keys move it; the counter button and a
   mouse drag do too (main.js). Without JS the strip still swipes. */
.gallery { position: relative; }
.gallery__track {
  position: absolute; inset: 0; display: flex;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none;
  cursor: grab;
}
.gallery__track::-webkit-scrollbar { display: none; }
.gallery__track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.gallery__track:focus-visible { outline-offset: -3px; }
.gallery__img {
  flex: 0 0 100%; width: 100%; height: 100%; object-fit: cover;
  scroll-snap-align: start; scroll-snap-stop: always;
  -webkit-user-drag: none; user-select: none;
}
.gallery__bar {
  position: absolute; left: 0.6rem; right: 0.6rem; bottom: 0.6rem; z-index: 1;
  display: flex; justify-content: space-between; align-items: center; gap: 0.5rem;
  pointer-events: none;
}
.gallery__bar > * { pointer-events: auto; }
.gallery__cap, .gallery__next {
  padding: 0.3rem 0.6rem; border-radius: 999px;
  background: rgb(0 0 0 / 0.62); color: #fff;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  font-size: 0.75rem; font-weight: 600; line-height: 1.3;
}
.gallery__next { border: 0; font-family: inherit; cursor: pointer; font-variant-numeric: tabular-nums; min-height: 1.75rem; }
@media (hover: hover) and (pointer: fine) { .gallery__next:hover { background: rgb(0 0 0 / 0.8); } }
html:not(.js) .gallery__next { display: none; }
/* Dots say "there is more to swipe"; the current one stretches. */
.gallery__dots {
  display: flex; gap: 4px; padding: 0.45rem 0.55rem; border-radius: 999px;
  background: rgb(0 0 0 / 0.45); pointer-events: none;
}
.gallery__dots i { width: 6px; height: 6px; border-radius: 3px; background: rgb(255 255 255 / 0.5); transition: width 240ms var(--sc-ease-out), background-color 240ms; }
.gallery__dots i.is-on { width: 14px; background: #fff; }
@media (prefers-reduced-motion: reduce) { .gallery__dots i { transition: none; } }

.flags { display: flex; flex-wrap: wrap; gap: 1rem 2rem; }
.flags li { display: flex; align-items: center; gap: 0.6rem; }
.flags img { width: 1.75rem; height: 1.75rem; border-radius: 50%; box-shadow: 0 0 0 1px rgb(255 255 255 / 0.12); }
.flags b { color: var(--sc-ink-soft); font-weight: 600; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- 5 close -- */
.close__stage {
  display: grid; grid-template-rows: 1fr auto;
  padding: calc(var(--bar-h) + 2rem) var(--sc-gutter) max(1.5rem, env(safe-area-inset-bottom));
  text-align: center;
}
.close__inner { align-self: center; display: grid; justify-items: center; }
.close__title {
  font-size: clamp(3.4rem, 1.6rem + 8vw, 9rem);
  line-height: 0.95; letter-spacing: -0.05em;
}
.close__sub { margin-top: 1.25rem; font-size: var(--sc-t-lg); color: var(--sc-ink-soft); }
/* The close comes alive: each word rises in as the section arrives, then a
   slow blue light sweeps across the words while it stays on screen. main.js
   arms it and toggles .is-live; reduced motion keeps it still. */
.close__word { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .close.is-armed .close__word {
    color: transparent;
    background: linear-gradient(100deg, var(--sc-ink) 0 38%, #2997ff 47%, #0066cc 53%, var(--sc-ink) 62% 100%);
    background-size: 300% 100%; background-position: 100% 0;
    -webkit-background-clip: text; background-clip: text;
    opacity: 0; transform: translateY(0.3em);
  }
  .close.is-live .close__word {
    animation: close-rise 900ms var(--sc-ease-out) forwards, close-sweep 7s ease-in-out 1.2s infinite;
  }
  .close.is-live .close__word + .close__word { animation-delay: 140ms, 1.45s; }
}
@keyframes close-rise { to { opacity: 1; transform: none; } }
@keyframes close-sweep {
  0% { background-position: 100% 0; }
  32%, 100% { background-position: 0% 0; }
}
.close .ctas { margin-top: 2rem; }
.close__mail { color: var(--sc-accent); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .close__mail:hover { text-decoration: underline; text-underline-offset: 0.2em; } }
.foot { display: grid; justify-items: center; gap: 0.25rem; font-size: var(--sc-t-xs); color: var(--sc-ink-soft); }
/* Credits stay out of the way: one small line until someone asks. */
.credits summary {
  cursor: pointer; list-style: none; font-size: 0.6875rem; color: var(--sc-ink-soft);
  opacity: 0.8; touch-action: manipulation;
}
.credits summary::-webkit-details-marker { display: none; }
.credits summary:hover { opacity: 1; text-decoration: underline; text-underline-offset: 0.2em; }
.credits ul { margin-top: 0.4rem; max-width: 40rem; font-size: 0.6875rem; line-height: 1.5; }
.credits a { color: inherit; }

/* ------------------------------------------------------------- tablets -- */
@media (max-width: 1100px) {
  .tiles--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* -------------------------------------------------------------- phones --
   Separate composition, not a shrink: the portrait leads at full width and
   takes whatever height the text leaves, so everything a recruiter needs
   still fits one screen. Portrait tablets get the same composition. Vertical
   rhythm is in svh so a short phone (iPhone SE with browser bars) fits too. */
@media (max-width: 759px), (max-width: 1100px) and (orientation: portrait) {
  .hero {
    height: 100vh; height: 100svh; min-height: 0; align-items: stretch;
    padding-top: max(clamp(0.75rem, 2.4svh, 2rem), env(safe-area-inset-top)); padding-bottom: clamp(0.9rem, 2.4svh, 1.5rem);
  }
  .hero__grid {
    grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas: "photo" "text"; gap: clamp(0.9rem, 2.6svh, 1.75rem); align-items: stretch;
  }
  /* The photo is laid out out of flow, so it takes only the height the grid
     row gives it and can never push into the text below. */
  .hero__photo { display: block; position: relative; align-self: stretch; min-height: 0; margin: 0; overflow: hidden; border-radius: 22px; }
  .hero__photo img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; max-height: none; aspect-ratio: auto;
    object-fit: cover; object-position: 50% 12%;
    border-radius: 0; box-shadow: none;
  }
  .proofs__label { margin-top: clamp(0.9rem, 2.6svh, 1.75rem); font-size: 0.6875rem; }
  .proofs { display: flex; flex-wrap: wrap; gap: 0.9rem 1.5rem; margin-top: 0.45rem; padding-top: clamp(0.6rem, 1.6svh, 1rem); }
  .proofs li { min-width: 0; flex: 1 1 8.5rem; }
  .proofs strong { font-size: clamp(1.15rem, 0.9rem + 1.6vw, 1.5rem); }
  .proofs span { font-size: 0.8125rem; }
  .hero__name { font-size: clamp(2.2rem, 10vw, 5.5rem); line-height: 0.95; letter-spacing: -0.04em; }
  .hero__role { margin-top: clamp(0.5rem, 1.8svh, 1.25rem); font-size: clamp(1rem, 0.78rem + 1.5vw, 1.75rem); max-width: 34ch; line-height: 1.25; }
  .hero .ctas { margin-top: clamp(0.6rem, 2svh, 1.5rem); }

  .route__stage {
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "text" "map";
    padding-top: calc(var(--bar-h) + 1.25rem);
    padding-bottom: max(1rem, env(safe-area-inset-bottom));
    gap: 1rem;
  }
  .route__statement { font-size: clamp(1.1rem, 0.85rem + 1.6vw, 1.9rem); line-height: 1.22; }
  .chip { max-width: 11rem; font-size: 0.6875rem; padding: 0.35rem 0.5rem 0.4rem; }
  .chip strong { font-size: 0.75rem; }
  .chip small { font-size: 0.6875rem; }
}

/* Short phones (an iPhone SE with Safari's bars showing is 548px tall):
   the name goes to one line and the rhythm tightens so all of it still fits. */
@media (max-width: 759px) and (max-height: 700px) {
  .hero__name { font-size: clamp(1.75rem, 8.6vw, 2.25rem); }
  .hero__name span { display: inline; }
  .hero__role { font-size: 1.0625rem; line-height: 1.22; }
  .hero .btn { min-height: 2.5rem; padding-block: 0.55rem; }
}

@media (max-width: 899px) {
  :root { --sc-gutter: 1.25rem; }
  .work__grid { grid-template-columns: 1fr; gap: 0; }
  /* On a phone the media column becomes a slim band that sticks under the
     bar and swaps as each employer scrolls past. */
  .work__media {
    top: var(--bar-h); z-index: 5; height: auto;
    grid-template-columns: 4.25rem minmax(0, 1fr); grid-template-rows: auto;
    align-items: center; gap: 0.9rem;
    margin-inline: calc(-1 * var(--sc-gutter)); padding: 0.75rem var(--sc-gutter);
    background: rgb(245 245 247 / 0.92);
    -webkit-backdrop-filter: saturate(180%) blur(16px); backdrop-filter: saturate(180%) blur(16px);
    border-bottom: 1px solid var(--hair);
  }
  .media-stack { aspect-ratio: auto; width: 4.25rem; height: 4.25rem; max-height: none; border-radius: 14px; background: #fff; }
  .media__mark { font-size: 0.875rem; letter-spacing: -0.02em; text-align: center; }
  .media__logo { width: 72%; }
  .media__tag, .media__scrim, .media__photo { display: none !important; }
  .role__media {
    display: block; margin: 0 0 1.25rem; aspect-ratio: 4 / 3;
    border-radius: 18px; overflow: hidden; background: #e8e8ed;
  }
  .role__media img { width: 100%; height: 100%; object-fit: cover; }
  .role__media--duo { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; background: #fff; }
  .media--duo { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; gap: 0; }
  .duo .media__plate { inset: 0; height: auto; padding: 0.3rem 0.4rem; }
  .duo .media__plate img { width: auto; height: 1.3rem; max-width: 100%; max-height: none; }
  .media__plate { inset: 0; height: auto; padding: 0.5rem; border-radius: 0; box-shadow: none; }
  .media__plate img { width: auto; height: auto; max-width: 100%; max-height: 100%; }
  .tenure { gap: 0.3rem; }
  .tenure__readout { font-size: 0.8125rem; }
  .role { min-height: 0; padding-block: 2.25rem; }
  /* Keep focused links clear of the sticky band as well as the bar. */
  .work a { scroll-margin-top: calc(var(--bar-h) + 6.5rem); }
  .role:first-child { padding-top: 1.5rem; }
  .tiles--3, .tiles--2, .tiles--split { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------- reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  .bar, .bar.is-on { transition: none; }
  .btn { transition: none; }
  .route__statement .w { transition: none; }
  .media { transition: none; }
  .tenure__seg { transition: none; }
}

/* -------------------------------------------------------------- skills -- */
/* Three tiers of depth. The column states the level, a small three-step
   meter repeats it at a glance, and each skill carries one line of proof.
   The meters fill once, segment by segment, when the tile comes into view
   (main.js arms them only when motion is allowed). Hovering or tapping a
   skill marks it with a thin accent line. */
.skills {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.75rem clamp(1.5rem, 3vw, 3rem);
}
.tier__name {
  display: flex; align-items: center; gap: 0.6rem;
  padding-bottom: 0.85rem; border-bottom: 1px solid var(--hair);
  font-size: var(--sc-t-sm); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.tier__meter { display: inline-flex; gap: 3px; }
.tier__meter i {
  position: relative; overflow: hidden;
  width: 0.9rem; height: 0.3rem; border-radius: 2px; background: #d2d2d7;
}
.tier__meter i::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--sc-accent); transform: scaleX(0); transform-origin: left center;
}
/* Only the fill animates; arming empties the meters at once. */
.tier.is-filled .tier__meter i::after { transition: transform 420ms cubic-bezier(0.3, 0.7, 0.2, 1); }
.tier.is-filled .tier__meter i:nth-child(2)::after { transition-delay: 180ms; }
.tier.is-filled .tier__meter i:nth-child(3)::after { transition-delay: 360ms; }
.tier[data-level="3"] .tier__meter i::after,
.tier[data-level="2"] .tier__meter i:nth-child(-n+2)::after,
.tier[data-level="1"] .tier__meter i:first-child::after { transform: none; }
.tier.is-armed:not(.is-filled) .tier__meter i::after { transform: scaleX(0); }
.tier__list { display: grid; gap: 1.1rem; margin-top: 1.1rem; }
.tier__list > div { position: relative; }
.tier__list > div::before {
  content: ""; position: absolute; left: -0.85rem; top: 0.1rem; bottom: 0.1rem;
  width: 2px; border-radius: 2px; background: var(--sc-accent);
  transform: scaleY(0); transform-origin: top center; transition: transform 220ms ease;
}
.tier__list dt { font-size: var(--sc-t-lg); font-weight: 600; letter-spacing: -0.015em; line-height: 1.25; }
.tier__list dd { margin-top: 0.2rem; color: var(--sc-ink-soft); line-height: 1.4; text-wrap: pretty; transition: color 220ms ease; }
@media (hover: hover) {
  .tier__list > div:hover::before { transform: none; }
  .tier__list > div:hover dd { color: var(--sc-ink); }
}
.tier__list > div.is-focus::before { transform: none; }
.tier__list > div.is-focus dd { color: var(--sc-ink); }
@media (prefers-reduced-motion: reduce) {
  .tier__meter i::after, .tier__list > div::before, .tier__list dd { transition: none; }
}
/* A suggestion Gabriel has not confirmed yet. check-placeholders.mjs counts it. */
.tier__list > div[data-tbd] {
  margin: -0.4rem -0.6rem; padding: 0.4rem 0.6rem; border-radius: 10px;
  background: #fff8db; outline: 1.5px dashed #c9a000; outline-offset: -1.5px;
}
.skills__tools {
  grid-column: 1 / -1; padding-top: 1.1rem; border-top: 1px solid var(--hair);
  font-size: var(--sc-t-sm); color: var(--sc-ink-soft);
}
.skills__tools span:first-child { font-weight: 600; color: var(--sc-ink); margin-right: 0.5rem; }
@media (max-width: 759px) {
  .skills { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ 404 -- */
.nf { min-height: 100vh; min-height: 100svh; }
