/* =============================================================
   Ayushi Ajmera — Portfolio
   Built from "Portfolio 2026" → page: portfolio → frame: Ayushi AJmera
   Design canvas is 1440 wide; content column 1296 with 72px gutters.
   ============================================================= */

:root {
  /* palette lifted from the Figma frame */
  --paper:  #F9EDDB;   /* page background          */
  --ink:    #403C3C;   /* body + headings          */
  --cream:  #FFF9E9;   /* type on the hero         */
  --sun:    #FFDA3F;   /* accent / eyebrow dot     */
  --stroke: #E7DFCD;   /* hairline on nav buttons  */
  --surface-2: #F7F6F4; /* Vector 42 tone — the alternating surface */
  /* How far a surface reaches past the next wave. It must cover the crest's
     FULL travel (--wave-overlap 170px) plus the wave's own height (~86px),
     or mid-rise the wave renders over the page body instead of the surface
     above it — which shows as a stray band under a hard straight edge. */
  --wave-tuck: 280px;

  /* type
     NOTE: TASA Explorer (the body face in the Figma file) is a Figma-hosted
     font with no webfont version. It is kept first in the stack so it is used
     if you ever install it locally; on the web Space Grotesk stands in. */
  --serif: "DM Serif Display", Georgia, "Times New Roman", serif;
  --sans:  "TASA Explorer", "Space Grotesk", system-ui, -apple-system, sans-serif;
  --ui:    "Space Grotesk", system-ui, -apple-system, sans-serif;
  --mono:  "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --light: "Inter", system-ui, -apple-system, sans-serif;

  /* rhythm */
  --gutter: 72px;
  --column: 1296px;
  --section-gap: 188px;  /* vertical gap between sections in the frame */
  --radius: 39px;        /* project tile corner radius */
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
h1, h2, p { margin: 0; }

/* Shared mono label: eyebrows, captions, footer meta */
.mono,
.hero__eyebrow,
.contact__eyebrow,
.project__meta p,
.project__index,
.footer__row {
  font-family: var(--mono);
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

/* =============================================================
   HERO
   Frame: 1440 × 849 image, nav overlaid, headline in DM Serif.
   ============================================================= */

.hero {
  position: relative;
  width: 100%;
  aspect-ratio: 1440 / 849;
  overflow: hidden;
  isolation: isolate;
}

.hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* Hatched sun — sits at x915 / y-94 on the 1440 canvas, so it bleeds
   off the top edge exactly as it does in the frame. */
.hero__sun {
  position: absolute;
  left: 63.54%;          /*  915 / 1440 */
  top: -11.07%;          /*  -94 / 849  */
  width: 39.24%;         /*  565 / 1440 */
  height: auto;
  z-index: 1;
  pointer-events: none;
}

/* Cloud and gulls, positioned off the 1440 × 849 hero canvas.
   The cloud sits behind the headline; gull 1 rides in front of it. */
.hero__cloud,
.hero__bird {
  position: absolute;
  height: auto;
  z-index: 1;
  pointer-events: none;
}

.hero__cloud {
  left: 28.68%;          /* 413 / 1440 */
  top: 47.59%;           /* 404 / 849  */
  width: 22.78%;         /* 328 / 1440 */
}

.hero__bird--1 {
  left: 27.22%;          /* 392 / 1440 */
  top: 42.21%;
  width: 5.49%;          /*  79 / 1440 */
  z-index: 3;
}

.hero__bird--2 {
  left: 32.92%;          /* 474 / 1440 */
  top: 43.18%;
  width: 4.86%;          /*  70 / 1440 */
}

/* ---------- nav ---------- */

.nav {
  position: absolute;
  inset: 0 var(--gutter) auto;
  top: 24px;
  height: 56px;
  z-index: 3;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  color: var(--cream);
  font-family: var(--ui);
  font-size: 16px;
}

.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
}
.nav__brand svg { width: 14px; height: 20px; }

/* translucent capsule holding the three nav actions */
.nav__pill {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.nav__link {
  padding: 8px 10px;
  border-radius: 99px;
  border: 1px solid transparent;
  line-height: 1;
  transition: border-color 0.25s ease, background-color 0.25s ease;
}
/* no ring at rest — not even on the current page. It appears on hover only. */
.nav__link:hover,
.nav__link:focus-visible { border-color: rgba(255, 255, 255, 0.9); }

.nav__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  background: #fff;
  color: #000;
  line-height: 1;
  transition: transform 0.25s ease;
}
.nav__cta svg { width: 24px; height: 24px; }
.nav__cta:hover { transform: translateY(-1px); }

.nav__tools {
  justify-self: end;
  display: flex;
  gap: 4px;
}
.nav__icon {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--stroke);
  color: var(--ink);
  cursor: pointer;
  padding: 0;
  transition: transform 0.25s ease;
}
.nav__icon svg { width: 22px; height: 22px; }
.nav__icon:hover { transform: translateY(-1px); }

