/* ========== LOAD INTRO (home.js) ==========
   An inline script in <head> sets .intro; home.js sets up the start positions, then removes it. */
.intro .site-header,
.intro .hero__stage > * { visibility: hidden; }

.w__in { display: inline-block; }   /* each word's inner span, added by home.js, rises inside the word */

/* ========== HERO ========== */
.hero {
  position: relative;
  overflow-x: clip;   /* the intro shifts whole lines sideways; clip (not hidden) keeps the sticky stage working */
}

/* Everything visible in the hero. Pinned while the media grows (see GROW ON SCROLL). */
.hero__stage {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  padding: calc(var(--header-h) + 24px) var(--pad) 136px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Headline: --fit = width of the longest line in em (measured),
   so the longest line fills exactly the space between the side paddings.
   In use: variant c. Variant a is kept as a fallback (markup in docs/DECISIONS.md). */
.hero__title {
  --fit: 5.73;            /* variant a: 'YAĞMUR + slot' = 5.63em (measured, Outfit 800) + lean allowance */
  --rows: 3.1;            /* block height in em: 3 lines of 0.92 + 2 gaps of 0.1, plus room for the Ğ breve */
  --fs-max: 220px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: min(calc((100vw - 2 * var(--pad)) / var(--fit)), var(--fs-max));
  line-height: 0.92;
  letter-spacing: -0.01em;
  display: flex;
  flex-direction: column;
  gap: 0.1em;             /* room for the İ dot and Ğ breve between lines */
}

.hero[data-headline="c"] .hero__title {
  --fit: 9.6;             /* 'I MAKE + slot + THINGS' = 9.51em (Outfit 800) */
  --rows: 3.65;           /* middle line holds the 1.5em slot: 0.92 + 0.1 + 1.5 + 0.1 + 0.92 = 3.54, plus breve */
}

.hero__line {
  display: flex;
  align-items: center;
  gap: 0.2em;
  white-space: nowrap;
}

.hero__line--start  { justify-content: flex-start; }
.hero__line--center { justify-content: center; }
.hero__line--end    { justify-content: flex-end; }

.w { display: inline-block; }

/* Faux italic, as on the reference: the word before the media slot leans with the slot */
.w--skew {
  transform: skewX(-10deg);
  transform-origin: 0 100%;
}

/* ========== MEDIA SLOT (grows into the full-bleed section on scroll) ========== */
.hero__slot {
  --slot-h: 0.74em;
  --skew: calc(var(--slot-h) * 0.1763);   /* tan(10deg) * height, matches the -10deg lean */
  position: relative;
  flex: none;
  width: calc(var(--slot-h) * 4 / 3 + var(--skew));
  height: var(--slot-h);
}

/* Variant c: a bigger window, taller than the letters (the lines around it open up a little).
   With it, 'I MAKE + slot + THINGS' is the longest line and sets --fit. */
.hero[data-headline="c"] .hero__slot { --slot-h: 1.5em; }

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--surface);
  /* slant capped at half the width, so the shape stays a parallelogram while the intro opens the slot */
  clip-path: polygon(min(var(--skew), 50%) 0, 100% 0, calc(100% - min(var(--skew), 50%)) 100%, 0 100%);
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
  filter: brightness(0.82);
}
.hero__media video {   /* the showreel is already night-toned: no dimming */
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Slot shape B: rounded rectangle, no lean. The radius lives on the slot so home.js can read it in px. */
.hero[data-slot="round"] .hero__slot { --skew: 0px; border-radius: 0.12em; }
.hero[data-slot="round"] .hero__media { clip-path: none; border-radius: inherit; }
.hero[data-slot="round"] .w--skew { transform: none; }

/* ========== GROW ON SCROLL (reference: wearetheromans.com) ==========
   home.js adds .is-grow on screens at least 768px wide and 500px tall when reduced motion is off.
   The stage stays pinned for one screen of scrolling while the media grows from its slot to
   full-bleed (size, corners and zoom are set by home.js), then for half a screen more (--hold)
   while the full-bleed media stands still with the scroll cue, then it scrolls away.
   The stage follows the visible screen (dvh), so it still fills it when a tablet's toolbar hides;
   the pinned distance stays in small-viewport heights (svh): 1 of grow + --hold. */
.is-grow .hero { --hold: 0.5; height: calc(100vh * (2 + var(--hold))); }
@supports (height: 1svh) { .is-grow .hero { height: calc(100svh * (1 + var(--hold)) + 100dvh); } }

.is-grow .hero__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  overflow: clip;
}

