/* ===========================================================
   Cyril Wochok / Experience Map — styles
   =========================================================== */

:root {
  --gray: #8e8e93;
  --dark: #42464e;
  --black: #000000;
  --white: #ffffff;
  --pill-bg: rgba(66, 70, 78, 0.2);
  --nav-w: 64px;
  /* Card width is the viewport minus the nav column, not the full
     100vw — otherwise the card is wider than the space actually
     left of it, and its right-hand content (the photo's own 16px
     padding included) gets pushed past the browser window's right
     edge instead of landing flush with it. */
  --card-w: calc(100vw - var(--nav-w));
  --card-gap: 0px;
  --header-h: 128px;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Helvetica, Arial, sans-serif;
  --happy: #34c759;
  --meh: #5ac8fa;
  --sad: #ff3b30;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--white);
  color: var(--black);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-x: none;
}

body { min-height: 100vh; }

img { display: block; max-width: none; }

button { font-family: inherit; cursor: pointer; }

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

/* ---------------- Header ---------------- */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  height: var(--header-h);
  padding: 24px 24px 0 calc(var(--nav-w) + 16px);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  background: linear-gradient(to bottom, rgba(255,255,255,0.96) 76%, rgba(255,255,255,0));
  pointer-events: none;
}

.site-header .header-rule {
  height: 9px;
  width: 100%;
  background: var(--dark);
  margin-bottom: 14px;
  border-radius: 2px;
}

.site-header h1 {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.4px;
  color: var(--dark);
  max-width: 560px;
}

.resume-download {
  position: fixed;
  top: 20px;
  left: 4px;
  z-index: 60;
  width: 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  color: var(--black);
  pointer-events: auto;
}

.resume-download img { width: 17px; height: auto; }

.resume-download span {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: -0.2px;
}

/* ---------------- Left Nav ---------------- */
/* Nav sits below the header (matches Figma: Header ends, Left Nav
   begins immediately after) so it never covers the resume link or
   any header content. */

.left-nav {
  /* purely the translucent backdrop-blur panel — Faces, Stories and
     Skills are all independently fixed-positioned (below) and
     synced by script.js to specific rows in the first project
     card, so the panel itself carries no layout content. */
  position: fixed;
  top: var(--header-h);
  left: 0;
  bottom: 0;
  width: var(--nav-w);
  z-index: 50;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-right: 1px solid rgba(66, 70, 78, 0.12);
}

.mood-faces {
  position: fixed;
  top: 0;
  left: 0;
  width: var(--nav-w);
  height: 100vh;
  z-index: 51;
  pointer-events: none;
}

.mood-faces img {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 22px;
  height: 22px;
  /* JS sets each icon's exact top to line up with the journey-map
     band in the first project card; these are sane fallbacks
     before that measurement runs. */
}

.mood-faces img:nth-child(1) { top: calc(var(--header-h) + 118px); }
.mood-faces img:nth-child(2) { top: calc(var(--header-h) + 198px); }
.mood-faces img:nth-child(3) { top: calc(var(--header-h) + 278px); }

.nav-item {
  position: fixed;
  left: 0;
  width: var(--nav-w);
  z-index: 52;
  padding: 10px 8px 0;
  border-top: 1px solid rgba(66, 70, 78, 0.35);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--black);
  box-sizing: border-box;
  /* JS sets each item's exact top to line up with that project's
     Tasks ("Stories") or Skills row; these are sane fallbacks. */
}

.nav-item[data-nav="stories"] { top: calc(var(--header-h) + 560px); }
.nav-item[data-nav="skills"] { top: calc(var(--header-h) + 760px); }

.nav-item img { width: 19px; height: auto; opacity: 0.55; }

.nav-item span {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: -0.2px;
  text-align: center;
}

/* ---------------- Arrows ---------------- */

.rail-arrow {
  position: fixed;
  top: calc(var(--header-h) + 8px);
  z-index: 45;
  width: 40px;
  height: 40px;
  border-radius: 16px;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  color: var(--black);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.rail-arrow:disabled { opacity: 0.35; pointer-events: none; }
.rail-arrow:active { transform: scale(0.92); }
.rail-arrow svg { width: 18px; height: 18px; }

/* Sits centered on the left-nav column (near its top, above where
   the mood faces / Stories / Skills items are positioned) instead
   of past it, so it never overlaps a card's title. z-index has to
   clear the nav's own layers (panel 50, faces 51, nav items 52). */
.arrow-prev {
  left: calc((var(--nav-w) - 40px) / 2);
  z-index: 53;
}
.arrow-next { right: 16px; }

/* ---------------- Project rail ---------------- */

.rail-viewport {
  position: relative;
  padding-top: var(--header-h);
  min-height: 100vh;
}

/* The rail is a CSS grid, not flex: each project-card is a column,
   and every card shares the SAME seven row tracks (head, image,
   graph, rule, tasks, rule, skills) via "subgrid" below. A row
   track's height is always the tallest content any card puts in
   it, so e.g. every card's Tasks grid starts at the same Y — even
   though quote length (and therefore graph-section height) varies
   a lot from project to project. This is what makes the rows line
   up across cards instead of each card's sections drifting to
   whatever height its own content happens to need. */
.project-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--card-w);
  grid-template-rows: auto auto auto auto auto auto auto;
  align-items: start;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scroll-padding-left: var(--nav-w);
  padding-left: var(--nav-w);
  column-gap: var(--card-gap);
  scrollbar-width: none;
}

