/* =============================================
   RENIER — EDITORIAL PORTFOLIO
   Headings: Oswald · Everything else: Inter
============================================= */
:root {
  --bg: #f7f7f5;
  --tint: #e8e8e3;
  --white: #ffffff;
  --text: #171717;
  --muted: #5c5c5c;
  --line: #dededa;
  --ink: #171717;

  --f-display: "Oswald", "Archivo Narrow", "Arial Narrow", sans-serif;
  --f-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* spacing scale */
  --s1: 0.5rem;
  --s2: 1rem;
  --s3: 1.5rem;
  --s4: 2.5rem;
  --s5: 4rem;
  --s6: 6rem;
  --s-sec: clamp(4.5rem, 9vw, 8rem);
  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --max: 1360px;
  --gut: clamp(0.5rem, 1.1vw, 1rem);
  --r: 1.75rem; /* sheet corner / overlap */
  --r-img: 6px;
  --head-h: 4.5rem;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* type scale */
  --t-hero: clamp(3rem, 7vw, 6.5rem);
  --mag: 1; /* travel multiplier for the joining text effect */
  --ease-mag: cubic-bezier(0.16, 1, 0.3, 1);
  --t-h2: clamp(1.9rem, 3.4vw, 2.75rem);
  --t-h3: clamp(1.15rem, 1.7vw, 1.5rem);
  --t-body: 0.9375rem;
  --t-small: 0.75rem;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
body {
  background: var(--bg);
  color: var(--text);
  font: 400 var(--t-body)/1.7 var(--f-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img {
  display: block;
  max-width: 100%;
}
img {
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}
.hero-photo img,
.about-photo img,
.gal-item img,
.lightbox img {
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}
a {
  color: inherit;
  text-decoration: none;
}
ul,
ol {
  list-style: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}
em {
  font-family: inherit;
  font-style: normal;
  font-weight: 600;
  text-transform: none;
}
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}
::selection {
  background: var(--ink);
  color: var(--bg);
}

.skip {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 200;
  background: var(--ink);
  color: var(--bg);
  padding: 0.6rem 1rem;
  border-radius: 99px;
  font-size: 0.85rem;
  transition: top 0.2s;
}
.skip:focus {
  top: 1rem;
}

.label {
  font: 500 var(--t-small)/1.4 var(--f-body);
  letter-spacing: 0.01em;
  color: var(--muted);
}

/* ---------- HEADER ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.1rem var(--pad);
  pointer-events: none;
  transition:
    background 0.3s,
    padding 0.3s;
}
.site-header > * {
  pointer-events: auto;
}
.site-header.scrolled {
  background: rgba(247, 247, 245, 0.94);
  border-bottom: 1px solid var(--line);
  padding-block: 0.75rem;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font: 500 0.9rem/1 var(--f-display);
  letter-spacing: 0.02em;
}
.brand-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--ink);
}
.pill {
  position: relative;
}
.menu-list {
  display: flex;
  gap: 0.1rem;
  background: var(--ink);
  color: var(--bg);
  padding: 0.3rem;
  border-radius: 99px;
}
.menu-list a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1rem;
  border-radius: 99px;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  opacity: 0.8;
  transition:
    opacity 0.25s,
    background 0.25s;
}
.menu-list a:hover,
.menu-list a:focus-visible {
  opacity: 1;
  background: rgba(255, 255, 255, 0.12);
}
.menu-list a.active {
  opacity: 1;
  background: rgba(255, 255, 255, 0.18);
}
.menu-list a:focus-visible {
  outline-color: var(--bg);
  outline-offset: -2px;
}
.menu-btn {
  display: none;
}

/* ---------- SHARED ---------- */
.in {
  max-width: var(--max);
  margin-inline: auto;
  transform-origin: 50% 100%;
}

/* every section after the hero is a "sheet": opaque, rounded top, overlaps the one before */
.sheet {
  position: relative;
  z-index: 1;
  background: var(--bg);
  border-radius: var(--r) var(--r) 0 0;
  margin-top: calc(var(--r) * -1);
  padding: var(--s-sec) var(--pad);
  box-shadow: 0 -16px 36px -20px rgba(0, 0, 0, 0.3); /* lifts each sheet off the one beneath */
}
.sheet.tint {
  background: var(--tint);
}

.sec-head {
  display: block;
  padding-bottom: var(--s3);
  margin-bottom: var(--s5);
  border-bottom: 1px solid var(--ink);
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
h2 {
  font: 600 var(--t-h2)/1.1 var(--f-display);
  letter-spacing: 0;
}
h2 em {
  font-size: 1.1em;
  letter-spacing: 0;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  min-height: 44px;
  padding: 0.7rem 1.3rem;
  border-radius: 99px;
  font-size: 0.82rem;
  font-weight: 500;
  transition:
    transform 0.3s var(--ease),
    background 0.3s;
}
.btn-solid {
  background: var(--ink);
  color: var(--bg);
}
.btn-solid:hover {
  transform: translateY(-2px);
  background: #000;
}
.btn-full {
  width: 100%;
  justify-content: space-between;
}
.btn-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.85rem;
  font-weight: 500;
  box-shadow: inset 0 -1px 0 var(--ink);
  transition: opacity 0.25s;
}
.btn-link:hover {
  opacity: 0.55;
}

/* reveal (JS on only) */
.js .rv {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.8s var(--ease),
    transform 0.8s var(--ease);
}
.js .rv.on {
  opacity: 1;
  transform: none;
}

/* ---------- 1. HOME ---------- */
.hero {
  position: relative;
  z-index: 0;
  background: var(--bg);
  height: 100svh;
  min-height: 38rem;
  overflow: hidden;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: var(--s3);
  padding: 0 var(--pad);
  transform: scale(calc(1 - var(--p, 0) * 0.05));
  transform-origin: 50% 0;
  opacity: calc(1 - var(--p, 0) * 0.5);
}
.hero-copy {
  grid-column: 1 / 8;
  grid-row: 1;
  align-self: end;
  padding-bottom: calc(var(--s5) + var(--r));
  translate: 0 calc(var(--p, 0) * -3vh);
}
.hero-name {
  font: 700 var(--t-hero)/0.94 var(--f-display);
  letter-spacing: -0.01em;
}
.hn-line {
  display: block;
}
@media (min-width: 861px) {
  .hn-line {
    white-space: nowrap;
  }
} /* keep the intended two-line composition on desktop; mobile wraps naturally */
.hero-role {
  margin-top: var(--s3);
  font: 500 clamp(1.05rem, 1.5vw, 1.3rem)/1.3 var(--f-body);
  letter-spacing: 0.01em;
}
.rp {
  white-space: nowrap;
}
.rp-dot {
  margin-inline: 0.12em;
  opacity: 0.55;
}

/* magnetic joining text: words start offset from different directions and settle into place.
   Pure CSS (no JS, no layout shift: only the `translate` property moves). Final state = normal text. */
.mw {
  display: inline-block;
}
.mt:not(.mt-on) [data-join] .mw {
  opacity: 0;
  animation: mt-show 0s 10.5s forwards;
} /* JS adds .mt-on once words are placed */
@keyframes mt-show {
  to {
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .mt [data-join] .mw {
    opacity: 1 !important;
    animation: none;
  }
}
.hero-intro {
  margin-top: var(--s2);
  max-width: 34ch;
  color: var(--muted);
}
.hero-actions {
  margin-top: var(--s4);
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex-wrap: wrap;
}

.hero-photo {
  grid-column: 8 / 13;
  grid-row: 1;
  margin: var(--head-h) calc(var(--pad) * -1) calc(var(--r) + var(--s3)) 0;
  background: var(--tint);
  overflow: hidden;
  position: relative;
  border-radius: 0 0 0 clamp(5rem, 13vw, 12rem);
}
.hero-photo img {
  position: absolute;
  left: 0;
  top: -6%;
  width: 100%;
  height: 112%;
  object-fit: cover;
  object-position: 50% 20%;
  filter: grayscale(1) contrast(1.05);
  translate: 0 calc(var(--p, 0) * 6vh);
}

/* ---------- 2. ABOUT ---------- */
.about {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: var(--s3);
  align-items: center;
}
.about-photo {
  grid-column: 2 / 6;
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5.9;
  background: var(--line);
  border-radius: var(--r-img);
}
.about-text {
  grid-column: 7 / 12;
}
.about-text h2 {
  margin: var(--s2) 0 var(--s3);
}
.about-text h2 .about-hi {
  display: block;
  margin-bottom: 0.35rem;
  font: 500 clamp(1rem, 1.4vw, 1.15rem) / 1.3 var(--f-body);
  letter-spacing: 0;
  color: var(--muted);
}
.about-text h2 .about-name {
  display: block;
}
.about-lead {
  font: 500 clamp(1.1rem, 1.6vw, 1.35rem)/1.4 var(--f-body);
  margin-bottom: var(--s2);
}
.about-text p:not(.label):not(.about-lead) {
  color: #3a3a3a;
  max-width: 60ch;
}
.about-text p + p {
  margin-top: var(--s2);
}

/* social icon buttons (About) */
.socials {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}
.social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  color: var(--ink);
  transition:
    background 0.25s,
    color 0.25s,
    transform 0.25s var(--ease);
}
.social-btn:hover,
.social-btn:focus-visible {
  background: var(--ink);
  color: var(--bg);
  transform: translateY(-2px);
}
.label-end {
  margin-top: var(--s4);
}

/* parallax images: slightly oversized, moved by JS via --py (independent of hover scale) */
[data-parallax] {
  position: absolute;
  left: 0;
  top: -8%;
  width: 100%;
  height: 116%;
  object-fit: cover;
  object-position: 50% 30%;
  filter: grayscale(1) contrast(1.05);
  translate: 0 var(--py, 0px);
}
.about-photo img {
  object-position: 50% 25%;
}

/* ---------- DARK SECTIONS (shared texture language) ---------- */
.sheet.dark {
  --tx-line: rgba(255, 255, 255, 0.16);
  background: #121212;
  color: #f0f0ec;
  overflow: hidden;
  box-shadow: 0 -18px 40px -16px rgba(0, 0, 0, 0.55);
}
.sheet.dark::before {
  /* fine grain */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' 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 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url%28%23n%29'/%3E%3C/svg%3E");
  background-size: 220px 220px;
  opacity: 0.1;
}
.tex {
  /* contour lines, slower than the foreground */
  position: absolute;
  inset: -10% 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='380' viewBox='0 0 640 380'%3E%3Cg fill='none' stroke='white' stroke-opacity='.1' stroke-width='1' vector-effect='non-scaling-stroke'%3E%3Cpolyline points='0,18.0 16,22.1 32,26.0 48,29.5 64,32.2 80,34.2 96,35.3 112,35.6 128,35.0 144,33.8 160,32.0 176,29.9 192,27.6 208,25.4 224,23.3 240,21.6 256,20.2 272,19.3 288,18.6 304,18.2 320,18.0 336,17.8 352,17.4 368,16.7 384,15.8 400,14.4 416,12.7 432,10.6 448,8.4 464,6.1 480,4.0 496,2.2 512,1.0 528,0.4 544,0.7 560,1.8 576,3.8 592,6.5 608,10.0 624,13.9 640,18.0'/%3E%3Cpolyline points='0,67.8 16,71.5 32,74.0 48,75.4 64,75.5 80,74.6 96,72.6 112,70.0 128,66.9 144,63.6 160,60.3 176,57.3 192,54.8 208,52.8 224,51.3 240,50.4 256,49.8 272,49.4 288,49.1 304,48.7 320,47.9 336,46.8 352,45.1 368,42.9 384,40.4 400,37.6 416,34.8 432,32.1 448,29.9 464,28.5 480,27.9 496,28.4 512,30.1 528,32.9 544,36.8 560,41.5 576,46.8 592,52.4 608,58.0 624,63.2 640,67.8'/%3E%3Cpolyline points='0,115.7 16,115.7 32,114.2 48,111.5 64,107.9 80,103.6 96,99.2 112,94.8 128,90.7 144,87.3 160,84.6 176,82.6 192,81.3 208,80.5 224,80.1 240,79.8 256,79.3 272,78.5 288,77.2 304,75.4 320,72.9 336,70.0 352,66.8 368,63.5 384,60.5 400,58.0 416,56.4 432,55.9 448,56.8 464,59.1 480,62.8 496,67.8 512,73.8 528,80.5 544,87.6 560,94.6 576,101.1 592,106.8 608,111.2 624,114.2 640,115.7'/%3E%3Cpolyline points='0,150.2 16,145.5 32,140.0 48,134.3 64,128.7 80,123.5 96,119.1 112,115.6 128,113.0 144,111.4 160,110.4 176,109.9 192,109.6 208,109.3 224,108.5 240,107.3 256,105.3 272,102.7 288,99.5 304,96.0 320,92.4 336,89.1 352,86.5 368,84.9 384,84.6 400,85.9 416,88.8 432,93.4 448,99.5 464,106.8 480,115.0 496,123.5 512,131.9 528,139.6 544,146.2 560,151.4 576,154.8 592,156.3 608,155.9 624,153.8 640,150.2'/%3E%3Cpolyline points='0,157.8 16,154.9 32,152.3 48,150.0 64,148.3 80,147.0 96,146.1 112,145.7 128,145.5 144,145.4 160,145.3 176,145.1 192,144.6 208,143.8 224,142.7 240,141.4 256,139.9 272,138.3 288,136.9 304,135.8 320,135.1 336,135.1 352,135.9 368,137.4 384,139.6 400,142.6 416,146.2 432,150.1 448,154.1 464,158.1 480,161.8 496,164.9 512,167.3 528,168.8 544,169.4 560,169.0 576,167.9 592,166.0 608,163.5 624,160.7 640,157.8'/%3E%3Cpolyline points='0,181.7 16,179.2 32,177.4 48,176.2 64,175.6 80,175.4 96,175.4 112,175.4 128,175.3 144,174.8 160,174.0 176,172.7 192,171.2 208,169.3 224,167.5 240,165.8 256,164.5 272,163.8 288,164.0 304,165.1 320,167.2 336,170.4 352,174.4 368,179.2 384,184.5 400,190.0 416,195.3 432,200.1 448,204.2 464,207.2 480,209.1 496,209.7 512,209.0 528,207.2 544,204.4 560,200.9 576,196.9 592,192.7 608,188.6 624,184.9 640,181.7'/%3E%3Cpolyline points='0,205.5 16,204.8 32,204.6 48,204.7 64,205.0 80,205.0 96,204.7 112,204.0 128,202.7 144,201.0 160,199.0 176,197.0 192,195.1 208,193.7 224,193.1 240,193.5 256,195.0 272,197.8 288,201.9 304,207.0 320,213.1 336,219.7 352,226.4 368,233.0 384,238.9 400,243.9 416,247.5 432,249.6 448,250.1 464,249.0 480,246.4 496,242.6 512,237.9 528,232.5 544,227.0 560,221.6 576,216.8 592,212.6 608,209.3 624,207.0 640,205.5'/%3E%3Cpolyline points='0,233.5 16,234.0 32,234.4 48,234.4 64,233.8 80,232.7 96,231.0 112,229.0 128,226.9 144,225.0 160,223.6 176,223.1 192,223.7 208,225.8 224,229.2 240,234.2 256,240.4 272,247.6 288,255.5 304,263.5 320,271.2 336,278.2 352,283.9 368,288.0 384,290.2 400,290.5 416,288.9 432,285.4 448,280.5 464,274.4 480,267.6 496,260.7 512,254.0 528,247.9 544,242.7 560,238.6 576,235.7 592,234.0 608,233.2 624,233.1 640,233.5'/%3E%3Cpolyline points='0,274.5 16,274.5 32,274.1 48,273.5 64,272.7 80,271.8 96,271.1 112,270.5 128,270.4 144,270.8 160,271.8 176,273.5 192,275.9 208,278.9 224,282.3 240,286.1 256,289.9 272,293.5 288,296.7 304,299.4 320,301.2 336,302.1 352,302.1 368,301.1 384,299.3 400,296.8 416,293.7 432,290.3 448,286.8 464,283.5 480,280.4 496,277.9 512,275.9 528,274.5 544,273.6 560,273.3 576,273.4 592,273.7 608,274.1 624,274.4 640,274.5'/%3E%3Cpolyline points='0,303.8 16,302.9 32,302.0 48,301.2 64,300.6 80,300.6 96,301.2 112,302.7 128,305.0 144,308.2 160,312.2 176,316.8 192,321.8 208,326.8 224,331.6 240,335.8 256,339.1 272,341.4 288,342.5 304,342.2 320,340.7 336,338.0 352,334.4 368,330.0 384,325.2 400,320.3 416,315.7 432,311.5 448,307.9 464,305.2 480,303.3 496,302.2 512,301.9 528,302.1 544,302.6 560,303.3 576,304.0 592,304.5 608,304.6 624,304.4 640,303.8'/%3E%3Cpolyline points='0,331.9 16,331.4 32,331.5 48,332.4 64,334.3 80,337.3 96,341.3 112,346.3 128,352.0 144,358.1 160,364.2 176,370.0 192,375.1 208,379.1 224,381.7 240,382.8 256,382.2 272,380.0 288,376.3 304,371.5 320,365.7 336,359.5 352,353.2 368,347.1 384,341.7 400,337.2 416,333.7 432,331.3 448,330.1 464,329.8 480,330.2 496,331.1 512,332.3 528,333.4 544,334.3 560,334.8 576,334.8 592,334.4 608,333.6 624,332.7 640,331.9'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 640px 380px;
  translate: 0 var(--ty, 0px);
  opacity: calc(0.35 + var(--d, 1) * 0.65);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 18%, #000 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 18%, #000 82%, transparent 100%);
}
.dark .in {
  position: relative;
  z-index: 1;
}
/* Experience texture is a static picture: no parallax drift, no fade (!important beats the scroll scripts' inline values) */
#experience .tex {
  inset: 0;
  height: 100%;
  translate: none !important;
  transform: none !important;
  opacity: 1 !important;
  will-change: auto;
}
.dark .label {
  color: #a4a49f;
}
.dark .sec-head {
  border-bottom-color: var(--tx-line);
}
.dark .btn-solid {
  background: var(--bg);
  color: var(--ink);
}
.dark .btn-solid:hover {
  background: #fff;
}
.dark :focus-visible {
  outline-color: #ecece8;
}

/* ---------- EXPERIENCE: still texture ----------
   The grain + contour layers are screen-sized and stay put while only the text scrolls over them.
   (Padding moves from the section to .in so the sticky layers span the full section box,
   and overflow: clip, unlike hidden, doesn't break sticky.) */
#experience {
  padding: 0;
  overflow: hidden;
  overflow: clip;
}

