/* ─── Fonts ─────────────────────────────────────────────── */
@font-face {
  font-family: "Neue Haas Grotesk Text Pro";
  src: url("fonts/NHaasGroteskTXPro-55Rg.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Haas Grotesk Text Pro";
  src: url("fonts/NHaasGroteskTXPro-75Bd.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ─── Tokens ─────────────────────────────────────────────── */
:root {
  --color-bg:         #131415;
  --color-text:       #ffffff;
  --color-muted:      #9b9b9b;
  --color-hover-bg:   #ececec;
  --color-hover-text: #131415;
  --color-divider:    rgba(90, 90, 90, 0.20);

  --font: "Neue Haas Grotesk Text Pro", "Helvetica Neue", Arial, sans-serif;

  --size-display: clamp(40px, 5.56vw, 160px); /* 80px at 1440px, scales to 160px at 2880px */
  --size-ui:      16px;
  --size-copy:    14px;
  --size-icon:    clamp(28px, 3.89vw, 112px); /* scales with display text */

  --leading-display: 1.1;
  --tracking-display: 0.02em;
  --tracking-ui:      0.02em;
}

/* ─── Reset ──────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* ─── Base ───────────────────────────────────────────────── */
html {
  height: 100%;
}

body {
  min-height: 100vh;
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  flex-direction: row;
  overflow: hidden;
}

a {
  color: inherit;
  text-decoration: none;
}

/* ─── Sidebar ────────────────────────────────────────────── */
.sidebar {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 20px 0;
  width: 100%;
  min-height: 100vh;
  flex-shrink: 0;
  transition: width 0.4s cubic-bezier(0, 0.3, 0.24, 1);
  position: relative;
  z-index: 1;
}

body.sidebar-mode .sidebar {
  width: 20vw;
  border-right: 1px solid var(--color-divider);
}

body.sidebar-mode {
  /* The sidebar is always exactly 20vw here, so this is a plain vw value
     equivalent to 7.2% of the sidebar's own width (the clipping-safe ratio
     calibrated against the longest label) — same resting size as a cqw-based
     value, but since it doesn't track the sidebar's width live during the
     open/close transition, font-size's own transition animates toward a
     single fixed target instead of a moving one, keeping it in sync with
     the sidebar's width transition instead of lagging behind it. */
  --size-display: clamp(14px, 1.44vw, 32px);
  --size-icon: 17px;
}

/* Tablet: sidebar (project list, About/LinkedIn, email) hides entirely
   while a project is open — the close button is the only way back to
   the home list, which already surfaces all of these. The project page's
   own layout stays desktop-style here; only the sidebar goes away. */
@media (max-width: 1024px) {
  body.sidebar-mode .sidebar {
    display: none;
  }
}


/* ─── Page load entrance animations ─────────────────────── */
@keyframes divider-draw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* With fade — nav + footer */
@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* No fade — rows slide up from behind the divider below */
@keyframes rise-in-nofade {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* Logo — expand to "Jeffrey Park", hold, collapse to "JP" */
@keyframes logo-firstname {
  0%   { max-width: 0; }
  20%  { max-width: 56px; }
  70%  { max-width: 56px; }
  100% { max-width: 0; }
}
@keyframes logo-lastname {
  0%   { max-width: 0; }
  20%  { max-width: 40px; }
  70%  { max-width: 40px; }
  100% { max-width: 0; }
}
@keyframes logo-space {
  0%   { width: 0; }
  20%  { width: 5px; }
  70%  { width: 5px; }
  100% { width: 0; }
}

.firstname-clip { animation: logo-firstname 2.4s cubic-bezier(0, 0.3, 0.24, 1); }
.lastname-clip  { animation: logo-lastname  2.4s cubic-bezier(0, 0.3, 0.24, 1); }
.name-space     { animation: logo-space     2.4s cubic-bezier(0, 0.3, 0.24, 1); }

/* Nav */
header nav .nav-link:nth-child(1) {
  animation: rise-in 0.8s cubic-bezier(0, 0.3, 0.24, 1) both;
  animation-delay: 420ms;
}
header nav .nav-link:nth-child(2) {
  animation: rise-in 0.8s cubic-bezier(0, 0.3, 0.24, 1) both;
  animation-delay: 460ms;
}

/* Dividers */
.project-list .divider {
  animation: divider-draw 0.8s cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* Clip wrapper — hides row below its slot until it animates up */
.list-row-clip {
  overflow: hidden;
}

/* List rows — no opacity fade, rises up from behind divider below */
.project-list .list-row {
  animation: rise-in-nofade 0.8s cubic-bezier(0, 0.3, 0.24, 1) both;
}

/* Divider stagger — 400ms ahead of everything else */
.project-list > :nth-child(1)  { animation-delay: 60ms; }
.project-list > :nth-child(3)  { animation-delay: 120ms; }
.project-list > :nth-child(5)  { animation-delay: 180ms; }
.project-list > :nth-child(7)  { animation-delay: 240ms; }
.project-list > :nth-child(9)  { animation-delay: 300ms; }
.project-list > :nth-child(11) { animation-delay: 360ms; }

/* Row stagger — target .list-row inside each clip wrapper */
.project-list > :nth-child(2)  .list-row { animation-delay: 500ms; }
.project-list > :nth-child(4)  .list-row { animation-delay: 560ms; }
.project-list > :nth-child(6)  .list-row { animation-delay: 620ms; }
.project-list > :nth-child(8)  .list-row { animation-delay: 680ms; }
.project-list > :nth-child(10) .list-row { animation-delay: 740ms; }

/* Footer */
footer .copyright {
  animation: rise-in 0.8s cubic-bezier(0, 0.3, 0.24, 1) both;
  animation-delay: 780ms;
}
footer .email-btn {
  animation: rise-in 0.8s cubic-bezier(0, 0.3, 0.24, 1) both;
  animation-delay: 820ms;
}

/* ─── Project panel ──────────────────────────────────────── */
.project-panel {
  flex: 1;
  min-height: 100vh;
  position: relative;
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.4s cubic-bezier(0, 0.3, 0.24, 1);
}

.project-scroll {
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  scroll-behavior: smooth;
  background: #131415;
}

body.sidebar-mode .project-panel {
  transform: translateX(0);
}

/* ─── Close button ───────────────────────────────────────── */
.close-btn {
  display: flex;
  position: absolute;
  top: 20px;
  right: 24px;
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  border: none;
  background: none;
  color: var(--color-muted);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  z-index: 10;
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.close-btn.is-entering {
  animation: close-btn-in 0.4s cubic-bezier(0, 0.3, 0.24, 1) 0.2s forwards;
  pointer-events: auto;
}

.close-btn.is-exiting {
  position: fixed;
  animation: close-btn-out 0.4s cubic-bezier(0, 0.3, 0.24, 1) forwards;
  pointer-events: none;
}

@keyframes close-btn-in {
  from { opacity: 0; transform: rotate(90deg); }
  to   { opacity: 1; transform: rotate(0deg); }
}

@keyframes close-btn-out {
  from { opacity: 1; transform: rotate(0deg); }
  to   { opacity: 0; transform: rotate(90deg); }
}

.close-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  border: 1px solid var(--color-divider);
  background: none;
  z-index: -1;
  transition: background-color 0.2s cubic-bezier(0, 0.3, 0.24, 1), border-color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.close-btn:hover {
  color: var(--color-hover-text);
}

.close-btn:hover::before {
  background-color: var(--color-hover-bg);
  border-color: var(--color-hover-bg);
}

/* ─── Header ─────────────────────────────────────────────── */
header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 16px 0 24px;
  height: 40px;
}

/* ─── Logo ───────────────────────────────────────────────── */
.logo {
  display: flex;
  align-items: center;
  font-size: var(--size-ui);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  color: #ececec;
  cursor: pointer;
}

.j-group,
.p-group {
  display: flex;
  align-items: center;
}

.initial {
  flex-shrink: 0;
}

.firstname-clip,
.lastname-clip {
  overflow: hidden;
  max-width: 0;
  transition: max-width 0.35s cubic-bezier(0, 0.3, 0.24, 1);
  white-space: nowrap;
  padding-bottom: 0.2em;
  margin-bottom: -0.2em;
}

.name-space {
  width: 0;
  transition: width 0.35s cubic-bezier(0, 0.3, 0.24, 1);
  flex-shrink: 0;
}

.logo:hover .firstname-clip { max-width: 56px; }
.logo:hover .lastname-clip  { max-width: 40px; }
.logo:hover .name-space     { width: 5px; }

/* Dim inactive rows in sidebar mode */
body.sidebar-mode .word,
body.sidebar-mode .amp {
  color: var(--color-muted);
}

body.sidebar-mode .list-row.active .word,
body.sidebar-mode .list-row.active .amp {
  color: var(--color-text);
}

/* In sidebar-mode: hover shows white text but suppresses lottie */
body.sidebar-mode .list-row:hover .word,
body.sidebar-mode .list-row:hover .amp {
  color: var(--color-text);
}

body.sidebar-mode .list-row:hover .icon        { opacity: 0; }
body.sidebar-mode .list-row:hover .amp         { opacity: 1; }
body.sidebar-mode .list-row:hover .sep--icon-only {
  width: calc(var(--size-display) * 0.3);
}

/* Disable logo expand in sidebar mode */
body.sidebar-mode .logo:hover .firstname-clip { max-width: 0; }
body.sidebar-mode .logo:hover .lastname-clip  { max-width: 0; }
body.sidebar-mode .logo:hover .name-space     { width: 0; }


/* Sidebar mode: keep labels + arrow visible */
body.sidebar-mode .nav-link { padding: 0 10px; }

/* ─── Nav links ──────────────────────────────────────────── */
nav {
  display: flex;
  gap: 8px;
}

.nav-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 40px;
  padding: 0 16px;
  font-family: var(--font);
  font-size: var(--size-copy);
  font-weight: 400;
  letter-spacing: var(--tracking-ui);
  color: var(--color-muted);
  border-radius: 9999px;
  border: none;
  background: none;
  cursor: pointer;
  -webkit-font-smoothing: antialiased;
  position: relative;
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.nav-link::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  background-color: transparent;
  transition: background-color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
  z-index: -1;
}

.nav-link svg {
  transition: stroke 0.2s cubic-bezier(0, 0.3, 0.24, 1);
  position: relative;
  top: 1px;
}

.nav-link:hover {
  color: var(--color-hover-text);
}

.nav-link.active {
  color: var(--color-text);
}

.nav-link.active:hover {
  color: var(--color-hover-text);
}

.nav-link:hover::before {
  background-color: var(--color-hover-bg);
}

.nav-link:active::before,
.close-btn:active::before {
  animation: btn-press 0.15s cubic-bezier(0, 0.3, 0.24, 1);
}

/* ─── Content section (list + footer) ───────────────────── */
.content-section {
  display: flex;
  flex-direction: column;
  gap: 40px;
}

/* ─── Project list ───────────────────────────────────────── */
.project-list {
  display: flex;
  flex-direction: column;
}

.divider {
  height: 1px;
  background-color: var(--color-divider);
  transform-origin: left;
}

/* ─── List row ───────────────────────────────────────────── */
.list-row {
  display: block;
  padding: 8px 24px;
  cursor: pointer;
  transition: padding 0.4s cubic-bezier(0, 0.3, 0.24, 1);
}

.project-item {
  display: flex;
  align-items: center;
  gap: 24px;
}

/* ─── Project title words ────────────────────────────────── */
.word {
  font-size: var(--size-display);
  font-weight: 700;
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  color: var(--color-text);
  font-feature-settings: "cv03" on, "cv04" on, "cv09" on, "cv11" on;
  white-space: nowrap;
  text-transform: uppercase;
  transition: font-size 0.4s cubic-bezier(0, 0.3, 0.24, 1), color 0.4s cubic-bezier(0, 0.3, 0.24, 1);
}

/* ─── Separator ──────────────────────────────────────────── */
.project-item { gap: 0; }

.sep {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Rows without & (Rivian, Joyful, Archive):
   default width = natural word space; expands to icon size on hover */
.sep--icon-only {
  position: relative;
  width: calc(var(--size-display) * 0.3); /* ~24px at 80px — acts as word space */
  transition: width 0.35s cubic-bezier(0, 0.3, 0.24, 1);
}

.sep--icon-only .icon {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
}

.list-row:hover .sep--icon-only {
  width: calc(var(--size-icon) + 32px);
}

.list-row:hover .sep--icon-only .icon {
  pointer-events: auto;
}

/* Rows with & (Security, Energy):
   space is always reserved; amp and icon stack in same cell */
.sep--swap {
  display: grid;
  place-items: center;
  padding: 0 calc(var(--size-display) * 0.2);
}

.sep--swap .amp,
.sep--swap .icon {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Amp text */
.amp {
  font-size: var(--size-display);
  font-weight: 700;
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  color: var(--color-text);
  font-feature-settings: "cv03" on, "cv04" on, "cv09" on, "cv11" on;
  transition: font-size 0.4s cubic-bezier(0, 0.3, 0.24, 1), color 0.4s cubic-bezier(0, 0.3, 0.24, 1), opacity 0.25s cubic-bezier(0, 0.3, 0.24, 1);
}

/* Icon */
.icon {
  opacity: 0;
  transition: opacity 0.25s cubic-bezier(0, 0.3, 0.24, 1);
}

.icon svg {
  width: var(--size-icon);
  height: var(--size-icon);
}

.lottie-canvas {
  width: var(--size-icon);
  height: var(--size-icon);
  display: block;
  flex-shrink: 0;
  transition: width 0.4s cubic-bezier(0, 0.3, 0.24, 1), height 0.4s cubic-bezier(0, 0.3, 0.24, 1);
}

.list-row:hover .amp  { opacity: 0; }
.list-row:hover .icon { opacity: 1; }

/* ─── Footer ─────────────────────────────────────────────── */
footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 16px 0 24px;
  height: 40px;
}

.copyright-glyph {
  font-size: 16px;
}

.copyright {
  font-size: var(--size-copy);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--color-muted);
  padding: 10px 0;
}

/* ─── Email button states ────────────────────────────────── */

/* Label: clipped wrapper + sliding inner span */
.email-label-wrap {
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  margin-right: 4px;
}
.email-label {
  white-space: nowrap;
  display: inline-block;
}
.email-label.label-exit {
  animation: label-exit 0.1s cubic-bezier(0, 0.3, 0.24, 1) forwards;
}
.email-label.label-enter {
  animation: label-enter 0.1s cubic-bezier(0, 0.3, 0.24, 1) forwards;
}
@keyframes label-exit {
  from { transform: translateY(0); }
  to   { transform: translateY(-110%); }
}
@keyframes label-enter {
  from { transform: translateY(110%); }
  to   { transform: translateY(0); }
}

/* Smooth width transition between label states */
.email-btn {
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1), width 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

/* Icon container: stacked via grid, sized to match out-link icon */
.email-icons {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
}
.icon-copy,
.icon-thumb {
  grid-area: 1 / 1;
  transform-origin: center;
}
.icon-thumb { opacity: 0; }

/* Copied: icon animations */
.email-btn.copied .icon-copy {
  animation: icon-out 0.2s cubic-bezier(0, 0.3, 0.24, 1) forwards;
}
.email-btn.copied .icon-thumb {
  animation: icon-in 0.2s cubic-bezier(0, 0.3, 0.24, 1) forwards;
}
.email-btn.copied .email-icons {
  animation: icon-bounce 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes btn-press {
  0%   { transform: scale(1); }
  40%  { transform: scale(0.94); }
  100% { transform: scale(1); }
}

@keyframes icon-bounce {
  0%   { transform: scale(1); }
  30%  { transform: scale(0.75); }
  100% { transform: scale(1); }
}

/* Revert: counter-clockwise (overrides copied animations) */
.email-btn.copied.reverting .icon-thumb {
  animation: icon-out-ccw 0.2s cubic-bezier(0, 0.3, 0.24, 1) forwards;
}
.email-btn.copied.reverting .icon-copy {
  animation: icon-in-ccw 0.2s cubic-bezier(0, 0.3, 0.24, 1) forwards;
}

@keyframes icon-out {
  from { opacity: 1; transform: rotate(0deg); }
  to   { opacity: 0; transform: rotate(90deg); }
}

@keyframes icon-in {
  from { opacity: 0; transform: rotate(-90deg); }
  to   { opacity: 1; transform: rotate(0deg); }
}

@keyframes icon-out-ccw {
  from { opacity: 1; transform: rotate(0deg); }
  to   { opacity: 0; transform: rotate(-90deg); }
}

@keyframes icon-in-ccw {
  from { opacity: 0; transform: rotate(90deg); }
  to   { opacity: 1; transform: rotate(0deg); }
}


/* ═══════════════════════════════════════════════════════════
   PROJECT PAGE
   ═══════════════════════════════════════════════════════════ */

/* ─── Reveal animation ───────────────────────────────────── */
.proj-reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.55s cubic-bezier(0, 0.3, 0.24, 1),
              transform 0.55s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ─── Hero ───────────────────────────────────────────────── */
.proj-hero {
  padding: 80px 80px 40px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.proj-eyebrow {
  position: absolute;
  top: 20px;
  left: 24px;
  height: 40px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 16px;
  font-weight: 700;
  color: var(--color-muted);
  letter-spacing: 0.02em;
  opacity: 0;
  pointer-events: none;
  transition: transform 0.3s cubic-bezier(0, 0.3, 0.24, 1), opacity 0.3s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-eyebrow.is-visible {
  opacity: 1;
}

.proj-eyebrow.is-scrolled {
  transform: translateX(-16px);
  opacity: 0;
}

/* ─── Scroll meter (advance to next project) ─────────────── */
/* The elongating "o" pill alone communicates scroll progress — the text
   stays a static muted color (no fill sweep) so it doesn't compete with
   that motion. Hover is the only thing that brightens it, as a plain
   affordance that the whole group is clickable. */
.scroll-meter {
  margin: 160px 0 85px;
  padding: 0 80px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.scroll-meter[hidden] {
  display: none;
}

.scroll-meter-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: clamp(36px, 6vw, 120px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
}

.scroll-meter-line {
  display: flex;
  justify-content: flex-start;
}

.scroll-meter-line1 {
  align-items: center;
}

.scroll-meter-line2 {
  align-items: flex-end;
}

.scroll-meter-seg {
  white-space: nowrap;
  color: var(--color-muted);
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.scroll-meter-group:hover .scroll-meter-seg {
  color: var(--color-text);
}

/* The "o" in "project": a real SVG ring instead of a stretched letterform, so
   its rounded ends stay true semicircles (fixed radius = half its fixed
   height) no matter how wide JS grows it, and its stroke weight (not a fill)
   stays constant to match the surrounding letters' stroke thickness — a
   scaleX'd glyph would smear those ends into an ellipse and thicken its
   stroke as it stretched. Sized and baseline-aligned to read as a real
   lowercase "o" among the other letters, with a little breathing room on
   each side standing in for letter-spacing (which doesn't carry across
   sibling elements the way it does within a single text run). */
.scroll-meter-o-svg {
  display: inline-block;
  height: 0.58em;
  margin: 0 0.05em 0.16em;
  color: var(--color-muted);
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.scroll-meter-o-rect {
  fill: none;
}

.scroll-meter-group:hover .scroll-meter-o-svg {
  color: var(--color-text);
}

/* Classic "scroll down" mouse glyph: a pill outline with a dot that eases
   down the inside, fading in as it starts and out as it reaches the bottom
   before resetting — reads as a continuous drip rather than a mechanical
   tick. */
.scroll-meter-mouse {
  position: relative;
  display: inline-flex;
  align-items: flex-start;
  justify-content: center;
  width: 0.4em;
  height: 0.64em;
  margin-left: 0.3em;
  color: var(--color-muted);
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.scroll-meter-mouse svg {
  display: block;
  width: 100%;
  height: 100%;
}

.scroll-meter-group:hover .scroll-meter-mouse {
  color: var(--color-text);
}

.scroll-meter-mouse-ball {
  position: absolute;
  top: 15%;
  left: 50%;
  width: 0.075em;
  height: 0.075em;
  border-radius: 50%;
  background: currentColor;
  animation: scroll-meter-mouse-scroll 1.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes scroll-meter-mouse-scroll {
  0%   { transform: translate(-50%, 0);      opacity: 0; }
  15%  { opacity: 1; }
  55%  { transform: translate(-50%, 0.26em); opacity: 1; }
  75%  { transform: translate(-50%, 0.26em); opacity: 0; }
  76%  { transform: translate(-50%, 0); }
  100% { transform: translate(-50%, 0);      opacity: 0; }
}

.proj-headline {
  font-size: clamp(36px, 6vw, 120px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: #ffffff;
  width: 100%;
}

.proj-subtext {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-muted);
  max-width: 540px;
}

/* ─── About hero: portrait (1/3) + content (2/3) ─────────── */
.proj-about-hero {
  padding-bottom: 80px;
  min-height: 100vh;
  justify-content: center;
}

.proj-about-columns {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  column-gap: 64px;
}

@media (max-width: 768px) {
  .proj-about-columns {
    grid-template-columns: 1fr;
    row-gap: 40px;
  }
}

.proj-about-photos-col {
  position: relative;
  aspect-ratio: 1 / 1;
  max-height: calc(100vh - 160px);
}

.proj-about-photo {
  position: absolute;
  display: block;
  width: 47%;
  height: auto;
  border-radius: clamp(8px, 1.5vw, 16px);
  pointer-events: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  user-select: none;
}

.proj-about-photo--1 {
  left: 0;
  top: 0;
  z-index: 1;
}

.proj-about-photo--2 {
  right: 0;
  top: 32%;
  z-index: 2;
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: 10% center;
  filter: grayscale(100%);
}

@media (max-width: 600px) {
  .proj-about-photos-col {
    aspect-ratio: auto;
    min-height: 320px;
  }
}

.proj-about-content-col {
  display: flex;
  flex-direction: column;
}

.proj-about-content-col h1 {
  margin-bottom: 16px;
}

.proj-about-content-col .proj-subtext {
  margin-bottom: 40px;
}

.proj-about-divider {
  height: 1px;
  background: var(--color-divider);
  margin: 0;
}

.proj-about-facts {
  display: flex;
  flex-direction: column;
}

.proj-about-fact {
  display: grid;
  grid-template-columns: 180px 1fr;
  padding: 16px 0;
  border-bottom: 1px solid var(--color-divider);
}

.proj-about-fact-label {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-muted);
}

.proj-about-fact-value {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-hover-bg);
}

@media (max-width: 600px) {
  .proj-about-fact {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

.proj-about-camera-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 9999px;
  cursor: pointer;
  animation: proj-camera-wiggle 3s ease-in-out infinite;
}

.proj-about-camera-trigger::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  border: 1px solid var(--color-divider);
  background: none;
  z-index: -1;
  transition: background-color 0.2s cubic-bezier(0, 0.3, 0.24, 1), border-color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-about-camera-trigger:hover::before {
  background-color: var(--color-hover-bg);
  border-color: var(--color-hover-bg);
}

@keyframes proj-camera-wiggle {
  0%, 100% { transform: rotate(0deg) scale(1); }
  4% { transform: rotate(-18deg) scale(1.08); }
  8% { transform: rotate(14deg) scale(1.08); }
  12% { transform: rotate(-10deg) scale(1.05); }
  16% { transform: rotate(6deg) scale(1.02); }
  20% { transform: rotate(-2deg) scale(1); }
  24% { transform: rotate(0deg) scale(1); }
}

.proj-about-camera-float {
  --rot: 0deg;
  position: fixed;
  top: 0;
  left: 0;
  border-radius: clamp(8px, 1.5vw, 16px);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
  object-fit: cover;
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transform: translate(-50%, -50%) rotate(var(--rot)) scale(0.94);
  transition: transform 0.15s ease-out;
}

.proj-about-camera-float.is-visible {
  opacity: 1;
  transform: translate(-50%, -50%) rotate(var(--rot)) scale(1);
}

.proj-about-camera-float.is-fading {
  opacity: 0;
  transition: transform 0.15s ease-out, opacity 2s ease-out 1.2s;
}

/* ─── Hero media ─────────────────────────────────────────── */
.proj-hero-media {
  padding: 40px 80px 80px;
}

.proj-hero-media video,
.proj-hero-media img {
  width: 100%;
  display: block;
  border-radius: clamp(8px, 1.5vw, 16px);
}

/* ─── Pull quote (white card) ────────────────────────────── */
.proj-quote-wrap {
  background: #ffffff;
  padding: 80px;
}

.proj-quote {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.proj-quote p {
  font-size: clamp(36px, 5vw, 72px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: #131415;
}

.proj-quote cite {
  font-size: 14px;
  font-style: normal;
  color: var(--color-muted);
}

/* ─── Section divider ────────────────────────────────────── */
.proj-divider {
  height: 1px;
  background: var(--color-divider);
}

/* ─── Content section ────────────────────────────────────── */
.proj-section {
  padding: 80px 80px 104px;
  display: flex;
  flex-direction: column;
  gap: 56px;
}

/* ─── Section header (2-col) ─────────────────────────────── */
.proj-section-header {
  display: flex;
  gap: clamp(16px, 2.22vw, 40px);
}

.proj-section-left {
  flex: 0 0 clamp(180px, 29.17vw, 420px);
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.11vw, 20px);
}

.proj-section-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.proj-num {
  font-size: 24px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

.proj-section-title {
  font-size: clamp(28px, 5vw, 96px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: var(--color-text);
  margin-top: -0.13em;
}

.proj-section-sub {
  font-size: clamp(18px, 1.67vw, 36px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

/* ─── Stacked section block: label + headline + copy, image-above pattern ── */
.proj-section-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.proj-section-label {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.proj-section-copy {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 560px;
}

/* Left-border callout: a single emphasized statement set apart from
   surrounding body copy, e.g. a design principle. */
.proj-callout {
  border-left: 3px solid var(--color-text);
  padding-left: 20px;
}

.proj-callout-headline {
  font-size: clamp(18px, 1.67vw, 32px);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

/* Plain full-bleed photo (no device bezel) — for real photography rather
   than UI/screen mockups, which use .proj-media-card instead. */
.proj-photo {
  width: 100%;
  display: block;
  border-radius: clamp(8px, 1.5vw, 16px);
}

.proj-inline-link {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 4px;
  cursor: pointer;
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-inline-link:hover {
  color: var(--color-muted);
}

.proj-inline-link svg {
  flex-shrink: 0;
}

/* "Rivian" in the About headline: icon sits flush against the word with
   no underline, relying on the icon alone to signal it's a link.
   Normal inline flow + vertical-align tracks the text baseline more
   reliably here than flex's baseline alignment did for a replaced SVG. */
h1 .proj-inline-link {
  display: inline;
  gap: 0;
  text-decoration: none;
}

/* The icon's own artwork sits inset within its viewBox (path spans 4–14
   of an 18x18 box), so its visible strokes end ~3px above its bounding
   box's bottom edge even when that box is baseline-aligned. Nudge the
   box down so the ink itself lands on the baseline. */
h1 .proj-inline-link svg {
  vertical-align: baseline;
  position: relative;
  top: 3px;
}

.proj-body {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-muted);
}

/* ─── Role / timeline meta ───────────────────────────────── */
.proj-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
}

.proj-meta-key {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-muted);
}

.proj-meta-val {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.proj-meta-val span {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-hover-bg);
}

.proj-dot {
  color: var(--color-muted) !important;
}

/* ─── Media card (screen bezel) ─────────────────────────── */
.proj-media-card {
  background: #000000;
  padding: clamp(10px, 1.5vw, 20px);
  border-radius: clamp(20px, 3.5vw, 40px);
}

.proj-media-card video,
.proj-media-card img {
  width: 100%;
  display: block;
  border-radius: calc(clamp(20px, 3.5vw, 40px) - clamp(10px, 1.5vw, 20px));
}

/* ─── Feature cards (3-col) ──────────────────────────────── */
.proj-features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.proj-feature {
  display: flex;
  flex-direction: column;
  border-radius: clamp(8px, 1.5vw, 16px);
  overflow: hidden;
  background: #1a1b1c;
}

.proj-feature-art {
  height: 200px;
  background: #0e0f10;
}

.proj-feature-copy {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.proj-feature-label {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--color-text);
}

/* ─── Panel wrapping rows ────────────────────────────────── */
.proj-panels-wrap {
  padding: 56px 80px 80px;
}

.proj-panels-wrap {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* ─── Sidekick row: diagram (fixed, centered) + display (fills + crops) ─── */
.proj-sidekick-row {
  display: flex;
  align-items: stretch;
  gap: clamp(24px, 3.5vw, 64px);
  height: clamp(360px, 36vw, 560px);
}

.proj-sidekick-diagram {
  flex: 0 0 20%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 24px;
}

.proj-sidekick-diagram video {
  width: 100%;
  height: auto;
  display: block;
}

.proj-sidekick-caption {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.proj-sidekick-display {
  flex: 1 1 auto;
  min-width: 0;
  position: relative;
  border-radius: clamp(8px, 1.5vw, 16px);
  overflow: visible;
  background: #0e0f10;
}

.proj-sidekick-display video {
  position: absolute;
  top: 0;
  left: 0;
  width: auto;
  height: 100%;
  display: block;
}


/* ─── Voice-in-context card ──────────────────────────────── */
.proj-voice-card {
  background: #000000;
  border-radius: clamp(8px, 1.5vw, 16px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.proj-voice-tags {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  padding: 32px 32px 0;
}

.proj-voice-tag-sep {
  color: var(--color-muted);
}

.proj-voice-tag {
  opacity: 0.4;
  transition: opacity 0.3s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-voice-tag.is-active {
  opacity: 1;
}

.proj-voice-tag--listening { color: #f5a623; }
.proj-voice-tag--thinking  { color: #5ac8fa; }
.proj-voice-tag--speaking  { color: #34c759; }
.proj-voice-tag--error     { color: #ff453a; }

.proj-voice-wave {
  padding: 24px 0 32px;
  overflow: hidden;
}

.proj-voice-wave video {
  width: 200%;
  height: auto;
  display: block;
}

/* ─── Scenario carousel ──────────────────────────────────── */
/* Scroll-jack: the zone is tall enough to give the page's normal scroll
   somewhere to go while the layout stays pinned; JS maps how far the user
   has scrolled through it directly onto the carousel's scrollLeft. Once
   the zone is exhausted, the sticky element unpins and page scroll carries
   on to the next section as usual. */
.proj-scenario-scrollzone {
  position: relative;
  height: 320vh;
}

.proj-scenario-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.proj-scenario-layout {
  display: flex;
  align-items: center;
  gap: clamp(24px, 4vw, 64px);
  width: 100%;
}

.proj-scenario-carousel-wrap {
  flex: 1 1 60%;
  min-width: 0;
}

.proj-scenario-carousel {
  --slide-w: 220px;
  position: relative;
  overflow: hidden;
  padding: 40px 0;
  -webkit-mask-image: linear-gradient(to right, transparent 0, black 18%, black 82%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, black 18%, black 82%, transparent 100%);
}

/* The track holds every slide and is the thing that actually moves — its
   transform is what gets a real CSS transition, so sliding from one
   scenario to the next always eases along the site's cubic-bezier curve
   instead of jumping straight to the new position. */
.proj-scenario-track {
  position: relative;
  display: flex;
  gap: 16px;
  width: max-content;
  transition: transform 0.6s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-scenario-slide {
  flex: 0 0 var(--slide-w);
  border-radius: clamp(8px, 1.5vw, 16px);
  overflow: hidden;
  opacity: 0.2;
  transform: scale(0.9);
  transition: opacity 0.3s cubic-bezier(0, 0.3, 0.24, 1), transform 0.3s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-scenario-slide.is-active {
  opacity: 1;
  transform: scale(1);
}

.proj-scenario-slide video {
  display: block;
  width: 100%;
  height: auto;
}

.proj-scenario-copy {
  flex: 1 1 40%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.proj-scenario-headline {
  font-size: clamp(18px, 1.67vw, 36px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

.proj-scenario-icons {
  display: flex;
  gap: 16px;
  margin-top: 8px;
}

.proj-scenario-icon {
  display: flex;
  color: var(--color-muted);
  opacity: 0.35;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0, 0.3, 0.24, 1), color 0.3s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-scenario-icon:hover {
  opacity: 0.7;
}

.proj-scenario-icon.is-active {
  color: var(--color-text);
  opacity: 1;
}

@media (max-width: 768px) {
  .proj-scenario-scrollzone {
    height: 220vh;
  }

  .proj-scenario-sticky {
    height: auto;
    min-height: 100vh;
  }

  .proj-scenario-layout {
    flex-direction: column;
    align-items: stretch;
  }

  .proj-scenario-carousel {
    padding-left: 16px;
    padding-right: 16px;
  }
}

/* ─── Unmute toggle ───────────────────────────────────────── */
.proj-scenario-unmute {
  display: block;
  margin: 20px auto 0;
  padding: 10px 24px;
  border-radius: 9999px;
  border: none;
  background: var(--color-hover-bg);
  color: var(--color-hover-text);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
  cursor: pointer;
  transition: opacity 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-scenario-unmute:hover {
  opacity: 0.85;
}

/* ─── Closing ────────────────────────────────────────────── */
.proj-closing-statement {
  padding: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
}

.proj-closing-headline {
  font-size: clamp(28px, 5vw, 96px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: #ffffff;
  max-width: 780px;
}

/* ─── AI Day CTA ─────────────────────────────────────────── */
.proj-ai-day-cta {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 24px 0;
  color: var(--color-muted);
  text-decoration: none;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  transition: color 0.2s cubic-bezier(0, 0.3, 0.24, 1);
}

.proj-ai-day-cta:hover {
  color: var(--color-text);
}

.proj-ai-day-cta svg {
  position: relative;
  top: 1px;
  flex-shrink: 0;
}


/* ─── Project footer ─────────────────────────────────────── */
.proj-footer {
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding: 32px 80px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  text-align: center;
}

.proj-thanks {
  font-size: 14px;
  line-height: 1.5;
  color: #9b9b9b;
}

.proj-cta {
  font-size: 14px;
  color: #ffffff;
}

.proj-cta a {
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.proj-cta a:hover {
  color: #9b9b9b;
}

/* Project pages carry a generous 80px side gutter on desktop; that's far
   too much on mobile, so it collapses to 16px below the breakpoint. */
@media (max-width: 768px) {
  .proj-hero,
  .proj-hero-media,
  .proj-quote-wrap,
  .proj-section,
  .proj-panels-wrap,
  .proj-closing-statement,
  .proj-footer,
  .scroll-meter {
    padding-left: 16px;
    padding-right: 16px;
  }

  .proj-section-header {
    display: contents;
  }

  .proj-section-left {
    flex: 0 0 auto;
  }

  .proj-media-card {
    order: 2;
  }

  .proj-section-right {
    order: 3;
  }
}

/* ─── Coming soon page ───────────────────────────────────── */
/* Standalone placeholder page (coming-soon branch) — overrides the base
   body's sidebar/panel flex-row layout to simply center everything. */
body.coming-soon-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  text-align: center;
}

.coming-soon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(24px, 4vw, 48px);
}

.coming-soon-headline {
  font-size: clamp(32px, 6vw, 80px);
  font-weight: 700;
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  color: var(--color-text);
}

.coming-soon-icons {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.8vw, 36px);
}

.coming-soon-icon {
  width: clamp(18px, 2.8vw, 36px);
  height: clamp(18px, 2.8vw, 36px);
}
