/* =========================================================
   GRID v7 · Woven Light HERO ONLY (first 100vh section)
   Loaded AFTER cinema.css. Styles ONLY the woven hero +
   its canvas/vignette overlay. Everything below the hero
   is governed by cinema.css (unchanged from v6/root).
   ========================================================= */

/* === v7 pass-15 · First-paint animation gate ===
   The brand-lock sting (.v7oi) and the Hero entrance keyframes are
   all paused by default and only flip to running once the inline
   <script> in index.html has set data-v7oi="ready" on <html> (which
   happens after a double rAF, i.e. after at least one paint frame).
   This guarantees the user sees the full opening sequence regardless
   of how long the page took to load. Without this gate, CSS keyframes
   start at "CSS apply" time and can complete invisibly before first
   paint on slow loads. */
.v7oi,
.v7oi-corner,
.v7oi-letter,
.v7oi-label,
.hw-letter,
.hero-sub,
.hero-lede,
.hero-cta-row,
.hero-scroll-cue,
.hero-scroll-arrow {
  animation-play-state: paused;
}
html[data-v7oi="ready"] .v7oi,
html[data-v7oi="ready"] .v7oi-corner,
html[data-v7oi="ready"] .v7oi-letter,
html[data-v7oi="ready"] .v7oi-label,
html[data-v7oi="ready"] .hw-letter,
html[data-v7oi="ready"] .hero-sub,
html[data-v7oi="ready"] .hero-lede,
html[data-v7oi="ready"] .hero-cta-row,
html[data-v7oi="ready"] .hero-scroll-cue,
html[data-v7oi="ready"] .hero-scroll-arrow {
  animation-play-state: running;
}

/* === Woven canvas (lives INSIDE .woven-hero in document flow) ===
   position: absolute makes it anchor to .woven-hero, so when the
   user scrolls, it scrolls up with the hero like any normal section
   child. No fixed/sticky/pin behavior — the canvas physically leaves
   the viewport from the top as section 1 exits. */
#woven-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
  display: block;
}

/* Outer vignette — also a child of .woven-hero, scrolls with it. */
.woven-vignette {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, transparent 24%, rgba(10, 10, 15, 0.55) 78%, rgba(10, 10, 15, 0.82) 100%);
}

/* === The hero section itself ===
   position: relative establishes the positioning context for the
   absolute canvas + vignette children. overflow: hidden so the
   canvas can't leak above/below the hero region. */
.woven-hero {
  position: relative;
  z-index: 5;
  min-height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 80px 24px 120px;
  overflow: hidden;
}

/* === Cinematic title-card scrim ===
   Sits ABOVE the canvas (z:0) and the vignette (z:1) but BELOW the
   text (z:3). The previous version had z-index:-1 which placed it
   behind the canvas, so it was effectively invisible and the text
   was reading directly against bright particle bands.

   The new scrim is a soft elliptical light-pocket: the particles stay
   fully visible at the section edges, the center is gently darkened
   just enough to seat the wordmark + Hebrew text + CTA in a readable
   lane without making the hero feel patched, flat, or heavy. No blur
   filter (was costing GPU and produced a mushy edge); the gradient's
   own stops do all the falloff work. */
.woven-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(
    ellipse 58% 42% at center,
    rgba(10, 10, 15, 0.78) 0%,
    rgba(10, 10, 15, 0.55) 28%,
    rgba(10, 10, 15, 0.28) 55%,
    rgba(10, 10, 15, 0.08) 80%,
    transparent 100%
  );
}

/* === Hero text elements sit above the absolute canvas + vignette ===
   position: relative + z-index lifts these in-flow elements above the
   absolute-positioned canvas (z:0) and vignette (z:1) inside the same
   .woven-hero stacking context. Without this, the canvas would paint
   over the text per the CSS painting order. */
.hero-wordmark,
.hero-sub,
.hero-lede,
.hero-cta-row {
  position: relative;
  z-index: 3;
}
.hero-scroll-cue { z-index: 3; }

/* === GRID wordmark (singular center attraction) === */
.hero-wordmark {
  margin: 0;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  /* Min lowered from 96 -> 64 so a 390px-wide phone (19vw = 74px)
     renders the wordmark at 74px instead of being forced up to 96px.
     The 96px floor was making the hero overflow 100vh on a 390x844
     viewport, pushing the CTA below the fold and crowding the scroll
     cue. The cap stays at 260px for very wide desktops. */
  font-size: clamp(64px, 19vw, 260px);
  line-height: 0.9;
  letter-spacing: -0.025em;
  color: #F5F7F8;
  direction: ltr;
  /* Shadows refined to actually do letterform definition. The previous
     pure-glow stack (80px white + 160px blue) was bleeding INTO the
     particles and made the wordmark feel smudgy. The scrim now handles
     the heavy contrast work, so the shadows can be tight and crisp:
     a short dark drop for edge definition + a soft halo that integrates
     the wordmark into the light pocket + a brand-blue rim for identity. */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.55),
    0 2px 14px rgba(0, 0, 0, 0.55),
    0 0 36px rgba(0, 0, 0, 0.40),
    0 0 72px rgba(59, 131, 247, 0.18);
}
.hw-letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(50px);
  will-change: opacity, transform;
  /* v7 pass-11: entrance moved from GSAP to CSS keyframes so it fires
     the moment the stylesheet is applied (during HTML parse) instead of
     after the whole 7-script defer chain finishes (three.js + gsap +
     ScrollTrigger + cinema.js + scenes-home.js + cinema-fx.js +
     woven.js). On a cold load that's roughly 300-500ms earlier — the
     real bottleneck on perceived "time until GRID is readable". */
  animation: hero-letter-in 0.05s cubic-bezier(0.215, 0.61, 0.355, 1) both;
}
/* v7 pass-17: Hero entrance delays shifted +0.30s (1.60s -> 1.90s)
   to stay locked to the new overlay fade-out start. Cross-dissolve
   begins at 1.90s, both finish around 2.18s. */