.project-rail::-webkit-scrollbar { display: none; }

/* No horizontal padding on the card itself, and --card-gap is 0 —
   cards butt up against each other edge to edge. The journey-band
   (line + dashed grid) and the project photo go all the way to
   those edges too, so they read as one continuous strip across the
   whole row with zero visual break between projects. Only the text
   sections (head, quotes, tasks, skills) get their own inner
   padding so copy doesn't touch the seam. */
.project-card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: 1 / span 7;
  row-gap: 0;
  scroll-snap-align: start;
  width: 100%;
  padding: 0 0 64px;
  box-sizing: border-box;
}

.project-card .product-head {
  padding: 6px 16px 24px;
}

.project-card .product-head .eyebrow {
  font-size: 12px;
  color: var(--gray);
  margin: 0 0 8px;
}

.project-card .product-head h2 {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.18px;
  margin: 0;
}

.project-image-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 16px;
}

.project-image {
  position: relative;
  width: 100%;
  aspect-ratio: 312 / 176;
  border-radius: 16px;
  overflow: hidden;
  background: #d9d9d9;
}

.project-image img { width: 100%; height: 100%; object-fit: cover; }

/* "View Case Study" floats over the image, bottom-right corner. */
.case-study-btn {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 2;
  border: none;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 510;
  color: var(--black);
}

.case-study-btn:hover { background: var(--black); color: var(--white); }

/* ---------------- Sentiment / journey-map section ----------------
   .graph-section is a fixed 296px-tall positioning frame — the same
   296px-tall reference frame the source design (Figma node
   308-47593) uses for every project card. Both the journey-band
   (line + dashed grid) and the quote blocks are absolutely
   positioned within it using the exact top/left/width/height values
   from that design, so quotes land at precisely the same spot
   relative to the line as in Figma. Horizontal placement (left/
   right/width) is expressed in %, so it scales with the responsive
   card width; vertical placement (top/height/padding) is expressed
   in px, matching the fixed-height treatment already used for the
   journey-band itself. */

.graph-section {
  position: relative;
  margin-top: 8px;
  height: 296px;
}

/* Full-bleed, square corners, no side margin — this is what lets
   the dashed grid + colored line run edge to edge into the next
   card with zero gap or rounded-corner interruption at the seam. */
.journey-band {
  position: absolute;
  top: 81px;
  left: 0;
  width: 100%;
  height: 180px;
  overflow: hidden;
}

.journey-band .band-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0.9;
}

.journey-band .graph-line {
  position: absolute;
  display: block;
  opacity: 0.98;
}

/* Each project's line only occupies part of the 344x180 reference
   band in the source design — that's intentional: it's how one
   project's curve lines up with the next project's curve at the
   shared card edge, so the journey reads as continuous across the
   whole row instead of five independent charts. EGM is the first
   card so its line starts inset from the left edge; AA is the last
   card so its line stops short of the right edge; the three middle
   projects run full-bleed left-to-right so they connect on both
   sides.

   NOTE: <img> is a replaced element — giving it "inset" with
   width/height:auto does NOT stretch it to that box (it falls back
   to intrinsic size and silently ignores the crop). top/left/width/
   height must be set explicitly so the browser actually scales the
   image to fill the exact region.

   Recomputed from the latest reworked "Stroke" line assets (Figma
   node 308-47593). In this revision the "Horizontal Lines" band box
   and the "Graph" (line) box now share the same frame (both 180px
   tall, top-aligned to the same point) — so .journey-band's height
   was bumped from 160px to 180px to match, and each project's
   composed inset(outer)/inset(inner) crop applies directly with no
   extra offset conversion needed. */
