/* ============================================================
   ZZ Portfolio — v2 "Refined Evolution"
   Branch copy. Does not affect the original site.

   Design read: developer/designer portfolio, refined-editorial
   language. Warm-neutral palette + single amber accent (brand
   continuity). Griffy kept ONLY as the logo mark; headlines use
   Bricolage Grotesque, body uses Inter.

   Dials: VARIANCE 6 / MOTION 4 / DENSITY 3
   Shape system: buttons = pill, cards/media = 16px, chips = pill.
   One accent (amber family), one theme at a time (light/dark).
   ============================================================ */

/* ---------- THEME TOKENS ---------- */
:root {
  --bg:            #faf8f4;  /* warm off-white, never pure white */
  --bg-elevated:   #fffdf9;
  --surface:       #f3efe7;  /* warm card alt */
  --text:          #1c1917;  /* warm near-black, never pure black */
  --text-muted:    #57534e;
  --border:        #e7e1d6;
  --border-strong: #d8cfbf;
  --accent:        #b45309;  /* amber-700 — AA-safe link color on light */
  --accent-soft:   #f59e0b;  /* brand amber for small marks/underlines */
  --shadow:        0 1px 2px rgba(28,25,23,.04), 0 12px 32px -12px rgba(28,25,23,.12);
  --nav-h: 68px;
}

body.dark-mode {
  --bg:            #1c1917;  /* warm stone-950 */
  --bg-elevated:   #292524;
  --surface:       #262220;
  --text:          #faf8f4;
  --text-muted:    #a8a29e;
  --border:        #3a3531;
  --border-strong: #4b443e;
  --accent:        #fbbf24;  /* amber-400 — AA on dark */
  --accent-soft:   #fbbf24;
  --shadow:        0 1px 2px rgba(0,0,0,.3), 0 16px 40px -16px rgba(0,0,0,.55);
}

/* ---------- BASE ---------- */
* { transition: background-color .3s ease, color .3s ease, border-color .3s ease; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 12px); }

body {
  background-color: var(--bg);
  color: var(--text);
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
  position: relative;
}

/* Subtle static texture replacing particles.js — fixed, no repaint cost */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(60vw 60vw at 78% -8%, rgba(245,158,11,.10), transparent 60%),
    radial-gradient(48vw 48vw at -10% 12%, rgba(245,158,11,.06), transparent 55%);
}
body.dark-mode::before {
  background:
    radial-gradient(60vw 60vw at 78% -8%, rgba(251,191,36,.10), transparent 60%),
    radial-gradient(48vw 48vw at -10% 12%, rgba(251,191,36,.05), transparent 55%);
}

/* Back-to-top probe: zero-width, tall, no layout impact. Button shows
   once this top band has scrolled out of view. */
#top-sentinel { position: absolute; top: 0; left: 0; width: 1px; height: 360px; pointer-events: none; }

.display { font-family: "Bricolage Grotesque", "Inter", sans-serif; letter-spacing: -0.02em; }
.logo    { font-family: "Griffy", cursive; }

.text-muted-c { color: var(--text-muted); }
.accent-link  { color: var(--accent); font-weight: 500; text-decoration: none; text-underline-offset: 3px; }
.accent-link:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.accent-bar   { color: var(--accent-soft); }

/* ---------- NAV ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  height: var(--nav-h);
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--border);
}
@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
}
.nav-link { color: var(--text-muted); font-weight: 500; }
.nav-link:hover { color: var(--accent); }
.icon-btn { color: var(--text-muted); }
.icon-btn:hover { color: var(--accent); }

/* ---------- BUTTONS (pill) ---------- */
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  border-radius: 9999px; font-weight: 600; line-height: 1;
  padding: .85rem 1.5rem; white-space: nowrap;
  transition: transform .2s ease, background-color .3s ease, color .3s ease, border-color .3s ease;
}
.btn:active { transform: translateY(1px) scale(.99); }

.btn-primary { background: var(--text); color: var(--bg); }
.btn-primary:hover { transform: translateY(-2px); box-shadow: var(--shadow); }

.btn-secondary { background: transparent; color: var(--text); border: 1px solid var(--border-strong); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-2px); }

/* ---------- HERO ---------- */
.hero { min-height: calc(100dvh - var(--nav-h)); }
.hero-portrait {
  border-radius: 20px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  background: var(--surface);
}
.hero-frame { position: relative; }
.hero-frame::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 20px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
  pointer-events: none;
}

/* ---------- SECTION HEADERS ---------- */
.section-title { font-size: clamp(1.9rem, 4vw, 2.75rem); font-weight: 700; }
.rule { height: 1px; background: var(--border); }

/* ---------- ABOUT — lede + spec index (Design 1) ---------- */
/* Hairline two-column card: a bold lede keeps the voice, facts drop
   into a scannable specimen index. Gap = 1px so the border shows through. */
