:root {
  --bg: #F0F1F3;          /* platinum */
  --ink: #255BFC;         /* full spectrum blue */
  --muted: #255BFCcc;
  --rule: #255BFC22;
  --accent: #255BFC;
  --footer-blue: #255BFC;
  --serif: "Google Sans Flex", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --sans: "Google Sans Flex", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --max: 1280px;
  --pad: clamp(1.25rem, 4vw, 3rem);
  /* Reduced from 40 → 20 max so the hero logo sits closer to the page edge
     once the video boxes in. Feels more iOS-restrained. */
  --hero-pad: clamp(12px, 2.2vw, 20px);
  --hero-top: 132px;
  /* Apple-style spring curve. Used for taps and the bottom-sheet slide. */
  --ease-ios: cubic-bezier(0.32, 0.72, 0, 1);
  /* Editorial / drift curve. Used for ambient motion (scroll, FLIP). */
  --ease-editorial: cubic-bezier(0.16, 1, 0.3, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Kill the default gray flash on tap; we provide our own active states. */
  -webkit-tap-highlight-color: transparent;
}

/* Pin html to the page bg so iOS rubber-band overscroll never flashes white,
   and ensure the page covers the full dynamic viewport on mobile. */
html {
  min-height: 100dvh;
  background-color: var(--bg);
}

a { color: inherit; text-decoration: none; }
img, video { display: block; max-width: 100%; height: auto; }

/* iOS-style press feedback on every tappable element. ~120ms is short enough
   to feel haptic; the Apple ease has the right "settle" on release. */
@media (hover: none), (pointer: coarse) {
  a, button, [role="button"], .work__media, .site-footer__wordmark {
    transition: transform 120ms var(--ease-ios), opacity 120ms var(--ease-ios);
  }
  a:active, button:active, [role="button"]:active,
  .work__media:active, .site-footer__wordmark:active {
    transform: scale(0.97);
    opacity: 0.85;
  }
}

/* ---------- Hero (scroll-driven) ----------
   Section is taller than the viewport to give the animation runway.
   .hero__pin sticks for that runway, then unsticks and the page continues.

   The mark is TWO stacked copies of the same ALAB SVG:
     • back  — solid blue (#255BFC)
     • front — solid white, sits on top, offset by --diverge
   On the dark video they're aligned, so only white reads. As the logo
   travels up onto the platinum band, the front shifts up-left; the blue
   back peeks out down-right, producing the cursive "j-hook" silhouette
   from Figma Phases 2 & 3.

   Phases:
     Phase 1 (0.00 → 0.45)  shrink + travel to top   (band 0 → 132px)
     Phase 2 (0.45 → 0.65)  hold                     (band 132px, small)
     Phase 3 (0.65 → 1.00)  grow at top              (band 132 → 180px)
   Diverge ramps 0 → 1 across (0.40 → 0.60), centered on band arrival.

   Variables driven by JS:
     --travel       0 → 1   logo Y position (center → band)
     --logo-scale   1 → s2 → s3   container scale (s2 = 225/491, s3 = 423/491)
     --diverge      0 → 1   front-copy offset away from back
     --frame-inset  0 → 1   video full-bleed → boxed
     --band-h       animated band height (px)
*/
.hero {
  --travel: 0;
  --logo-scale: 1;
  --diverge: 0;
  --frame-inset: 0;
  --band-h: 0px;
  /* Cursor follow on the front mark only; -1 → +1, normalized within the logo. */
  --front-dx: 0;
  --front-dy: 0;
  position: relative;
  /* dvh tracks the currently visible viewport on iOS — as the URL bar
     hides/shows, the runway and pin resize together. */
  height: 260dvh;
  background: var(--bg);
}

.hero__pin {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
}

.hero__frame {
  position: absolute;
  /* top band grows from 0 → 132px → 180px across phases (driven by JS --band-h);
     other three sides use --hero-pad once boxed */
  top: var(--band-h);
  right: calc(var(--hero-pad) * var(--frame-inset));
  bottom: calc(var(--hero-pad) * var(--frame-inset));
  left: calc(var(--hero-pad) * var(--frame-inset));
  background: #111;
  overflow: hidden;
  /* Grows from 0 → 80px as the video boxes in. Squircled where supported. */
  border-radius: calc(80px * var(--frame-inset));
  corner-shape: squircle;
}

.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__logo {
  /* Container handles position + scale; SVG children handle z-stacking and divergence. */
  --logo-w: clamp(280px, 38vw, 489px);
  position: absolute;
  left: 50%;
  /* travel from viewport center to the center of the (animating) top band */
  top: calc(50vh - (50vh - (var(--band-h) / 2)) * var(--travel));
  width: var(--logo-w);
  aspect-ratio: 489 / 113;
  transform: translate(-50%, -50%) scale(var(--logo-scale));
  transform-origin: 50% 50%;
  z-index: 5;
  user-select: none;
  will-change: transform, top;
}

.hero__mark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

/* Back: solid blue. Stays anchored to the container. */
.hero__mark--back {
  color: var(--ink);  /* #255BFC */
  z-index: 1;
}

/* Front: same color as the page bg, sits on top. Offsets up-left as --diverge
   grows. On the platinum band the front blends with the bg, so the blue back
   reads as the cursive "j-hook" silhouette. At full divergence:
   ~5% of width left, ~21% of height up — matches Figma.
   --front-dx / --front-dy add a small cursor-follow translate when the pointer
   is over the logo (driven by JS). */
.hero__mark--front {
  --follow-max: 4%;
  color: var(--bg);  /* #F0F1F3 — same as page bg */
  z-index: 2;
  transform: translate(
    calc(var(--diverge) * -5% + var(--front-dx) * var(--follow-max)),
    calc(var(--diverge) * -21% + var(--front-dy) * var(--follow-max))
  );
  transition: transform 0s;
}

@media (prefers-reduced-motion: reduce) {
  .hero { height: 100dvh; }
  .hero__pin { position: static; height: 100dvh; }
}

/* ---------- Work section (Figma node 2017:100) ----------
   Two rows on an 8-column grid:
   • Top row: lede text (cols 1–3) | square vase (4–6) | portrait luv lamp (7–8)
   • Bottom row: portrait timothy (1–2) | square bubble (3–5) | square tall vase (6–8)
*/
.work {
  --work-gap: clamp(12px, 1.16vw, 20px);   /* 20px at 1728px design width */
  --work-pad: clamp(20px, 2.31vw, 40px);   /* 40px at 1728px */
  padding: clamp(4rem, 8.5vw, 8.5rem) var(--work-pad) clamp(4rem, 7.5vw, 7.5rem);
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 6vw, 7rem);
}