/* Fixed-height stage: on short, wide windows the width-based headline would run into the header
   and the bottom row, so it is also capped by height: the block (--rows em tall) has to fit inside
   the stage's top (header + 24px) and bottom (136px) padding. */
.is-grow .hero__title {
  font-size: min(calc((100vw - 2 * var(--pad)) / var(--fit)), var(--fs-max), calc((100svh - var(--header-h) - 160px) / var(--rows)));
}

.is-grow .hero__media {
  --zoom: 1.5;           /* picture starts zoomed in and settles to 1 at full-bleed (read by home.js) */
  z-index: 2;            /* above the headline and the bottom row */
  max-width: none;       /* base.css caps pictures at their container (the small slot) */
}
.is-grow .hero__media img,
.is-grow .hero__media video { transform: scale(var(--zoom)); }

/* Full-bleed (.is-full, home.js): the headline and bottom row are covered anyway, so they are hidden
   (they would show through the melting media); the media's bottom becomes see-through over the hold
   (--fade, up to 45%) so the real background — glows, grain, stars — shows instead of a hard edge.
   The mask is only on while full-bleed. */
.hero.is-full .hero__title .w,
.hero.is-full .hero__bottom { visibility: hidden; }
.is-grow .hero.is-full .hero__media {
  -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 var(--fade, 0%));
  mask-image: linear-gradient(to top, transparent 0%, #000 var(--fade, 0%));
}

/* Night rising into the picture: the site's navy and violet glow come up from the bottom of the
   full-bleed media, so the scroll cue reads on any frame. Inside the media, so it grows, rounds and
   scrolls away with it. Fades in over the last fifth of the grow (--scrim, written by home.js).
   Dense enough that the label keeps 4.5:1 even on a white frame (measured at 1024x768 and 1280x600). */
.is-grow .hero__media::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;            /* above the picture */
  height: max(46%, 340px);
  pointer-events: none;
  opacity: var(--scrim, 0);
  background:
    radial-gradient(40% 62% at 50% 100%, rgb(var(--glow-violet) / 0.16), rgb(var(--glow-indigo) / 0.05) 60%, rgb(var(--glow-indigo) / 0)),
    radial-gradient(56% 100% at 50% 100%, rgb(var(--bg-rgb) / 0.9) 0%, rgb(var(--bg-rgb) / 0.78) 30%, rgb(var(--bg-rgb) / 0.46) 62%, rgb(var(--bg-rgb) / 0) 100%),
    linear-gradient(to top, rgb(var(--bg-rgb) / 0.35), rgb(var(--bg-rgb) / 0) 40%);
}

/* A keyboard-focused arrow stays visible above the grown media, on a navy tile */
.is-grow .hero__arrow:focus-visible { z-index: 5; background: rgb(var(--bg-rgb) / 0.85); }

/* ========== HERO BOTTOM ROW ========== */
.hero__bottom {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: 40px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 24px;
}

.hero__intro {
  max-width: 36ch;
  text-wrap: balance;
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-mid);
}

.hero__tagline {
  display: block;
  margin-top: 10px;
  font-size: 12px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text);
}

.hero[data-headline="c"] .hero__tagline { display: none; }

.hero__arrow { flex: none; }   /* a round light button (.btn-light--round, base.css) */
.hero__arrow:hover svg { translate: 0 3px; }

.hero__mobile-media { display: none; }

