/* registering the accents lets them animate when the scenery changes */
@property --accent {
  syntax: '<color>';
  inherits: true;
  initial-value: #83B8D8;
}
@property --accent-2 {
  syntax: '<color>';
  inherits: true;
  initial-value: #BBB7DC;
}

/* the accents only animate once the first photo has been sampled, so the
   page does not visibly slide from its defaults into the real colours */
:root.accents-ready {
  transition: --accent 900ms cubic-bezier(0.22, 1, 0.36, 1),
              --accent-2 900ms cubic-bezier(0.22, 1, 0.36, 1);
}

:root {
  /* plain values first, for anything that cannot do color-mix */
  --ink: #F2EFE9;
  --ink-lead: rgba(242, 239, 233, 0.90);
  --ink-soft: rgba(242, 239, 233, 0.80);
  --ink-mute: rgba(242, 239, 233, 0.64);
  /* then the same tones with a trace of whichever photo is up. reading text
     stays white and stays out of the way; the colour belongs to the labels,
     numbers and buttons, not to the prose. */
  --ink: color-mix(in oklch, var(--accent) 4%, #F2EFE9);
  --ink-lead: color-mix(in oklch, var(--accent) 7%, rgba(242, 239, 233, 0.90));
  --ink-soft: color-mix(in oklch, var(--accent-2) 9%, rgba(242, 239, 233, 0.80));
  --ink-mute: color-mix(in oklch, var(--accent-2) 20%, rgba(242, 239, 233, 0.62));
  --ground: #0B0D0F;
  --accent: #83B8D8;
  /* app.js swings this off the primary for the photo themes; everywhere
     else the two stay the same and the page reads as one hue */
  --accent-2: var(--accent);
  --line: rgba(242, 239, 233, 0.14);
  --edge: rgba(242, 239, 233, 0.32);
  --panel: rgba(11, 13, 15, 0.66);
  --serif: 'Fraunces', Georgia, serif;
  --sans: 'Karla', system-ui, -apple-system, sans-serif;
  --gutter: clamp(20px, 5vw, 72px);
  --measure: 1180px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* no rubber-band at the ends: the photo is fixed but the nav and footer
     scroll, so a bounce drags the footer hairline up over a still background */
  overscroll-behavior-y: none;
}

body {
  margin: 0;
  font-family: var(--sans);
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

.skip { position:absolute; left:-9999px; top:0; z-index:100; background:var(--accent); color:#14100A; padding:12px 20px; font-weight:600; }
.skip:focus { left: 12px; top: 12px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

/* sections clear the sticky nav when jumped to. 59px puts a section's top
   border exactly under the scrolled nav's hairline, so the two read as one */
section[id] { scroll-margin-top: 59px; }

/* ---------- scroll progress ---------- */
.progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 40; pointer-events: none; }
.progress span {
  display: block; height: 100%; width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
}

/* ---------- the landscape ---------- */
.bg { position: fixed; inset: 0; z-index: -2; overflow: hidden; }

.bg__layer {
  position: absolute; inset: -2%;
  background-size: cover;
  background-position: center;
  opacity: 0;
  animation: kenburns 42s ease-in-out infinite alternate;
  /* `translate` is its own property, so pointer drift composes with the Ken Burns transform */
  translate: var(--px, 0) var(--py, 0);
  transition: opacity 1000ms var(--ease), translate 700ms ease-out;
  will-change: opacity, transform, translate;
}
.bg__layer.is-active { opacity: 1; }
/* if the head script never ran there is still a photo behind the hero */
.bg__layer--a { background-image: url("img/scene-3.webp"); }

@keyframes kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.07) translate3d(-1.2%, -1%, 0); }
}