.graph-line.gl-egm    { top: 2.22%;  left: 12.72%; width: 87.28%; height: 70.23%; }
.graph-line.gl-sonic  { top: 4.49%;  left: 0;      width: 100%;   height: 68.48%; }
.graph-line.gl-swa    { top: 13.45%; left: 0;      width: 100%;   height: 81.89%; }
.graph-line.gl-gilead { top: 5.73%;  left: 0;      width: 100%;   height: 64.76%; }
.graph-line.gl-aa     { top: 2.22%;  left: 0;      width: 86.21%; height: 84.97%; }

/* quote-block: absolutely positioned within .graph-section using
   the exact box (top/left/right/height + padding) that each quote
   occupies in the source design, so the quote lands at the same
   spot relative to the journey line as in Figma. Each project gets
   its own modifier class (below) carrying that project's specific
   box; this shared class carries the parts that are the same for
   every quote — the flex layout plumbing and the type styles.
   Per explicit instruction: attribution is bold, body copy is
   regular weight (the source design uses a medium weight for the
   body; this intentionally overrides that). */
.quote-block {
  position: absolute;
  display: flex;
  font-size: 9px;
  line-height: 1.5;
}

.quote-block .quote-attr { font-weight: 700; margin: 0 0 4px; }
.quote-block .quote-body { font-weight: 400; margin: 0; }

.quote-block .quote-spacer { flex: 0 0 8px; }

/* connector: a line running from the quote text down to a dot that
   touches the journey band at a specific point on the curve */
.quote-block .quote-marker {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.quote-block .quote-connector {
  width: 1px;
  min-height: 8px;
  flex: 1 1 auto;
  background: var(--dark);
  opacity: 0.55;
}

.quote-block .quote-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 0 0 1px rgba(66, 70, 78, 0.4), 0 2px 6px rgba(0, 0, 0, 0.25);
  flex-shrink: 0;
}

/* ---- per-project boxes, matching Figma node 308-47593 exactly ---- */

/* EGM has two quotes: Miller (bottom-anchored, spans the full
   width, centered) and Linneman (top-anchored, narrower left-hand
   column, left-aligned). */
.qb-egm-1 {
  top: 20.87px;
  height: 207px;
  left: 0;
  right: 0;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding: 0 4.65% 6px 33.72%;
  text-align: center;
}
.qb-egm-1 .quote-marker { padding-right: 6.98%; }

.qb-egm-2 {
  top: 27.87px;
  height: 247px;
  left: 4.65%;
  right: 48.55%;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding-top: 82px;
  text-align: left;
}
.qb-egm-2 .quote-marker { padding-left: 9.3%; }

/* Sonic: single quote, laid out as a row — text right-aligned on
   the left, connector + dot on the right — vertically centered on
   the band. */
.qb-sonic {
  top: 20.87px;
  height: 207px;
  left: 29.07%;
  right: 4.65%;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
}
.qb-sonic .quote-text { text-align: right; width: 39.53%; flex: 0 0 auto; }
.qb-sonic .quote-spacer { flex: 0 0 8px; width: 8px; }
.qb-sonic .quote-marker { flex-direction: column; justify-content: flex-end; height: 100%; }

/* Southwest: single quote, bottom-anchored, right-aligned. */
.qb-swa {
  top: 20.87px;
  height: 207px;
  left: 33.43%;
  right: 4.65%;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding-bottom: 78px;
  text-align: right;
}
.qb-swa .quote-marker { padding-left: 41.86%; }

/* Gilead: single quote, top-anchored, narrow centered column. */
.qb-gilead {
  top: 27.87px;
  height: 247px;
  left: 2.33%;
  right: 50.87%;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding-top: 56px;
  text-align: center;
}
.qb-gilead .quote-marker { padding-left: 23.26%; }

/* AA: single quote, top-anchored, narrow centered column. */
.qb-aa {
  top: 27.87px;
  height: 247px;
  left: 4.65%;
  right: 55.52%;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding-top: 48px;
  text-align: center;
}
.qb-aa .quote-marker { padding-right: 18.6%; }

/* divider */

.rule {
  height: 1px;
  background: var(--dark);
  opacity: 0.6;
  margin: 20px 16px;
}

/* tasks */

.tasks-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 16px;
}

.tasks-grid p {
  font-size: 9px;
  line-height: 1.5;
  margin: 0;
}

/* skills */

.skills-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 0 16px;
}

.skill-pill {
  background: var(--pill-bg);
  border-radius: 8px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  text-align: center;
}

.skill-pill span {
  font-size: 9px;
  line-height: 1.25;
  letter-spacing: -0.09px;
}

/* ---------------- Modals ---------------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(20, 20, 22, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  overflow-y: auto;
}

.modal-overlay.open { opacity: 1; pointer-events: auto; }

/* Video + image lightbox are short/fixed-height, so they read
   better vertically centered rather than pinned to the top like
   the long, scrolling case-study modal. */
