/* ============================================
   DESIGN TOKENS
   ============================================ */
:root {
  --paper: #FFFFFF;
  --paper-dim: #F9FAFB;
  --ink: #181818;
  --ink-soft: #464646;
  --muted: #99A0AC;
  --line: #F3F4F6;
  --accent: #AB8B3E;
  --accent-ink: #FFFFFF;
  --nav-bg: rgba(255, 255, 255, 0.86);

  /* placeholder tint set — one per project, kept muted/desaturated */
  --tint-orbit: #C9D1E0;
  --tint-meridian: #D8D2C0;
  --tint-harbor: #C7D2C6;

  --font-display: 'Bricolage Grotesque', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, monospace;

  --measure: 68ch;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --nav-h: 4.5rem;

  /* spacing scale — the standard rhythm between a text block and the
     next content block (stat row, grid, list, gallery, color panel)
     within a section. One generous hero tier for the single big
     image moment near the top of each case study. */
  --space-block: clamp(3rem, 6vw, 6rem);   /* 48–96px */
  --space-hero: 8rem;                       /* 128px */
}

:root[data-theme="dark"] {
  --paper: #181818;
  --paper-dim: #1E1F22;
  --ink: #F3F2EC;
  --ink-soft: #C6C5BC;
  --muted: #8F8F86;
  --line: #34353A;
  --accent: #E6B84F;
  --accent-ink: #0E0F12;
  --nav-bg: rgba(22, 23, 26, 0.86);
}

/* ============================================
   RESET
   ============================================ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.25s ease, color 0.25s ease;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p { margin: 0; }
::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ============================================
   REVEAL — a generic "comes into focus" entrance:
   soft blur + a slight rise, sharpening to rest as
   the element crosses into view. Add .reveal to any
   heading, paragraph, or image; toggled once by an
   IntersectionObserver in script.js, same trigger
   point as the rest of the site's scroll reveals.
   ============================================ */
.reveal {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(28px);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.is-visible {
  opacity: 1;
  filter: none;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    filter: none;
    transform: none;
    transition: none;
  }
}

/* A heading's .body-text siblings reveal together with it, as one block,
   rather than each staggering in on its own separate scroll trigger —
   only the heading is observed; its paragraphs just ride along. */
.section-head-stacked.reveal ~ .body-text {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(28px);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.section-head-stacked.reveal.is-visible ~ .body-text {
  opacity: 1;
  filter: none;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .section-head-stacked.reveal ~ .body-text {
    opacity: 1;
    filter: none;
    transform: none;
    transition: none;
  }
}

/* ============================================
   GUIDED — opt-in via <body class="guided">. Faint
   column guides (solid at the container edges,
   dashed at the quarter marks) run down every
   section, and every other section sits on a light
   gray band that runs edge to edge. Modeled on
   Stripe's marketing pages.
   Guides live in a ::before behind the content, so
   nothing needs its own wrapper. Inside a band, the
   surface color used by panels/cards flips to white
   (or a lifted dark) so they still read against it.
   ============================================ */
.guided {
  --guide-solid: #EEEEF2;
  --guide-dash: #EEEEF2;
  --band: #F9F9FA;
  --dash: repeating-linear-gradient(to bottom, var(--guide-dash) 0 4px, transparent 4px 8px);
  /* one vertical rhythm: section padding, and the space between a
     section's text and its first images */
  --section-pad: clamp(5rem, 12vw, 9rem);
}
:root[data-theme="dark"] .guided {
  --guide-solid: rgba(255, 255, 255, 0.08);
  --guide-dash: rgba(255, 255, 255, 0.11);
  --band: #1E1F22;
}
.guided :is(.section, .case-hero, .hero, .work, .about) {
  position: relative;
  isolation: isolate;
}
/* Twice the standard section padding, so each band has room to breathe. */
.guided .section {
  padding-top: var(--section-pad);
  padding-bottom: var(--section-pad);
}
/* The gap from a section's text down to its first images matches the gap
   from those images to the next section. */
.guided .grid-shots,
.guided .journey-panels {
  margin-top: var(--section-pad);
}
/* A gallery with no heading above it (e.g. a flat image dump right after
   the hero) skips that gap — the section's own padding is enough. */
.guided .journey-panels.flush-top {
  margin-top: 0;
}
/* A section that ends on a full-bleed image lets the image run to its
   edge instead of leaving a white gap under it. */
.guided .section:has(> .full-bleed-img:last-child) {
  padding-bottom: 0;
}
/* The last section's own bottom padding already provides the space, so
   the next-project block doesn't add its own margin on top of it. */
.guided .next-project {
  margin-top: 0;
}
.guided :is(.section, .case-hero, .hero, .work, .about)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--guide-solid), var(--guide-solid)),
    linear-gradient(var(--guide-solid), var(--guide-solid)),
    var(--dash), var(--dash), var(--dash);
  background-size: 1px 100%;
  background-repeat: no-repeat;
  /* One grid: the content box (the wrap minus its gutters) is split into
     four exactly equal columns, so the dashed lines sit at its quarters.
     The two solid lines are a frame half a gutter outside the content. */
  /* (the sub-pixel terms undo CSS resolving % against width minus the
     1px line, so the quarters are exact) */
  background-position:
    calc(var(--gutter) / 2) 0,
    calc(100% - var(--gutter) / 2) 0,
    calc(25% + var(--gutter) / 2 + 0.25px) 0,
    calc(50% + 0.5px) 0,
    calc(75% - var(--gutter) / 2 + 0.75px) 0;
}
@media (max-width: 900px) {
  .guided :is(.section, .case-hero, .hero, .work, .about)::before {
    background-size: 1px 100%, 1px 100%, 0 0, 1px 100%, 0 0;
  }
}
.guided :is(.section, .work, .about):nth-of-type(even) {
  background: var(--band);
  box-shadow: 0 0 0 100vmax var(--band);
  clip-path: inset(0 -100vmax);
  --paper-dim: #FFFFFF;
  --line: #E4E6EB;
}
:root[data-theme="dark"] .guided :is(.section, .work, .about):nth-of-type(even) {
  --paper-dim: #26272B;
}

/* ============================================
   LAYOUT PRIMITIVES
   ============================================ */
.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ============================================
   NAV
   ============================================ */
.site-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: var(--nav-bg);
  backdrop-filter: blur(8px);
  transition: background-color 0.25s ease;
}
.site-nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.nav-right {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 3vw, 1.75rem);
}
.nav-icons {
  display: flex;
  align-items: center;
  gap: 1.05rem;
}
.nav-icons a,
.nav-icons button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 19px;
  padding: 0;
  color: var(--ink-soft);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}
.nav-icons a:hover,
.nav-icons button:hover { color: var(--accent); }
.nav-icons svg { width: 100%; height: 100%; display: block; }

/* Back to top — sits in the nav where the dark-mode toggle used to live;
   hidden until the page has scrolled, so the nav isn't cluttered at rest. */