.hw-letter:nth-child(1) { animation-delay: 1.90s; }
.hw-letter:nth-child(2) { animation-delay: 1.91s; }
.hw-letter:nth-child(3) { animation-delay: 1.92s; }
.hw-letter:nth-child(4) { animation-delay: 1.93s; }
@keyframes hero-letter-in {
  to { opacity: 1; transform: translateY(0); }
}

/* The R is the brand-accent letter (mirrors v6 .hero-r pattern) */
.hw-letter--accent {
  color: #3B83F7;
  /* Crisp dark drop + tighter blue halo. Cleaner read on the bright
     particle bands and keeps the identity glow without bleeding into
     the surrounding white letters. */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.55),
    0 2px 14px rgba(0, 0, 0, 0.55),
    0 0 40px rgba(59, 131, 247, 0.55),
    0 0 90px rgba(59, 131, 247, 0.30);
}

/* === Hebrew subtitle (high contrast over particle band) === */
.hero-sub {
  margin: 40px 0 0;
  font-family: 'Heebo', sans-serif;
  font-weight: 500;
  font-size: clamp(22px, 2.6vw, 32px);
  letter-spacing: 0.06em;
  color: #F5F7F8;
  opacity: 0;
  transform: translateY(20px);
  /* v7 pass-17: delay shifted to 1.96s (intro offset 1.90s + 0.06s). */
  animation: hero-text-in 0.10s cubic-bezier(0.215, 0.61, 0.355, 1) 1.96s both;
  /* width:100% caps the sub at the hero's content area so a long
     Hebrew title can never visually clip past the viewport edge on
     a narrow phone. */
  width: 100%;
  max-width: 640px;
  will-change: opacity, transform;
  /* Layered drop + tight halo. The scrim plus these two shadow layers
     keeps the Hebrew at full premium #F5F7F8 (not a dimmed grey) while
     reading cleanly against the densest part of the particle torus. */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.75),
    0 2px 10px rgba(0, 0, 0, 0.55),
    0 0 28px rgba(0, 0, 0, 0.45);
}

.hero-lede {
  margin: 18px auto 0;
  font-family: 'Heebo', sans-serif;
  font-weight: 400;
  /* Bumped the cap from 18 -> 19px so the lede holds its weight at
     1440+ widths; the body now feels equally important to the sub
     instead of a footnote. */
  font-size: clamp(15px, 1.55vw, 19px);
  line-height: 1.65;
  /* Lifted from #C9CDD4 to a slightly warmer near-white so the lede
     reads as part of the same hero stack as the sub instead of fading
     into the particles. The scrim provides the contrast back. */
  color: #DDE1E6;
  opacity: 0;
  transform: translateY(20px);
  /* v7 pass-17: delay shifted to 2.02s (intro offset 1.90s + 0.12s). */
  animation: hero-text-in 0.10s cubic-bezier(0.215, 0.61, 0.355, 1) 2.02s both;
  /* width:100% + max-width caps the lede to the lesser of 520px or the
     hero's content box. Without width:100%, a flex item with only
     max-width can grow past the parent's content area when its natural
     content (long Hebrew lede) wants to be wider than max-width, which
     was clipping the right edge of the lede on a 390px phone. */
  width: 100%;
  max-width: 520px;
  will-change: opacity, transform;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.65),
    0 0 20px rgba(0, 0, 0, 0.45);
}

/* === Hero CTA (scoped via .woven-hero to avoid collision with cinema's .cta) === */
.hero-cta-row {
  margin-top: 44px;
  opacity: 0;
  transform: translateY(20px);
  will-change: opacity, transform;
  /* v7 pass-17: delay shifted to 2.08s (intro offset 1.90s + 0.18s). */
  animation: hero-text-in 0.10s cubic-bezier(0.215, 0.61, 0.355, 1) 2.08s both;
}
/* Shared keyframe for sub / lede / CTA: slide up + fade in. */
@keyframes hero-text-in {
  to { opacity: 1; transform: translateY(0); }
}
.woven-hero .hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 14px 30px;
  border-radius: 999px;
  /* Bumped the glass fill (0.07 -> 0.10) and the border (0.20 -> 0.32)
     so the pill reads as deliberate rather than as a faint outline lost
     in the particle field. The drop shadow seats it on the scrim
     without making it feel heavy. */
  background: rgba(255, 255, 255, 0.10);
  border: 1.5px solid rgba(255, 255, 255, 0.32);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 28px -10px rgba(0, 0, 0, 0.55);
  color: #F5F7F8;
  font-family: 'Heebo', sans-serif;
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: background 280ms ease, border-color 280ms ease, transform 200ms ease, box-shadow 280ms ease;
}
.woven-hero .hero-cta:hover {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.46);
  box-shadow: 0 12px 36px -10px rgba(59, 131, 247, 0.45);
}
.woven-hero .hero-cta:active { transform: scale(0.98); }
.woven-hero .hero-cta-arrow {
  font-size: 16px;
  display: inline-block;
  transition: transform 220ms ease;
}
.woven-hero .hero-cta:hover .hero-cta-arrow { transform: translateX(-4px); }

