/* =========================================================================
   SYF — Shape Your Finance — stylesheet
   Organized by: reset/tokens -> shared components -> per-section (in page
   order) -> media queries live next to the rules they override.
   ========================================================================= */

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: hidden; }
/* body's own overflow-x:hidden removed in the Situations scroll-linked-
   reveal round: it was redundant with html's rule (html is the actual
   root scroller regardless of this property; the guarantee doesn't need
   restating on body) and, empirically, `overflow-x: hidden` (or any non-
   visible overflow) on body turns it into an unexpected extra scroll
   container between the viewport and any position:sticky descendant,
   which silently breaks sticky's ability to engage at all (a pinned
   headline never actually pinned in real testing on this exact issue —
   proved by removing the two rules one at a time, see implementation-
   notes/situations.md). html's own rule alone was confirmed sufficient:
   zero-horizontal-overflow re-verified at both breakpoints after this
   change, no regression. This is a global/shared rule — flagged here and
   in the log rather than changed silently, per this project's scope
   discipline, since it was a hard functional blocker for the sticky pin
   the task explicitly asked for, not a style preference. */
body, h1, h2, h3, p, figure, ul, textarea { margin: 0; }
img, svg, video { display: block; max-width: 100%; }
button { font: inherit; border: none; background: none; cursor: pointer; color: inherit; }
ul { list-style: none; margin: 0; padding: 0; }
a { color: inherit; }
input, textarea { font: inherit; color: inherit; }

/* ===== Brand tokens (locked palette — nothing outside this list) ===== */
:root {
  --navy: #1A3956;
  --navy-deep: #122A40;
  --navy-light: #2C5578;
  --turquoise: #16837A;
  --turquoise-deep: #0E5F57;
  --turquoise-pastel: #79CBBD;
  --cream: #F5F2EC;
  --gold: #C9A86A;
  --gold-pastel: #EDC383;
  --gold-rich: #E0B378;
  --tint-blue: #E7ECEF;
  --tint-mint: #EAF1EC;
  --white: #FFFFFF;

  --font-head: 'Secular One', 'Noto Sans Hebrew', sans-serif;
  --font-body: 'Noto Sans Hebrew', sans-serif;
  /* Loaded per spec but not applied to any Hebrew text — its Hebrew glyphs
     render as a plain fallback face with none of the Latin hand-drawn
     character. See implementation-notes.md Deviations. Kept defined in
     case a future Latin accent word ever needs it. */
  --font-accent: 'Amatic SC', 'Noto Sans Hebrew', sans-serif;

  /* Dramatic type scale per spec: hero 72-88 desktop / 38-44 mobile, section 48-64 / 34-40, body 18-20 */
  --fs-hero: clamp(2.375rem, 1.05rem + 5.4vw, 5.5rem);
  --fs-section: clamp(2.125rem, 1.5rem + 2.6vw, 4rem);
  --fs-body: clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem);
  --fs-label: 14px;

  --ease-out: cubic-bezier(.16,.84,.44,1);
  --dur-reveal: 600ms;
  --header-h: 82px; /* static, known value — see implementation-notes.md */
  --side-pad: clamp(20px, 6vw, 64px);
  --wrap: 1360px;
}

body {
  font-family: var(--font-body);
  color: var(--navy);
  background: var(--cream);
  line-height: 1.6;
  font-size: var(--fs-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-head); font-weight: 400; }
main { display: block; }
section { position: relative; }

.tq { color: var(--turquoise); }
/* Every anchored section clears the sticky header on jump/scroll-to. */
[id] { scroll-margin-top: calc(var(--header-h) + 16px); }
.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(20px, 5vw, 56px);
}

/* Visible focus ring everywhere — palette colors, not browser default */
:focus-visible {
  outline: 3px solid var(--gold-rich);
  outline-offset: 2px;
  border-radius: 4px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  z-index: 1000;
  top: -60px;
  inset-inline-start: 12px;
  background: var(--navy);
  color: var(--cream);
  padding: 12px 20px;
  border-radius: 10px;
  transition: top 200ms var(--ease-out);
}
.skip-link:focus { top: 12px; }

/* ===== Scroll reveal (separate transition system — never merged with any
   accordion/state-transition declaration, they silently overwrote each
   other once during the prototype phase) ===== */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  transition-delay: var(--d, 0ms);
}
.reveal.in-view { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .hero-anim,
  .situations-word, .situation { opacity: 1 !important; transform: none !important; transition: none !important; }
  * { animation: none !important; }
  /* Situations' pin track must not leave dead scroll distance under
     reduced motion — collapses to auto height and the stage drops out of
     sticky entirely, so the section behaves as a normal static block, CSS
     alone (script.js also skips attaching its scroll listener in this
     mode, but the layout collapse can't depend on JS running first). */
  .situations-pin-track { height: auto !important; }
  /* Restores the section's original top spacing (100px) and the old
     headline-to-list gap (64px, previously .situations-head's own
     margin-bottom, removed when the headline moved into the pinned
     stage) — so the collapsed static layout matches what this section
     looked like before this round, not just "not broken." */
  .situations-pin-stage { position: static !important; height: auto !important; padding-block: 100px 64px; }
}

/* ===== Pill button ===== */
.pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 34px;
  min-height: 44px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 17px;
  background: var(--turquoise);
  color: var(--white);
  transition: transform 220ms var(--ease-out), box-shadow 220ms var(--ease-out), background 220ms var(--ease-out);
  box-shadow: 0 6px 18px rgba(26,57,86,0.12);
}
@media (hover: hover) {
  .pill-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(26,57,86,0.22); }
}
.pill-btn:active { transform: translateY(0); }
.pill-btn--dark { background: var(--navy); color: var(--cream); }

/* ===== Header ===== */
.site-header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px clamp(16px, 4vw, 48px);
  background: transparent;
  color: var(--navy);
  transition: background 320ms var(--ease-out), box-shadow 320ms var(--ease-out);
}
.site-header.is-solid {
  background: rgba(245, 242, 236, 0.92);
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 22px rgba(26,57,86,0.10);
}
/* The source SVG's 842x596 canvas has ~67% dead vertical padding around the
   actual wordmark+tagline (measured via rendered-pixel ink bands, see
   implementation-notes.md) — sizing the raw <img> can't hit a real visual
   target without also scaling that padding past the CTA pill's height.
   .logo-crop clips it to the actual content box so the visible glyph scales
   independently of the file's built-in canvas margins. */
.site-header .logo-crop {
  display: block;
  position: relative;
  width: 133.4px;
  height: 46.89px;
  overflow: hidden;
}
.site-header .logo-crop img {
  position: absolute;
  top: -47.01px;
  left: -30.23px;
  height: 137px;
  width: 193.56px; /* explicit, not auto: the <img>'s width/height HTML attributes
    (140x40, a stale ratio vs the real 842x596 SVG) map to a CSS aspect-ratio
    that hijacks auto-width once the element is absolutely positioned */
  max-width: none; /* site-wide "img{max-width:100%}" reset would otherwise
    clamp this to the crop container's width */
  display: block;
}
/* Mobile gets its own, smaller SYF-glyph target (~23px vs desktop's 34px) —
   not a proportional scale-down of the desktop crop. At 390px the logo
   competes with the hamburger and CTA pill for the same 390px of width;
   34px read as crowding that row even though it's correctly sized on
   desktop. Same crop-via-scale-and-offset technique, recalibrated. */
@media (max-width: 899px) {
  .site-header .logo-crop {
    width: 90.58px;
    height: 31.83px;
  }
  .site-header .logo-crop img {
    top: -31.91px;
    left: -20.52px;
    height: 93px;
    width: 131.36px;
  }
}
.site-header .pill-btn {
  background: var(--navy);
  color: var(--cream);
  padding: 13px 22px;
  min-height: 44px;
  font-size: 14.5px;
  box-shadow: none;
}
.header-inner {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.header-nav {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 40px);
}
.header-nav__links {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.4vw, 32px);
}
.header-nav__links a {
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  color: var(--navy);
  padding: 6px 2px;
  position: relative;
  transition: color 200ms var(--ease-out);
}
.header-nav__links a.is-active { color: var(--turquoise-deep); }
.header-nav__links a::after {
  content: '';
  position: absolute;
  inset-inline: 2px;
  bottom: 0;
  height: 2px;
  background: var(--turquoise);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 220ms var(--ease-out);
}
.header-nav__links a.is-active::after { transform: scaleX(1); }
@media (hover: hover) {
  .header-nav__links a:hover::after { transform: scaleX(1); }
}

.hamburger {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
}
.hamburger svg { width: 24px; height: 24px; }
.hamburger .icon-close { display: none; }
.hamburger[aria-expanded="true"] .icon-open { display: none; }
.hamburger[aria-expanded="true"] .icon-close { display: block; }

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: var(--cream);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 32px;
  transform: translateY(-100%);
  opacity: 0;
  visibility: hidden;
  transition: transform 320ms var(--ease-out), opacity 320ms var(--ease-out), visibility 320ms;
}
.mobile-nav.is-open {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
}
.mobile-nav a {
  font-family: var(--font-head);
  font-size: 28px;
  color: var(--navy);
  text-decoration: none;
}

@media (max-width: 899px) {
  .header-nav__links { display: none; }
  .hamburger { display: flex; }
}

/* ===== Utility: alternating section climates (never plain white) =====
   Listed in current DOM order (see index.html) — class-indexed, not
   position-indexed, so the reorder itself required no changes here beyond
   re-tuning .section-proof (see implementation-notes/README.md, "Section
   reorder" — it collided with .section-strips once they became adjacent).
   .section-about is overridden to cream by .about-section (round 3 —
   see implementation-notes/about-sagi.md); listed here as cream too so
   this table stays accurate rather than silently wrong. That puts three
   cream sections in a row (Situations, About, Process) — checked by eye
   and re-measured after the change, see the same log for the result. */
.section-hero      { background: var(--cream); }
.section-situations{ background: var(--cream); }
.section-about     { background: var(--cream); }
/* ---- Round 3 (ambient-glow.md): these tints meet at hard 1px steps at
   their top edges. The raw channel deltas are tiny (3-14 per channel) but
   a flat step still reads as a ruled line by eye (Mach-band edge contrast,
   not magnitude) — measured and confirmed on real screenshots, see
   ambient-glow.md. Each gets a top-edge ramp technique matching FAQ's own
   (100px, matching each section's own padding-block top value exactly so
   the ramp always resolves to flat before any content starts).
   Class-indexed, not position-indexed — so a DOM reorder can silently
   invalidate a ramp tuned for the OLD neighbor's color. Confirmed by this
   project's own history: the guidance-strips-before-how-it-works reorder
   (see implementation-notes/strips.md and how-it-works.md, "Round 9"/
   "Round 6") re-pixel-sampled all three new boundaries rather than
   assuming these still held, and found two hard cuts — .section-process
   (flat, no ramp) now sits after Strips (ends tint-blue) instead of after
   About (cream), and .section-proof's ramp source was still tint-blue
   though its new predecessor, Process, is flat cream. Both re-tuned below;
   .section-strips itself needed no change since About (its predecessor
   both before and after this reorder) is unchanged. */
.section-strips    { background: linear-gradient(to bottom, var(--cream) 0, var(--tint-blue) 100px, var(--tint-blue) 100%); }
.section-process   { background: linear-gradient(to bottom, var(--tint-blue) 0, var(--cream) 100px, var(--cream) 100%); }
.section-proof     { background: linear-gradient(to bottom, var(--cream) 0, var(--tint-mint) 100px, var(--tint-mint) 100%); }
.section-form      { background: linear-gradient(to bottom, var(--tint-mint) 0, var(--cream) 100px, var(--cream) 100%); }
.section-faq       { background: linear-gradient(to bottom, var(--cream) 0, var(--tint-mint) 100px, var(--tint-mint) 100%); }

.section-headline {
  font-size: var(--fs-section);
  line-height: 1.12;
  max-width: 16ch;
}
.section-eyebrow {
  display: inline-block;
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 1.5px;
  color: var(--turquoise-deep);
  margin-bottom: 14px;
}

/* =========================================================================
   Section 1 — Hero
   ========================================================================= */
.hero {
  position: relative;
  background:
    radial-gradient(120% 90% at 12% 8%, var(--tint-mint) 0%, transparent 55%),
    radial-gradient(110% 90% at 88% 22%, var(--tint-blue) 0%, transparent 60%),
    var(--cream);
  color: var(--navy);
  /* dvh first choice; vh declared before it as a fallback for browsers that
     don't support dvh — iOS Safari's collapsing URL bar changes the plain
     vh viewport height mid-scroll, dvh tracks the real visible height */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  padding-block: calc(var(--header-h) + 40px) 64px;
}

/* ---- Ambient glow: preset B colors/opacity, calibrated faster drift.
   No filter:blur anywhere — iOS Safari rasterizes animated blur into a
   static composited layer, defeating the drift entirely. Softness is baked
   into the radial-gradient itself, which animates cleanly everywhere. ---- */