.about-card {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: var(--shadow);
}
.about-cell { background: var(--bg-elevated); padding: clamp(1.5rem, 3vw, 2.5rem); }

.about-lede {
  font-family: "Bricolage Grotesque", "Inter", sans-serif;
  font-weight: 600; letter-spacing: -.015em;
  font-size: clamp(1.3rem, 2.2vw, 1.75rem); line-height: 1.3;
  max-width: 26ch; color: var(--text);
}
.about-lede .accent-bar { font-weight: 700; }
.about-sub { margin-top: 1.25rem; color: var(--text-muted); font-size: 1rem; max-width: 40ch; }

.spec-list { display: flex; flex-direction: column; }
.spec-row {
  display: grid; grid-template-columns: 7rem 1fr; gap: 1.1rem;
  padding: .85rem 0; border-bottom: 1px solid var(--border); align-items: baseline;
}
.spec-row:first-child { padding-top: 0; }
.spec-row:last-child { border-bottom: 0; padding-bottom: 0; }
.spec-row dt {
  font-family: "JetBrains Mono", monospace;
  font-size: .72rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-muted);
}
.spec-row dd { font-size: 1rem; font-weight: 500; line-height: 1.5; color: var(--text); }
.spec-row dd .spec-sub { color: var(--text-muted); font-weight: 400; }

@media (max-width: 760px) {
  .about-card { grid-template-columns: 1fr; }
  .spec-row { grid-template-columns: 6rem 1fr; gap: .85rem; }
}

/* ---------- CARDS (16px) ---------- */
.card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow);
  transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
  overflow: hidden;
}
.card:hover { transform: translateY(-6px); border-color: var(--border-strong); }
.card-media { background: var(--surface); }
.card-title { color: var(--text); }
.card-body  { color: var(--text-muted); }

.chip {
  background: var(--surface);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 9999px;
  font-size: .75rem;
  padding: .25rem .7rem;
}

.card-icon { color: var(--text-muted); }
.card-icon:hover { color: var(--accent); }

/* ---------- VIDEOS ---------- */
.video-item { border-radius: 16px; overflow: hidden; background: var(--surface); border: 1px solid var(--border); }
.video-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease; }
.video-item:hover img { transform: scale(1.05); }
.video-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.72), rgba(0,0,0,.15) 55%, transparent);
  opacity: 0; transition: opacity .3s ease;
}
.video-item:hover .video-scrim { opacity: 1; }

/* ---------- WORK — pinned scroll gallery (v2.1) ----------
   Default state = normal stacked list (no-JS / reduced-motion / ≤760px).
   JS adds .pin-on → tall track + sticky stage + single-active crossfade. */
.work { position: relative; z-index: 2; }
/* Heading lives INSIDE the stage so it stays pinned with the projects
   (no scroll-away void). Aligns to the 60rem slide column; title matches
   the .section-title scale used by About / Videos / Contact. */
.work-intro { width: 100%; max-width: 60rem; margin: 0 auto; padding: 0 0 1.75rem; }
.work-kicker { font-family: "JetBrains Mono", monospace; font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 .55rem; }
.work-kicker span { color: var(--accent); }
.work-title { font-weight: 700; font-size: clamp(1.9rem, 4vw, 2.75rem); letter-spacing: -.02em; line-height: 1.1; margin: 0 0 .6rem; color: var(--text); }
.work-lede { color: var(--text-muted); max-width: 48ch; font-size: clamp(.96rem, 1.2vw, 1.06rem); line-height: 1.6; margin: 0; }

/* Double-bezel media frame */
.bezel { background: var(--surface); border: 1px solid var(--border); border-radius: 18px; padding: .5rem; box-shadow: var(--shadow); }
.bezel-core { border-radius: 13px; overflow: hidden; background: var(--bg-elevated); }
.bezel-core img { width: 100%; height: 100%; object-fit: cover; display: block; }

.gallery-track { position: relative; }
.gallery-stage { display: block; padding: 2.5rem 1.5rem 4rem; }
.gallery-slides { position: relative; list-style: none; margin: 0 auto; padding: 0; width: 100%; max-width: 60rem; }
.gallery-slide { position: static; opacity: 1; transform: none; filter: none; pointer-events: auto; list-style: none; margin-bottom: 4.5rem; }

.gallery-rail { display: none; list-style: none; margin: 0; padding: 0; }
.gallery-rail li { width: 3px; height: 26px; border-radius: 999px; background: var(--border-strong); transition: background .5s cubic-bezier(.16,1,.3,1), height .5s cubic-bezier(.16,1,.3,1); }
.gallery-rail li.is-active { background: var(--accent); height: 44px; }

