/* nikitakissel.com v2 — shared styles for Home, Work, About, Vibing.
   Type follows nefaurk.com/about (Rubik: Light body, Black headings);
   neutral white/grey text on near-black, candle amber for actions only. */

:root {
  --bg: #0a0a0a;
  --surface: #131313;
  --card: #0e0e0e;
  --text: #ffffff;
  --text-secondary: #a0a4a7;
  --text-muted: #6b6f72;
  --hairline: #262626;
  --line: #333333;
  --accent: #a47c4c;        /* candle amber */
  --accent-soft: rgba(164, 124, 76, 0.55);
  --accent-hover: #c09562;
  --on-accent: #120d08;
  --font: "Rubik", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html { background: var(--bg); color-scheme: dark; overflow-x: clip; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 20px;
  font-weight: 300;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img { max-width: 100%; }
::selection { background: var(--accent); color: var(--on-accent); }
p { margin: 0; }

a { color: var(--accent); text-underline-offset: 3px; }
a:hover { color: var(--accent-hover); }
a:focus-visible, button:focus-visible, summary:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; border-radius: 6px; }

/* ---------- Top bar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--hairline);
}
.topbar-inner {
  max-width: 68rem;
  margin: 0 auto;
  padding: 1rem 1.75rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.logo {
  color: var(--text);
  text-decoration: none;
  font-weight: 700;
  font-size: 1.06rem;
  line-height: 1.05;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.logo span { display: block; }
.logo:hover { color: var(--accent); }
.nav { display: flex; gap: 1.9rem; }
.nav a { color: var(--text-secondary); text-decoration: none; font-size: 1.125rem; font-weight: 500; transition: color 0.7s ease; }
.nav a:hover { color: var(--text); }
/* where you are: the header word turns gold, gently (on Home it follows the scroll; on a page it fades in on arrival) */
.nav a.is-here { color: var(--accent); }
.nav a[aria-current="page"] { color: var(--accent); animation: nav-here 0.9s ease both; }
@keyframes nav-here { from { color: var(--text-secondary); } to { color: var(--accent); } }

/* ---------- Page frame ---------- */

.wrap { max-width: 68rem; margin: 0 auto; padding: 0 1.75rem; }
.narrow { max-width: 46rem; margin-left: auto; margin-right: auto; }

.page-title {
  margin: 5.5rem 0 2.4rem;
  text-align: center;
  font-weight: 700;
  font-size: clamp(2.6rem, 7vw, 3.5rem);
  line-height: 1.1;
}
.section-title {
  margin: 6.5rem 0 2rem;
  text-align: center;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 1.75rem);
  color: var(--text-secondary);
}

.prose { display: flex; flex-direction: column; gap: 1.2rem; color: var(--text-secondary); }

/* ---------- Home hero ---------- */

/* photo on the left, name + role + tagline + buttons on the right */
.home { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 3.5rem; padding: 6rem 0 7rem; }
.home .hero-photo { flex: 0 0 auto; width: 300px; height: 400px; margin: 0; }
.home-text { flex: 0 1 30rem; min-width: 0; }
.home-text .btn-row { justify-content: flex-start; margin-top: 2.4rem; }
.home-text .hero-name { font-size: clamp(2.8rem, 7vw, 4.25rem); }
@media (max-width: 760px) {
  .home { padding: 3.5rem 0 4rem; gap: 2.2rem; }
  .home .hero-photo { width: min(100%, 300px); height: 360px; }
  .home-text { text-align: center; }
  .home-text .btn-row { justify-content: center; }
}
.hero { text-align: center; padding: 5.5rem 0 3.5rem; }
.hero-name {
  margin: 0;
  font-weight: 700;
  font-size: clamp(2.8rem, 9vw, 4.5rem);
  line-height: 1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.hero-role { margin-top: 1.4rem; font-weight: 500; font-size: clamp(1.4rem, 3.5vw, 1.75rem); }
.hero-tag { margin-top: 0.3rem; font-size: clamp(1.15rem, 3vw, 1.5rem); color: var(--text-secondary); }
.hero-photo {
  display: block;
  width: min(100%, 380px);
  height: 480px;
  margin: 0 auto;
  object-fit: cover;
  object-position: 50% 28%;
  border-radius: 12px;
  border: 1px solid var(--hairline);
}

/* ---------- Buttons: one style everywhere ---------- */

.btn-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem; margin-top: 3rem; }
.btn-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem; margin-top: 2.8rem; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 13rem;
  min-height: 3.6rem;
  padding: 0 1.8rem;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: var(--accent);
  color: var(--on-accent);
  font: 500 1.125rem/1.2 var(--font);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--on-accent); }
/* secondary: dark with an amber outline (e.g. "I can help") */
.btn-quiet { background: var(--surface); border-color: var(--accent-soft); color: var(--text); }
.btn-quiet:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* contact links under the single "Get in touch" button */
.contact-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem 1.6rem; margin: 1.3rem 0 0; padding: 0; list-style: none; font-size: 1.06rem; }
.contact-links a { color: var(--text-secondary); text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 4px; }
.contact-links a:hover { color: var(--accent); text-decoration-color: var(--accent); }
.btn-grid .btn { min-width: 0; width: 100%; }

/* ---------- Project cards ---------- */