/* Fades the whole glow layer to transparent over its last ~18% so the hero's
   own ambient color never reaches a hard cutoff at the section boundary
   below — root cause of a visible seam was glow-blob--3 (bottom:-20%)
   still tinting the very last pixels of the hero at certain x-positions
   while the next section's background was flat cream there, with no blend
   between them. A mask on this existing decorative layer (not a new
   element, nothing in the hero's content/video/headline/CTA) fixes it at
   the source. See implementation-notes.md for the measured proof. */
.hero-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 82%, transparent 100%);
}
.glow-blob { position: absolute; border-radius: 50%; opacity: .55; will-change: transform; }
.glow-blob--1 {
  width: 62vw; height: 62vw; max-width: 820px; max-height: 820px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  top: -14%; inset-inline-start: -16%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
.glow-blob--2 {
  width: 54vw; height: 54vw; max-width: 700px; max-height: 700px;
  background: radial-gradient(circle, var(--gold-rich) 0%, var(--gold-rich) 35%, transparent 70%);
  top: 20%; inset-inline-end: -18%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
.glow-blob--3 {
  width: 48vw; height: 48vw; max-width: 620px; max-height: 620px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  bottom: -20%; inset-inline-start: 18%;
  animation: glowDrift3 10s ease-in-out infinite alternate;
}
@keyframes glowDrift1 { from { transform: translate(0,0) scale(1); } to { transform: translate(120px, 95px) scale(1.16); } }
@keyframes glowDrift2 { from { transform: translate(0,0) scale(1); } to { transform: translate(-110px, -85px) scale(0.9); } }
@keyframes glowDrift3 { from { transform: translate(0,0) scale(1); } to { transform: translate(95px, -115px) scale(1.14); } }
@media (max-width: 767px) {
  .glow-blob--1 { width: 92vw; height: 92vw; }
  .glow-blob--2 { width: 82vw; height: 82vw; }
  .glow-blob--3 { display: none; }
}

/* ---- Fingerprint contour motif, behind the headline ---- */
.fingerprint-wrap { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.fingerprint { position: absolute; color: var(--navy); opacity: .08; }
.fingerprint--hero {
  width: min(140vw, 900px); height: min(140vw, 900px);
  top: 46%; inset-inline-start: 8%;
  transform: translateY(-50%);
}

.hero-inner {
  position: relative;
  z-index: 1;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(20px, 5vw, 56px);
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "headline" "subhead" "media" "cta";
  align-items: center;
  width: 100%;
}
@media (min-width: 900px) {
  .hero-inner {
    grid-template-columns: 1.55fr 1fr;
    grid-template-areas:
      "headline media"
      "subhead  media"
      "cta      media";
    column-gap: 24px;
  }
}

.hero-headline {
  grid-area: headline;
  font-size: var(--fs-hero);
  line-height: 1.05;
  letter-spacing: -0.5px;
  max-width: 14ch;
}
/* "רצית" — Amatic SC accent word per spec. NOTE: Amatic SC's Hebrew glyphs
   render as a plain fallback-style face with none of its Latin hand-drawn
   character (verified visually) — see implementation-notes.md Deviations.
   Using the proven italic/skew treatment on the body face instead. */
.hero-headline .handwritten {
  position: relative;
  font-style: italic;
  display: inline-block;
  transform: skewX(-6deg) rotate(-2deg);
  color: var(--turquoise-deep);
  padding-inline: 2px;
}
.hero-headline .handwritten svg {
  position: absolute;
  inset-inline-start: -2%;
  bottom: -0.14em;
  width: 104%;
  height: 0.3em;
  overflow: visible;
}
.hero-headline .handwritten svg path { fill: none; stroke: var(--gold); stroke-width: 5; stroke-linecap: round; }

.hero-subheadline {
  grid-area: subhead;
  margin-top: 26px;
  font-size: var(--fs-body);
  max-width: 36ch;
  color: rgba(26,57,86,0.82);
}
.hero-cta-row {
  grid-area: cta;
  margin-top: 32px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}
.hero-reassurance { font-size: var(--fs-label); color: rgba(26,57,86,0.74); }

.hero-media {
  grid-area: media;
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  margin-top: 28px;
}
.video-portal {
  position: relative;
  width: clamp(200px, 40vw, 300px);
  aspect-ratio: 9 / 16;
  overflow: hidden;
  border: 1px solid rgba(26,57,86,0.12);
  border-radius: 12px;
  box-shadow: 0 24px 54px rgba(26,57,86,0.18);
  background: var(--navy-deep);
}
@media (min-width: 900px) {
  .hero-media { margin-top: 0; }
  .video-portal { margin-inline-start: -56px; max-height: 620px; }
}
.hero-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }

.mute-toggle {
  position: absolute;
  z-index: 3;
  bottom: 14px;
  inset-inline-end: 14px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(18,42,64,0.55);
  backdrop-filter: blur(4px);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mute-toggle svg { width: 19px; height: 19px; }
.mute-toggle .mute-slash { opacity: 0; transition: opacity 150ms var(--ease-out); }
.mute-toggle.is-muted .mute-slash { opacity: 1; }

@media (max-width: 899px) {
  .hero { min-height: auto; padding-block: calc(var(--header-h) + 14px) 16px; }
  .hero-subheadline { margin-top: 8px; }
  .hero-media { margin-top: 14px; }
  .hero-cta-row { margin-top: 26px; gap: 10px; justify-content: center; }
  .hero-cta-row .pill-btn { padding: 13px 27px; font-size: 15px; }
  .hero-reassurance { display: block; margin-top: 2px; text-align: center; }
  .video-portal { width: 58vw; }
}
@media (max-width: 899px) and (max-height: 720px) {
  .hero { padding-block: calc(var(--header-h) + 8px) 4px; }
  .video-portal { width: 40vw; }
  .hero-subheadline { margin-top: 4px; }
  .hero-media { margin-top: 6px; }
  .hero-cta-row { margin-top: 6px; gap: 6px; }
}

/* =========================================================================
   Section 2 — Situations ("מוצאים את עצמכם באחד המצבים האלה?")
   Redesign: numerals removed (that treatment now belongs to "How it works"
   alone), icons carry the per-item identity instead, real photography is
   process's language so this section stays graphic/iconographic. Deliberately
   NOT a uniform card grid: four items placed at staggered column/row offsets
   on desktop, alternating indents on mobile — unchanged from before.
   ========================================================================= */
.situations { padding-block: 0 90px; position: relative; }
/* Headline no longer sits in the section's own normal-flow padding block —
   it now lives inside the pinned stage below, which supplies its own
   vertical centering. Top padding moved there; bottom padding (the
   reserved whitespace the signpost texture sits in) is unchanged. */
.situations-head { max-width: 46ch; position: relative; z-index: 1; }

/* =========================================================================
   Scroll-linked pinned headline stage — see implementation-notes/
   situations.md ("scroll-linked reveal" round) for the full design
   rationale, the risks considered, and how the numbers below were tuned.
   The track is a real, height-reserving block (not an overlay/JS-fixed
   trick), so anchor jumps, scrollspy, and normal layout flow all stay
   correct with zero special-casing elsewhere on the site — the browser
   computes everything downstream from a real, measurable box.
   ========================================================================= */
/* dvh-first per CLAUDE.md's iOS Safari rule (vh line kept above it as the
   fallback) — a sticky stage's track sized in bare vh would resize under
   Safari's collapsing URL bar mid-scroll, corrupting the pin math while
   the user is inside it. --situations-pin-extra is the one number that
   controls how long the pinned "beat" lasts; tuned by scrolling through
   on a real viewport, not guessed — see the log for the values tried. */
.situations-pin-track {
  --situations-pin-extra: 85vh;
  height: calc(100vh + var(--situations-pin-extra));
  height: calc(100dvh + var(--situations-pin-extra));
  position: relative;
}
.situations-pin-stage {
  position: sticky;
  top: var(--header-h);
  height: calc(100vh - var(--header-h));
  height: calc(100dvh - var(--header-h));
  display: flex;
  align-items: center;
  overflow: hidden;
}

/* ---- Ambient glow: third recurring instance of the hero's technique
   (hero -> how-it-works -> here), same keyframes reused, no filter:blur on
   anything animated. Recalibrated for this section: cream base instead of
   the old flat --tint-mint wash, opacity between the hero's and process's.
   See implementation-notes.md for the "this is now a deliberate motif" note.
   Moved inside the pinned stage in the scroll-linked-reveal round: this
   section's total height became almost entirely track/content-driven once
   the pin track shipped, and this glow's blob offsets are percentages —
   sizing/positioning glow elements as percentages of a content-driven
   height is the exact sitewide law this would have broken by staying
   section-wide (see CLAUDE.md). Scoping it to the stage (a fixed,
   viewport-derived height) satisfies that law AND keeps the glow visually
   attached to the headline for the pin's entire duration, rather than
   scrolling out from behind it after the first viewport of scroll. ---- */
/* Mirrors the hero's own bottom-edge mask, at this section's top edge: the
   stage sits exactly where the section used to start (right after Hero),
   so the same top-edge fade-in this glow already had is still exactly as
   necessary. The cross-SECTION bottom fade added in about-sagi.md's round 3
   (for the Situations-to-About seam) is still not needed here — this glow
   doesn't reach that seam now that it's confined to the stage. But the
   stage's own bottom edge is a real, separate cut: .situations-pin-stage
   clips with overflow:hidden, and situations-glow-blob--2 is bottom-
   anchored close enough to that edge that its own radial fade (opaque to
   35% of its radius, then fading to transparent by 70%) hadn't reached
   zero alpha by the time the box got clipped — confirmed by pixel-sampling
   a vertical strip through it (round "scroll-linked reveal round 2" in the
   log): a real device screenshot showed this as a hard line at the exact
   point the pin releases. This second, tighter fade zone tapers the whole
   glow layer to zero exactly at the stage's bottom edge, so nothing is
   left for overflow:hidden to clip mid-fade. */
.situations-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 78%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 78%, transparent 100%);
}
.situations-glow-blob { position: absolute; border-radius: 50%; }
.situations-glow-blob--1 {
  width: 50vw; height: 50vw; max-width: 600px; max-height: 600px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  opacity: .16;
  top: -12%; inset-inline-end: -14%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
.situations-glow-blob--2 {
  width: 42vw; height: 42vw; max-width: 520px; max-height: 520px;
  background: radial-gradient(circle, var(--gold-rich) 0%, var(--gold-rich) 35%, transparent 70%);
  opacity: .15;
  bottom: -10%; inset-inline-start: -10%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .situations-glow-blob--1 { width: 88vw; height: 88vw; top: -100px; opacity: .2; }
  .situations-glow-blob--2 { width: 78vw; height: 78vw; bottom: -90px; opacity: .2; }
}

/* ---- Signpost silhouette: ambient background texture, concept = SYF as
   the one clear guide inside a multi-directional intersection (the
   section's four situations). Anchored to the section's bottom-right
   corner (grounded, since the post literally stands on the ground) —
   deliberately the opposite side from situation--4, which is left-aligned
   and sits lowest of the four blocks (margin-top:110px), so the texture's
   footprint and that block's text never occupy the same horizontal band.
   Fixed height, bottom-anchored, well inside the section's reserved
   bottom whitespace (90px padding + the transition line's own 104px
   margin-top) so it can't reach up into the situation grid regardless of
   how tall that grid renders — confirmed by measurement, not just this
   arithmetic, see implementation-notes.md. ---- */
.situations-texture {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  bottom: 0;
  inset-inline-start: clamp(8px, 2vw, 20px);
  width: clamp(150px, 15vw, 200px);
  height: clamp(155px, 15.5vw, 205px);
  overflow: hidden;
  opacity: .32;
  /* Round 2: the source is now cropped tight to the silhouette itself (see
     implementation-notes.md), so the subject fills most of the frame —
     the mask only needs to feather the outer rim, not carve deep into the
     image the way round 1's mask did (which faded the box edges but also
     ate the silhouette, since round 1's frame was mostly empty sky). Mask
     stays fully opaque out to 55% of its own radius, only the outer ring
     fades. */
  -webkit-mask-image: radial-gradient(ellipse 68% 68% at 50% 52%, #000 55%, transparent 100%);
  mask-image: radial-gradient(ellipse 68% 68% at 50% 52%, #000 55%, transparent 100%);
}
.situations-texture img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  filter: url(#situationsDuotone);
  display: block;
}
@media (max-width: 767px) {
  /* Desktop's bottom:0 placement shares the transition line's row, which
     is fine there (the line doesn't reach full width, confirmed via the
     text's own rendered glyph extent, not just its box). On mobile the
     stacked layout makes that line run edge-to-edge, so sharing that row
     puts the texture directly behind real text. Re-anchored instead into
     the gap between situation--4 (the last, lowest block) and the
     transition line — measured at ~126px on a real render, a fixed
     bottom-offset (rather than 0/percentage) because that gap's position
     depends on stacked content height, not the viewport — same reasoning
     as this project's other fixed-pixel mobile fixes. Confirmed via
     rendered-rect intersection against every block, icon, and the
     transition text's actual glyph rects, not just their boxes. Sized to
     use nearly all of that ~126px gap now that the crop needs to read at
     a glance, not just fit. */
  .situations-texture {
    width: clamp(84px, 24vw, 106px);
    height: 106px;
    bottom: 138px;
    inset-inline-start: 10px;
  }
}

/* ---- Headline: giant question-mark motif, same treatment family as the
   fingerprint contour (low-opacity navy shape behind the text) but a
   distinct glyph — the section's own punctuation, enlarged, not a re-skin
   of that asset. This is the only headline treatment; the alternate
   outline/fill-word variant explored during review was removed rather than
   left dormant — see implementation-notes.md. ---- */
.situations-qmark {
  display: block;
  position: absolute;
  z-index: 0;
  font-family: var(--font-head);
  font-size: clamp(240px, 32vw, 480px);
  line-height: 1;
  color: var(--navy);
  opacity: .07;
  top: -0.28em;
  inset-inline-end: -0.12em;
  pointer-events: none;
  user-select: none;
}

.situations-headline { position: relative; z-index: 1; }
/* Word-by-word reveal: script.js sets opacity/transform per word every
   frame, purely as a function of scroll position — no CSS transition here
   on purpose. A transition would lag behind the actual scroll position by
   its own duration, which breaks "reversible, scroll-linked" the moment
   the user changes direction or scrolls fast; the easing lives in the
   progress math in JS instead, applied once to the whole pin progress.
   display:inline-block (not plain inline) so `transform` is guaranteed to
   apply — real spaces sit between the spans in the markup as ordinary
   text nodes, untouched by either property, so wrapping behaves exactly
   like plain text and the reveal never shifts word positions (zero CLS).
   Hidden by default so a user without JS never sees a flash of the fully-
   built sentence before the real progressive reveal takes over — same
   default-hidden-until-JS-resolves convention as `.reveal` above, and the
   same JS-runs-synchronously assumption already relied on there (no
   defer/async on script.js). Reveal order needs no RTL-specific logic:
   the spans are written in natural reading order in the markup, and the
   page's own dir="rtl" already lays that out right-to-left — revealing
   index 0, 1, 2... in DOM order IS revealing right-to-left in reading
   order, for free. */
.situations-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(10px);
  will-change: opacity, transform;
}

.situations-list {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: clamp(16px, 3vw, 32px);
  row-gap: 56px;
  position: relative;
  z-index: 1;
  /* Round 2: items now enter with a translateX offset (see .situation
     below) instead of translateY — that offset can render past the grid's
     own right edge (situation--2/--4 sit flush against it on desktop) at
     intermediate scroll positions. html's own overflow-x:hidden (see the
     reset section) guarantees the PAGE never scrolls horizontally, but it
     doesn't stop a mid-animation frame from visibly poking past this
     section's edge before that guarantee kicks in — so this container
     clips its own overflow, scoped tightly to where the sliding elements
     actually live rather than reaching for a section- or body-wide rule
     again (that already caused the sticky-breaking bug this round's log
     documents; this is a sibling of the pin-track, not an ancestor of it,
     so it can't repeat that bug). */
  overflow-x: hidden;
}
/* Items: replaces the sitewide .reveal system for this section only (that
   system's IntersectionObserver fires once and never reverses — the brief
   calls for scroll-linked and reversible, so a one-shot trigger can't do
   this job; the two systems were also never meant to run on the same
   elements at once, a documented lesson from an earlier round). Hidden by
   default for the same before-JS-resolves reason as the words above;
   script.js scrubs opacity/transform continuously from each item's own
   getBoundingClientRect(), independent of the pin progress.
   Round 2: entry changed from a bottom-up translateY to a side entry from
   the right (the RTL reading direction) — translateX is a physical
   operation (always screen-right for positive values, regardless of
   dir="rtl"), so a positive starting offset IS "from the right" here with
   no logical/physical translation needed; verified against the rendered
   result, not assumed (see the log — this project has a documented bug
   precedent from mixing logical offsets with physical transforms, which
   this avoids by using only a physical value). "Slide + fade with its
   icon" is read as the icon arriving together with its block (one
   transform on the whole <li>) rather than a second, separately-timed
   animation on the icon alone. */
.situation {
  position: relative;
  grid-column: 1 / 13;
  opacity: 0;
  transform: translateX(72px);
  will-change: opacity, transform;
}
.situation-icon {
  display: block;
  width: clamp(52px, 6vw, 72px);
  height: clamp(52px, 6vw, 72px);
  color: var(--turquoise-deep);
  margin-bottom: 18px;
}
/* Verified real vector paths (viewBox 0 0 256 256 on all four), not font
   glyphs — replaced a previous custom-drawn set after one rendered as the
   literal characters "11" instead of an icon on a real device (a font-
   glyph/icon-font rendering path, not a vector bug in these SVGs). Every
   shape sets its own fill="none" explicitly except one accent dot (situation
   1's coin rivet), which has no fill attribute at all and so inherits `fill`
   from the svg root below — this rule targets only the root, never the
   individual shapes, so it can't clobber their explicit fill="none". */
.situation-icon svg { width: 100%; height: 100%; fill: currentColor; }
.situation-title {
  position: relative;
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(21px, 2vw, 27px);
  line-height: 1.3;
  max-width: 20ch;
}
.situation-line {
  position: relative;
  margin-top: 10px;
  max-width: 34ch;
  color: rgba(26,57,86,0.82);
}

/* Small-subheading scale (a step above body/title text, well below the
   section headline) so this reads as the section's closing statement and
   transition into the strips below, not skippable small print. Emphasis
   uses the site's existing color-split technique (.tq turquoise-on-navy,
   the same pattern as the hero's "בלי הדאגה") rather than a new treatment. */
.situations-transition {
  position: relative;
  z-index: 1;
  margin-top: 104px;
  text-align: center;
  font-family: var(--font-head);
  font-size: clamp(26px, 2.6vw, 36px);
  line-height: 1.3;
  color: var(--navy);
}

@media (min-width: 900px) {
  .situation--1 { grid-column: 1 / 7; }
  .situation--2 { grid-column: 7 / 13; margin-top: 70px; }
  .situation--3 { grid-column: 2 / 8; margin-top: 40px; }
  .situation--4 { grid-column: 8 / 13; margin-top: 110px; }
}
@media (max-width: 899px) {
  .situation--1 { margin-inline-start: 0; }
  .situation--2 { margin-inline-start: 10vw; }
  .situation--3 { margin-inline-start: 4vw; }
  .situation--4 { margin-inline-start: 14vw; }
}

/* =========================================================================
   Section 3 — Guidance-areas strips
   Desktop: hover/focus-expand. Mobile: tap accordion, one open at a time.
   Duotone navy/turquoise gradients built from tokens only — no hue rotation.
   ========================================================================= */
.strips-section { padding-block: 100px 88px; position: relative; }
.strips-head { margin-bottom: 48px; max-width: 44ch; position: relative; z-index: 1; }

/* ---- Ambient glow: sixth instance of the sitewide glowDrift motif (see
   implementation-notes/ambient-glow.md for the full sitewide round — this
   is the first of four sections that got it in that round). Cool,
   turquoise-only pairing (no gold) — deliberately the one section that
   stays in the same color family as its own duotone cards below, rather
   than the warmer gold-leaning pairs used elsewhere, so it reads as a
   variation on this section's own language rather than a copy-paste of
   another section's. Blobs sized modestly and anchored to the headline/
   CTA whitespace specifically: the six duotone cards between them are
   opaque and z-index:1, so anything sized to reach behind the cards would
   be spending paint/composite cost on pixels nobody ever sees — sized to
   matter where they're actually visible instead. Both edges fade (this
   section sits between two light neighbors; process's own boundary and
   this section's were already confirmed a clean, intentional flat-color
   break in situations.md round 8's sweep — this glow's own top/bottom
   fades keep it that way rather than reopening a bleed). */
.strips-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
}
.strips-glow-blob { position: absolute; border-radius: 50%; }
.strips-glow-blob--1 {
  width: 46vw; height: 46vw; max-width: 560px; max-height: 560px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  opacity: .58;
  top: -14%; inset-inline-end: -10%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
.strips-glow-blob--2 {
  width: 44vw; height: 44vw; max-width: 520px; max-height: 520px;
  background: radial-gradient(circle, var(--turquoise-pastel) 0%, var(--turquoise-pastel) 35%, transparent 70%);
  opacity: .72;
  bottom: -12%; inset-inline-start: -8%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .strips-glow-blob--1 { width: 80vw; height: 80vw; top: -70px; opacity: .6; }
  .strips-glow-blob--2 { width: 76vw; height: 76vw; bottom: -60px; opacity: .74; }
}

/* ---- Radial composition (see implementation-notes/strips.md): six equal
   cards in two columns of three, wrapped around a central giant-motif
   anchor, replacing the earlier single row of six. This was diagnosed
   (both a manual outside-eye review and an /impeccable critique dual-
   agent pass) as the section where the sitewide "giant low-opacity
   signature motif" — present in every section above this one — stops
   appearing, and where six near-identical rectangles in a row read as a
   stock template silhouette regardless of internal styling quality. Both
   are addressed structurally here, not by further tuning the old layout. */
.strips-radial {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: clamp(20px, 4vw, 48px);
}
.strips-radial .strips {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.strips > li { list-style: none; }
/* The anchor is a sibling <div> between the two <ul>s, never a member of
   either (a <ul> may only contain <li> children) — DOM order alone gives
   mobile its "three / anchor / three" stack once .strips-radial switches
   to flex-direction:column, no JS or absolute positioning required. */
.strips-anchor {
  flex: none;
  width: clamp(140px, 20vw, 280px);
  aspect-ratio: 1;
  pointer-events: none;
}
/* ---- Converging-lines centre mark (introduced Round 5, replacing the
   fingerprint that used to live in .strips-anchor). Round 6 removed the
   fingerprint from this section entirely, including the background-wash
   instance Round 5 moved it to (it read as an unintentional grey smudge
   at 1440px, not as texture) — this section now carries no fingerprint
   instance at all; see DESIGN.md's giant-low-opacity-motif entry, updated
   to match. Six thin lines radiate from a solid centre dot toward each
   card and fade out well before reaching it — a quiet radiating mark, not
   an org-chart connector set. Desktop-only: hidden by default (mobile-
   first); a separate, smaller divider variant of this same mark shows on
   mobile instead (.strips-mark-mobile below), not a scaled-down copy of
   this one. */
.strips-mark { display: none; }
@media (min-width: 768px) {
  .strips-mark {
    display: block;
    width: 100%;
    height: 100%;
    /* Lines are authored past the 0-200 viewBox on purpose (they reach
       toward the gap between the anchor and the cards, not just the
       anchor's own square footprint) — must not clip at the box edge. */
    overflow: visible;
  }
}
/* ---- Round 6, Fix 2: mobile divider mark — the inverse visibility
   pattern of .strips-mark above (visible by default/mobile-first, hidden
   from 768px up, where the desktop mark takes over). The four diagonal
   rays stay entirely inside the 0-100 viewBox (max reach local radius 32).
   Round 7, Task 2 extended the two horizontal rays out to local x
   -114.5/214.5, well past that box, so overflow:visible is now required
   here too (previously not needed — see implementation-notes/strips.md
   Round 7). */
.strips-mark-mobile { display: block; width: 100%; height: 100%; overflow: visible; }
@media (min-width: 768px) {
  .strips-mark-mobile { display: none; }
}
/* Endpoints are hard-coded (see implementation-notes/strips.md Round 5 for
   the ray/rectangle-intersection math): each line stops at ~65% of the
   real distance from the centre dot to that card's nearest edge, computed
   once from measured card centres after Task A's arc offset, not derived
   at runtime. The mask's radialGradient (opaque at centre, transparent by
   70% of its own 150-unit radius = local radius 105) does the actual
   fade — the authored line length (~103-113 units) intentionally runs a
   little past that, so the last few units of each line are fully masked
   out rather than ending on a hard cut. */
/* Round 6, Fix 3: raised from 1px/.13 (effectively invisible at 1440px,
   per client feedback) to 1.5px/.26 — tuned by eye against the raised
   screenshot until the mark reads without leaning in, short of where it
   starts to look like a diagram (see implementation-notes/strips.md
   Round 6 for the before/after comparison). The two purely horizontal
   lines (pointing at cards 1 and 4) lost visibility fastest against the
   background at the shared opacity — confirmed on screenshots, not
   assumed from the angle math alone — so they get a dedicated modifier
   class at a higher opacity rather than a blanket bump that would have
   overshot the diagonals. */
.strips-mark-line { fill: none; stroke: var(--navy); stroke-opacity: .26; stroke-width: 1.5; stroke-linecap: round; }
.strips-mark-line--horizontal { stroke-opacity: .32; }
.strips-mark-ring { fill: none; stroke: var(--navy); stroke-opacity: .18; stroke-width: 1; }
.strips-mark-dot { fill: var(--navy); }

.strip {
  display: block;
  position: relative;
  width: 100%;
  min-height: clamp(148px, 15vw, 180px);
  border-radius: 18px;
  text-align: start;
  background: var(--white);
  border: 1px solid rgba(26,57,86,0.10);
  box-shadow: 0 12px 28px rgba(26,57,86,0.06);
  padding: 30px 20px 22px 34px;
  cursor: pointer;
  /* Card surface + text invert together — the "dramatic color inversion"
     open state, replacing the old subtle overlay-opacity/flex-grow
     expansion. No height change between rest and open on either
     breakpoint: this card is already tall enough to reserve the
     description's space, so opening never reflows the page. */
  transition: background 420ms var(--ease-out), border-color 420ms var(--ease-out), box-shadow 420ms var(--ease-out);
}
/* Keyed off .is-open only (JS-driven), not a bare :hover/:focus-visible —
   those synthetic states aren't reliable here: JS already adds .is-open on
   real hover/focus (see script.js), and a bare :hover rule left "sticky"
   on touch after a tap-to-close, fighting the JS state (confirmed on a
   touch-emulated pass — the card stayed inverted with the label faded out
   after tapping to collapse it). */
.strip.is-open {
  background: var(--navy-deep);
  border-color: rgba(245,242,236,0.14);
  box-shadow: 0 18px 40px rgba(18,42,64,0.28);
}
/* ---- Round 5, Task A: bow the two columns outward around the centre
   mark so the composition reads as an arc, not two flat parallel stacks.
   Only the middle card of each column moves — top/bottom cards keep
   their original x — which is what creates the curve. Selector keys off
   :nth-child on the <li> (the actual flex item), not the button, per
   README.md's original <ul>/<li> nth-child bug: `.strip:nth-child(2)`
   would silently never match, since every button is its own <li>'s only
   child. Physical values, not logical: dir="rtl" is fixed sitewide, and
   .strips--a is the confirmed (measured) physically-right column, so
   "away from centre" is unambiguous — +X for .strips--a's middle card,
   -X for .strips--b's. clamp()-based magnitude, not a fixed px, so the
   bow scales down approaching 768px rather than staying constant right
   up to the breakpoint edge; transform:translateX (not margin) so this
   never triggers a reflow of surrounding cards. Desktop-only: mobile is a
   single linear stack with no columns to bow. */
@media (min-width: 768px) {
  .strips--a > li:nth-child(2) .strip { transform: translateX(clamp(12px, 2.2vw, 34px)); }
  .strips--b > li:nth-child(2) .strip { transform: translateX(calc(-1 * clamp(12px, 2.2vw, 34px))); }
}
/* ---- Corner badge: the six icons move from a giant low-opacity texture
   behind the text to a defined badge breaking out of the card's own top
   corner. Consequently the card surface itself stays clean — no
   background icon layered under the text — so there's only one
   decorative system per card, not two competing ones. Six distinct
   navy/turquoise blends carry per-card individuality now (the same six
   pairings the old whole-card gradients used), concentrated in a small
   element where the difference actually reads, rather than spread across
   a full card background where it didn't. Explicit navy/turquoise-family
   blends only, per DESIGN.md — no hue rotation or generated color. Fixed
   px sizing (not container-query units): the badge is a constant-size
   element regardless of card state, unlike the old full-card icon-as-
   texture which had to track two different resize axes. */
.strip-badge {
  position: absolute;
  top: -18px;
  inset-inline-start: -18px;
  z-index: 1;
  width: 56px;
  height: 56px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 18px rgba(26,57,86,0.22);
}
.strip[data-index="0"] .strip-badge { background: linear-gradient(135deg, var(--navy-light), var(--turquoise-deep)); }
.strip[data-index="1"] .strip-badge { background: linear-gradient(160deg, var(--navy), var(--turquoise-deep)); }
.strip[data-index="2"] .strip-badge { background: linear-gradient(160deg, var(--turquoise), var(--navy)); }
.strip[data-index="3"] .strip-badge { background: linear-gradient(200deg, var(--turquoise), var(--navy-light)); }
.strip[data-index="4"] .strip-badge { background: linear-gradient(160deg, var(--turquoise-deep), var(--navy-deep)); }
.strip[data-index="5"] .strip-badge { background: linear-gradient(160deg, var(--navy), var(--turquoise)); }
/* fill:currentColor scoped to only the svg root (never the individual
   shapes): the calculator icon's six digit-dots have no fill attribute
   of their own (unlike every other shape in all six icons, which set
   fill="none" explicitly), so without this they'd default to solid
   black per the SVG spec. Targeting only the root reaches those dots via
   ordinary inheritance without overriding any shape's own explicit
   fill="none" — same reasoning as the Situations icons' fill fix. */
.strip-badge svg { width: 28px; height: 28px; display: block; color: var(--white); fill: currentColor; }
/* ---- Round 5, Task C: badges break outward, away from the centre mark,
   in both columns. The shared inset-inline-start rule above put both
   columns' badges on the same physical side (correct for .strips--a, the
   right column — outward there already meant physically-right — but
   wrong for .strips--b, the left column, where physically-right means
   pointing IN toward the new centre mark). Explicit physical value, not a
   second logical property: same reasoning as Task A's translateX signs.
   Desktop-only — mobile stacks both lists into one linear column with no
   inward/outward distinction, so the shared base rule stays correct and
   unchanged there. */
@media (min-width: 768px) {
  .strips--b .strip-badge { inset-inline-start: auto; left: -18px; }
}

.strip-content { display: block; }
.strip-name-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.strip-name {
  font-family: var(--font-head);
  font-size: clamp(16px, 1.3vw, 19px);
  line-height: 1.2;
  color: var(--navy);
  transition: color 420ms var(--ease-out);
}
.strip.is-open .strip-name { color: var(--cream); }
/* Visible affordance that the card is interactive — flagged by both
   reviews as missing entirely from the old design (nothing hinted
   "hover/tap for more" on a collapsed card). Rotates on open; color
   inherits the name's own state transition via currentColor. */
.strip-chevron {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--navy);
  opacity: .55;
  transition: transform 380ms var(--ease-out), color 420ms var(--ease-out), opacity 380ms var(--ease-out);
}
.strip.is-open .strip-chevron { color: var(--cream); opacity: .9; transform: rotate(180deg); }
.strip-line {
  display: block;
  margin-top: 10px;
  font-size: 14.5px;
  max-width: 32ch;
  color: rgba(26,57,86,0.72);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 380ms var(--ease-out) 80ms, transform 380ms var(--ease-out) 80ms, color 420ms var(--ease-out);
}
.strip.is-open .strip-line { opacity: 1; transform: translateY(0); color: rgba(245,242,236,0.88); }

@media (max-width: 767px) {
  /* Round 6, Fix 2: gap collapsed from 28px to 24px (1.5x the 16px normal
     card-to-card gap this stack already uses — see implementation-notes/
     strips.md Round 6 for the measured before/after). This gap value
     controls the ONLY two things it touches: the space between list A's
     last card and .strips-anchor, and between .strips-anchor and list B's
     first card — nothing else in the mobile stack depends on it. */
  .strips-radial { flex-direction: column; gap: 24px; }
  /* Anchor box down from min(46vw,200px) (a leftover from when it held
     the full-size fingerprint, ~179px tall at 390px) to a fixed 76px —
     sized to the mobile divider mark itself (Fix 2), not to a motif that
     no longer lives here. */
  .strips-anchor { width: 76px; }
  .strip { padding-inline-start: 30px; }
}

.strips-cta { display: flex; justify-content: center; margin-top: 56px; position: relative; z-index: 1; }

/* =========================================================================
   Section 4 — How it works ("איך זה עובד")
   Redesign round 2: photo-backed step blocks stay (approved on real
   device), six focused fixes on top of round 1. See implementation-notes.md
   Deviations for the full reasoning. Photo block height is fixed
   (aspect-ratio) and never changes on open/close — only the body panel
   below it grows. Accordion still uses the CSS grid-template-rows 0fr/1fr
   trick (no JS height measurement).
   ========================================================================= */
.process-section { padding-block: 100px 90px; }
.process-head { max-width: 44ch; margin-bottom: 56px; position: relative; z-index: 1; }

/* ---- Headline treatment: eyebrow removed, fingerprint motif + handwritten/
   underline accent reused verbatim from the hero's own vocabulary (same
   asset via <use href="#heroFpBlob">, same accent-word technique) — no new
   decorative language invented. Duplicated here rather than broadening the
   hero's own selector, since the hero component itself is out of scope. ---- */
.fingerprint--process {
  width: min(70vw, 480px); height: min(70vw, 480px);
  top: -8%; inset-inline-end: -6%;
}
.process-headline .handwritten {
  position: relative;
  font-style: italic;
  display: inline-block;
  transform: skewX(-6deg) rotate(-2deg);
  color: var(--turquoise-deep);
  padding-inline: 2px;
}
.process-headline .handwritten svg {
  position: absolute;
  inset-inline-start: -2%;
  bottom: -0.14em;
  width: 104%;
  height: 0.3em;
  overflow: visible;
}
.process-headline .handwritten svg path { fill: none; stroke: var(--gold); stroke-width: 5; stroke-linecap: round; }

/* ---- Ambient glow, adapted from the hero's own glow technique (same
   keyframes, same radial-gradient-only approach — no filter:blur, no new
   animation system). Originally shipped at a much lower intensity than
   the hero; the glow-benchmark round (see implementation-notes/
   ambient-glow.md) raised opacity/size so this section's own measured
   delta lands in the same 64-120 range as every other section's glow —
   it no longer deliberately stays under the hero's presence. Respects
   prefers-reduced-motion via the shared global
   `* { animation: none !important; }` override. ---- */
/* Section-reorder verification (see implementation-notes/README.md) found
   this glow was hard-cut at the section's own top edge — process-glow-blob--1
   sits with a negative top offset so it's already well inside its solid
   interior by the time the section's own boundary clips it, at both
   breakpoints, regardless of which section precedes it. Same root cause,
   same fix, as the hero/situations seam and situations-glow's own top-edge
   fade below: mask the glow in from transparent over its first stretch
   (originally ~15%, converted to a fixed 100px in the glow-benchmark
   round — see the comment directly below).
   Bottom fade added in the Situations "scroll-linked reveal round 2"
   sitewide sweep: process-glow-blob--2 is bottom-anchored and had the
   same missing-fade defect as about-glow-blob--2 and situations-glow-
   blob--2 — visible here at the process->guidance seam as a warm band
   cut off abruptly just before the (intentional) flat cream->tint-blue
   break, rather than fading to nothing first. See the log. */
/* Fixed-px fade distance, not a percentage of section height — same fix
   and same reasoning as about-glow above: this section is four stacked
   accordion/photo rows, so its rendered height varies with content far
   more than a viewport-scaled section would, and a 15%/82% mask let
   blob--2's opaque core drift entirely into the fade tail (measured
   center at 100%+ down on desktop). See implementation-notes/
   ambient-glow.md, glow-benchmark round. */
.process-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
}
.process-glow-blob { position: absolute; border-radius: 50%; }
.process-glow-blob--1 {
  width: 50vw; height: 50vw; max-width: 600px; max-height: 600px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  opacity: .5;
  top: -10%; inset-inline-start: -12%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
.process-glow-blob--2 {
  width: 46vw; height: 46vw; max-width: 540px; max-height: 540px;
  background: radial-gradient(circle, var(--gold-rich) 0%, var(--gold-rich) 35%, transparent 70%);
  opacity: .58;
  bottom: -14%; inset-inline-end: -8%;
  animation: glowDrift3 10s ease-in-out infinite alternate;
}
/* Mobile override: `top`/`bottom` above are percentages of the glow
   container's height, which equals the whole section's height. That's fine
   on desktop (short relative to viewport), but on mobile this section is
   four stacked photo cards tall — content-driven, not viewport-driven, like
   the hero is — so -10%/-14% of ~1400px confined the blobs almost entirely
   above the visible content, off in the headline's whitespace. Fixed px
   offsets here decouple the blobs from that ever-growing height. Sizing and
   opacity, updated in the glow-benchmark round (see implementation-notes/
   ambient-glow.md), now land this section's own measured delta inside the
   Hero's benchmark range (64-120) rather than "below the hero's own
   opacity" — the earlier "stay well under the hero" framing was itself
   part of why this glow read as invisible; it's no longer the goal. */
@media (max-width: 767px) {
  .process-glow-blob--1 { width: 88vw; height: 88vw; top: -80px; opacity: .53; }
  .process-glow-blob--2 { width: 80vw; height: 80vw; bottom: -70px; opacity: .61; }
}

.process-list { display: flex; flex-direction: column; gap: 30px; max-width: 900px; position: relative; z-index: 1; }

/* ---- Position-based rhythm, not size-based: every block is the same
   width/aspect ratio (see .process-media below); variation comes only from
   alternating horizontal alignment and vertical offset. Step 1 is
   flex-start, which is the *right* edge in this RTL column flex (cross-
   start = inline-start = right), matching "step 1 starts on the right." ---- */
.process-item { width: 100%; }
@media (min-width: 900px) {
  .process-item { width: 64%; }
  .process-item--1 { align-self: flex-start; }
  .process-item--2 { align-self: flex-end; margin-top: 38px; }
  .process-item--3 { align-self: flex-start; margin-top: -6px; }
  .process-item--4 { align-self: flex-end; margin-top: 38px; }
}
@media (max-width: 899px) {
  .process-item--2 { margin-top: 18px; }
  .process-item--4 { margin-top: 18px; }
}

.process-item {
  position: relative;
  border-radius: 22px;
  background: var(--navy-deep);
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(18,42,64,0.18);
}

/* Photo block: same aspect ratio on every step (equal-size blocks). 16:9 is
   wider than the source photos' native ~3:2, so object-fit:cover always has
   vertical room to crop — needed so step 4's low object-position can
   actually cut the sky at every breakpoint. Fixed height regardless of
   accordion state — only .process-panel below it grows. */
.process-media { position: relative; overflow: hidden; aspect-ratio: 16 / 9; }
.process-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
}
/* Step 4: refocus on the two walking figures, who sit left-of-center and
   low in the frame — the tree (right side) and sky (top) are not the
   subject. object-position alone only has vertical room to crop (see
   above), so a scale+origin zoom creates horizontal crop room too. */
.process-item--4 .process-media img {
  object-position: 50% 80%;
  transform: scale(1.38);
  transform-origin: 30% 66%;
}
/* Mobile needs its own values, not a scaled-down copy of desktop's: a grid
   overlay on the source photo (see implementation-notes.md) located the
   midpoint between the two figures at ~44%/76% of the frame. Round 3 used
   that point at scale(1.7), which was directionally right but still left
   the tree reading as dominant at a portrait aspect — the focal point was
   correct, the zoom just wasn't aggressive enough. Round 4 pushes the zoom
   much further (3.0) and nudges the origin slightly past the two-figure
   midpoint, toward the pair and away from the tree, since some tree is
   unavoidable in a wide source photo and the goal is minimizing it, not
   erasing it. Same 16:9 box as desktop, so the box-to-image mapping is
   identical at both breakpoints — only this mobile-scoped zoom differs. */
@media (max-width: 599px) {
  .process-item--4 .process-media img { transform: scale(3.0); transform-origin: 40% 72%; }
}

/* Overlay deepens toward the bottom, where the caption row and (when open)
   the body panel sit. Same gradient recipe, same stops, on three of the
   four photos — calibrated against the brightest source photo so contrast
   holds everywhere; see implementation-notes.md for the measured ratios. */
.process-media-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(18,42,64,.08) 0%,
    rgba(18,42,64,.16) 42%,
    rgba(18,42,64,.74) 64%,
    rgba(18,42,64,.90) 100%);
}
/* Step 3 only: same family of treatment, deeper end of the range across the
   *whole* photo (not just the bottom), so the notebook's English planning
   text sinks toward illegible while hand/pen/paper stay visible as texture.
   No blur — see implementation-notes.md for why and the residual-legibility
   call. */
