/* ============================================================
   DESIGN TOKENS
   Edit these to re-theme the whole site quickly.
============================================================ */
:root {
  /* Palette */
  --bg:         #F8F6F4;   /* page background */
  --ink:        #867070;   /* primary text */
  --accent:     #D5B4B4;   /* pinkish accent */
  --tint:       #EFE9E6;   /* soft fill behind images while loading */
  --hero-ground:#EFEAE7;   /* sampled from the hero artwork's background */
  --hairline:   #E4DCD8;   /* thin divider rules */
  --light:      #F8F6F4;   /* text on dark / over imagery */

  /* Typography */
  /* Inria Serif carries no Hebrew, so Frank Ruhl Libre picks up those
     glyphs; fallback is per-character, so mixed titles stay correct. */
  --serif: 'Inria Serif', 'Frank Ruhl Libre', Georgia, 'Times New Roman', serif;
  --sans:  'DM Sans', 'Heebo', system-ui, -apple-system, sans-serif;

  /* Layout */
  --max-width: 1180px;
  --gutter: clamp(1.25rem, 5vw, 3.5rem);
  --nav-height: 64px;
}

/* ============================================================
   RESET / BASE
============================================================ */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* No rounded corners anywhere — squared, strict edges */
img {
  display: block;
  max-width: 100%;
  border-radius: 0;
}
a { color: inherit; text-decoration: none; }

/* Small-caps label helper */
.label {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
}

.container {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Thin hairline divider between sections */
.hairline {
  border: 0;
  height: 1px;
  background: var(--hairline);
  max-width: var(--max-width);
  margin-inline: auto;
  width: calc(100% - 2 * var(--gutter));
}

/* ============================================================
   SCROLL FADE-IN ANIMATION
============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.9s ease, transform 0.9s ease;
  will-change: opacity, transform;
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ============================================================
   1. NAVIGATION
   Transparent over the hero image, solid on scroll.
============================================================ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--nav-height);
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.4s ease, border-color 0.4s ease, color 0.4s ease;
  /* The hero and project covers are light artwork, so the nav reads in
     ink over them. Revisit if a dark cover image is ever used. */
  color: var(--ink);
}
.nav.is-solid {
  background: rgba(248, 246, 244, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
}
.nav__inner {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.nav__brand {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.15rem;
  letter-spacing: 0.02em;
}
.nav__links {
  display: flex;
  gap: clamp(1.1rem, 2.5vw, 2rem);
  list-style: none;
}
.nav__links a {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  position: relative;
  padding-bottom: 3px;
}
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 1px;
  background: currentColor;
  transition: width 0.35s ease;
}
.nav__links a:hover::after { width: 100%; }

/* ============================================================
   2. HERO — one full-section image, stretched edge to edge
============================================================ */
.hero {
  position: relative;
  width: 100%;
  /* The artwork is 16:9. Matching that ratio here means it shows whole and
     edge to edge with no surrounding ground — and so no seam where the
     artwork's ivory would meet the page white. Capped to the viewport. */
  aspect-ratio: 16 / 9;
  max-height: 100svh;
  overflow: hidden;
  /* Only visible on very wide screens, where the cap kicks in. */
  background: var(--hero-ground);
}
/* Sized to the rendered artwork exactly, so the loose shapes can be
   positioned as percentages of the image and stay pinned at any size. */
.hero__stage {
  position: relative;
  height: 100%;
  aspect-ratio: 16 / 9;
}
.hero__img {
  width: 100%;
  height: 100%;
  /* contain, never cover: the artwork is a finished composition with
     type inside it, so it must not be cropped at any viewport. */
  object-fit: contain;
  object-position: center;
}

/* ------------------------------------------------------------
   FLOATING SHAPES
   These three were lifted out of the artwork and layered back on
   at their original coordinates, so they can drift on their own.
   Everything else — the flowers, the mat, the type — is still one
   flat image underneath and never moves.
------------------------------------------------------------ */
.hero__shape {
  position: absolute;
  height: auto;
  will-change: transform;
}
/* Lifted out of the artwork — coordinates are the originals. */
.hero__shape--circle   { left: 31.562%; top: 46.319%; width: 3.008%; animation: drift-a  8s ease-in-out      0s infinite; }
.hero__shape--pyramid  { left: 26.680%; top: 52.292%; width: 3.594%; animation: drift-b 10s ease-in-out     -2s infinite; }
.hero__shape--star     { left: 61.797%; top: 43.125%; width: 3.242%; animation: drift-c  7s ease-in-out      0s infinite; }
.hero__shape--cylinder { left: 67.383%; top: 46.528%; width: 3.867%; animation: drift-d 11s ease-in-out     -4s infinite; }

/* Added decoration, sitting in the empty ground around the composition. */
.hero__shape--f-cube    { left: 12.500%; top: 63.000%; width: 4.000%; animation: drift-b 13s ease-in-out    -6s infinite; }
.hero__shape--f-pyramid { left: 82.000%; top: 60.000%; width: 3.400%; animation: drift-e 10s ease-in-out    -1s infinite; }
.hero__shape--f-circle  { left: 36.000%; top: 87.500%; width: 2.300%; animation: drift-a  9s ease-in-out    -5s infinite; }
.hero__shape--f-star    { left: 64.000%; top: 88.000%; width: 2.600%; animation: drift-c  8s ease-in-out    -3s infinite; }

/* Percentage translations resolve against each shape's own box, so the
   drift stays proportional however large the hero happens to be drawn.
   These used to move about 13% of a 40px shape over 9 to 19 seconds,
   roughly half a pixel a second, which reads as a rendering fault rather
   than as motion. The travel is now about 50% and the loops are shorter,
   so a shape covers a fifth of its own width in a second or two. */
@keyframes drift-a {
  0%, 100% { transform: translate(0, 0); }
  33%      { transform: translate(22%, -48%); }
  66%      { transform: translate(-16%, -22%); }
}
@keyframes drift-b {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  40%      { transform: translate(-24%, -40%) rotate(-16deg); }
  70%      { transform: translate(12%, -16%) rotate(7deg); }
}
@keyframes drift-c {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(16%, -50%) rotate(30deg); }
}
@keyframes drift-d {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  35%      { transform: translate(-20%, -34%) rotate(11deg); }
  75%      { transform: translate(16%, -46%) rotate(-11deg); }
}
@keyframes drift-e {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(-14%, -52%) rotate(18deg); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__shape { animation: none; }
}