/* ---------- hero copy ---------- */

/* Spans x216 → x1178 on the 1440 canvas: the eyebrow sits flush left of that
   band, the headline flush right of it. That right alignment is what opens the
   gap on the left where the cloud and gulls sit — keep them in step. */
.hero__copy {
  position: absolute;
  z-index: 2;
  left: 15%;                 /*  216 / 1440 */
  width: 66.81%;             /*  962 / 1440 */
  top: 17.8%;                /*  151 / 849 — top of the headline block */
  color: var(--cream);
}

.hero__eyebrow {
  font-size: 12px;
  letter-spacing: 0.14em;
  margin-bottom: 26px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.hero__eyebrow .dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--sun);
  flex: none;
}

.hero h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(52px, 9.44vw, 136px);   /* 136 / 1440 */
  line-height: 1.06;
  letter-spacing: -0.01em;
  text-align: right;
}

/* Line one dances on hover — once per hover, never looping. Each WORD moves as
   a single block, so the letters inside stay locked together. script.js wraps
   each word and sets --i (its index, for the stagger) and --r (its tilt,
   alternating direction so the two words lean apart rather than together). */
.dance__word {
  display: inline-block;
}

.dance.is-dancing .dance__word {
  will-change: transform;
  animation: word-dance 500ms cubic-bezier(.45, 0, .55, 1) both;
  animation-delay: calc(var(--i) * 40ms);
}

@keyframes word-dance {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  45%      { transform: translateY(-4px) rotate(var(--r)); }
}

/* Line two cycles Solves → Code → Design → Vibe → Ship and back, for ever.
   All five words share ONE grid cell, so the slot is permanently as wide as
   the widest word — nothing reflows as they swap. The words are left-aligned
   in that slot, so every one of them starts on the same x; the longest of them
   ("Design") is what reaches the right edge, under "who". */
.flip {
  display: inline-grid;
  justify-items: start;
  perspective: 800px;

  /* How long each word is on screen. The loop and every stagger are derived
     from it, so this is the only number to change to re-time the headline. */
  --flip-hold: 2s;
  --flip-loop: calc(var(--flip-hold) * 5);   /* 5 words */
}

.flip__word {
  grid-area: 1 / 1;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  animation: flip-word var(--flip-loop) linear infinite both;
}
.flip__word:nth-child(2) { animation-delay: calc(var(--flip-hold) * 1); }
.flip__word:nth-child(3) { animation-delay: calc(var(--flip-hold) * 2); }
.flip__word:nth-child(4) { animation-delay: calc(var(--flip-hold) * 3); }
.flip__word:nth-child(5) { animation-delay: calc(var(--flip-hold) * 4); }

/* 5 words share the loop, so each owns 20% of it. At a 2s hold that is
   0.3s flipping in, 1.4s sitting still, 0.3s flipping out. */
@keyframes flip-word {
  0%   { opacity: 0; transform: rotateX(-90deg);
         animation-timing-function: cubic-bezier(.16,1,.3,1); }
  3%   { opacity: 1; transform: rotateX(0deg); }
  17%  { opacity: 1; transform: rotateX(0deg);
         animation-timing-function: cubic-bezier(.7,0,.84,0); }
  20%  { opacity: 0; transform: rotateX(90deg); }
  100% { opacity: 0; transform: rotateX(90deg); }
}

/* =============================================================
   INTRO
   ============================================================= */

.intro {
  width: min(1218px, calc(100% - var(--gutter) * 2));
  margin: var(--section-gap) auto 0;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 49px;
}

.intro p {
  font-size: clamp(22px, 2.78vw, 40px);    /* 40 / 1440 */
  line-height: 1.52;
}

.intro__lead {
  font-weight: 700;
  font-size: clamp(24px, 3.06vw, 44px);    /* 44 / 1440 */
  line-height: 1.36;
}

/* =============================================================
   WORK
   Three rows. Wide tile 766, narrow tile 498, 32px apart,
   both 581 tall, then a caption 24px underneath.
   ============================================================= */

.work {
  width: min(var(--column), calc(100% - var(--gutter) * 2));
  margin: var(--section-gap) auto 0;
  display: flex;
  flex-direction: column;
  gap: 102px;        /* row-to-row spacing */
}