/* Pinned mode (JS adds .pin-on). 400vh ≈ 4 slides, ~1 viewport of scroll each. */
.gallery-track.pin-on { height: 320vh; }
.gallery-track.pin-on .gallery-stage { position: sticky; top: 0; min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; padding: 5rem 1.5rem 2.5rem; overflow: hidden; }
.gallery-track.pin-on .work-intro { flex: 0 0 auto; }
.gallery-track.pin-on .gallery-rail { display: flex; position: absolute; left: 1.5rem; top: 50%; transform: translateY(-50%); flex-direction: column; gap: .7rem; z-index: 4; }
.gallery-track.pin-on .gallery-slides { min-height: min(50vh, 430px); flex: 0 0 auto; }
.gallery-track.pin-on .gallery-slide { position: absolute; inset: 0; margin-bottom: 0; opacity: 0; transform: translateY(36px) scale(.99); filter: blur(8px); pointer-events: none; transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1), filter .7s cubic-bezier(.16,1,.3,1); }
.gallery-track.pin-on .gallery-slide.is-active { opacity: 1; transform: none; filter: blur(0); pointer-events: auto; }

/* Project card inside a slide */
.proj { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.4rem, 3vw, 2.4rem); align-items: center; height: 100%; }
.proj-media { width: 100%; }
.proj-media .bezel-core { aspect-ratio: 16 / 10; }
.proj-index { font-family: "Bricolage Grotesque", sans-serif; font-weight: 800; color: var(--accent); letter-spacing: .1em; font-size: .85rem; }
.proj-title { font-weight: 700; font-size: clamp(1.35rem, 2.4vw, 1.9rem); line-height: 1.1; margin: .45rem 0 .4rem; color: var(--text); }
.proj-pov { color: var(--text-muted); max-width: 46ch; margin: 0 0 1.4rem; font-size: clamp(.98rem, 1.3vw, 1.06rem); line-height: 1.6; }
.proj-tags { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; padding: 0; margin: 0 0 1.6rem; }
.proj-tags li { font-size: .72rem; color: var(--text-muted); border: 1px solid var(--border); border-radius: 9999px; padding: .3rem .75rem; background: var(--surface); }
.proj-links { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; }
.proj-links .btn { padding: .7rem 1.2rem; font-size: .9rem; }

@media (max-width: 880px) {
  .proj { grid-template-columns: 1fr; gap: 1.5rem; }
}

/* Mobile ≤760px: never pin — mirrors the JS breakpoint */
@media (max-width: 760px) {
  .gallery-track.pin-on { height: auto; }
  .gallery-track.pin-on .gallery-stage { position: static; min-height: 0; overflow: visible; display: block; padding: 1rem 1.5rem 4rem; }
  .gallery-track.pin-on .gallery-rail { display: none; }
  .gallery-track.pin-on .gallery-slides { min-height: 0; }
  .gallery-track.pin-on .gallery-slide { position: static; inset: auto; opacity: 1; transform: none; filter: none; pointer-events: auto; margin-bottom: 4.5rem; transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  .gallery-track.pin-on { height: auto; }
  .gallery-track.pin-on .gallery-stage { position: static; min-height: 0; overflow: visible; display: block; padding: 1rem 1.5rem 4rem; }
  .gallery-track.pin-on .gallery-rail { display: none; }
  .gallery-track.pin-on .gallery-slide { position: static; inset: auto; opacity: 1; transform: none; filter: none; pointer-events: auto; margin-bottom: 4.5rem; transition: none; }
}

/* Mobile: drop the last stacked slide's inter-slide margin so the gap above
   "Featured videos" matches the other section titles (≈3rem top + stage pad,
   not the 4.5rem trailing slide gap on top). Wins over the stacked-state
   rules above via :last-child specificity + source order; desktop untouched. */
@media (max-width: 760px) {
  .gallery-slide:last-child,
  .gallery-track.pin-on .gallery-slide:last-child { margin-bottom: 0; }
}

/* ---------- CONTACT / FOOTER ---------- */
.social-icon { color: var(--text-muted); display: inline-block; transition: transform .25s ease, color .3s ease; }
.social-icon:hover { color: var(--accent); transform: translateY(-3px); }
.footer { border-top: 1px solid var(--border); color: var(--text-muted); }

/* ---------- BACK TO TOP ---------- */
.to-top {
  position: fixed; bottom: 2rem; right: 2rem; z-index: 60;
  width: 3rem; height: 3rem; border-radius: 9999px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-elevated); color: var(--accent);
  border: 1px solid var(--border-strong); box-shadow: var(--shadow);
  opacity: 0; transform: translateY(8px) scale(.9); pointer-events: none;
  transition: opacity .3s ease, transform .3s ease;
}
.to-top.show { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.to-top:hover { transform: translateY(-2px); }

/* ---------- MOTION: scroll reveal (MOTION_INTENSITY 4) ---------- */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1); }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  .reveal { opacity: 1; transform: none; }
  .card:hover, .btn:hover, .social-icon:hover, .video-item:hover img { transform: none; }
}

/* ---------- MOBILE MENU ---------- */
.mobile-menu { background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow); }
.mobile-menu a { color: var(--text-muted); }
.mobile-menu a:hover { color: var(--accent); }