.bg__tint {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(11,13,15,0.66) 0%, rgba(11,13,15,0.12) 34%, rgba(11,13,15,0.30) 100%),
    linear-gradient(100deg, rgba(11,13,15,0.72) 0%, rgba(11,13,15,0.10) 58%, rgba(11,13,15,0) 100%);
  transition: background 900ms var(--ease);
}
/* bright photos get a heavier scrim so the hero copy keeps its contrast */
.is-bright .bg__tint {
  background:
    linear-gradient(180deg, rgba(11,13,15,0.74) 0%, rgba(11,13,15,0.38) 34%, rgba(11,13,15,0.58) 100%),
    linear-gradient(100deg, rgba(11,13,15,0.86) 0%, rgba(11,13,15,0.40) 58%, rgba(11,13,15,0.18) 100%);
}

/* film grain, so the photos don't look like stock wallpaper */
.bg__grain {
  position: absolute; inset: -50%;
  opacity: 0.16;
  mix-blend-mode: overlay;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 7s steps(6) infinite;
}
@keyframes grain {
  0%,100% { transform: translate(0, 0); }
  17% { transform: translate(-3%, 2%); }
  34% { transform: translate(2%, -3%); }
  51% { transform: translate(-2%, -2%); }
  68% { transform: translate(3%, 1%); }
  85% { transform: translate(-1%, 3%); }
}

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 18px var(--gutter);
  background-color: rgba(11, 13, 15, 0);
  /* blur(0px), not `none`: a filter can only transition into another filter
     of the same shape, so `none` would make this snap instead of fade */
  backdrop-filter: blur(0px) saturate(1);
  transition: background-color 300ms var(--ease),
              backdrop-filter 300ms var(--ease),
              padding 300ms var(--ease);
}
.nav.is-scrolled {
  /* app.js sets --nav-tint from the top of whichever photo is up. .bg__tint
     has already taken most of the light out of that strip, so the bar only
     has to finish the job and can stay glass rather than going black. */
  background-color: rgba(11, 13, 15, var(--nav-tint, 0.38));
  backdrop-filter: blur(18px) saturate(1.3);
  padding-top: 13px; padding-bottom: 13px;
}

/* the scrim that carries the brand over a bright photo before the bar arrives */
.nav::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, rgba(11,13,15,0.5), rgba(11,13,15,0));
  transition: opacity 300ms var(--ease);
}
.nav.is-scrolled::before { opacity: 0.3; }

/* and the hairline underneath */
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--line); opacity: 0; pointer-events: none;
  transition: opacity 300ms var(--ease);
}
.nav.is-scrolled::after { opacity: 1; }

.nav__brand { display: flex; align-items: center; gap: 11px; font-weight: 600; font-size: 15px; }
.nav__brand img { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid var(--edge); transition: transform 400ms var(--ease); }
.nav__brand:hover img { transform: rotate(-6deg) scale(1.06); }

.nav__links { display: flex; align-items: center; gap: 26px; font-size: 14.5px; color: var(--ink-soft); }
.nav__links a { position: relative; transition: color 200ms ease; }
.nav__links a:not(.nav__cta)::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -5px; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: right;
  transition: transform 300ms var(--ease);
}
.nav__links a:not(.nav__cta):hover { color: var(--ink); }
.nav__links a:not(.nav__cta):hover::after,
.nav__links a.is-current::after { transform: scaleX(1); transform-origin: left; }
.nav__links a.is-current { color: var(--accent); }

.nav__cta {
  border: 1px solid var(--edge); border-radius: 999px;
  padding: 8px 18px; color: var(--ink);
  transition: background 240ms var(--ease), color 240ms var(--ease), border-color 240ms var(--ease);
}
.nav__cta:hover { background: var(--accent); border-color: var(--accent); color: #14100A; }

/* ---------- hero ---------- */
.hero {
  min-height: max(92svh, 640px);
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 0 var(--gutter) clamp(84px, 11vh, 128px);
  position: relative;
  overflow: hidden;
}
.hero__inner { max-width: 1100px; will-change: transform, opacity; }

.eyebrow {
  display: flex; align-items: center;
  margin: 0 0 24px;
  font-size: 13.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex-shrink: 0;
  margin-right: 11px;
  box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent) 60%, transparent);
  animation: pulse 3s ease-out infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent) 55%, transparent); }
  70% { box-shadow: 0 0 0 11px color-mix(in oklch, var(--accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent) 0%, transparent); }
}