.nav-icons .back-to-top {
  opacity: 0;
  transform: translateY(-10px) scale(0.7);
  pointer-events: none;
  transition: opacity 0.25s ease,
              transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
              color 0.2s ease;
}
.back-to-top.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
@media (prefers-reduced-motion: reduce) {
  .nav-icons .back-to-top { transition: opacity 0.2s ease, color 0.2s ease; transform: none; }
}
.site-nav .logo {
  font-family: var(--font-display);
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  font-weight: 600;
}
.site-nav .nav-links {
  display: flex;
  gap: 2rem;
  align-items: center;
}
.site-nav .nav-links a {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  position: relative;
}
.site-nav .nav-links a.contact {
  color: var(--ink);
  transition: color 0.2s ease;
}
.site-nav .nav-links a.contact:hover {
  color: var(--accent);
}

/* ============================================
   HOMEPAGE — HERO
   ============================================ */
.hero {
  padding-top: clamp(3.5rem, 10vw, 8rem);
  padding-bottom: clamp(2.5rem, 6vw, 4rem);
}
.hero .eyebrow { margin-bottom: 1.25rem; }
.hero h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.8rem, 8.5vw, 6.4rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
  max-width: 15ch;
}
.hero .sub,
.case-hero .sub {
  margin-top: 3rem;
  max-width: 58ch;
  font-size: 1.05rem;
  color: var(--ink-soft);
}
.hero .sub + .sub {
  margin-top: 1.25rem;
}
.hero .sub a,
.case-hero .sub a {
  border-bottom: 1px solid var(--muted);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.hero .sub a:hover,
.case-hero .sub a:hover {
  color: var(--accent);
  border-color: var(--accent);
}


/* ============================================
   HOMEPAGE — WORK LIST
   ============================================ */
.work {
  position: relative;
}
.work .eyebrow { margin-bottom: 1.1rem; }
.work-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: clamp(1.5rem, 4vw, 2.5rem) 0;
  border-bottom: 1px solid var(--line);
  transition: opacity 0.25s ease;
}
.work-list:hover .work-row { opacity: 0.4; }
.work-list .work-row:hover { opacity: 1; }
/* No trailing line after the last row — the next section's band color
   already marks the end of the list, so the hairline is redundant. */
.work-row:last-child { border-bottom: none; }

.work-row .title {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 6.5vw, 4.25rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  transition: color 0.2s ease;
}
.work-row:hover .title { color: var(--accent); }

.work-row .meta {
  display: flex;
  gap: 1.75rem;
  flex-shrink: 0;
}
.work-row .meta span {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
  letter-spacing: 0.03em;
}
@media (max-width: 560px) {
  /* let the role/years wrap under the title instead of pushing the page wider */
  .work-row > a { flex-wrap: wrap; row-gap: 0.4rem; }
}

/* ============================================
   ABOUT ME
   ============================================ */
.about {
  padding-top: clamp(3rem, 8vw, 5.5rem);
  padding-bottom: clamp(6rem, 15vw, 9rem);
}
.about .eyebrow { margin-bottom: 1.1rem; }
.about-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 5vw, 3.25rem);
  letter-spacing: -0.015em;
  line-height: 1.05;
  max-width: 16ch;
  margin: 0 0 clamp(1.75rem, 4vw, 2.5rem);
}

.about-text {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  width: 100%;
  margin-bottom: clamp(3rem, 7vw, 5rem);
}
.about-text p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 1.02rem;
}
@media (max-width: 680px) {
  .about-text { grid-template-columns: 1fr; }
}

/* ---- Photo + copy split (trial layout) ---- */
.about-split {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: center;
}
.about-photo img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 28px;
}
.about-copy p:not(.eyebrow) {
  margin: 0;
  color: var(--ink-soft);
  font-size: 1.02rem;
}
.about-copy p:not(.eyebrow) + p:not(.eyebrow) {
  margin-top: 1.25rem;
}
@media (max-width: 680px) {
  .about-split { grid-template-columns: 1fr; gap: 2rem; }
}

/* ---- Collage ---- */
.collage {
  position: relative;
  width: 100%;
  max-width: 720px;
  aspect-ratio: 1229 / 916.7;
  margin: 0 auto;
}
.collage-item {
  position: absolute;
  cursor: pointer;
  transition: transform 0.35s ease, z-index 0s;
  will-change: transform;
}
/* The photos already have rounded corners baked into the PNG's own
   transparency (each item's box matches its source image's aspect ratio,
   so object-fit: cover isn't actually cropping anything). A drop-shadow
   filter reads that real alpha silhouette, so the shadow always matches
   the photo's actual rounded edge — a box-shadow paired with a guessed
   CSS border-radius left a faint gap wherever the guess was even a pixel
   or two off. Filter isn't in the transition list, so hover swaps it
   instantly rather than animating it frame by frame; only the scale-up
   is actually animated. */
.collage-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: drop-shadow(0 14px 26px rgba(23, 24, 28, 0.20));
}

.item-1 { left: 0%;    top: 0%;    width: 69.7%; height: 88.1%; z-index: 1; }
.item-2 { left: 60%;   top: 15.6%; width: 40%;   height: 52.1%; z-index: 2; }
.item-3 { left: 38%;   top: 54.3%; width: 44.6%; height: 45.7%; z-index: 3; }

/* Hovering an individual photo brings it to the front, enlarges it slightly,
   and deepens its shadow — the others stay put. */
.collage-item:hover {
  transform: scale(1.05);
  z-index: 10 !important;
}
.collage-item:hover img {
  filter: drop-shadow(0 26px 44px rgba(23, 24, 28, 0.32));
}

@media (prefers-reduced-motion: reduce) {
  .collage-item { transition: none; }
}
@media (max-width: 680px) {
  .collage { aspect-ratio: auto; position: static; display: grid; grid-template-columns: repeat(1, 1fr); gap: 0.9rem; }
  .collage-item { position: static; width: auto !important; height: 220px !important; transform: none !important; top: auto; }
  .collage-item:hover { transform: none !important; }
  .collage-item:hover img { filter: drop-shadow(0 14px 26px rgba(23, 24, 28, 0.20)); }
}

/* ============================================
   FOOTER — reveal-from-behind. The footer is
   position:fixed to the viewport bottom, permanently,
   sitting BEHIND the main content (negative z-index).
   The main content wrapper (.page-content) is opaque
   and reserves extra scroll space via margin-bottom
   equal to the footer's height (kept in sync by JS),
   so the footer stays completely hidden until the
   content's own bottom edge scrolls up past the
   viewport, opening a gap that reveals the footer
   underneath. Colors are inverted (bg: --ink, text:
   --paper) so it stays correctly contrasted in both
   light and dark mode automatically.
   ============================================ */