.work__row {
  display: flex;
  gap: 32px;
  align-items: flex-start;
}

.project {
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}
.project--wide   { flex: 766 1 0; }
.project--narrow { flex: 498 1 0; }

.project__media {
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.55s cubic-bezier(.2,.7,.2,1);
}
.project--wide   .project__media { aspect-ratio: 766 / 581; }
.project--narrow .project__media { aspect-ratio: 498 / 581; }

.project__media:hover { transform: scale(0.985); }

.project__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Placeholder panels — swap each for <img> when the real case-study
   visuals are ready (see README). */
.project__ph {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(150deg, #d9ded8, #aeb9b1 45%, #7f8984);
}
.project__ph[data-tone="green"]  { background: linear-gradient(150deg, #9fae8d, #6d7f5c 48%, #3d4a30); }
.project__ph[data-tone="blue"]   { background: linear-gradient(150deg, #a9c6dd, #5c8bb0 52%, #24455e); }
.project__ph[data-tone="sand"]   { background: linear-gradient(150deg, #ede3cd, #c4b291 50%, #7a6d51); }
.project__ph[data-tone="deep"]   { background: linear-gradient(150deg, #9fb6c9, #4d6d8a 52%, #1d3345); }
.project__ph[data-tone="forest"] { background: linear-gradient(150deg, #8fa47e, #55684a 50%, #2b3722); }
.project__ph[data-tone="slate"]  { background: linear-gradient(150deg, #b8bfc4, #75828c 52%, #38434c); }

.project__caption {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
}

.project__meta { display: flex; flex-direction: column; gap: 10px; }

.project__meta h2 {
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(22px, 2.08vw, 30px);    /* 30 / 1440 */
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.project__title-link {
  color: inherit;
  text-decoration: none;
  transition: opacity .25s ease;
}

.project__title-link:hover { opacity: .62; }

.project__meta p {
  font-size: 11px;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.project__index {
  font-size: 11px;
  color: color-mix(in srgb, var(--ink) 40%, transparent);
  flex: none;
  padding-top: 4px;
}

/* =============================================================
   CONTACT
   ============================================================= */

.contact {
  width: min(1227px, calc(100% - var(--gutter) * 2));
  margin: var(--section-gap) auto 0;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 38px;
}

.contact__eyebrow {
  font-size: 11px;
  color: color-mix(in srgb, var(--ink) 50%, transparent);
}

.contact__pair {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.contact__pair p {
  font-family: var(--light);
  font-weight: 300;
  font-size: clamp(22px, 3.06vw, 44px);    /* 44 / 1440 */
  line-height: 1.32;
}

.contact__pair a {
  font-weight: 700;
  font-size: clamp(30px, 5.42vw, 78px);    /* 78 / 1440 */
  line-height: 1.23;
  letter-spacing: -0.025em;
  overflow-wrap: anywhere;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 2px;
  background-repeat: no-repeat;
  background-position: 0 92%;
  transition: background-size 0.45s cubic-bezier(.2,.7,.2,1);
}
.contact__pair a:hover { background-size: 100% 2px; }

/* =============================================================
   FOOTER
   Full-bleed meadow illustration with the meta row sitting on its
   paper-coloured upper half. The fade hides the seam between the
   illustration's paper tone and --paper.
   ============================================================= */

.footer {
  position: relative;
  margin-top: var(--section-gap);
  width: 100%;
  aspect-ratio: 1440 / 506;
  overflow: hidden;
  isolation: isolate;
}

.footer__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* blends the illustration's paper into the page background */
.footer::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 39.5%;                 /* 200 / 506 */
  z-index: 1;
  background: linear-gradient(var(--paper), rgba(249, 237, 219, 0));
  pointer-events: none;
}

.footer__meta {
  position: absolute;
  z-index: 2;
  left: var(--gutter);
  right: var(--gutter);
  top: 11.07%;                   /* 56 / 506 */
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.footer__rule {
  height: 1px;
  background: color-mix(in srgb, var(--ink) 16%, transparent);
}

.footer__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.footer__links {
  display: flex;
  gap: 32px;
  color: color-mix(in srgb, var(--ink) 75%, transparent);
}
.footer__links a { transition: color 0.25s ease; }
.footer__links a:hover { color: var(--ink); }

/* =============================================================
   SCROLL REVEAL
   ============================================================= */

.reveal {
  opacity: 0;
  transform: translateY(45px);
  transition: opacity 0.8s ease, transform 0.9s cubic-bezier(.2,.7,.2,1);
}
.reveal.is-visible { opacity: 1; transform: none; }

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

  /* hold the headline on the original word */
  .flip__word { animation: none; opacity: 0; transform: none; }
  .flip__word:first-child { opacity: 1; }
}

/* =============================================================
   RESPONSIVE
   ============================================================= */

@media (max-width: 1100px) {
  :root { --gutter: 40px; --section-gap: 130px; --radius: 28px; }
  .work { gap: 72px; }
  .nav__link { padding: 8px; }
}

@media (max-width: 780px) {
  :root { --gutter: 22px; --section-gap: 96px; --radius: 22px; }

  .hero { aspect-ratio: 3 / 4; }
  .hero__bg { object-position: 62% center; }
  .hero__sun { top: -6%; left: 52%; width: 58%; }

  /* the headline fills the middle of the phone hero, so the cloud and gulls
     drift down into the clear band of sky just above the horizon */
  .hero__cloud   { left: 9%;  top: 48.5%; width: 33%; }
  .hero__bird--1 { left: 7%;  top: 43%;   width: 10%; }
  .hero__bird--2 { left: 21%; top: 44.5%; width: 9%; }

  /* the narrow column has no room for the right-aligned band, so the phone
     hero centres both lines instead */
  .hero__copy {
    left: 50%;
    transform: translateX(-50%);
    width: calc(100% - var(--gutter) * 2);
    top: 20%;
  }
  .hero__eyebrow { font-size: 10px; margin-bottom: 18px; }
  .hero h1 { font-size: clamp(44px, 13vw, 76px); text-align: center; }
  /* the words share a left edge here too, so the cycle reads the same way it
     does on desktop rather than re-centring on every swap */
  .flip { justify-items: start; }

  /* the pill's inner links collapse; the CTA carries the nav */
  .nav { grid-template-columns: 1fr auto; top: 16px; }
  .nav__pill {
    grid-column: 2;
    background: none;
    border: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    padding: 0;
  }
  .nav__link { display: none; }
  .nav__tools { display: none; }

  .intro { gap: 32px; }
  .work { gap: 56px; }

  /* one project per row */
  .work__row { flex-direction: column; gap: 56px; }
  .project--wide,
  .project--narrow { flex: 1 1 auto; width: 100%; }
  .project--wide .project__media,
  .project--narrow .project__media { aspect-ratio: 4 / 3; }

  .project__meta h2 { font-size: 22px; }

  .contact { gap: 26px; }

  .footer { aspect-ratio: 1440 / 620; }
  .footer__meta { top: 7%; gap: 12px; }
  .footer__row { flex-direction: column; align-items: flex-start; gap: 12px; font-size: 11px; }
  .footer__links { gap: 20px; }
}

/* =============================================================
   CLOSING BLOCK — contact + footer on one surface (Figma 2147226738)
   Its top edge is a wave that rises with scroll, covering the work
   grid above it. Only clip-path changes, so it stays on the compositor.
   ============================================================= */

.closing {
  --closing-surface: #F7F6F4;   /* Vector 42 fill from the Figma frame */
  --wave-overlap: 170px;        /* how far the crest travels upward */

  position: relative;
  z-index: 3;
  /* no negative pull: the block starts a normal gap below the work grid, so
     the cards are never covered. --wave-overlap is now purely how far the
     crest starts below this top edge, i.e. how far it travels upward. */
  margin-top: var(--section-gap);
  background: var(--closing-surface);
  /* JS swaps in the wavy path; this is the straight-edge fallback */
  clip-path: url(#waveClip);
}

/* the <defs> carrier must not take up space */
.closing__defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* the block owns the surface now, so these lose their own spacing.
   --wave-band is the room the wave needs at the top before any content. */
/* Content always sits below the crest's LOWEST position, so the wave can
   never slice text — it only ever reveals the surface behind it. */
.closing { --wave-band: calc(var(--wave-overlap) + 30px); }
.closing .contact { margin-top: 0; padding-top: var(--wave-band); }
.closing .footer  { margin-top: 96px; }
/* the footer art fades into the closing surface, not the page paper, so the
   two share one unbroken colour and the join never shows */
.closing .footer::before {
  background: linear-gradient(var(--closing-surface), rgba(247, 246, 244, 0));
}

/* no clip at all when motion is reduced — a plain straight edge */
@media (prefers-reduced-motion: reduce) {
  .closing { clip-path: none; }
  .closing .contact { padding-top: 0; }
}

@media (max-width: 900px) {
  .closing { --wave-overlap: 160px; }
}

/* avatar in the nav pill — a home button. Figma "Navigation": pill 444x56,
   avatar 40x40 at 9,8 then a 60px gap before the 326px link group. */
.nav__pill { gap: 60px; }
.nav__items { display: flex; align-items: center; gap: 16px; }

.nav__home {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  overflow: hidden;
  display: block;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.nav__home img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nav__home { box-shadow: 0 0 0 1px transparent; }
.nav__home:hover,
.nav__home:focus-visible { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.9); }
.nav__home:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

@media (max-width: 760px) {
  .nav__pill { gap: 14px; }
  .nav__items { gap: 10px; }
}


/* =============================================================
   HERO -> INTRO RISER
   The paper surface laps over the hero illustration and its top edge
   is the same wave as the closing block, rising with scroll.
   ============================================================= */
.riser {
  --wave-overlap: 170px;                 /* how far the crest travels upward */
  --wave-band: calc(var(--wave-overlap) + 30px);

  position: relative;
  /* padding, not a child margin: a child's margin would collapse straight
     through the riser and cancel any overlap */
  padding-top: calc(var(--wave-band) + var(--section-gap));
  background: var(--paper);
  clip-path: url(#introWave);
}
.riser .intro { margin-top: 0; }

@media (prefers-reduced-motion: reduce) {
  .riser { clip-path: none; margin-top: 0; padding-top: var(--section-gap); }
}

@media (max-width: 900px) { .riser { --wave-overlap: 120px; } }

/* =============================================================
   WORK ROWS — scroll-linked zoom
   JS writes the scale; this only sets the origin and promotes the row
   so the browser keeps it on its own layer.
   ============================================================= */
.work__row {
  transform-origin: 50% 50%;
  will-change: transform;
}

/* the row owns the motion now, so the per-card reveal is a plain fade */
.reveal { transform: none; transition: opacity 0.8s ease; }
.reveal.is-visible { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .work__row { transform: none !important; will-change: auto; }
}

/* =============================================================
   CLOSING — the wave footer fills the screen when you reach it
   ============================================================= */
.closing {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.closing .contact { flex: 1 0 auto; justify-content: center; }


/* =============================================================
   STAGES — each section holds still while the next rises over it
   A stage is sticky, so it stops moving once it reaches its pin
   offset; the following riser then scrolls up over it with its wavy
   edge. JS sets --pin per stage: 0 for a section shorter than the
   viewport, negative for a taller one so you can still reach its end.
   ============================================================= */
.stage {
  position: sticky;
  top: var(--pin, 0px);
}
/* later sections paint over earlier ones as they rise */
.hero.stage   { z-index: 1; }
#introRise    { z-index: 2; }
#workRise     { z-index: 3; }
.closing      { z-index: 4; }

/* NOTE: no drop-shadow on a clipped element — clip-path is applied after
   filter, so the shadow is clipped away with it: renders nothing, still
   costs a composite. */

/* Only the intro laps up over the hero: the hero's lower edge is artwork, so
   there is nothing to cover. It keeps the page paper, which reads clearly
   against the illustration behind it. */
#introRise { margin-top: calc(var(--wave-band) * -1); }

/* The work section rises over the intro with its own wave. */
#workRise { clip-path: url(#workWave); }

/* Alternating surfaces, so every wave edge has something to show against:
   hero art -> cool -> paper -> cool. Without this the intro/work boundary is
   paper on paper and the wave is invisible. */
#introRise { background: var(--surface-2); }

/* The project section runs on a near-black surface. Redefining --ink locally
   flips every piece of type inside it in one move: the card titles inherit
   `color`, and the role line and index numbers are color-mix()es of --ink,
   so they follow automatically. */
#workRise {
  background: #202020;
  --ink: #F9EDDB;
  color: var(--ink);
}

/* --wave-tuck: how far the cool surface reaches BELOW the work riser's top,
   so the whole wave (crest AND trough) has something to sit against. It must
   exceed the wave's own height or the troughs come out paper-on-paper. */
#introRise { padding-bottom: calc(var(--section-gap) + var(--wave-tuck)); }
#workRise  { margin-top: calc(var(--wave-tuck) * -1); }

/* Same trick at the bottom of the dark section: it must reach past the
   closing block's resting crest, or the near-black would simply stop on a
   hard straight edge and the footer's wave would rise over the body instead.
   The extra padding and the negative margin cancel, so the closing block
   lands in exactly the same place. */
#workRise { padding-bottom: calc(var(--section-gap) + var(--wave-tuck)); }
.closing  { margin-top: calc(var(--wave-tuck) * -1); }

@media (prefers-reduced-motion: reduce) {
  .stage { position: static; }
  #workRise { clip-path: none; margin-top: 0; padding-top: var(--section-gap); }
}