/* ============================================================
   INTRO — name, tagline and the rotating badge
============================================================ */
.intro { padding-block: clamp(3rem, 8vw, 6rem); }
.intro__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(2rem, 6vw, 5rem);
}
.intro__name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.25rem, 6vw, 3.75rem);
  line-height: 1.05;
  letter-spacing: 0.005em;
}
.intro__tagline {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(0.98rem, 1.6vw, 1.2rem);
  max-width: 34ch;
  margin-top: 0.85rem;
}

/* Rotating circular badge — circle stays 132px, text enlarged */
.badge {
  width: 132px;
  height: 132px;
  flex: 0 0 auto;
  animation: spin 30s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .badge { animation: none; }
}
.badge text {
  font-family: var(--sans);
  font-size: 16px;          /* viewBox units — renders ~10.5px */
  letter-spacing: 3.6px;
  text-transform: uppercase;
  fill: var(--ink);
  font-weight: 500;
}
.badge__mark { fill: var(--accent); }

/* ============================================================
   3. AUTO-SCROLLING CAROUSEL
============================================================ */
.carousel {
  padding-block: clamp(2rem, 5vw, 3.5rem);
  overflow: hidden;
}
.carousel__track {
  display: flex;
  gap: 1rem;
  width: max-content;
  /* CSS drives the loop; JS clones the slides for seamlessness */
  animation: marquee 52s linear infinite;
}
.carousel:hover .carousel__track { animation-play-state: paused; }
@keyframes marquee {
  from { transform: translateX(0); }
  /* -50% because the track holds two identical halves */
  to   { transform: translateX(-50%); }
}
/* Fixed height, natural width: the work is a mix of tall A4 pieces and
   4:3 mockups, and a square crop would cut a third off the tall ones.
   Letting each keep its own proportions shows every piece whole and
   gives the strip an organic, uneven rhythm. */