.pcard {
  position: relative;
  margin-top: 9rem;
  border: 1px solid var(--accent-soft);
  border-radius: 16px;
  background: var(--card);
}
.pcard-top { display: flex; flex-wrap: wrap; min-height: 26rem; }
.pcard-text {
  flex: 1 1 22rem;
  min-width: 0;
  padding: 2.75rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 1.4rem;
}
.pcard-label { font-size: 1rem; font-weight: 500; color: var(--text-secondary); }
.pcard-label span { color: #4a4a4a; margin: 0 0.3em; }
.pcard-title { margin: 0; font-weight: 400; font-size: clamp(1.7rem, 3.4vw, 2.35rem); line-height: 1.2; }
.pcard-visual { flex: 1 1 22rem; position: relative; min-height: 26rem; }
.phone {
  position: absolute;
  left: 50%;
  top: -6rem;
  transform: translateX(-50%);
  width: 236px;
  padding: 8px;
  border-radius: 38px;
  background: #000;
  box-shadow: 0 0 0 1.5px #2a2a2a, 0 26px 50px rgba(0, 0, 0, 0.6);
}
.phone img { display: block; width: 220px; height: 476px; object-fit: cover; object-position: top; border-radius: 30px; }
.callout {
  position: absolute;
  max-width: 15rem;
  padding: 0.75rem 1rem;
  border-radius: 12px;
  background: #151515;
  border: 1px solid var(--accent-soft);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.55);
  font-size: 0.875rem;
  line-height: 1.35;
  color: var(--text-secondary);
}
.callout b { display: block; margin-bottom: 0.15rem; font-weight: 500; font-size: 0.95rem; color: var(--text); }
.callout.c1 { left: 2%; top: 3rem; }
.callout.c2 { right: 2%; top: 16rem; }

.chat { display: flex; flex-direction: column; justify-content: center; gap: 0.9rem; padding: 2.75rem; }
.bubble { align-self: flex-start; max-width: 85%; padding: 0.75rem 1rem; border-radius: 16px 16px 16px 4px; background: #1a1a1a; border: 1px solid #2c2c2c; font-size: 1rem; color: var(--text); }
.pcard-visual.chat .callout { position: static; align-self: flex-end; }

.pcard-more { border-top: 1px solid var(--hairline); padding: 2.75rem; }
.pcard-more[hidden] { display: none; }
.pcard-cols { display: flex; flex-wrap: wrap; gap: 3rem; margin-top: 2.6rem; }
.pcard-cols > div { flex: 1 1 20rem; min-width: 0; display: flex; flex-direction: column; gap: 1.6rem; }
.field h4 { margin: 0 0 0.4rem; font-size: 0.875rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.field p { color: var(--text-secondary); }
.field.strong p { color: var(--text); }
.pcard-more .btn-row { margin-top: 2.4rem; }

.shot-open { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; -webkit-tap-highlight-color: transparent; }
.shot { display: block; width: 100%; height: auto; border-radius: 10px; border: 1px solid var(--hairline); }
.shot-hint { margin-top: 0.8rem; text-align: center; font-size: 0.9rem; color: var(--text-muted); }

@media (max-width: 760px) {
  .pcard { margin-top: 7rem; }
  .pcard-visual { order: -1; min-height: 0; padding: 0 1.25rem 0.5rem; display: flex; flex-direction: column; align-items: center; gap: 0.75rem; }
  .phone { position: relative; left: auto; top: -4.5rem; transform: none; margin-bottom: -3.5rem; }
  .callout { position: static; max-width: none; width: 100%; }
  .pcard-text, .pcard-more { padding: 1.75rem 1.25rem; }
  .chat { padding: 1.75rem 1.25rem 0; }
}

/* ---------- Experience ---------- */

.jobs { display: flex; flex-direction: column; gap: 3rem; }
.job-head { text-align: center; margin-bottom: 0.9rem; }
.job-name { margin: 0; font-weight: 700; font-size: clamp(1.6rem, 4.5vw, 1.9rem); line-height: 1.15; }
.job-meta { margin-top: 0.4rem; font-size: 0.875rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }
.job p { color: var(--text-secondary); }

/* ---------- About ---------- */

.about-intro { display: flex; flex-wrap: wrap; gap: 2.75rem; align-items: stretch; }
/* the frame stretches to the text's height; the photo fills it */
.about-photo {
  flex: 1 1 18rem;
  min-width: 0;
  min-height: 26rem;
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid var(--hairline);
}
.about-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 60% 40%; }
.about-intro .prose { flex: 1.4 1 22rem; min-width: 0; }

.values { border-top: 1px solid var(--hairline); }
.values details { border-bottom: 1px solid var(--hairline); padding: 1.35rem 0; }
.values summary {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 2.75rem;
  cursor: pointer;
  list-style: none;
  font-weight: 500;
  font-size: 1.5rem;
}
.values summary::-webkit-details-marker { display: none; }
.values summary::marker { content: ""; }
.vchev {
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid var(--accent);
  border-bottom: 1.5px solid var(--accent);
  transform: rotate(-45deg);
  transition: transform 180ms ease;
}
.values details[open] .vchev { transform: rotate(45deg); }
.values .prose { padding: 0.9rem 0 0.25rem 1.6rem; gap: 0.9rem; }

.plain-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.45rem; text-align: center; color: var(--text-secondary); }

/* ---------- Frames (Vibing) ---------- */

