:root {
  /* Orange system */
  --orange: #FF6A00;
  --orange-bright: #FF8124;
  --orange-deep: #E04E00;
  --orange-glow: rgba(255, 106, 0, 0.45);
  --ink: #1A1410;
  --ink-soft: #5A4F47;
  --paper: #FBF8F4;
  --line: rgba(26, 20, 16, 0.10);

  /* Master timeline (seconds) — tweak everything from here.
       Each beat starts where the previous ends; adjust freely. */
  --t-blackHold: 0.8;
  /* pure black holds */
  --t-fadeDur: 3.0;
  /* very slow black -> white */
  --t-dotStart: 3.0;
  /* circle begins scaling 0 -> 3.5rem radius */
  --t-dotDur: 2.6;
  /* very slow scale */
  --t-splitStart: 5.6;
  /* one circle becomes two */
  --t-splitDur: 2.0;
  /* one moves left, one moves right (bookends) */
  --t-wordStart: 6.25;
  /* vinhry.com begins revealing at ~half of the split (5.6 + 1.5/2) */
  --t-menuStart: 7.6;
  /* menu reveals under the wordmark */
  --t-logoStart: 8.1;   /* logo begins revealing — after orbs fully exit at 7.6s */
  --t-logoDur:   3.8;   /* blur+scale reveal duration — increase for slower unfold */

  /* Logo reveal keyframe stops — adjust to shape the reveal:
     --logo-s*  : scale   (0 = invisible, 1 = full size)
     --logo-b*  : blur px (higher = more blurred)
     --logo-g*  : glow px (orange drop-shadow spread; final stop persists) */
  --logo-s0: 0;      /* 0%  — start scale       */
  --logo-s1: 0.6;    /* 40% — scale midpoint    */
  --logo-s2: 1.04;   /* 75% — slight overshoot  */
  --logo-s3: 1;      /* 100% — settle           */
  --logo-b0: 20px;   /* 0%  — start blur        */
  --logo-b1: 8px;    /* 40% — mid blur          */
  --logo-b2: 1px;    /* 75% — nearly clear      */
  --logo-b3: 0px;    /* 100% — pin-sharp        */
  --logo-g0: 0px;    /* 0%  — no glow           */
  --logo-g1: 14px;   /* 40% — glow building     */
  --logo-g2: 26px;   /* 75% — glow near peak    */
  --logo-g3: 18px;   /* 100% — final resting glow (stays on the clean logo) */
  --logo-glow-color: rgba(255, 106, 0, 0.55); /* glow tint + strength */

  --orb-gap: clamp(7rem, 22vw, 19rem);
  /* how far the split dots travel out */
  --orb-rise: 0rem;
  /* split stays perfectly horizontal */
  --dot-baseline: -2.0rem;
  /* lift the dot line so each dot is vertically centered on the "v" in vinhry.com */
  --orb-scale: 1;
  /* split dots stay the same size as the peak dot */

  /* vinhry.com scale-up reveal — control each keyframe stop here.
       The word grows: w-s0 → w-s1 → w-s2 → w-s3(overshoot) → w-s4(settle).
       Larger --w-s3 (e.g. 1.06) = bigger bounce; set --w-s3 = 1 for no bounce. */
  --w-dur: 1.75s;
  /* total reveal duration */
  --w-s0: 0;
  /* start  (0%)   */
  --w-s1: 0.48;
  /* @ 25%        */
  --w-s2: 0.96;
  /* @ 55%        */
  --w-s3: 1.03;
  /* @ 78% — peak overshoot (the "tiny bounce") */
  --w-s4: 1;
  /* settle (100%) — actual size */
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: "Inter", sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Subtle paper grain over everything */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.035;
  mix-blend-mode: multiply;
  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='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================
     STAGE — the cinematic intro
     ============================================================ */
.stage {
  position: relative;
  /* Fallback chain: svh → dvh → JS-measured real height (--app-height).
     The last declared value the browser understands wins; --app-height is the
     most accurate on iOS Safari (set from window.innerHeight, see index.html). */
  height: 100vh;
  height: 100svh;
  height: 100dvh;
  height: var(--app-height, 100dvh);
  width: 100%;
  display: grid;
  place-items: center;
  overflow: hidden;
  isolation: isolate;
  /* Stage itself very slowly turns from black to white underneath everything */
  background: #000;
  animation: stageLighten calc(var(--t-fadeDur) * 1s) cubic-bezier(0.4, 0, 0.2, 1) forwards;
  animation-delay: calc(var(--t-blackHold) * 1s);
}

@keyframes stageLighten {
  0% {
    background: #000;
  }

  55% {
    background: #241a12;
  }

  /* warm amber dusk midpoint */
  100% {
    background: var(--paper);
  }
}

/* Fireflies — tiny glowing dots drifting in the dark, gone before the screen turns white */
.fireflies {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* above stage bg, below circles + text */
  pointer-events: none;
  /* The whole swarm fades out as the curtain lightens */
  animation: firefliesGone 1.2s ease forwards;
  animation-delay: calc((var(--t-blackHold) + var(--t-fadeDur) * 0.45) * 1s);
}

@keyframes firefliesGone {
  to {
    opacity: 0;
  }
}

.firefly {
  position: absolute;
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: radial-gradient(circle, #ffd9a8 0%, var(--orange-bright) 45%, rgba(255, 106, 0, 0) 72%);
  opacity: 0;
  will-change: transform, opacity;
  /* twinkle (opacity pulse) + drift (gentle float), each with its own delay/duration */
  animation:
    twinkle var(--tw) ease-in-out var(--dly) infinite,
    drift var(--dr) ease-in-out var(--dly) infinite alternate;
}

@keyframes twinkle {

  0%,
  100% {
    opacity: 0;
  }

  18% {
    opacity: var(--max);
  }

  50% {
    opacity: calc(var(--max) * 0.35);
  }

  82% {
    opacity: var(--max);
  }
}

@keyframes drift {
  from {
    transform: translate(0, 0);
  }

  to {
    transform: translate(var(--dx), var(--dy));
  }
}

/* The circle rig is centered; circles are absolutely positioned to it.
     z-index ladder:  orbs (1) < wordmark/menu (2).  No overlay covers them. */
.rig {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  /* Lift the dot line up so it rides the wordmark's baseline, not stage center */
  transform: translateY(var(--dot-baseline));
}

/* Two circles start perfectly stacked at center, read as ONE,
     then split into bookends that FRAME the word (far left / far right). */
.circle {
  position: absolute;
  top: 50%;
  left: 50%;
  /* dot size ≈ x-height of the wordmark (wordmark is clamp(2.6rem,8vw,6rem); dot ≈ half) */
  width: clamp(1.4rem, 4vw, 2.8rem);
  height: clamp(1.4rem, 4vw, 2.8rem);
  margin: calc(clamp(1.4rem, 4vw, 2.8rem) / -2) 0 0 calc(clamp(1.4rem, 4vw, 2.8rem) / -2);
  border-radius: 50%;
  transform: translate(0, 0) scale(0);
  background: radial-gradient(circle at 38% 34%, var(--orange-bright), var(--orange) 56%, var(--orange-deep));
  box-shadow: 0 0 0 0 var(--orange-glow);
  will-change: transform;
}

/* circle-a -> grows from 0, then travels LEFT to become the left bookend */
.circle-a {
  animation:
    dotGrow calc(var(--t-dotDur) * 1s) cubic-bezier(0.16, 0.7, 0.2, 1) both,
    moveLeft calc(var(--t-splitDur) * 1s) cubic-bezier(0.65, 0, 0.2, 1) forwards;
  animation-delay:
    calc(var(--t-dotStart) * 1s),
    calc(var(--t-splitStart) * 1s);
}

/* circle-b -> identical grow (stacked on A), then travels RIGHT */
.circle-b {
  animation:
    dotGrow calc(var(--t-dotDur) * 1s) cubic-bezier(0.16, 0.7, 0.2, 1) both,
    moveRight calc(var(--t-splitDur) * 1s) cubic-bezier(0.65, 0, 0.2, 1) forwards;
  animation-delay:
    calc(var(--t-dotStart) * 1s),
    calc(var(--t-splitStart) * 1s);
}

@keyframes dotGrow {
  0% {
    transform: translate(0, 0) scale(0);
    box-shadow: 0 0 0px 0px var(--orange-glow);
  }

  100% {
    transform: translate(0, 0) scale(1);
    box-shadow: 0 0 30px 1px var(--orange-glow);
  }
}

/* Split: two equal dots travel apart, then fade out as the split finishes */
@keyframes moveLeft {
  0% {
    transform: translate(0, 0) scale(1);
    opacity: 1;
  }

  65% {
    transform: translate(calc(-0.78 * var(--orb-gap)), var(--orb-rise)) scale(var(--orb-scale));
    opacity: 1;
  }

  100% {
    transform: translate(calc(-1 * var(--orb-gap)), var(--orb-rise)) scale(var(--orb-scale));
    opacity: 0;
  }
}

@keyframes moveRight {
  0% {
    transform: translate(0, 0) scale(1);
    opacity: 1;
  }

  65% {
    transform: translate(calc(0.78 * var(--orb-gap)), var(--orb-rise)) scale(var(--orb-scale));
    opacity: 1;
  }

  100% {
    transform: translate(var(--orb-gap), var(--orb-rise)) scale(var(--orb-scale));
    opacity: 0;
  }
}

/* Brand lockup ----------------------------------------------- */
.brand-logo {
  width: clamp(4rem, 10vw, 6rem);
  height: clamp(4rem, 10vw, 6rem);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  /* Position above the lockup with enough gap so the logo doesn't touch the wordmark */
  bottom: calc(100% + 1.2rem);
  left: 50%;
  transform: translateX(-50%);
  transform-origin: center bottom;
  opacity: 0;
  animation: logoDrop calc(var(--t-logoDur) * 1s) cubic-bezier(0.4, 0, 0.2, 1) forwards;
  animation-delay: calc(var(--t-logoStart) * 1s);
}

.brand-logo img {
  width: 100%;
  height: auto;
}

.lockup {
  position: relative;
  z-index: 2;
  text-align: center;
  display: grid;
  justify-items: center;
  gap: 1.4rem;
  pointer-events: none;
  /* re-enabled on the menu links below */
}

.wordmark {
  font-family: "Inter", sans-serif;
  font-weight: 400;
  font-size: clamp(2.6rem, 8vw, 6rem);
  letter-spacing: -0.03em;
  line-height: 0.9;
  color: var(--ink);
  opacity: 0;
  transform-origin: center center;
  /* scale grows out from the centre */
  /* ease-out between stops; the scale values themselves come from :root (--w-s*) */
  animation: wordReveal var(--w-dur) ease-out forwards;
  animation-delay: calc(var(--t-wordStart) * 1s);
}

.wordmark .dot {
  color: var(--orange);
  font-style: italic;
}

.wordmark .com {
  color: var(--ink-soft);
}

/* Logo reveals: scale 0→1, blur x→0, glow 0→x, opacity 0→1.
   Ends on a clean, sharp logo carrying a resting orange glow. */
@keyframes logoDrop {
  0% {
    opacity: 0;
    transform: translateX(-50%) scale(var(--logo-s0));
    filter: blur(var(--logo-b0)) drop-shadow(0 0 var(--logo-g0) var(--logo-glow-color));
  }

  40% {
    opacity: 0.85;
    transform: translateX(-50%) scale(var(--logo-s1));
    filter: blur(var(--logo-b1)) drop-shadow(0 0 var(--logo-g1) var(--logo-glow-color));
  }

  75% {
    opacity: 1;
    transform: translateX(-50%) scale(var(--logo-s2));
    filter: blur(var(--logo-b2)) drop-shadow(0 0 var(--logo-g2) var(--logo-glow-color));
  }

  100% {
    opacity: 1;
    transform: translateX(-50%) scale(var(--logo-s3));
    filter: blur(var(--logo-b3)) drop-shadow(0 0 var(--logo-g3) var(--logo-glow-color));
  }
}

@keyframes wordReveal {
  0% {
    opacity: 0;
    transform: scale(var(--w-s0));
  }

  25% {
    opacity: 1;
    transform: scale(var(--w-s1));
  }

  55% {
    transform: scale(var(--w-s2));
  }

  78% {
    transform: scale(var(--w-s3));
  }

  100% {
    opacity: 1;
    transform: scale(var(--w-s4));
  }
}

.tagline {
  font-family: "Space Mono", monospace;
  font-size: clamp(0.52rem, 1.6vw, 0.78rem);
  letter-spacing: clamp(0.12em, 0.34em, 0.34em);
  text-transform: uppercase;
  color: var(--ink-soft);
  opacity: 0;
  max-width: 90vw;
  text-align: center;
  animation: softUp 1s ease forwards;
  animation-delay: calc((var(--t-wordStart) + 0.45) * 1s);
}

/* Intro menu under the wordmark */
.intro-menu {
  list-style: none;
  display: flex;
  gap: clamp(0.8rem, 3vw, 3rem);
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 0.25rem;
  padding: 0 1rem;
}

.intro-menu li {
  opacity: 0;
  transform: translateY(14px);
  animation: softUp 0.9s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.intro-menu li:nth-child(1) {
  animation-delay: calc((var(--t-menuStart) + 0.00) * 1s);
}

.intro-menu li:nth-child(2) {
  animation-delay: calc((var(--t-menuStart) + 0.18) * 1s);
}

.intro-menu li:nth-child(3) {
  animation-delay: calc((var(--t-menuStart) + 0.36) * 1s);
}

.intro-menu a {
  position: relative;
  pointer-events: auto;
  /* re-enable clicks (lockup is none) */
  font-family: "Sora", sans-serif;
  font-weight: 500;
  font-size: clamp(0.82rem, 2.2vw, 1rem);
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
  padding-bottom: 4px;
  white-space: nowrap;
}

.intro-menu a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.intro-menu a:hover {
  color: var(--orange-deep);
}

.intro-menu a:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

@keyframes softUp {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Scroll cue */
.scroll-cue {
  position: absolute;
  bottom: 2.2rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 7;
  font-family: "Space Mono", monospace;
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink-soft);
  opacity: 0;
  animation: softUp 1s ease forwards, bob 2.4s ease-in-out infinite;
  animation-delay: calc((var(--t-menuStart) + 0.9) * 1s), calc((var(--t-menuStart) + 1.4) * 1s);
}

.scroll-cue span {
  display: block;
  text-align: center;
  margin-top: 6px;
  font-size: 0.9rem;
}

@keyframes bob {

  0%,
  100% {
    transform: translate(-50%, 0);
  }

  50% {
    transform: translate(-50%, 6px);
  }
}

/* Fade the cue out once the user scrolls down; it returns near the top.
     Added after the intro animation finishes (see JS), so transitions apply cleanly. */
.scroll-cue.cue-ready {
  animation: bob 2.4s ease-in-out infinite;
  /* keep the gentle bob */
  transition: opacity 0.5s ease, visibility 0.5s ease;
  opacity: 1;
}

.scroll-cue.cue-ready.cue-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Skip-intro button — subtle, top-right, only useful while the intro plays */
.skip-intro {
  position: absolute;
  top: 1.6rem;
  right: 1.6rem;
  z-index: 8;
  appearance: none;
  border: 1px solid var(--ink-soft);
  background: rgba(255, 255, 255, 0.10);
  color: var(--ink-soft);
  font-family: "Space Mono", monospace;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 0.55rem 0.9rem;
  border-radius: 999px;
  cursor: pointer;
  opacity: 0;
  backdrop-filter: blur(2px);
  /* skipWindow drives the full lifecycle: hidden → white-on-dark → ink-on-light → hidden */
  animation: skipWindow calc((var(--t-menuStart) + 1.2) * 1s) ease forwards;
  animation-delay: calc(var(--t-blackHold) * 1s);
}

.skip-intro:hover {
  color: var(--orange-bright);
  border-color: var(--orange);
  background: rgba(255, 106, 0, 0.10);
}

.skip-intro:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/*
   * skipWindow: the button lives only while the intro plays.
   * 0–8%   : hidden (pure black hold)
   * 8–34%  : white text + translucent border  (dark phase, bg still fading)
   * 34–82% : ink text + light border          (light phase, bg is paper)
   * 82–100%: fade out and lock to opacity:0 (forwards fill keeps it gone)
   */
@keyframes skipWindow {
  0% {
    opacity: 0;
    pointer-events: none;
    color: rgba(255, 255, 255, 0.8);
    border-color: rgba(255, 255, 255, 0.30);
    background: rgba(255, 255, 255, 0.06);
  }

  8% {
    opacity: 1;
    pointer-events: auto;
    color: rgba(255, 255, 255, 0.8);
    border-color: rgba(255, 255, 255, 0.30);
    background: rgba(255, 255, 255, 0.06);
  }

  34% {
    opacity: 1;
    pointer-events: auto;
    color: rgba(255, 255, 255, 0.8);
    border-color: rgba(255, 255, 255, 0.30);
    background: rgba(255, 255, 255, 0.06);
  }

  44% {
    opacity: 1;
    pointer-events: auto;
    color: var(--ink-soft);
    border-color: var(--line);
    background: rgba(251, 248, 244, 0.60);
  }

  82% {
    opacity: 1;
    pointer-events: auto;
    color: var(--ink-soft);
    border-color: var(--line);
    background: rgba(251, 248, 244, 0.60);
  }

  100% {
    opacity: 0;
    pointer-events: none;
    color: var(--ink-soft);
    border-color: var(--line);
    background: rgba(251, 248, 244, 0.60);
  }
}

/* Click-skip: JS adds .intro-done → override animation fill immediately */
body.intro-done .skip-intro {
  opacity: 0 !important;
  pointer-events: none !important;
  animation: none !important;
}

/* Accessibility: respect reduced motion -> reveal final state instantly */
@media (prefers-reduced-motion: reduce) {
  .skip-intro {
    display: none;
  }

  /* no intro to skip */
  .stage {
    animation: none;
    background: var(--paper);
  }

  .circle-a,
  .circle-b {
    opacity: 0;
    animation: none;
  }

  .wordmark,
  .tagline,
  .intro-menu li,
  .scroll-cue {
    opacity: 1;
    transform: none;
    filter: none;
    animation: none;
  }
}

/* Re-usable */
.d-none {
  display: none !important;
}

/* ============================================================
     CONTENT — the rest of the page (real links live here)
     ============================================================ */
main {
  position: relative;
  z-index: 1;
}

.section {
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(5rem, 12vw, 9rem) clamp(1.5rem, 6vw, 4rem);
}

.eyebrow {
  font-family: "Space Mono", monospace;
  font-size: 0.7rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--orange-deep);
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 1.6rem;
}

.eyebrow::before {
  content: "";
  width: 1.8rem;
  height: 2px;
  background: var(--orange);
}

h2.title {
  font-family: "Fraunces", serif;
  font-weight: 400;
  font-size: clamp(2rem, 6vw, 3.6rem);
  letter-spacing: -0.025em;
  line-height: 1.02;
  margin-bottom: 1.5rem;
}

h2.title em {
  color: var(--orange);
  font-style: italic;
}

.lede {
  font-size: clamp(1.05rem, 2.4vw, 1.3rem);
  line-height: 1.7;
  color: var(--ink-soft);
  max-width: 56ch;
  font-weight: 300;
}

/* About divider line */
.section+.section {
  border-top: 1px solid var(--line);
}

/* What I Do — discipline cards */
.grid {
  margin-top: 3rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.card {
  background: var(--paper);
  padding: 2.2rem 1.9rem;
  transition: background 0.4s ease, transform 0.4s ease;
  position: relative;
}

.card:hover {
  background: #fff;
}

.card .num {
  font-family: "Space Mono", monospace;
  font-size: 0.72rem;
  color: var(--orange);
  letter-spacing: 0.1em;
}

.card h3 {
  font-family: "Fraunces", serif;
  font-weight: 500;
  font-size: 1.45rem;
  margin: 1rem 0 0.7rem;
  letter-spacing: -0.01em;
}

.card p {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-soft);
  font-weight: 300;
}

.card::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 0;
  background: var(--orange);
  transition: width 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.card:hover::after {
  width: 100%;
}

/* Get in touch */
.contact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem 3rem;
  margin-top: 2.6rem;
}

.mail {
  font-family: "Fraunces", serif;
  font-style: italic;
  font-size: clamp(1.3rem, 5vw, 2.8rem);
  color: var(--ink);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
  word-break: break-word;
}

.mail:hover {
  color: var(--orange-deep);
  border-color: var(--orange);
}

.socials {
  display: flex;
  gap: 1.4rem;
  flex-wrap: wrap;
}

.socials a {
  font-family: "Space Mono", monospace;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color 0.3s ease;
}

.socials a:hover {
  color: var(--orange);
}

footer {
  border-top: 1px solid var(--line);
  padding: 2.2rem clamp(1.5rem, 6vw, 4rem);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  font-family: "Space Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  max-width: 1080px;
  margin: 0 auto;
}

footer .mk {
  color: var(--orange);
}

/* Reveal-on-scroll */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.reveal.in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
     MOBILE — phones ≤ 480px
     ============================================================ */
@media (max-width: 480px) {
  :root {
    --orb-gap: clamp(9rem, 52vw, 14rem);
    --dot-baseline: -2.1rem;
  }

  .skip-intro {
    top: 1rem;
    right: 1rem;
    font-size: 0.58rem;
    padding: 0.45rem 0.75rem;
  }

  .lockup {
    gap: 1rem;
  }

  .wordmark {
    font-size: clamp(2.2rem, 13vw, 3rem);
  }

  .tagline {
    font-size: 0.5rem;
    letter-spacing: 0.12em;
    padding: 0 0.5rem;
  }

  .intro-menu {
    gap: 0.9rem;
    padding: 0 0.5rem;
  }

  .scroll-cue {
    font-size: 0.55rem;
    bottom: 1.4rem;
  }

  .section {
    padding: 3.5rem 1.25rem;
  }

  .card {
    padding: 1.6rem 1.25rem;
  }

  .contact {
    gap: 1rem;
  }

  .mail {
    font-size: clamp(1.15rem, 6vw, 1.6rem);
  }

  footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
    padding: 1.8rem 1.25rem;
  }
}

/* Very narrow phones (~320px) */
@media (max-width: 360px) {
  :root {
    --orb-gap: clamp(8rem, 50vw, 12rem);
  }

  .intro-menu {
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
  }

  .tagline {
    display: none;
  }
}