/* ========== SHOWREEL BUTTON (hero-video.js) ==========
   Pauses and plays the showreel; shown once hero-video.js runs (.has-reel). On wide screens it rides the
   video's bottom-right corner: home.js moves it with the growing media (a transform from the stage's
   top-left), and it appears once placed (.is-placed). On phones it sits in the phone video's top-right
   corner, clear of the scroll cue. Frosted like the project pages' video button. */
.hero__play {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;            /* above the grown media (2), like the cue */
  display: none;
  width: 40px;
  height: 40px;
  background: rgb(var(--bg-rgb) / 0.6);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity 0.4s var(--ease-out);
}
.hero__play svg { width: 16px; height: 16px; }
.hero__play .hero__play-play,
.hero.is-paused .hero__play .hero__play-pause { display: none; }
.hero.is-paused .hero__play .hero__play-play { display: block; }
.hero.has-reel .hero__play:not(.hero__play--phone) { display: inline-flex; }
.hero__play.is-placed { opacity: 1; }

/* ========== SCROLL CUE: LIGHT LINE (reference idea: jingjinghan.com's light running down a wire) ==========
   'Scroll to see the projects' at the foot of the media, above a hair-thin line: a drop of lavender
   light slides down the line and ends in a small four-point twinkle, like a falling star pointing at
   the projects. A plain link to #work (same instant jump as the arrow). The line, drop and twinkle
   are decorative (aria-hidden in the markup).
   home.js (SCROLL CUE) sets .is-cue on the hero (grow mode: the cue is shown) and .is-live on the cue
   (the loop runs). Grow mode: over the full-bleed media, in the night scrim. Without grow: still at the
   foot of the phone image, or in the middle of the bottom row on big screens, otherwise hidden. */
.hero__cue {
  --cue-track: 56px;     /* length of the line = how far the drop falls (cue-fall) */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 28px;          /* + 12px padding: the line ends 40px above the stage bottom */
  z-index: 3;            /* above the grown media (2) */
  width: max-content;
  margin-inline: auto;   /* centred on the stage (not on the media box), so transform stays free */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;    /* hit area */
  color: var(--text);
  text-decoration: none;
}

.hero__cue-label {
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.24em;
  margin-right: -0.24em; /* the last letter's tracking would push the text off-centre */
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: 0 0 16px rgb(var(--glow-lavender) / 0.55);
  transition: text-shadow 0.4s var(--ease-out);
}

/* The wire: clips the drop above it; the extra 12px below the foot holds the twinkle's lower ray */
.hero__cue-line {
  position: relative;
  width: 21px;
  height: calc(var(--cue-track) + 12px);
  overflow: hidden;
}
.hero__cue-line::before {
  content: '';
  position: absolute;
  left: 10px;
  top: 0;
  width: 1px;
  height: var(--cue-track);
  background: var(--text);
  opacity: 0.24;
  transition: opacity 0.4s var(--ease-out);
}