.process-item--3 .process-media-overlay {
  background: linear-gradient(to bottom,
    rgba(18,42,64,.68) 0%,
    rgba(18,42,64,.74) 38%,
    rgba(18,42,64,.87) 64%,
    rgba(18,42,64,.95) 100%);
}
.process-item--3 .process-media img {
  object-position: 66% 42%;
  transform: scale(1.28);
  transform-origin: 60% 40%;
}

.process-trigger {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  gap: 16px;
  width: 100%;
  margin-top: -92px;
  padding: 0 clamp(18px, 3vw, 28px) 20px;
  text-align: start;
}
@media (max-width: 599px) {
  .process-trigger { margin-top: -84px; }
}

.process-step-num {
  flex-shrink: 0;
  font-family: var(--font-head);
  line-height: 0.9;
  font-size: clamp(48px, 3vw + 24px, 84px);
  color: var(--gold-rich);
}
.process-title {
  flex: 1;
  padding-bottom: 6px;
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(19px, 1.6vw, 24px);
  color: var(--cream);
}
.process-chevron {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  margin-bottom: 8px;
  color: var(--gold-rich);
  transition: transform 320ms var(--ease-out);
}
.process-item.is-open .process-chevron { transform: rotate(180deg); }

.process-panel {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 400ms var(--ease-out);
}
.process-item.is-open .process-panel { grid-template-rows: 1fr; }
.process-panel-inner { overflow: hidden; min-height: 0; }
.process-body {
  padding: 2px clamp(18px, 3vw, 28px) 26px;
  max-width: 58ch;
  color: rgba(245,242,236,0.86);
}