.work__row {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: var(--work-gap);
  align-items: start;
  /* Perspective for 3D tilt on .work__media children. */
  perspective: 1400px;
}

.work__lede {
  grid-column: 1 / span 3;
  align-self: center;        /* vertically centered within the row */
  margin: 0;
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(20px, 2.2vw, 38px);
  line-height: 1.2;
  color: var(--ink);
}

/* Top row image placement */
.work__item--remnant { grid-column: 4 / span 3; }
.work__item--luv     { grid-column: 7 / span 2; }

/* Bottom row image placement */
.work__item--timothy { grid-column: 1 / span 2; }
.work__item--bubble  { grid-column: 3 / span 3; }
.work__item--tallvase{ grid-column: 6 / span 3; }

.work__item {
  margin: 0;
  display: flex;
  flex-direction: column;
  /* Cursor-driven 3D tilt vars cascade to .work__inner (the tilting layer).
     --tilt-x/y range -1..+1 (cursor position from item center). */
  --tilt-x: 0;
  --tilt-y: 0;
}

/* Inner wrapper — receives the 3D tilt so the whole container (caption +
   photo) lifts together. Kept separate from .work__item so the entrance
   transform on the figure isn't fighting the tilt rotation.
   Tilt is restrained (3deg max) — the goal is "subtly leaning toward you",
   not a parlour-trick wobble. */