/* The falling drop: a 1px comet with a soft lavender bloom and a bright head */
.hero__cue-drop {
  position: absolute;
  left: 10px;
  top: -28px;            /* starts just above the wire */
  width: 1px;
  height: 28px;
  background: linear-gradient(to bottom, rgb(var(--glow-lavender) / 0), rgb(var(--glow-lavender) / 0.9) 70%, #fff);
  opacity: 0;
}
.hero__cue-drop::before {   /* bloom along the tail (static blur, never animated) */
  content: '';
  position: absolute;
  left: -3px;
  right: -3px;
  top: 8px;
  bottom: -2px;
  border-radius: 4px;
  background: linear-gradient(to bottom, rgb(var(--glow-lavender) / 0), rgb(var(--glow-lavender) / 0.45));
  filter: blur(3px);
}
.hero__cue-drop::after {    /* head */
  content: '';
  position: absolute;
  left: -1px;
  bottom: -1.5px;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 4px 1px rgb(var(--glow-lavender) / 0.95), 0 0 10px 3px rgb(var(--glow-violet) / 0.55);
}

/* The landing twinkle: a bright core with two thin rays, centred on the foot of the wire.
   At its peak it is a '+' whose vertical ray continues the wire. */
.hero__cue-glint {
  position: absolute;
  left: 0;
  top: calc(var(--cue-track) - 10px);
  width: 21px;
  height: 21px;
  opacity: 0;
  background:
    radial-gradient(circle, #fff 0 1.2px, rgb(var(--glow-lavender) / 0.85) 2px, rgb(var(--glow-lavender) / 0.25) 4.5px, rgb(var(--glow-lavender) / 0) 8px),
    linear-gradient(90deg, rgb(var(--glow-lavender) / 0), rgb(232 228 255 / 0.95) 50%, rgb(var(--glow-lavender) / 0)) 50% 50% / 100% 1px no-repeat,
    linear-gradient(rgb(var(--glow-lavender) / 0), rgb(232 228 255 / 0.95) 50%, rgb(var(--glow-lavender) / 0)) 50% 50% / 1px 100% no-repeat;
}

/* The loop, only while .is-live (otherwise nothing runs). One 2.8s cycle: the drop falls (lands at
   1.68s), the twinkle peaks at 1.74s, the drop is gone at 1.96s, the twinkle at 2.35s, then ~0.7s of
   dark. All three start together 0.5s after .is-live, so they stay in step. */
.hero__cue.is-live .hero__cue-drop {
  animation: cue-fall 2.8s cubic-bezier(0.65, 0, 0.35, 1) 0.5s infinite, cue-fade 2.8s linear 0.5s infinite;
}
.hero__cue.is-live .hero__cue-glint { animation: cue-glint 2.8s linear 0.5s infinite; }

@keyframes cue-fall {      /* 56px line (grow mode) */
  0% { transform: translateY(0); }
  60%, 100% { transform: translateY(56px); }
}
@keyframes cue-fall-sm {   /* 40px line (phones and still layouts) */
  0% { transform: translateY(0); }
  60%, 100% { transform: translateY(40px); }
}

/* Hover and keyboard focus: the label glows brighter and the wire lights up (the loop keeps its pace) */
@media (hover: hover) and (pointer: fine) {
  .hero__cue:hover .hero__cue-label { text-shadow: 0 0 18px rgb(var(--glow-lavender) / 0.9), 0 0 4px rgb(var(--glow-lavender) / 0.5); }
  .hero__cue:hover .hero__cue-line::before { opacity: 0.45; }
}
.hero__cue:focus-visible .hero__cue-label { text-shadow: 0 0 18px rgb(var(--glow-lavender) / 0.9), 0 0 4px rgb(var(--glow-lavender) / 0.5); }
.hero__cue:focus-visible .hero__cue-line::before { opacity: 0.45; }

/* The navy halo keeps the ring readable on any frame of the media */
.hero__cue:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
  border-radius: 12px;
  box-shadow: 0 0 0 6px rgb(var(--bg-rgb) / 0.85);
}

/* Grow mode: hidden until the media is almost full-bleed (.is-cue), then it blurs in.
   A keyboard-focused cue stays shown. */
.is-grow .hero__cue {
  opacity: 0;
  visibility: hidden;
  filter: blur(8px);
  transform: translateY(12px);
  transition: opacity 0.35s ease, filter 0.35s ease, transform 0.35s ease, visibility 0s 0.35s;
}
.is-grow .hero.is-cue .hero__cue,
.is-grow .hero__cue:focus-visible {
  opacity: 1;
  visibility: visible;
  filter: none;
  transform: none;
  transition: opacity 0.9s var(--ease-out), filter 0.9s var(--ease-out), transform 0.9s var(--ease-out), visibility 0s;
}

/* Without grow: a shorter line. Shown only where it has room: in the middle of the bottom row on big
   screens (between the intro text and the arrow) and on phones (see MOBILE); elsewhere the arrow
   carries the prompt. */
html:not(.is-grow) .hero__cue { --cue-track: 40px; display: none; }
html:not(.is-grow) .hero__cue.is-live .hero__cue-drop { animation-name: cue-fall-sm, cue-fade; }

@media (min-width: 1040px) and (min-height: 640px) {
  html:not(.is-grow) .hero__cue { display: flex; }
}

/* ========== MOBILE ========== */
@media (max-width: 767px) {
  .hero__stage {
    min-height: 0;
    padding-bottom: 48px;
    justify-content: flex-start;
    padding-top: calc(var(--header-h) + 48px);
  }

  /* Words wrap and centre; size is set so the longest single word fits */
  .hero__title {
    --fit-m: 4.4;          /* longest single word: 'YAĞMUR' = 4.31em */
    font-size: min(calc((100vw - 2 * var(--pad)) / var(--fit-m)), 96px);
    line-height: 1.2;      /* wrapped lines: room for the Ğ breve under the comma/letters above */
    text-align: center;
    gap: 0;
  }
  .hero[data-headline="c"] .hero__title { --fit-m: 5.65; }  /* 'THOUGHTS' = 5.57em */

  .hero__line { display: block; white-space: normal; }
  .hero__line .w { margin: 0 0.1em; }
  .hero__slot { display: none; }

  .hero__bottom { position: static; margin-top: 32px; }

  .hero__mobile-media {
    display: block;
    margin-top: 32px;
    aspect-ratio: 4 / 3;   /* the desktop slot's shape: the showreel's wide scenes stay (almost) whole */
    overflow: hidden;
    border-radius: 12px;
    background: var(--surface);
  }
  .hero__mobile-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: brightness(0.82);
  }
  .hero__mobile-media video {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  /* Showreel button: in the phone video's top-right corner (phones have no slot for the wide one) */
  .hero.has-reel .hero__play:not(.hero__play--phone) { display: none; }
  .hero.has-reel .hero__play--phone { display: inline-flex; left: auto; top: 12px; right: 12px; opacity: 1; }

  /* Scroll cue over the foot of the phone image (the phone's 'video section'), in its own night scrim */
  html:not(.is-grow) .hero__cue {
    display: flex;
    bottom: calc(48px + 16px);   /* stage bottom padding + 16px: the link ends 16px above the image's edge */
    gap: 10px;
  }
  .hero__cue-label { font-size: 12px; }

  .hero__mobile-media { position: relative; }
  .hero__mobile-media::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 75%;           /* the label sits high in the short phone image: the night has to reach it */
    border-radius: 0 0 12px 12px;
    pointer-events: none;
    background:
      radial-gradient(40% 62% at 50% 100%, rgb(var(--glow-violet) / 0.16), rgb(var(--glow-indigo) / 0.05) 60%, rgb(var(--glow-indigo) / 0)),
      radial-gradient(100% 100% at 50% 100%, rgb(var(--bg-rgb) / 0.9) 0%, rgb(var(--bg-rgb) / 0.82) 30%, rgb(var(--bg-rgb) / 0.62) 62%, rgb(var(--bg-rgb) / 0) 100%),
      linear-gradient(to top, rgb(var(--bg-rgb) / 0.35), rgb(var(--bg-rgb) / 0) 40%);
  }
}