.page-content {
  position: relative;
  z-index: 1;
  background: var(--paper);
  transition: background-color 0.25s ease;
}
.site-footer {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  z-index: -1;
  background: var(--ink);
  color: var(--paper);
  padding-top: clamp(5rem, 11vw, 8rem);
  padding-bottom: clamp(3rem, 6vw, 4.5rem);
  transition: background-color 0.25s ease, color 0.25s ease;
}
.site-footer .foot-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.site-footer h2 {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 6.5vw, 4rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.015em;
  max-width: 16ch;
  color: var(--paper);
}
.site-footer .foot-email {
  font-family: var(--font-mono);
  font-size: clamp(0.85rem, 1.6vw, 1rem);
  color: var(--paper);
  border-bottom: 1px solid color-mix(in srgb, var(--paper) 35%, transparent);
  padding-bottom: 0.2em;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.site-footer .foot-email:hover {
  color: var(--accent);
  border-color: var(--accent);
}
.site-footer .foot-links {
  display: flex;
  gap: 1.75rem;
}
.site-footer .foot-links a {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--paper) 60%, transparent);
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.site-footer .foot-links a:hover {
  color: var(--accent);
  border-color: var(--accent);
}
.site-footer .foot-bottom {
  margin-top: clamp(3.5rem, 8vw, 6rem);
  display: flex;
  justify-content: space-between;
  color: color-mix(in srgb, var(--paper) 45%, transparent);
  font-family: var(--font-mono);
  font-size: 0.72rem;
}

/* ============================================
   CASE STUDY — HERO / META STRIP
   ============================================ */
.case-hero {
  padding-top: clamp(2.5rem, 6vw, 4.5rem);
}
.back-link {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  margin-bottom: 2.5rem;
  transition: color 0.2s ease;
}
.back-link:hover { color: var(--accent); }

.case-hero h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.8rem, 8.5vw, 6.4rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
  max-width: 16ch;
}

.meta-strip {
  margin-top: clamp(2rem, 5vw, 3rem);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.meta-strip div {
  padding: 1.1rem var(--gutter) 1.1rem 2rem;
  border-left: 1px solid var(--line);
}
.meta-strip div:first-child { border-left: none; padding-left: 0; }
.meta-strip .label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.meta-strip .value {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--ink);
}

@media (max-width: 720px) {
  .meta-strip { grid-template-columns: repeat(2, 1fr); }
  .meta-strip div:nth-child(3) { border-left: none; padding-left: 0; }
}

/* Guided pages: no vertical dividers or horizontal rules. The strip fills
   the content box, so its four equal columns start exactly on the dashed
   guides (the quarters of the content box). Every cell's text sits half a
   gutter to the right of the guide on its left — the first cell's guide is
   the solid frame line, which is why it needs no padding of its own and
   lines up with the rest of the page's text. */
.guided .meta-strip {
  margin-top: clamp(2.25rem, 4vw, 3.5rem);
  border-top: none;
  border-bottom: none;
}
.guided .meta-strip div {
  padding: 1.1rem calc(var(--gutter) / 2);
  border-left: none;
}
.guided .meta-strip div:first-child { padding-left: 0; }
@media (max-width: 720px) {
  .guided .meta-strip div:nth-child(3) { padding-left: 0; }
}
/* Stat rows are always 2 or 3 items, never 4 — a 4-up row of big numbers
   reads as noise. They still live on the same four quarter-columns as
   everything else, though: with 2 or 3 items the row just fills that many
   quarters left to right and leaves the rest of the row empty, the same
   way a short journey-panels row or an understocked screen-grid would,
   rather than stretching to fill the whole width. */
.guided .stat-row {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
}
.guided .stat-row > .stat { padding-left: calc(var(--gutter) / 2); padding-right: 0; }
.guided .stat-row > .stat:first-child { padding-left: 0; }
/* Bite-size points: two columns (two or four points), like Stripe's
   feature grids — starting on the solid frame line and the center guide. */
.guided .bite-grid {
  grid-template-columns: repeat(2, 1fr);
  gap: 3rem 0;
}
.guided .bite-grid > .bite { padding-left: 0; padding-right: 2rem; }
.guided .bite-grid > .bite:nth-child(even) { padding-left: calc(var(--gutter) / 2); }
.guided .bite-grid > .bite::before { content: none; }
.guided .bite h3 { position: relative; }
.guided .bite h3::before {
  content: "";
  position: absolute;
  left: calc(var(--gutter) / -2 - 0.5px);
  top: 0.1em;
  width: 2px;
  height: 1.15em;
  background: var(--accent);
}
@media (max-width: 900px) {
  .guided .stat-row {
    grid-template-columns: repeat(2, 1fr);
    row-gap: 2.5rem;
  }
  .guided .stat-row > .stat:nth-child(odd) { padding-left: 0; }
  .guided .stat-row > .stat:nth-child(even) { padding-left: calc(var(--gutter) / 2); }
}
@media (max-width: 560px) {
  .guided .stat-row,
  .guided .bite-grid { grid-template-columns: 1fr; }
  .guided .stat-row > .stat,
  .guided .stat-row > .stat:nth-child(even),
  .guided .bite-grid > .bite,
  .guided .bite-grid > .bite:nth-child(even) { padding-left: 0; padding-right: 0; }
}

/* Homepage: the work list gets breathing room before the about band, and
   the about band takes the same generous padding as a case-study section. */
.guided .work { padding-bottom: calc(var(--section-pad) / 2); }
.guided .about {
  padding-top: var(--section-pad);
  padding-bottom: var(--section-pad);
}
/* The two about paragraphs are a two-column row on the grid: the first
   starts on the frame line, the second on the center guide. */
.guided .about-text { gap: 0; }
.guided .about-text > p:first-child { padding-right: 2rem; }
.guided .about-text > p:last-child { padding-left: calc(var(--gutter) / 2); }
@media (max-width: 680px) {
  .guided .about-text { row-gap: 1.5rem; }
  .guided .about-text > p:first-child,
  .guided .about-text > p:last-child { padding-left: 0; padding-right: 0; }
}

/* Sprint / pillar columns: four equal columns on the grid (two on narrow
   screens), text half a gutter right of each guide, with the same short
   accent tick on the title as the bite-size points. */
/* Each column is a subgrid spanning its own rows (title, optional date,
   list), so titles that wrap to two lines don't push their list out of line
   with the neighboring columns. */
