/* ============================================================
   Portfolio 2026 — site.css
   Layout + shared components. Tokens and the type ramp live in
   tokens.css (1:1 from the Figma variables) — link it first.
   ============================================================ */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: "DM Sans", -apple-system, sans-serif;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; }
figure, figcaption { margin: 0; padding: 0; }
p { margin: 0; }
h1, h2, h3, h4 { margin: 0; font-weight: inherit; }
a { color: inherit; text-decoration: none; }
button { font: inherit; border: 0; background: none; padding: 0; cursor: pointer; color: inherit; }

/* ---------- Navigation pill ---------- */
.nav-wrap {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  justify-content: center;
  align-items: flex-start; /* nav keeps its natural height even in the 0-height overlay variant */
  padding: 32px 0 24px;
  pointer-events: none;
}
.nav-wrap .nav { pointer-events: auto; }
/* overlay variant (Home): fixed so it takes zero flow space — the hero stays full-fold behind it */
.nav-wrap.nav-overlay { position: fixed; top: 0; left: 0; right: 0; height: auto; padding: 32px 0 0; overflow: visible; }
.nav {
  display: flex;
  align-items: center;
  gap: var(--xxs);
  padding: var(--xs);
  background: var(--glass-bg);
  border: 2px solid var(--glass-border-color);
  border-radius: var(--radius-full);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}
/* .nav a states live in components.css (.Tabs 105:1587) */

/* Buttons + LinkButton live in components.css (180:1618, 178:959) */

/* ---------- Project Card ---------- */
/* Project Card — Figma 329:8184 (rest / hover / pressed) */
.project-card {
  flex: 1 1 0;
  min-width: 1px;
  display: flex;
  flex-direction: column;
}
.project-card:focus:not(:focus-visible) { outline: none; }
/* cover: rounded image; shadow lifts on hover, presses in on click */
.project-card .cover {
  height: 300px;
  border-radius: var(--radius-sm);
  background: linear-gradient(to bottom, var(--grad-top), var(--grad-bottom));
  overflow: hidden;
  transition: box-shadow 0.3s ease;
}
.project-card:hover .cover { box-shadow: 0 12px 40px rgba(17, 17, 19, 0.06), 0 1px 2px rgba(17, 17, 19, 0.04); }
.project-card:active .cover { box-shadow: 0 2px 4px rgba(17, 17, 19, 0.08); }
.project-card .cover img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }
.project-card:hover .cover img { transform: scale(1.03); }
/* composed cover: project shot floating over the gradient */
.project-card .cover.cover-shot { position: relative; }
.project-card .cover.cover-shot img {
  position: absolute;
  left: 50%;
  top: 36px;
  transform: translateX(-50%);
  width: 78%;
  height: auto;
  border-radius: 12px;
  box-shadow: 0 24px 60px rgba(30, 25, 60, 0.22), 0 2px 6px rgba(30, 25, 60, 0.08);
  object-fit: initial;
}
.project-card:hover .cover.cover-shot img { transform: translateX(-50%) translateY(-6px); }
/* phone-style cover: tall portrait shots */
.project-card .cover.cover-shot.cover-phone img { width: 38%; }
/* body: no fill, top padding only */
.project-card .card-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sm);
  padding-top: var(--ml);
}
.project-card .card-head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--xxs); width: 100%; }
.project-card .card-title-row { display: flex; align-items: center; gap: 10px; width: 100%; }
.project-card .text-block { flex: 1 1 0; min-width: 1px; display: flex; flex-direction: column; align-items: flex-start; gap: var(--xxs); }
.project-card .card-body .desc { color: var(--body); }
/* arrow button: hidden at rest, fades in (bordered) on hover, dark-filled on press */
.project-card .card-arrow {
  flex: none;
  width: 40px; height: 40px;
  border-radius: var(--radius-full);
  display: grid; place-items: center;
  border: 1px solid var(--line);
  background: transparent;
  opacity: 0; transform: translateY(-2px);
  transition: opacity 0.25s ease, transform 0.25s ease, background-color 0.2s ease, border-color 0.2s ease;
}
.project-card .card-arrow img { width: 16px; height: 16px; transition: filter 0.2s ease; }
.project-card:hover .card-arrow { opacity: 1; transform: none; }
.project-card:active .card-arrow { background: var(--ink); border-color: var(--ink); }
.project-card:active .card-arrow img { filter: invert(1); }
.project-card .card-tags { display: flex; gap: var(--xs); align-items: center; flex-wrap: wrap; }

