/* =========================================================
   Tokens: colors sampled from the scene (dusk sky, stone, sunset)
   ========================================================= */
:root {
  --bg: #15131d;          /* page background, warm near-black */
  --surface: #1e1b29;
  --surface-2: #2a2637;
  --sky: #323c5f;         /* top of the painted sky */
  --text: #f6eee4;        /* cream */
  --muted: #bcb3c4;
  --accent: #f3a573;      /* sunset peach */
  --accent-hover: #f7bb92;
  --on-accent: #1a1426;
  --paper: #fff6ea;       /* bubbles + ripple labels */
  --ink: #1d1a2b;
  --border: rgba(246, 238, 228, 0.14);
  --focus: #ffd9a8;

  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* 1.25 type scale */
  --fs-sm: 0.875rem;
  --fs-base: 1.0625rem;
  --fs-md: 1.25rem;
  --fs-lg: 1.5625rem;
  --fs-xl: 1.953rem;
  --fs-2xl: clamp(2.2rem, 4.4vw, 3.6rem);

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --radius: 14px;
  --gutter: clamp(16px, 4vw, 48px);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 500; line-height: 1.15; margin: 0; letter-spacing: -0.01em; }
p { margin: 0; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 6px; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 50;
  background: var(--paper); color: var(--ink); padding: 10px 16px; border-radius: 10px;
  text-decoration: none; font-weight: 600; transition: top 0.2s var(--ease-out);
}
.skip-link:focus { top: 12px; }
.muted { color: var(--muted); }

/* =========================================================
   Hero
   ========================================================= */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 580px;
  overflow: hidden;
  background: var(--sky);
  isolation: isolate;
}
/* soft dusk scrim behind the nav + intro text, and a fade into the page below */
.hero::before, .hero::after {
  content: ""; position: absolute; left: 0; right: 0; pointer-events: none; z-index: 2;
}
.hero::before { top: 0; height: 46%; background: linear-gradient(rgba(21, 19, 40, 0.62), rgba(21, 19, 40, 0)); }
.hero::after {   /* the rocks dissolve into the page colour, on an eased curve so the fade has no visible start */
  bottom: 0; height: 26%;
  background: linear-gradient(180deg, rgba(21, 19, 29, 0) 0%, rgba(21, 19, 29, 0.06) 22%, rgba(21, 19, 29, 0.2) 42%, rgba(21, 19, 29, 0.45) 62%, rgba(21, 19, 29, 0.75) 80%, rgba(21, 19, 29, 0.93) 92%, var(--bg) 100%);
}

.nav {
  position: absolute; z-index: 10; top: 0; left: 0; right: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 20px var(--gutter);
}
.nav-logo { font-family: var(--font-display); font-size: var(--fs-md); text-decoration: none; }
.nav-links { list-style: none; display: flex; align-items: center; gap: clamp(12px, 2.4vw, 28px); margin: 0; padding: 0; }
.nav-links a {
  text-decoration: none; font-size: var(--fs-sm); font-weight: 500; opacity: 0.9;
  padding: 10px 2px; background: linear-gradient(currentColor, currentColor) no-repeat 0 85% / 0 1px;
  transition: background-size 0.25s var(--ease-out), opacity 0.2s;
}
.nav-links a:hover { opacity: 1; background-size: 100% 1px; }
.sound-toggle {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--border); cursor: pointer;
  transition: background 0.2s;
}
.sound-toggle:hover { background: rgba(255, 255, 255, 0.16); }
.sound-toggle .wave { display: none; }
.sound-toggle[aria-pressed="true"] .wave { display: inline; }
.sound-toggle[aria-pressed="true"] .mute { display: none; }

.hero-copy {
  position: absolute; z-index: 5;
  top: clamp(88px, 15vh, 140px); left: var(--gutter);
  max-width: min(560px, 46vw);
  text-shadow: 0 1px 18px rgba(20, 16, 40, 0.55);
}
.eyebrow {
  font-size: var(--fs-sm); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--paper); opacity: 0.85; margin-bottom: 12px;
}
.hero-copy h1 { font-size: var(--fs-2xl); font-weight: 500; }
.lede { margin-top: 14px; font-size: var(--fs-md); line-height: 1.5; color: #f3e6da; max-width: 40ch; }

.stage { position: absolute; inset: 0; z-index: 1; }
.scene-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* The video only feeds the canvas. Kept "rendered" (not display:none) so every browser keeps decoding it. */
.scene-video { position: absolute; left: 0; top: 0; width: 2px; height: 2px; opacity: 0; pointer-events: none; }
.no-webgl .scene-video { opacity: 1; width: auto; height: auto; max-width: none; }
.no-webgl .scene-canvas { display: none; }

.overlay { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.overlay > * { pointer-events: auto; }

/* Anchored elements: js sets --x/--y (px inside the stage). */
[data-anchor] { position: absolute; left: var(--x, -999px); top: var(--y, -999px); }

/* Invisible hit areas over the two characters */
.zone {
  position: absolute; background: transparent; border: 0; padding: 0; cursor: pointer;
  border-radius: 40% 40% 24% 24%;
}
.zone:focus-visible { outline: 2px dashed var(--focus); outline-offset: 4px; }

/* -------- shared show/hide -------- */
.hint, .bubble, .pebble, .ripple-label, .replay {
  opacity: 0; visibility: hidden;
  transition: opacity 0.35s var(--ease-out), transform 0.45s var(--ease-out), visibility 0s linear 0.45s;
}
.is-shown {
  opacity: 1 !important; visibility: visible !important;
  transition: opacity 0.35s var(--ease-out), transform 0.45s var(--ease-out), visibility 0s;
}

/* -------- hint pill ("psst… hover over us") -------- */
.hint {
  display: flex; align-items: center; gap: 8px; margin: 0;
  transform: translate(-50%, calc(-100% + 8px));
  padding: 8px 14px 8px 10px; border-radius: 999px;
  background: rgba(24, 20, 40, 0.62); border: 1px solid rgba(255, 246, 234, 0.22);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  font-size: var(--fs-sm); color: var(--paper); white-space: nowrap; pointer-events: none;
}
.hint.is-shown { transform: translate(-50%, -100%); animation: bob 2.6s ease-in-out 0.5s infinite; }
.hint-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 0 rgba(243, 165, 115, 0.7); animation: ping 1.8s ease-out infinite; }
.tap-word { display: none; }
@media (hover: none) { .hover-word { display: none; } .tap-word { display: inline; } }

/* -------- speech bubbles -------- */
.bubble {
  width: max-content; max-width: min(270px, calc(100vw - 32px));
  transform: translate(0, calc(-100% + 10px)) scale(0.96); transform-origin: var(--tail, 50%) 100%;
  padding: 12px 16px; border-radius: 16px;
  background: var(--paper); color: var(--ink);
  font-size: 0.95rem; line-height: 1.45;
  box-shadow: 0 12px 30px -8px rgba(15, 10, 30, 0.45);
}
.bubble.is-shown { transform: translate(0, -100%) scale(1); }
.bubble::after {
  content: ""; position: absolute; top: 100%; left: var(--tail, 50%); transform: translateX(-50%);
  border: 9px solid transparent; border-top-color: var(--paper); border-bottom: 0;
}
.bubble-title { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; margin-bottom: 2px; }
.bubble-zeny { padding-right: 36px; }
.bubble-close {
  position: absolute; top: 2px; right: 2px; width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: transparent; color: var(--ink); font-size: 1.25rem; line-height: 1; cursor: pointer;
}
.bubble-close:hover { background: rgba(29, 26, 43, 0.08); }
.bubble-cta { margin-top: 12px; }   /* the look is .btn .btn-primary */

/* -------- the pebble -------- */
.pebble {
  width: 72px; height: 48px; padding: 0; border: 0; background: transparent; cursor: grab;
  transform: translate(-50%, -50%) translateY(10px);
}
.pebble.is-shown { transform: translate(-50%, -50%); }
.pebble svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 3px 3px rgba(20, 10, 5, 0.55)); transition: transform 0.25s var(--ease-out); }
.pebble::before { /* warm glow halo */
  content: ""; position: absolute; inset: -14px -10px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 214, 160, 0.55), rgba(255, 214, 160, 0));
  animation: glow 2s ease-in-out infinite; pointer-events: none;
}
.pebble::after { /* expanding ring */
  content: ""; position: absolute; left: 50%; top: 55%; width: 70px; height: 26px;
  border: 1.5px solid rgba(255, 230, 200, 0.75); border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.6); opacity: 0; animation: ring 2s ease-out infinite; pointer-events: none;
}
.pebble:hover svg, .pebble:focus-visible svg { transform: translateY(-4px) rotate(-6deg); }
.pebble:active { cursor: grabbing; }
.pebble-hint {
  position: absolute; bottom: calc(100% + 14px); left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: var(--fs-sm); color: var(--paper);
  background: rgba(24, 20, 40, 0.62); border: 1px solid rgba(255, 246, 234, 0.22);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: 6px 12px; border-radius: 999px; animation: bob 2.6s ease-in-out infinite;
}
.pebble-hint::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: rgba(24, 20, 40, 0.62); border-bottom: 0;
}
.pebble.is-picked { transform: translate(-50%, -50%) translateY(-24px) scale(0.6); opacity: 0; visibility: hidden; }

/* -------- labels that rise out of the ripples -------- */
.ripple-label {
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  transform: translate(-50%, -60%) scale(0.92);
  padding: 10px 18px; min-height: 44px; border-radius: 999px;
  background: rgba(255, 246, 234, 0.94); color: var(--ink); text-decoration: none;
  font-family: var(--font-display); font-size: 1.15rem; font-weight: 500;
  box-shadow: 0 10px 30px -10px rgba(20, 10, 40, 0.6), 0 0 0 6px rgba(255, 246, 234, 0.14);
}
.ripple-label.is-shown { transform: translate(-50%, -100%) scale(1); }
.ripple-label.is-shown:hover { transform: translate(-50%, calc(-100% - 4px)) scale(1.03); }
.ripple-num { font-family: var(--font-body); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; color: #6b5a6e; }
.ripple-label::before { /* little stem down to the water */
  content: ""; position: absolute; top: 100%; left: 50%; width: 1.5px; height: var(--stem-len, var(--stem, 26px));
  background: linear-gradient(rgba(255, 246, 234, 0.8), rgba(255, 246, 234, 0)); transform: translateX(-50%) rotate(var(--stem-tilt, 0deg)); transform-origin: 50% 0;
}

.replay {
  transform: translate(-50%, -50%) translateY(8px);
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px; border-radius: 999px; cursor: pointer; white-space: nowrap;
  background: rgba(24, 20, 40, 0.62); border: 1px solid rgba(255, 246, 234, 0.22); color: var(--paper); font-size: var(--fs-sm);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.replay.is-shown { transform: translate(-50%, -50%); }
.replay:hover { background: rgba(24, 20, 40, 0.8); }

/* -------- cursor tag ("That's me" / "Say hi to Zeny") -------- */
.cursor-tag {
  position: absolute; left: 0; top: 0; pointer-events: none; white-space: nowrap;
  padding: 5px 10px; border-radius: 999px; font-size: 0.8rem; font-weight: 500;
  background: var(--paper); color: var(--ink); box-shadow: 0 6px 16px -6px rgba(10, 5, 30, 0.5);
  opacity: 0; transform: translate(var(--cx, 0), var(--cy, 0)) translate(14px, 14px) scale(0.9);
  transition: opacity 0.2s, transform 0.08s linear;
}
.cursor-tag.is-on { opacity: 1; transform: translate(var(--cx, 0), var(--cy, 0)) translate(14px, 14px) scale(1); }
/* Zeny's tag is pinned beside him: to the left, centred on his head */
.cursor-tag.is-pinned { transform: translate(var(--cx, 0), var(--cy, 0)) translate(calc(-100% - 6px), -50%) scale(0.9); transition: opacity 0.2s; }
.cursor-tag.is-pinned.is-on { transform: translate(var(--cx, 0), var(--cy, 0)) translate(calc(-100% - 6px), -50%) scale(1); }
@media (hover: none) { .cursor-tag { display: none; } }

.scroll-cue {
  position: absolute; z-index: 5; left: 50%; bottom: 18px; transform: translateX(-50%);
  display: inline-flex; gap: 6px; align-items: center; min-height: 44px; padding: 0 12px;
  font-size: var(--fs-sm); color: var(--paper); opacity: 0.8; text-decoration: none;
}
.scroll-cue:hover { opacity: 1; }
.scroll-cue span:last-child { animation: bob 2.4s ease-in-out infinite; display: inline-block; }

@keyframes bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -4px; } }
@keyframes ping { 0% { box-shadow: 0 0 0 0 rgba(243, 165, 115, 0.7); } 80%, 100% { box-shadow: 0 0 0 10px rgba(243, 165, 115, 0); } }
@keyframes glow { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
@keyframes ring { 0% { opacity: 0.9; transform: translate(-50%, -50%) scale(0.6); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.5); } }

/* =========================================================
   Hero, small screens: text sits on the sky, the scene below it
   ========================================================= */
@media (max-width: 760px) {
  .hero { height: auto; min-height: 0; display: flex; flex-direction: column; overflow: visible; }
  .hero::before { display: none; }
  .nav { padding-top: 12px; padding-bottom: 12px; }

  .hero-copy { position: relative; top: auto; left: auto; max-width: none; padding: 8px var(--gutter) 0; text-shadow: none; }
  .lede { font-size: var(--fs-base); }
  .stage { position: relative; inset: auto; height: clamp(400px, 122vw, 640px); margin-top: -8px; overflow: hidden; }
  .stage::before { /* blend the top of the painting into the sky color above */
    content: ""; position: absolute; top: 0; left: 0; right: 0; height: 22%; z-index: 2; pointer-events: none;
    background: linear-gradient(var(--sky), rgba(50, 60, 95, 0));
  }
  .scroll-cue { bottom: 6px; }
  .ripple-label { font-size: 1rem; padding: 8px 14px; }
}