.guided .sprint-grid {
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.guided .sprint-grid > .sprint {
  padding-left: calc(var(--gutter) / 2);
  padding-right: 1.5rem;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 2;
  align-content: start;
}
.guided .sprint-grid > .sprint:has(.date) { grid-row: span 3; }
.guided .sprint-grid > .sprint:first-child { padding-left: 0; }
@media (max-width: 900px) {
  .guided .sprint-grid { grid-template-columns: repeat(2, 1fr); }
  .guided .sprint-grid > .sprint { padding-bottom: 3rem; }
  .guided .sprint-grid > .sprint:nth-child(odd) { padding-left: 0; }
  .guided .sprint-grid > .sprint:nth-child(even) { padding-left: calc(var(--gutter) / 2); }
}
@media (max-width: 560px) {
  .guided .sprint-grid { grid-template-columns: 1fr; }
  .guided .sprint-grid > .sprint:nth-child(n),
  .guided .sprint-grid > .sprint:has(.date) {
    display: block;
    grid-row: auto;
    padding: 0 0 2.5rem;
  }
}

/* Screen grids: four across, each item centered in its guide column with
   half a gutter either side (two across on narrow screens). */
.guided .screen-grid {
  grid-template-columns: repeat(4, 1fr);
  column-gap: var(--gutter);
  row-gap: var(--section-pad);
  padding: 0 calc(var(--gutter) / 2);
  margin-top: var(--section-pad);
}
@media (max-width: 900px) {
  .guided .screen-grid { grid-template-columns: repeat(2, 1fr); row-gap: 3rem; }
}

/* Two-up split (text beside an image): the halves meet at the center guide. */
@media (min-width: 761px) {
  .guided .split { column-gap: var(--gutter); }
}

/* Numbered work items: the same rhythm as top-level sections — each item
   gets the full --section-pad above and below (not half), so the gap
   between two work items matches the gap between two top-level sections
   instead of reading tighter. */
.guided .journey-list li { padding: var(--section-pad) 0; }
.guided .journey-list li:first-child { padding-top: 0; }
.guided .journey-list li:last-child { padding-bottom: 0; }
/* Several work items share one long section (so the progress rail reads
   as one continuous piece of work), which otherwise leaves them all on a
   single, unbroken background — the alternating rhythm the rest of the
   page has stops the moment a section runs long. Every other item gets
   its own band, picking up the section-level rhythm one level down: its
   own bleed-to-edge fill, and its own copy of the guide lines (its
   background would otherwise paint over the section's guides, which sit
   behind normal content but in front of the section's own background). */
.guided .journey-list li:nth-child(even) {
  position: relative;
  isolation: isolate;
  background: var(--band);
  box-shadow: 0 0 0 100vmax var(--band);
  clip-path: inset(0 -100vmax);
  --paper-dim: #FFFFFF;
  --line: #E4E6EB;
}
:root[data-theme="dark"] .guided .journey-list li:nth-child(even) {
  --paper-dim: #26272B;
}
.guided .journey-list li:nth-child(even)::before {
  content: "";
  position: absolute;
  /* Unlike .section, the <li> carries no gutter padding of its own — its
     edges sit flush with the section's content box, one gutter in from
     where the section measures its guides. Reaching a gutter past the
     li's own left/right edges puts this pseudo's box back to exactly the
     section's own width, so the same position formulas below land on the
     same absolute pixels as the section's guides instead of drifting a
     full gutter inward. */
  left: calc(-1 * var(--gutter));
  right: calc(-1 * var(--gutter));
  top: 0;
  bottom: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--guide-solid), var(--guide-solid)),
    linear-gradient(var(--guide-solid), var(--guide-solid)),
    var(--dash), var(--dash), var(--dash);
  background-size: 1px 100%;
  background-repeat: no-repeat;
  background-position:
    calc(var(--gutter) / 2) 0,
    calc(100% - var(--gutter) / 2) 0,
    calc(25% + var(--gutter) / 2 + 0.25px) 0,
    calc(50% + 0.5px) 0,
    calc(75% - var(--gutter) / 2 + 0.75px) 0;
}
@media (max-width: 900px) {
  .guided .journey-list li:nth-child(even)::before {
    background-size: 1px 100%, 1px 100%, 0 0, 1px 100%, 0 0;
  }
}

/* ============================================
   CASE STUDY — PLACEHOLDER IMAGE BLOCKS
   ============================================ */
.ph {
  background: var(--ph-color, var(--paper-dim));
  border: 1px solid var(--line);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  min-height: 260px;
  overflow: hidden;
  position: relative;
}
.ph.tall { min-height: 420px; }
.ph img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ph:has(img) {
  background: none;
  border: none;
}
.ph.tall:has(img) {
  aspect-ratio: 16 / 9;
  min-height: 0;
  height: auto;
}
.ph .ph-label,
.ph .ph-dims {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: rgba(23, 24, 28, 0.4);
}

.section {
  padding-top: clamp(2.5rem, 6vw, 4.5rem);
  padding-bottom: clamp(2.5rem, 6vw, 4.5rem);
}
.section-head {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}
.section-head .num {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--muted);
}
.section-head h2 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.5vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* stacked variant — small "01 Category" eyebrow line, then a large
   title below it on its own line, rather than num + h2 inline */
.section-head-stacked {
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}
.eyebrow-num {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 0.75rem;
}
.section-head-stacked h2 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.5vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

.section .body-text {
  max-width: var(--measure);
  color: var(--ink-soft);
  font-size: 1.02rem;
}
.section .body-text + .body-text { margin-top: 1.1rem; }

/* standalone subsection heading — same weight as .sprint-grid h3,
   for splitting one section into a couple of named parts */
.subhead {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 3vw, 1.65rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
  margin-top: var(--space-block);
}
.subhead + .body-text { margin-top: 0.85rem; }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
@media (max-width: 760px) {
  .split { grid-template-columns: 1fr; }
}
.split.reverse .ph { order: 2; }
@media (max-width: 760px) {
  .split.reverse .ph { order: 0; }
}

.stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-top: var(--space-block);
}
@media (max-width: 720px) {
  .stat-row { grid-template-columns: 1fr; }
}
/* A grid item won't shrink past its content's natural width by default,
   which is exactly backwards for a big bold number in a narrow column —
   it overflows into its neighbor instead of wrapping. min-width: 0 lets
   it actually respect the column; break-word gives it somewhere to go
   (a second line) if the number still doesn't fit at the smallest size. */
.stat-row > .stat { min-width: 0; }
.stat-row .stat .num {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6.5vw, 4rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--accent);
  overflow-wrap: break-word;
}
.stat-row .stat .label {
  margin-top: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
  letter-spacing: 0.04em;
}

/* Compare chart — a small horizontal-bar comparison for a handful of
   labeled percentages (e.g. close rate by cohort). Bars grow from 0 to
   their real width when the chart's .reveal enters view, riding the same
   generic observer as every other .reveal — each bar's target width is
   just a CSS custom property set inline per row. */
.compare-chart {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  max-width: var(--measure);
  margin-top: var(--space-block);
}
.compare-row {
  display: grid;
  grid-template-columns: 13rem 1fr 4.5rem;
  align-items: center;
  gap: 1rem;
}
.compare-label {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}
.compare-track {
  height: 10px;
  border-radius: 999px;
  background: var(--paper-dim);
  overflow: hidden;
}
.compare-fill {
  --fill: 0%;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 1.1s cubic-bezier(0.16, 1, 0.3, 1);
}
.compare-chart.is-visible .compare-fill {
  width: var(--fill);
}
.compare-value {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink);
  text-align: right;
}
@media (max-width: 640px) {
  .compare-row {
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }
  .compare-value { text-align: left; }
}

.sprint-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 3rem);
  margin-top: var(--space-block);
}
@media (max-width: 720px) {
  .sprint-grid { grid-template-columns: 1fr; gap: 2.5rem; }
}
.sprint-grid h3 {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 3vw, 1.65rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 0.4rem;
}
.sprint-grid .date {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 1.5rem;
}
.sprint-grid ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.sprint-grid li {
  font-size: 0.92rem;
  color: var(--ink-soft);
  padding-top: 0.9rem;
  margin-top: 0.9rem;
  border-top: 1px solid var(--line);
}
.sprint-grid li:first-child {
  padding-top: 0;
  margin-top: 0;
  border-top: none;
}