.process-cta { margin-top: 48px; position: relative; z-index: 1; }

/* =========================================================================
   Section 5 — About Sagi ("נעים להכיר, אני שגיא")
   Round 2 (see implementation-notes/about-sagi.md): round 1 only recolored
   the original capsule-photo + connector + single-card template and read
   as unchanged on screenshot. That template is retired entirely — no
   capsule crop, no connector thread, no single filled card. Replaced with
   an alternating text/photo rhythm and a dramatic-scale headline moment.
   Round 3: the two colour variants built for comparison in round 2 are
   resolved — "warm identity" (cream background, warm glow) ships; the
   cooler tint-mint variant's overrides were removed rather than left
   dormant. See implementation-notes/about-sagi.md for why.
   ========================================================================= */
.about-section { padding-block: 100px 96px; position: relative; background: var(--cream); }

/* ---- Ambient glow: fourth instance of the site's recurring glowDrift
   motif, both blobs warm (gold-rich / gold-pastel) for the shipped
   "warm identity" climate — confirmed to stay warm-only through the
   glow-benchmark round's opacity/size increase too (see implementation-
   notes/ambient-glow.md), no cool hue ever imported into this section.
   Top fade-in added in round 3: same fix as process-glow's (see above)
   and for the same reason — About's own top-edge blob--1 is gold-rich,
   unmasked, sitting at the same physical corner as situations-glow-
   blob--2 just above it (see that section's comment); faded in from
   transparent over the first stretch (originally ~15%, converted to a
   fixed 100px in the glow-benchmark round) so the seam
   isn't lit from both sides at once. Bottom fade added in the Situations
   "scroll-linked reveal round 2" sitewide sweep: about-glow-blob--2 is
   bottom-anchored and, like situations-glow-blob--2 before this same
   sweep, wasn't faded out before this glow's own overflow:hidden clipped
   it at the section's real bottom edge (the about->process seam) —
   confirmed by pixel-sampling a visible gold band cutting off abruptly
   there instead of blending into plain cream first, see the log. */