#experience > .in {
  max-width: calc(var(--max) + 2 * var(--pad));
  padding: var(--s-sec) var(--pad);
}

#experience::before,
#experience > .tex {
  display: block;
  position: sticky;
  top: 0;
  left: 0;
  right: auto;
  bottom: auto;
  width: 100%;
  height: 100vh;
  margin-bottom: -100vh;
  translate: none;
  -webkit-mask-image: none;
  mask-image: none;
}

/* ---------- 4. EXPERIENCE (dark, two columns: date | content) ---------- */
.xp-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s4);
  padding: var(--s4) 0;
  border-top: 1px solid var(--tx-line);
  align-items: start;
}
.xp-row:first-child {
  border-top: 0;
  padding-top: 0;
}
.xp-when {
  display: grid;
  gap: 0.35rem;
  justify-items: end;
  text-align: right;
}
.xp-date {
  white-space: nowrap;
  font: 500 clamp(1rem, 1.5vw, 1.2rem)/1.2 var(--f-display);
  color: #bdbdb8;
}
.xp-type {
  font-size: var(--t-small);
  color: #a4a49f;
}
.xp-main h3 {
  font: 600 clamp(1.3rem, 2.1vw, 1.75rem)/1.1 var(--f-display);
  letter-spacing: 0;
}
.xp-org {
  margin-top: 0.3rem;
  font: 500 1.05rem/1.3 var(--f-body);
  color: #bdbdb8;
}
.xp-desc {
  margin-top: var(--s2);
  color: #d2d2cd;
  max-width: 62ch;
}
.xp-meta {
  margin-top: var(--s2);
  font-size: var(--t-small);
  color: #a4a49f;
}