/* Chapter divider — marks the start of a distinct project on a long,
   multi-project page (e.g. project-rocket.html holding several
   initiatives). Bigger and bolder than a numbered section-head, so
   it reads as "a new project starts here," not just another section. */
.chapter-head {
  padding-top: clamp(4rem, 10vw, 7rem);
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}
.chapter-head .chapter-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1rem;
}
.chapter-head h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.2rem, 5.5vw, 3.5rem);
  letter-spacing: -0.015em;
  line-height: 1.05;
  max-width: 20ch;
  margin: 0;
}


.numbered-list {
  display: flex;
  flex-direction: column;
  gap: 2.25rem;
  margin-top: var(--space-block);
  max-width: var(--measure);
  list-style: none;
  padding: 0;
}
.numbered-list li {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2.1vw, 1.35rem);
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--ink);
}
.numbered-list .n {
  flex: none;
  width: 2.1rem;
  height: 2.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
}

/* ============================================
   PROBLEM GRID — four bordered cards, one per
   problem: a light icon badge, a short title, and
   a one-line specific consequence underneath.
   ============================================ */
.problem-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  margin-top: var(--space-block);
}
@media (max-width: 900px) {
  .problem-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .problem-grid { grid-template-columns: 1fr; }
}
.problem-card {
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 1.75rem;
  transition: border-color 0.3s ease,
              transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 0.3s ease;
}
/* Hover: the stroke fades out while the card lifts and picks up a soft
   shadow, and a numbered badge warms to the accent. Hover-capable
   pointers only, and no lift for reduced-motion. */
@media (hover: hover) {
  .problem-card:hover {
    border-color: transparent;
    transform: translateY(-4px);
    box-shadow: 0 14px 36px rgba(23, 24, 28, 0.09);
  }
  :root[data-theme="dark"] .problem-card:hover {
    box-shadow: 0 14px 36px rgba(0, 0, 0, 0.45);
  }
  .problem-card:hover .problem-num { color: var(--accent); }
}
@media (prefers-reduced-motion: reduce) {
  .problem-card:hover { transform: none; }
}
.problem-icon {
  width: 48px;
  height: 48px;
  margin-bottom: 3.5rem;
}
/* Numbered badge — stands in for .problem-icon when a card is a numbered
   item (01, 02, …) rather than an illustrated one. Same 48px footprint. */
.problem-num {
  width: 48px;
  height: 48px;
  margin-bottom: 3.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: var(--paper-dim);
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  transition: color 0.3s ease;
}
.problem-card h3 {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
  margin: 0 0 0.6rem;
}
.problem-card p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.92rem;
  line-height: 1.5;
}

/* ============================================
   BITE GRID — a paragraph broken into three short,
   scannable points: open columns (no boxes), each
   with a short accent tick, a mono number, a title,
   and a line or two of text.
   ============================================ */
.bite-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}
@media (max-width: 760px) {
  .bite-grid { grid-template-columns: 1fr; }
}
.bite::before {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  margin-bottom: 1.25rem;
  background: var(--accent);
}
.bite-num {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 1.5rem;
}
.bite h3 {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
  margin: 0 0 0.6rem;
}
.bite p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* BITE STACK — vertical variant of the bite grid: the same num +
   accent-bar heading, run top to bottom instead of side by side, for a
   short sequence of standalone points rather than a broken-up paragraph. */
.bite-stack {
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 4vw, 2.75rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}
.guided .bite-stack > .bite { padding-left: 0; }
.guided .bite-stack > .bite::before { content: none; }

/* ============================================
   GRID SHOTS — a row of individual phone screenshots, one per guide
   column (four across, two per row on narrow screens), no panel behind
   them. Each phone is centered in its column with half a gutter of space
   on either side, so the phones are all the same width, evenly spaced,
   and sit between the guide lines.
   ============================================ */
.grid-shots {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: 64px;
}
.grid-shot {
  margin: 0;
  padding: 0 calc(var(--gutter) / 2);
  position: relative;
  isolation: isolate;
}
/* A drop-shadow filter (not box-shadow) so the shadow always matches the
   phone's real silhouette exactly — the PNG's own rounded corners, which
   turned out to vary a pixel or two between images, so no single guessed
   border-radius could fit all of them without a visible gap on some.
   Just ONE drop-shadow layer, not three stacked: each stacked layer is a
   separate blur pass, and three of them across four full-height images is
   what was actually slow — a single layer costs the same as no filter at
   all. Filter isn't in the transition list, so hover swaps it instantly
   instead of animating it; only the lift (transform) is animated. */
.grid-shot img {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.09));
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
:root[data-theme="dark"] .grid-shot img {
  filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.4));
}
/* Reveal without the blur: four big images blurring at once as they enter
   view is the heaviest thing on the page. */
.grid-shot.reveal,
.grid-shot.reveal.is-visible {
  filter: none;
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .grid-shot img { will-change: transform; }
  /* Hover is read on the figure, which never moves — hovering the image
     itself lets it slide out from under the cursor and flicker at its edge. */
  .grid-shot:hover img {
    transform: translateY(-8px);
    filter: drop-shadow(0 22px 40px rgba(0, 0, 0, 0.12));
  }
  :root[data-theme="dark"] .grid-shot:hover img {
    filter: drop-shadow(0 22px 40px rgba(0, 0, 0, 0.48));
  }
}
@media (max-width: 900px) {
  .grid-shots { grid-template-columns: repeat(2, 1fr); row-gap: 3rem; }
}

/* ============================================
   JOURNEY LIST — the connected pieces of a body
   of work as an ordered arc: a mono phase label
   in the left rail, the piece name and one line
   of what it did on the right, hairline between.
   ============================================ */
.journey-list {
  list-style: none;
  padding: 0;
}
.journey-list li {
  padding: 64px 0;
}
.journey-list li:first-child {
  padding-top: 0;
}
.journey-list h3 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.5vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 clamp(1.5rem, 4vw, 2.5rem);
}
.journey-list p {
  margin: 0;
  color: var(--ink-soft);
  max-width: var(--measure);
  font-size: 1.02rem;
}

/* Journey shots — a small, curated set of screens under a journey-list
   item, always visible (no reveal interaction). Scrolls horizontally
   by touch/trackpad if it doesn't fit. */