/* Fixed-px fade distance, not a percentage of section height — this
   section's height is content-driven (photo/text rows, not viewport-
   scaled like the hero), so a 15%/82% percentage mask silently shrinks
   the flat "fully visible" zone on tall renders and pushes a corner-
   anchored blob's opaque core into the fade tail (measured: blob--2's
   center landed at 94% down on mobile, well past the 82% fade-start —
   see implementation-notes/ambient-glow.md, glow-benchmark round). Same
   fixed-px-ramp technique already used for the section-boundary color
   grades below, reused here for the same reason: it decouples the fade
   width from a height that can change with content. */
.about-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
}
.about-glow-blob { position: absolute; border-radius: 50%; }
.about-glow-blob--1 {
  width: 50vw; height: 50vw; max-width: 600px; max-height: 600px;
  background: radial-gradient(circle, var(--gold-rich) 0%, var(--gold-rich) 35%, transparent 70%);
  opacity: .58;
  top: -14%; inset-inline-start: -12%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
.about-glow-blob--2 {
  width: 44vw; height: 44vw; max-width: 520px; max-height: 520px;
  background: radial-gradient(circle, var(--gold-pastel) 0%, var(--gold-pastel) 35%, transparent 70%);
  opacity: .72;
  bottom: -12%; inset-inline-end: -10%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .about-glow-blob--1 { width: 88vw; height: 88vw; top: -80px; opacity: .61; }
  .about-glow-blob--2 { width: 78vw; height: 78vw; bottom: -70px; opacity: .75; }
}

.about-inner {
  max-width: 1160px;
  margin-inline: auto;
  padding-inline: var(--side-pad);
  position: relative;
  z-index: 1;
}

/* ---- Headline: this section's own typographic moment, distinct from the
   hero/how-it-works skewed-accent-word + self-drawing underline and from
   Situations' giant "?". "שגיא" jumps to a dramatically larger scale than
   the rest of the sentence — kept in navy, not gold: gold-rich and gold
   both measure under 2:1 against this site's light backgrounds (checked
   before using it, see implementation-notes/about-sagi.md), so neither can
   carry real text here. The word instead carries a static, solid
   gold-rich rule underneath it — deliberately NOT the hero's self-drawing
   animated underline; this one is simply already there. */
.about-head { max-width: 640px; margin-bottom: 56px; }
.about-headline { font-size: var(--fs-section); line-height: 1.16; }
.about-name {
  display: inline-block;
  font-size: 1.5em;
  line-height: 1;
  border-bottom: 6px solid var(--gold-rich);
  padding-bottom: 0.06em;
}

/* ---- Alternating rhythm: text, photo, text, photo — a deliberate change
   of pace instead of one flat block, replacing round 1's single card.
   Splits on Sagi's own two existing paragraphs, no new copy breaks
   invented. Stacked in that literal reading order on mobile; from 900px,
   row 2 reverses so the photos zigzag left/right down the page instead of
   repeating the same side twice. ---- */
.about-flow { display: flex; flex-direction: column; gap: 48px; }
.about-row { display: flex; flex-direction: column; gap: 28px; }

/* No filled card — that's what made round 1 read as unchanged. Text sits
   directly on the section's own background, with a plain vertical rule on
   the reading-start edge as the only structural marker. Variant B
   recolors this rule further down. */
.about-text {
  max-width: 620px;
  border-inline-start: 3px solid var(--gold-rich);
  padding-inline-start: 20px;
}
.about-body { font-size: var(--fs-body); line-height: 1.7; color: rgba(26,57,86,0.86); }
.about-body + .about-body { margin-top: 14px; }
/* Emphasis reuses the site's existing color-split vocabulary (.tq), with
   its color overridden to turquoise-deep and weight added: measured
   against this section's actual background, plain --turquoise at
   body-text size measures 4.24-4.27:1 — under the 4.5:1 minimum regular
   text needs (the same reason Situations' own .tq text was bumped to
   large-text scale rather than shipped at body size). turquoise-deep at
   the same size/weight measures 6.5+:1. This stays cool in BOTH colour
   variants for the same reason the headline word stays navy — there's no
   accessible way to render it in gold at this size on this site's light
   backgrounds; the warmth lives in the background/rule/photo frame
   instead. Two emphasis moments in the copy, not a highlighter effect. */
.about-body .tq { color: var(--turquoise-deep); font-weight: 600; }

/* Closing line: navy text (safe) highlighted with a gold-pastel background
   instead of gold-as-text-color, so it still visibly carries warmth
   without failing contrast (see the .tq note above — the same constraint
   applies here). box-decoration-break lets the highlight wrap cleanly if
   the line breaks across two lines on narrow viewports. */
.about-closing { margin-top: 18px; }
.about-closing span {
  background: var(--gold-pastel);
  color: var(--navy);
  font-family: var(--font-head);
  font-size: clamp(20px, 2.2vw, 26px);
  line-height: 1.5;
  padding: 2px 10px;
  border-radius: 6px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* Round 3: reduced from a 360px cap (900px on desktop via the clamp below)
   — at 1440px the photos dominated the composition and pulled attention
   from the copy. Sized down so text and image read as balanced weight. */
.about-photo {
  width: 100%;
  max-width: 260px;
  margin-inline: auto;
  overflow: hidden;
  border-radius: 16px;
  border: 3px solid var(--gold-rich);
  box-shadow: 0 18px 40px rgba(26,57,86,0.14);
}
.about-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.about-photo--1 { aspect-ratio: 4 / 5; }
.about-photo--2 { aspect-ratio: 1 / 1; }

@media (min-width: 900px) {
  .about-row { flex-direction: row; align-items: center; gap: 48px; }
  .about-row--2 { flex-direction: row-reverse; }
  .about-text { flex: 1; min-width: 0; }
  .about-photo { flex-shrink: 0; width: clamp(190px, 17vw, 230px); max-width: none; margin-inline: 0; }
}

/* =========================================================================
   Section 6 — Social proof ("אנשים שכבר עשו סדר")
   Quotes form a complete section on their own; counters are a fully
   removable, self-contained block appended after (never interleaved,
   never straddling a background-tint seam).
   ========================================================================= */
.proof-section { padding-block: 100px 96px; position: relative; }

/* ---- Ambient glow: seventh instance of the sitewide glowDrift motif
   (implementation-notes/ambient-glow.md). Soft pastel pairing (gold-pastel
   + turquoise-pastel, both unused as glow colors before this round) for a
   gentler feel than the richer tones elsewhere — fits quotes/personal
   testimony better than a saturated wash. The quote cards themselves stay
   opaque white (z-index:1 below), so the glow is only ever actually seen
   in the open background around and above/below them; both edges fade
   the same way as every other middle section on the site. */
.proof-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
}
.proof-glow-blob { position: absolute; border-radius: 50%; }
.proof-glow-blob--1 {
  width: 50vw; height: 50vw; max-width: 600px; max-height: 600px;
  background: radial-gradient(circle, var(--gold-pastel) 0%, var(--gold-pastel) 35%, transparent 70%);
  opacity: .65;
  top: -12%; inset-inline-start: -12%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
.proof-glow-blob--2 {
  width: 44vw; height: 44vw; max-width: 520px; max-height: 520px;
  background: radial-gradient(circle, var(--turquoise-pastel) 0%, var(--turquoise-pastel) 35%, transparent 70%);
  opacity: .65;
  bottom: -10%; inset-inline-end: -10%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .proof-glow-blob--1 { width: 88vw; height: 88vw; top: -80px; opacity: .68; }
  .proof-glow-blob--2 { width: 76vw; height: 76vw; bottom: -70px; opacity: .68; }
}

.proof-head { max-width: 46ch; margin-bottom: 56px; position: relative; z-index: 1; }
/* The sitewide .section-headline max-width:16ch (DESIGN.md's "never runs
   the full measure" rule) is a deliberate forced-break for most headlines,
   but this specific 18-character heading ("אנשים שכבר עשו סדר") breaks
   right after "עשו", stranding "סדר" alone on its own line — a widow, not
   the intended editorial break. Scoped override, desktop only (matches
   this section's own existing 900px two-column breakpoint) — mobile keeps
   the shared 16ch rule and its current (correct) wrap untouched. Text
   itself is unchanged; only the wrap width. */
@media (min-width: 900px) {
  /* Both the heading's own 16ch cap AND its parent .proof-head's 46ch cap
     (529.9px at this font-size — narrower than the 18-char heading needs)
     were constraining the line width; overriding only the heading and
     missing the parent was caught on the first render, not assumed fixed
     from the CSS alone. */
  .proof-head { max-width: none; }
  .proof-headline { max-width: none; }
}

/* ---- Round: video + cards + counter body. Grid only from 900px up
   (matches this section's existing two-column breakpoint) — below that,
   normal block flow already puts video/cards/counter in the right order
   (DOM order = brief's own listed structure), so no grid is needed there.
   grid-template-areas repositions the counter beside the video on desktop
   WITHOUT moving it in the DOM — screen readers/keyboard order stays
   video -> cards -> counter -> CTA (see implementation-notes/testimonials.md
   for why that reading order was kept even though it diverges from the
   desktop visual order). */
.proof-body { position: relative; z-index: 1; }

.proof-video-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 9 / 16;
  border-radius: 18px;
  overflow: hidden;
  background: var(--navy-deep);
  box-shadow: 0 18px 40px rgba(26,57,86,0.14);
  margin-bottom: 32px;
}
/* Round 2: at full column width, 9:16 made the video fill essentially the
   whole mobile viewport height (measured 343x610 at 390px against an
   844px viewport before this fix — the section opened as a wall of video
   with no context). Capped to ~72% of the content column, centered; the
   aspect-ratio keeps it a true 9:16, never a fixed px height (CLAUDE.md).
   Desktop (>=900px) is unchanged — width there already comes from the
   grid track's own minmax(320px,380px), not from this rule. */
@media (max-width: 899px) {
  .proof-video-wrap { width: 72%; margin-inline: auto; }
}
.proof-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.proof-video-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 12px 26px rgba(26,57,86,0.3);
  transition: transform 220ms var(--ease-out), box-shadow 220ms var(--ease-out);
}
/* Triangle SVG path points right; a 3px optical nudge keeps it centred in
   the circle rather than reading as shifted left (a plain play triangle
   otherwise looks off-centre — well-known optical-alignment fix). */