/* ---------- 4. PROJECTS (unified panels) ---------- */
.work {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s3);
}
.proj {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  min-height: 15rem;
  padding: var(--s3) var(--s3) var(--s3);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  transition:
    border-color 0.3s,
    background 0.3s;
}
.proj-top {
  display: grid;
  gap: 0.25rem;
}
.proj-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s2);
}
.proj-year {
  flex: none;
  font-size: var(--t-small);
  color: var(--muted);
  white-space: nowrap;
}
.proj-cat {
  font-size: var(--t-small);
  color: var(--muted);
}
.proj-title {
  font: 600 var(--t-h3)/1.2 var(--f-display);
  letter-spacing: 0;
}
.proj-desc {
  color: #3a3a3a;
  max-width: 60ch;
}
.proj-foot {
  margin-top: auto;
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s2);
}
.proj-stack {
  font-size: var(--t-small);
  color: var(--muted);
}
.proj-arrow {
  font-size: 1.1rem;
  line-height: 1;
  transition: transform 0.3s var(--ease);
}
a.proj-link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
} /* whole panel is the hit area */
.proj:has(a.proj-link):hover {
  border-color: var(--ink);
  background: #fcfcfb;
}
.proj:has(a.proj-link):hover .proj-arrow {
  transform: translate(3px, -3px);
}
.proj:has(a.proj-link:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}
a.proj-link:focus-visible {
  outline: 0;
}