.carousel__item {
  flex: 0 0 auto;
  height: clamp(180px, 21vw, 290px);
  overflow: hidden;
  cursor: pointer;
  background: var(--tint);
  opacity: 0.9;
  transition: opacity 0.4s ease;
}
.carousel__item:hover { opacity: 1; }
.carousel__item img {
  width: 100%;
  height: 100%;
  /* The slot is set to each picture's own ratio, so cover crops nothing. */
  object-fit: cover;
}

/* ============================================================
   4. WORKS — editorial layout, one work at a time,
      each given its own space and rhythm
============================================================ */
.works { padding-block: clamp(3.5rem, 9vw, 7rem); }
.works__head { margin-bottom: clamp(2.5rem, 7vw, 5rem); }
.works__heading {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.1;
  margin-top: 0.5rem;
}

.work {
  display: block;
  position: relative;   /* anchors the sprig in the channel beside it */
  margin-top: clamp(4rem, 11vw, 9.5rem);
}
.work:first-of-type { margin-top: 0; }

/* Asymmetric widths + alignment give each piece its own breathing room */
.work--wide    { width: min(100%, 64%); }
.work--medium  { width: min(100%, 52%); }
.work--narrow  { width: min(100%, 43%); }
.work--full    { width: min(100%, 72%); }
.work--left    { margin-right: auto; }
.work--right   { margin-left: auto; }
.work--center  { margin-inline: auto; }

.work__frame {
  overflow: hidden;
  background: var(--tint);
}
.work__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.9s ease;
}
.work:hover .work__frame img { transform: scale(1.03); }

/* ------------------------------------------------------------
   PRESSED-FLOWER SPRIGS
   Each piece is set to one side, leaving an empty channel opposite.
   These fill it and carry the hero's botanical language down the
   page. Purely decorative: they sit outside the card and ignore the
   pointer, so they never trigger the card's hover or its link.
------------------------------------------------------------ */
.work__sprig {
  position: absolute;
  top: var(--sprig-top, 50%);
  transform: translateY(-50%);
  height: auto;
  pointer-events: none;
  user-select: none;
}

/* Each sprig is sized and inset so it sits centred in the channel beside
   its piece, rather than hugging the card and leaving a void at the outer
   edge. Both numbers are a share of the piece's own width, so the channel
   is (100 − pieceWidth) / pieceWidth, and the inset is half of whatever
   the sprig does not use. Recompute the pair if you change a width. */
.work--wide   .work__sprig { width: 31%; }   /* 64% piece → 56.3% channel */
.work--narrow .work__sprig { width: 54%; }   /* 43% piece → 132.6% channel */
.work--medium .work__sprig { width: 42%; }   /* 52% piece → 92.3% channel */
.work--full   .work__sprig { width: 28%; }   /* 72% piece → 38.9% channel */

.work--wide.work--left    .work__sprig { left: 100%;  margin-left: 12.6%; }
.work--narrow.work--right .work__sprig { right: 100%; margin-right: 39.3%; }
.work--medium.work--left  .work__sprig { left: 100%;  margin-left: 25.1%; }
.work--medium.work--right .work__sprig { right: 100%; margin-right: 25.1%; }
.work--full.work--right   .work__sprig { right: 100%; margin-right: 5.5%; }

.work__meta {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-top: 1.1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--hairline);
}
.work__index {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: var(--accent);
  flex: 0 0 auto;
}
.work__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  line-height: 1.2;
  /* Shrink to the text rather than filling the row: an RTL title in a
     grown box would align to the far edge and float away from its index.
     dir="auto" still orders the characters correctly; this only decides
     where the block sits, and the page itself reads left to right. */
  flex: 0 1 auto;
  text-align: start;
}
.work__tag {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  flex: 0 0 auto;
  /* Logical, not physical: on a row flipped to rtl for a Hebrew title
     this pushes the tag to the left instead. */
  margin-inline-start: auto;
  opacity: 0.75;
}
.work:hover .work__title { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }

/* ============================================================
   5. ABOUT
============================================================ */
.about {
  padding-block: clamp(2.75rem, 6vw, 4.5rem);
  text-align: center;
}
.about__text {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.15rem, 2.4vw, 1.7rem);
  line-height: 1.35;
  /* Wide enough to set the sentence in two lines rather than four. */
  max-width: 47ch;
  /* Evens out the two lines instead of leaving a short second one. */
  text-wrap: balance;
  margin-inline: auto;
}
.about__text em { font-style: italic; }
.about__link {
  display: inline-block;
  margin-top: 1.75rem;
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--accent);
  padding-bottom: 2px;
  transition: border-color 0.3s ease;
}
.about__link:hover { border-color: var(--ink); }

/* ============================================================
   6. FOOTER
============================================================ */
.footer {
  padding-block: clamp(3rem, 7vw, 5.5rem);
  text-align: center;
}
.footer__email {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2.6vw, 1.75rem);
  font-weight: 400;
  display: inline-block;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.footer__email:hover { border-color: var(--accent); }
.footer__social {
  display: flex;
  justify-content: center;
  /* Each mark is cropped to its ink, so its bottom edge is its baseline.
     Aligning to flex-end therefore sits both marks on a shared baseline. */
  align-items: flex-end;
  gap: 1rem;
  margin-bottom: 1.75rem;
}
.footer__social a {
  display: block;
  padding: 6px;           /* nothing visible — just a usable tap target */
  opacity: 0.75;
  transition: opacity 0.3s ease, color 0.3s ease;
}
.footer__social a:hover { opacity: 1; color: var(--accent); }
.footer__social svg { display: block; width: auto; }

/* The two logos fill their artboards very differently — LinkedIn is a tall
   stacked mark, Behance a short wide wordmark — so equal box sizes look
   wrong. These heights are the ink itself, tuned so the letterforms read
   at the same size: Behance's cap height lands at 0.78 of LinkedIn's. */
.footer__social .icon-linkedin { height: 16px; }
.footer__social .icon-behance  { height: 12.5px; }
.footer__copy {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.7;
}

/* ============================================================
   LIGHTBOX (built from scratch)
============================================================ */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 5vw;
  background: rgba(60, 50, 50, 0.9);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.35s ease;
}
.lightbox.is-open { display: flex; opacity: 1; }
.lightbox__stage {
  display: grid;
  place-items: center;
  transform: scale(0.97);
  transition: transform 0.35s ease;
}
.lightbox.is-open .lightbox__stage { transform: scale(1); }
.lightbox__media {
  max-width: 90vw;
  max-height: 88vh;
  border-radius: 0;
}
.lightbox__close {
  position: absolute;
  top: 20px; right: 24px;
  width: 40px; height: 40px;
  border: 1px solid rgba(248, 246, 244, 0.4);
  background: transparent;
  color: var(--light);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background 0.3s ease;
}
.lightbox__close:hover { background: rgba(248, 246, 244, 0.14); }

/* ============================================================
   RESPONSIVE
============================================================ */
@media (max-width: 860px) {
  .work--wide,
  .work--medium,
  .work--narrow,
  .work--full { width: 100%; }
  /* Pieces run full width here, so there is no channel left to fill. */
  .work__sprig { display: none; }
}
@media (max-width: 760px) {
  /* At phone widths a 16:9 hero is short enough that the fixed nav would
     sit on top of the artwork, so give the nav its own band above it and
     let the section grow to fit the image. */
  .hero {
    aspect-ratio: auto;
    height: auto;
    padding-top: var(--nav-height);
  }
  .hero__stage { height: auto; width: 100%; }
}