@media (max-width: 359px) {
  .hero__cue-label { letter-spacing: 0.2em; margin-right: -0.2em; }   /* fits a 320px phone's image */
}

/* ========== SCROLL CUE: REDUCED MOTION AND FORCED COLOURS ==========
   No loop and no fades: a still 'resting frame', the drop resting at the foot of a wire that brightens
   from faint white to lavender, with a small still twinkle. */
@media (prefers-reduced-motion: reduce) {
  .hero__cue,
  .hero__cue-label,
  .hero__cue-line::before { transition: none; }
  .hero__cue .hero__cue-drop,
  .hero__cue.is-live .hero__cue-drop { animation: none; opacity: 1; transform: translateY(var(--cue-track)); }
  .hero__cue .hero__cue-glint,
  .hero__cue.is-live .hero__cue-glint { animation: none; opacity: 0.9; transform: scale(0.7); }
  .hero__cue .hero__cue-line::before,
  .hero__cue:hover .hero__cue-line::before,
  .hero__cue:focus-visible .hero__cue-line::before {
    opacity: 1;
    background: linear-gradient(rgb(238 241 246 / 0.14), rgb(var(--glow-lavender) / 0.7));
  }
}

@media (forced-colors: active) {
  /* keep the wire (the gradients are dropped in this mode); the label follows the system link colour */
  .hero__cue .hero__cue-line::before,
  .hero__cue:hover .hero__cue-line::before,
  .hero__cue:focus-visible .hero__cue-line::before { background: CanvasText; opacity: 1; }
}