/* on a phone the line wraps and strands "NC", so the location goes */
@media (max-width: 560px) { .eyebrow__loc { display: none; } }

.hero h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(52px, 8.5vw, 104px);
  line-height: 1.0;
  letter-spacing: -0.032em;
  text-shadow: 0 2px 34px rgba(0,0,0,0.5);
  font-variation-settings: 'opsz' 144, 'SOFT' 28, 'WONK' 1;
}
.section-title, .contact__title, .now-grid h3, .proj__body h3, .role__co {
  font-variation-settings: 'opsz' 72, 'SOFT' 18, 'WONK' 1;
}
.hero__lead {
  margin: 26px 0 0; max-width: 640px;
  font-size: clamp(17px, 2vw, 20.5px); line-height: 1.6;
  color: var(--ink-lead);
  text-shadow: 0 1px 18px rgba(0,0,0,0.65);
}
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-top: 40px; }

/* the photograph fades into the first panel rather than meeting a hard edge */
.hero::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 320px; pointer-events: none;
  background: linear-gradient(180deg, rgba(11,13,15,0) 0%, var(--panel) 100%);
}
.hero > * { position: relative; z-index: 1; }

.hero__scroll {
  position: absolute; left: var(--gutter); bottom: 18px;
  display: flex; align-items: center; gap: 10px;
  font-size: 11.5px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute);
  transition: opacity 320ms var(--ease);
}
.is-scrolled .hero__scroll { opacity: 0; }
@media (max-height: 720px) { .hero__scroll { display: none; } }

.hero__scroll span {
  display: block; width: 1px; height: 26px;
  background: linear-gradient(var(--accent), transparent);
  animation: drop 2.4s var(--ease) infinite;
}
@keyframes drop {
  0% { transform: scaleY(0); transform-origin: top; opacity: 0; }
  40% { transform: scaleY(1); transform-origin: top; opacity: 1; }
  70% { transform: scaleY(1); transform-origin: bottom; opacity: 1; }
  100% { transform: scaleY(0); transform-origin: bottom; opacity: 0; }
}

/* buttons */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  height: 50px; padding: 0 26px; border-radius: 999px;
  font-size: 15px; font-weight: 600;
  transition: transform 300ms var(--ease), background 240ms ease, border-color 240ms ease, box-shadow 300ms var(--ease);
}
.btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; transition: transform 300ms var(--ease); }
.btn--solid { background: var(--accent); color: #14100A; }
.btn--solid:hover { transform: translateY(-2px); box-shadow: 0 14px 34px color-mix(in oklch, var(--accent) 24%, transparent); }
.btn--solid:hover svg { transform: translateX(4px); }
.btn--quiet { border: 1px solid var(--edge); color: var(--ink); }
.btn--quiet:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-2px); }

/* the first panel meets the hero's fade, so it needs no rule of its own */
#now { border-top: 0; }
#now::after { top: 0; }

/* ---------- panels ---------- */
.panel {
  position: relative;
  background: var(--panel);
  backdrop-filter: blur(15px) saturate(1.05);
  border-top: 1px solid var(--line);
  padding: clamp(64px, 9vw, 108px) 0;
}
.panel--tight { padding: clamp(48px, 6vw, 76px) 0; }
.panel--end { background: rgba(11,13,15,0.86); padding: clamp(80px, 11vw, 132px) 0; }
.wrap { width: min(100% - (var(--gutter) * 2), var(--measure)); margin-inline: auto; }

.sec-num {
  margin: 0 0 14px;
  font-size: 12px; letter-spacing: 0.22em; color: var(--accent); opacity: 0.92;
}
.section-title {
  margin: 0 0 18px;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(30px, 4vw, 44px); letter-spacing: -0.022em;
}
.section-lead { margin: 0 0 46px; max-width: 680px; font-size: 17px; line-height: 1.65; color: var(--ink-soft); }
.section-lead strong { color: var(--ink); font-weight: 600; }
.todo { color: var(--ink-mute); font-style: italic; border-left: 2px solid color-mix(in oklch, var(--accent) 55%, transparent); padding-left: 18px; }