.proof-video-play svg { width: 26px; height: 26px; margin-inline-start: 3px; }
@media (hover: hover) {
  .proof-video-play:hover { transform: scale(1.06); box-shadow: 0 16px 34px rgba(26,57,86,0.36); }
}
/* Set once playback starts (script.js) and never unset — native <video
   controls>, added the same moment, take over play/pause from here on. */
.proof-video-wrap.is-playing .proof-video-play { display: none; }

.proof-quotes {
  display: flex;
  flex-direction: column;
  gap: 40px;
  position: relative;
  z-index: 1;
}
/* ---- Round 2 (see implementation-notes/testimonials.md): the white card
   is gone — quote, name and screenshot now sit directly on the section's
   own background. Same "dissolve the box, let scale/color/type carry it"
   move already used for About-Sagi and the counter (Round 1's own comment
   above flagged this as a deliberate, temporary mismatch to resolve once
   real quotes replaced the drafts — this is that resolution). Only the
   screenshot keeps a container (see .proof-shot below) since a photograph
   still needs a defined edge to read as an object; free-floating quote
   text does not. */
.proof-quote {
  position: relative;
  max-width: 640px;
}
/* Decorative quote mark now sits above the (larger) quote text itself
   rather than inset into a card's padding-box, since there is no padding
   box left to inset into. */
.proof-quote-text::before {
  content: '\201C';
  position: absolute;
  top: -34px;
  inset-inline-start: -6px;
  font-family: var(--font-head);
  font-size: 80px;
  line-height: 1;
  color: var(--turquoise);
  opacity: .16;
}
/* Larger, lighter, generous line-height, narrower measure — reads as a set
   quotation, not body copy. 300 is a real weight of the loaded Noto Sans
   Hebrew family (see the Google Fonts link in index.html's <head>, widened
   this round to include it) — never a synthetic/faux-bold-style fake, per
   DESIGN.md's Never-Faux-Bold rule applied here to its light-weight
   equivalent. No italic: Hebrew has no true italic and browsers only
   synthesise one by skewing, which reads as broken (CLAUDE.md). */
.proof-quote-text {
  position: relative;
  font-size: clamp(1.375rem, 1.2rem + 0.7vw, 1.625rem);
  font-weight: 300;
  line-height: 1.85;
  color: var(--navy);
  max-width: 26ch;
}
.proof-quote-name {
  position: relative;
  margin-top: 20px;
  font-family: var(--font-head);
  font-size: 16px;
  color: var(--turquoise-deep);
}

/* ---- WhatsApp screenshot peek: the one element in this card that keeps a
   container — a photograph needs a defined edge, quote text no longer
   does (see .proof-quote above). A hairline border stands in for the old
   card's own border now that there's no white surface framing it; no
   shadow (CLAUDE.md/DESIGN.md: a heavy card shadow here would make the
   screenshot read as its own card again, the exact thing this round
   removes). Height is tuned PER CARD, not shared — see the three
   .proof-quote--* overrides below and implementation-notes/testimonials.md
   for the measured reasoning (the shared 220px value duplicated each
   quote's own opening lines on Adi's and David's shorter screenshots). */
.proof-shot {
  display: block;
  position: relative;
  width: 100%;
  height: 220px;
  margin-top: 18px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid rgba(26,57,86,0.14);
  padding: 0;
  cursor: pointer;
  background: var(--white);
}
.proof-shot-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}
.proof-shot-fade {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 55%, var(--white) 100%);
  pointer-events: none;
}
.proof-shot-hint {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  /* 0.68 measured 4.55:1 on white — technically AA-passing but with almost
     no margin. 0.72 is the same fixed alpha this project already uses for
     this exact navy-on-light-surface problem (social-proof.md's counter
     label, the lead-form round) rather than a new one-off number. */
  color: rgba(26,57,86,0.72);
}

/* ---- Per-card screenshot peek tuning (Round 2). The extracted quotes
   open with the same sentence the screenshot's TOP shows, so a shared
   object-position:top duplicated the quote directly beneath it — most
   visibly on Shahar's and David's cards. Each value below was derived by
   simulating the real object-fit:cover crop against the actual PNG at
   the three rendered widths this card can actually be at this section's
   own breakpoints — 350px (mobile single column, 390px test width),
   254px (900px's three-column row — narrower than mobile, since three
   columns have to fit in less space than one), 400px (1440px's row) —
   then reading each cropped result to confirm the first full visible
   line is NOT part of the quote. See implementation-notes/testimonials.md
   for the full per-card, per-width measurement table. */
/* Shahar's screenshot (716x1106) has a real paragraph gap right after the
   text the quote draws from. object-position: 50% 80% lands the crop's
   top edge inside that gap at all three widths (350/254/400 → 42.7%/
   46.3%/48.9% of the image height) — first full visible line: "מבחינתי,
   גישת המפתח של שגיא היא" (350px/254px) / "הירידה לפרטים הקטנים לצד שיח
   מחובר" (400px, after a faint fresh-text sliver at the very top edge),
   all fresh, not in the quote. Height unchanged (220px). */
.proof-quote--shahar .proof-shot-img { object-position: 50% 80%; }
.proof-quote--adi .proof-shot {
  /* Adi's screenshot (530x544) is nearly square — this card's own
     rendered screenshot width actually varies more than the other two
     across this section's own breakpoints (254px at 900px's 3-column
     row, 350px in mobile's single column, 400px at 1440px — narrower at
     900px than at 390px, since 900px is where three columns first have
     to fit), and the 900px case is the tightest: at 220px, or even
     130px, tall, the crop still surfaces the quote's own closing lines
     ("מהתהליך כשאנחנו מסכימים שזה היה" / "מצוין, הכרחי מומלץ לכל אחד")
     partway down, measured and re-measured against the real image at all
     three widths, not assumed from one. 102px, bottom-aligned (50%
     100%), is the tallest value that still clears those lines at 254px
     — first full visible line at all three widths: "מקצוענים תותחים
     והכל ממש ברוח" (400px) / "המלצנו לחברים שלנו ואנחנו נשמח" (254px) /
     "מקצוענים תותחים והכל ממש ברוח" (350px), all fresh, after the
     quote's own "...לכל אחד." ending. */
  height: 102px;
}
.proof-quote--adi .proof-shot-img { object-position: 50% 100%; }
.proof-quote--david .proof-shot {
  /* David's screenshot (384x504) has the same problem in reverse: the
     quote's closing line ("אנחנו ממליצים בחום לכל מי שחושב על קניית
     דירה") is repeated verbatim near the screenshot's own bottom
     (measured: starts ~82% down the image), so bottom-aligning (Adi's
     fix) would surface THAT duplicate instead. 123px at 50% 77% is the
     measured window that starts after the quote's own lines end (~50%)
     and finishes before the closing-line repeat begins, at 350px and
     400px; at 254px (the narrowest of the three) the window's bottom
     edge (85.5%) does reach a couple of pixels into that repeated line's
     own top edge, but by that point it's both a partial single-line
     sliver and ~79% faded by .proof-shot-fade's own gradient (the fade
     starts at 55% of the box; this sliver sits at ~90% down it) —
     judged and accepted as a real but minor residual, not re-tuned
     further, since shrinking the window enough to clear it at 254px too
     would cut visibly into the fresh "מעבר למקצועיות..." paragraph that
     is this card's main non-duplicate content. First full visible line
     at all three widths: "מעבר למקצועיות, שגיא הוא אדם נעים," (350px/
     400px) / "בזכותו, כל התהליך הרגיש פשוט" (254px), both fresh. */
  height: 123px;
}
.proof-quote--david .proof-shot-img { object-position: 50% 77%; }

@media (min-width: 900px) {
  .proof-body {
    display: grid;
    grid-template-columns: minmax(320px, 380px) 1fr;
    grid-template-areas: "video counter" "cards cards";
    column-gap: 40px;
    align-items: start;
  }
  .proof-video-wrap { grid-area: video; margin-bottom: 0; }
  .proof-quotes { grid-area: cards; flex-direction: row; align-items: flex-start; gap: 24px; margin-top: 48px; }
  .proof-quote { flex: 1; min-width: 0; }
  /* Re-tuned against the real quotes' measured heights (see
     implementation-notes/testimonials.md) — the draft-quote values (0/48/18)
     were tuned for three near-equal cards; דוד's real quote is ~150% שחר's
     length and renders ~68px taller even with the same 220px screenshot
     peek on every card, so giving it the OLD stagger's own +18px on top of
     that pushed its bottom edge well below the other two. דוד (the
     tallest) gets the smallest margin-top here specifically to compensate
     for its own extra height, not to break the wave pattern — the other
     two still step down normally. Result: a visible top-edge wave
     (28/52/0) with all three bottom edges landing within ~40px of each
     other instead of ~90px. */
  /* Re-tuned again for Round 2: the larger/lighter/looser quote typography
     plus each card's own new screenshot-peek height (220/102/123px — see
     the .proof-quote--* rules above) changed every card's rendered height
     again, more drastically than Round 1's own re-tune anticipated —
     Adi in particular is now ~150-165px shorter than the other two
     (its screenshot peek alone dropped from 220px to 102px). Measured at
     1440px before choosing new values: שחר 505px, עדי 339px, דוד 456px.
     A flat-bottom match would need Adi's own margin-top alone near
     166px, which read as an oversized, mechanical gap on screen (judged
     on the actual render, not from the numbers) — settled for a smaller
     offset that keeps a visible top-edge wave and pulls the bottom
     spread from ~142px (unstaggered) down to ~66px, not all the way to
     zero. */
  .proof-quote:nth-child(1) { margin-top: 0; }
  .proof-quote:nth-child(2) { margin-top: 96px; }
  .proof-quote:nth-child(3) { margin-top: 24px; }
}

/* ---- Counter: self-contained, removable block. One background zone
   only (this section's tint), generous margin so it never sits flush
   against the section's own edge / the next section's seam.
   Card-removal round (see social-proof.md): the white card is gone
   entirely — same "dissolve the box, let scale/color carry it" move as
   About-Sagi's own card removal. The quote cards above have since had
   the same white surface removed too (testimonials.md Round 2), so both
   halves of this section now sit on the bare background consistently.
   The counter itself (icon, number, prefix, label — every rule below
   down to .proof-counter-label) stays untouched here, per that round's
   explicit "move, not a redesign." */