/* ========== PROJECTS (reference: ricardochance.com) ==========
   A normal-flow list of big cards in a centre column. On screens 768px+ with motion allowed, home.js
   adds .has-captions: the side columns show the active project's name (left) and its details (right),
   held in the middle of the screen and faded in letter by letter as each card passes; the text under
   the cards is then kept for screen readers only. Otherwise (phones, reduced motion, no JS) the
   details sit under each card. The pictures drift a little inside their frames (parallax, home.js). */
.work {
  display: grid;
  grid-template-columns: 1fr;
  column-gap: 32px;
  padding: 120px var(--pad) 160px;
}

.work__side { display: none; }

.work__label {
  margin-bottom: 40px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.work__list {
  list-style: none;
  display: grid;
  gap: 56px;
}

/* Under the list: the way to every project (projects/index.html); the look is .btn-light (base.css) */
.work__all {
  display: flex;
  width: fit-content;
  margin: 72px auto 0;
}

.work__card {
  display: block;
  color: inherit;
  text-decoration: none;
}
a.work__card:focus-visible { outline-offset: 8px; border-radius: 16px; }

.work__media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 12px;
  background: var(--surface);
}

.work__zoom {             /* hover zoom (the img itself carries the parallax) */
  display: block;
  width: 100%;
  height: 100%;
  transition: transform 0.9s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  a.work__card:hover .work__zoom { transform: scale(1.03); }
}

.work__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.2);  /* room for the parallax drift (home.js moves it ±8% of the frame) */
}

.work__badge {            /* 'In progress · coming soon' on the teaser */
  position: absolute;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(var(--bg-rgb) / 0.55);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
}
.work__badge::before {    /* a small lavender light */
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(var(--glow-lavender));
  box-shadow: 0 0 10px 2px rgb(var(--glow-lavender) / 0.7);
}

.work__info {
  display: grid;
  gap: 6px;
  margin-top: 20px;
}
.work__title { font-size: 20px; font-weight: 600; line-height: 1.3; }
.work__meta { font-size: 12px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--text-mid); }
.work__desc { max-width: 52ch; font-size: 15px; color: var(--text-mid); }