.journey-shots {
  display: flex;
  gap: 64px;
  margin-top: 64px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.journey-shots::-webkit-scrollbar { display: none; }
.journey-shots img {
  height: 360px;
  width: auto;
  flex-shrink: 0;
  border-radius: 14px;
  filter: drop-shadow(0 10px 24px rgba(23, 24, 28, 0.14));
}

/* Journey panels — full-width exhibit shots stacked under a journey-list
   item, one per beat of the story. */
.journey-panels {
  display: flex;
  flex-direction: column;
  gap: 64px;
  margin-top: 64px;
}
.journey-panels img {
  width: 100%;
  height: auto;
  display: block;
}
/* A bare img as a direct child of .journey-panels (not wrapped in
   .journey-panel) is a self-contained shot — its own card and
   background baked into the file, just not the shadow, so it's added
   here the same way as .journey-panel's phone screens. */
.journey-panels > img,
.image-pair img {
  filter: drop-shadow(0 20px 40px rgba(23, 24, 28, 0.16));
}
/* .image-pair — two self-contained shots (their own card and
   background baked into the file) placed side by side inside
   .journey-panels, instead of one full-width image. Each stays its own
   .reveal so they blur in the same way as every other exhibit shot. */
.image-pair {
  display: flex;
  gap: 64px;
}
.image-pair img { flex: 1; min-width: 0; }
@media (max-width: 640px) {
  .image-pair { flex-direction: column; gap: 40px; }
}
/* .journey-panel (singular) — for a shot exported as just the screens on
   a transparent canvas, no shadow and no fill baked in. The panel
   (background + rounded corners + even padding) is drawn here instead,
   so it stays on-theme in dark mode; the shadow is a CSS filter on the
   image itself, kept off the padded wrapper so it can't clip into a
   seam (drop-shadow + border-radius + overflow-hidden on one element
   rasterizes a visible edge — see the video player fix earlier). */
.journey-panel {
  background: var(--paper-dim);
  border-radius: 28px;
  padding: clamp(2.5rem, 6vw, 5rem);
}
.journey-panel img {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 20px 40px rgba(23, 24, 28, 0.16));
}
/* .journey-panel.fit — for a shot exported at its own fixed width
   (a single narrow screen, not a full-bleed collage): the image holds
   its natural size instead of stretching to fill the panel, and stays
   centered in the extra space. */
.journey-panel.fit img {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
}

/* Logo grid — a flat wall of client logos, mixing a full-width wordmark
   tile (1068x620) with 2-up square mark tiles (502x502). Each is a
   single self-contained image — card background, padding, and logo
   already composited in Figma at those exact proportions — so this is
   just a grid placing images at their own intrinsic aspect ratio. 64px
   gap on both axes is exactly what puts two 502px tiles side by side
   at 1068px total. The corner radius stays here (rather than baked
   into the export) so it's pixel-perfect at any scale and matches
   every other rounded card on the site. */
.logo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4rem;
}
.logo-tile {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 28px;
}
.logo-tile.wide {
  grid-column: 1 / -1;
}
@media (max-width: 640px) {
  .logo-grid {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
}

.tool-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.5rem;
}
.tool-list span {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.35rem 0.85rem;
}

/* ============================================
   FEATURE ROW (image + text pairing inside a
   subsection — narrower image column than .split,
   sized for a portrait phone-shaped placeholder)
   ============================================ */
.feature {
  display: grid;
  grid-template-columns: minmax(200px, 280px) 1fr;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center;
}
.feature.reverse { grid-template-columns: 1fr minmax(200px, 280px); }
.feature.reverse .device-ph { order: 2; }
.feature.wide { grid-template-columns: minmax(260px, 420px) 1fr; }
.feature.wide.reverse { grid-template-columns: 1fr minmax(260px, 420px); }
.feature.wide.reverse .phone-fan { order: 2; }
@media (max-width: 760px) {
  .feature, .feature.reverse, .feature.wide, .feature.wide.reverse { grid-template-columns: 1fr; }
  .feature.reverse .device-ph,
  .feature.wide.reverse .phone-fan { order: 0; }
}

/* fanned phone-screenshot cluster — 3 stacked screenshots that spread
   into a fan with a staggered reveal when scrolled into view */
.phone-fan {
  position: relative;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 1 / 1.05;
  margin: 0 auto;
}
.phone-fan img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 34%;
  border-radius: 18px;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.82) rotate(0deg);
  transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.5s ease;
  filter: drop-shadow(0 16px 26px rgba(23, 24, 28, 0.2));
}
.phone-fan.in-view img { opacity: 1; }
.phone-fan.in-view img:nth-child(1) {
  transform: translate(-50%, -50%) translate(2%, -6%) rotate(5deg);
  z-index: 1;
  transition-delay: 0s;
}
.phone-fan.in-view img:nth-child(2) {
  transform: translate(-50%, -50%) translate(-40%, 14%) rotate(-8deg);
  z-index: 3;
  transition-delay: 90ms;
}
.phone-fan.in-view img:nth-child(3) {
  transform: translate(-50%, -50%) translate(35%, 16%) rotate(7deg);
  z-index: 2;
  transition-delay: 160ms;
}

/* Story beat — a numbered narrative moment paired with a single
   flattened hero image, alternating sides down the page. */
.story-beat {
  display: grid;
  grid-template-columns: 2fr 3fr;
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: center;
  margin-top: 24px;
}
.story-beat.reverse { grid-template-columns: 3fr 2fr; }
.story-beat .num {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.5vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-bottom: 1.25rem;
  line-height: 1;
}
.story-beat .story-beat-text p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 1.02rem;
}
.story-beat img {
  width: 100%;
  height: auto;
  display: block;
}
.story-beat.reverse .story-beat-img { order: -1; }
@media (max-width: 760px) {
  .story-beat, .story-beat.reverse { grid-template-columns: 1fr; }
  .story-beat.reverse .story-beat-img { order: 0; }
}

/* ============================================
   MOOD CAROUSEL — the Color Story told as a
   horizontal, auto-advancing row of full panels
   (num + text beside its screen), the next one
   peeking at the edge; dot pagination below syncs
   to whichever card is centered and reveals in on
   its own. Swipe/drag or a dot click takes over
   from the autoplay immediately.
   ============================================ */
.mood-carousel {
  margin-top: var(--space-block);
}
.mood-track {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.mood-track::-webkit-scrollbar { display: none; }
/* Leading and trailing spacers are identical widths, so centering the
   first card and centering the last card both land the active card in
   exactly the same spot: the page's normal 1068px content column. */
.mood-spacer {
  flex-shrink: 0;
  width: max(0px, calc((100vw - 1068px) / 2));
}
.mood-card {
  flex: 0 0 min(1068px, 92vw);
  margin-right: 48px;
  scroll-snap-align: center;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  background: var(--paper-dim);
  border-radius: 28px;
  padding: clamp(2rem, 5vw, 4rem);
}
.mood-card:last-child { margin-right: 0; }
@media (max-width: 760px) {
  .mood-card { margin-right: 24px; }
}
.mood-card .num {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.5vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1;
  margin-bottom: 1.25rem;
}
.mood-card-text p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 1.02rem;
  max-width: 34ch;
}
.mood-card-img img {
  width: 100%;
  height: auto;
  display: block;
}
@media (max-width: 760px) {
  .mood-card { grid-template-columns: 1fr; text-align: left; }
  .mood-card-img { order: -1; }
}
.mood-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  margin-top: 2rem;
}
.mood-dot {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--line);
  border: none;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.mood-dot.is-active {
  width: 28px;
}
.mood-dot-fill {
  position: absolute;
  inset: 0;
  width: 0%;
  background: var(--muted);
  border-radius: inherit;
}