/* =========================================================
   Sections
   ========================================================= */
.section { max-width: 1200px; margin: 0 auto; padding: clamp(72px, 10vw, 140px) var(--gutter) 0; scroll-margin-top: 8px; }
.section-head { max-width: 680px; margin-bottom: clamp(36px, 5vw, 64px); }
.section-num { font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.08em; color: var(--accent); margin-bottom: 8px; }
.section-head h2 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
.section-intro { margin-top: 14px; color: var(--muted); font-size: var(--fs-md); line-height: 1.5; }

.placeholder {
  display: grid; place-items: center; text-align: center; padding: 16px;
  min-height: 100%; width: 100%;
  border: 1.5px dashed rgba(246, 238, 228, 0.25); border-radius: var(--radius);
  background: repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.02) 0 12px, rgba(255, 255, 255, 0.04) 12px 24px);
  color: var(--muted); font-size: var(--fs-sm);
}

/* Projects */
.projects { display: grid; gap: clamp(48px, 7vw, 96px); }
.project { display: grid; grid-template-columns: 7fr 5fr; gap: clamp(24px, 4vw, 56px); align-items: center; }


.project-media { display: block; aspect-ratio: 16 / 10; border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.project-media > * { transition: transform 0.5s var(--ease-out); }
.project:hover .project-media:not(.dv-cover):not(.ai-cover) > * { transform: scale(1.02); }
/* a real screenshot cover: white UI framed on a soft teal "water" mat */
.project-cover { display: grid; place-items: center; padding: 6%; background: radial-gradient(120% 100% at 50% 0%, rgba(127, 209, 193, 0.22), transparent 70%), var(--surface); }
.project-cover img { width: 100%; height: auto; border-radius: 8px; box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.7); }
.project-meta { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 10px; }
.project h3 { font-size: var(--fs-xl); }
.project-summary { margin-top: 12px; color: #e6dcd2; max-width: 46ch; }
.project-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 22px 0 26px; padding: 16px 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.project-facts dt { font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
.project-facts dd { margin: 0; font-size: var(--fs-sm); }

/* THE button: one design everywhere on the site (home, case studies, the board, the notes, Zeny's bubble).
   .btn = shape, type and size; .btn-primary = the peach main action. Places that use it only add margins. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 46px; padding: 0 20px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text); text-decoration: none; cursor: pointer;
  font-family: var(--font-body); font-style: normal; font-weight: 500; font-size: 0.95rem; line-height: 1.2; letter-spacing: normal; white-space: nowrap;
  transition: background 0.2s, border-color 0.2s, transform 0.2s var(--ease-out);
}
.btn:hover { background: var(--surface-2); border-color: rgba(246, 238, 228, 0.3); transform: translateY(-1px); }
.btn span[aria-hidden] { transition: transform 0.2s var(--ease-out); }
.btn:hover span[aria-hidden] { transform: translateX(3px); }
.btn-primary { background: var(--accent); color: var(--on-accent); border-color: transparent; font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); border-color: transparent; color: var(--on-accent); }
.btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.btn:disabled { opacity: 0.6; cursor: default; transform: none; }

/* Beyond work */
.about { display: grid; grid-template-columns: 5fr 7fr; gap: clamp(24px, 4vw, 56px); align-items: center; }
.about-photo { aspect-ratio: 4 / 5; }
.about-text h3, .feature h3 { font-size: var(--fs-xl); margin-bottom: 14px; }
.about-text p + p { margin-top: 12px; }
.about-text p { max-width: 58ch; color: #e6dcd2; }

.feature {
  margin-top: clamp(56px, 8vw, 104px); display: grid; grid-template-columns: 5fr 7fr; gap: clamp(24px, 4vw, 56px); align-items: center;
  padding: clamp(20px, 3vw, 32px); border-radius: calc(var(--radius) + 8px);
  background: linear-gradient(135deg, rgba(76, 96, 196, 0.22), rgba(243, 165, 115, 0.12)), var(--surface);
  border: 1px solid var(--border); scroll-margin-top: 24px;
}
.feature-media img { border-radius: var(--radius); aspect-ratio: 5 / 4; object-fit: cover; width: 100%; }
.feature-body p { max-width: 54ch; }
.feature-body p + p { margin-top: 10px; }
.feature-body .btn { margin-top: 22px; }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 72px); margin-top: clamp(56px, 8vw, 104px); }
.sub-title { font-size: var(--fs-lg); margin-bottom: 20px; }
.journey { list-style: none; margin: 0; padding: 0 0 0 20px; border-left: 1px solid var(--border); }
.journey li { position: relative; display: grid; gap: 2px; padding: 0 0 26px; }
.journey li::before { content: ""; position: absolute; left: -26px; top: 7px; width: 11px; height: 11px; border-radius: 50%; background: var(--bg); border: 2px solid var(--accent); }
.journey-when { font-size: var(--fs-sm); color: var(--accent); font-weight: 600; }
.fun-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.fun-grid .placeholder { aspect-ratio: 1; }
.fun-grid p { margin-top: 8px; font-size: var(--fs-sm); color: var(--muted); }


/* About me */
.about-lede { font-size: var(--fs-md); line-height: 1.55; }
.feature-compact { margin-top: 0; grid-template-columns: 1fr; align-items: start; }
.feature-compact .feature-media img { aspect-ratio: 16 / 9; }

/* Footer */
.footer { max-width: 1200px; margin: clamp(96px, 12vw, 160px) auto 0; padding: 0 var(--gutter) 40px; }
.footer h2 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
.footer .muted { margin-top: 12px; }
.footer-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.footer-note { margin-top: 72px; padding-top: 24px; border-top: 1px solid var(--border); font-size: var(--fs-sm); color: var(--muted); }

@media (max-width: 860px) {
  .project, .about, .feature, .split { grid-template-columns: 1fr; }
}

/* Scroll reveal (only when JS is running, so content is never hidden without it) */
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out); }
.js .reveal.is-in { opacity: 1; transform: none; }

/* ?motion=full adds .force-motion so the full experience can be previewed */
@media (prefers-reduced-motion: reduce) {
  :root:not(.force-motion) { scroll-behavior: auto; }
  :root:not(.force-motion) *, :root:not(.force-motion) *::before, :root:not(.force-motion) *::after { animation: none !important; }
  :root:not(.force-motion).js .reveal { opacity: 1; transform: none; transition: none; }
  :root:not(.force-motion) :is(.hint, .bubble, .pebble, .ripple-label, .replay) { transition: opacity 0.2s, visibility 0s; }
}

/* About me: a cropped, centred portrait (the source photo is tall; we frame head to waist) */
.about-photo { position: relative; margin: 0; aspect-ratio: 4 / 5; overflow: hidden; border-radius: 22px 22px 120px 22px; background: var(--surface); box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.7); }
.about-photo img { position: absolute; width: 135%; max-width: none; height: auto; left: -17%; top: -54%; }
.about-photo::after { /* a warm wash so it sits in the dusk palette */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(243, 165, 115, 0) 55%, rgba(21, 19, 29, 0.35)); }
.about-text .about-lede { font-family: var(--font-display); font-size: clamp(1.5rem, 2.6vw, 2rem); line-height: 1.3; color: var(--text); margin-bottom: 18px; }
.super { font-weight: 600; color: var(--accent); letter-spacing: 0.04em; }
.journey-chat { display: inline-grid; gap: 2px; margin-top: 26px; padding: 16px 22px; border-radius: 20px 20px 20px 6px; background: var(--surface); border: 1px solid var(--border); text-decoration: none; transition: transform 0.25s var(--ease-out), border-color 0.25s; }
.journey-chat:hover { transform: translateY(-3px); border-color: rgba(243, 165, 115, 0.5); }
.journey-chat-q { font-family: var(--font-display); font-size: 1.2rem; color: var(--text); }
.journey-chat-a { color: var(--accent); font-weight: 500; }
.journey-chat-a span { display: inline-block; transition: transform 0.25s var(--ease-out); }
.journey-chat:hover .journey-chat-a span { transform: translateX(4px); }

/* ---------- About me: the daydream (cut-out portrait + drifting thought clouds) ---------- */
.dream {
  overflow: hidden; isolation: isolate; touch-action: pan-y;
  background:
    radial-gradient(60% 40% at 80% 18%, rgba(255, 214, 160, 0.55), transparent 70%),
    radial-gradient(70% 50% at 10% 85%, rgba(201, 194, 232, 0.55), transparent 70%),
    linear-gradient(180deg, #4b4a7a 0%, #8a6f9a 45%, #e7a98c 82%, #f3c9a2 100%);
}
.dream::after { display: none; }
.dream-me { z-index: 2; pointer-events: none; -webkit-mask: linear-gradient(180deg, #000 82%, transparent 100%); mask: linear-gradient(180deg, #000 82%, transparent 100%);
  filter: drop-shadow(0 10px 24px rgba(40, 20, 50, 0.35)); }
.dream-clouds { position: absolute; inset: 0; z-index: 1; }
.cloud {
  position: absolute; left: var(--x); top: var(--y); width: var(--w, 86px); aspect-ratio: 1.45; display: grid; place-items: center;
  border: 0; padding: 0; background: none; cursor: grab; touch-action: none; user-select: none;
  transform: translate(var(--dx, 0px), var(--dy, 0px)) translate(var(--px, 0px), var(--py, 0px));
  animation: drift var(--t, 9s) ease-in-out var(--delay, 0s) infinite alternate;
}
.cloud svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 6px 10px rgba(50, 30, 60, 0.18)); transition: transform 0.25s var(--ease-out); }
.cloud svg path { fill: rgba(255, 250, 244, var(--a, 0.92)); }
.cloud-emoji { position: relative; font-size: calc(var(--w, 86px) * 0.3); line-height: 1; transform: translateY(6%); transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); }
.cloud:hover svg { transform: scale(1.06); }
.cloud.is-dragging { cursor: grabbing; animation-play-state: paused; z-index: 4; }
.cloud.pop svg { animation: pop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1); }
.cloud.pop .cloud-emoji { animation: pop-emoji 0.45s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes drift { from { translate: 0 0; } to { translate: var(--mx, 12px) var(--my, -10px); } }
@keyframes pop { 0% { transform: scale(1); } 40% { transform: scale(1.25, 0.85); } 100% { transform: scale(1); } }
@keyframes pop-emoji { 0% { transform: translateY(6%) scale(0.2) rotate(-40deg); } 100% { transform: translateY(6%) scale(1); } }

/* the main thought: dots rising from her head (she looks up-left) to a big cloud */
.dream-thought { position: absolute; z-index: 3; inset: 0; pointer-events: none; }
.dream-thought .dot { position: absolute; border-radius: 50%; background: rgba(255, 250, 244, 0.95); box-shadow: 0 3px 8px rgba(50, 30, 60, 0.2); animation: rise 2.4s ease-in-out infinite; }
.d1 { left: 33%; top: 36%; width: 9px; height: 9px; }
.d2 { left: 26%; top: 30%; width: 13px; height: 13px; animation-delay: 0.25s !important; }
.d3 { left: 18%; top: 23%; width: 18px; height: 18px; animation-delay: 0.5s !important; }
@keyframes rise { 0%, 100% { transform: translateY(0); opacity: 0.85; } 50% { transform: translateY(-4px); opacity: 1; } }
.dream-main {
  position: absolute; left: 4%; top: 4%; width: 36%; aspect-ratio: 1.5; display: grid; place-items: center;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 100'%3E%3Cpath d='M38 88c-20 0-32-12-32-27 0-14 11-25 25-26 3-17 17-29 35-29 14 0 26 7 32 19 4-2 8-3 13-3 18 0 32 14 32 31 0 1 0 2-.1 3C150 59 150 64 150 68c0 11-9 20-20 20z' fill='%23fffaf4'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  filter: drop-shadow(0 8px 14px rgba(50, 30, 60, 0.25)); pointer-events: auto; cursor: pointer;
}
.dream-emoji { font-size: clamp(1.4rem, 3.2vw, 2.2rem); transform: translateY(6%); }
.dream-emoji.swap { animation: pop-emoji 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
.dream-hint { position: absolute; z-index: 5; left: 12px; bottom: 12px; margin: 0; padding: 5px 11px; border-radius: 999px; background: rgba(21, 19, 29, 0.55); color: var(--paper); font-size: 0.78rem; backdrop-filter: blur(4px); transition: opacity 0.4s; }
.dream.touched .dream-hint { opacity: 0; }
@media (prefers-reduced-motion: reduce) { :root:not(.force-motion) .cloud { animation: none; } }
.motion-calm .cloud, .motion-calm .dream-thought .dot { animation: none !important; }

/* ---------- Beyond work: image accordion (hover a strip, it opens; neighbours give way) ---------- */
.acc { list-style: none; margin: 0; padding: 0; display: flex; height: clamp(400px, 60vh, 580px); border-radius: 24px; overflow: hidden; background: #0f0e16; box-shadow: 0 40px 80px -40px rgba(0, 0, 0, 0.8); }
.acc-item { position: relative; flex: var(--g, 1) 1 0; min-width: 0; transition: flex-grow 0.8s cubic-bezier(0.34, 1.45, 0.64, 1); }
.acc-item + .acc-item { box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.08); }
.acc-link { position: absolute; inset: 0; display: block; overflow: hidden; color: var(--paper); text-decoration: none; }
.acc-link:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; border-radius: 0; }
.acc-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform: scale(1.08); transition: transform 1s var(--ease-out), filter 0.6s; filter: saturate(0.85) brightness(0.82); }
.acc-item.is-open .acc-img { transform: scale(1); filter: none; }
.acc-link::after { /* legibility wash at the bottom */
  content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(15, 14, 22, 0) 45%, rgba(15, 14, 22, 0.78)); pointer-events: none; }