/* ---------- 5. GALLERY (dynamic bento) ----------
   Items are rendered from js/gallery-data.js. JS picks which pictures are feature tiles and places
   every tile on the grid (.is-bento). Fallback for very large sets: evenly fitted rows (.gal-row). */
.gal {
  display: flex;
  flex-direction: column;
  gap: var(--gut);
}
.gal.is-bento {
  display: grid;
  margin-inline: auto;
}
.gal.is-bento .gal-item {
  aspect-ratio: auto;
  flex: none;
}
.gal-row {
  display: flex;
  align-items: flex-start;
  gap: var(--gut);
  width: 100%;
  margin-inline: auto;
}
.gal-item {
  position: relative;
  display: block;
  flex: 1 1 0%;
  min-width: 0;
  padding: 0;
  overflow: hidden;
  border-radius: var(--r-img);
  background: var(--line);
  cursor: zoom-in;
  aspect-ratio: 4 / 5;
}
.gal-item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
  scale: var(--s, 1);
  transition:
    scale 1s var(--ease),
    opacity 0.4s;
}
.gal-item:hover,
.gal-item:focus-visible {
  --s: 1.03;
}
.gal noscript img {
  width: 100%;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(247, 247, 245, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4rem 1.25rem 1.5rem;
  opacity: 0;
  transition: opacity 0.3s;
  cursor: zoom-out;
}
.lightbox[hidden] {
  display: none;
}
.lightbox.open {
  opacity: 1;
}
.lightbox img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.lb-close {
  position: absolute;
  top: 1.1rem;
  right: var(--pad);
  padding: 0 1.1rem;
  min-height: 44px;
  border-radius: 99px;
  background: var(--ink);
  color: var(--bg);
  font-size: 0.85rem;
}

/* ---------- 6. SKILLS ---------- */
.skills {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s5) var(--s4);
}
.skill-col {
  border-top: 1px solid var(--line);
  padding-top: var(--s2);
}
.skill-col h3 {
  margin-bottom: var(--s2);
  font: 600 1.05rem/1.3 var(--f-body);
  color: var(--text);
  overflow-wrap: anywhere;
}
.skill-col li {
  font: 400 1rem/1.85 var(--f-body);
  color: #3a3a3a;
}