/* ---------- now ---------- */
.now-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 34px; }
.now-grid article { padding-top: 20px; border-top: 1px solid var(--line); transition: border-color 400ms var(--ease); }
.now-grid article:hover { border-top-color: var(--accent); }
.now-grid h3 { color: color-mix(in oklch, var(--accent-2) 16%, var(--ink)); margin: 0 0 12px; font-family: var(--serif); font-weight: 500; font-size: 22px; letter-spacing: -0.01em; }
.now-grid p { margin: 0; font-size: 15.5px; line-height: 1.68; color: var(--ink-soft); }

/* ---------- experience ---------- */
.role { display: grid; grid-template-columns: 230px minmax(0, 1fr); gap: 40px; padding: 38px 0; border-top: 1px solid var(--line); }
.role:first-of-type { border-top: 0; padding-top: 0; }
.role__meta { display: flex; flex-direction: column; gap: 5px; }
.role__co { font-family: var(--serif); font-size: 27px; letter-spacing: -0.015em; color: color-mix(in oklch, var(--accent-2) 18%, var(--ink)); }
.role--current .role__co { color: var(--accent); }
.role__where { font-size: 13.5px; color: var(--ink-mute); }

.job + .job { margin-top: 32px; padding-top: 28px; border-top: 1px dashed var(--line); }
.job__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 20px; margin-bottom: 14px; }
.job__head h3 { margin: 0; font-size: 18.5px; font-weight: 600; letter-spacing: -0.01em; }
.job__head h3 span { font-weight: 400; color: var(--ink-mute); }
.job__dates { font-size: 13.5px; color: var(--ink-mute); white-space: nowrap; }
.job ul { margin: 0; padding-left: 19px; display: flex; flex-direction: column; gap: 10px; }
.job li { font-size: 15.5px; line-height: 1.66; color: var(--ink-soft); }
.job li::marker { color: color-mix(in oklch, var(--accent-2) 72%, transparent); }
.job strong { color: var(--ink); font-weight: 600; }
.role--edu .job__head { margin-bottom: 0; }
details.job > summary { list-style: none; cursor: pointer; position: relative; padding-right: 28px; }
details.job > summary::-webkit-details-marker { display: none; }
details.job > summary::after { content: ""; position: absolute; right: 4px; top: 0.55em; width: 8px; height: 8px; border-right: 1.5px solid var(--ink-mute); border-bottom: 1.5px solid var(--ink-mute); transform: rotate(45deg); transition: transform 240ms var(--ease); }
details.job[open] > summary::after { transform: rotate(-135deg); top: 0.75em; }
details.job > summary:hover h3 { color: var(--accent); }
details.job:not([open]) > summary { margin-bottom: 0; }

/* ---------- toolkit ---------- */
.kit { margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 0 44px; }
.kit > div { padding: 15px 0; border-top: 1px solid var(--line); }
.kit dt { font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-2); margin-bottom: 7px; }
.kit dd { margin: 0; font-size: 15px; line-height: 1.6; color: var(--ink-soft); }