/* === Scroll cue (invites continuation into the cinematic story) === */
.hero-scroll-cue {
  position: absolute;
  bottom: 36px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-family: 'Heebo', sans-serif;
  font-size: 10px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: #C9CDD4;
  opacity: 0;
  /* v7 pass-16: cue shifted to 2.00s start (intro fade ends at 1.85s,
     cue follows shortly after). Fade and pulse durations unchanged. */
  animation: woven-cue-fade-in 0.35s ease-out 2.00s forwards, woven-cue-pulse 2.4s ease-in-out 2.35s infinite;
  pointer-events: none;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.hero-scroll-arrow {
  font-size: 14px;
  display: inline-block;
  /* v7 pass-16: bounce shifted to 2.35s to follow the cue fade. */
  animation: woven-cue-bounce 2s ease-in-out 2.35s infinite;
}
@keyframes woven-cue-fade-in {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to   { opacity: 0.85; transform: translate(-50%, 0); }
}
@keyframes woven-cue-pulse {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 0.95; }
}
@keyframes woven-cue-bounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(5px); }
}

/* === Mobile tuning for the woven hero only === */
@media (max-width: 480px) {
  .woven-hero { padding: 60px 18px 100px; }
  .hero-sub { margin-top: 24px; }
  .woven-hero .hero-cta { padding: 12px 24px; font-size: 14px; }
  /* v7 pass-40: width was calc(100vw - 36px). On an RTL document `100vw`
     resolves against the viewport INCLUDING any overflow, which combined
     with the fixed brand-lock overlay pushed the layout to ~441px on a
     390px phone — shoving the hero off-centre and clipping scene text on
     the right edge. `100%` resolves against the padded hero box instead,
     so it can never exceed the real inline area. The global overflow-x
     guard at the foot of this file backstops any other stray overflow. */
  .hero-sub,
  .hero-lede {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }
}

/* === Scene 1 (The Noise) layout: KEEP cinema.css defaults ===
   Earlier rounds tried to shrink scene 1's min-height to remove the
   "dead scroll" feeling after the headline reveal. That broke scene
   2's panel:canvas alignment because the cinema engine's master ST
   allocates uniform canvas time per scene (1/6 of span) while panel
   positions advance by each scene's actual height. Diverging scene 1
   from the 70vh rhythm cascaded into scene 2 lag. The dead-scroll
   perception is now addressed via a longer panel-reveal scrub for
   scene 1 in v7/js/cinema.js (`end: 'top -50%'` instead of `top -10%`),
   so the panel content keeps physically arriving through most of
   scene 1's 70vh scroll range instead of a quick 50vh scrub followed
   by static panel. */

/* =========================================================
   === v7 pass-14 · PRE-HERO BRAND-LOCK INTRO STING ========
   =========================================================
   Pure CSS keyframes, ~1.0s total user-perceived time. Mirrors the
   v6/root "01 / Opening" brand-lock visual language (4 square cell
   frames with corner brackets + GRID letters on a faint blueprint
   grid + small "A DIGITAL STUDIO" label) but compressed dramatically
   into a sharp brand sting.

   Timing:
     0.00s .. 0.16s  corner brackets snap in (16 corners with stagger)
     0.05s .. 0.40s  GRID letters fade up + de-blur (0.05s stagger)
     0.22s .. 0.40s  bottom label fades in
     0.40s .. 0.80s  hold (everything visible, brand moment)
     0.80s .. 1.00s  overlay cross-dissolves out (visibility:hidden)
     0.80s onwards   underlying Woven Hero entrance fires (CSS keyframes
                     above were shifted by +0.80s exactly for this)

   No JavaScript. Reduced-motion users skip the sting entirely. */