.modal-overlay.modal-center {
  align-items: center;
}

.modal-panel {
  position: relative;
  background: var(--white);
  border-radius: 20px;
  width: 100%;
  max-width: 760px;
  padding: 40px 24px 48px;
  transform: translateY(12px);
  transition: transform 0.2s ease;
}

.modal-overlay.open .modal-panel { transform: translateY(0); }

.modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 5;
  width: 32px;
  height: 32px;
  border-radius: 16px;
  border: none;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(2px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-close svg { width: 16px; height: 16px; }

.case-product-head { padding-bottom: 8px; }
.case-product-head .eyebrow { font-size: 12px; color: var(--gray); margin: 0 0 6px; }
.case-product-head h2 { font-size: 24px; font-weight: 700; letter-spacing: -0.24px; margin: 0; }

.case-meta {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 0;
  flex-wrap: wrap;
}

.case-meta div { flex: 1 1 120px; }
.case-meta .label { font-size: 12px; color: var(--gray); margin: 0 0 2px; }
.case-meta .value { font-size: 16px; font-weight: 510; letter-spacing: -0.16px; margin: 0; }

.case-block { margin: 24px 0; }
.case-block .kicker { font-size: 12px; color: var(--gray); margin: 0 0 8px; font-weight: 400; }
.case-block h3 { font-size: 16px; font-weight: 700; margin: 0 0 8px; }
.case-block p { font-size: 16px; line-height: 1.5; margin: 0 0 8px; }
.case-block p:last-child { margin-bottom: 0; }
.case-block p.lede { font-weight: 700; }

.case-image {
  position: relative;
  border-radius: 24px;
  overflow: hidden;
  margin: 16px 0;
  background: #e5e5e5;
}

.case-image img { width: 100%; display: block; }

.view-video-btn {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 3;
  border: none;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(3px);
  border-radius: 16px;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 510;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.view-video-btn:hover { background: var(--black); color: var(--white); }
.view-video-btn svg { width: 12px; height: 12px; }

.expand-image-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 3;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--black);
}

.expand-image-btn:hover { background: var(--black); color: var(--white); }
.expand-image-btn svg { width: 17px; height: 17px; }

.image-panel {
  max-width: min(95vw, 1400px);
  padding: 0;
  background: transparent;
  box-shadow: none;
}

.image-panel .modal-close {
  background: rgba(0, 0, 0, 0.55);
  top: 16px;
  right: 16px;
}
.image-panel .modal-close svg { color: #fff; }

.image-lightbox {
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-lightbox img {
  max-width: 100%;
  max-height: 88vh;
  width: auto;
  height: auto;
  display: block;
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}

.video-panel {
  max-width: 900px;
  padding: 0;
  background: #000;
  overflow: hidden;
}

.video-panel .modal-close {
  background: rgba(0,0,0,0.6);
}
.video-panel .modal-close svg { color: #fff; }

.video-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16/9;
  background: #111;
  display: flex;
  align-items: center;
  justify-content: center;
}

.video-embed iframe,
.video-embed video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.video-placeholder {
  color: #aaa;
  font-size: 14px;
  text-align: center;
  padding: 24px;
}

/* ---------------- Responsive ---------------- */

@media (min-width: 720px) {
  :root {
    --nav-w: 84px;
    --card-w: 480px;
    --card-gap: 0px;
    --header-h: 120px;
  }

  .site-header { padding-left: calc(var(--nav-w) + 24px); }
  .site-header h1 { font-size: 28px; }

  .resume-download { top: 24px; left: 8px; width: 76px; }

  /* still no horizontal padding on the card itself — the photo and
     journey-band stay full-bleed at every breakpoint. Only the text
     sections get a little more breathing room on larger screens. */
  .project-card { padding: 0 0 80px; }
  .product-head { padding-left: 24px; padding-right: 24px; }
  .rule { margin-left: 24px; margin-right: 24px; }
  .tasks-grid { padding-left: 24px; padding-right: 24px; }
  .skills-grid { padding-left: 24px; padding-right: 24px; }

  .arrow-prev { left: calc((var(--nav-w) - 40px) / 2); }

  .tasks-grid p { font-size: 11px; }
  .quote-block { font-size: 11px; }
}

@media (min-width: 1100px) {
  :root {
    --card-w: 440px;
  }
  .project-rail { padding-right: 10vw; }
}

@media (min-width: 1440px) {
  :root {
    --nav-w: 96px;
    --card-w: 420px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .project-rail { scroll-behavior: auto; }
}