/* phone-shaped placeholder for feature screenshots —
   swap contents for a single <img> when a real shot is ready */
.device-ph {
  background: var(--ph-color, var(--paper-dim));
  border: 1px solid var(--line);
  border-radius: 28px;
  aspect-ratio: 9 / 18.5;
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 2.5rem 1.5rem 2rem;
  overflow: hidden;
}
.device-ph::before {
  content: '';
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  width: 44px;
  height: 5px;
  border-radius: 999px;
  background: rgba(23, 24, 28, 0.14);
}
.device-icon {
  width: 34%;
  color: rgba(23, 24, 28, 0.32);
}
.device-icon svg { display: block; width: 100%; height: auto; }
.device-caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  text-align: center;
}
.device-ph .ph-label,
.device-ph .ph-dims {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: rgba(23, 24, 28, 0.38);
}
.device-ph:has(img) {
  background: none;
  border: none;
}
.device-ph img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 28px;
}

/* ============================================
   NEXT PROJECT FOOTER
   ============================================ */
.next-project {
  border-top: 1px solid var(--line);
  margin-top: clamp(3rem, 8vw, 5rem);
  transition: border-color 0.2s ease;
}
.next-project a {
  display: block;
  padding: clamp(2.5rem, 7vw, 5rem) 0;
  transition: background 0.2s ease;
}
.next-project a:hover { background: var(--paper-dim); }
.next-project h2, .next-project .arrow { transition: color 0.2s ease; }
.next-project a:hover h2, .next-project a:hover .arrow { color: var(--accent); }
.next-project:has(a:hover) { border-top-color: var(--paper-dim); }
.next-project .eyebrow { margin-bottom: 1rem; }
.next-project .wrap {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.next-project h2 {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 7.5vw, 4.75rem);
  font-weight: 600;
  letter-spacing: -0.015em;
}
.next-project .arrow {
  font-family: var(--font-mono);
  font-size: 1.2rem;
  color: var(--muted);
}

/* ============================================
   FULL-BLEED IMAGE — single image spanning the
   full browser width, breaking out of .wrap
   ============================================ */
.full-bleed-img {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--paper);
}
/* ============================================
   VIDEO FRAME — contained (not full-bleed), rounded
   video with a minimal custom player: a single
   centered play button at rest, and small controls
   (play/pause, mute, scrub) that appear on hover
   once it's playing.
   ============================================ */
.video-frame {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: #000;
  box-shadow: 0 20px 50px rgba(23, 24, 28, 0.22);
}
.video-frame video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: pointer;
}
.video-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 2.5rem 1.25rem 1.1rem;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent);
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.video-frame:hover .video-controls,
.video-frame:focus-within .video-controls {
  opacity: 1;
  pointer-events: auto;
}

.video-btn {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.95);
  color: #181818;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.video-btn svg { width: 14px; height: 14px; display: none; }

.video-toggle .icon-play { display: block; }
.video-frame.is-playing .video-toggle .icon-play { display: none; }
.video-frame.is-playing .video-toggle .icon-pause { display: block; }

.video-fullscreen svg { display: block; }

.video-mute .icon-vol-on { display: block; }
.video-frame.is-muted .video-mute .icon-vol-on { display: none; }
.video-frame.is-muted .video-mute .icon-vol-off { display: block; }

.video-progress {
  flex: 1;
  height: 3px;
  background: rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  cursor: pointer;
}
.video-progress-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: inherit;
}
.full-bleed-img img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform: translateY(var(--py, 0px));
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .full-bleed-img img { transform: none; }
}

/* ============================================
   HORIZONTAL SCROLL — user-driven scroll gallery.
   First image left-aligns with the text column above
   it; the track bleeds to the viewport's right edge so
   the next image peeks in as a scroll hint. Progress
   bar sits back inside the text column below it.
   ============================================ */