.v7oi {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: radial-gradient(120% 90% at 50% 55%, #0E0E16 0%, #08080D 55%, #050509 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  /* v7 pass-17: gentle pacing bump. Hold 1.60s -> 1.90s, fade 0.25s
     -> 0.28s. Total intro ~2.18s (was 1.85s). +0.33s of breathing
     room so the GRID-square reads as premium rather than rushed,
     still well under the v6/root opening (~4s+). */
  animation: v7oi-out 0.28s ease-in 1.90s forwards;
}
@keyframes v7oi-out {
  to { opacity: 0; visibility: hidden; }
}

.v7oi-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right,  rgba(245, 247, 248, 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(245, 247, 248, 0.045) 1px, transparent 1px);
  background-size: 60px 60px;
  mask-image: radial-gradient(140% 100% at 50% 55%, #000 35%, rgba(0, 0, 0, 0.35) 75%, transparent 100%);
  -webkit-mask-image: radial-gradient(140% 100% at 50% 55%, #000 35%, rgba(0, 0, 0, 0.35) 75%, transparent 100%);
  pointer-events: none;
}

.v7oi-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(1400px, 84vw);
  height: min(460px, 38vh);
  transform: translate(-50%, -50%);
  background: radial-gradient(60% 70% at 50% 50%, rgba(111, 168, 255, 0.20) 0%, rgba(111, 168, 255, 0.06) 40%, transparent 75%);
  filter: blur(22px);
  pointer-events: none;
}

.v7oi-stage {
  position: relative;
  width: min(1240px, 84vw);
  height: min(380px, 34vh);
}

.v7oi-cells {
  position: absolute;
  inset: 0;
  display: flex;
  gap: clamp(8px, 1.6vw, 28px);
}

.v7oi-cell {
  position: relative;
  flex: 1 1 0;
  height: 100%;
}

.v7oi-corner {
  position: absolute;
  width: 14px;
  height: 14px;
  border: 1px solid #6FA8FF;
  opacity: 0;
  animation: v7oi-corner-in 0.16s cubic-bezier(0.215, 0.61, 0.355, 1) both;
}
.v7oi-corner.tl { top: -1px; left:  -1px; border-right:  0; border-bottom: 0; animation-delay: 0s;    }
.v7oi-corner.tr { top: -1px; right: -1px; border-left:   0; border-bottom: 0; animation-delay: 0.02s; }
.v7oi-corner.bl { bottom: -1px; left:  -1px; border-right: 0; border-top: 0; animation-delay: 0.04s; }
.v7oi-corner.br { bottom: -1px; right: -1px; border-left:  0; border-top: 0; animation-delay: 0.06s; }
@keyframes v7oi-corner-in {
  to { opacity: 1; }
}

.v7oi-wordmark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  gap: clamp(8px, 1.6vw, 28px);
  width: 100%;
  font-family: 'Space Grotesk', 'Heebo', system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(80px, 14vw, 220px);
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: #F5F7F8;
  text-align: center;
  text-shadow: 0 0 40px rgba(111, 168, 255, 0.22), 0 2px 8px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

.v7oi-letter {
  flex: 1 1 0;
  opacity: 0;
  /* v7 pass-17: per-letter duration 0.32s -> 0.38s, stagger
     0.10s -> 0.12s. Letters land 0.12 -> 0.86s (was 0.10 -> 0.72s).
     Small bump only -- adds breath between G/R/I/D without slowing
     the overall rhythm. */
  animation: v7oi-letter-in 0.38s cubic-bezier(0.215, 0.61, 0.355, 1) both;
}
.v7oi-letter:nth-child(1) { animation-delay: 0.12s; }
.v7oi-letter:nth-child(2) { animation-delay: 0.24s; }
.v7oi-letter:nth-child(3) { animation-delay: 0.36s; }
.v7oi-letter:nth-child(4) { animation-delay: 0.48s; }
@keyframes v7oi-letter-in {
  from { opacity: 0; transform: translateY(14px); filter: blur(6px); }
  to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
}
.v7oi-letter--accent {
  color: #6FA8FF;
  text-shadow: 0 0 60px rgba(111, 168, 255, 0.65), 0 2px 8px rgba(0, 0, 0, 0.55);
}

.v7oi-label {
  position: absolute;
  bottom: clamp(40px, 7vh, 80px);
  left: 50%;
  transform: translateX(-50%);
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: clamp(10px, 1.1vw, 13px);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(245, 247, 248, 0.42);
  white-space: nowrap;
  opacity: 0;
  /* v7 pass-17: label shifted to follow the slower letters
     (last letter ends at 0.86s, label starts at 0.80s, ends 1.12s). */
  animation: v7oi-label-in 0.32s ease-out 0.80s both;
  pointer-events: none;
}
@keyframes v7oi-label-in {
  to { opacity: 1; }
}

/* === Reduced-motion: kill the woven canvas, force hero text visible.
       cinema.css already handles reduced-motion for the rest of the page. === */
@media (prefers-reduced-motion: reduce) {
  .hw-letter,
  .hero-sub,
  .hero-lede,
  .hero-cta-row {
    opacity: 1 !important;
    transform: none !important;
    will-change: auto !important;
    /* v7 pass-11: kill the new CSS keyframe entrance under reduced
       motion (matches the original GSAP-disabled behaviour). */
    animation: none !important;
  }
  .hero-scroll-cue {
    opacity: 0.8 !important;
    animation: none !important;
  }
  .hero-scroll-arrow { animation: none !important; }
  #woven-canvas { display: none; }
  .woven-vignette { background: rgba(10, 10, 15, 0.4); }
  /* v7 pass-14: pre-Hero brand-lock overlay is purely decorative —
     skip the sting entirely under reduced motion. */
  .v7oi { display: none; }
}

/* =================================================================
   v7 pass-22 · Cinematic typography readability pass
   -----------------------------------------------------------------
   Every rule here is scoped to `.cinema .panel ...`, which only
   exists inside the six cinematic scenes (01 The Noise → 06 The
   Next System). The Woven Light hero uses `.woven-hero .hw-letter
   / .hero-sub / .hero-lede / .hero-cta` and is NOT matched, so the
   hero typography is preserved exactly as the user signed off on.

   Goals: larger headlines, larger body, layered drop-shadow on every
   supporting line so the chaos / wireframe / particle canvases never
   swallow the copy. Premium feel maintained — sizes scale via clamp,
   shadows are soft (no harsh outlines), kicker stays restrained.

   Since woven.css is only linked from v7/index.html, these rules
   cannot leak to root / v6 / other pages.
   ================================================================= */

/* --- Main headlines -------------------------------------------- */
/* v7 pass-23 retune: pass-22's 88/112 caps felt slightly oversized
   on desktop. Pulled both clamps back ~10% while keeping a clear bump
   over the original cinema.css values (76/96). Still strong and
   dominant, just no longer screaming. */
.cinema .panel .title {
  font-size: clamp(36px, 8.2vw, 80px);
  line-height: 1.06;
  letter-spacing: -0.022em;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.70),
    0 2px 12px rgba(0, 0, 0, 0.45),
    0 0 36px rgba(0, 0, 0, 0.30);
}
.cinema .panel .title.big {
  font-size: clamp(44px, 10vw, 100px);
  line-height: 1.04;
}

/* The accent words (the <em>) inherit the title's shadow but get a
   tighter blue halo so the colour pop reads cleanly over chaos. */