.proof-counters { margin-top: 56px; position: relative; z-index: 1; }
@media (min-width: 900px) {
  .proof-counters { grid-area: counter; align-self: center; margin-top: 0; }
  /* Round 2: previously the block simply started at the grid area's own
     inline-start edge, which in RTL is the edge nearest the video — it
     read as hugging it (measured gap: 40px, equal to the column-gap
     alone). display:flex + justify-content:center is direction-agnostic
     (no logical/physical RTL trap to get wrong here, unlike most of this
     project's other RTL fixes) and centers the counter's own content
     width within the remaining 1fr grid track. */
  .proof-counters { display: flex; justify-content: center; }
  /* The brief's own definition of "centered" is against the true empty
     space between the video's outer edge and the content column's far
     edge — not just this track. The 40px column-gap sits entirely
     outside the "counter" track (between it and the video track), so
     centering within the track alone left the block 20px (half the
     gap) short of the video-relative center — measured: 900px gave a
     107.3px gap on the far side vs. 147.3px on the video side before
     this line. translateX is always physical regardless of dir (there
     is no logical equivalent to get backwards here), and this project's
     layout puts the video track physically rightmost at every width
     this grid applies at, so a fixed +20px (half of the fixed 40px gap,
     not viewport-dependent) reliably shifts toward it. Re-measured after:
     both sides land within a few tenths of a px of each other at both
     900px and 1440px. */
  .proof-counter { transform: translateX(20px); }
}
.proof-counter-top {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 20px);
}
/* Icon is a companion to the stat, not a label restating it — aria-hidden,
   the visible label text already says what the number means. Sized
   relative to the digits (not a fixed small px) so it keeps reading as a
   companion at both breakpoints instead of shrinking into a speck on
   mobile or a fixed size looking tiny next to the now-larger number. */
.proof-counter-icon {
  display: block;
  flex-shrink: 0;
  width: clamp(46px, 5.5vw, 64px);
  height: clamp(46px, 5.5vw, 64px);
  color: var(--turquoise-deep);
}
.proof-counter-icon svg { width: 100%; height: 100%; }
.proof-counter-num {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-head);
  line-height: 1.15;
}
/* Natural DOM order (prefix span, then digits span, then icon) already
   reads right under dir="rtl" — "מעל" lands rightmost, "200" next, the
   icon leftmost — the same free RTL-ordering property this project has
   relied on before (see situations.md's word-reveal). No row-reverse or
   logical-property juggling needed; verified via getBoundingClientRect
   on the rendered page, not assumed, given this project's own documented
   logical/physical RTL bug precedent (moved the icon to the other side
   of the number this round — re-verified the same way, see
   social-proof.md).
   Color roles split the phrase now that there's no card to separate it
   from the section background: "מעל" is muted navy (a lead-in word,
   subordinate), the digits are the full-strength brand teal (the actual
   statement) — same two-tier hierarchy the label extends a third, quieter
   step further. Secular One has no bold weight (CLAUDE.md), so this
   hierarchy leans entirely on size + color, never faux-bold. */
.proof-counter-prefix {
  font-size: clamp(20px, 2.2vw, 26px);
  color: rgba(26,57,86,0.75);
}
.proof-counter-digits {
  font-size: clamp(52px, 7vw, 84px);
  color: var(--turquoise-deep);
  /* Prevents the digit count changing (200 -> 3 digits vs. a shorter
     mid-animation value) from reflowing the prefix/icon next to it while
     the count-up runs. */
  font-variant-numeric: tabular-nums;
}
.proof-counter-label {
  display: block;
  margin-top: 10px;
  font-size: 15px;
  /* 0.7 (this label's alpha before this round, measured fine against the
     old white card) measures 4.49:1 on the section's --tint-mint
     background now that the card is gone — just under the 4.5:1 text
     minimum. Bumped to 0.72, the same fixed alpha already used for this
     exact class of problem in the lead-form round: 4.74:1. */
  color: rgba(26,57,86,0.72);
}

.proof-cta { margin-top: 48px; position: relative; z-index: 1; }

/* ---- Testimonial screenshot lightbox: single shared instance (markup at
   the end of index.html, outside the section). Fixed full-viewport overlay,
   z-index above the header (100) and mobile-nav (99) — see script.js for
   focus-trap/Escape/backdrop-close, which deliberately mirrors the mobile
   nav's own implementation rather than inventing a second pattern. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox[hidden] { display: none; }
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18,42,64,0.92);
}
.lightbox-close {
  position: absolute;
  z-index: 2;
  top: clamp(12px, 3vw, 28px);
  inset-inline-end: clamp(12px, 3vw, 28px);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(245,242,236,0.12);
  color: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox-close svg { width: 20px; height: 20px; }
@media (hover: hover) {
  .lightbox-close:hover { background: rgba(245,242,236,0.22); }
}
.lightbox-stage {
  position: relative;
  z-index: 1;
  /* 100dvh with a 100vh fallback line above it (CLAUDE.md) — the stage,
     not the outer .lightbox, carries the height so the fallback/DVH pair
     stays on one element rather than duplicated across two. */
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: clamp(16px, 4vw, 48px);
  /* Full-viewport-sized, so without this it sits on top of and completely
     swallows every click meant for .lightbox-backdrop underneath — caught
     by an actual backdrop-click test, not assumed from the CSS. Only the
     image itself (re-enabled below) needs to receive pointer events. */
  pointer-events: none;
}
.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 24px 54px rgba(18,42,64,0.4);
  cursor: zoom-in;
  transition: transform 220ms var(--ease-out);
  pointer-events: auto;
  touch-action: none; /* this element owns pinch/pan itself — see script.js */
  /* Without this, a real mouse drag on an <img> triggers the browser's own
     native "drag this image out of the page" ghost-drag gesture, which
     hijacks the mousemove stream after the first move event — caught by
     an actual click-and-drag test, not assumed from reading the CSS.
     draggable="false" in the HTML covers Chrome/Firefox; -webkit-user-drag
     is the same thing for older Safari, which doesn't reliably honor the
     attribute alone. */
  -webkit-user-drag: none;
  user-select: none;
}
.lightbox-img.is-zoomed { cursor: grab; }
.lightbox-img.is-panning { cursor: grabbing; transition: none; }
/* Mid-pinch: no easing lag between the fingers and the image. */
.lightbox-img.is-gesturing { transition: none; }

/* =========================================================================
   Section 7 — Lead form ("הצעד הראשון לא עולה כלום")
   Demo only: client-side validation, no network call. See script.js for
   the single spot where a future endpoint gets wired in.
   Round 2 (see implementation-notes/lead-form.md): same diagnosis as About
   Sagi before its own fix — everything sat on one flat axis (white card,
   grey-cream fields, navy button), no warm note, no background event.
   Fields go white-on-card with a visible border + a gold-rich bottom rule
   (structural gold, never text — the gold family fails contrast as text
   on light backgrounds, documented in about-sagi.md); the section gets its
   own low-key ambient glow (fifth instance of the sitewide glowDrift
   motif, calibrated down since this is a task-focused section that must
   never compete with filling the form). ========================================================================= */
.form-section { position: relative; padding-block: 100px 100px; }

/* ---- Ambient glow: deliberately the quietest instance on the site
   (opacity .08-.12 vs. .12-.22 elsewhere) — supports, never distracts
   from the task. Top/bottom mask-fade from the start, matching the
   convention fixed for situations-glow/about-glow in the round-3
   about-sagi work, rather than waiting to find the same bleed bug again. */
.form-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
}
.form-glow-blob { position: absolute; border-radius: 50%; }
.form-glow-blob--1 {
  width: 40vw; height: 40vw; max-width: 480px; max-height: 480px;
  background: radial-gradient(circle, var(--gold-rich) 0%, var(--gold-rich) 35%, transparent 70%);
  opacity: .09;
  top: -10%; inset-inline-start: -10%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
.form-glow-blob--2 {
  width: 34vw; height: 34vw; max-width: 420px; max-height: 420px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  opacity: .08;
  bottom: -10%; inset-inline-end: -8%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .form-glow-blob--1 { width: 74vw; height: 74vw; top: -60px; opacity: .12; }
  .form-glow-blob--2 { width: 64vw; height: 64vw; bottom: -60px; opacity: .11; }
}

.form-wrap { max-width: 640px; margin-inline: auto; padding-inline: var(--side-pad); position: relative; z-index: 1; }
.form-head { text-align: center; margin-bottom: 44px; }
.form-head .section-headline { max-width: none; margin-inline: auto; }
/* Modest headline moment, scoped to this section only: a static gold rule
   under the whole headline (not a per-word treatment like About Sagi's
   `.about-name` — this headline doesn't have a single word to carry it,
   and the brief asked to keep focus on the form, not stage a new motif). */
.form-head-rule {
  display: block;
  width: 56px;
  height: 3px;
  border-radius: 2px;
  background: var(--gold-rich);
  margin: 18px auto 0;
}

.lead-form {
  background: var(--white);
  border: 1px solid rgba(26,57,86,0.08);
  border-radius: 24px;
  padding: clamp(26px, 5vw, 44px);
  box-shadow: 0 20px 46px rgba(26,57,86,0.08);
}
.form-row { margin-bottom: 22px; }
.form-row label {
  display: block;
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 8px;
  color: var(--navy);
}
.field-required { color: var(--turquoise-deep); font-weight: 700; margin-inline-start: 2px; }
/* .55/.6 alpha measured 3.19:1/3.64:1 against white — under the 4.5:1 body-text
   minimum. Bumped to .72, re-measured at 5.11:1. */
.field-optional { color: rgba(26,57,86,0.72); font-weight: 400; font-size: 13px; margin-inline-start: 4px; }
.form-required-note {
  font-size: 13px;
  color: rgba(26,57,86,0.72);
  margin: -8px 0 18px;
}

/* Fields go white (same surface as the card) — a visible border is what
   defines the field now, not a flat cream fill: a thin navy-alpha frame
   plus a solid gold-rich bottom rule, the section's clearest warm note
   short of the ambient glow. Gold stays structural here (the border), not
   text — see the section comment above. Border alpha is .55, not a
   lighter value: since field and card are the same white, the border is
   the ONLY boundary cue (no fill difference to fall back on) — WCAG
   1.4.11 non-text contrast needs 3:1 for that; .22 measured only 1.50:1,
   .55 measures 3.19:1. */
.form-row input[type="text"],
.form-row input[type="tel"],
.form-row input[type="email"],
.form-row textarea {
  width: 100%;
  border: 1.5px solid rgba(26,57,86,0.55);
  border-bottom: 3px solid var(--gold-rich);
  border-radius: 12px;
  padding: 13px 16px;
  font-size: 16px;
  background: var(--white);
  min-height: 48px;
  transition: border-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.form-row textarea { min-height: 90px; resize: vertical; }
/* Focus: full turquoise border (the gold bottom rule is deliberately
   overridden while active — a temporary all-turquoise highlight, not a
   loss of the accent) plus a soft ring, layered on top of the sitewide
   gold :focus-visible outline rather than replacing it. */
.form-row input:focus, .form-row textarea:focus {
  border-color: var(--turquoise);
  box-shadow: 0 0 0 4px rgba(22,131,122,0.18);
}
/* No red in the locked palette: invalid fields get a heavier navy border
   plus the error text carries an explicit "!" glyph — the signal is weight
   + icon + text, never color alone. */
.form-row input[aria-invalid="true"], .form-row textarea[aria-invalid="true"] { border-color: var(--navy-deep); border-width: 2px; }
/* Invalid + focused: stays navy-deep (still wrong) rather than switching
   to the "all clear" turquoise ring, so the two states can't be confused. */
.form-row input[aria-invalid="true"]:focus, .form-row textarea[aria-invalid="true"]:focus {
  border-color: var(--navy-deep);
  box-shadow: 0 0 0 4px rgba(18,42,64,0.18);
}

.field-error {
  margin-top: 6px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--navy-deep);
  min-height: 1em;
}
.field-error:not(:empty)::before { content: '\26A0\FE0E\00A0'; }

.form-row--checkbox {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex-wrap: wrap;
}
.form-row--checkbox input[type="checkbox"] {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  accent-color: var(--turquoise);
  margin-top: 2px;
}
.form-row--checkbox label { font-size: 14.5px; font-weight: 400; margin-bottom: 0; }
.form-row--checkbox label a { color: var(--turquoise-deep); text-decoration: underline; }
.form-row--checkbox .field-error { flex-basis: 100%; }

.form-status {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--navy-deep);
  margin-bottom: 14px;
  min-height: 1em;
}
.form-status:not(:empty)::before { content: '\26A0\FE0E\00A0'; }
/* Reused for the network/server-error state (script.js) alongside its
   existing validation-reminder use — same "something's wrong" visual
   language, just richer content (a fallback mailto link) that plain
   validation text never needed. */
.form-status a { color: var(--turquoise-deep); font-weight: 700; text-decoration: underline; }