/* ---------- 7. CONTACT (light) ---------- */
.contact {
  display: grid;
  grid-template-columns: 6fr 5fr;
  column-gap: clamp(2rem, 8vw, 7rem);
  align-items: start;
}
.contact-text h2 {
  margin: var(--s2) 0 var(--s3);
}
.contact-line {
  color: var(--muted);
}
.clinks {
  margin-top: var(--s4);
}
.clinks li {
  border-top: 1px solid var(--line);
}
.clinks li:last-child {
  border-bottom: 1px solid var(--line);
}
.clinks a {
  display: block;
  padding: 0.8rem 0;
  font: 500 0.95rem/1.3 var(--f-display);
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
  transition: padding 0.35s var(--ease);
}
.clinks a:hover {
  padding-left: 0.7rem;
}
.cform {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: clamp(1.25rem, 3vw, 2rem);
}
.fgrp {
  margin-bottom: var(--s3);
}
.fgrp label {
  display: block;
  font-size: var(--t-small);
  letter-spacing: 0.01em;
  color: var(--muted);
  margin-bottom: 0.3rem;
}
.fgrp input,
.fgrp textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--text);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: 0.5rem 0;
  border-radius: 0;
  resize: vertical;
  transition: border-color 0.25s;
}
.fgrp input:focus,
.fgrp textarea:focus {
  outline: 0;
  border-color: var(--ink);
  box-shadow: 0 1px 0 var(--ink);
}
.fgrp input::placeholder,
.fgrp textarea::placeholder {
  color: #6e6e69;
}
#fsuccess {
  display: none;
  margin-top: var(--s2);
  font-size: 0.9rem;
}