/* ---------- Contact section ---------- */
.contact-anchor {
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--xxl) var(--xl);
}
.contact-section {
  position: relative;
  height: 396px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background:
    radial-gradient(closest-side at 38% -6%, rgba(255, 243, 226, 1), rgba(255, 243, 226, 0) 78%),
    radial-gradient(closest-side at 82% 28%, rgba(255, 217, 190, 0.9), rgba(255, 217, 190, 0) 75%),
    radial-gradient(closest-side at 12% 48%, rgba(255, 217, 190, 0.75), rgba(255, 217, 190, 0) 75%),
    radial-gradient(closest-side at 6% 84%, rgba(220, 217, 255, 0.9), rgba(220, 217, 255, 0) 78%),
    radial-gradient(closest-side at 90% 88%, rgba(185, 185, 250, 0.95), rgba(185, 185, 250, 0) 80%),
    linear-gradient(to bottom, var(--grad-top), var(--grad-bottom));
}
.contact-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.contact-content {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ml);
  text-align: center;
}
.contact-content .contact-body {
  display: flex;
  flex-direction: column;
  gap: var(--xs);
  max-width: 560px;
}
.contact-content .sub { color: var(--body); }
.contact-actions { display: flex; gap: 12px; }

/* ---------- Footer ---------- */
.footer-margin { width: 100%; margin: 0 auto; padding-top: var(--max); }
/* Figma Footer 274:7895 — border + labels share the wrapper's 1080px box, no inner padding */
.footer {
  background: #fff;
  border-top: 1px solid var(--line);
  padding: var(--ml) 0 var(--max);
}
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--body);
}

/* ---------- Scroll reveal (micro) ---------- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ============================================================
   HOME
   ============================================================ */
.hero {
  position: relative;
  /* full fold at every viewport (svh = stable height under mobile browser chrome) */
  height: 100vh;
  height: 100svh;
  min-height: 480px;
  overflow: hidden;
  background: linear-gradient(to bottom, var(--grad-top), var(--grad-bottom));
}
.hero-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* CSS fallback glows if canvas JS fails; hidden once canvas is live */
.hero-glows { position: absolute; inset: 0; pointer-events: none; }
.hero.canvas-live .hero-glows { display: none; }
.hero-glows .glow { position: absolute; border-radius: 50%; filter: blur(60px); }
.glow-cream       { left: 12.5%; top: -25.7%; width: 62.5%; height: 91%;  background: rgba(255, 243, 226, 0.9); }
.glow-peach       { left: 52.8%; top: 5.7%;   width: 52.8%; height: 80%;  background: rgba(255, 217, 190, 0.8); }
.glow-peach-2     { left: -6.3%; top: 23.7%;  width: 52.8%; height: 80%;  background: rgba(255, 217, 190, 0.8); }
.glow-lilac       { left: -11.1%; top: 40%;   width: 47.2%; height: 85.7%; background: rgba(220, 217, 255, 0.9); }
.glow-periwinkle  { left: 68.1%; top: 60%;    width: 38.9%; height: 62.9%; background: rgba(185, 185, 250, 0.9); }


/* Hero copy sits in the bottom-left corner of the frame (Figma 482:2056):
   48px side margin, 48px off the floor, whatever the viewport height. */
.hero-intro {
  position: absolute;
  left: var(--xxl);
  bottom: var(--xxl);
  width: calc(100% - var(--xxl) * 2);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  z-index: 10;
  pointer-events: none;
}
.hero-lines {
  display: flex;
  flex-direction: column;
  gap: var(--ml);
  width: 100%;
}

/* hero header entrance (preserved animation language) */
.hero-intro .line-1,
.hero-intro .line-2 {
  opacity: 0;
  transform: translateY(28px);
  animation: hero-rise 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.hero-intro .line-1 { animation-delay: 0.08s; }
.hero-intro .line-2 { animation-delay: 0.18s; }
@keyframes hero-rise {
  to { opacity: 1; transform: none; }
}

/* physics chips canvas sits above gradient, below nav */
.chips-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 20; }
/* hidden DOM chips used for measurement / no-JS fallback */
.chips-measure {
  position: absolute;
  top: 0; left: 0;
  visibility: hidden;
  pointer-events: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--xs);
}
.logo-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s);
  padding: var(--xs) var(--ml) var(--xs) var(--xs);
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.45);
  box-shadow: 0 2px 6px rgba(17, 17, 19, 0.08);
  white-space: nowrap;
}
.logo-chip .logo-circle {
  width: 64px; height: 64px;
  border-radius: 50%;
  background: #fff;
  display: grid;
  place-items: center;
  flex: none;
  overflow: hidden;
}
.logo-chip .logo-circle img { width: 34.9px; height: 34.9px; object-fit: contain; }
.logo-chip .logo-plain { width: 64px; height: 64px; flex: none; }
.logo-chip .logo-plain img { width: 100%; height: 100%; }
.logo-chip .chip-label {
  font-size: 32px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
}
/* reduced-motion fallback: chips shown as a static row at the hero base */
.chips-measure.chips-static {
  visibility: visible;
  top: auto;
  bottom: var(--ml);
  left: 50%;
  transform: translateX(-50%) scale(0.62);
  transform-origin: bottom center;
  width: 150%;
  justify-content: center;
  z-index: 20;
}