/* Honeypot: the standard "visually-hidden" idiom — clipped to a 1x1 box
   rather than shoved off-canvas with a large negative offset, not
   display:none/visibility:hidden (some bots skip those two specifically).
   A `left: -9999px` version was tried first and caused a real, reproducible
   bug found during this round's own verification: it made the ENTIRE page
   render as a blank flat background in Chromium (confirmed via a bisection
   — removing just this one rule was the difference between a fully blank
   screenshot and a fully correct one; every computed style/DOM check still
   reported normal values throughout, only the actual paint was affected).
   Root cause not fully diagnosed (a rasterizer/compositor issue with a
   ~10,000px-distant absolutely-positioned box on this specific page, not
   something CSS-review alone would have caught), but not worth re-risking
   for a field real users never see anyway — this clip-based pattern gives
   the identical result (unreachable, invisible, unread by not being
   included in the accessible name of anything) without the offset.
   tabindex="-1" + autocomplete="off" (on the input) and aria-hidden (on
   this wrapper) keep it unreachable by keyboard and screen readers too —
   it is never a real field for a real user of any kind. */
.form-honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.form-submit { width: 100%; }
.form-reassurance {
  margin-top: 16px;
  text-align: center;
  font-size: var(--fs-label);
  color: rgba(26,57,86,0.74);
}

/* Thank-you: the page's peak success moment, so it gets the same warmth
   treatment as the rest of this round rather than a bare outline check —
   a gold-rich top edge on the card, and a two-tone icon (gold-pastel badge
   fill, turquoise-deep check) instead of a flat currentColor outline. */
.form-thankyou {
  background: var(--white);
  border: 1px solid rgba(26,57,86,0.08);
  border-top: 4px solid var(--gold-rich);
  border-radius: 24px;
  padding: clamp(36px, 7vw, 56px);
  text-align: center;
  box-shadow: 0 20px 46px rgba(26,57,86,0.08);
}
.form-thankyou-icon {
  width: 64px;
  height: 64px;
  margin-inline: auto;
  margin-bottom: 18px;
}
.form-thankyou h3 { font-size: 26px; color: var(--turquoise-deep); }
.form-thankyou p { margin-top: 12px; color: rgba(26,57,86,0.82); }

/* =========================================================================
   Section 8 — FAQ ("שאלות נפוצות")
   Deliberately a different accordion rhythm than "How it works": flat
   divided rows with a +/x toggle glyph, no card shadows, so adjacent
   sections don't read as the same component reused.
   ========================================================================= */
.faq-section { padding-block: 100px 96px; position: relative; }

/* ---- Ambient glow: eighth instance of the sitewide glowDrift motif
   (implementation-notes/ambient-glow.md). Richer, more saturated pairing
   (plain --gold + --turquoise, both mid-tone) than Social proof's pastel
   one just above it — FAQ has the most open, uninterrupted background of
   any of the four newly-added sections (rows of text, no cards), so it
   can carry a slightly more present glow without competing with content.
   Corners swapped relative to Social proof's (top-end/bottom-start here
   vs. top-start/bottom-end there) for the same reason every other pair of
   adjacent sections varies corners — so the two don't read as the same
   glow shifted one section down. */
.faq-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
}
.faq-glow-blob { position: absolute; border-radius: 50%; }
.faq-glow-blob--1 {
  width: 54vw; height: 54vw; max-width: 640px; max-height: 640px;
  background: radial-gradient(circle, var(--gold) 0%, var(--gold) 35%, transparent 70%);
  opacity: .55;
  top: -14%; inset-inline-end: -12%;
  animation: glowDrift3 10s ease-in-out infinite alternate;
}
.faq-glow-blob--2 {
  width: 46vw; height: 46vw; max-width: 540px; max-height: 540px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  opacity: .55;
  bottom: -12%; inset-inline-start: -10%;
  animation: glowDrift1 9s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .faq-glow-blob--1 { width: 90vw; height: 90vw; top: -90px; opacity: .58; }
  .faq-glow-blob--2 { width: 78vw; height: 78vw; bottom: -70px; opacity: .58; }
}

.faq-head { max-width: 44ch; margin-bottom: 48px; position: relative; z-index: 1; }

.faq-list { max-width: 820px; border-top: 1px solid rgba(26,57,86,0.14); position: relative; z-index: 1; }
.faq-item { border-bottom: 1px solid rgba(26,57,86,0.14); }
.faq-trigger {
  display: flex;
  align-items: center;
  gap: 18px;
  width: 100%;
  padding: 24px 4px;
  text-align: start;
}
.faq-question {
  flex: 1;
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(17px, 1.4vw, 20px);
}
.faq-toggle {
  flex-shrink: 0;
  position: relative;
  width: 26px;
  height: 26px;
  color: var(--turquoise-deep);
}
.faq-toggle::before, .faq-toggle::after {
  content: '';
  position: absolute;
  background: currentColor;
  border-radius: 2px;
  /* physical left, not inset-inline-start: this pairs with a physical
     translate(-50%,-50%) below to center the crosshair — centering has no
     directional meaning, so mixing a logical offset with a physical
     transform here would only cancel out correctly in LTR. */
  top: 50%; left: 50%;
}
.faq-toggle::before { width: 16px; height: 2px; transform: translate(-50%,-50%); }
.faq-toggle::after { width: 2px; height: 16px; transform: translate(-50%,-50%); transition: transform 280ms var(--ease-out); }
.faq-item.is-open .faq-toggle::after { transform: translate(-50%,-50%) rotate(90deg); }

.faq-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 380ms var(--ease-out); }
.faq-item.is-open .faq-panel { grid-template-rows: 1fr; }
.faq-panel-inner { overflow: hidden; min-height: 0; }
.faq-answer { padding: 0 4px 24px; max-width: 62ch; color: rgba(26,57,86,0.82); }

.faq-cta { margin-top: 44px; position: relative; z-index: 1; }

/* =========================================================================
   Section 9 — Footer (dark navy closing anchor)
   This is the one genuine light-to-dark seam on the page (every other
   section boundary is light-to-light) — see implementation-notes/
   ambient-glow.md for the measurement that confirmed that, and for why
   only this boundary gets the stronger "grade the base color, not just
   the glow" treatment.
   ========================================================================= */
/* The graded top edge: fades FAQ's own --tint-mint into --navy-deep over
   a fixed 48px, then holds flat navy-deep for the rest of the footer —
   replaces what was an instant color swap at the box boundary with a
   short ramp, without diluting the footer's job as "you've reached the
   end" (48px is a sliver against this section's 300-700px+ height, and
   resolves to fully solid navy well before any real content — the
   72px top padding means text never sits inside the graded zone). */
.site-footer {
  position: relative;
  background: linear-gradient(to bottom, var(--tint-mint) 0, var(--navy-deep) 48px, var(--navy-deep) 100%);
  color: var(--cream);
  padding-block: 72px 28px;
}

/* ---- Ambient glow: ninth and final instance of the sitewide glowDrift
   motif (implementation-notes/ambient-glow.md) — the one dark-surface
   calibration on the site. Hero's own blob opacities (.55) or even the
   light sections' (.12-.22) would either vanish or read as a dirty smudge
   against --navy-deep; judged by eye against the actual rendered navy,
   not assumed, landed on .12/.10 — visible as a soft lift, not a stain.
   Only a TOP fade: this is the last section on the page, there is nothing
   below it to blend into (same reasoning as the Hero needing only a
   BOTTOM fade, mirrored). */
.footer-glow {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 100%);
}
.footer-glow-blob { position: absolute; border-radius: 50%; }
.footer-glow-blob--1 {
  width: 34vw; height: 34vw; max-width: 420px; max-height: 420px;
  background: radial-gradient(circle, var(--turquoise) 0%, var(--turquoise) 35%, transparent 70%);
  opacity: .4;
  top: -16%; inset-inline-start: -10%;
  animation: glowDrift2 8s ease-in-out infinite alternate;
}
.footer-glow-blob--2 {
  width: 30vw; height: 30vw; max-width: 380px; max-height: 380px;
  background: radial-gradient(circle, var(--gold-rich) 0%, var(--gold-rich) 35%, transparent 70%);
  opacity: .34;
  bottom: -14%; inset-inline-end: -8%;
  animation: glowDrift3 10s ease-in-out infinite alternate;
}
@media (max-width: 767px) {
  .footer-glow-blob--1 { width: 66vw; height: 66vw; top: -60px; opacity: .42; }
  .footer-glow-blob--2 { width: 58vw; height: 58vw; bottom: -50px; opacity: .36; }
}

.footer-inner {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 40px;
  position: relative;
  z-index: 1;
}
.footer-brand img { height: 28px; width: auto; }
.footer-tagline { margin-top: 16px; max-width: 32ch; font-size: 15px; color: rgba(245,242,236,0.68); line-height: 1.7; }
.footer-col h3 { font-family: var(--font-head); font-weight: 400; font-size: 16px; color: var(--turquoise-pastel); margin-bottom: 16px; }
.footer-col ul { display: flex; flex-direction: column; gap: 10px; }
.footer-col a { font-size: 14.5px; color: rgba(245,242,236,0.78); text-decoration: none; }
@media (hover: hover) { .footer-col a:hover { color: var(--cream); text-decoration: underline; } }
/* The remaining "מידע" column still has its h3 (not in this round's
   removal scope), so a naive removal of the other two headings left
   their content flush with the row's top — sitting above where מידע's
   own links start, reading as misaligned leftover columns rather than a
   deliberate layout. Sizing these to their own content height and
   pinning them to the row's bottom (rather than a hardcoded px offset
   guessing the heading's height) keeps them aligned with מידע's link
   list without depending on a fragile fixed number that could drift if
   that heading's font/margin ever changes. */
.footer-col--headless { align-self: end; }

.footer-social-links { display: flex; gap: 12px; }
.footer-social-links a {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(245,242,236,0.08);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* 21px, up from 18px — modest bump, not a resize of the circle's own
   proportions (padding around the icon stays ~11-11.5px either way).
   44px circle doubles as a real WCAG/HIG touch-target minimum, not just
   a size that reads better. */
/* fill:currentColor scoped to only the svg root — Instagram's lens dot
   and LinkedIn's "i" dot are <circle>s with no fill attribute of their
   own, so without this they'd default to solid black (the same bug this
   project already hit on the Situations icon-1 accent dot and the Strips
   calculator icon; same fix, same reasoning). Scoping it to the root
   reaches the dots via ordinary inheritance without overriding any
   shape's own explicit fill="none" — a rule targeting the shapes
   directly would clobber those. */
.footer-social-links svg { width: 21px; height: 21px; fill: currentColor; }
@media (hover: hover) { .footer-social-links a:hover { background: rgba(245,242,236,0.18); } }

.footer-bottom {
  margin-top: 56px;
  padding-top: 24px;
  border-top: 1px solid rgba(245,242,236,0.14);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  justify-content: space-between;
  position: relative;
  z-index: 1;
  font-size: 13px;
  color: rgba(245,242,236,0.58);
}

@media (max-width: 899px) {
  .footer-inner { grid-template-columns: 1fr 1fr; row-gap: 36px; }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
  .footer-inner { grid-template-columns: 1fr; }
}

/* =========================================================================
   Legal pages (privacy.html, accessibility.html) — see
   implementation-notes/legal-pages.md. Deliberately plain: no ambient
   glow, no motif, no card. Reuses only existing tokens/type scale — the
   only new selectors are the ones needed for a single-column long-form
   text layout, which nothing else on the site needed until now.
   ========================================================================= */
.legal-main { padding-block: calc(var(--header-h) + 48px) 96px; }
.legal-wrap {
  /* Narrower than the sitewide --wrap (1360px, built for multi-column
     marketing sections) — a comfortable reading measure for long-form
     Hebrew body text, not the page's full content width. */
  max-width: 720px;
  margin-inline: auto;
  padding-inline: clamp(20px, 6vw, 64px);
}
.legal-title { font-size: var(--fs-section); line-height: 1.12; margin-bottom: 32px; }
.legal-wrap p.legal-intro { margin-bottom: 8px; }
.legal-wrap h2 {
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  line-height: 1.25;
  margin-top: 48px;
  margin-bottom: 16px;
}
.legal-wrap p { font-size: var(--fs-body); line-height: 1.7; color: rgba(26,57,86,0.86); margin-bottom: 20px; }
/* Sitewide reset sets ul{list-style:none}; a real semantic list on a text
   page needs its bullets back to actually read as a list, not just be
   marked up as one. list-style-position stays the browser default
   (outside) — RTL puts the marker on the line's own start side (visually
   the right) automatically, no logical-property special-casing needed. */
.legal-wrap ul { padding-inline-start: 1.4em; margin: -4px 0 20px; display: flex; flex-direction: column; gap: 8px; }
.legal-wrap li { font-size: var(--fs-body); line-height: 1.7; color: rgba(26,57,86,0.86); list-style: disc; }
.legal-wrap a { color: var(--turquoise-deep); text-decoration: underline; text-underline-offset: 2px; }
@media (hover: hover) { .legal-wrap a:hover { color: var(--turquoise); } }
.legal-wrap p.legal-updated {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid rgba(26,57,86,0.12);
  font-size: var(--fs-label);
  color: rgba(26,57,86,0.72);
}