.cinema .panel .title em {
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.70),
    0 2px 12px rgba(0, 0, 0, 0.45),
    0 0 28px rgba(59, 131, 247, 0.32);
}

/* --- Supporting body copy -------------------------------------- */
/* v7 pass-23: bumped another notch (mobile floor 17 → 18, desktop cap
   20 → 22). Colour pushed slightly brighter (#E2E6EC → #E6EAEF) and
   the shadow stack reinforced (mid-range alpha 0.65 → 0.78, blur
   10 → 14, ambient blur 28 → 36) so the lines sit visibly forward of
   the chaos / wireframe / particle canvases on every scene. */
.cinema .panel .body {
  font-size: clamp(18px, 4.7vw, 20px);
  line-height: 1.68;
  color: #E6EAEF;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.90),
    0 2px 14px rgba(0, 0, 0, 0.78),
    0 0 36px rgba(0, 0, 0, 0.55);
}
@media (min-width: 768px) {
  .cinema .panel .body {
    font-size: clamp(19px, 1.55vw, 22px);
    line-height: 1.62;
  }
}
.cinema .panel .body.lg {
  font-size: clamp(19px, 5vw, 22px);
  line-height: 1.6;
}
@media (min-width: 768px) {
  .cinema .panel .body.lg {
    font-size: clamp(20px, 1.7vw, 24px);
    line-height: 1.58;
  }
}

/* --- Lede (used by a couple of scenes) ------------------------- */
.cinema .panel .lede {
  font-size: clamp(18px, 4.8vw, 21px);
  line-height: 1.6;
  color: #E6EAEF;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.90),
    0 2px 14px rgba(0, 0, 0, 0.78),
    0 0 36px rgba(0, 0, 0, 0.55);
}
@media (min-width: 768px) {
  .cinema .panel .lede {
    font-size: clamp(19px, 1.6vw, 23px);
  }
}

/* --- Kicker (chapter label) ------------------------------------ */
/* Restrained bump — kicker holds hierarchy as the smallest element,
   but the previous 11px was disappearing on dense backgrounds. */
.cinema .panel .kicker {
  font-size: 12px;
  letter-spacing: 0.24em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.65);
}
@media (min-width: 768px) {
  .cinema .panel .kicker { font-size: 13px; }
}

/* --- Capabilities list (scene 4) ------------------------------- */
/* v7 pass-23: caps text moves up with the body bump so the list
   keeps a consistent weight inside the panel hierarchy. Shadow stack
   matches the body's reinforced layers. */
.cinema .panel .caps-t {
  font-size: clamp(17px, 4.5vw, 20px);
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.88),
    0 2px 12px rgba(0, 0, 0, 0.65);
}
@media (min-width: 768px) {
  .cinema .panel .caps-t {
    font-size: clamp(18px, 1.45vw, 21px);
  }
}
.cinema .panel .caps-n {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.70);
}

/* --- Closing CTA paragraph (scene 6 contact line) -------------- */
.cinema .panel .contact-line {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.70);
}

/* =================================================================
   v7 pass-25 · Dual-channel CTAs (WhatsApp + Email)
   -----------------------------------------------------------------
   Hero and scene-6 closing CTA both expose two contact buttons:
   a primary WhatsApp pill and a ghost-style Email pill. All rules
   scoped to .woven-hero / .cinema .panel so they cannot leak.
   ================================================================= */

/* --- Hero CTA row: flex layout for the two buttons ------------- */
.woven-hero .hero-cta-row {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  align-items: center;
}
.woven-hero .hero-cta {
  position: relative;
}
.woven-hero .hero-cta-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  /* SVG inherits via currentColor so it tracks the text colour. */
  color: currentColor;
}
/* Ghost variant for the email button — same shape, no fill, lighter
   border so the WhatsApp pill remains the primary action. */
.woven-hero .hero-cta--ghost {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.22);
  box-shadow: 0 4px 18px -12px rgba(0, 0, 0, 0.40);
}
.woven-hero .hero-cta--ghost:hover {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.36);
  box-shadow: 0 8px 24px -12px rgba(0, 0, 0, 0.55);
}

/* --- Scene-6 closing CTA: side-by-side button pair ------------- */
.cinema .panel .cta-pair {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  align-items: center;
  margin-block: 12px 8px;
}
.cinema .panel .cta-pair .cta-magnet {
  /* magnet wrapper is inline by default; ensure each pill is its own
     hit target and gets its own magnetic transform stack. */
  display: inline-flex;
}
.cinema .panel .cta-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  margin-inline-end: 4px;
  color: currentColor;
}
/* Ghost variant of cinema's .cta — kept inside .cinema .panel so it
   inherits .cta sizing/typography from cinema.css but overrides the
   accent fill with a transparent ghost treatment. */
.cinema .panel .cta.cta--ghost {
  background: transparent;
  border: 1.5px solid rgba(245, 247, 248, 0.32);
  color: #F5F7F8;
  box-shadow: 0 4px 18px -12px rgba(0, 0, 0, 0.45);
}
.cinema .panel .cta.cta--ghost:hover {
  background: rgba(245, 247, 248, 0.08);
  border-color: rgba(245, 247, 248, 0.50);
  box-shadow: 0 10px 28px -12px rgba(0, 0, 0, 0.55);
}

/* --- Mobile: stack the CTA pair when there's no room ----------- */
@media (max-width: 480px) {
  .woven-hero .hero-cta-row,
  .cinema .panel .cta-pair {
    flex-direction: column;
    width: 100%;
  }
  .woven-hero .hero-cta-row > .hero-cta,
  .cinema .panel .cta-pair > .cta-magnet { width: 100%; }
  .cinema .panel .cta-pair > .cta-magnet > .cta { width: 100%; justify-content: center; }
  .woven-hero .hero-cta { justify-content: center; }
}