/* ---------- projects ---------- */
/* a big screenshot needs more air under the heading than a line of text does */
.section-title + .proj { margin-top: 44px; }
.proj { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 48px; align-items: center; margin-bottom: 72px; }
/* flipped rows mirror the column widths too, so every screenshot is the same size */
.proj--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.proj--flip .proj__shot { order: 2; }
.proj__shot {
  display: block; overflow: hidden; border-radius: 10px;
  border: 1px solid var(--line);
  box-shadow: 0 30px 70px rgba(0,0,0,0.55);
  transition: transform 600ms var(--ease), box-shadow 600ms var(--ease), border-color 600ms var(--ease);
}
/* Fill the preview frame without letterboxing. */
.proj__shot img {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top center;
  transition: transform 900ms var(--ease);
}
/* screenshots wipe up rather than fading in */
.proj__shot img.proj__image--full { aspect-ratio: auto; height: auto; }
.proj.reveal .proj__shot img { clip-path: inset(0 0 42% 0); transform: scale(1.05); }
.proj.reveal.is-in .proj__shot img {
  clip-path: inset(0 0 0 0); transform: scale(1);
  transition: clip-path 1400ms var(--ease) 80ms, transform 1800ms var(--ease) 80ms;
}
.proj.reveal.is-in .proj__shot:hover img { transform: scale(1.035); transition: transform 900ms var(--ease); }
.proj__shot:hover { transform: translateY(-5px); border-color: color-mix(in oklch, var(--accent) 45%, transparent); box-shadow: 0 40px 90px rgba(0,0,0,0.62); }
.proj__shot:hover img { transform: scale(1.035); }

.proj__kicker { margin: 0 0 13px; font-size: 12.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent-2); }
.proj__body h3 { margin: 0 0 15px; font-family: var(--serif); font-weight: 500; font-size: clamp(28px, 3.4vw, 38px); letter-spacing: -0.02em; }
/* :not() keeps this off the kicker, which is also a <p> and was losing
   its accent to this rule on specificity */
.proj__body p:not(.proj__kicker) { margin: 0 0 22px; font-size: 16px; line-height: 1.68; color: var(--ink-soft); }
.proj__link { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600; color: var(--accent); }
.proj__link svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; transition: transform 300ms var(--ease); }
.proj__link:hover svg { transform: translate(3px, -3px); }

.also { margin: 0; padding-top: 30px; border-top: 1px solid var(--line); font-size: 15px; color: var(--ink-mute); }
.also a { color: var(--ink-soft); border-bottom: 1px solid var(--line); transition: color 200ms ease, border-color 200ms ease; }
.also a:hover { color: var(--accent); border-color: var(--accent); }

/* ---------- contact ---------- */
.contact__title { margin: 0 0 18px; font-family: var(--serif); font-weight: 400; font-size: clamp(38px, 6vw, 64px); letter-spacing: -0.03em; }
.contact__actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* ---------- footer ---------- */
.foot { background: var(--ground); border-top: 1px solid var(--line); padding: 26px 0; }
.foot__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; font-size: 13px; color: var(--ink-mute); }

/* ---------- scenery control, living in the hero ---------- */
.scenes {
  position: absolute; right: var(--gutter); bottom: 20px;
  display: flex; align-items: center; gap: 16px;
}
.scenes__label,
.scenes__count {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute); white-space: nowrap;
}
.scenes__dots { display: flex; align-items: center; gap: 7px; }

.scenes__dot {
  position: relative; width: 7px; height: 7px; padding: 0;
  border: 0; border-radius: 999px; cursor: pointer;
  background: rgba(242, 239, 233, 0.34);
  transition: background 320ms var(--ease), width 320ms var(--ease);
}
.scenes__dot::before { content: ""; position: absolute; inset: -15px -4px; }
.scenes__dot:hover { background: rgba(242, 239, 233, 0.72); }
.scenes__dot.is-active { width: 24px; background: var(--accent); }

/* hovering a dot shows the photo it would switch to */
.scenes__peek {
  position: absolute; bottom: 19px; left: 50%;
  width: 104px; height: 68px; border-radius: 5px;
  background-size: cover; background-position: center;
  border: 1px solid var(--edge);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.5);
  opacity: 0; translate: -50% 6px; pointer-events: none;
  transition: opacity 260ms var(--ease), translate 260ms var(--ease);
}
.scenes__dot:hover .scenes__peek,
.scenes__dot:focus-visible .scenes__peek { opacity: 1; translate: -50% 0; }