/* ---------- FOOTER (textured black, its own sheet) ---------- */
.foot {
  padding-block: var(--s6) 0;
}
.foot .tex {
  -webkit-mask-image: none;
  mask-image: none;
} /* texture runs edge to edge here */
.foot-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--s4);
  flex-wrap: wrap;
  padding-bottom: var(--s5);
}
.foot-sign {
  font: 600 var(--t-h3)/1.15 var(--f-display);
}
.foot-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem var(--s3);
}
.foot-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.85rem;
  color: #d2d2cd;
  transition: color 0.25s;
}
.foot-nav a:hover {
  color: #fff;
}
.foot-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  padding-top: var(--s3);
  border-top: 1px solid var(--tx-line);
  font-size: var(--t-small);
  color: #a4a49f;
}
.foot-row a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.foot-row a:hover {
  color: #fff;
}
.foot-word {
  font: 700 clamp(3rem, 15vw, 13rem)/0.8 var(--f-display);
  text-align: center;
  color: rgba(255, 255, 255, 0.075);
  margin-top: var(--s4);
  transform: translateY(0.08em);
  user-select: none;
  white-space: nowrap;
  translate: calc(var(--wx, 0) * 1%) 0; /* driven by scroll (JS) */
  opacity: var(--wo, 1);
}
/* the motto reuses .foot-word so existing JS hooks keep working, but is static, readable and wraps by sentence */
.foot-word.foot-motto {
  font: 700 clamp(2.25rem, 9.5vw, 6.5rem)/1.05 var(--f-display);
  text-transform: none;
  text-align: center;
  letter-spacing: -0.01em;
  color: #ecece8;
  user-select: text;
  white-space: normal;
  transform: none;
  translate: none;
  opacity: 1;
  padding-bottom: var(--s5);
}
.foot-motto span {
  display: inline-block;
  white-space: nowrap;
} /* sentences wrap as units on narrow screens */
@media (min-width: 861px) {
  .foot-word.foot-motto {
    font-size: clamp(1.75rem, 3.1vw, 3.6rem);
    white-space: nowrap;
  } /* one line, left to right */
}
@media (max-width: 860px) {
  .foot-word.foot-motto {
    font-size: clamp(1.9rem, 8.5vw, 3.2rem);
  }
}

/* footer layout: centred name, links in one tidy row, centred motto */
.foot-top {
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--s3);
  padding-bottom: var(--s4);
}
.foot-nav {
  justify-content: center;
  gap: 0.2rem var(--s4);
}
.foot-nav a {
  padding: 0 0.1rem;
  position: relative;
}
.foot-nav a::after {
  content: "";
  position: absolute;
  left: 0.1rem;
  right: 0.1rem;
  bottom: 0.55rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s var(--ease);
}
.foot-nav a:hover::after,
.foot-nav a:focus-visible::after {
  transform: scaleX(1);
}
.foot-word.foot-motto {
  margin-top: var(--s5);
}
@media (max-width: 860px) {
  .foot-nav {
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: center;
    gap: 0.1rem var(--s4);
  }
  .foot-row {
    justify-content: center;
    text-align: center;
  }
}

/* ---------- LAYERED SCROLL (desktop, motion allowed) ---------- */
@media (min-width: 861px) and (min-height: 560px) and (prefers-reduced-motion: no-preference) {
  .hero {
    position: sticky;
    top: 0;
  } /* hero stays put while About slides over it */
  .sheet.pin {
    position: sticky;
  } /* same for each pinned section; JS sets `top` so its bottom edge pins */
}