/* Selected work */
.selected-work {
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--xxl);
  padding: var(--max) 0 0;
}
.home-bio {
  max-width: 800px;
  width: 100%;
  padding: var(--xxl) 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--xxl);
}
.home-bio p { color: var(--ink); text-align: left; width: 100%; } /* Figma 190:1072 */
.work-content {
  width: 100%;
  max-width: 1160px;
  padding: 0 var(--xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ml);
}
.work-content .btn { margin-top: var(--ml); }
.work-header {
  width: 100%;
  max-width: 1080px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sm);
}
.work-cards {
  width: 100%;
  max-width: 1080px;
  display: flex;
  align-items: stretch;
  gap: var(--xxl);
}

/* ============================================================
   ABOUT
   ============================================================ */
.about-intro {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 120px 0 var(--xxl);
  display: flex;
  flex-direction: column;
  gap: var(--ml);
}
.about-intro .heading-block { position: relative; display: flex; flex-direction: column; gap: var(--sm); }

/* Portrait floating over the heading (Figma 272:19711): 170px circle centred
   at 400/328 of the 800×411 header, so it lands between "builder" and "habit".
   It idles with a gentle bob and stays wherever it's dragged (js/portrait-drag.js). */
.about-portrait {
  position: absolute;
  left: 39.4%;
  top: 59.2%;
  width: 21.25%;
  aspect-ratio: 1 / 1;
  z-index: 2;
  touch-action: none;
}
/* JS writes the drag transform here */
.about-portrait__drag { width: 100%; height: 100%; cursor: grab; will-change: transform; }
.about-portrait__drag.is-dragging { cursor: grabbing; }
/* idle bob, on its own layer so it never fights the drag transform */
.about-portrait__float {
  width: 100%;
  height: 100%;
  animation: about-portrait-float 6s ease-in-out infinite;
}
.about-portrait__drag.is-dragging .about-portrait__float { animation-play-state: paused; }
.about-portrait__img {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  object-fit: cover;
  background: var(--white);
  box-shadow: var(--shadow-float);
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}
@keyframes about-portrait-float {
  0%   { transform: translateY(0) rotate(0deg); }
  50%  { transform: translateY(-12px) rotate(-1.5deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
@media (prefers-reduced-motion: reduce) {
  .about-portrait__float { animation: none; }
}
.about-intro p.para { color: var(--ink); }
.about-intro .body-2-med { font-size: 20px; font-weight: 500; line-height: 1.4; letter-spacing: -0.03em; color: var(--ink); }

.numbered-list { display: flex; flex-direction: column; gap: var(--xs); }
.numbered-list .list-item { display: flex; gap: var(--xs); align-items: flex-start; }
.numbered-list .num { font-size: 20px; font-weight: 300; line-height: 1.4; letter-spacing: -0.02em; color: var(--ink); white-space: nowrap; }
.numbered-list .text { flex: 1; font-size: 20px; font-weight: 300; line-height: 1.4; letter-spacing: -0.02em; color: var(--ink); }
.numbered-list .text strong { font-weight: 500; letter-spacing: -0.03em; }

/* Recommendations strip */
.recs {
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--xxl) var(--xl);
  display: flex;
  flex-direction: column;
  gap: var(--ml);
}
.recs .label-serif { letter-spacing: 4px; }
.reviews {
  background: transparent;
  display: flex;
  gap: var(--ml);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0;
  -webkit-overflow-scrolling: touch;
  /* Full-bleed to the right: the strip starts at the content margin but runs
     off the right edge of the VIEWPORT, so the next card is cut by the screen
     edge, not by the container. (50% = half the centred container's content
     width, so 50% − 50vw is exactly the gap to the viewport edge.) */
  margin-right: calc(50% - 50vw);
  padding: 0 var(--xl) 0 0;   /* breathing room once scrolled to the last card */
}
.reviews::-webkit-scrollbar { height: 8px; }
.reviews::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.reviews .review {
  flex: none;
  width: 744px;
  max-width: 82vw;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  scroll-snap-align: start;
  background: #fff;
}
.reviews .review img { display: block; width: 100%; height: auto; }

.experience {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: var(--xxl) 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ml);
}
.experience .label-serif { width: 100%; letter-spacing: 4px; }
.exp-rows { width: 100%; }
.exp-row {
  display: flex;
  align-items: flex-start;
  padding: 20px 0;
  border-top: 1px solid var(--line);
  font-size: 16px;
  line-height: 1.4;
  letter-spacing: -0.02em;
  transition: background-color 0.25s ease;
}
.exp-row:hover { background: linear-gradient(to right, transparent, rgba(245, 244, 241, 0.8) 12%, rgba(245, 244, 241, 0.8) 88%, transparent); }
.exp-row .company { width: 280px; font-weight: 500; color: var(--ink); }
.exp-row .role { flex: 1; font-weight: 300; color: var(--body); }
.exp-row .years { width: 120px; text-align: right; font-weight: 300; color: var(--body); }

/* ============================================================
   CASE STUDIES
   ============================================================ */
.cs-header {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 120px 0 var(--xxl);
  display: flex;
  flex-direction: column;
  gap: var(--ml);
}
.cs-header .heading-block { display: flex; flex-direction: column; gap: var(--sm); }
.cs-header .sub { color: var(--ink); }
.cs-grid {
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--xxl) var(--xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--xxl);
}
.cs-row {
  width: 100%;
  max-width: 1080px;
  display: flex;
  align-items: stretch;
  gap: var(--xxl);
}
/* last row with a single card keeps half width, left-aligned */
.cs-row.single { justify-content: flex-start; }
.cs-row.single .project-card { flex: 0 1 calc((100% - var(--xxl)) / 2); }