.work__inner {
  display: flex;
  flex-direction: column;
  transform-style: preserve-3d;
  transform:
    rotateY(calc(var(--tilt-x) * 3deg))
    rotateX(calc(var(--tilt-y) * -3deg));
  will-change: transform;
}

.work__caption {
  font-weight: 700;
  font-size: clamp(13px, 1.05vw, 18px);
  line-height: 1.2;
  color: var(--ink);
  text-align: right;
  margin-bottom: clamp(10px, 1vw, 17px);
}

.work__media {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: #d8dde4;
  border-radius: 80px;
  /* Continuous corners (squircle) where supported — falls back to standard
     border-radius elsewhere. Apple uses this rounding everywhere. */
  corner-shape: squircle;
  cursor: pointer;
}
.work__media--square   { aspect-ratio: 1 / 1; }
.work__media--portrait { aspect-ratio: 396 / 606; }   /* ≈ 0.653 */

/* Photo wrapper — gets the slow expo-out hover scale. Separate from the img
   so the img can keep its instant scroll-parallax translate without inheriting
   the long transition. */
.work__photo {
  position: absolute;
  inset: 0;
  transform: scale(1);
  transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}
.work__item:hover .work__photo {
  transform: scale(1.05);
}

.work__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slight overscale leaves room for the scroll-parallax translate
     (--parallax  -1 at top of viewport → +1 at bottom). */
  transform: scale(1.08) translate3d(0, calc(var(--parallax, 0) * -6%), 0);
  will-change: transform;
}

/* Entrance: each work fades + lifts into place when it enters the viewport. */
.work__item {
  --enter: 0;            /* 0 = hidden, 1 = visible */
  opacity: calc(0.001 + var(--enter));
  transform: translate3d(0, calc((1 - var(--enter)) * 24px), 0)
             scale(calc(0.97 + 0.03 * var(--enter)));
  transition:
    opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.9s cubic-bezier(0.2, 0.8, 0.2, 1);
  will-change: transform, opacity;
}
.work__item.is-visible { --enter: 1; }

/* Reduced-motion users get static, visible items with no parallax. */
@media (prefers-reduced-motion: reduce) {
  .work__item {
    --enter: 1;
    transition: none;
  }
  .work__media img { transform: none; }
}

/* ---------- Mobile stack ---------- */
@media (max-width: 760px) {
  .work__row { grid-template-columns: 1fr; }
  .work__lede,
  .work__item--remnant,
  .work__item--luv,
  .work__item--timothy,
  .work__item--bubble,
  .work__item--tallvase { grid-column: 1; }
  .work__lede { padding-top: 0; font-size: clamp(20px, 5vw, 28px); }
}

/* ---------- Footer (Figma node 1:41) ---------- */
.site-footer {
  background: var(--bg);   /* platinum, matches page */
  padding: clamp(2rem, 3.35vw, 48px) clamp(1.25rem, 2.78vw, 40px) clamp(1.75rem, 2.85vw, 41px);
  border-top: none;
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 5.3vw, 3.3rem);
}

.site-footer__inner {
  max-width: 1440px;
  width: 100%;
  margin: 0 auto;
}

.site-footer__wordmark {
  /* Container for the two stacked SVG marks. Diverged so the cursive
     silhouette reads. Front shifts toward the cursor on hover, and squishes
     toward the pointer while being dragged (pinched). */
  --diverge: 0.6;
  --front-dx: 0;
  --front-dy: 0;
  --follow-max: 2%;
  --pinch-x: 0;
  --pinch-y: 0;
  --pinch-max: 14%;
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 489 / 113;
  color: var(--footer-blue);
  cursor: grab;
  touch-action: none;   /* prevent page scroll while dragging on touch */
}

.site-footer__wordmark.is-pinched { cursor: grabbing; }

.site-footer__mark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.site-footer__mark--back {
  color: var(--footer-blue);   /* #255BFC */
  z-index: 1;
}