/* =================================================================
   v7 pass-34 · "Design. Code. Scale." brand signet
   -----------------------------------------------------------------
   A designed three-part premium module that crystallises the GRID
   motto. Sits between the cinematic engine and the outro footer
   (see v7/index.html for the markup). Pure CSS reveal driven by a
   one-shot IntersectionObserver (see inline script in index.html);
   no scroll-spy, no GSAP dependency, no impact on scene math.

   Mobile-first: single column stack with comfortable spacing. At
   ≥ 768px the three columns lay out side-by-side with a thin
   gradient rule between each pair. Words stay LTR English; Hebrew
   descriptors fill the meaning below each word.
   ================================================================= */

.brand-signet {
  position: relative;
  z-index: 3;
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(56px, 9vw, 96px) clamp(20px, 5vw, 64px);
  text-align: center;
}
.signet-rule {
  width: 100%;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(245, 247, 248, 0.16) 20%,
    rgba(245, 247, 248, 0.22) 50%,
    rgba(245, 247, 248, 0.16) 80%,
    transparent 100%);
}
.signet-tag {
  display: inline-block;
  margin: clamp(28px, 4vw, 44px) 0 clamp(36px, 6vw, 64px);
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(10px, 1.05vw, 11px);
  font-weight: 500;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(245, 247, 248, 0.55);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
.signet-tag::before,
.signet-tag::after {
  content: '';
  display: inline-block;
  width: clamp(18px, 3vw, 30px);
  height: 1px;
  background: rgba(245, 247, 248, 0.30);
  vertical-align: middle;
  margin: 0 clamp(10px, 1.6vw, 18px);
}

.signet-stack {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(40px, 6vw, 56px);
  /* The grid items host English headings + numbers; keep flow LTR so
     "01 / 02 / 03" reads correctly on every device irrespective of
     the document's RTL direction. */
  direction: ltr;
}
@media (min-width: 768px) {
  .signet-stack {
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(24px, 4vw, 56px);
  }
}

.signet-col {
  position: relative;
  padding: 0 clamp(8px, 1.6vw, 20px);
}
/* Thin gradient separator between columns at tablet+ only. RTL doc
   plus LTR grid means visual column order = DOM order = 01,02,03;
   the rule sits on the right of each non-last column. */
@media (min-width: 768px) {
  .signet-col:not(:last-child)::after {
    content: '';
    position: absolute;
    top: 12%;
    right: 0;
    width: 1px;
    height: 76%;
    background: linear-gradient(180deg,
      transparent 0%,
      rgba(245, 247, 248, 0.14) 50%,
      transparent 100%);
  }
}

.signet-num {
  display: block;
  margin-bottom: clamp(10px, 1.6vw, 16px);
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(11px, 1.1vw, 12px);
  font-weight: 500;
  letter-spacing: 0.28em;
  color: rgba(111, 168, 255, 0.85);
}
.signet-word {
  margin: 0 0 clamp(14px, 2vw, 20px);
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(44px, 7vw, 84px);
  line-height: 0.96;
  letter-spacing: -0.025em;
  color: #F5F7F8;
  text-shadow:
    0 2px 12px rgba(0, 0, 0, 0.55),
    0 0 36px rgba(59, 131, 247, 0.10);
}
.signet-meaning {
  margin: 0 auto;
  max-width: 22ch;
  font-family: 'Heebo', sans-serif;
  font-size: clamp(14px, 1.1vw, 15px);
  font-weight: 400;
  line-height: 1.65;
  color: rgba(221, 225, 230, 0.92);
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.80),
    0 2px 10px rgba(0, 0, 0, 0.50);
  /* The descriptor itself contains Hebrew, so flip back to RTL for
     its content even though the parent grid was set to LTR for the
     numerals. */
  direction: rtl;
}

.signet-tagline {
  margin: clamp(40px, 6vw, 64px) 0 clamp(20px, 3.5vw, 36px);
  font-family: 'Heebo', sans-serif;
  font-size: clamp(14px, 1.15vw, 17px);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(245, 247, 248, 0.68);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.65);
}

/* --- Reveal animation (one-shot, no scroll-spy) --- */
/* Initial state — hidden until the section comes into view. The
   inline IntersectionObserver in v7/index.html adds .is-revealed
   once, then disconnects. */