.hscroll {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: var(--space-block);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.hscroll::-webkit-scrollbar { display: none; }
.hscroll-track {
  --hscroll-gap: 64px;
  display: flex;
  align-items: flex-end;
  gap: var(--hscroll-gap);
  width: max-content;
  padding-right: var(--gutter);
  padding-top: 5rem;
  padding-bottom: 5rem;
}
.hscroll-spacer {
  flex-shrink: 0;
  width: max(var(--gutter), calc((100vw - 1180px) / 2 + var(--gutter)));
  margin-right: calc(-1 * var(--hscroll-gap));
  scroll-snap-align: start;
}
.hscroll-track img {
  height: clamp(308px, 42vw, 528px);
  width: auto;
  display: block;
  flex-shrink: 0;
  scroll-snap-align: start;
  filter: drop-shadow(0 10px 40px rgba(23, 24, 28, 0.16));
}
/* placeholder screens (.ph) inside an hscroll track, before real
   screenshots are in — same phone-portrait proportions as a real
   screen would have, so swapping in images later doesn't reflow. */
.hscroll-track .ph {
  height: clamp(308px, 42vw, 528px);
  aspect-ratio: 9 / 19.5;
  flex-shrink: 0;
  scroll-snap-align: start;
  min-height: 0;
}
.hscroll-progress {
  margin-top: 1.5rem;
  height: 3px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.hscroll-progress-fill {
  height: 100%;
  width: 0%;
  background: var(--muted);
  border-radius: inherit;
}
@media (prefers-reduced-motion: no-preference) {
  .hscroll-progress-fill { transition: width 0.05s linear; }
}

/* ============================================
   SCREEN GRID — static grid of app screens,
   contained within the text column (no bleed).
   ============================================ */
.screen-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  row-gap: 72px;
  column-gap: 72px;
  margin-top: var(--space-block);
}
.screen-grid img,
.screen-grid .phone-shot {
  width: 100%;
  display: block;
  filter: blur(10px) drop-shadow(0 10px 40px rgba(23, 24, 28, 0.16));
  opacity: 0;
  transform: translateY(64px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.screen-grid img { height: auto; }
.screen-grid img.is-visible,
.screen-grid .phone-shot.is-visible {
  opacity: 1;
  transform: none;
  filter: blur(0) drop-shadow(0 10px 40px rgba(23, 24, 28, 0.16));
  transition: opacity 0.7s ease, transform 0.3s ease, filter 0.3s ease;
}
.screen-grid img.is-visible:hover,
.screen-grid .phone-shot.is-visible:hover {
  transform: translateY(-8px);
  filter: blur(0) drop-shadow(0 18px 32px rgba(23, 24, 28, 0.22));
}
/* real screenshots (not the blank-phone.svg placeholder, which draws
   its own frame) get the same device bezel recreated as an overlay —
   rounded casing + notch + home indicator — so a real screenshot
   reads as a phone photo, not just a bordered rectangle. Fixed dark
   casing color regardless of site theme, since it should read as a
   physical edge against any screenshot content. */
.screen-grid .phone-shot {
  position: relative;
  border-radius: 14%;
  border: 6px solid #181818;
  overflow: hidden;
  box-sizing: border-box;
}
.screen-grid .phone-shot img {
  width: 100%;
  height: auto;
  display: block;
  filter: none;
  opacity: 1;
  transform: none;
  transition: none;
}
.screen-grid .phone-shot .notch {
  position: absolute;
  top: 2.2%;
  left: 50%;
  transform: translateX(-50%);
  width: 26%;
  height: 3.2%;
  background: #181818;
  border-radius: 999px;
}
.screen-grid .phone-shot .home-indicator {
  position: absolute;
  bottom: 2.2%;
  left: 50%;
  transform: translateX(-50%);
  width: 22%;
  height: 0.7%;
  background: #C9C8BE;
  border-radius: 999px;
}
@media (prefers-reduced-motion: reduce) {
  .screen-grid img,
  .screen-grid .phone-shot {
    opacity: 1;
    transform: none;
    filter: drop-shadow(0 10px 40px rgba(23, 24, 28, 0.16));
    transition: none;
  }
}
@media (max-width: 760px) {
  .screen-grid { grid-template-columns: repeat(2, 1fr); gap: 48px; }
}
@media (max-width: 480px) {
  .screen-grid { grid-template-columns: repeat(3, 1fr); gap: 14px; }
}

/* ============================================
   FILMSTRIP — auto-scrolling image preview strip
   Used on case study pages under the Overview text.
   ============================================ */
.filmstrip {
  overflow: hidden;
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: var(--space-block);
}
.filmstrip-track {
  display: flex;
  align-items: flex-end;
  gap: 64px;
  width: max-content;
  will-change: transform;
  padding: 6rem 0;
}
.filmstrip-track img {
  height: clamp(308px, 42vw, 528px);
  width: auto;
  display: block;
  flex-shrink: 0;
  filter: drop-shadow(0 10px 40px rgba(23, 24, 28, 0.16));
}
@media (prefers-reduced-motion: reduce) {
  .filmstrip-track { transform: none !important; }
}

/* ============================================
   PULL LINE — a large italic statement pulled
   out as a standalone visual break, e.g. between
   two image-heavy sections.
   ============================================ */
.pull-line {
  max-width: 760px;
  margin: clamp(3.5rem, 7vw, 5rem) 0;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  font-weight: 500;
  font-style: italic;
  line-height: 1.4;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.pull-line cite {
  display: block;
  margin-top: 1.25rem;
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ============================================
   SCROLL PROGRESS RAIL — fixed left-edge marker
   on case study pages showing overall scroll
   progress and the section currently in view.
   Desktop only; hidden below 1180px.
   ============================================ */
.progress-rail {
  position: fixed;
  left: 28px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}
.progress-rail-track {
  width: 2px;
  height: 220px;
  background: var(--line);
  border-radius: 999px;
  position: relative;
  overflow: hidden;
}
.progress-rail-fill {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0%;
  background: var(--accent);
  border-radius: inherit;
}
.progress-rail-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  color: var(--muted);
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
}
@media (max-width: 1180px) {
  .progress-rail { display: none; }
}

/* ============================================
   PASSWORD GATE — the prompt shown in place of a
   private case study (see tools/build_lock.py).
   Reuses the homepage hero type so it reads as
   part of the site, not a system dialog.
   ============================================ */
.gate-page .gate { min-height: calc(100vh - var(--nav-h)); }
.gate-auto .gate { visibility: hidden; }
.gate {
  --gate-error: #C93B3B;
  transition: opacity 0.45s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.45s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}
:root[data-theme="dark"] .gate { --gate-error: #FF7B7B; }
.gate.is-leaving {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(-12px);
  pointer-events: none;
}
.gate-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.gate-form { margin-top: 2.5rem; max-width: 26rem; }
.gate-field { position: relative; display: flex; align-items: center; }
.gate-field input {
  width: 100%;
  height: 3.5rem;
  padding: 0 6.4rem 0 1.4rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper-dim);
  border: 1px solid color-mix(in srgb, var(--muted) 45%, transparent);
  border-radius: 999px;
  outline: none;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.gate-field input::placeholder { color: var(--muted); }
.gate-field input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent);
}
.gate-field.is-error input {
  border-color: var(--gate-error);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--gate-error) 16%, transparent);
}
.gate-field.is-error { animation: gate-shake 0.4s cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes gate-shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-7px); }
  40%, 60% { transform: translateX(7px); }
}
.gate-eye, .gate-submit {
  position: absolute;
  top: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  cursor: pointer;
  transform: translateY(-50%);
}
.gate-eye {
  right: 3.6rem;
  width: 2rem;
  height: 2rem;
  color: var(--muted);
  background: none;
  transition: color 0.2s ease;
}
.gate-eye:hover { color: var(--accent); }
.gate-eye svg, .gate-submit svg { width: 1.2rem; height: 1.2rem; display: block; }
.gate-eye .eye-off { display: none; }
.gate-eye.is-showing .eye-on { display: none; }
.gate-eye.is-showing .eye-off { display: block; }
.gate-submit {
  right: 0.5rem;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--paper);
  background: var(--ink);
  border-radius: 50%;
  transition: background-color 0.2s ease, transform 0.2s ease;
}
.gate-submit:hover { background: var(--accent); }
.gate-submit:focus-visible, .gate-eye:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gate-form.is-busy .gate-submit svg { display: none; }
.gate-form.is-busy .gate-submit { pointer-events: none; }
.gate-form.is-busy .gate-submit::after {
  content: "";
  width: 1.05rem;
  height: 1.05rem;
  border: 2px solid color-mix(in srgb, var(--paper) 35%, transparent);
  border-top-color: var(--paper);
  border-radius: 50%;
  animation: gate-spin 0.7s linear infinite;
}
@keyframes gate-spin { to { transform: rotate(360deg); } }
.gate-msg {
  min-height: 1.5rem;
  margin: 0.9rem 0 0 1.4rem;
  font-size: 0.9rem;
  color: var(--gate-error);
}
.gate-help { margin-top: 1.5rem; font-size: 0.92rem; color: var(--muted); }
.gate-help a {
  color: var(--ink-soft);
  border-bottom: 1px solid var(--muted);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.gate-help a:hover { color: var(--accent); border-color: var(--accent); }
@media (max-width: 640px) {
  .gate-field input { font-size: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .gate, .gate-field.is-error { transition: none; animation: none; }
  .gate.is-leaving { filter: none; transform: none; }
}

/* Homepage "Why work with me" / "How I work" — both reuse the established
   sprint-grid and bite-grid components; these rules only set spacing. */
.why { padding-bottom: clamp(4rem, 9vw, 6.5rem); }
.why .about-title { max-width: 24ch; }
.why-lede {
  max-width: 52ch;
  margin: 0;
  font-size: 1.02rem;
  color: var(--ink-soft);
}
.how-lede { margin: 0; max-width: 52ch; font-size: 1.02rem; color: var(--ink-soft); }