.site-footer__mark--front {
  color: var(--bg);            /* #F0F1F3 — same as page bg */
  z-index: 2;
  transform: translate(
    calc(var(--diverge) * -5% + var(--front-dx) * var(--follow-max) + var(--pinch-x) * var(--pinch-max)),
    calc(var(--diverge) * -21% + var(--front-dy) * var(--follow-max) + var(--pinch-y) * var(--pinch-max))
  );
}

.site-footer__meta {
  display: grid;
  /* Mirrors Figma columns: ©2026 at left, Instagram/Contact right-aligned ~73%,
     gap, then SLC time ~86% across. */
  grid-template-columns: auto 1fr 14% auto;
  align-items: start;
  font-family: "Google Sans Flex", var(--sans);
  font-weight: 700;
  font-size: clamp(1rem, 1.67vw, 24px);
  line-height: 1.25;
  color: var(--footer-blue);
}

.site-footer__copy {
  grid-column: 1;
  justify-self: start;
}

.site-footer__links {
  grid-column: 2;
  justify-self: end;
  text-align: right;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35em;
}

.site-footer__links a {
  color: var(--footer-blue);
  text-decoration: none;
}

.site-footer__links a:hover { opacity: 0.7; }

.site-footer__time {
  grid-column: 4;
  justify-self: end;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 600px) {
  .site-footer__meta {
    grid-template-columns: 1fr 1fr;
    row-gap: 1.25rem;
  }
  .site-footer__copy { grid-column: 1; }
  .site-footer__links { grid-column: 2; }
  .site-footer__time { grid-column: 1 / -1; justify-self: start; }
}

/* ---------- Lightbox (work piece detail) ---------- */
/* ---------- Lightbox ----------
   Shared-element transition: the clicked photo's bounding rect is captured,
   then the modal's media slot is inverse-transformed to sit on top of it
   exactly. Releasing the inverse transform with a CSS transition makes the
   photo appear to grow out of the grid into the modal. The modal's media
   slot uses --src-aspect (set per-piece via JS) so it shares the source's
   aspect ratio — no object-fit recropping during flight. The panel chrome
   (background + shadow) fades in around the growing photo. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 3vw, 2.5rem);
  pointer-events: none;
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { pointer-events: auto; }

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(240, 241, 243, 0);
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  transition:
    background 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    backdrop-filter 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    -webkit-backdrop-filter 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}
.lightbox.is-open .lightbox__backdrop {
  background: rgba(240, 241, 243, 0.86);   /* platinum tint */
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.lightbox__panel {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  width: min(1180px, 100%);
  max-height: calc(100dvh - clamp(2rem, 6vw, 5rem));
  /* Chrome (bg + shadow) materializes around the FLIP'ing photo. */
  background: rgba(240, 241, 243, 0);
  border-radius: 24px;
  padding: clamp(1.25rem, 2.4vw, 2.25rem);
  box-shadow: 0 30px 80px -20px rgba(37, 91, 252, 0);
  transition:
    background 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.1s,
    box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.1s;
}
.lightbox.is-open .lightbox__panel {
  background: var(--bg);
  box-shadow: 0 30px 80px -20px rgba(37, 91, 252, 0.18);
}

.lightbox__close {
  position: absolute;
  top: clamp(0.75rem, 1.4vw, 1.25rem);
  right: clamp(0.75rem, 1.4vw, 1.25rem);
  z-index: 2;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}
.lightbox__close:hover {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}