.brand-signet .signet-tag,
.brand-signet .signet-col,
.brand-signet .signet-tagline {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.7s ease-out,
    transform 0.7s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.brand-signet.is-revealed .signet-tag       { transition-delay: 0s;    }
.brand-signet.is-revealed .signet-col:nth-child(1) { transition-delay: 0.10s; }
.brand-signet.is-revealed .signet-col:nth-child(2) { transition-delay: 0.22s; }
.brand-signet.is-revealed .signet-col:nth-child(3) { transition-delay: 0.34s; }
.brand-signet.is-revealed .signet-tagline   { transition-delay: 0.50s; }
.brand-signet.is-revealed .signet-tag,
.brand-signet.is-revealed .signet-col,
.brand-signet.is-revealed .signet-tagline {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .brand-signet .signet-tag,
  .brand-signet .signet-col,
  .brand-signet .signet-tagline {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* =================================================================
   v7 pass-34 · Mobile safe area for the fixed bottom-right pill
   -----------------------------------------------------------------
   The site-wide floating navigation lives at bottom: 12px on mobile
   (~40px tall × ~190px wide). Without bottom-padding on the LAST
   pieces of the document (final cinematic scene, brand signet,
   outro), the pill would visually overlap a CTA, the contact-line,
   or the grid-studio.online link on a short phone viewport. These
   rules add a 60-90px safe area only at small widths so the pill
   floats over empty space, not content.
   ================================================================= */
@media (max-width: 767px) {
  .scene[data-scene="6"] .panel { padding-block-end: 80px; }
  .brand-signet { padding-block-end: 96px; }
  .outro        { padding-block-end: 80px; }
}

/* =================================================================
   v7 pass-38 · Mobile Hero text readability
   -----------------------------------------------------------------
   Mirrors the pass-37 treatment, but for the Woven Light hero
   (.woven-hero ...). Lifts the Hebrew subtitle and lede to pure
   #FFFFFF and strengthens their layered text-shadow so the copy
   reads cleanly over the particle torus on phones. Affects ONLY
   colour and text-shadow — animation properties (delay, duration,
   easing, transforms) are untouched so the existing hero entrance
   timing remains identical. Desktop ≥768px keeps the pass-17/22
   styling.
   ================================================================= */
@media (max-width: 767px) {
  .woven-hero .hero-sub,
  .woven-hero .hero-lede {
    color: #FFFFFF;
    text-shadow:
      0 1px 2px rgba(0, 0, 0, 0.95),
      0 2px 14px rgba(0, 0, 0, 0.85),
      0 0 32px rgba(0, 0, 0, 0.65);
  }
  /* GRID letters: existing white + blue halo is correct visually,
     but a slightly stronger crisp drop helps over busy particle
     bands without losing the brand halo. */
  .woven-hero .hw-letter {
    text-shadow:
      0 2px 3px rgba(0, 0, 0, 0.85),
      0 0 22px rgba(0, 0, 0, 0.55),
      0 0 36px rgba(0, 0, 0, 0.45),
      0 0 72px rgba(59, 131, 247, 0.20);
  }
  /* CTA labels — keep the pill glass aesthetic, just ensure the
     label stays readable on a busy backdrop. */
  .woven-hero .hero-cta,
  .woven-hero .hero-cta-label {
    color: #FFFFFF;
  }
  .woven-hero .hero-cta-label {
    text-shadow:
      0 1px 2px rgba(0, 0, 0, 0.85),
      0 2px 10px rgba(0, 0, 0, 0.55);
  }
}

/* =================================================================
   v7 pass-37 · Mobile subtitle readability
   -----------------------------------------------------------------
   On phones, the pass-23 #E6EAEF body colour was reading slightly
   grey against the chaos and wireframe canvases. This block lifts
   ALL supporting text inside .cinema .panel (body / body.lg / lede)
   AND inside .brand-signet (signet-meaning) to a crisp #FFFFFF on
   small viewports, and strengthens the layered shadow so it sits
   visibly forward of the canvas without feeling heavy. Desktop
   styling from pass-23 is preserved.
   ================================================================= */
@media (max-width: 767px) {
  .cinema .panel .body,
  .cinema .panel .body.lg,
  .cinema .panel .lede,
  .brand-signet .signet-meaning {
    color: #FFFFFF;
    text-shadow:
      0 1px 2px rgba(0, 0, 0, 0.95),
      0 2px 14px rgba(0, 0, 0, 0.85),
      0 0 32px rgba(0, 0, 0, 0.65);
  }
}

/* =================================================================
   v7 pass-28 · Side-nav rules moved out of this file.
   All .v7-sidenav styles now live in /css/v7-sidenav.css and are
   linked from every page that hosts the site nav (V7 home + the
   root auxiliary pages). The pass-27 `.chapters { display: none }`
   override was also removed: the cinematic chapter rail is back to
   visible on V7 because the new site nav sits at top-right and the
   chapter dots sit at center-right — two separate UI concerns,
   visually distinct positions. See /css/v7-sidenav.css for the
   site-nav styles, and css/cinema.css for the chapter rail.
   ================================================================= */

/* =================================================================
   v7 pass-40 · GLOBAL OVERFLOW GUARD
   Backstops the mobile horizontal wobble. overflow-x is clipped on
   both the root and body; max-width pins them to the real viewport so
   no stray element can widen the scrollable area. Vertical scroll and
   the GSAP ScrollTrigger story are unaffected (only the X axis clips).
   .v7oi is also clipped so its corner brackets can't bleed outward.

   IMPORTANT: overflow-x MUST be `clip`, not `hidden`. `hidden` promotes
   overflow-y to `auto` (CSS spec), making <html> a scroll container,
   which breaks the cinematic `position: sticky` stage (it scrolls away
   instead of pinning). `clip` clips the X axis WITHOUT creating a scroll
   container, so sticky + ScrollTrigger keep working and mobile stays fixed.
   ================================================================= */
html, body { max-width: 100%; overflow-x: clip; }
.v7oi { overflow: hidden; }

/* =================================================================
   v7 pass-40 · PROOF TEASER (slim strip between hero and cinema)
   ================================================================= */
.proof-teaser {
  position: relative;
  z-index: 3;
  background: #07070B;
  border-block: 1px solid rgba(245, 247, 248, 0.06);
}
.pt-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 16px 22px;
  display: flex;
  align-items: center;
  gap: 18px;
  text-decoration: none;
  color: #E6EAEF;
  flex-wrap: wrap;
}
.pt-eyebrow {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.28em;
  color: rgba(245, 247, 248, 0.42);
  flex: 0 0 auto;
}
.pt-thumbs { display: flex; gap: 8px; flex: 0 0 auto; }
.pt-thumbs img {
  width: 64px; height: 40px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid rgba(245, 247, 248, 0.12);
  filter: saturate(0.85) brightness(0.82);
  transition: filter 0.35s ease, transform 0.35s ease;
}
.pt-inner:hover .pt-thumbs img { filter: none; }
.pt-text {
  font-size: 15px;
  color: rgba(245, 247, 248, 0.78);
  flex: 1 1 auto;
  min-width: 0;
}
.pt-cta { color: #6FA8FF; margin-inline-start: 8px; white-space: nowrap; }
@media (max-width: 600px) {
  .pt-inner { gap: 12px 14px; }
  .pt-eyebrow { width: 100%; }
  .pt-thumbs img { width: 54px; height: 34px; }
  .pt-text { font-size: 13.5px; }
}

/* =================================================================
   v7 pass-40 · SELECTED WORK / עבודות נבחרות — editorial showcase
   ================================================================= */
.selwork {
  position: relative;
  z-index: 3;
  background: linear-gradient(180deg, #0A0A0F 0%, #08080D 100%);
  padding: clamp(72px, 10vw, 140px) clamp(20px, 5vw, 64px);
}
.selwork-head {
  max-width: 880px;
  margin: 0 auto clamp(48px, 6vw, 84px);
  text-align: center;
}
.selwork-eyebrow {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 12px;
  letter-spacing: 0.3em;
  color: #6FA8FF;
  margin: 0 0 16px;
}
.selwork-title {
  font-family: 'Heebo', system-ui, sans-serif;
  font-weight: 900;
  font-size: clamp(34px, 6vw, 60px);
  color: #F5F7F8;
  letter-spacing: -0.02em;
  margin: 0 0 18px;
}
.selwork-intro {
  font-size: clamp(15px, 2vw, 18px);
  line-height: 1.7;
  color: rgba(245, 247, 248, 0.7);
  margin: 0;
}
.selwork-list {
  list-style: none;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(56px, 8vw, 120px);
}
.selwork-row {
  display: grid;
  grid-template-columns: 1.12fr 0.88fr;
  align-items: center;
  gap: clamp(28px, 4vw, 64px);
  opacity: 0;
  transform: translateY(42px);
  transition: opacity 0.85s cubic-bezier(0.215, 0.61, 0.355, 1),
              transform 0.85s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.selwork-row.is-revealed { opacity: 1; transform: none; }
/* Alternate the editorial rhythm: even rows put the media on the
   other side. order on .selwork-media flips it within the grid. */
.selwork-row:nth-child(even) { grid-template-columns: 0.88fr 1.12fr; }
.selwork-row:nth-child(even) .selwork-media { order: 2; }

.selwork-media {
  position: relative;
  display: block;
  border-radius: 16px;
  overflow: hidden;
  text-decoration: none;
  box-shadow: 0 30px 80px -42px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(245, 247, 248, 0.06);
  transition: transform 0.5s cubic-bezier(0.215, 0.61, 0.355, 1), box-shadow 0.5s ease;
}
.selwork-media:hover {
  transform: translateY(-6px);
  box-shadow: 0 44px 110px -38px rgba(0, 0, 0, 0.9),
              0 0 70px -22px rgba(111, 168, 255, 0.5),
              0 0 0 1px rgba(111, 168, 255, 0.28);
}
.selwork-frame { display: block; }
.selwork-frame img { display: block; width: 100%; height: auto; }
.selwork-live {
  position: absolute;
  top: 14px;
  inset-inline-start: 14px;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: #9FE7B8;
  background: rgba(8, 8, 13, 0.62);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid rgba(159, 231, 184, 0.28);
}
.selwork-kicker {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 12px;
  letter-spacing: 0.22em;
  color: rgba(245, 247, 248, 0.45);
  margin: 0 0 12px;
}
.selwork-name {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 600;
  font-size: clamp(26px, 3.4vw, 40px);
  color: #F5F7F8;
  letter-spacing: -0.01em;
  margin: 0 0 14px;
}
.selwork-desc {
  font-size: clamp(15px, 1.6vw, 17px);
  line-height: 1.75;
  color: rgba(245, 247, 248, 0.72);
  margin: 0 0 20px;
}
.selwork-tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0;
  margin: 0 0 24px;
}
.selwork-tags li {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: rgba(245, 247, 248, 0.6);
  border: 1px solid rgba(245, 247, 248, 0.16);
  border-radius: 999px;
  padding: 6px 13px;
}
.selwork-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  font-size: 15px;
  color: #6FA8FF;
  text-decoration: none;
}
.selwork-cta span { transition: transform 0.3s ease; }
.selwork-cta:hover span { transform: translateX(-5px); }
.selwork-foot { text-align: center; margin: clamp(48px, 6vw, 84px) 0 0; }
.selwork-foot a {
  color: rgba(245, 247, 248, 0.6);
  text-decoration: none;
  font-size: 15px;
  border-bottom: 1px solid rgba(245, 247, 248, 0.2);
  padding-bottom: 3px;
  transition: color 0.3s ease;
}
.selwork-foot a:hover { color: #F5F7F8; }

/* Mobile: clean single column, media first, no horizontal overflow. */
@media (max-width: 860px) {
  .selwork-row,
  .selwork-row:nth-child(even) { grid-template-columns: 1fr; gap: 22px; }
  .selwork-row:nth-child(even) .selwork-media { order: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .selwork-row { opacity: 1; transform: none; transition: none; }
  .pt-thumbs img { transition: none; }
}