/* ---------- reveal ---------- */
.reveal { opacity: 0; transform: translateY(11px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 820ms var(--ease), transform 820ms var(--ease);
  transition-delay: calc(var(--d, 0) * 48ms);
}

/* hero entrance */
.r { opacity: 0; transform: translateY(18px); }
.loaded .r {
  opacity: 1; transform: none;
  transition: opacity 900ms var(--ease), transform 900ms var(--ease);
  transition-delay: calc(var(--i) * 110ms + 120ms);
}

/* ---------- responsive ---------- */
@media (max-width: 1050px) {
  .scenes__label { display: none; }
}

@media (max-width: 900px) {
  .scenes { position: static; margin-top: 34px; justify-content: flex-start; }
  .scenes__peek { display: none; }
  .role { grid-template-columns: 1fr; gap: 20px; }
  .proj { grid-template-columns: 1fr; gap: 26px; margin-bottom: 56px; }
  .proj--flip .proj__shot { order: 0; }
  .hero { min-height: max(84svh, 600px); }
  .hero__scroll { display: none; }
  /* the links still fit here, they just need less room */
  .nav__links { gap: 18px; font-size: 13.5px; }
  .nav__cta { padding: 7px 15px; }
}

/* below this the four links crowd the brand, so only the invitation stays */
@media (max-width: 620px) {
  .nav__links a:not(.nav__cta) { display: none; }
  .nav__brand span { font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  :root { transition: none; }
  .reveal, .r, .w { opacity: 1; transform: none; transition: none; }
  .scenes__dot, .scenes__peek, .panel::after { transition: none; }
  .panel::after { transform: scaleX(1); }
  .proj.reveal .proj__shot img { clip-path: none; transform: none; }
  .bg__layer { transition: none; animation: none; }
  .bg__grain { animation: none; }
  .dot { animation: none; }
  .is-scrolled .hero__scroll { opacity: 0; }
  .hero__scroll span { animation: none; }
  .btn, .proj__shot, .proj__shot img, .nav, .nav__brand img { transition: none; }
}

/* a short accent tick draws in along each panel's top edge */
.panel::after {
  content: ""; position: absolute; top: -1px; left: 0;
  width: 92px; height: 1px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 1100ms var(--ease) 140ms;
}
.panel.is-lit::after { transform: scaleX(1); }

/* ---------- closing (outside work + contact, together) ---------- */
.closing {
  display: grid;
  grid-template-columns: minmax(0, 290px) minmax(0, 1fr);
  gap: clamp(40px, 7vw, 96px);
  align-items: start;
}
.closing__me img {
  width: 132px; height: 132px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--line); margin-bottom: 22px;
}
.closing__label {
  margin: 0 0 9px;
  font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--accent-2);
}
.closing__personal { margin: 0; font-size: 15.5px; line-height: 1.7; color: var(--ink-soft); }

.closing__main { padding-top: 6px; }
.closing__lead { margin: 0 0 40px; max-width: 520px; font-size: 17px; line-height: 1.65; color: var(--ink-soft); }

.closing__email {
  display: inline-block;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(24px, 3.4vw, 38px); letter-spacing: -0.02em;
  color: var(--accent);
  border-bottom: 1px solid transparent;
  transition: border-color 300ms var(--ease);
  word-break: break-word;
}
.closing__email:hover { border-bottom-color: var(--accent); }

.closing__links { display: flex; flex-wrap: wrap; gap: 26px; margin-top: 34px; font-size: 15px; color: var(--ink-soft); }
.closing__links a { border-bottom: 1px solid var(--line); padding-bottom: 3px; transition: color 200ms ease, border-color 200ms ease; }
.closing__links a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- theme switcher ---------- */

@media (max-width: 760px) {
  .closing { grid-template-columns: 1fr; gap: 34px; }
  .closing__me img { width: 92px; height: 92px; margin-bottom: 16px; }
  .foot__row { flex-wrap: wrap; gap: 12px; }
}

/* smooth scroll (Lenis) needs native smooth scrolling off */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
/* project screenshots tilt toward the cursor */
.proj__shot { transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); will-change: transform; }
.proj__shot:hover { transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-5px); }