.lightbox__media {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  background: #d8dde4;
  /* Aspect inherits source aspect ratio per-piece (set inline by JS) so the
     FLIP doesn't recrop the photo mid-flight. Falls back to 4:5 if unset. */
  aspect-ratio: var(--src-aspect, 4 / 5);
  max-height: calc(100dvh - clamp(4rem, 10vw, 8rem));
  min-height: 0;
  /* FLIP origin at top-left keeps inverse-transform math straightforward. */
  transform-origin: 0 0;
  will-change: transform, border-radius;
  transition:
    transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
    border-radius 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.lightbox__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Source's photo wrapper is at scale(1.05+1.08) — modal img starts slightly
     zoomed and settles to scale(1) so the photo content "tightens" into place
     as it lands. JS clears these inline values after the transition. */
  transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.lightbox__info {
  display: flex;
  flex-direction: column;
  gap: clamp(1rem, 1.5vw, 1.5rem);
  padding: clamp(0.5rem, 1vw, 1rem) clamp(0.5rem, 1.5vw, 1rem);
  overflow-y: auto;
  min-height: 0;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.25s,
    transform 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.25s;
}
.lightbox.is-open .lightbox__info {
  opacity: 1;
  transform: translateY(0);
}
.lightbox__close {
  opacity: 0;
  transition:
    opacity 0.3s ease 0.3s,
    background 0.2s,
    color 0.2s,
    border-color 0.2s,
    transform 120ms var(--ease-ios);
}
.lightbox.is-open .lightbox__close { opacity: 1; }
.lightbox__close:active { transform: scale(0.92); }

/* Share button — iOS-shaped pill, only shown when navigator.share is available
   (JS removes [hidden]). Sits next to the close button. */
.lightbox__share {
  position: absolute;
  top: clamp(0.75rem, 1.4vw, 1.25rem);
  right: calc(clamp(0.75rem, 1.4vw, 1.25rem) + 48px);
  z-index: 2;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 50%;
  cursor: pointer;
  opacity: 0;
  transition:
    opacity 0.3s ease 0.32s,
    background 0.2s,
    color 0.2s,
    border-color 0.2s,
    transform 120ms var(--ease-ios);
}
.lightbox.is-open .lightbox__share { opacity: 1; }
.lightbox__share:hover {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.lightbox__share:active { transform: scale(0.92); }

/* Grabber pill: visible only on mobile, sits at the top-center of the sheet.
   Communicates "this can be dragged down to dismiss". */
.lightbox__grabber {
  display: none;
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 5px;
  border-radius: 999px;
  background: rgba(37, 91, 252, 0.25);
  pointer-events: none;
  z-index: 3;
}

/* Source media is hidden during FLIP so it doesn't ghost beneath the
   growing modal photo. Visibility (not display) preserves grid layout. */
.work__media.is-flip-source { visibility: hidden; }

.lightbox__title {
  margin: 0;
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.4vw, 2.25rem);
  line-height: 1.1;
  color: var(--ink);
}

.lightbox__meta {
  margin: 0;
  display: grid;
  gap: 0.6rem;
}
.lightbox__row {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: 1rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--rule);
  font-size: 0.95rem;
}
.lightbox__row:last-child {
  border-bottom: 1px solid var(--rule);
}
.lightbox__row dt {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  align-self: center;
}
.lightbox__row dd {
  margin: 0;
  color: var(--ink);
  font-weight: 500;
}

.lightbox__notes {
  margin: 0;
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--ink);
}

/* While lightbox is open, lock background scrolling. */
body.lightbox-open { overflow: hidden; }

/* ====================================================================
   Mobile: iOS-y treatments
   ==================================================================== */