@media (max-width: 720px) {
  .skills {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ---------- MOBILE NAV + STACKING ---------- */
@media (max-width: 860px) {
  :root {
    --head-h: 4rem;
    --mag: 0.5;
    --t-hero: clamp(2.6rem, 14.5vw, 6.5rem);
  }
  .menu-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    background: none;
    color: var(--ink);
    padding: 0.6rem 0.75rem;
    margin-right: -0.75rem;
  }
  .menu-btn i {
    width: 1.1rem;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    position: relative;
    transition: background 0.2s 0.1s;
  }
  .menu-btn i::before,
  .menu-btn i::after {
    content: "";
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition:
      top 0.3s var(--ease),
      transform 0.3s var(--ease);
  }
  .menu-btn i::before {
    top: -6px;
  }
  .menu-btn i::after {
    top: 6px;
  }
  .menu-btn[aria-expanded="true"] i {
    background: transparent;
  }
  .menu-btn[aria-expanded="true"] i::before {
    top: 0;
    transform: rotate(45deg);
  }
  .menu-btn[aria-expanded="true"] i::after {
    top: 0;
    transform: rotate(-45deg);
  }
  .menu-list {
    position: absolute;
    right: 0;
    top: calc(100% + 0.5rem);
    min-width: 13rem;
    flex-direction: column;
    border-radius: 1.2rem;
    padding: 0.5rem;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition:
      opacity 0.25s,
      transform 0.25s,
      visibility 0.25s;
  }
  .menu-list.open {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .menu-list a {
    padding: 0.8rem 1rem;
    font-size: 0.95rem;
    border-radius: 0.8rem;
  }

  .hero {
    display: block;
    height: auto;
    min-height: 0;
    padding-top: calc(var(--head-h) + var(--s3));
    padding-bottom: 0;
  }
  .hero-copy {
    padding-bottom: var(--s4);
  }
  .hero-role {
    font-size: clamp(0.8rem, 3.5vw, 1.1rem);
  }
  .hero-photo {
    margin: 0 calc(var(--pad) * -1);
    aspect-ratio: 4 / 4.4;
    border-radius: 0 0 0 clamp(4rem, 26vw, 10rem);
  }

  .about {
    display: block;
  }
  .about-photo {
    width: min(80%, 24rem);
    margin-bottom: var(--s4);
  }
  .about-text {
    max-width: 36rem;
  }

  .xp-row {
    grid-template-columns: 1fr;
    gap: var(--s1);
    padding: var(--s3) 0;
  }
  .xp-when {
    order: -1;
    grid-auto-flow: row;
    justify-items: start;
    text-align: left;
    gap: 0.2rem;
  }
  .xp-date {
    white-space: normal;
  }

  .contact {
    display: block;
  }
  .cform {
    margin-top: var(--s4);
  }
}

@media (max-width: 700px) {
  .work {
    grid-template-columns: 1fr;
  }
  .proj {
    min-height: 0;
  }
  .sec-head {
    margin-bottom: var(--s4);
  }
}
@media (max-width: 480px) {
  .skills {
    grid-template-columns: 1fr 1fr;
    gap: var(--s4) var(--s2);
  }
}
@media (max-width: 340px) {
  .skills {
    grid-template-columns: 1fr;
  }
}

/* ---------- IMAGE SKELETONS (class added by js/preloader.js until each image has loaded) ---------- */
.hero-photo img,
.about-photo img {
  transition: opacity 0.6s;
}
.is-loading {
  position: relative;
  overflow: hidden;
}
.is-loading img {
  opacity: 0 !important;
}
.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.6) 50%, transparent 70%) 0 0 /
    250% 100%;
  animation: img-shimmer 1.5s linear infinite;
}
@keyframes img-shimmer {
  to {
    background-position: -150% 0;
  }
}

/* ---------- MOTION ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* hero title settles in after the name; the name itself is driven by js/text-join.js */
  @keyframes mg-fade {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
  .hero-role {
    animation: mg-fade 0.7s var(--ease) 0.6s both;
  }

  .js .skills .skill-col {
    transition: translate 1s var(--ease-mag) calc(0.1s + var(--i, 0) * 0.08s);
  }
  .js .skills:not(.on) .skill-col {
    translate: calc(var(--mx, 0em) * var(--mag)) calc(var(--my, 0em) * var(--mag));
  }
  .skill-col:nth-child(1) {
    --i: 0;
    --mx: -2.5rem;
    --my: 1rem;
  }
  .skill-col:nth-child(2) {
    --i: 1;
    --mx: 0rem;
    --my: 2rem;
  }
  .skill-col:nth-child(3) {
    --i: 2;
    --mx: 2.5rem;
    --my: 1rem;
  }
  .skill-col:nth-child(4) {
    --i: 3;
    --mx: -2.5rem;
    --my: 1rem;
  }
  .skill-col:nth-child(5) {
    --i: 4;
    --mx: 0rem;
    --my: 2rem;
  }
  .skill-col:nth-child(6) {
    --i: 5;
    --mx: 2.5rem;
    --my: 1rem;
  }
}