@media (max-width: 640px) {
  /* Badge moves into the top-right corner, with the name and tagline
     running beneath it. */
  .intro__inner {
    display: block;
    position: relative;
  }
  .badge {
    position: absolute;
    top: 0;
    /* Offsets resolve against the padding box, so match the page gutter
       rather than sitting flush to the screen edge. */
    right: var(--gutter);
    width: 108px;
    height: 108px;
  }
  .intro__text { padding-right: 120px; }
  .work__meta { flex-wrap: wrap; row-gap: 0.35rem; }
  .work__tag { width: 100%; }
  .nav__links { gap: 0.9rem; }
  .nav__links a { font-size: 0.66rem; letter-spacing: 0.1em; }
}

/* ============================================================
   PROJECT PAGE
   Used by every file in /projects.
============================================================ */
.project-hero {
  position: relative;
  width: 100%;
  height: 62svh;
  min-height: 340px;
  overflow: hidden;
  background: var(--tint);
}
.project-hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.project-head { padding-block: clamp(2.5rem, 7vw, 4.5rem) 0; }
.project-index {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: var(--accent);
}
.project-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 1.05;
  margin-top: 0.35rem;
  text-align: left;   /* keeps a Hebrew title on the page's own margin */
}
/* Hebrew name sitting under the English one */
.project-title-he {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.15rem, 2.4vw, 1.6rem);
  line-height: 1.25;
  margin-top: 0.4rem;
  opacity: 0.75;
  /* dir="rtl" would push this to the far edge, reading as a second
     column rather than a line under the English name. The characters
     still order right-to-left; only the block sits on the page margin. */
  text-align: left;
}

/* ------------------------------------------------------------
   BILINGUAL WRITE-UP
   English block, then Hebrew below it. dir="rtl" on the Hebrew
   block flips its reading order and its alignment together, so
   nothing here needs to hard-code a side.
------------------------------------------------------------ */
.project-text__label {
  display: block;
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-bottom: 0.9rem;
}
.project-text + .project-text {
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding-top: clamp(2rem, 4vw, 2.75rem);
  border-top: 1px solid var(--hairline);
}

.project-lead {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1rem, 1.8vw, 1.25rem);
  max-width: 46ch;
  margin-top: 1rem;
}

/* Year / role / client */
.project-meta {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
  margin-top: clamp(2rem, 5vw, 3rem);
  padding-block: 1.25rem;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.project-meta dt {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.7;
}
.project-meta dd {
  font-size: 0.92rem;
  margin-top: 0.4rem;
}

.project-body {
  max-width: 62ch;
  padding-block: clamp(2.5rem, 6vw, 4rem);
}
.project-body p + p { margin-top: 1.1rem; }

/* ------------------------------------------------------------
   GALLERY — 5 to 7 media items (images or video).
   Alternate .media--full and .media--half; a trailing lone
   half-width item is promoted to full width by site.js.
------------------------------------------------------------ */
.gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
  align-items: start;
  padding-bottom: clamp(3rem, 7vw, 5rem);
}
.media {
  grid-column: span 1;
  margin: 0;
  overflow: hidden;
  background: var(--tint);
  cursor: zoom-in;
}
/* Cut-out artwork keeps its transparency, so the page ground shows through
   instead of the loading tint sitting behind it as a visible panel. */
.media--cutout { background: transparent; }
.media--full { grid-column: 1 / -1; }
.media img,
.media video {
  width: 100%;
  height: auto;
  display: block;
  transition: opacity 0.4s ease;
}
.media:hover img,
.media:hover video { opacity: 0.88; }
.media figcaption {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-top: 0.7rem;
}

/* Link through to the next project */
.project-next {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: clamp(2rem, 5vw, 3.5rem);
  border-top: 1px solid var(--hairline);
}
.project-next__label {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.7;
}
.project-next__title {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2.4vw, 1.75rem);
}
.project-next:hover .project-next__title {
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
}

@media (max-width: 640px) {
  .project-meta { grid-template-columns: 1fr; gap: 1rem; }
  .gallery { grid-template-columns: 1fr; }
  .media { grid-column: 1 / -1; }
}