/* ---------- Mobile: bottom-sheet lightbox ----------
   Below 760px, the lightbox stops being a centered card and becomes a
   bottom sheet that slides up from the home-indicator edge. Drag the
   grabber down to dismiss — JS adds rubber-band resistance and a flick
   threshold. Backdrop opacity tracks the drag.
   FLIP is bypassed on mobile (the panel slide does the heavy lifting).
*/
@media (max-width: 760px) {
  .lightbox {
    /* Bottom-anchored layout — panel hugs the bottom edge. */
    place-items: end stretch;
    padding: 0;
  }

  .lightbox__panel {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    width: 100%;
    max-height: 92dvh;
    border-radius: 28px 28px 0 0;
    corner-shape: squircle;
    /* Bottom padding respects the home-indicator. */
    padding:
      28px
      clamp(1rem, 5vw, 1.5rem)
      calc(clamp(1.25rem, 5vw, 1.75rem) + env(safe-area-inset-bottom))
      clamp(1rem, 5vw, 1.5rem);
    gap: 1.25rem;
    overflow-y: auto;
    overscroll-behavior: contain;   /* keep iOS bounce inside the sheet */
    /* JS sets translateY directly during drag; baseline starts off-screen. */
    transform: translateY(100%);
    transition: transform 0.42s var(--ease-ios);
    /* Reset desktop chrome animation; mobile sheet handles its own bg/shadow. */
    background: var(--bg);
    box-shadow: 0 -10px 40px -8px rgba(37, 91, 252, 0.12);
  }
  .lightbox.is-open .lightbox__panel { transform: translateY(0); }
  /* Class added by JS during pointer drag — kills CSS transition so the
     panel tracks the finger 1:1 instead of easing on every move. */
  .lightbox__panel.is-dragging { transition: none; }

  .lightbox__grabber { display: block; }

  /* Close button moves to top-right inside the sheet, share button beside it. */
  .lightbox__close {
    top: 18px;
    right: 14px;
    width: 36px;
    height: 36px;
  }
  .lightbox__share {
    top: 18px;
    right: 60px;
    width: 36px;
    height: 36px;
  }

  /* Photo slot: full width at top, source aspect respected. */
  .lightbox__media {
    border-radius: 20px;
    corner-shape: squircle;
    /* Cap so portrait pieces don't push the info panel off-screen. */
    max-height: 50dvh;
    /* Disable mobile FLIP transition — panel slide handles motion. */
    transition: none;
  }
  .lightbox__img { transition: none; }

  .lightbox__info { padding: 0; gap: 1rem; }
  .lightbox__title { font-size: 1.5rem; }
  .lightbox__row { grid-template-columns: 5rem 1fr; gap: 0.75rem; }
}

/* ---------- Mobile: horizontal snap gallery ----------
   On mobile, both .work__row containers are flattened with `display: contents`
   so their children become direct flex children of .work. The whole work
   section becomes ONE horizontal scroller — lede card first, then all five
   photos in a single uninterrupted swipe (like an App Store / Photos shelf).
*/
@media (max-width: 760px) {
  .work {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: visible;
    gap: 16px;
    padding: clamp(2rem, 6vw, 3rem) 6vw clamp(2.5rem, 7vw, 4rem);
    scroll-snap-type: x mandatory;
    scroll-padding-left: 6vw;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .work::-webkit-scrollbar { display: none; }

  /* Rows collapse to display: contents so .work__lede + all .work__item
     elements become siblings under .work (the flex/scroll container). */
  .work__row {
    display: contents;
    perspective: none;          /* tilt is desktop-only */
  }

  .work__lede,
  .work__item--remnant,
  .work__item--luv,
  .work__item--timothy,
  .work__item--bubble,
  .work__item--tallvase {
    grid-column: auto;
  }

  .work__lede {
    flex: 0 0 78vw;
    align-self: stretch;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    padding: 0;
    font-size: clamp(20px, 5.5vw, 28px);
    display: flex;
    align-items: center;
  }

  .work__item {
    flex: 0 0 78vw;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    /* Disable entrance offset/scale on mobile — items appear as you swipe to
       them, the entrance transition would fight horizontal scroll-snap. */
    --enter: 1;
    transform: none !important;
    opacity: 1;
    transition: none;
  }

  /* Smaller iOS-style corners on photos, replaces the 80px desktop pebble. */
  .work__media {
    border-radius: 32px;
    corner-shape: squircle;
  }

  /* Caption sits left-aligned on mobile (above each card). */
  .work__caption {
    text-align: left;
    margin-bottom: 10px;
    font-size: 14px;
  }

  /* Hover scale isn't relevant on coarse pointers — the :active scale takes
     over via the global tap rules above. */
  .work__photo { transition: none; }
  .work__item:hover .work__photo { transform: scale(1); }
}

/* ---------- Mobile: footer adopts the home-indicator ---------- */
@media (max-width: 760px) {
  .site-footer {
    padding-bottom: calc(clamp(1.75rem, 2.85vw, 41px) + env(safe-area-inset-bottom));
  }
}

/* ---------- Smallest screens: hero compaction ---------- */
@media (max-width: 600px) {
  .hero { height: 220dvh; }
  .hero__logo { --logo-w: clamp(220px, 60vw, 360px); }
}