/* ============================================================
   Responsive — mobile adaptation from the same tokens
   ============================================================ */
/* Display is sized for the 1440 frame (240px across a 1344 column). Below that
   it tracks the viewport at the same ratio so "Product Builder." keeps its
   two-line break instead of overflowing. */
@media (max-width: 1440px) {
  .display { font-size: min(240px, 16.67vw); }
}
@media (max-width: 900px) {
  .display { font-size: 64px; letter-spacing: -0.05em; }
  .display-2 { font-size: 56px; letter-spacing: -0.025em; }
  .h1 { font-size: 48px; }
  .h2, .h2-med { font-size: 36px; }
  .body-1 { font-size: 20px; }

  .work-cards, .cs-row { flex-direction: column; }
  .home-bio, .about-intro, .experience, .cs-header { padding-left: var(--ml); padding-right: var(--ml); }
  .footer { width: calc(100% - 48px); margin: 0 auto; }
  .contact-anchor { padding: 0 var(--ml); }
  .contact-content { padding: 0 var(--ml); }
  .contact-content .contact-body { max-width: 100%; }
  .contact-actions { flex-wrap: wrap; justify-content: center; }
  .exp-row { flex-wrap: wrap; gap: 4px; }
  .exp-row .company { width: 100%; }
  .exp-row .role { flex: 1 1 auto; }
  .exp-row .years { width: auto; }
}
@media (max-width: 540px) {
  .display { font-size: 48px; letter-spacing: -0.03em; }
  .display-2 { font-size: 48px; letter-spacing: -0.01em; }
  .h1 { font-size: 40px; }
  .h2, .h2-med { font-size: 32px; }
  .h3, .h3-med { font-size: 24px; }
  .body-1 { font-size: 20px; }
  .nav a { padding: var(--s) var(--sm); }
  .contact-section { height: auto; padding: var(--max) 0; }
  .contact-content { position: relative; inset: auto; padding: 0 var(--sm); }
  .contact-actions { flex-wrap: wrap; justify-content: center; }
}

/* ---------- Small phones (iPhone 13+, Android 360-430) ---------- */
@media (max-width: 400px) {
  .nav { gap: 0; padding: 6px; }
  .nav a { padding: 10px 12px; font-size: 13px; }
}
@media (max-width: 480px) {
  .about-intro { padding-top: 96px; }
  .cs-header { padding-top: 96px; }
  .home-bio p { text-align: left; }
  .selected-work { padding-top: var(--xxl); }
  .work-cards { flex-direction: column; }
  .reviews { padding: var(--sm); gap: var(--sm); scroll-padding: 0 var(--sm); }
  .reviews .review { max-width: 88vw; }
  .recs { padding: var(--l) var(--sm); }
  .contact-anchor { padding: var(--l) var(--sm); }
  .footer { width: calc(100% - 32px); margin: 0 auto; padding: var(--ml) 0 var(--l); }
  .footer-margin { padding-top: var(--l) !important; }
  .exp-row { font-size: 15px; }
  .cs-grid { padding: var(--l) var(--sm); }
  .cs-row { flex-direction: column; }
}