/* Mobile card-stack (class .fx-on is set by the inline script in index.html; it also sets each section's `top`) */
.fx-on .hero,
.fx-on .sheet.pin {
  position: sticky;
}
.fx-on [data-parallax] {
  top: -14%;
  height: 128%;
}
.fx-on .hero-photo img {
  top: -14%;
  height: 128%;
}
.fx-on [data-parallax],
.fx-on .tex,
.fx-on .sheet.pin > .in {
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
  .is-loading::after {
    animation: none;
  }
  .js .rv {
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
   LOADING SCREEN + SLOW-CONNECTION SKELETON  (driven by js/preloader.js)
   Hidden unless the page script switches it on (html.pl-on), so it can never trap a visitor.
   ============================================================ */
/* Loading screen + slow-connection skeleton. Small on purpose: it is the only stylesheet that blocks the first paint. */
.pl {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  overflow: hidden;
  background: #121212;
  color: #f0f0ec;
  border-radius: 0 0 1.75rem 1.75rem;
  font-family: "Oswald", "Archivo Narrow", "Arial Narrow", sans-serif;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
  transition: transform 0.95s cubic-bezier(0.76, 0, 0.24, 1);
  animation: pl-failsafe 0.4s 9s forwards;
}
html.pl-on .pl {
  display: block;
}
.pl.out {
  transform: translateY(-101%);
}
.pl-dark {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(1.1rem, 3vw, 2rem) clamp(1.25rem, 4vw, 3.5rem);
}
.pl-top,
.pl-bottom {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 1rem;
  flex-wrap: wrap;
}
.pl-top {
  align-items: center;
  font:
    500 0.85rem/1 "Inter",
    system-ui,
    sans-serif;
  letter-spacing: 0.02em;
}
.pl-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.pl-brand i {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: #f0f0ec;
}
.pl-note {
  opacity: 0.55;
}
.pl-num {
  font-weight: 700;
  font-size: clamp(6rem, 26vw, 15rem);
  line-height: 0.8;
  letter-spacing: -0.02em;
  display: flex;
  align-items: flex-start;
  font-variant-numeric: tabular-nums;
}
.pl-num sup {
  font-size: 0.22em;
  margin: 0.25em 0 0 0.12em;
  font-weight: 500;
}
.pl-role {
  font:
    500 clamp(0.8rem, 1.3vw, 1rem)/1.35 "Inter",
    system-ui,
    sans-serif;
  opacity: 0.75;
  max-width: 26ch;
  text-align: right;
}
.pl-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: rgba(255, 255, 255, 0.14);
}
.pl-bar i {
  position: absolute;
  inset: 0;
  background: #f0f0ec;
  transform: scaleX(0);
  transform-origin: left;
  animation: pl-indet 2.4s ease-in-out infinite;
}
.pl-bar i[style] {
  animation: none;
}
@keyframes pl-indet {
  0% {
    transform: scaleX(0);
  }
  60% {
    transform: scaleX(0.8);
  }
  100% {
    transform: scaleX(0.95);
  }
}
@keyframes pl-failsafe {
  to {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}
/* slow-connection skeleton: a quiet mock-up of the hero */
.pl-skel {
  position: absolute;
  inset: 0;
  background: #f7f7f5;
  color: #5c5c5c;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.6s,
    visibility 0.6s;
  display: flex;
  flex-direction: column;
  font:
    500 0.8rem/1.4 "Inter",
    system-ui,
    sans-serif;
}
.pl.slow .pl-skel {
  opacity: 1;
  visibility: visible;
}
.sk {
  display: block;
  border-radius: 6px;
  background: linear-gradient(100deg, #e6e6e1 30%, #f3f3ef 50%, #e6e6e1 70%) 0 0/250% 100%;
  animation: sk-shimmer 1.5s linear infinite;
}
@keyframes sk-shimmer {
  to {
    background-position: -150% 0;
  }
}
.sk-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.1rem clamp(1.25rem, 4vw, 3.5rem);
}
.sk-brand {
  width: 9rem;
  height: 0.8rem;
}
.sk-pill {
  width: min(24rem, 52vw);
  height: 2.9rem;
  border-radius: 99px;
}
.sk-hero {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: 1.5rem;
  padding: 0 clamp(1.25rem, 4vw, 3.5rem);
  min-height: 0;
}
.sk-copy {
  grid-column: 1/8;
  align-self: end;
  padding-bottom: 5.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  align-items: flex-start;
}
.sk-h1 {
  width: min(30rem, 90%);
  height: clamp(3rem, 7vw, 6rem);
  border-radius: 8px;
}
.sk-h1.s2 {
  width: min(20rem, 62%);
}
.sk-role {
  width: min(22rem, 70%);
  height: 1.5rem;
  margin-top: 0.7rem;
}
.sk-line {
  width: min(26rem, 80%);
  height: 0.9rem;
}
.sk-line.s2 {
  width: min(17rem, 55%);
}
.sk-btn {
  width: 9.5rem;
  height: 2.9rem;
  border-radius: 99px;
  margin-top: 0.8rem;
}
.sk-photo {
  grid-column: 8/13;
  margin: 0 calc(clamp(1.25rem, 4vw, 3.5rem) * -1) 3rem 0;
  border-radius: 0 0 0 clamp(5rem, 13vw, 12rem);
  animation-duration: 1.8s;
}
.sk-msg {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1.6rem;
  text-align: center;
  letter-spacing: 0.04em;
}
.sk-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 3px;
  overflow: hidden;
  background: #e6e6e1;
}
.sk-bar i {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 35%;
  background: #171717;
  animation: sk-run 1.2s ease-in-out infinite;
}
@keyframes sk-run {
  0% {
    left: -35%;
  }
  100% {
    left: 100%;
  }
}
@media (max-width: 860px) {
  .sk-hero {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding-bottom: 0;
  }
  .sk-copy {
    align-self: stretch;
    padding-bottom: 1.5rem;
  }
  .sk-photo {
    flex: none;
    height: 30vh;
    margin: 0 calc(clamp(1.25rem, 4vw, 3.5rem) * -1);
    border-radius: 0 0 0 5rem;
  }
  .sk-pill {
    width: 7rem;
  }
  .sk-msg {
    bottom: 0.8rem;
  }
}
html.pl-lock {
  overflow: hidden;
  animation: pl-unlock 0s 9s forwards;
}
@keyframes pl-unlock {
  to {
    overflow: visible;
  }
}
@media (prefers-reduced-motion: reduce) {
  .pl {
    transition: opacity 0.3s;
  }
  .pl.out {
    transform: none;
    opacity: 0;
  }
  .sk,
  .sk-bar i,
  .pl-bar i {
    animation: none;
  }
}