/* Side columns: three-column grid like the reference (centre 60vw / 600px / 800px) */
@media (min-width: 768px) {
  .work { grid-template-columns: 1fr 60vw 1fr; }
  .work__col { grid-column: 2; }
  .has-captions .work__side { display: block; }
  .has-captions .work__side--names { grid-column: 1; grid-row: 1; }
  .has-captions .work__side--meta { grid-column: 3; grid-row: 1; }
  .has-captions .work__list { gap: 32px; }

  /* the details under the cards: kept for screen readers only */
  .has-captions .work__info {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
@media (min-width: 1280px) { .work { grid-template-columns: 1fr 600px 1fr; } }
@media (min-width: 1440px) { .work { grid-template-columns: 1fr 800px 1fr; } }

/* WebGL pictures (works-gl.js, big screens with a mouse): a fixed canvas above the background and
   below the page draws each picture over its card, bent by the scroll speed. A card gets .is-gl once
   its picture is drawn there; the real <img> then stays in place but invisible. */
.works-gl {
  position: fixed;
  inset: 0;
  z-index: -1;            /* after .bg in the page, so above it */
  pointer-events: none;
}
.work__card.is-gl .work__media { background: transparent; }
.work__card.is-gl .work__media img { opacity: 0; }
/* The teaser's label waits for its picture to rise out of the night (.is-revealed, works-gl.js) */
.work__card.is-gl .work__badge { transition: opacity 0.8s 0.3s; }
.work__card.is-gl:not(.is-revealed) .work__badge { opacity: 0; transition: none; }

/* All captions share one spot, held in the middle of the screen while the list passes */
.work__stack {
  position: sticky;
  top: 50%;
  display: grid;
  transform: translateY(-50%);
}
.work__cap {
  grid-area: 1 / 1;
  opacity: 1;
}
.work__cap .ch { opacity: 0; }   /* letters, made by home.js */

.work__side--names .work__cap {
  font-size: clamp(20px, 1.9vw, 32px);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.work__side--meta .work__cap { text-align: right; }
.work__cap-meta {
  display: block;
  font-size: 12px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text-mid);
}
.work__cap-desc {
  display: block;
  margin: 12px 0 0 auto;
  max-width: 26ch;
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-mid);
}

/* ========== ABOUT ==========
   The statement lights up word by word as it scrolls through the screen, and the photos fan out from
   a pile (home.js ABOUT). Without JS or with reduced motion: fully lit, already fanned out. */
.about {
  display: grid;
  grid-template-columns: 1fr;
  gap: 64px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 160px var(--pad);
}

.about__label {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.about__title {
  margin: 14px 0 24px;
  font-size: 18px;
  font-weight: 500;
  color: var(--text-mid);
}

.about__statement {
  font-size: clamp(26px, 2.9vw, 44px);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.01em;
}
.about__word { transition: opacity 0.2s linear; }   /* words, made by home.js */

.about__facts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px 28px;
  margin-top: 56px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.about__facts dt {
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.about__facts dd { font-size: 15px; }

.about__cv { margin-top: 40px; }   /* the look is .btn-light (base.css) */

/* Photos: a pile that fans out; --q (0 piled .. 1 fanned) is set by home.js, --x/--y/--r per photo */
.about__photos {
  position: relative;
  height: 400px;
}
.about__photo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 190px;
  overflow: hidden;
  border-radius: 12px;
  box-shadow: 0 30px 60px rgb(0 0 0 / 0.45);
  transform: translate(-50%, -50%)
             translate(calc(var(--x) * var(--q, 1)), calc(var(--y) * var(--q, 1)))
             rotate(calc(var(--r) * var(--q, 1)));
  transition: scale 0.5s var(--ease-out);
}
.about__photo img { display: block; width: 100%; height: auto; filter: url(#photo-cool); }   /* cool tone */
.about__photo .about__true {   /* the photo's own colours, on top, shown on hover */
  position: absolute;
  inset: 0;
  height: 100%;
  filter: none;
  opacity: 0;
  transition: opacity 0.6s ease;
}
@media (hover: hover) and (pointer: fine) {
  .about__photo:hover { z-index: 1; scale: 1.06; }
  .about__photo:hover .about__true { opacity: 1; }
}

@media (min-width: 768px) {
  .about__facts { grid-template-columns: repeat(3, 1fr); }
  .about__photo { width: 250px; }
  .about__photos { height: 520px; }
}
@media (min-width: 1024px) {
  .about {
    grid-template-columns: 1fr 380px;
    gap: 80px;
    align-items: center;
  }
}

/* ========== PHONES: SECTION SPACING ==========
   The 320px pauses between the sections (160 + 160) are almost half a phone screen of empty sky:
   halved here (Contact's own phone rules are in base.css). */
@media (max-width: 767px) {
  .work { padding-top: 80px; padding-bottom: 80px; }
  .about { padding-top: 80px; padding-bottom: 80px; }
}