/* the label while closed: written up the strip */
.acc-tag {
  position: absolute; left: 50%; bottom: 22px; z-index: 2; transform: translateX(-50%) rotate(180deg); writing-mode: vertical-rl;
  font-family: var(--font-display); font-size: 1.15rem; letter-spacing: 0.02em; white-space: nowrap; transition: opacity 0.3s;
}
.acc-item.is-open .acc-tag { opacity: 0; }
/* the panel content while open */
.acc-open { position: absolute; left: 24px; right: 24px; bottom: 24px; z-index: 2; display: grid; gap: 4px; opacity: 0; transform: translateY(14px); transition: opacity 0.35s, transform 0.5s var(--ease-out); pointer-events: none; }
.acc-item.is-open .acc-open { opacity: 1; transform: none; transition-delay: 0.18s; }
.acc-name { font-family: var(--font-display); font-size: clamp(1.6rem, 2.6vw, 2.3rem); line-height: 1.1; white-space: nowrap; }
.acc-hint { color: #e9dfe8; font-size: 0.95rem; white-space: nowrap; }
.acc-go { margin-top: 10px; justify-self: start; padding: 7px 14px; border-radius: 999px; background: var(--paper); color: var(--ink); font-weight: 600; font-size: 0.85rem; white-space: nowrap; }

/* writing: a page of the poem instead of a photo */
.acc-paper { background: repeating-linear-gradient(180deg, transparent 0 33px, rgba(90, 120, 170, 0.16) 33px 34px), #f6efe2; }
.acc-paper::after { background: linear-gradient(180deg, rgba(246, 239, 226, 0) 40%, rgba(36, 31, 44, 0.85)); }
.acc-words { position: absolute; left: 26px; top: 28px; width: 420px; font-family: var(--font-display); font-style: italic; font-size: 1.3rem; line-height: 34px; color: #2f2738; opacity: 0.85; }
/* theatre: velvet curtains until there's a photo */
.acc-curtain { background: radial-gradient(60% 35% at 50% 0%, rgba(255, 200, 140, 0.35), transparent 70%), repeating-linear-gradient(90deg, #6d1f2a 0 18px, #8c2f39 18px 30px, #5a1822 30px 40px); }
.acc-mask { position: absolute; left: 50%; top: 38%; transform: translate(-50%, -50%) scale(0.8); font-size: 3.6rem; opacity: 0.85; transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); }
.acc-item.is-open .acc-mask { transform: translate(-50%, -50%) scale(1.25) rotate(-8deg); }

/* phones: the strips stack, and a tap opens one (a second tap goes in) */
@media (max-width: 700px) {
  .acc { flex-direction: column; height: 620px; }
  .acc-item + .acc-item { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); }
  .acc-tag { writing-mode: horizontal-tb; left: 18px; bottom: 50%; transform: translateY(50%); }
  .acc-open { left: 18px; right: 18px; bottom: 18px; }
  .acc-words { width: 300px; font-size: 1.05rem; line-height: 28px; }
  .acc-item:not(.is-open) .acc-words { opacity: 0.18; }
  .acc-paper .acc-tag { color: #2f2738; }
}
@media (prefers-reduced-motion: reduce) { :root:not(.force-motion) .acc-item { transition-duration: 0.3s; transition-timing-function: ease-out; } }

/* ---------- About me: the "untangling" video (tall clip framed from the top: cloud + head to waist) ---------- */
.about-video { background: #000; }
.about-vid { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 0%; display: block; }
.about-replay {
  position: absolute; z-index: 3; left: 12px; bottom: 12px; display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px;
  border: 0; border-radius: 999px; cursor: pointer; background: rgba(246, 238, 228, 0.92); color: var(--ink); font-size: 0.82rem; font-weight: 600;
  animation: popin-btn 0.4s var(--ease-out);
}
.about-replay:hover { background: #fff; }
@keyframes popin-btn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* =========================================================
   My journey: a paper boat on a winding river
   ========================================================= */
.voyage { margin-top: clamp(64px, 9vw, 112px); }
.voyage-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 24px; margin-bottom: 24px; }
.voyage-head .sub-title { margin: 0; }
.voyage-hint { font-size: var(--fs-sm); color: var(--muted); }
.voyage-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(24px, 4vw, 56px); align-items: start; }

/* the card (sticks beside the river while you scroll) */
.voyage-card-wrap { position: sticky; top: 24px; }
.voyage-card {
  position: relative; padding: 26px 26px 20px; border-radius: 22px; overflow: hidden;
  background: linear-gradient(160deg, rgba(76, 96, 196, 0.16), rgba(243, 165, 115, 0.08)), var(--surface); border: 1px solid var(--border);
  box-shadow: 0 30px 60px -36px rgba(0, 0, 0, 0.8);
}
.voyage-card::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 4px; background: linear-gradient(90deg, #4c60c4, #f3a573); opacity: 0.8; }
.voyage-card > * { opacity: 0; transform: translateY(10px); }
.voyage-card.is-in > * { opacity: 1; transform: none; transition: opacity 0.45s var(--ease-out), transform 0.5s var(--ease-out); }
.voyage-card.is-in > :nth-child(2) { transition-delay: 0.05s; }
.voyage-card.is-in > :nth-child(3) { transition-delay: 0.1s; }
.voyage-card.is-in > :nth-child(4) { transition-delay: 0.15s; }
.voyage-card.is-in > :nth-child(n+5) { transition-delay: 0.2s; }
.vc-kicker { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.vc-title { font-family: var(--font-display); font-weight: 500; font-size: clamp(1.6rem, 2.6vw, 2.1rem); line-height: 1.15; }
.vc-place { margin-top: 6px; color: var(--muted); font-size: 0.95rem; }
.vc-body { margin-top: 14px; color: #e6dcd2; }
.vc-label { margin-top: 18px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.vc-list { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.vc-list li { position: relative; padding-left: 20px; color: #e6dcd2; }
.vc-list li::before { content: ""; position: absolute; left: 2px; top: 0.6em; width: 9px; height: 5px; border-radius: 50%; border: 1.5px solid #8fa3e8; }
.vc-left { margin-top: 16px; padding: 4px 14px 12px; border-left: 3px solid var(--accent); background: rgba(243, 165, 115, 0.08); border-radius: 0 12px 12px 0; }
.vc-left .vc-label { margin-top: 10px; color: var(--accent); }
.vc-left .vc-body { margin-top: 4px; }
.vc-link { display: inline-block; margin-top: 16px; color: var(--accent); font-weight: 600; text-decoration: none; }
.vc-link:hover { text-decoration: underline; }
.vc-nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
.vc-next, .vc-back { min-height: 40px; padding: 0 16px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: transform 0.2s var(--ease-out), background 0.2s; }
.vc-next { background: var(--accent); color: var(--on-accent); border-color: transparent; }
.vc-next:hover:not(:disabled), .vc-back:hover:not(:disabled) { transform: translateY(-2px); }
.vc-next:disabled { background: var(--surface-2); color: var(--muted); cursor: default; }
.vc-back:disabled { opacity: 0.35; cursor: default; }

/* the river */
.voyage-river { position: relative; min-height: 420px; touch-action: pan-y; }
.river-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.river-shore { fill: none; stroke: rgba(120, 140, 220, 0.12); stroke-width: 96; stroke-linecap: round; }
.river-body { fill: none; stroke: url(#riverGrad); stroke-width: 56; stroke-linecap: round; }
.river-shine { fill: none; stroke: rgba(200, 215, 255, 0.18); stroke-width: 1.5; stroke-dasharray: 30 46; transform: translate(-12px, 0); }
.river-current { fill: none; stroke: rgba(255, 255, 255, 0.35); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 2 18; animation: current 3s linear infinite; }
@keyframes current { to { stroke-dashoffset: -80; } }
.dock { fill: none; stroke: #a17a5b; stroke-width: 4; stroke-linecap: round; }
.rock { fill: #5d5868; stroke: #3e3a48; stroke-width: 1.5; }
.chop { fill: none; stroke: rgba(255, 255, 255, 0.5); stroke-width: 1.6; stroke-linecap: round; animation: chop 1.2s ease-in-out infinite alternate; }
@keyframes chop { from { transform: translateY(0); } to { transform: translateY(-3px); } }
.fog { fill: rgba(230, 230, 255, 0.12); filter: blur(6px); animation: fog 9s ease-in-out infinite alternate; }
@keyframes fog { from { transform: translateX(-18px); } to { transform: translateX(18px); } }
.tower { fill: #f6eee4; }
.stripe { stroke: #d65a4a; stroke-width: 3; }
.lamp { fill: #ffd27a; }
.beam { fill: rgba(255, 220, 140, 0.22); animation: beam 3.2s ease-in-out infinite; }
@keyframes beam { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

/* checkpoints */
.river-stops { list-style: none; margin: 0; padding: 0; position: absolute; inset: 0; pointer-events: none; }
.stop { position: absolute; transform: translate(-50%, -50%); pointer-events: auto; }
.stop-btn { position: relative; display: block; width: 46px; height: 46px; padding: 0; border: 0; background: none; cursor: pointer; }
.buoy {
  position: relative; display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%; font-size: 1.2rem;
  background: var(--surface); border: 2px solid rgba(246, 238, 228, 0.25); box-shadow: 0 8px 18px -8px rgba(0, 0, 0, 0.6);
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), border-color 0.3s, background 0.3s;
  animation: buoy 3.4s ease-in-out infinite;
}
.stop:nth-child(2n) .buoy { animation-delay: -1.2s; }
@keyframes buoy { 0%, 100% { translate: 0 0; } 50% { translate: 0 -3px; } }
.stop-btn:hover .buoy, .stop-btn:focus-visible .buoy { transform: scale(1.14); border-color: var(--accent); }
.stop.is-current .buoy { background: var(--accent); border-color: #fff3e6; }
.stop.is-current .buoy::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; border: 2px solid var(--accent); animation: ring-pulse 1.8s ease-out infinite; }
@keyframes ring-pulse { from { opacity: 0.9; transform: scale(1); } to { opacity: 0; transform: scale(1.6); } }
.stop-label {
  position: absolute; top: 50%; transform: translateY(-50%); white-space: nowrap; font-family: var(--font-display); font-size: 1.05rem; color: var(--text);
  padding: 4px 10px; border-radius: 999px; background: rgba(21, 19, 29, 0.7); backdrop-filter: blur(4px); transition: color 0.2s;
}
.stop-num { font-family: var(--font-body); font-size: 0.7rem; font-weight: 600; color: var(--accent); }
.on-left .stop-label { right: calc(100% + 12px); }
.on-right .stop-label { left: calc(100% + 12px); }
.stop-btn:hover .stop-label { color: var(--accent); }
.flag { position: absolute; left: 34px; top: -10px; width: 3px; height: 18px; background: #f6eee4; transform-origin: bottom; transform: scaleY(0); transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); }
.flag::after { content: ""; position: absolute; left: 3px; top: 0; border: 6px solid transparent; border-left: 10px solid var(--accent); border-right: 0; }
.stop.is-visited .flag { transform: scaleY(1); }

@keyframes rock { from { rotate: -5deg; } to { rotate: 5deg; } }
.wake { position: absolute; z-index: 2; width: 10px; height: 4px; margin: -2px 0 0 -5px; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, 0.55); pointer-events: none; animation: wake 1.4s ease-out forwards; }
@keyframes wake { to { width: 56px; height: 16px; margin: -8px 0 0 -28px; opacity: 0; } }

/* calm motion: everything still; the boat simply appears at each stop */
.is-calm .river-current, .is-calm .chop, .is-calm .fog, .is-calm .beam, .is-calm .buoy, .is-calm .stop.is-current .buoy::after { animation: none !important; }

/* phones: river first, the card floats at the bottom of the screen while you're on the river */
@media (max-width: 860px) {
  .voyage-grid { grid-template-columns: 1fr; }
  .voyage-card-wrap { order: 2; position: sticky; top: auto; bottom: 12px; z-index: 5; }
  .voyage-card { max-height: 46vh; overflow: auto; padding: 18px 18px 14px; }
  .vc-title { font-size: 1.4rem; }
  .stop-label { font-size: 0.85rem; padding: 2px 8px; }
  .on-left .stop-label, .on-right .stop-label { left: 50%; right: auto; top: calc(100% + 4px); transform: translateX(-50%); }
}

/* ---------- My journey, painted: the river image + living water + a rowing boat ---------- */
.voyage-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); }
.voyage-card-wrap { position: static; }
.voyage .voyage-river {
  position: relative; min-height: 0; aspect-ratio: 1376 / 768; border-radius: 22px; overflow: hidden; touch-action: pan-y;
  box-shadow: 0 40px 80px -40px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.river-img, .river-water { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.has-water .river-img { visibility: hidden; }

/* drifting mist over the third bend, and the lighthouse lamp breathing */
.river-fx { position: absolute; inset: 0; pointer-events: none; }
.fx-mist { position: absolute; left: 22%; top: 58%; width: 42%; height: 16%; border-radius: 50%; background: radial-gradient(closest-side, rgba(225, 222, 240, 0.32), transparent); filter: blur(8px); animation: mist 14s ease-in-out infinite alternate; }
.fx-mist-2 { left: 48%; top: 62%; width: 36%; height: 13%; animation-duration: 18s; animation-delay: -6s; opacity: 0.8; }
@keyframes mist { from { transform: translateX(-6%); } to { transform: translateX(8%); } }
.fx-lamp { position: absolute; left: 60.6%; top: 78.6%; width: 9%; aspect-ratio: 1; border-radius: 50%; transform: translate(-50%, -50%); background: radial-gradient(closest-side, rgba(255, 200, 110, 0.55), rgba(255, 200, 110, 0) 70%); mix-blend-mode: screen; animation: lamp 3.4s ease-in-out infinite; }
@keyframes lamp { 0%, 100% { opacity: 0.55; transform: translate(-50%, -50%) scale(0.92); } 50% { opacity: 1; transform: translate(-50%, -50%) scale(1.08); } }

/* checkpoints: small lanterns floating on the water */
.voyage .stop { position: absolute; transform: translate(-50%, -50%); pointer-events: auto; }
.voyage .stop-btn { position: relative; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; background: none; cursor: pointer; }
.lantern { position: relative; width: 14px; height: 14px; border-radius: 50%; background: radial-gradient(circle at 40% 35%, #fff6e0, #f3b36b 60%, #c9773f); box-shadow: 0 0 0 3px rgba(255, 246, 234, 0.25), 0 0 18px 4px rgba(255, 190, 110, 0.55); transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); animation: lantern 3s ease-in-out infinite; }
.voyage .stop:nth-child(2n) .lantern { animation-delay: -1.4s; }
@keyframes lantern { 0%, 100% { box-shadow: 0 0 0 3px rgba(255, 246, 234, 0.25), 0 0 14px 3px rgba(255, 190, 110, 0.45); } 50% { box-shadow: 0 0 0 3px rgba(255, 246, 234, 0.35), 0 0 22px 6px rgba(255, 190, 110, 0.7); } }
.voyage .stop-btn:hover .lantern, .voyage .stop-btn:focus-visible .lantern { transform: scale(1.35); }
.voyage .stop.is-current .lantern { transform: scale(1.5); }
.voyage .stop.is-current .lantern::after { content: ""; position: absolute; inset: -8px; border-radius: 50%; border: 1.5px solid rgba(255, 236, 210, 0.8); animation: ring-pulse 1.8s ease-out infinite; }
.voyage .stop.is-visited .lantern { background: radial-gradient(circle at 40% 35%, #fffaf0, #ffd28a 60%, #e09a4f); }
.voyage .stop-label {
  position: absolute; white-space: nowrap; font-family: var(--font-display); font-size: 0.98rem; color: #fff8ee;
  padding: 3px 10px; border-radius: 999px; background: rgba(21, 19, 29, 0.55); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); transition: background 0.2s; pointer-events: none;
}
.voyage .stop-btn:hover .stop-label, .voyage .stop.is-current .stop-label { background: rgba(21, 19, 29, 0.8); }
.voyage .stop-num { font-family: var(--font-body); font-size: 0.68rem; font-weight: 600; color: #ffc98f; }
.side-r .stop-label { left: calc(100% + 2px); top: 50%; transform: translateY(-50%); }
.side-l .stop-label { right: calc(100% + 2px); top: 50%; transform: translateY(-50%); }
.side-t .stop-label { top: auto; bottom: calc(100% + 2px); left: 50%; transform: translateX(-50%); }
.side-b .stop-label { top: calc(100% + 2px); left: 50%; transform: translateX(-50%); }

/* the boat (with me in it), sitting IN the water.
   The waterline runs along the hull at a slight slant (the boat is drawn in perspective):
   below it the hull fades into the river, and a dim mirrored copy + contact shadow sit underneath. */
.voyage .boat {
  position: absolute; left: 0; top: 0; z-index: 3; height: auto; aspect-ratio: 640 / 325; cursor: grab; touch-action: none; user-select: none;
  transform-origin: 50% 72%; border-radius: 12px;
  --waterline: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -33 640 358' preserveAspectRatio='none'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='328.2' y1='214' x2='331.6' y2='242'%3E%3Cstop offset='0' stop-color='%23fff'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='0'/%3E%3C/linearGradient%3E%3Crect y='-33' width='640' height='358' fill='url(%23g)'/%3E%3C/svg%3E");
  --mirror: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 325' preserveAspectRatio='none'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='305' y1='20' x2='331.4' y2='240'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='.62' stop-color='%23fff' stop-opacity='.8'/%3E%3Cstop offset='.94' stop-color='%23fff'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='0'/%3E%3C/linearGradient%3E%3Crect width='640' height='325' fill='url(%23g)'/%3E%3C/svg%3E");
}
.boat > * { position: absolute; pointer-events: none; }
.boat img { display: block; width: 100%; height: auto; max-width: none; -webkit-user-drag: none; }
/* the hull: masked at the waterline; the picture inside it bobs and pitches, the waterline stays put */
.boat-hull { left: 0; right: 0; top: -10.15%; bottom: 0; -webkit-mask: var(--waterline) 0 0 / 100% 100% no-repeat; mask: var(--waterline) 0 0 / 100% 100% no-repeat; }
.boat-hull .boat-img {
  position: absolute; left: 0; bottom: 0; filter: brightness(0.9) saturate(0.9) sepia(0.08);
  transform-origin: 50% 72%; transform: rotate(var(--pitch, 0deg)); transition: transform 0.25s ease-out;
  animation: row-bob 3.2s ease-in-out infinite;
}
@keyframes row-bob { 0%, 100% { margin-bottom: 0; } 50% { margin-bottom: -2.5px; } }   /* sinks a touch, then lifts */
/* its reflection: mirrored across the slanted waterline, darker, softer, fading with depth */
.boat-reflect {
  left: 0; top: 0; transform-origin: 50% 72%; transform: rotate(-6.7deg) scaleY(-1) rotate(6.7deg);
  -webkit-mask: var(--mirror) 0 0 / 100% 100% no-repeat; mask: var(--mirror) 0 0 / 100% 100% no-repeat;
  opacity: 0.38; filter: blur(1.4px) brightness(0.7) saturate(0.8); animation: reflect 2.6s ease-in-out infinite;
}
@keyframes reflect { 0%, 100% { opacity: 0.38; } 50% { opacity: 0.26; } }
/* a dark patch where the hull displaces the water, and a thin line of foam hugging it */
.boat-shadow { left: 2%; right: 2%; top: 63%; height: 20%; border-radius: 50%; transform: rotate(-6.7deg); background: radial-gradient(closest-side, rgba(12, 8, 24, 0.55), rgba(12, 8, 24, 0)); filter: blur(3px); }
.boat-foam { left: 4%; right: 4%; top: 69.5%; height: 4.5%; border-radius: 50%; transform: rotate(-6.7deg); background: radial-gradient(closest-side, rgba(255, 236, 214, 0.5), rgba(255, 236, 214, 0) 75%); mix-blend-mode: screen; animation: foam 1.9s ease-in-out infinite; }
@keyframes foam { 0%, 100% { opacity: 0.45; } 50% { opacity: 0.8; } }
/* the oars: wood, a lighter edge; a blade under water goes dim and green-blue */
.boat-oars { left: 0; top: 0; width: 100%; height: 100%; overflow: visible; }
.oar-shaft { fill: none; stroke: #6b4426; stroke-width: 11; stroke-linecap: round; }
.oar-blade { fill: #8a5a34; stroke: #5a381e; stroke-width: 3; stroke-linejoin: round; transition: opacity 0.18s; }
.oar-far .oar-shaft { stroke: #5e3b20; }
.boat.blades-in .oar-blade { opacity: 0.35; }

.voyage.is-sailing .boat-hull .boat-img { animation-duration: 1.6s; }
.voyage.is-sailing .boat-foam { animation-duration: 0.8s; }
.voyage.is-dragging .boat { cursor: grabbing; }
.voyage .boat:focus-visible { outline: 2px dashed var(--focus); outline-offset: 4px; }

.is-calm .fx-mist, .is-calm .fx-lamp, .is-calm .lantern, .is-calm .boat *, .is-calm .stop.is-current .lantern::after { animation: none !important; }

@media (max-width: 860px) {
  .voyage-grid { grid-template-columns: 1fr; }
  .voyage-card-wrap { order: 2; position: static; }
  .voyage-card { max-height: none; }
  .voyage .stop-label { font-size: 0.78rem; padding: 2px 7px; }
  .voyage .stop-btn { width: 30px; height: 30px; }
  .lantern { width: 11px; height: 11px; }
}

/* ---------- My journey, immersive: the river leaves its box ----------
   A tall track holds a full-screen stage that stays pinned while you scroll. The painting fills it edge
   to edge and dissolves into the page at every side; the card floats in the scene beside each checkpoint. */
.voyage-track { position: relative; width: 100vw; margin-left: calc(50% - 50vw); height: calc(100vh + var(--steps, 5) * 80vh); }
.voyage-stage {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
  -webkit-mask: linear-gradient(to bottom, transparent, #000 14%, #000 86%, transparent), linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(to bottom, transparent, #000 14%, #000 86%, transparent), linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
  mask-composite: intersect;
}
.voyage-stage .voyage-river { position: absolute; left: 0; top: 0; aspect-ratio: auto; min-height: 0; border-radius: 0; box-shadow: none; overflow: visible; will-change: transform; }
.voyage-stage .river-img, .voyage-stage .river-water { width: 100%; height: 100%; }
.voyage-stage .voyage-card {
  position: absolute; left: 0; top: 0; z-index: 6; width: min(380px, 32vw); max-height: calc(100vh - 48px); overflow: auto;
  background: linear-gradient(160deg, rgba(76, 96, 196, 0.14), rgba(243, 165, 115, 0.07)), rgba(21, 19, 29, 0.74);
  backdrop-filter: blur(12px) saturate(1.1); -webkit-backdrop-filter: blur(12px) saturate(1.1);
  border: 1px solid rgba(255, 246, 234, 0.12); box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.8);
  transition: opacity 0.35s var(--ease-out);
}
.voyage.is-sailing .voyage-card { opacity: 0; pointer-events: none; }   /* while she rows, the scene takes over */
.voyage-head { position: relative; z-index: 2; margin-bottom: -6vh; }

@media (max-width: 860px) {
  .voyage-stage { height: 100svh; -webkit-mask: linear-gradient(to bottom, transparent, #000 8%, #000 100%); mask: linear-gradient(to bottom, transparent, #000 8%, #000 100%); }
  .voyage-stage .voyage-card { left: 12px; right: 12px; top: auto; bottom: 12px; width: auto; max-height: 46svh; transform: none; padding: 18px 18px 14px; }
  .voyage.is-sailing .voyage-card { opacity: 0.6; }
}
@media (prefers-reduced-motion: reduce) { .voyage-stage .voyage-card { transition: none; } }
/* the painting's own edges dissolve too, so wherever the camera drifts there's never a hard border */
.voyage-stage .voyage-river {
  -webkit-mask: linear-gradient(to bottom, transparent, #000 4%, #000 92%, transparent), linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(to bottom, transparent, #000 4%, #000 92%, transparent), linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  mask-composite: intersect;
}
.voyage-stage .vc-nav { flex-wrap: wrap; }
.voyage-stage .vc-next, .voyage-stage .vc-back { white-space: nowrap; }
/* the tall painting: mist over the third bend, and the lighthouse lamp */
.voyage-stage .fx-mist { left: 46%; top: 45.5%; width: 46%; height: 6%; }
.voyage-stage .fx-mist-2 { left: 30%; top: 49%; width: 34%; height: 4.5%; }
.voyage-stage .fx-lamp { left: 72.6%; top: 83.7%; width: 7%; }

/* ---------- About me: a small round portrait beside the write-up (the words lead) ---------- */
.about { grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: clamp(28px, 4vw, 56px); max-width: 940px; }
.about-portrait {
  position: relative; margin: 6px 0 0; width: clamp(140px, 15vw, 190px); aspect-ratio: 1; border-radius: 50%; overflow: hidden;
  box-shadow: 0 0 0 4px rgba(255, 246, 234, 0.08), 0 0 0 10px rgba(243, 165, 115, 0.07), 0 24px 48px -24px rgba(0, 0, 0, 0.8);
}
.about-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.about-portrait::after { /* a touch of the dusk palette so it sits with the rest of the page */
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: linear-gradient(160deg, rgba(76, 96, 196, 0.08), rgba(243, 165, 115, 0.1)); mix-blend-mode: soft-light;
}
@media (max-width: 760px) {
  .about { grid-template-columns: 1fr; gap: 20px; }
  .about-portrait { width: 112px; margin: 0; }
}

/* ---------- About → My journey, one story ----------
   The portrait and write-up sit as a balanced, centred pair; a little stream runs from the
   "Curious about my journey?" bridge down into the river, and the river ends with the invitation to chat. */
.about { max-width: 980px; margin-inline: auto; grid-template-columns: clamp(200px, 22vw, 264px) minmax(0, 1fr); align-items: center; gap: clamp(32px, 5vw, 72px); }
.about-portrait { width: 100%; margin: 0; }
.journey-chat:hover .journey-chat-a .down { transform: translateY(3px); }

.story-stream {
  width: 2px; height: clamp(90px, 14vh, 150px); margin: clamp(44px, 6vw, 80px) auto 20px;
  background: repeating-linear-gradient(to bottom, rgba(243, 165, 115, 0.8) 0 6px, transparent 6px 14px); background-size: 2px 14px;
  -webkit-mask: linear-gradient(transparent, #000 25%, #000 75%, transparent); mask: linear-gradient(transparent, #000 25%, #000 75%, transparent);
  animation: stream-flow 1.1s linear infinite;
}
@keyframes stream-flow { to { background-position: 0 14px; } }

.voyage { margin-top: 0; }
.voyage-head { flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 6px; }

.voyage-outro { display: flex; justify-content: center; margin-top: clamp(28px, 4vw, 56px); text-align: center; }
.voyage-outro .journey-chat { margin-top: 0; border-radius: 20px; }

@media (prefers-reduced-motion: reduce) { :root:not(.force-motion) .story-stream { animation: none; } }
@media (max-width: 760px) {
  .about { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 20px; }
  .about-portrait { width: 132px; }
  .about-text p { margin-inline: auto; }
}
.story-bridge { display: flex; justify-content: center; margin-top: clamp(44px, 6vw, 80px); text-align: center; }
.story-bridge .journey-chat { margin-top: 0; border-radius: 20px; }
.story-bridge + .story-stream { margin-top: 18px; }
/* the portrait lines up with the "About me" title; 48px from the write-up to the bridge */
.about { margin-inline: 0; }
.story-bridge { margin-top: 48px; }
/* "Curious about my journey?" now lines up with the write-up; the stream drops from its centre */
.story-bridge { display: block; margin-top: 48px; text-align: left; }
.story-stream { margin: 14px 0 10px; }
@media (max-width: 760px) { .story-bridge { text-align: center; } }

/* ---------- Journey cards: a glimpse that fits on screen, with the tilt-card feel ----------
   The outer .voyage-card is only positioned (it follows the boat); .vc-inner is the card you see and
   tilt. No scrolling inside, no buttons: scrolling the page is how you row on. */
.voyage-stage .voyage-card {
  width: min(360px, 30vw); max-height: none; overflow: visible; padding: 0;
  background: none; border: 0; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; perspective: 800px;
}
.voyage-stage .voyage-card::before { display: none; }
.voyage-stage .voyage-card > * { opacity: 0; transform: translateY(10px); }
.voyage-stage .voyage-card.is-in > * { opacity: 1; transform: none; }
.vc-inner {
  position: relative; padding: 22px 22px 18px; border-radius: 24px; overflow: hidden; transform-style: preserve-3d; will-change: transform;
  background: linear-gradient(160deg, rgba(76, 96, 196, 0.16), rgba(243, 165, 115, 0.08)), rgba(21, 19, 29, 0.8);
  backdrop-filter: blur(12px) saturate(1.1); -webkit-backdrop-filter: blur(12px) saturate(1.1);
  border: 1px solid rgba(255, 246, 234, 0.12); box-shadow: 0 20px 44px -12px rgba(0, 0, 0, 0.55);
  transition: opacity 0.45s var(--ease-out), box-shadow 0.3s;
}
.voyage-card:hover .vc-inner { box-shadow: 0 9px 24px -8px rgba(0, 0, 0, 0.5); }
.vc-inner::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px; background: linear-gradient(90deg, #4c60c4, #f3a573); opacity: 0.8; }
.vc-sheen { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; }
.vc-inner .vc-kicker { margin-bottom: 6px; font-size: 0.72rem; }
.vc-step { color: var(--text); opacity: 0.85; }
.vc-inner .vc-title { font-size: clamp(1.35rem, 2vw, 1.6rem); }
.vc-inner .vc-place { margin-top: 4px; font-size: 0.88rem; }
.vc-inner .vc-body { margin-top: 10px; font-size: 0.92rem; line-height: 1.5; }
.vc-inner .vc-body + .vc-body { margin-top: 6px; }
.vc-tags { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.vc-tags li { padding: 4px 10px; border-radius: 999px; font-size: 0.78rem; color: #f6e6d6; background: rgba(243, 165, 115, 0.12); border: 1px solid rgba(243, 165, 115, 0.25); }
.vc-inner .vc-left { margin-top: 12px; padding: 2px 12px 10px; }
.vc-inner .vc-left .vc-body { font-size: 0.88rem; }
.vc-inner .vc-link { margin-top: 12px; font-size: 0.92rem; }
.vc-cue { margin-top: 14px; font-size: 0.88rem; font-weight: 600; color: var(--accent); }
.vc-cue-arrow { display: inline-block; animation: bob 2.4s ease-in-out infinite; }
.is-calm .vc-cue-arrow { animation: none; }
@media (max-width: 860px) {
  .voyage-stage .voyage-card { width: auto; max-height: none; padding: 0; }
  .vc-inner { padding: 16px 16px 14px; }
  .vc-inner .vc-body { font-size: 0.88rem; }
}


/* ---------- Hero title: "I design the moment people stop second-guessing." ----------
   "stop" in coral; a hand-drawn line crosses out "second-guessing" and the doubt (?) floats away.
   Plays once on load, again on hover. Quiet enough that the lake stays the main event. */
.hero-copy h1.hero-title { font-size: clamp(2rem, 3.6vw, 3.1rem); line-height: 1.12; max-width: 17ch; letter-spacing: -0.01em; }
.ht-stop { color: #ff8a73; font-style: italic; }
.ht-doubt { position: relative; display: inline-block; white-space: nowrap; }
.ht-strike { position: absolute; left: -3%; top: 50%; width: 106%; height: 0.42em; margin-top: -0.17em; overflow: visible; pointer-events: none; }
.ht-strike path { fill: none; stroke: #ff8a73; stroke-width: 3.4; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; animation: ht-draw 0.75s cubic-bezier(.6, .1, .3, 1) 1.1s forwards; }
.ht-q { position: absolute; right: -0.55em; top: -0.35em; font-size: 0.6em; color: #ff8a73; opacity: 0; animation: ht-float 1.6s ease-out 1.75s forwards; }
@keyframes ht-draw { to { stroke-dashoffset: 0; } }
@keyframes ht-float { 0% { opacity: 0; transform: translate(0, 6px) rotate(0); } 25% { opacity: 1; } 100% { opacity: 0; transform: translate(14px, -26px) rotate(24deg); } }
/* hover the title to cross it out again */
.hero-title:hover .ht-strike path { animation: ht-redraw 0.75s cubic-bezier(.6, .1, .3, 1) forwards; }
.hero-title:hover .ht-q { animation: ht-float2 1.6s ease-out 0.6s forwards; }
@keyframes ht-redraw { 0% { stroke-dashoffset: 100; } 100% { stroke-dashoffset: 0; } }
@keyframes ht-float2 { 0% { opacity: 0; transform: translate(0, 6px) rotate(0); } 25% { opacity: 1; } 100% { opacity: 0; transform: translate(14px, -26px) rotate(24deg); } }
@media (prefers-reduced-motion: reduce) {
  :root:not(.force-motion) .ht-strike path { animation: none; stroke-dashoffset: 0; }
  :root:not(.force-motion) .ht-q { animation: none; }
}
@media (max-width: 760px) { .hero-copy h1.hero-title { font-size: clamp(1.9rem, 8vw, 2.4rem); max-width: 16ch; } }

/* ---------- Hero copy, readable on the painted sky ----------
   No shade over the scene. Each line carries its own contrast: pure white, a heavier weight, and a
   tight dark glow that hugs the letters like a soft outline, so the sky around them stays untouched. */
.hero-copy .eyebrow { opacity: 1; color: #ffffff; font-weight: 600; }
.hero-copy .lede { color: #ffffff; font-weight: 600; text-shadow: 0 0 1px rgba(14, 10, 30, 0.95), 0 1px 2px rgba(14, 10, 30, 0.9), 0 0 5px rgba(14, 10, 30, 0.8), 0 0 14px rgba(14, 10, 30, 0.45); }
.hero-copy .eyebrow, .hero-copy .hero-title { text-shadow: 0 0 1px rgba(14, 10, 30, 0.7), 0 1px 3px rgba(14, 10, 30, 0.6), 0 0 16px rgba(14, 10, 30, 0.4); }
.hero-copy .hero-title { color: #ffffff; }
.ht-stop { color: #ff9a85; font-weight: 600; text-shadow: 0 0 1px rgba(14, 10, 30, 1), 0 0 2px rgba(14, 10, 30, 0.95), 0 1px 4px rgba(14, 10, 30, 0.85), 0 0 12px rgba(14, 10, 30, 0.55) !important; }
.hero-role { display: inline-flex; align-items: center; gap: 10px; }
.role-dot { width: 6px; height: 6px; border-radius: 50%; background: #7fd1c1; box-shadow: 0 0 0 3px rgba(127, 209, 193, 0.22); animation: role-pulse 2.6s ease-in-out infinite; }
@keyframes role-pulse { 0%, 100% { box-shadow: 0 0 0 3px rgba(127, 209, 193, 0.22); } 50% { box-shadow: 0 0 0 6px rgba(127, 209, 193, 0.08); } }
@media (max-width: 760px) { .hero-copy .lede, .hero-copy .eyebrow, .hero-copy .hero-title { text-shadow: none; } }

/* =========================================================
   From the lake to a section (js/transition.js), and the water that comes along
   ========================================================= */
/* below the surface: deep lake water, a little lighter where you went in */
.dive-veil {
  position: fixed; inset: 0; z-index: 200; pointer-events: none; opacity: 0; visibility: hidden;
  background:
    radial-gradient(90% 70% at var(--x, 50%) var(--y, 60%), rgba(96, 104, 160, 0.45), rgba(21, 19, 29, 0) 70%),
    linear-gradient(180deg, #262a45, #1a1928 60%, var(--bg));
}
.dive-veil.is-on { visibility: visible; }
.hero { will-change: transform, filter; }
/* the section number catches the last ring */
.section-num { position: relative; display: inline-block; }
.section-num.num-ripple::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 14px; height: 6px; border-radius: 50%;
  border: 1.5px solid var(--accent); transform: translate(-50%, -50%); animation: num-ring 1.2s ease-out 0.25s both;
}
@keyframes num-ring { 0% { opacity: 1; width: 14px; height: 6px; } 100% { opacity: 0; width: 120px; height: 36px; } }

/* the sky's reflection carries on below the lake, and slow water lines drift behind the sections */
main { position: relative; isolation: isolate; }
main::before {
  content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: 0; height: 420px; pointer-events: none;
  background:
    radial-gradient(60% 70% at 55% 40%, rgba(243, 165, 115, 0.07), transparent 70%),
    linear-gradient(180deg, rgba(110, 96, 150, 0) 0%, rgba(110, 96, 150, 0.1) 35%, transparent);   /* starts at nothing, so it meets the hero's fade without a line */
}
main::after {
  content: ""; position: absolute; z-index: -1; inset: 0; pointer-events: none; opacity: 0.55;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='140' viewBox='0 0 600 140'%3E%3Cg fill='none' stroke='%23fff6ea' stroke-opacity='.05' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M20 30 q60 -8 120 0 t120 0'/%3E%3Cpath d='M330 62 q50 -6 100 0 t100 0'/%3E%3Cpath d='M90 104 q70 -9 140 0 t140 0'/%3E%3Cpath d='M440 128 q40 -5 80 0'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 600px 140px;
  -webkit-mask-image: linear-gradient(180deg, #000, #000 60%, transparent);
  mask-image: linear-gradient(180deg, #000, #000 60%, transparent);
  animation: water-drift 60s linear infinite;
}
@keyframes water-drift { to { background-position: 600px 0; } }

/* project cards rise from the surface: a ring opens under each as it arrives */
.project { position: relative; }
.project::after {
  content: ""; position: absolute; left: 50%; bottom: -18px; width: 40%; height: 18px; border-radius: 50%;
  border: 1.5px solid rgba(255, 246, 234, 0.25); transform: translateX(-50%) scale(0.3); opacity: 0; pointer-events: none;
}
.js .project.reveal { transform: translateY(34px); }
.js .project.reveal.is-in { transform: none; transition: opacity 0.9s var(--ease-out), transform 1s cubic-bezier(.2, .9, .3, 1.05); }
.project.is-in::after { animation: card-ring 1.4s ease-out 0.15s both; }
@keyframes card-ring { 0% { opacity: 0.9; transform: translateX(-50%) scale(0.3); } 100% { opacity: 0; transform: translateX(-50%) scale(1.6); } }

/* a small ripple where the pointer touches a picture */



/* -------- Side project: Focus Buddy, after the case studies -------- */
.fb-card {
  margin-top: clamp(64px, 9vw, 120px); padding: clamp(20px, 3vw, 36px); border-radius: calc(var(--radius) + 8px);
  background: radial-gradient(90% 120% at 0% 0%, rgba(230, 176, 92, 0.16), transparent 60%),
              linear-gradient(135deg, rgba(60, 72, 190, 0.2), rgba(243, 165, 115, 0.08)), var(--surface);
  border: 1px solid var(--border); scroll-margin-top: 24px;
}
.fb-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-bottom: clamp(18px, 2.5vw, 28px); }
.fb-grid { display: grid; grid-template-columns: 7fr 5fr; gap: clamp(24px, 4vw, 56px); align-items: center; }
.fb-body .project-summary + .project-summary { margin-top: 10px; }
.fb-why { font-family: var(--font-display); font-style: italic; color: #f0d9b5; max-width: 44ch; margin-bottom: 22px; }

/* the clip: the real app in a little browser window */
.fb-clip { display: block; position: relative; text-decoration: none; color: inherit; }
.fb-window { display: block; border-radius: 14px; overflow: hidden; background: #0b0f1c; border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 30px 60px -28px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(230, 176, 92, 0.06); transition: transform 0.5s var(--ease-out); }
.fb-card:hover .fb-window { transform: translateY(-3px); }
.fb-screen { display: block; position: relative; aspect-ratio: 750 / 470; overflow: hidden; }
.fb-frame { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s ease, transform 3.2s ease-out; transform: scale(1.03); }
.fb-frame.is-on { opacity: 1; transform: scale(1); }
.fb-cursor { position: absolute; left: var(--x, 64%); top: var(--y, 90%); width: 20px; height: 20px; pointer-events: none; z-index: 2;
  transition: left 0.9s cubic-bezier(.45, .05, .25, 1), top 0.9s cubic-bezier(.45, .05, .25, 1), opacity 0.3s;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M3 2l13 7-6 1.6L7.4 17z' fill='%23fff' stroke='%23111' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5)); }
.fb-cursor::after { content: ""; position: absolute; left: -11px; top: -11px; width: 26px; height: 26px; border-radius: 50%; border: 2px solid rgba(230, 176, 92, 0.9); opacity: 0; transform: scale(0.3); }
.fb-cursor.is-click::after { animation: fb-click 0.55s ease-out; }
@keyframes fb-click { 0% { opacity: 1; transform: scale(0.3); } 100% { opacity: 0; transform: scale(1.4); } }
.fb-steps { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.fb-steps b { position: relative; overflow: hidden; font-weight: 500; font-size: 0.76rem; padding: 6px 11px; border-radius: 999px; color: var(--muted); background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border); transition: color 0.3s, border-color 0.3s, background 0.3s; }
.fb-steps b.is-on { color: #1d1608; background: #e6b05c; border-color: transparent; }

@media (max-width: 860px) {
  .fb-grid { grid-template-columns: 1fr; }
}
.fb-kicker span:not(.role-dot) { white-space: nowrap; } .fb-kicker .role-dot { flex: none; }

/* Focus Buddy card, simplified: one eyebrow, one title, one line, one button; the clip carries the rest */
.fb-grid { grid-template-columns: 3fr 2fr; gap: clamp(28px, 4.5vw, 64px); }
.fb-eyebrow { display: flex; align-items: center; gap: 10px; font-size: 0.78rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: #e6b05c; margin-bottom: 14px; }
.fb-body h3 { font-size: clamp(1.75rem, 2.6vw, 2.35rem); line-height: 1.12; letter-spacing: -0.01em; max-width: 14ch; }
.fb-lede { margin-top: 16px; font-size: 1.02rem; line-height: 1.6; color: var(--muted); max-width: 36ch; }
.fb-body .btn { margin-top: 28px; }
@media (max-width: 860px) { .fb-grid { grid-template-columns: 1fr; } .fb-body h3 { max-width: none; } }

/* =========================================================
   Site nav, on every page (js/sitenav.js drives the classes):
   - clear over the lake / a case-study hero, a slim glass bar after it (.is-solid)
   - slides away while you scroll down, back the moment you scroll up (.is-hidden)
   - the section you're in is marked (aria-current); Contact is a small outlined pill
   - phones: name + Menu, the links drop down as a panel (.is-open)
   ========================================================= */
.site-nav {
  --nav-solid: rgba(21, 19, 29, 0.78);
  --nav-panel: #1f1c2e;
  --nav-line: rgba(255, 255, 255, 0.08);
  transition: transform 0.38s var(--ease-out), background 0.3s, padding 0.3s, box-shadow 0.3s, color 0.3s;
}
.nav.site-nav { position: fixed; z-index: 60; top: 0; left: 0; right: 0; }
.site-nav.is-solid { background: var(--nav-solid); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 1px 0 var(--nav-line); }
.nav.site-nav.is-solid { padding-top: 10px; padding-bottom: 10px; }
.site-nav.is-hidden { transform: translateY(-110%); }
.nav-links a[aria-current] { opacity: 1; background-size: 100% 1px; }
.nav-links .nav-contact { padding: 6px 14px; border: 1px solid currentColor; border-radius: 999px; background-image: none; opacity: 1; }
.nav-links .nav-contact:hover { background: rgba(255, 255, 255, 0.12); }
.nav-links .nav-contact[aria-current] { background: rgba(255, 255, 255, 0.14); }
.nav-tools { display: flex; align-items: center; gap: 10px; }
.nav-menu {
  display: none; min-height: 40px; padding: 0 16px; border-radius: 999px; cursor: pointer;
  border: 1px solid currentColor; background: none; color: inherit; font-size: var(--fs-sm); font-weight: 600;
}
@media (min-width: 761px) {
  .nav.site-nav .nav-links { margin-left: auto; }
}
@media (max-width: 760px) {
  .nav-menu { display: inline-flex; align-items: center; }
  .site-nav .nav-links {
    display: none; position: absolute; top: calc(100% + 6px); left: 12px; right: 12px; flex-direction: column; align-items: stretch; gap: 2px;
    padding: 10px; border-radius: 16px; background: var(--nav-panel); box-shadow: 0 18px 40px -16px rgba(0, 0, 0, 0.55), 0 0 0 1px var(--nav-line);
  }
  .site-nav.is-open .nav-links { display: flex; animation: nav-drop 0.25s var(--ease-out); }
  .site-nav .nav-links a { display: block; padding: 12px 14px; font-size: var(--fs-base); border-radius: 10px; background-image: none; }
  .site-nav .nav-links a[aria-current] { background: rgba(127, 127, 140, 0.16); }
  .site-nav .nav-links .nav-contact { margin-top: 6px; text-align: center; }
  .nav.site-nav { justify-content: flex-start; }
  .nav.site-nav .nav-tools { margin-left: auto; }
  .hero-copy { margin-top: 72px; }   /* the nav floats over the top now */
}
@keyframes nav-drop { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* =========================================================
   Contact: stones on the shore.
   A centred heading, then a row of river stones on dusk water (the address
   sits under the email stone, with an icon copy): each stone bobs, sends a
   ripple when you reach for it, and the email stone splashes when copied.
   ========================================================= */
.contact { position: relative; }
.contact-head { max-width: 680px; }
.contact-head h2 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
.contact-status { display: inline-flex; align-items: center; gap: 10px; margin-top: 14px; color: var(--muted); font-size: var(--fs-base); }

.zeny-says { font-family: var(--font-display); font-size: clamp(1.45rem, 2.4vw, 1.8rem); line-height: 1.1; color: #f2c46d; transform: rotate(-2deg); transform-origin: left; }
.zeny-sign { margin-left: 6px; color: var(--muted); white-space: nowrap; }

/* ---------- the shore ---------- */
.shore {
  list-style: none; position: relative; margin: clamp(48px, 7vw, 80px) 0 0; padding: clamp(28px, 4vw, 44px) clamp(12px, 3vw, 40px) clamp(56px, 7vw, 84px);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: clamp(28px, 4vw, 48px) 16px; justify-items: center;
  border-radius: 28px; overflow: hidden; isolation: isolate;
  background:
    radial-gradient(70% 60% at 50% 0%, rgba(243, 165, 115, 0.16), transparent 70%),
    linear-gradient(180deg, rgba(70, 62, 120, 0.28), rgba(30, 27, 52, 0.55) 70%, rgba(21, 19, 29, 0.2));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.shore::before {   /* slow drifting water lines */
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0.9; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='520' height='120' viewBox='0 0 520 120'%3E%3Cg fill='none' stroke='%23fff6ea' stroke-opacity='.07' stroke-width='1.3' stroke-linecap='round'%3E%3Cpath d='M20 26 q50 -7 100 0 t100 0'/%3E%3Cpath d='M280 58 q45 -6 90 0 t90 0'/%3E%3Cpath d='M70 92 q60 -8 120 0 t120 0'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 520px 120px; animation: water-drift 50s linear infinite;
}
.stone-spot[hidden] { display: none; }
.stone-spot { display: grid; justify-items: center; align-content: start; gap: 14px; text-align: center; }
.stone-note { max-width: 17ch; min-height: 2.3em; font-family: var(--font-body); font-size: 0.9rem; line-height: 1.3; color: var(--paper); opacity: 0.9; position: relative; }
.stone-note::after {   /* a little hand-drawn arrow down to the stone */
  content: ""; display: block; width: 22px; height: 22px; margin: 4px auto 0; opacity: 0.75;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 3c3 5 4 10 3 17m0 0-4-4m4 4 4-4' fill='none' stroke='%23f3a573' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* a river stone: a soft pebble, its icon pressed in, its reflection on the water */
.stone {
  position: relative; display: grid; justify-items: center; gap: 16px; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--text); text-decoration: none; font: inherit;
}
.stone-rock {
  --c1: #f6c7a4; --c2: #c9734a;
  position: relative; display: grid; place-items: center; width: 118px; height: 86px;
  border-radius: 52% 48% 46% 54% / 60% 58% 42% 40%;
  background: radial-gradient(120% 100% at 30% 22%, rgba(255, 255, 255, 0.55), transparent 38%), radial-gradient(140% 120% at 40% 30%, var(--c1), var(--c2) 70%);
  box-shadow: inset -8px -10px 16px rgba(0, 0, 0, 0.22), inset 4px 5px 8px rgba(255, 255, 255, 0.25), 0 14px 18px -10px rgba(0, 0, 0, 0.6);
  animation: stone-bob 4.2s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -1.1s);
  transition: transform 0.35s var(--ease-out);
}
.stone-rock svg { width: 34px; height: 34px; color: rgba(29, 26, 43, 0.78); filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.35)); }
.stone-in .stone-rock { --c1: #b8c6ea; --c2: #56679f; }
.stone-in .stone-rock svg { color: rgba(16, 20, 44, 0.78); }
.stone-md .stone-rock { --c1: #efe6da; --c2: #a8998a; border-radius: 46% 54% 50% 50% / 56% 52% 48% 44%; }
.stone-cv .stone-rock { --c1: #b5e6dc; --c2: #3f8f80; }
/* its reflection, and the ripple rings it sends out */
.stone-rock::before, .stone-rock::after {
  content: ""; position: absolute; left: 50%; top: 100%; width: 140%; height: 26px; border-radius: 50%; pointer-events: none;
  transform: translate(-50%, -30%) scale(0.6); border: 1.5px solid rgba(255, 246, 234, 0.5); opacity: 0;
}
.stone-name { font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.02em; color: var(--text); opacity: 0.88; }
.stone:hover .stone-rock, .stone:focus-visible .stone-rock { transform: translateY(-8px) rotate(-2deg); animation-play-state: paused; }
.stone:hover .stone-rock::before, .stone:focus-visible .stone-rock::before { animation: stone-ring 1.6s ease-out infinite; }
.stone:hover .stone-rock::after, .stone:focus-visible .stone-rock::after { animation: stone-ring 1.6s ease-out 0.8s infinite; }
.stone:hover .stone-name { opacity: 1; }
.stone:focus-visible { outline: none; }
.stone:focus-visible .stone-rock { outline: 3px solid var(--accent); outline-offset: 6px; }
.stone.is-copied .stone-rock { animation: stone-plop 0.7s var(--ease-out); }
.stone.is-copied .stone-rock::before { animation: stone-ring 0.9s ease-out; border-width: 2.5px; }
.stone.is-copied .stone-name { color: #7fd1c1; }
@keyframes stone-bob { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-5px) rotate(1deg); } }
@keyframes stone-ring { 0% { opacity: 0.85; transform: translate(-50%, -30%) scale(0.5); } 100% { opacity: 0; transform: translate(-50%, -30%) scale(1.6); } }
@keyframes stone-plop { 0% { transform: translateY(-8px); } 35% { transform: translateY(8px) scale(1.04, 0.94); } 70% { transform: translateY(-3px); } 100% { transform: none; } }

@media (max-width: 760px) {
  .shore { display: flex; flex-wrap: wrap; justify-content: center; }
  .stone-spot { flex: 0 0 calc(50% - 8px); }
  .stone-note { font-size: 1.25rem; }
  .stone-rock { width: 100px; height: 74px; }
}

/* contact, round two: centred heading; the address lives under the email stone with an icon-only copy (copy → tick);
   Zeny's aside sits at the foot of the shore */
.contact-head { margin: 0 auto; text-align: center; }
.contact-status { justify-content: center; }
.shore-wrap {
  position: relative; margin-top: clamp(40px, 6vw, 64px); border-radius: 28px; overflow: hidden; isolation: isolate;
  padding-bottom: clamp(26px, 4vw, 40px);
  background:
    radial-gradient(70% 60% at 50% 0%, rgba(243, 165, 115, 0.16), transparent 70%),
    linear-gradient(180deg, #2b2742, #221f33 70%, #1f1c2e);
  border: 1px solid rgba(246, 238, 228, 0.1);   /* a solid dusk card that lifts off the page: lighter than the background all the way down */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 30px 60px -30px rgba(0, 0, 0, 0.7);
}
.shore-wrap::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='520' height='120' viewBox='0 0 520 120'%3E%3Cg fill='none' stroke='%23fff6ea' stroke-opacity='.07' stroke-width='1.3' stroke-linecap='round'%3E%3Cpath d='M20 26 q50 -7 100 0 t100 0'/%3E%3Cpath d='M280 58 q45 -6 90 0 t90 0'/%3E%3Cpath d='M70 92 q60 -8 120 0 t120 0'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 520px 120px; animation: water-drift 50s linear infinite;
}
.shore { margin: 0; background: none; box-shadow: none; border-radius: 0; overflow: visible; padding-bottom: clamp(28px, 4vw, 40px); }
.shore::before { content: none; }
.stone-note.is-blank { visibility: hidden; }
.stone-mail { gap: 0; }
.stone-addr { display: inline-flex; align-items: center; gap: 6px; margin-top: 2px; font-size: var(--fs-sm); font-weight: 600; color: var(--text); white-space: nowrap; }
.copy-icon {
  position: relative; display: grid; place-items: center; width: 34px; height: 34px; padding: 0; border-radius: 10px; cursor: pointer;
  border: 1px solid rgba(255, 246, 234, 0.16); background: rgba(255, 246, 234, 0.08); color: var(--text);
  transition: background 0.2s, border-color 0.2s, color 0.2s, transform 0.2s var(--ease-out);
}
.copy-icon:hover { background: rgba(255, 246, 234, 0.16); transform: translateY(-1px); }
.copy-icon svg { position: absolute; width: 17px; height: 17px; transition: opacity 0.2s, transform 0.3s var(--ease-out); }
.copy-icon .ic-tick { opacity: 0; transform: scale(0.4); }
.copy-icon.is-copied { color: #7fd1c1; border-color: rgba(127, 209, 193, 0.5); background: rgba(127, 209, 193, 0.14); }
.copy-icon.is-copied .ic-copy { opacity: 0; transform: scale(0.4); }
.copy-icon.is-copied .ic-tick { opacity: 1; transform: none; }
.zeny-says { display: block; margin: 0; padding: 0 16px; text-align: center; transform: rotate(-1.5deg); transform-origin: center; }
.stone-note { min-height: calc(2.1em + 26px); }   /* two lines + the arrow, so every stone sits at the same height */
.contact-status { display: block; } .contact-status .role-dot { display: inline-block; vertical-align: middle; margin: -2px 8px 0 0; }   /* the dot stays with the words when they wrap */

/* contact, round three: heading left-aligned like every other section; no notes over the stones;
   Zeny's line in the site's serif (Fraunces italic), quiet, not handwritten */
.contact-head { margin: 0; text-align: left; }
.shore { padding-top: clamp(40px, 5vw, 56px); }
.zeny-says {
  font-family: var(--font-display); font-style: italic; font-weight: 400; font-size: clamp(1.05rem, 1.6vw, 1.2rem); line-height: 1.5;
  color: var(--text); opacity: 0.85; transform: none;
}
.zeny-sign { font-family: var(--font-body); font-style: normal; font-size: var(--fs-sm); color: var(--muted); margin-left: 8px; }

/* =========================================================
   Visitor notes (js/notes.js): a turntable of notes on dusk water, above Contact.
   Front note big and readable; the others wait behind at an angle. The dashed card flips into a form.
   ========================================================= */
.vn-table {
  position: relative; height: 460px; border-radius: 28px; overflow: hidden; isolation: isolate; perspective: 1300px;
  cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none; outline: none;
  /* a solid dusk card that lifts off the page, like the contact card: lighter all the way down, a thin light edge, a soft shadow */
  background: radial-gradient(60% 70% at 50% 45%, rgba(243, 165, 115, 0.14), transparent 70%), linear-gradient(180deg, #2b2742, #221f33 70%, #1f1c2e);
  border: 1px solid rgba(246, 238, 228, 0.1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 30px 60px -30px rgba(0, 0, 0, 0.7);
}
.vn-table::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='520' height='120' viewBox='0 0 520 120'%3E%3Cg fill='none' stroke='%23fff6ea' stroke-opacity='.08' stroke-width='1.3' stroke-linecap='round'%3E%3Cpath d='M20 26 q50 -7 100 0 t100 0'/%3E%3Cpath d='M280 58 q45 -6 90 0 t90 0'/%3E%3Cpath d='M70 92 q60 -8 120 0 t120 0'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 520px 120px; animation: water-drift 50s linear infinite;
}
.vn-table.is-dragging { cursor: grabbing; }
.vn-table.is-writing, .vn-table.is-empty { cursor: default; }
.vn-table:focus-visible { box-shadow: inset 0 0 0 3px var(--accent), 0 30px 60px -30px rgba(0, 0, 0, 0.7); }
.vn-deck { position: absolute; left: 50%; top: calc(50% - 22px); width: 0; height: 0; transform-style: preserve-3d; }
.vn-card {
  --cw: 320px; --ch: 250px;
  position: absolute; left: calc(var(--cw) / -2); top: calc(var(--ch) / -2); width: var(--cw); height: var(--ch); margin: 0;
  transform-style: preserve-3d; will-change: transform, opacity;
  transition: width 0.45s var(--ease-out), height 0.45s var(--ease-out), left 0.45s var(--ease-out), top 0.45s var(--ease-out), opacity 0.35s;
}

/* a note */
.vn-note {
  position: relative; height: 100%; display: flex; flex-direction: column; padding: 26px 26px 22px; border-radius: 18px; background: var(--paper); color: var(--ink);
  box-shadow: 0 30px 50px -26px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(255, 255, 255, 0.5) inset;
}
.vn-note::before { content: "\201C"; display: block; height: 30px; font-family: var(--font-display); font-size: 3.4rem; line-height: 1; color: #c9734a; opacity: 0.6; }
.vn-text { font-family: var(--font-display); font-style: italic; font-size: 1.14rem; line-height: 1.45; color: #241f2c; overflow-wrap: anywhere; }
.vn-who { margin-top: auto; padding-top: 14px; font-size: 0.82rem; color: #6a6070; }
.vn-who b { color: #241f2c; font-weight: 600; }
.vn-note::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(70% 60% at var(--gx, 50%) var(--gy, 0%), rgba(255, 255, 255, 0.55), transparent 60%); opacity: var(--sheen, 0); mix-blend-mode: soft-light;
}
.vn-pending { position: absolute; right: 16px; top: 16px; padding: 3px 9px; border-radius: 999px; background: rgba(127, 209, 193, 0.22); color: #2f7f71; font-size: 0.68rem; font-weight: 600; }
.vn-card.is-new .vn-note { box-shadow: 0 0 0 3px var(--accent), 0 30px 50px -26px rgba(0, 0, 0, 0.85); }

/* the blank card: dark, dashed, glowing; flips over into a paper form */
.vn-flip { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform 0.7s cubic-bezier(.45, .05, .2, 1); }
.vn-slot.is-writing .vn-flip { transform: rotateY(180deg); }
.vn-face { position: absolute; inset: 0; border-radius: 18px; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.vn-blank {
  display: grid; place-items: center; align-content: center; gap: 12px; width: 100%; padding: 24px; text-align: center; cursor: pointer; color: var(--text); font: inherit;
  border: 2px dashed rgba(243, 165, 115, 0.75);
  background: radial-gradient(90% 80% at 50% 30%, rgba(243, 165, 115, 0.2), transparent 70%), #26223f;
  box-shadow: 0 0 40px -10px rgba(243, 165, 115, 0.35), inset 0 0 30px rgba(243, 165, 115, 0.08);
  transition: border-color 0.25s, background 0.25s;
}
.vn-blank:hover, .vn-blank:focus-visible { border-color: var(--accent); background: radial-gradient(90% 80% at 50% 30%, rgba(243, 165, 115, 0.3), transparent 70%), #2b2747; outline: none; }
.vn-plus { position: relative; display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--accent); color: var(--ink); font-size: 1.9rem; line-height: 1; }
.vn-plus::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; border: 1.5px solid rgba(243, 165, 115, 0.7); animation: vn-breathe 2.4s ease-out infinite; }
@keyframes vn-breathe { 0% { opacity: 0.9; transform: scale(0.85); } 100% { opacity: 0; transform: scale(1.35); } }
.vn-blank-title { font-family: var(--font-display); font-size: 1.35rem; line-height: 1.2; color: var(--paper); }
.vn-blank-sub { font-size: 0.84rem; color: var(--muted); max-width: 22ch; }

.vn-write { transform: rotateY(180deg); display: flex; flex-direction: column; gap: 8px; padding: 20px 22px 18px; background: var(--paper); color: var(--ink); box-shadow: 0 30px 60px -26px rgba(0, 0, 0, 0.9); }
.vn-write-top { display: flex; justify-content: space-between; align-items: center; }
.vn-write-title { font-family: var(--font-display); font-size: 1.15rem; color: #241f2c; }
.vn-x { width: 32px; height: 32px; border: 0; border-radius: 50%; background: rgba(36, 31, 44, 0.06); color: #463d4d; cursor: pointer; font-size: 1.1rem; line-height: 1; }
.vn-x:hover { background: rgba(36, 31, 44, 0.12); }
.vn-write textarea {
  flex: 1; min-height: 70px; padding: 0; border: 0; resize: none; background: transparent; outline: none;
  font-family: var(--font-display); font-style: italic; font-size: 1.08rem; line-height: 28px; color: #241f2c;
  background-image: repeating-linear-gradient(180deg, transparent 0 27px, rgba(80, 110, 170, 0.18) 27px 28px);
}
.vn-write textarea::placeholder { color: #a99f96; }
.vn-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
.vn-write input { width: 100%; min-width: 0; height: 34px; padding: 0; border: 0; border-bottom: 1.5px solid rgba(36, 31, 44, 0.3); background: transparent; outline: none; font: inherit; font-size: 0.9rem; color: #241f2c; }
.vn-write input::placeholder { color: #8a7f86; }
.vn-write input:focus { border-bottom-color: #c9734a; }
.vn-write .vn-trap { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.vn-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.vn-err { font-size: 0.75rem; color: #b5452f; min-height: 1em; }
.vn-slot.is-writing { --cw: 380px; --ch: 330px; }

/* controls */
.vn-controls { position: absolute; left: 0; right: 0; bottom: 18px; display: flex; justify-content: center; align-items: center; gap: 12px; pointer-events: none; transition: opacity 0.3s; }
.vn-controls > * { pointer-events: auto; }
.vn-table.is-writing .vn-controls { opacity: 0; }
.vn-table.is-writing .vn-controls > * { pointer-events: none; }
.vn-table.is-empty :is(.vn-arrow, .vn-count, .vn-hint) { display: none; }
.vn-arrow { width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgba(255, 246, 234, 0.18); background: rgba(21, 19, 29, 0.45); color: var(--text); cursor: pointer; font-size: 1rem; backdrop-filter: blur(6px); }
.vn-arrow:hover { background: rgba(255, 246, 234, 0.12); }
.vn-count { min-width: 64px; text-align: center; font-size: 0.8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.vn-add { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 16px; border: 1.5px dashed rgba(243, 165, 115, 0.8); border-radius: 999px; background: rgba(243, 165, 115, 0.1); color: var(--accent); font-weight: 600; font-size: 0.85rem; cursor: pointer; }
.vn-add:hover { background: rgba(243, 165, 115, 0.2); }
.vn-hint { position: absolute; left: 0; right: 0; top: 16px; text-align: center; font-size: 0.78rem; color: var(--muted); opacity: 0.8; pointer-events: none; transition: opacity 0.5s; }
.vn-hint.gone { opacity: 0; }
.vn-thanks { position: absolute; left: 50%; top: 16px; z-index: 200; max-width: calc(100% - 32px); transform: translateX(-50%); padding: 6px 14px; border-radius: 999px; background: rgba(127, 209, 193, 0.16); color: #7fd1c1; font-size: 0.82rem; font-weight: 600; text-align: center; opacity: 0; transition: opacity 0.4s; pointer-events: none; }
.vn-thanks.on { opacity: 1; }

@media (max-width: 760px) {
  .vn-table { height: 420px; }
  .vn-card { --cw: 250px; --ch: 230px; }
  .vn-note { padding: 22px 20px 18px; }
  .vn-text { font-size: 1.02rem; }
  .vn-slot.is-writing { --cw: min(340px, calc(100vw - 72px)); --ch: 340px; }
  .vn-row { grid-template-columns: 1fr; gap: 6px; }
  .vn-controls { gap: 8px; }
}
.vn .section-head { max-width: 820px; }   /* room for the title on one line */
.vn-arrow:disabled { opacity: 0.3; cursor: default; }   /* the ends of the row, while there are only a few notes */

/* journey cards: title and "place · years" sit together, the story a breath below, the step count at the foot */
.vc-inner .vc-title { margin: 0; }
.vc-inner .vc-place { margin-top: 6px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; }
.vc-inner .vc-dot { opacity: 0.6; }
.vc-inner .vc-when { color: var(--accent); font-weight: 600; font-variant-numeric: tabular-nums; }
.vc-inner .vc-place + .vc-body { margin-top: 16px; }
.vc-inner .vc-step { margin-top: 16px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.08em; color: var(--muted); opacity: 1; }

/* journey cards: one clear hierarchy, largest to quietest
   1 title · 2 place · years · 3 the story · 4 the pills · 5 the step count (bottom right) */
.vc-inner .vc-title { font-size: clamp(1.55rem, 2.3vw, 1.85rem); line-height: 1.1; color: var(--text); }
.vc-inner .vc-place { margin-top: 6px; font-size: 0.86rem; color: var(--muted); }
.vc-inner .vc-when { font-weight: 500; }
.vc-inner .vc-body { font-size: 1rem; line-height: 1.6; color: #f1e8de; }
.vc-inner .vc-place + .vc-body { margin-top: 14px; }
.vc-inner .vc-tags { margin-top: 16px; gap: 6px 8px; }
.vc-inner .vc-tags li { padding: 3px 10px; font-size: 0.72rem; font-weight: 400; color: var(--muted); background: transparent; border: 1px solid rgba(255, 246, 234, 0.16); }
.vc-inner .vc-step { margin-top: 10px; text-align: right; font-size: 0.68rem; font-weight: 500; letter-spacing: 0.1em; color: var(--muted); opacity: 0.7; }
@media (max-width: 760px) { .vc-inner .vc-body { font-size: 0.94rem; } }

/* the name in the corner, half under water (built by js/sitenav.js on every page) */


/* =========================================================
   Work covers.
   INTO: the work on desktop and mobile. AskINTO: a product shot with the headline result.
   Both tilt gently toward the cursor (js/main.js sets --tx/--ty on hover).
   ========================================================= */
.dv-cover, .ai-cover { position: relative; display: block; overflow: hidden; perspective: 1400px; }

/* ---------- INTO: desktop + phone ---------- */
.dv-cover { background: radial-gradient(90% 80% at 30% 0%, rgba(127, 209, 193, 0.22), transparent 65%), radial-gradient(60% 60% at 90% 100%, rgba(243, 165, 115, 0.14), transparent 70%), var(--surface); }
.dv-stage { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateX(var(--ty, 0deg)) rotateY(var(--tx, 0deg)); transition: transform 0.5s var(--ease-out); }
.dv-desk {
  position: absolute; left: 6%; top: 10%; width: 74%; border-radius: 10px; overflow: hidden; background: #fff;
  box-shadow: 0 30px 50px -24px rgba(0, 0, 0, 0.75), 0 0 0 1px rgba(255, 255, 255, 0.08);
  transition: transform 0.6s var(--ease-out);
}
.dv-screen { position: relative; display: block; aspect-ratio: 1666 / 860; overflow: hidden; background: #fff; }
.dv-screen img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; transition: transform 0.7s var(--ease-out), opacity 0.5s; }
.dv-s2 { transform: translateX(100%); }
.dv-phone {
  position: absolute; right: 6%; bottom: 7%; width: 21%; aspect-ratio: 9 / 18.5; padding: 5px; border-radius: 18px; background: #16141d;
  box-shadow: 0 26px 40px -18px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(255, 255, 255, 0.12); transform: translateZ(40px);
  transition: transform 0.6s var(--ease-out);
}
.dv-pscreen { position: relative; display: block; width: 100%; height: 100%; border-radius: 13px; overflow: hidden; background: #fff; }
.dv-pscreen img { display: block; width: 100%; height: auto; transform: translateY(0); transition: transform 6s cubic-bezier(.45, .05, .35, 1); }
.dv-tag { position: absolute; left: 6%; bottom: 7%; height: 26px; min-width: 150px; padding: 0 12px; border-radius: 999px; background: rgba(21, 19, 29, 0.72); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); color: var(--text); font: 500 0.72rem/26px var(--font-body); overflow: hidden; }
.dv-tag span { position: absolute; left: 12px; top: 0; white-space: nowrap; transition: transform 0.5s var(--ease-out), opacity 0.4s; }
.dv-t2 { transform: translateY(100%); opacity: 0; }

.project:hover .dv-s1 { transform: translateX(-30%); opacity: 0; }
.project:hover .dv-s2 { transform: none; }
.project:hover .dv-t1 { transform: translateY(-100%); opacity: 0; }
.project:hover .dv-t2 { transform: none; opacity: 1; }
.project:hover .dv-tag { min-width: 230px; }
.project:hover .dv-phone { transform: translateZ(40px) translateY(-6%); }
.project:hover .dv-pscreen img { transform: translateY(-62%); }

/* ---------- AskINTO: the assistant panel as it really appears (it opens beside the CRM; only the assistant is shown) ---------- */
.ai-cover { background: radial-gradient(70% 80% at 15% 0%, rgba(127, 209, 193, 0.45), transparent 65%), radial-gradient(60% 70% at 100% 100%, rgba(243, 165, 115, 0.35), transparent 70%), #ece6dc; font-family: var(--font-body); }
/* the assistant panel, as it opens beside the CRM: header with its tools, a thread of messages, the input */
.ai-panel {
  position: absolute; left: 7%; top: 6%; bottom: 6%; width: 47%; display: flex; flex-direction: column; overflow: hidden;
  border-radius: 10px; background: #fff; color: #1f2933;
  box-shadow: 0 24px 44px -22px rgba(30, 24, 40, 0.45), 0 0 0 1px rgba(30, 24, 40, 0.08);
}
.ai-ph { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px; border-bottom: 1px solid #ecebe8; }
.ai-ph b { font-size: 0.74rem; font-weight: 600; }
.ai-icons { display: flex; gap: 6px; color: #6b7480; }
.ai-icons svg { width: 11px; height: 11px; }
.ai-msgs { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.ai-m { display: grid; grid-template-columns: 18px 1fr; gap: 8px; padding: 9px 10px; font-size: 0.6rem; line-height: 1.45; }
.ai-bot { background: #f6f6f4; }
.ai-av { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 5px; color: #fff; }
.ai-av svg { width: 12px; height: 12px; }
.ai-user .ai-av { background: #5b7fd6; }
.ai-bot .ai-av { background: #0f6f63; }
.ai-t { min-width: 0; color: #2a323b; }
.ai-lead { display: block; }
.ai-rows { display: grid; gap: 1px; margin: 5px 0 6px; padding-left: 10px; }
.ai-row { position: relative; }
.ai-row::before { content: ""; position: absolute; left: -8px; top: 0.6em; width: 3px; height: 3px; border-radius: 50%; background: #0f6f63; }
.ai-row b { font-weight: 600; color: #1f2933; }
.ai-ask { display: block; color: #4a535c; }
.ai-next { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 4px; }
.ai-next span { padding: 1px 7px; border-radius: 999px; border: 1px solid #cfe2dd; background: #fff; color: #0f6f63; font-size: 0.54rem; font-weight: 600; }
.ai-acts { display: flex; justify-content: flex-end; gap: 7px; margin-top: 6px; color: #8a929a; }
.ai-acts svg { width: 10px; height: 10px; }
.ai-input { position: relative; margin: 6px 10px 8px; padding: 5px 26px 5px 9px; border-radius: 7px; border: 1px solid #e3e2de; color: #a0a6ac; font-size: 0.56rem; }
.ai-input i { position: absolute; right: 5px; top: 50%; width: 14px; height: 14px; margin-top: -7px; border-radius: 4px; background: #0f6f63; }

/* the result, beside the panel */
.ai-stat {
  position: absolute; right: 7%; top: 50%; width: 30%; transform: translateY(-50%); display: grid; gap: 4px; padding: 16px 16px 14px; border-radius: 14px;
  background: #fff; border: 1px solid rgba(30, 24, 40, 0.08); color: #241f2c; box-shadow: 0 24px 40px -18px rgba(30, 24, 40, 0.45);
}
.ai-stat strong { font-family: var(--font-display); font-weight: 500; font-size: clamp(2rem, 4vw, 2.9rem); line-height: 1; color: #0f6f63; }
.ai-stat > span:not(.ai-spark) { font-size: 0.74rem; line-height: 1.35; color: #6a6070; }
.ai-spark { display: flex; align-items: flex-end; gap: 3px; height: 26px; margin-top: 8px; }
.ai-spark i { flex: 1; border-radius: 2px 2px 0 0; background: linear-gradient(#0f6f63, rgba(15, 111, 99, 0.25)); }
.ai-spark i:nth-child(1) { height: 15%; } .ai-spark i:nth-child(2) { height: 22%; } .ai-spark i:nth-child(3) { height: 30%; } .ai-spark i:nth-child(4) { height: 46%; }
.ai-spark i:nth-child(5) { height: 60%; } .ai-spark i:nth-child(6) { height: 78%; } .ai-spark i:nth-child(7) { height: 100%; }

/* hover: the answer streams in, the bars grow */
.ai-cover.is-streaming .ai-lead, .ai-cover.is-streaming .ai-row, .ai-cover.is-streaming .ai-ask, .ai-cover.is-streaming .ai-next, .ai-cover.is-streaming .ai-acts { animation: ai-in 0.45s var(--ease-out) both; }
.ai-cover.is-streaming .ai-row:nth-child(1) { animation-delay: 0.15s; } .ai-cover.is-streaming .ai-row:nth-child(2) { animation-delay: 0.25s; }
.ai-cover.is-streaming .ai-row:nth-child(3) { animation-delay: 0.35s; } .ai-cover.is-streaming .ai-row:nth-child(4) { animation-delay: 0.45s; }
.ai-cover.is-streaming .ai-row:nth-child(5) { animation-delay: 0.55s; } .ai-cover.is-streaming .ai-ask { animation-delay: 0.65s; }
.ai-cover.is-streaming .ai-next { animation-delay: 0.75s; } .ai-cover.is-streaming .ai-acts { animation-delay: 0.9s; }
.ai-cover.is-streaming .ai-spark i { animation: ai-bar 0.8s var(--ease-out) both; transform-origin: bottom; animation-delay: calc(var(--k, 0) * 60ms); }

@media (max-width: 760px) {
  .ai-cover { aspect-ratio: 1 / 1; }
  .ai-panel { left: 5%; width: 60%; }
  .ai-stat { right: 5%; width: 30%; padding: 10px; }
  .ai-stat > span:not(.ai-spark) { font-size: 0.62rem; }
}

@keyframes ai-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
@keyframes ai-bar { from { transform: scaleY(0.1); } to { transform: none; } }

@media (max-width: 760px) {
  .dv-tag { display: none; }
}

/* INTO cover, round two: a light, airy backdrop so the screens stand out; the Contact Us page shown whole;
   the phone sits beside the desktop instead of covering it */
.dv-cover { background: radial-gradient(70% 80% at 15% 0%, rgba(127, 209, 193, 0.45), transparent 65%), radial-gradient(60% 70% at 100% 100%, rgba(243, 165, 115, 0.35), transparent 70%), #ece6dc; }
.dv-desk { left: 5%; top: 50%; width: 72%; transform: translateY(-58%); box-shadow: 0 24px 44px -22px rgba(30, 24, 40, 0.45), 0 0 0 1px rgba(30, 24, 40, 0.08); }
.dv-screen { aspect-ratio: 1666 / 772; }
.dv-s1 { object-fit: contain; object-position: center; background: #fff; }
.dv-phone { right: 5%; bottom: auto; top: 50%; width: 22%; transform: translateY(-50%) translateZ(40px); box-shadow: 0 24px 40px -18px rgba(30, 24, 40, 0.55), 0 0 0 1px rgba(30, 24, 40, 0.1); }
.project:hover .dv-phone { transform: translateY(-54%) translateZ(40px); }
.dv-tag { left: 5%; bottom: 6%; background: rgba(36, 31, 44, 0.78); }


/* Work cards: same pattern for every project, image left and the story right.
   On wide screens the image stretches to the full height of the text, so its top lines up with
   the first line and its bottom with the button. */
@media (min-width: 861px) {
  .project { align-items: stretch; }
  .project .project-media { aspect-ratio: auto; height: 100%; min-height: 380px; }
  .project-body { display: flex; flex-direction: column; }
  .project-body > .btn { margin-top: auto; align-self: flex-start; }
  .project-body .project-facts { margin-bottom: 24px; }
}
@media (min-width: 861px) {
  /* the taller INTO frame: bigger screens so they fill it */
  .dv-desk { left: 4%; width: 76%; }
  .dv-phone { right: 4%; width: 25%; }
}

/* AskINTO cover: a breath between the university list and "Would you like me to:"; a proper send button */
.ai-rows { margin-bottom: 12px; }
.ai-input i { display: grid; place-items: center; width: 18px; height: 18px; margin-top: -9px; border-radius: 50%; color: #fff; }
.ai-input i svg { width: 10px; height: 10px; }
/* the AskINTO panel is as tall as its conversation (never taller than the card), centred, so there's no empty strip */
.ai-panel { top: 50%; bottom: auto; max-height: 88%; transform: translateY(-50%); }
.beyond-cta { margin-top: clamp(24px, 3vw, 32px); }   /* breathing room between the strips and the button */

/* =========================================================
   Water on hover (built by js/sitenav.js): the name and the Work / Beyond work / About links.
   --lvl is the waterline: 100% = clear of the water. The name rests just above it with a thin line under it;
   on hover the water rises to halfway and the lower half goes under, tinted and wobbling.
   ========================================================= */
.nm { --lvl: 100%; --water: #9fc3f0; --line: 0; position: relative; display: inline-block; white-space: nowrap; line-height: 1.15; }
.nm .nm-top, .nm .nm-low { display: block; transition: clip-path 0.6s cubic-bezier(.34, 1.56, .64, 1); }
.nm .nm-top { clip-path: inset(0 0 calc(100% - var(--lvl)) 0); }
.nm .nm-low { position: absolute; left: 0; top: 0; color: var(--water); clip-path: inset(var(--lvl) 0 0 0); filter: url(#nm-wobble); opacity: 0.9; }
.nm::after {
  content: ""; position: absolute; left: -4px; right: -4px; top: var(--lvl); height: 1.5px; pointer-events: none; opacity: var(--line);
  background: linear-gradient(90deg, transparent, rgba(255, 246, 234, 0.7), transparent);
  transition: top 0.6s cubic-bezier(.34, 1.56, .64, 1), opacity 0.3s;
}
.nav-logo .nm { font-weight: 600; letter-spacing: -0.01em; --line: 1; }   /* the name: clear, with its line */
.nav-links a[aria-current] .nm { --line: 1; }                                         /* the section you're in keeps its line */
:is(.nav-logo, .nav-links a):is(:hover, :focus-visible) .nm { --lvl: 58%; --line: 1; }
.nav-links a:not(.nav-contact) { background-image: none; }                            /* the water replaces the old underline */

/* Zeny's little portrait beside his line: the same blue octopus as on the lake and in Focus Buddy */
.zeny-sign { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; }
.zeny-face { width: 3.2em; height: 3.2em; margin: -0.6em 0; transform: rotate(4deg); filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.35)); }

/* Zeny comes alive when you point at him: a hello wave, his little legs pattering left and right, a hop */
.zeny-face { display: inline-block; cursor: default; }
.zeny-face svg { display: block; width: 100%; height: 100%; overflow: visible; }
.zeny-face .zf-arm { transform-box: view-box; transform-origin: 88px 56px; }
.zeny-face .zf-leg { transform-box: view-box; transform-origin: var(--o); }
.zeny-face .zf-hat { transform-box: view-box; transform-origin: 48px 24px; }
.zeny-face .zf-body, .zeny-face .zf-legs { transform-box: view-box; transform-origin: 60px 100px; }
/* only while you point at him or tap him, so it plays even with reduced motion on */
:is(.zeny-sign, .bubble-title):hover .zf-arm, .zeny-face.is-waving .zf-arm { animation: zf-wave 0.5s ease-in-out infinite alternate; }
:is(.zeny-sign, .bubble-title):hover .zf-leg, .zeny-face.is-waving .zf-leg { animation: zf-patter 0.16s ease-in-out infinite alternate; }
:is(.zeny-sign, .bubble-title):hover .zf-leg:nth-child(even), .zeny-face.is-waving .zf-leg:nth-child(even) { animation-direction: alternate-reverse; }
:is(.zeny-sign, .bubble-title):hover .zf-body, .zeny-face.is-waving .zf-body { animation: zf-hop 0.5s ease-in-out infinite alternate; }
:is(.zeny-sign, .bubble-title):hover .zf-hat, .zeny-face.is-waving .zf-hat { animation: zf-tip 1s ease-in-out infinite; }
:is(.zeny-sign, .bubble-title):hover .zf-legs, .zeny-face.is-waving .zf-legs { animation: zf-shuffle 0.6s ease-in-out infinite alternate; }
@keyframes zf-wave { from { transform: rotate(-12deg); } to { transform: rotate(26deg); } }
@keyframes zf-patter { from { transform: rotate(-16deg); } to { transform: rotate(16deg); } }
@keyframes zf-hop { from { transform: translateY(0); } to { transform: translateY(-4px); } }
@keyframes zf-tip { 0%, 60%, 100% { transform: translateY(0) rotate(0); } 75% { transform: translateY(-6px) rotate(-10deg); } }
@keyframes zf-shuffle { from { transform: translateX(-3px); } to { transform: translateX(3px); } }


/* "opens in a new tab" icon (a box with an arrow leaving it) */
.ext-icon { display: inline-flex; }
.ext-icon svg { display: block; }
.btn:hover .ext-icon { transform: translate(2px, -2px); }
/* Zeny next to his name in the lake bubble: the same little character as in the contact section */
.bubble-title .zeny-face { width: 2em; height: 2em; margin: -0.5em 0 -0.5em 2px; vertical-align: middle; }
.btn .ext-icon svg, .bd-cta svg { width: 16px; height: 16px; }

/* footer: "Designed with ♥" — a small peach heart that sits on the text line */
.footer-heart { display: inline-block; vertical-align: -3px; margin: 0 1px; color: var(--accent); }