.frame {
  margin-top: 3rem;
  padding: 2.5rem 2.25rem;
  border: 1px solid var(--accent-soft);
  border-radius: 16px;
  background: var(--card);
}
.frame h2 { margin: 0 0 1.1rem; font-weight: 700; font-size: 1.6rem; }
/* the focus zone: brighter fill so it reads first */
.frame-focus { background: #1d1d1d; border-color: var(--accent); }
.frame-focus .prose { color: #c8cbcd; }
.frame .btn-row { justify-content: flex-start; margin-top: 2rem; }
.dots { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.75rem; color: var(--text-secondary); }
.dots li { display: flex; gap: 0.9rem; }
.dots li::before { content: ""; flex: none; margin-top: 0.65em; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }

/* ---------- Closing call to action + footer ---------- */

.cta { text-align: center; padding: 6.5rem 0 6.5rem; }
.cta h2 { margin: 0; font-weight: 300; font-size: clamp(1.6rem, 4.5vw, 2rem); color: var(--text-secondary); }
.cta .btn-row { margin-top: 1.8rem; }

/* the footer is as tall as the Vibing? button plus the same gap above and below it, so the button
   sits centered between the footer's line and the bottom of the page */
.footer {
  box-sizing: border-box; min-height: 6rem; padding: 1.45rem 1.75rem; border-top: 1px solid var(--hairline);
  text-align: center; font-size: 0.95rem; line-height: 1.6; color: var(--text-muted);
}

/* 2. grey buttons: same fill as the Vibing? focus frame (Work downloads grid) */
.btn-grey { background: #1d1d1d; border-color: var(--accent); color: var(--text); }
.btn-grey:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* 5. contact actions: icon + uppercase label, no box (nefaurk style) */
.contact-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 1.4rem 3.2rem; margin-top: 2.2rem; }
.contact-actions a {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 2.75rem;
  color: var(--text);
  font-weight: 700;
  font-size: 1.35rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-decoration: none;
}
.contact-actions a:hover { color: var(--accent); }
.contact-actions svg { width: 1.6rem; height: 1.6rem; flex: none; }

/* 8. footer links (Home) */
.footer a { color: var(--accent); text-decoration: underline; text-decoration-color: var(--accent-soft); text-underline-offset: 3px; }
.footer a:hover { color: var(--accent-hover); }

/* Background list on About: left-aligned under the toggles */
.plain-list.left { text-align: left; }

/* Hire me pop-up (native <dialog>: Esc and focus handled by the browser) */
.modal {
  width: min(92vw, 40rem);
  padding: 0;
  border: 1px solid var(--accent);
  border-radius: 16px;
  background: #1d1d1d;
  color: var(--text);
  font: inherit;
}
.modal::backdrop { background: rgba(0, 0, 0, 0.72); }
.modal-body { position: relative; padding: 2.75rem 2.5rem 2.5rem; }
.modal h2 { margin: 0 2rem 1.1rem 0; font-weight: 700; font-size: 1.6rem; }
.modal .prose { color: #c8cbcd; }
.modal .btn-row { justify-content: flex-start; margin-top: 2rem; }
.modal-close { position: absolute; top: 14px; right: 14px; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; }
.modal-close::before, .modal-close::after { content: ""; position: absolute; left: 12px; top: 21px; width: 20px; height: 1.5px; background: var(--text-secondary); }
.modal-close::before { transform: rotate(45deg); }
.modal-close::after { transform: rotate(-45deg); }
.modal-close:hover::before, .modal-close:hover::after { background: var(--text); }

/* Vibing? page has no page title: space the first frame from the header */
.vibing-top { padding-top: 4.5rem; }
.frame h1 { margin: 0 0 1.1rem; font-weight: 700; font-size: 1.6rem; }

/* "Gmail · Outlook" compose links under the Hire me button */
.webmail { margin: 1.6rem 0 0; font-size: 0.85rem; color: var(--text-muted); }
.webmail a { color: var(--text-secondary); text-decoration: underline; text-underline-offset: 4px; }
.webmail a:hover { color: var(--accent); }

/* ---------- Vibing? pill (every page) ---------- */

.vibing-pill {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 20;
  display: inline-flex;
  align-items: center;
  min-height: 3rem;
  padding: 0 1.4rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 500;
  font-size: 1.06rem;
  text-decoration: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.vibing-pill:hover { background: var(--accent-hover); color: var(--on-accent); }
.vibing-pill[aria-current="page"] { background: var(--surface); color: var(--accent); border: 1px solid var(--accent); }

@media (max-width: 560px) {
  .btn-grid { grid-template-columns: 1fr; }
  .btn { width: 100%; }
  .page-title { margin-top: 3.8rem; }
  .vibing-pill { right: 1rem; bottom: 1rem; }
  /* phones: three short lines on the left, clear of the button, and still as tall as the button plus its gaps */
  .footer { min-height: 5rem; text-align: left; padding: 0.55rem 8rem 0.55rem 1.25rem; font-size: 0.82rem; line-height: 1.45; }
  .f-sep { display: block; font-size: 0; }
}

/* ---------- Screenshot gallery (lightbox) ---------- */

.lb { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; background: rgba(5, 5, 5, 0.96); touch-action: pan-y; }
.lb[hidden] { display: none; }
.lb-fig { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 0.9rem; max-width: 100%; }
.lb-img { display: block; max-width: min(92vw, 1200px); max-height: 82vh; width: auto; height: auto; object-fit: contain; border-radius: 8px; user-select: none; -webkit-user-drag: none; }
.lb-cap { font-size: 0.9rem; color: var(--text-secondary); text-align: center; padding: 0 1rem; }
.lb-cap b { color: var(--accent); font-weight: 500; margin-right: 0.5em; }
.lb button { position: absolute; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%; background: rgba(20, 20, 20, 0.6); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.lb-close { top: 14px; right: 14px; }
.lb-close::before, .lb-close::after { content: ""; position: absolute; left: 14px; top: 23px; width: 20px; height: 1.5px; background: var(--text-secondary); }
.lb-close::before { transform: rotate(45deg); }
.lb-close::after { transform: rotate(-45deg); }
.lb-prev { left: 14px; top: 50%; margin-top: -24px; }
.lb-next { right: 14px; top: 50%; margin-top: -24px; }
.lb-prev::before, .lb-next::before { content: ""; position: absolute; top: 18px; width: 11px; height: 11px; border-right: 1.5px solid var(--accent); border-bottom: 1.5px solid var(--accent); }
.lb-prev::before { left: 20px; transform: rotate(135deg); }
.lb-next::before { left: 15px; transform: rotate(-45deg); }
@media (max-width: 640px) {
  .lb-prev, .lb-next { top: auto; bottom: 18px; margin-top: 0; }
  .lb-img { max-height: 74vh; }
}

@media (prefers-reduced-motion: reduce) {
  .vchev, .btn { transition: none; }
}

/* ---------- v3: anchors under the sticky bar ---------- */
[id] { scroll-margin-top: 6rem; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* ---------- v3: opinion ball ---------- */
/* .ball-mover carries the roll-in and the drag (ball + shadow together); .ball lifts while
   held and shakes; .ball-body spins while rolling (window and triangle turn with it);
   .ball-gloss is the light on it and never spins; .ball-shadow stays on the ground. */
.ball-mover {
  position: relative; width: var(--ball, 8rem); height: var(--ball, 8rem);
  transform: translateX(calc(var(--roll, 0px) + var(--dx, 0px) + var(--tx, 0px)));
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.ball {
  position: relative; z-index: 1; display: block; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 50%;
  background: none; cursor: grab; touch-action: none; -webkit-tap-highlight-color: transparent;
  translate: 0 calc(var(--dy, 0px) + var(--ty, 0px));
  transition: translate 0.4s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.ball:focus { outline: none; }
.ball:focus-visible { outline: 1px solid var(--accent-soft); outline-offset: 8px; }
.ball-body {
  position: absolute; inset: 0; border-radius: 50%; overflow: hidden; rotate: var(--spin, 0deg);
  background: radial-gradient(circle at 40% 34%, #343434 0, #171717 28%, #080808 60%, #000 100%);
}
/* light: a crisp highlight, a broad soft reflection, a thin rim, warm bounce from the shadow */
.ball-gloss {
  position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background:
    radial-gradient(circle at 31% 23%, rgba(255, 255, 255, 0.95) 0 1.4%, rgba(255, 255, 255, 0.5) 2.6%, transparent 7%),
    radial-gradient(ellipse 44% 30% at 37% 25%, rgba(255, 255, 255, 0.2), transparent 72%),
    radial-gradient(ellipse 70% 24% at 50% 99%, rgba(214, 168, 106, 0.26), transparent 70%),
    radial-gradient(circle at 50% 50%, transparent 66%, rgba(255, 255, 255, 0.05) 70%, transparent 72%);
  box-shadow: inset -14px -18px 32px rgba(0, 0, 0, 0.8), inset 4px 5px 12px rgba(255, 255, 255, 0.05);
}
/* a fine golden shadow on the ground. The floor is flat, so the shadow always lies flat on it
   (never rotates): it gets wider, softer and fainter as the ball is lifted, and when the ball is
   pulled sideways it trails a little behind and stretches along the floor */
.ball-shadow {
  position: absolute; left: 50%; bottom: -9%; z-index: 0; width: 78%; height: 15%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(214, 168, 106, 0.55), rgba(164, 124, 76, 0.22) 55%, transparent 100%);
  filter: blur(3px);
  transform: translateX(calc(-50% + var(--lift, 0) * 8px - var(--tilt, 0) * 6px))
             scale(calc(1 + var(--lift, 0) * 0.4 + var(--stretch, 0) * 0.18), calc(1 + var(--lift, 0) * 0.15));
  opacity: calc(0.95 - var(--lift, 0) * 0.5);
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.3, 1), opacity 0.4s ease;
}
/* held: the ball stays exactly under the finger; let go, it settles back slowly */
.ball-mover.is-dragging, .ball-mover.is-dragging .ball, .ball-mover.is-dragging .ball-shadow { transition: none; }
.ball-mover:not(.is-rolling), .ball-mover .ball, .ball-mover .ball-shadow { transition-duration: 0.7s; }
.ball-mover.is-held .ball { cursor: grabbing; }
/* rolling in: slow and unhurried, easing to a stop */
.ball-mover.is-rolling { transition: transform 3.2s cubic-bezier(0.3, 0.2, 0.45, 1); }
.ball-mover.is-rolling .ball-body { transition: rotate 3.2s cubic-bezier(0.3, 0.2, 0.45, 1); }
.ball-mover.pre-roll, .ball-mover.pre-roll .ball-body { transition: none; }

/* the window: recessed glass on the side, dark liquid, the triangle floating in it */
.ball-window {
  position: absolute; right: 13%; top: 27%; width: 46%; height: 46%; border-radius: 50%;
  display: grid; place-items: center; transform: rotate(-10deg) scaleX(0.86);
  background: radial-gradient(circle at 50% 58%, #0e1c52 0, #071030 52%, #02040d 100%);
  box-shadow: inset 0 4px 9px rgba(0, 0, 0, 0.95), inset 0 -2px 3px rgba(120, 150, 255, 0.12),
              0 0 0 2.5px #040404, 0 0 0 3.5px rgba(255, 255, 255, 0.07);
}
.ball-tri {
  width: 70%; height: 61%; display: grid; place-items: start center; padding-top: 12%;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  background: linear-gradient(172deg, #5674ec 0%, #2a43b4 55%, #17286f 100%);
  opacity: 0.3; transition: opacity 0.5s ease;
}
.ball-tiny { width: 66%; font-size: 3.2px; line-height: 1.15; text-align: center; color: #e6ecff; opacity: 0; transition: opacity 0.35s ease; }
.ball.is-revealed .ball-tri { opacity: 0.95; }
.ball.is-revealed .ball-tiny { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .ball.is-active:not(.is-shaking) { animation: ball-wiggle 0.6s ease; }
  .ball.is-shaking { animation: ball-shake 0.85s ease; }
}
@keyframes ball-wiggle { 0%, 100% { transform: none; } 30% { transform: rotate(-8deg); } 65% { transform: rotate(5deg); } }
@keyframes ball-shake {
  0%, 100% { transform: none; }
  10% { transform: translate(-20px, 6px) rotate(-20deg); }
  24% { transform: translate(18px, -9px) rotate(17deg); }
  38% { transform: translate(-16px, -4px) rotate(-14deg); }
  52% { transform: translate(13px, 8px) rotate(11deg); }
  66% { transform: translate(-9px, -4px) rotate(-7deg); }
  80% { transform: translate(5px, 2px) rotate(4deg); }
  92% { transform: translate(-2px, 0) rotate(-1.5deg); }
}

/* ---------- v3: Work intro ---------- */
.work-intro { margin-top: 0.5rem; }

/* ---------- v3: Experience, role first, with a timeline on the right ---------- */
.xp { max-width: 58rem; margin: 0 auto; }
.xp-row { display: grid; grid-template-columns: minmax(0, 1fr) 14rem; column-gap: 2.75rem; }
.xp-row .job { padding-bottom: 3rem; }
.job-role { margin: 0; font-weight: 700; font-size: clamp(1.35rem, 3.6vw, 1.65rem); line-height: 1.2; }
.xp .job-meta { margin-top: 0.45rem; }
.xp .job p { margin-top: 0.9rem; }
.tl-seg { position: relative; display: grid; grid-template-columns: 3rem 12px minmax(0, 1fr); grid-template-rows: auto 1fr; column-gap: 0.9rem; }
.tl-bar {
  grid-column: 2; grid-row: 1 / span 2; width: 12px; margin-bottom: 4px; border-radius: 3px;
  /* each stage up: stripes closer together and thicker, until the top stage is solid */
  --gap: calc(15px - var(--n) * 2.4px);                          /* 15, 12.6, 10.2, 7.8px from stripe to stripe */
  --sw: calc((0.12 + var(--n) * 0.235) * (15px - var(--n) * 2.4px)); /* gold covers 12, 35, 59, 82%: wider steps */
  background: repeating-linear-gradient(-45deg, var(--accent) 0 var(--sw), transparent var(--sw) var(--gap));
  box-shadow: inset 0 0 0 1px var(--accent-soft);
  -webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), #000); mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), #000);
}
.tl-bar.tl-full { background: var(--accent); -webkit-mask-image: none; mask-image: none; }
.tl-label { grid-column: 3; grid-row: 1 / span 2; align-self: center; font-size: 0.95rem; font-weight: 500; line-height: 1.3; color: var(--text); }
.tl-year { grid-column: 1; grid-row: 2; align-self: end; text-align: right; font-size: 0.85rem; color: var(--text-muted); transform: translateY(45%); }
/* phones: just the bar and the years; the roles are in the headings */
@media (max-width: 640px) {
  .xp-row { grid-template-columns: minmax(0, 1fr) 2.6rem; column-gap: 1rem; }
  .tl-seg { grid-template-columns: 9px minmax(0, 1fr); column-gap: 0.4rem; }
  .tl-bar { grid-column: 1; width: 9px; }
  .tl-label { display: none; }
  .tl-year { grid-column: 2; text-align: left; font-size: 0.72rem; }
}

/* v3: role line fits one line on desktop; on phones it breaks like the resume */
.home-text .hero-role { font-size: clamp(1.15rem, 2.2vw, 1.4rem); }
.role-br { display: none; }
@media (max-width: 760px) {
  .role-br { display: inline; }
  .role-sep { display: none; }
}

/* ================= v3 round 2: Home hero + Work intro ================= */

/* Hero (round 7): photo on the left, the text beside it, centered in the first screen;
   the ball rests on the bottom of the screen under the photo, its phrase under the text,
   centered on the ball. All text lines share one width; sizes come from v2.js:
   --ph/--pw photo, --bd ball diameter, --tw text width, --vh visible screen under the
   header, --pb room under the ball (its shadow, and a phrase taller than the ball).
   Two options: A = portrait photo, B = round photo exactly as wide as the ball. */
.hero3 {
  display: grid; grid-template-columns: var(--pw, 11rem) max-content; grid-template-rows: 1fr auto;
  grid-template-areas: "photo text" "ball says";
  justify-content: center; column-gap: 3.5rem; row-gap: 5rem;
  min-height: var(--vh, calc(100svh - 4.6rem)); padding: 3rem 0 var(--pb, 1.5rem); box-sizing: border-box;
}
.hero3-text { grid-area: text; align-self: center; display: flex; flex-direction: column; }
.hero3-photo { grid-area: photo; align-self: center; height: var(--ph, 14rem); position: relative; cursor: grab; touch-action: none; -webkit-tap-highlight-color: transparent; }
.hero3-photo:focus { outline: none; }
.hero3-photo:focus-visible .photo-clip { outline: 1px solid var(--accent-soft); outline-offset: 6px; }
/* round, as wide as the ball; it shakes and follows a drag like the ball */
.photo-clip {
  position: absolute; inset: 0; overflow: hidden; border-radius: 50%; border: 1px solid var(--hairline);
  translate: var(--pdx, 0px) calc(var(--pdy, 0px) - var(--plift, 0) * 12px); transition: translate 0.4s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.hero3-photo.is-dragging .photo-clip { transition: none; }
.photo-clip img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; pointer-events: none; -webkit-user-drag: none; user-select: none; }
.hero3-photo { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.hero3-photo.is-held { cursor: grabbing; }
@media (prefers-reduced-motion: no-preference) {
  .photo-clip.is-active:not(.is-shaking) { animation: ball-wiggle 0.6s ease; }
  .photo-clip.is-shaking { animation: ball-shake 0.85s ease; }
}
/* the thought: shown where the ball speaks (centered on the ball, under the text); a dark bubble
   with a fine gold edge and two little circles trailing up-left, toward the photo */
.thought {
  position: absolute; left: 0; top: calc(50% - var(--bd, 8rem) * 0.34); z-index: 5; width: max-content; max-width: var(--tw, 20rem); margin: 0;
  padding: 1rem 1.4rem; border-radius: 30px; background: #151515; border: 1px solid var(--accent-soft);
  color: var(--text-secondary); font-size: 1.15rem; line-height: 1.4; box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
  opacity: 0; transform: translateY(calc(-50% + 0.5rem)) scale(0.94); transform-origin: 0 0; pointer-events: none;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
/* the little circles, from the bubble up to the photo, shrinking as they go (placed by v2.js) */
.t-dot { position: absolute; box-sizing: border-box; border-radius: 50%; background: #151515; border: 1px solid var(--accent-soft); }
.thought.show { opacity: 1; transform: translateY(-50%); }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }   /* fully hidden: no stray pixel of text */

.hero3-roles { margin: 0; font-weight: 500; font-size: 1rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); line-height: 1.6; }
.hero3 .hero-tag { margin: 1.1rem 0 0; font-size: clamp(1.6rem, 2.8vw, 2.2rem); line-height: 1.22; color: var(--text-secondary); }
.role-line, .tag-line, .say-line { display: block; width: max-content; white-space: nowrap; }

/* bottom row, as tall as the ball: the ball under the photo; the phrase under the text,
   centered on the ball's center */
.hero3-ball { grid-area: ball; position: relative; display: flex; justify-content: center; align-items: center; height: var(--bd, 8rem); --ball: var(--bd, 8rem); }
/* "Opinion Ball": just quiet text at the ball's 10 o'clock, on hover / keyboard focus, or briefly
   on first touch; it comes in gently and leaves quickly */
.ball-note {
  position: absolute; z-index: 3; right: calc(50% + var(--bd, 8rem) * 0.433 + 4px); bottom: calc(50% + var(--bd, 8rem) * 0.25);
  padding: 0 2.8rem 0.8rem 0; color: var(--text-muted); font-size: 0.95rem; font-weight: 300; font-style: italic; white-space: nowrap;   /* the words sit at the far end of the line */
  opacity: 0; transform: translate(0.4rem, 0.25rem); pointer-events: none; transition: opacity 0.18s ease, transform 0.18s ease;
}
/* a fine leader from the words toward the ball's edge */
/* the line ends just off the ball's edge at 10 o'clock and points at its center */
.ball-note::after {
  content: ""; position: absolute; right: 0; bottom: 0; width: 2.4rem; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent-soft)); transform: rotate(30deg); transform-origin: right center;
}
.hero3-ball.note-on .ball-note { opacity: 1; transform: none; transition: opacity 0.8s ease 0.3s, transform 0.8s ease 0.3s; }
.hero3-ball.is-busy .ball-note { opacity: 0; transition: opacity 0.15s ease; }
.hero3-says { grid-area: says; position: relative; height: var(--bd, 8rem); }
.hero3 .ball-says {
  position: absolute; left: 0; top: 50%; width: var(--tw, 30rem); max-width: none; margin: 0;
  font-size: clamp(1.2rem, 1.9vw, 1.55rem); line-height: 1.4; color: var(--text-secondary);
  white-space: normal; pointer-events: none;
  opacity: 0; transform: translateY(calc(-50% + 0.4rem)); transition: opacity 0.4s ease, transform 0.4s ease;
}
.hero3 .ball-says.show { opacity: 1; transform: translateY(-50%); }

@media (max-width: 760px) {
  .hero3 { grid-template-columns: var(--pw, 5.5rem) minmax(0, 1fr); grid-template-rows: auto auto; align-content: center; column-gap: 1.1rem; row-gap: 3rem; justify-content: stretch; padding-top: 0; padding-bottom: 5rem; }   /* sits a touch above the middle, like the eye expects */
  .hero3-roles { font-size: 0.8rem; letter-spacing: 0.1em; }
  .hero3 .hero-tag { font-size: clamp(1rem, 4.4vw, 1.25rem); margin-top: 0.7rem; }
  .thought { font-size: 0.95rem; padding: 0.75rem 1rem; }
  /* the ball is at the left edge on phones: the note sits at its 2 o'clock instead */
  .ball-note { display: none; }   /* no hover on phones: no label */
  .hero3 .ball-says { font-size: clamp(0.88rem, 3.6vw, 1rem); }
}

/* Intro: the photo and the big name appear together; the name holds, fades away
   completely, and only then the text fades in in its place; then the ball rolls in. */
.intro-name {
  position: absolute; z-index: 30; margin: 0; pointer-events: none;
  font-weight: 700; line-height: 1.05; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text);
  opacity: 0; transition: opacity 0.8s ease;
}
.intro-name span { display: block; }
.intro-name.is-in { opacity: 1; }
.intro-name.is-in.is-out { opacity: 0; transition: opacity 1.1s ease; }
.hero3 > .hero3-text, .hero3 > .hero3-photo { transition: opacity 1.2s ease, transform 1.2s ease; }
html.intro-on .hero3 > .hero3-text { opacity: 0; transform: translateY(0.6rem); }
html.intro-on:not(.intro-show) .hero3 > .hero3-photo { opacity: 0; }
/* before its roll the ball waits off-screen (JS places it); without JS it just sits there */
html.ball-wait .hero3-ball { visibility: hidden; }

/* Vibing? on Home: hidden until the ball has scrolled out of view */
.is-home .vibing-pill { transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0s; }
.is-home.pill-hidden .vibing-pill { opacity: 0; transform: translateY(0.8rem); visibility: hidden; transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0.3s; }

/* Work intro: left-aligned under the hero, three versions to compare */
.work3 { margin: 0 auto; max-width: 64rem; text-align: center; }
.tnn { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3rem; text-align: left; }
.tnn-label { margin: 0 0 0.9rem; font-weight: 500; font-size: 0.9rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }
.tnn-text { margin: 0; font-size: clamp(1.1rem, 1.6vw, 1.3rem); line-height: 1.5; color: var(--text-secondary); }
.tnn-item:nth-child(2) .tnn-text { color: var(--text); }
.work3-actions { justify-content: center; margin-top: 5rem; }
@media (max-width: 760px) {
  .tnn { grid-template-columns: minmax(0, 1fr); gap: 1.3rem; }
  .tnn-label { margin-bottom: 0.35rem; font-size: 0.75rem; }
  .tnn-text { font-size: 0.98rem; line-height: 1.45; }
  .work3-actions { margin-top: 2.2rem; }
  .work3.snap-page { padding: 1.5rem 0; }
}
.work3-title { margin: 0 0 2.2rem; font-size: 0.9rem; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }
.wv { display: none; }
.work3[data-work="1"] .wv1, .work3[data-work="2"] .wv2, .work3[data-work="3"] .wv3 { display: block; }

/* 1 · At a glance: four facts */
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; background: var(--hairline); border: 1px solid var(--hairline); border-radius: 12px; overflow: hidden; }
.facts > div { display: flex; flex-direction: column; gap: 0.4rem; padding: 1.5rem 1.6rem; background: var(--bg); }
.facts b { font-weight: 700; font-size: 1.35rem; color: var(--text); }
.facts span { color: var(--text-secondary); line-height: 1.5; }
.work3-now { margin: 2rem 0 0; font-size: 1.15rem; line-height: 1.55; color: var(--text); }

/* 2 · Then → Now */
.then-now { display: grid; grid-template-columns: minmax(0, 1fr) 2.5rem minmax(0, 1fr); gap: 1.5rem; align-items: start; }
.tn-label { margin: 0 0 1rem; font-size: 0.85rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.then-now > div:last-child .tn-label { color: var(--accent); }
.then-now ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.9rem; }
.then-now li { color: var(--text-secondary); line-height: 1.5; padding-left: 1rem; border-left: 2px solid var(--line); }
.then-now > div:last-child li { color: var(--text); border-left-color: var(--accent); }
.tn-arrow { align-self: center; height: 2px; background: linear-gradient(90deg, var(--line), var(--accent)); position: relative; }
.tn-arrow::after { content: ""; position: absolute; right: -1px; top: -4px; border: 5px solid transparent; border-left: 7px solid var(--accent); border-right: 0; }

/* 3 · One statement, then proof */
.statement { margin: 0; font-size: clamp(1.6rem, 3.6vw, 2.3rem); line-height: 1.25; font-weight: 400; color: var(--text); max-width: 44rem; }
.proof { margin: 2.4rem 0 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; border-top: 1px solid var(--hairline); padding-top: 1.6rem; }
.proof dt { font-size: 0.85rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
.proof dd { margin: 0.5rem 0 0; color: var(--text-secondary); line-height: 1.5; }

.work3-looking { margin: 2.4rem 0 0; color: var(--text-secondary); line-height: 1.55; max-width: 44rem; }
.work3-buttons { margin-top: 2.2rem; max-width: 40rem; }

@media (max-width: 760px) {
  .facts { grid-template-columns: minmax(0, 1fr); }
  .then-now { grid-template-columns: minmax(0, 1fr); }
  .tn-arrow { width: 2px; height: 2rem; justify-self: start; margin-left: 1rem; background: linear-gradient(180deg, var(--line), var(--accent)); }
  .tn-arrow::after { right: auto; left: -4px; top: auto; bottom: -1px; border: 5px solid transparent; border-top: 7px solid var(--accent); border-bottom: 0; }
  .proof { grid-template-columns: minmax(0, 1fr); gap: 1.3rem; }
}

/* draft-only switcher */
.opt-switch {
  position: fixed; left: 1rem; bottom: 1.25rem; z-index: 40; display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem;
  max-width: calc(100vw - 9rem); padding: 0.4rem 0.6rem; border: 1px dashed var(--accent-soft); border-radius: 18px;
  background: rgba(10, 10, 10, 0.92); font-size: 0.8rem; color: var(--text-muted);
}
.opt-switch span { margin: 0 0.15rem 0 0.35rem; }
.opt-switch button { min-width: 2rem; min-height: 2rem; border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--text-secondary); font: 500 0.8rem var(--font); cursor: pointer; }
.opt-switch button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* ---------- v3: Home scrolls page by page (snap) ---------- */
/* each page fills the screen under the header; a scroll gesture carries on to the next page
   and stops there. Pages taller than the screen (an open "See more") scroll normally inside. */
:root { --vh: calc(100svh - var(--hh, 4.6rem)); }
html.snap { scroll-snap-type: y mandatory; scroll-padding-top: var(--hh, 4.6rem); }
.snap-start, .snap-page { scroll-snap-align: start; scroll-margin-top: 0; }   /* the header room is scroll-padding already */
.snap-page {
  min-height: var(--vh, calc(100svh - 4.6rem)); box-sizing: border-box; padding: 3rem 0;
  display: flex; flex-direction: column; justify-content: center;
}
.snap-page .section-title { margin: 0 0 2.5rem; }
.project-page .pcard { margin-top: 0; }
/* Experience scrolls freely and flows into the close */
.xp-page .cta { padding: 4.5rem 0 3rem; }
@media (max-width: 760px) {
  .project-page { padding-top: 5.5rem; }
  .project-page .callout { display: none; }
}

/* photo held: it lifts a touch before it shakes */
.photo-clip { scale: 1; transition: translate 0.4s cubic-bezier(0.2, 0.8, 0.3, 1), scale 0.3s ease; }
.hero3-photo.is-held { --plift: 1; }
.hero3-photo.is-held .photo-clip { scale: 1.035; }

/* ---------- Work with me (dialog steps) ---------- */
.wd-choices { display: flex; flex-direction: column; gap: 0.8rem; margin-top: 1.8rem; }
.wd-choice {
  display: block; width: 100%; padding: 1.05rem 1.3rem; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--text); font: 400 1.1rem var(--font); text-align: left; text-decoration: none; cursor: pointer;
}
.wd-choice:hover { border-color: var(--accent); color: var(--accent); }
.wd-back { margin: 0 0 1.2rem; padding: 0; border: 0; background: none; color: var(--text-muted); font: 400 0.95rem var(--font); cursor: pointer; }
.wd-back::before { content: "\2190  "; }
.wd-back:hover { color: var(--text); }

/* Vibing?: Back, in the dialog's style */
.vibing-back { display: block; margin: 0 0 1.4rem; }

/* Home: the footer is the last stop, so the very bottom can be reached */
html.snap .footer { scroll-snap-align: end; }
html.snap.snap-free { scroll-snap-type: none; }   /* inside Experience: free scrolling (v2.js) */

/* ---------- 3D ball (ball3d.js): the canvas replaces the painted ball; it shakes by moving,
   the turning happens in 3D */
.ball-canvas { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; }
.ball.is-3d .ball-body, .ball.is-3d .ball-gloss { display: none; }
.ball.is-3d.is-active:not(.is-shaking) { animation: none; }
@media (prefers-reduced-motion: no-preference) {
  .ball.is-3d.is-shaking { animation: ball-shake-3d 0.85s ease; }
}
@keyframes ball-shake-3d {
  0%, 100% { transform: none; }
  14% { transform: translate(-9px, 3px); }
  32% { transform: translate(8px, -4px); }
  50% { transform: translate(-6px, -2px); }
  68% { transform: translate(4px, 2px); }
  86% { transform: translate(-2px, -1px); }
}

/* Work page: a small gold cue at the bottom that the projects come next */
.work3.snap-page { position: relative; }
.next-cue {
  position: absolute; left: 50%; bottom: 1.4rem; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
  font-size: 0.75rem; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; text-decoration: none;
  color: var(--accent); opacity: 0.85;
}
.next-cue:hover { opacity: 1; }
.next-cue svg { width: 1.3rem; height: 1.3rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: no-preference) {
  .next-cue svg { animation: cue-bob 2.4s ease-in-out infinite; }
}
@keyframes cue-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@media (max-width: 760px) { .next-cue { bottom: 0.9rem; } }
