/* ============================================================
   batchenpeled.social

   PALETTE — measured off the live site, not invented.
   Every section on batchenpeled.social sits on #F8F2DC. Its
   borders are #BC957C. Buttons are 30px pills, cards 15px. The
   gold comes off her own BP monogram and the before/after cards.
   Warm cream is the brand; neutral gray is not in it anywhere.

   LOCKED
   - Ground ... --cream everywhere, --paper for lifted surfaces
   - Accent .. --gold / --gold-deep. --tan is a line colour only.
   - Radius .. pill buttons, 15px cards, 12px inputs (hers)
   - Type .... Fredoka display + Assistant body (hers)
   - Light only. No dark variant.
   ============================================================ */

:root {
  color-scheme: light;

  --cream:      #F8F2DC;   /* the live site's section background */
  --cream-deep: #F1E7C8;   /* derived, for banding */
  --paper:      #FFFFFF;
  --tan:        #BC957C;   /* the live site's border colour */
  --tan-soft:   #E3D2BE;
  --gold:       #A97C3F;   /* 3.3:1 on cream - large text only */
  --gold-deep:  #7F5C24;   /* 5.4:1 on cream, 4.9:1 on cream-deep, 6.1:1 under white */
  --ink:        #252525;   /* 13.7:1 on cream */
  --ink-soft:   #6B5D4A;   /* 5.7:1 on cream, tinted warm not gray */
  --danger:     #9E2B1E;

  /* These five used to be literals baked into their one call site each.
     The accessibility toolbar's colour themes (styles.css, further down)
     override the whole palette above by reassigning these custom
     properties - a literal can't be reached that way, so anything a theme
     needs to touch has to live here instead, even if only one rule reads
     it today. */
  --gold-hover:      #9A7038;   /* .btn--accent:hover fill/border */
  --on-media:        #FFF6E4;   /* text painted over a photo/video, not the page background */
  --veil-rgb:        38 28 16;  /* .ytcard__veil's own scrim tint */
  --handle-ring-rgb: 94 68 38;  /* .compare__handle's 1px seam ring */
  --backdrop-rgb:    42 32 20;  /* .lightbox::backdrop tint */

  --r-card:  15px;
  --r-input: 12px;

  --gutter: clamp(20px, 5vw, 52px);
  /* Notched phones in landscape put the display cutout inside the viewport,
     so the gutter has to be at least the safe-area inset. */
  --gutter-safe: max(clamp(20px, 5vw, 52px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));

  --ease: cubic-bezier(.16, 1, .3, 1);
  --nav-h: 72px;

  --step-lead: clamp(1.02rem, .97rem + .3vw, 1.18rem);
  --step-h2:   clamp(2.1rem, 1.5rem + 2.6vw, 3.6rem);
  --step-h1:   clamp(2.6rem, 1.7rem + 3.8vw, 5rem);

  --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M224 128a8 8 0 0 1-8 8H59.31l58.35 58.34a8 8 0 0 1-11.32 11.32l-72-72a8 8 0 0 1 0-11.32l72-72a8 8 0 0 1 11.32 11.32L59.31 120H216a8 8 0 0 1 8 8Z'/%3E%3C/svg%3E");

  /* --arrow is drawn pointing LEFT, which is "forward" in Hebrew. Multiply any
     directional transform by --flip and it points the right way in both
     languages, without shipping a second mirrored copy of the SVG. */
  --flip: 1;
}
:root[dir="ltr"] { --flip: -1; }

*, *::before, *::after { box-sizing: border-box; }

/* The UA gives <figure> `margin: 1em 40px`. Left unreset it pushed the work
   pages' hero media 40px outside its grid column, where overflow-x:hidden
   silently clipped it. */
figure { margin: 0; }

/* The default blue flash on tap looks like a bug next to the :active states. */
a, button, [role="slider"], summary { -webkit-tap-highlight-color: transparent; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
:root.a11y-motion-off { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: Assistant, system-ui, "Segoe UI", sans-serif;
  font-size: 1.0625rem;
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, .btn, .stat dd, .nav__brand-text, .case__name {
  font-family: Fredoka, Assistant, system-ui, sans-serif;
  font-weight: 500;
  line-height: 1.14;
  letter-spacing: -.02em;
}

img, video { max-width: 100%; display: block; }
a { color: inherit; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--gold-deep);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  /* Physical left + physical translate. Centring is not a directional idea, and
     mixing a LOGICAL inset with a PHYSICAL transform only happened to centre in
     RTL - in LTR it put the link half off-screen. */
  /* Hiding used to be a fixed top: -100px, which stopped covering the link's
     own height once the accessibility toolbar's font-scale control could
     make that height grow past 100px - at ~1.85x it started poking a few
     px into view on every page. translateY(-100%) is relative to the
     element's OWN box, not a fixed length, so it always fully hides it
     regardless of how large the text gets. */
  position: absolute; left: 50%; top: 0;
  transform: translate(-50%, -100%);
  z-index: 200; padding: .8rem 1.3rem;
  background: var(--gold-deep); color: var(--paper);
  border-radius: 0 0 var(--r-input) var(--r-input); font-weight: 600;
  transition: transform .2s var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); }

.wrap { width: 100%; max-width: 1220px; margin-inline: auto; padding-inline: var(--gutter-safe); }

.section { padding-block: clamp(5rem, 10vw, 9.5rem); }
.section__title { font-size: var(--step-h2); margin: 0 0 1.1rem; text-wrap: balance; }
.section__lead {
  font-size: var(--step-lead); color: var(--ink-soft);
  max-width: 56ch; margin: 0 0 clamp(2.5rem, 5vw, 4rem);
}

/* Banding keeps the cream from going flat over 6 screens. */
.band-paper { background: var(--paper); }
.band-deep  { background: var(--cream-deep); }

/* ─── Buttons ─────────────────────────────────────────────────
   Her live site: 30px pill, white fill, dark label. Primary is
   promoted to bronze, which is already in her monogram and cards.
   ───────────────────────────────────────────────────────────── */
.btn {
  --btn-bg: transparent; --btn-fg: var(--ink); --btn-bd: var(--tan);
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .8rem 1.6rem;
  font-size: 1rem; font-weight: 500;
  /* No white-space: nowrap. At normal size every button already fits on one
     line because there's room, not because wrapping is disabled - so this
     changes nothing visually today. But nowrap forced a real WCAG 1.4.10
     failure at large text sizes: "לצפות בעבודות" alone stopped fitting in a
     320px viewport at 200% zoom, and with nowrap the button (and everything
     containing it) had no choice but to push the whole page wider than the
     screen. A two-line button label under extreme zoom is a fine fallback;
     page-wide horizontal overflow is not. */
  text-decoration: none; cursor: pointer;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid var(--btn-bd); border-radius: 999px;
  transition: transform .2s var(--ease), background-color .2s var(--ease),
              border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.btn--accent {
  --btn-bg: var(--gold-deep); --btn-fg: var(--paper); --btn-bd: var(--gold-deep);
  box-shadow: 0 2px 10px rgb(138 100 48 / .22);
}
.btn--paper { --btn-bg: var(--paper); --btn-fg: var(--ink); --btn-bd: var(--tan-soft); }
.btn--lg { padding: 1rem 2.1rem; font-size: 1.06rem; }
.btn--block { width: 100%; }

@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-2px); }
  .btn--accent:hover { --btn-bg: var(--gold-hover); --btn-bd: var(--gold-hover); box-shadow: 0 6px 18px rgb(138 100 48 / .28); }
  .btn--paper:hover { --btn-bd: var(--tan); }
  .btn--ghost:hover { --btn-bd: var(--gold-deep); }
}
.btn:active { transform: translateY(0) scale(.985); }
@media (prefers-reduced-motion: reduce) { .btn:hover, .btn:active { transform: none; } }
:root.a11y-motion-off .btn:hover,
:root.a11y-motion-off .btn:active { transform: none; }

.link {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--gold-deep); text-decoration: none; font-weight: 600; font-size: .96rem;
  border-bottom: 1px solid var(--tan-soft); padding-bottom: 3px;
  transition: border-color .2s var(--ease);
}
/* Drawn arrow (Phosphor ArrowLeft) via mask, not a unicode glyph. */
.link::after {
  content: ""; width: 15px; height: 15px; background: currentColor;
  -webkit-mask: var(--arrow) center / contain no-repeat;
          mask: var(--arrow) center / contain no-repeat;
  transform: scaleX(var(--flip));
  transition: transform .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .link:hover { border-bottom-color: var(--gold-deep); }
  /* translateX applies in the flipped local space, so -4px always means "the
     way the arrow points" regardless of language. */
  .link:hover::after { transform: scaleX(var(--flip)) translateX(-4px); }
}

/* ─── Navigation ─────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 100;
  /* Solid first, translucent second. color-mix() needs Safari 16.2 (Dec
     2022); older WebKit discards the whole declaration and would leave this
     bar with NO background at all - page content scrolling visibly through
     the nav. The @supports rule below does not catch that case, because
     those Safari versions DO have backdrop-filter, they just lack
     color-mix. A plain preceding declaration is what actually covers it:
     anything that cannot parse line two simply keeps line one. */
  background: var(--cream);
  background: color-mix(in srgb, var(--cream) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.2); -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid transparent;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.nav.is-stuck {
  border-bottom-color: var(--tan-soft);
  background: var(--cream);
  background: color-mix(in srgb, var(--cream) 96%, transparent);
}
@supports not (backdrop-filter: blur(1px)) { .nav { background: var(--cream); } }

.nav__inner {
  /* min-height, not height: at normal size the content is always shorter
     than --nav-h so this renders identically, but a fixed height let the
     desktop CTA's own box overflow the bar once the accessibility
     toolbar's font-scale control grew it past ~1.6x - align-items:center
     doesn't clip an oversized flex item, it just lets it spill past the
     container's edge. min-height lets the bar grow with its content
     instead. */
  min-height: var(--nav-h);
  max-width: 1220px; margin-inline: auto; padding-inline: var(--gutter-safe);
  display: flex; align-items: center; gap: 1.5rem;
}
.nav__brand { display: flex; align-items: center; gap: .65rem; text-decoration: none; margin-inline-end: auto; }
.nav__brand img { width: 42px; height: 42px; }
.nav__brand-text { display: flex; flex-direction: column; font-size: 1rem; line-height: 1.15; }
.nav__brand-text small { font-size: .75rem; font-weight: 400; color: var(--ink-soft); letter-spacing: .12em; font-family: Assistant, sans-serif; }

.nav__links { display: flex; gap: 1.85rem; }
.nav__links a { text-decoration: none; font-size: .98rem; color: var(--ink-soft); transition: color .2s var(--ease); }
.nav__links a:hover { color: var(--ink); }

/* Hidden until the module confirms en.js actually loaded, so a missing or
   broken dictionary means NO control rather than a dead one. */
.lang { display: none; }
.i18n-ready .lang {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 34px; padding: .3rem .7rem;
  font: inherit; font-size: .85rem; font-weight: 600; letter-spacing: .04em;
  color: var(--ink-soft); background: transparent;
  border: 1px solid var(--tan-soft); border-radius: 999px; cursor: pointer;
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .lang:hover { color: var(--ink); border-color: var(--tan); }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

.nav__toggle {
  display: none; width: 44px; height: 44px; padding: 0;
  background: none; border: 0; cursor: pointer;
  flex-direction: column; align-items: center; justify-content: center; gap: 6px;
}
.nav__toggle span { display: block; width: 22px; height: 2px; background: var(--ink); transition: transform .25s var(--ease); }
.nav__toggle[aria-expanded="true"] span:first-child { transform: translateY(4px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:last-child  { transform: translateY(-4px) rotate(-45deg); }
.nav__drawer { display: none; }

@media (max-width: 900px) {
  .nav__links, .nav__cta { display: none; }
  .nav__toggle { display: flex; }
  /* Three items in the bar instead of two once the toggle joins the
     hamburger. At 320px: brand ~142 + lang 48 + burger 44 + gaps = ~270.
     px, not rem: a rem gap doubles under 200% text zoom while the bar's own
     width (from --gutter-safe, px/vw-based) does not - on the narrowest
     phones that was enough on its own to push nav__inner past the viewport.
     12px is the same size .75rem already was at normal zoom; this only
     changes what happens when zoomed. */
  .nav__inner { gap: 12px; }
  .nav__drawer {
    display: flex; flex-direction: column; gap: .25rem;
    padding: .5rem var(--gutter-safe) 1.5rem;
    background: var(--cream); border-bottom: 1px solid var(--tan-soft);
    max-height: calc(100dvh - var(--nav-h)); overflow-y: auto;
  }
  .nav__drawer[hidden] { display: none; }
  .nav__drawer a { text-decoration: none; padding: .9rem 0; color: var(--ink-soft); border-bottom: 1px solid var(--tan-soft); }
  .nav__drawer .btn { margin-top: 1rem; color: var(--paper); }
}

/* ─── Shared vertical media primitive ────────────────────────── */
.reel {
  margin: 0; position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--tan-soft);
  border: 1px solid var(--tan-soft);
  box-shadow: 0 14px 40px rgb(94 68 38 / .13);
}
.reel__video { width: 100%; height: 100%; object-fit: cover; }

/* ─── Hero ───────────────────────────────────────────────────── */
.hero {
  min-height: calc(100dvh - var(--nav-h));
  display: flex; align-items: center;
  padding-block: clamp(2.5rem, 6vw, 5rem);
  padding-inline: var(--gutter-safe);
}
.hero__grid {
  width: 100%; max-width: 1220px; margin-inline: auto;
  display: grid; gap: clamp(2rem, 5vw, 5rem);
  grid-template-columns: 1.1fr .9fr; align-items: center;
}
.hero__title { font-size: var(--step-h1); margin: 0 0 1.3rem; font-weight: 600; }
.hero__title span { display: block; }
.hero__title em { font-style: normal; color: var(--gold); }
.hero__sub { font-size: var(--step-lead); color: var(--ink-soft); max-width: 38ch; margin: 0 0 2.2rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; }
.hero__media { justify-self: end; width: 100%; max-width: 390px; }

/* The one page-load moment. Pure CSS, so nothing depends on JS
   being alive for the content to be readable. */
@media (prefers-reduced-motion: no-preference) {
  .hero__title, .hero__sub, .hero__actions, .hero__media {
    animation: rise .85s var(--ease) backwards;
  }
  .hero__sub     { animation-delay: .07s; }
  .hero__actions { animation-delay: .14s; }
  .hero__media   { animation-delay: .1s; }
}
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }

/* The accessibility toolbar's "stop animations" control needs to suppress
   this even when the OS reports no-preference. Unlike every other motion
   block in this file, the media query above is an ENABLING query, not a
   disabling one, so it can't be mirrored with a matching a11y-motion-off
   rule the way the others are - this is the inverse instead. It's also
   one-shot: the .85s entrance is over long before anyone could reach the
   toolbar, so this class only ever matters if it was already set, from a
   saved preference applied before this page's first paint. */
:root.a11y-motion-off .hero__title,
:root.a11y-motion-off .hero__sub,
:root.a11y-motion-off .hero__actions,
:root.a11y-motion-off .hero__media {
  animation: none;
}

@media (max-width: 900px) {
  .hero { min-height: 0; padding-block: clamp(2rem, 8vw, 3.5rem) clamp(3rem, 10vw, 5rem); }
  .hero__grid { grid-template-columns: 1fr; gap: 2.25rem; }
  .hero__media { justify-self: stretch; max-width: none; }
  .hero__media .reel { aspect-ratio: 4 / 5; }
}

/* ─── Work ───────────────────────────────────────────────────── */
.work .section__title { margin-bottom: clamp(2.5rem, 5vw, 4rem); }

/* One scrolling row. Her business clip is landscape and the other two are
   vertical, so instead of forcing a shared width (which steps raggedly) every
   clip gets the same media HEIGHT and takes whatever width its own aspect
   needs. Portrait and landscape then sit on one baseline, like a film strip.
   The row bleeds to the viewport edges so it reads as continuing off-screen. */
.reels {
  --gap: clamp(.9rem, 2vw, 1.6rem);
  display: flex;
  align-items: flex-start;
  gap: var(--gap);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch; /* momentum scroll in older WKWebViews (WhatsApp/Instagram in-app browser) */
  /* proximity, never mandatory. The cards differ in width (a 9:16 reel next to
     a 16:9 clip), so the last card's start-snap position sits far beyond the
     maximum scroll. Under mandatory the browser refuses to rest there and
     springs back, which made the third card unreachable. */
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  margin-inline: calc(var(--gutter-safe) * -1);
  padding-inline: var(--gutter-safe);
  padding-bottom: 1.1rem;

  /* The scrollbar stays VISIBLE on purpose. Hiding it left mouse users with no
     way to reach the third card at all: nothing to drag, and the wheel scrolls
     the page rather than the row. */
  scrollbar-width: thin;
  scrollbar-color: var(--tan) var(--tan-soft);
}
.reels::-webkit-scrollbar { height: 9px; }
.reels::-webkit-scrollbar-track { background: var(--tan-soft); border-radius: 999px; }
.reels::-webkit-scrollbar-thumb { background: var(--tan); border-radius: 999px; }
.reels::-webkit-scrollbar-thumb:hover { background: var(--gold-deep); }
/* Only offer the grab cursor when there is actually somewhere to go. On desktop
   all three cards fit, so the row does not scroll and must not pretend to. */
.reels.is-scrollable { cursor: grab; }
.reels.is-dragging { cursor: grabbing; scroll-snap-type: none; scroll-behavior: auto; }
.reels.is-dragging * { pointer-events: none; }

/* All three fit the row at once, so every title reads without moving the rail.
   Widths are fractions of the container derived from the aspect ratios:
   9:16 + 16:9 + 9:16 = 2.903 height-units, so 0.5625/2.903 and 1.7778/2.903.
   Sizing this way keeps the three media on one shared height automatically,
   at any container width, with nothing cropped. */
.reel-card { flex: 0 0 calc((100% - 2 * var(--gap)) * 0.1938); scroll-snap-align: start; }
.reel-card--wide { flex: 0 0 calc((100% - 2 * var(--gap)) * 0.6124); }
.reel-card .reel { width: 100%; height: auto; aspect-ratio: 9 / 16; }
.reel-card--wide .reel { aspect-ratio: 16 / 9; }

.reel-card { display: flex; flex-direction: column; gap: .55rem; }
.reel-card__title { font-size: clamp(1.1rem, .95rem + .5vw, 1.35rem); margin: .8rem 0 0; }
/* Capped so the caption under the wide landscape card does not run the full
   width of the clip while the portrait ones wrap at a third of it. */
.reel-card__text { margin: 0; color: var(--ink-soft); font-size: .92rem; line-height: 1.55; max-width: 36ch; }
.reel-card .link { margin-top: .35rem; align-self: flex-start; }

.reel-card .reel { transition: box-shadow .3s var(--ease), border-color .3s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .reel-card:hover .reel { border-color: var(--tan); box-shadow: 0 20px 52px rgb(94 68 38 / .2); }
}

@media (max-width: 760px) {
  /* Fitting all three cards at once (the desktop layout) would shrink each
     reel to ~70px wide on a phone screen: unwatchable. Below 760px the row
     goes back to a swipe rail, sized so a reel is actually watchable. Aspect
     ratios still come from the base rules above. The wide card's width is
     derived from the vertical card's width rather than capped independently,
     so its media lands on the same height as the two vertical reels instead
     of floating short against their flex-start top edge. */
  .reel-card { flex: 0 0 min(52vw, 210px); }
  .reel-card--wide { flex: 0 0 calc(min(52vw, 210px) * 256 / 81); }
}

/* ─── Results ────────────────────────────────────────────────── */
.cases { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1.5rem, 3vw, 2.6rem); }
.case {
  background: var(--cream);
  border: 1px solid var(--tan-soft);
  border-radius: var(--r-card);
  padding: clamp(1.5rem, 3vw, 2.4rem);
}
.case__head { margin-bottom: 1.6rem; }
.case__name { font-size: 1.6rem; margin: 0 0 .2rem; }
.case__meta { margin: 0; color: var(--ink-soft); font-size: .93rem; }

.stats { margin: 0; display: grid; gap: 1.3rem; }
.stat dt { color: var(--ink-soft); font-size: .88rem; margin-bottom: .3rem; }
.stat dd {
  margin: 0; display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  font-size: 1.6rem; font-weight: 600; font-variant-numeric: tabular-nums;
  font-family: Fredoka, sans-serif;
}
.stat--hero dd { font-size: clamp(2.1rem, 1.4rem + 2.2vw, 3.1rem); }
.stat__from { color: var(--ink-soft); font-weight: 400; font-size: .5em; text-decoration: line-through; text-decoration-color: var(--tan); }
.stat__arrow {
  width: .5em; height: .5em; background: var(--tan); align-self: center;
  -webkit-mask: var(--arrow) center / contain no-repeat;
          mask: var(--arrow) center / contain no-repeat;
  transform: scaleX(var(--flip));
}
.stat__to { color: var(--gold); }
.case__note { margin: 1.3rem 0 0; color: var(--ink-soft); font-size: .93rem; }

/* ─── Before/after comparison ────────────────────────────────
   The section claims an account went from X to Y. Dragging the
   seam is that claim, made physical. This is the page's one
   authored motion moment.

   direction:ltr is deliberate: a spatial control, not text, so
   the drag maths stays in one coordinate space. Labels are placed
   explicitly so "לפני" sits right, where a Hebrew reader starts.
   ───────────────────────────────────────────────────────────── */
.compare {
  position: relative;
  direction: ltr;
  margin-top: 1.8rem;
  aspect-ratio: var(--cmp-ratio, 3 / 4);
  border-radius: var(--r-card);
  overflow: hidden;
  border: 1px solid var(--tan-soft);
  background: var(--paper);
  box-shadow: 0 12px 34px rgb(94 68 38 / .14);
  touch-action: pan-y;
  user-select: none; -webkit-user-select: none;
  cursor: ew-resize;
}
.compare__img { width: 100%; height: 100%; object-fit: cover; object-position: top center; pointer-events: none; }
.compare__after { position: absolute; inset: 0; clip-path: inset(0 100% 0 0); will-change: clip-path; }

/* No transition by default: dragging and resizing track 1:1.
   Click, keyboard and the intro opt in via a class. */
.compare.is-anim .compare__after,
.compare.is-anim .compare__handle { transition: clip-path 240ms var(--ease), transform 240ms var(--ease); }
.compare.is-intro .compare__after,
.compare.is-intro .compare__handle { transition: clip-path 900ms var(--ease), transform 900ms var(--ease); }

.compare__label {
  position: absolute; inset-block-start: .8rem;
  padding: .25rem .85rem; border-radius: 999px;
  /* plaintext derives each label's direction from its own first strong
     character, so "לפני" reads RTL and "Before" reads LTR - inside a .compare
     that is permanently direction:ltr, and with no coupling to <html dir>. */
  font-size: .78rem; font-weight: 600; unicode-bidi: plaintext;
}
/* Solid fallback first - see the note on .nav about color-mix and Safari.
   This one sits directly on a photo, so losing the background would leave
   the label unreadable rather than merely plain. */
.compare__label--before { right: .8rem; background: var(--cream); background: color-mix(in srgb, var(--cream) 92%, transparent); color: var(--ink); border: 1px solid var(--tan-soft); }
.compare__label--after  { left: .8rem;  background: var(--gold-deep); color: var(--paper); }

.compare__handle {
  position: absolute; top: 0; bottom: 0; left: 0; width: 0;
  display: grid; place-items: center;
  transform: translateX(0); touch-action: none;
}
.compare__handle::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: -1px; width: 2px;
  background: var(--cream); box-shadow: 0 0 0 1px rgb(var(--handle-ring-rgb) / .22);
}
.compare__grip {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 999px;
  background: var(--cream); border: 1px solid var(--tan);
  box-shadow: 0 3px 14px rgb(94 68 38 / .26);
  cursor: ew-resize;
}
.compare__grip svg { width: 13px; height: 13px; fill: var(--gold-deep); }
.compare__handle:focus-visible { outline: none; }
.compare__handle:focus-visible .compare__grip { outline: 2px solid var(--gold-deep); outline-offset: 3px; }

.compare__zoom {
  position: absolute; inset-block-end: .8rem; left: .8rem;
  width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 999px; cursor: zoom-in;
  background: var(--cream);   /* fallback - see .nav note on color-mix */
  background: color-mix(in srgb, var(--cream) 92%, transparent);
  border: 1px solid var(--tan-soft);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.compare__zoom svg { width: 15px; height: 15px; fill: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .compare.is-anim .compare__after, .compare.is-anim .compare__handle,
  .compare.is-intro .compare__after, .compare.is-intro .compare__handle { transition: none; }
}
:root.a11y-motion-off .compare.is-anim .compare__after,
:root.a11y-motion-off .compare.is-anim .compare__handle,
:root.a11y-motion-off .compare.is-intro .compare__after,
:root.a11y-motion-off .compare.is-intro .compare__handle { transition: none; }
@media (max-width: 760px) { .cases { grid-template-columns: 1fr; } }

/* ─── About ──────────────────────────────────────────────────── */
.about__grid { display: grid; grid-template-columns: .92fr 1.08fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.about__media {
  margin: 0; aspect-ratio: 4 / 5;
  border-radius: var(--r-card); overflow: hidden;
  border: 1px solid var(--tan-soft); background: var(--tan-soft);
  box-shadow: 0 16px 44px rgb(94 68 38 / .15);
}
.about__media video { width: 100%; height: 100%; object-fit: cover; }
.about__copy p { color: var(--ink-soft); max-width: 62ch; }
.about__copy .section__title { margin-bottom: 1.5rem; }

.chips { list-style: none; display: flex; flex-wrap: wrap; gap: .55rem; padding: 0; margin: 2.2rem 0 0; }
.chips li {
  padding: .5rem 1.1rem; border-radius: 999px;
  border: 1px solid var(--tan-soft); background: var(--paper);
  font-size: .9rem; color: var(--ink);
}

@media (max-width: 900px) {
  .about__grid { grid-template-columns: 1fr; }
  /* The about clip is vertical now, so a 16:10 mobile box would gut the frame. */
  .about__media { aspect-ratio: 4 / 5; }
}

/* ─── Testimonials ───────────────────────────────────────────── */
.voices .section__title { margin-bottom: clamp(2rem, 4vw, 3rem); }

/* Two rows drifting opposite ways. Deliberately SLOW: the before/after slider
   is meant to be the page's one motion moment, and this must not out-shout it.
   It reads as a slow current under the section, not as an animation. */
.quotes {
  /* Tuned as SPEED, not duration. A fixed duration means the phone track -
     a third of the desktop width - crawls at a third of the pace, so the row
     looks static during the few seconds anyone actually spends here. The
     per-breakpoint times below keep it near 28px/s everywhere. */
  --row-time: 48s;
  /* px bounds, not rem: the card width above (min(76vw, 27rem)) picks its vw
     side at mobile widths and is immune to the browser's text-only zoom.
     A rem-bound gap is not - it grows under zoom while the card width
     doesn't, which desyncs the seamless-loop math this marquee depends on
     and leaks the oversized track past .quotes__row's overflow:hidden. */
  --quote-gap: clamp(14px, 2vw, 21px);
  display: grid; gap: var(--quote-gap);
  /* Full-bleed, so the row reads as continuing past the screen. */
  margin-inline: calc(var(--gutter-safe) * -1);
}
/* Forced ltr so the over-wide track anchors its LEFT edge to the row. Under the
   page's rtl it anchored right instead and overflowed leftwards, so drifting
   left emptied the right-hand side of the row within a second. Each card still
   sets its own text direction, so Hebrew reads correctly inside. */
.quotes__row { overflow: hidden; direction: ltr; }
/* Fade both ends instead of letting cards hit a hard edge. */
@supports (mask-image: linear-gradient(90deg, #000, transparent)) {
  .quotes__row {
    -webkit-mask: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
            mask: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  }
}
.quotes__track {
  display: flex; width: max-content;
  animation: quote-drift var(--row-time) linear infinite;
}
/* The spacing is a MARGIN on each card, not a flex gap. With `gap`, six cards
   have only five gaps, so half the track is 3 cards + 2.5 gaps while one set
   advance is 3 cards + 3 gaps - a 10px jump every loop. Carrying the gap on
   the card makes the track exactly two identical halves. */
.quotes__track > .quote { margin-inline-end: var(--quote-gap); }
@keyframes quote-drift { to { transform: translateX(-50%); } }
.quotes__row--back .quotes__track { animation-direction: reverse; animation-duration: calc(var(--row-time) * 1.25); }

/* No pause on hover. It looks harmless on a desktop, but touch browsers apply
   :hover on tap and keep it applied until you tap somewhere else, so on a phone
   one tap stopped the row dead and it stayed stopped. Reduced-motion below is
   the way this stops. */

.quote {
  flex: 0 0 min(76vw, 27rem);
  margin: 0;
  padding: clamp(1.3rem, 2.5vw, 1.8rem) clamp(1.4rem, 2.5vw, 1.9rem);
  background: var(--cream);
  border: 1px solid var(--tan-soft);
  border-radius: var(--r-card);
  /* Each card takes direction from its own first strong character, so the
     same markup reads correctly in Hebrew and in English. */
  unicode-bidi: plaintext;
}
.quote blockquote {
  margin: 0;
  font-family: Fredoka, sans-serif;
  font-size: clamp(1.02rem, .96rem + .32vw, 1.2rem);
  font-weight: 400; line-height: 1.5; letter-spacing: -.015em;
}
/* No quote currently carries an attribution. Kept so that adding a
   <figcaption class="quote__by"> later needs no new CSS. */
.quote__by { color: var(--ink-soft); font-size: .88rem; margin-top: .7rem; }

/* Shorter track on a phone, so a shorter loop to hold the same pace. Nothing
   pauses it, so the pace itself has to stay readable. */
@media (max-width: 720px) { .quotes { --row-time: 26s; } }

/* Nothing moves, and the duplicate set would be a visible repeat, so drop back
   to the static two-column layout this section had before. */
@media (prefers-reduced-motion: reduce) {
  .quotes { display: block; margin-inline: 0; }
  /* Hand direction back to the page so the grid fills right-to-left in Hebrew. */
  .quotes__row { overflow: visible; -webkit-mask: none; mask: none; direction: inherit; }
  .quotes__track {
    display: grid; grid-template-columns: repeat(2, 1fr); width: auto;
    gap: var(--quote-gap);
    animation: none;
  }
  .quotes__dupe { display: none; }
  /* The margin is the marquee's spacing mechanism; the grid uses gap instead. */
  .quotes__track > .quote { flex: none; margin-inline-end: 0; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 720px) {
  .quotes__track { grid-template-columns: 1fr; }
}
/* Same replacement as the reduce media query above, keyed off the toolbar's
   class instead of the OS preference - repeated in full rather than
   suppressing just the animation, since this is an additive layout change
   (grid instead of track), not a simple on/off. */
:root.a11y-motion-off .quotes { display: block; margin-inline: 0; }
:root.a11y-motion-off .quotes__row { overflow: visible; -webkit-mask: none; mask: none; direction: inherit; }
:root.a11y-motion-off .quotes__track {
  display: grid; grid-template-columns: repeat(2, 1fr); width: auto;
  gap: var(--quote-gap);
  animation: none;
}
:root.a11y-motion-off .quotes__dupe { display: none; }
:root.a11y-motion-off .quotes__track > .quote { flex: none; margin-inline-end: 0; }
@media (max-width: 720px) {
  :root.a11y-motion-off .quotes__track { grid-template-columns: 1fr; }
}

/* ─── Contact ────────────────────────────────────────────────── */
.contact__grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(2.5rem, 5vw, 5rem); align-items: start; }
.contact__aside .section__lead { margin-bottom: 2.5rem; }

.channels { list-style: none; padding: 0; margin: 0; display: grid; gap: .65rem; }
.channels a {
  display: flex; align-items: center; gap: .95rem;
  padding: .95rem 1.15rem; text-decoration: none;
  background: var(--paper); border: 1px solid var(--tan-soft); border-radius: var(--r-input);
  transition: border-color .2s var(--ease), transform .2s var(--ease);
}
.channels svg { width: 22px; height: 22px; fill: var(--gold-deep); flex: none; }
.channels span { display: flex; flex-direction: column; font-weight: 600; font-size: .98rem; }
.channels em { font-style: normal; font-weight: 400; font-size: .85rem; color: var(--ink-soft); }
@media (hover: hover) and (pointer: fine) {
  .channels a:hover { border-color: var(--tan); transform: translateX(calc(-3px * var(--flip))); }
}
@media (prefers-reduced-motion: reduce) { .channels a:hover { transform: none; } }
:root.a11y-motion-off .channels a:hover { transform: none; }

.form {
  /* px, not rem, for the same reason as --quote-gap and .nav__inner's gap:
     a CSS Grid track will not shrink below its content's min-content width
     by default, so a rem-bound gap/padding that doubles under 200% text
     zoom - while the card's own width stays anchored to the viewport - was
     enough on its own to force this grid wider than the page. */
  display: grid; grid-template-columns: 1fr 1fr; gap: 18.4px;
  background: var(--paper); border: 1px solid var(--tan-soft);
  border-radius: var(--r-card); padding: clamp(22.4px, 3vw, 35.2px);
  box-shadow: 0 14px 40px rgb(94 68 38 / .1);
}
.field { display: flex; flex-direction: column; gap: .45rem; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: .92rem; font-weight: 600; }
.field__opt { color: var(--ink-soft); font-weight: 400; }

.field input:not([type=checkbox]), .field select, .field textarea {
  font: inherit;
  font-size: 1rem;              /* 16px floor: below this iOS Safari zooms on focus */
  padding: .82rem 1rem;
  color: var(--ink);
  background: var(--cream);
  border: 1px solid var(--tan-soft);
  border-radius: var(--r-input);
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
  width: 100%;
}
.field textarea { resize: vertical; min-height: 100px; }
.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%), linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
  background-position: 1rem calc(50% + 2px), calc(1rem + 5px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
  /* Keeps a long option from running underneath the caret. */
  padding-inline-end: 2.6rem;
}
/* background-position has no logical keywords, so the caret is the one thing
   here that needs a real per-direction override. Both halves of the chevron
   shift together - move only one and the arrow inverts. */
:root[dir="ltr"] .field select {
  background-position: calc(100% - 1rem - 10px) calc(50% + 2px), calc(100% - 1rem - 5px) calc(50% + 2px);
}
.field :is(input, select, textarea):hover { border-color: var(--tan); }
.field :is(input, select, textarea):focus { border-color: var(--gold-deep); background: var(--paper); }
.field ::placeholder { color: var(--ink-soft); }

.field.is-invalid :is(input, select, textarea) { border-color: var(--danger); }
.field__error { margin: 0; color: var(--danger); font-size: .86rem; }

.consent { flex-direction: row; align-items: flex-start; gap: .7rem; flex-wrap: wrap; }
.consent input { width: 24px; height: 24px; flex: none; margin-top: .1rem; accent-color: var(--gold-deep); }
.consent label { font-size: .89rem; color: var(--ink-soft); line-height: 1.5; font-weight: 400; flex: 1; min-width: 0; }
.consent label a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.consent .field__error { flex-basis: 100%; }

.form .btn { grid-column: 1 / -1; margin-top: .4rem; }
.btn__spinner { display: none; width: 16px; height: 16px; border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%; }
.form.is-sending .btn__spinner { display: block; animation: spin .7s linear infinite; }
.form.is-sending .btn { pointer-events: none; opacity: .75; }
@keyframes spin { to { transform: rotate(360deg); } }
/* Missed when every other animation in this file got a reduced-motion
   exemption: an infinite spin has no natural end, so without this it ran
   for reduced-motion users on every submit. #formStatus already says
   "sending" in text, so removing the spin loses nothing. */
@media (prefers-reduced-motion: reduce) { .btn__spinner { animation: none; } }
:root.a11y-motion-off .btn__spinner { animation: none; }

.form__status { grid-column: 1 / -1; margin: 0; font-size: .94rem; min-height: 1.4em; }
.form__status.is-ok  { color: var(--gold-deep); font-weight: 600; }
.form__status.is-err { color: var(--danger); }

@media (max-width: 900px) {
  .contact__grid, .form { grid-template-columns: 1fr; }
}

/* ─── Work pages: hero + YouTube gallery ─────────────────────
   The live versions of these pages list each video as a bare
   76px bar with an icon and nothing else, so ten videos look
   identical. Here every video shows its own vertical frame.

   Nothing is requested from YouTube until a card is clicked:
   the thumbnail is a local WebP and the iframe is injected on
   demand, which is also why the live pages' `autoplay=1` embeds
   are gone.
   ───────────────────────────────────────────────────────────── */
.page-hero { padding-block: clamp(3rem, 7vw, 5.5rem) clamp(2.5rem, 5vw, 4rem); }
.page-hero__grid {
  display: grid; grid-template-columns: 1.15fr .85fr;
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}
.page-hero__title { font-size: var(--step-h1); margin: 0 0 1.2rem; font-weight: 600; }
.page-hero__text { font-size: var(--step-lead); color: var(--ink-soft); max-width: 52ch; margin: 0; }
.page-hero__media { justify-self: end; width: 100%; max-width: 330px; }

/* ─── Legal pages (terms / privacy / accessibility) ─────────────
   Text-only, no media column, so .page-hero is reused without its
   grid - just the title and the back-link above a single prose column. */
.legal { padding-block: clamp(2.5rem, 6vw, 5rem) clamp(5rem, 10vw, 8rem); }
.legal__updated { color: var(--ink-soft); font-size: .9rem; margin: -.6rem 0 2.2rem; }
.legal__body { max-width: 68ch; }
.legal__body p { color: var(--ink-soft); margin: 0 0 1.2rem; }
.legal__body ul { color: var(--ink-soft); margin: 0 0 1.2rem; padding-inline-start: 1.4rem; }
.legal__body li { margin-bottom: .4rem; }
.legal__body p:last-child, .legal__body ul:last-child { margin-bottom: 0; }

.back {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--ink-soft); text-decoration: none; font-size: .95rem;
  margin-bottom: 1.6rem;
}
.back::before {
  content: ""; width: 15px; height: 15px; background: currentColor;
  -webkit-mask: var(--arrow) center / contain no-repeat;
          mask: var(--arrow) center / contain no-repeat;
  /* "Back" points the opposite way to "forward", hence the extra negation. */
  transform: scaleX(calc(var(--flip) * -1)); transition: transform .2s var(--ease);
}
.back:hover { color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .back:hover::before { transform: scaleX(calc(var(--flip) * -1)) translateX(-3px); } }

@media (max-width: 900px) {
  .page-hero__grid { grid-template-columns: 1fr; gap: 2rem; }
  .page-hero__media { justify-self: stretch; max-width: none; }
  .page-hero__media .reel { aspect-ratio: 4 / 5; }
}

/* 130px floor so even a 320px phone gets two reels across, not one giant one. */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: clamp(.75rem, 2.2vw, 1.6rem); }
@media (min-width: 900px) { .gallery { grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); } }

.ytcard {
  position: relative; padding: 0; margin: 0; display: block; cursor: pointer;
  aspect-ratio: 9 / 16; overflow: hidden;
  border-radius: var(--r-card);
  border: 1px solid var(--tan-soft);
  background: var(--tan-soft);
  box-shadow: 0 10px 28px rgb(94 68 38 / .12);
  transition: transform .28s var(--ease), box-shadow .28s var(--ease), border-color .28s var(--ease);
}
.ytcard > img { width: 100%; height: 100%; object-fit: cover; }
.ytcard iframe { width: 100%; height: 100%; border: 0; display: block; }

/* Scrim only where the play control and caption sit, so the frame stays legible. */
.ytcard__veil {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgb(var(--veil-rgb) / .72) 0%, rgb(var(--veil-rgb) / .12) 38%, rgb(var(--veil-rgb) / 0) 62%);
}
.ytcard__play {
  /* Physical left + physical translate, for the same reason as .skip-link. */
  position: absolute; inset-block-start: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 54px; height: 54px; border-radius: 999px;
  display: grid; place-items: center; pointer-events: none;
  background: var(--cream);   /* fallback - see .nav note on color-mix */
  background: color-mix(in srgb, var(--cream) 92%, transparent);
  border: 1px solid var(--tan);
  box-shadow: 0 4px 18px rgb(38 28 16 / .34);
  transition: transform .28s var(--ease), background-color .2s var(--ease);
}
/* margin-LEFT, not inline-start. The play triangle points physically right in
   every language, so its optical-centring nudge must too - inline-start
   resolved to margin-right in Hebrew and pushed it the wrong way. */
.ytcard__play svg { width: 19px; height: 19px; fill: var(--gold-deep); margin-left: 2px; }
.ytcard__title {
  position: absolute; inset-inline: .85rem; inset-block-end: .85rem;
  color: var(--on-media); font-size: .95rem; font-weight: 600; line-height: 1.35;
  pointer-events: none; text-shadow: 0 1px 6px rgb(30 22 12 / .55);
}

@media (hover: hover) and (pointer: fine) {
  .ytcard:hover { transform: translateY(-4px); border-color: var(--tan); box-shadow: 0 20px 44px rgb(94 68 38 / .22); }
  .ytcard:hover .ytcard__play { transform: translate(-50%, -50%) scale(1.09); background: var(--cream); }
}
.ytcard:active { transform: translateY(-1px) scale(.99); }
@media (prefers-reduced-motion: reduce) {
  .ytcard, .ytcard__play { transition: none; }
  .ytcard:hover, .ytcard:active { transform: none; }
  .ytcard:hover .ytcard__play { transform: translate(-50%, -50%); }
}
:root.a11y-motion-off .ytcard,
:root.a11y-motion-off .ytcard__play { transition: none; }
:root.a11y-motion-off .ytcard:hover,
:root.a11y-motion-off .ytcard:active { transform: none; }
:root.a11y-motion-off .ytcard:hover .ytcard__play { transform: translate(-50%, -50%); }

/* Once playing, the card is an iframe: drop the decorations. */
.ytcard.is-playing { cursor: default; aspect-ratio: 9 / 16; }
.ytcard.is-playing .ytcard__veil,
.ytcard.is-playing .ytcard__play,
.ytcard.is-playing .ytcard__title { display: none; }

/* ─── Closing CTA band ───────────────────────────────────────── */
.cta-band { background: var(--cream-deep); padding-block: clamp(3.5rem, 7vw, 5.5rem); }
.cta-band__inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1.5rem 2.5rem; }
.cta-band h2 { font-size: clamp(1.7rem, 1.2rem + 1.8vw, 2.5rem); margin: 0; max-width: 22ch; }
.cta-band p { margin: .6rem 0 0; color: var(--ink-soft); max-width: 46ch; }

/* ─── Footer ─────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--tan-soft);
  padding-block: 3.2rem;
  /* clear the iOS home indicator */
  padding-bottom: max(3.2rem, calc(1.5rem + env(safe-area-inset-bottom, 0px)));
}
.foot__inner { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem 2rem; }
.foot__brand { display: flex; align-items: center; gap: .7rem; font-weight: 600; margin-inline-end: auto; }
.foot__brand img { width: 38px; height: 38px; }
.foot__links { display: flex; flex-wrap: wrap; gap: 1.35rem; }
.foot__links a { color: var(--ink-soft); text-decoration: none; font-size: .92rem; padding-block: .35rem; }
.foot__links a:hover { color: var(--ink); }
.foot__legal { margin: 0; color: var(--ink-soft); font-size: .87rem; flex-basis: 100%; }

/* ─── Landscape phones ───────────────────────────────────────
   A 740x360 phone is under the 900px stack breakpoint, so the hero
   stacked and grew to ~1300px inside a 360px viewport. There is
   plenty of width here and almost no height, so go back side by
   side and size the reel off the viewport height instead.
   ───────────────────────────────────────────────────────────── */
@media (orientation: landscape) and (max-height: 520px) {
  .hero, .page-hero { min-height: 0; padding-block: 1.15rem; }
  .hero__grid, .page-hero__grid { grid-template-columns: 1fr auto; gap: 2rem; align-items: center; }
  .hero__media, .page-hero__media { justify-self: end; width: auto; max-width: none; }
  .hero__media .reel, .page-hero__media .reel {
    aspect-ratio: 9 / 16; height: 68dvh; width: auto;
  }
  .hero__title { font-size: clamp(1.9rem, 1.4rem + 2vw, 2.6rem); margin-bottom: .8rem; }
  .hero__sub, .page-hero__text { margin-bottom: 1.2rem; font-size: 1rem; }
  .section { padding-block: clamp(3rem, 8vh, 5rem); }
}

/* ─── Touch tuning ───────────────────────────────────────────
   Standalone links sized for a fingertip on touch devices only,
   so pointer layouts keep their tighter rhythm. WCAG 2.5.8 asks
   for 24px; 44px is what iOS and Android actually expect.
   ───────────────────────────────────────────────────────────── */
@media (pointer: coarse) {
  .link, .back, .foot__links a, .nav__links a { min-height: 44px; align-items: center; }
  .foot__links { gap: .5rem 1.35rem; }
  .nav__drawer a { padding-block: 1rem; }
  .compare__zoom { width: 44px; height: 44px; }
  .consent input { width: 28px; height: 28px; }
  .compare__label { font-size: .82rem; padding: .3rem .9rem; }
  /* Grow the hit area of links inside a sentence without changing the line box. */
  .consent label a, .foot__legal a { padding-block: .5rem; margin-block: -.5rem; }
  .nav__brand { min-height: 44px; }
  .i18n-ready .lang { min-height: 44px; min-width: 48px; }
}

/* Long single words (URLs, handles) must not force a sideways scroll. */
.case__meta, .channels em, .quote blockquote, .about__copy p,
.page-hero__text, .section__lead, .ytcard__title { overflow-wrap: anywhere; }

/* Headings too - missed by the rule above, and the highest-risk spot for it:
   --step-h1 alone is already 41.6px, and normal white-space wrapping can
   only break AT a space. A single long English word ("Accessibility") in a
   narrow column has no space to break at, so at 200% text zoom it rendered
   on one line and overflowed the page - not a container-width bug, just
   nowhere valid to wrap. Same fix as above, same already-proven technique. */
h1, h2, h3 { overflow-wrap: anywhere; }

/* ─── Lightbox ───────────────────────────────────────────────── */
.lightbox {
  border: 0; padding: 0; max-width: min(94vw, 640px); max-height: 92dvh;
  background: transparent; color: var(--cream); overflow: visible;
}
.lightbox::backdrop { background: rgb(var(--backdrop-rgb) / .82); backdrop-filter: blur(6px); }
.lightbox img { width: 100%; height: auto; max-height: 82dvh; object-fit: contain; border-radius: var(--r-card); }
.lightbox__cap { margin: .95rem 0 0; text-align: center; font-size: .9rem; color: var(--cream); }
.lightbox__close {
  position: absolute; inset-block-start: -48px; inset-inline-end: 0;
  width: 40px; height: 40px; display: grid; place-items: center;
  background: var(--cream); border: 1px solid var(--tan); border-radius: 50%; cursor: pointer;
}
.lightbox__close svg { width: 18px; height: 18px; fill: var(--ink); }
.lightbox[open] { animation: lb .25s var(--ease); }
@keyframes lb { from { opacity: 0; transform: scale(.97); } }
@media (prefers-reduced-motion: reduce) { .lightbox[open] { animation: none; } }
:root.a11y-motion-off .lightbox[open] { animation: none; }

/* ═══════════════════════════════════════════════════════════════
   Accessibility toolbar
   A self-built control panel in the spirit of the Israeli
   accessibility widgets bundled with most sites here (the
   WordPress predecessor to this rebuild carried one) - but
   reaching WCAG 1.4.12 Text Spacing, which those generally don't,
   and built from this site's own tokens rather than a filter
   stack, for reasons explained below. Markup and behaviour live in
   app.js; everything about how it looks, including every place it
   recolours the page, lives here. /accessibility documents what it
   does for visitors, including the full shortcut list.
   ═══════════════════════════════════════════════════════════════ */

/* ─── Colour themes ───────────────────────────────────────────────
   One of these five is active at a time (radio semantics - enforced
   by the toolbar module, not by this CSS). Each is a full override
   of the palette custom properties defined at the top of this file,
   deliberately NOT a filter() on html/body. A root filter would:
   (a) leave the lightbox untouched, since <dialog> content painted
   in the top layer sits outside the root element's subtree; (b)
   turn html/body into a containing block for this toolbar's own
   position:fixed elements, displacing them; (c) double-transform
   .nav's own backdrop-filter. Overriding the custom properties
   instead reaches everything that already reads them, with none of
   that, because the palette was already tokenized before this.
   ───────────────────────────────────────────────────────────────── */

/* High contrast - near-maximum contrast, for low vision generally. */
:root.a11y-contrast {
  color-scheme: dark;
  --cream: #000; --cream-deep: #000; --paper: #000;
  --ink: #FFF; --ink-soft: #EDEDED;
  --gold: #FFD400; --gold-deep: #FFD400; --gold-hover: #E6BF00;
  --tan: #FFF; --tan-soft: #8C8C8C;
  --danger: #FF8A75;
  --on-media: #FFF;
}
/* The nav's translucent, blurred band reads as a grey smear at this
   contrast level rather than a clean panel - flatten it to a solid fill. */
:root.a11y-contrast .nav {
  background: var(--cream);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* Invert - a dark theme built from the brand palette, not a CSS invert()
   filter (which would also invert every photo and video on the page). */
:root.a11y-invert {
  color-scheme: dark;
  --cream: #1B1B1B; --cream-deep: #141414; --paper: #0F0F0F;
  --ink: #F5F0E4; --ink-soft: #C9BFA9;
  --gold: #E3B876; --gold-deep: #F2C98B; --gold-hover: #FFD9A0;
  --tan: #6B5D4A; --tan-soft: #4A4030;
  --danger: #FF8A75;
}

/* Black on yellow - high glare tolerance, a common low-vision preference. */
:root.a11y-yellow {
  --cream: #FFE800; --cream-deep: #FFE800; --paper: #FFF480;
  --ink: #000; --ink-soft: #1A1A1A;
  --gold: #000; --gold-deep: #000; --gold-hover: #333;
  --tan: #000; --tan-soft: #4D4D4D;
  --danger: #7A0000;
  --on-media: #FFE800;
}

/* Monochrome - the palette goes to grey, and so, narrowly, does the media:
   img/video/iframe only, never html/body, for the same top-layer /
   containing-block reasons documented above. */
:root.a11y-mono {
  --cream: #EDEDED; --cream-deep: #E0E0E0; --paper: #FFF;
  --ink: #1A1A1A; --ink-soft: #4D4D4D;
  --gold: #595959; --gold-deep: #333; --gold-hover: #262626;
  --tan: #999; --tan-soft: #CCC;
  --danger: #333;
  --on-media: #F2F2F2;
  --veil-rgb: 38 38 38; --handle-ring-rgb: 60 60 60; --backdrop-rgb: 20 20 20;
}
:root.a11y-mono img, :root.a11y-mono video, :root.a11y-mono iframe { filter: grayscale(1); }

/* Sepia - warm, reduced-glare tone some low-vision and dyslexic readers
   prefer over full black-on-white. */
:root.a11y-sepia {
  --cream: #F4ECD8; --cream-deep: #EAD9B5; --paper: #FBF3E3;
  --ink: #4B3621; --ink-soft: #6F4E2E;
  --gold: #8B5A2B; --gold-deep: #6B4423; --gold-hover: #7A4A1E;
  --tan: #B08D57; --tan-soft: #D8C39A;
  --danger: #8B3A1D;
  --on-media: #FBF3E3;
}
:root.a11y-sepia img, :root.a11y-sepia video, :root.a11y-sepia iframe { filter: sepia(.55); }

/* ─── Text size & spacing ──────────────────────────────────────────
   A percentage on the root multiplies the visitor's OWN browser
   default font size rather than clobbering it - never
   calc(16px * ...). This is deliberately the same mechanism as the
   browser's own text-only zoom, which the whole site was already
   verified clean against at 200% (font-scale 2.0): zero px
   font-size declarations and zero em-based breakpoints anywhere in
   this file mean nothing here behaves differently under one vs the
   other. Five steps: 1 / 1.25 / 1.5 / 1.75 / 2.
   ───────────────────────────────────────────────────────────────── */
html { font-size: calc(100% * var(--a11y-font-scale, 1)); }

/* WCAG 1.4.12 Text Spacing - independent of font-scale above, and of
   the individual line-height/letter-spacing values already set on
   specific components throughout this file. Applied at body level so
   anything WITHOUT its own explicit value inherits it; components
   that set their own (buttons, nav, cards) are deliberately left
   alone, since the criterion targets body copy, not UI chrome. Three
   steps (0/1/2): the top step meets or exceeds the criterion's actual
   minimums (1.5x line height, 0.12em letter-spacing, 0.16em
   word-spacing). */
body {
  line-height: calc(1.68 + .5 * var(--a11y-space-step, 0));
  letter-spacing: calc(.06em * var(--a11y-space-step, 0));
  word-spacing: calc(.08em * var(--a11y-space-step, 0));
}
p, li { margin-block: calc(.5em * var(--a11y-space-step, 0)); }

/* ─── Reading aids ─────────────────────────────────────────────────── */

:root.a11y-headings h1, :root.a11y-headings h2, :root.a11y-headings h3 {
  outline: 3px solid #1E5AAB; outline-offset: 4px; border-radius: 4px;
  background: rgb(30 90 171 / .08);
}
:root.a11y-links a {
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 2px;
}

/* Arial, not a dyslexia-specific face like OpenDyslexic: those ship with no
   Hebrew glyphs at all, so on a Hebrew-first site the browser would just
   fall back to the default font anyway - a control that visibly does
   nothing while claiming to help. Arial is also the face Israeli
   accessibility guidance conventionally names, and has full Hebrew
   coverage. Overrides both the body font and the display font (Fredoka on
   headings), since a heading in a display face is exactly the kind of
   thing this control exists to flatten.

   !important, the only one in this file: several components set
   font-family with two classes (e.g. .nav__brand-text small), which would
   out-specificity a plain :root.a11y-font-readable * rule regardless of
   source order. A user-facing "make everything readable" toggle failing
   silently on exactly the elements most likely to need it is worse than
   the one specificity escape hatch this file otherwise avoids. */
:root.a11y-font-readable, :root.a11y-font-readable * {
  font-family: Arial, Helvetica, sans-serif !important;
}

/* Reading guide: a bar that tracks the pointer, driven by JS via
   transform (never top - that would force layout on every mouse move).
   Off on touch, where there's no hovering pointer to follow. */
.a11y-guide-bar {
  position: fixed; left: 0; right: 0; top: 0; height: 3px;
  background: #1E5AAB; z-index: 155; pointer-events: none;
  transform: translateY(-100%);
}
@media (pointer: coarse) { .a11y-guide-bar { display: none; } }

/* Custom cursors. Capped by browsers around 128px and ignored entirely
   on touch, hence no coarse-pointer guard needed here - touch devices
   already fall back to `auto` on their own. */
:root.a11y-cursor-big, :root.a11y-cursor-big * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24'%3E%3Cpath d='M4 2l14 10-6 2 4 7-3 2-4-7-5 4z' fill='black' stroke='white' stroke-width='1'/%3E%3C/svg%3E") 4 4, auto;
}
:root.a11y-cursor-dark, :root.a11y-cursor-dark * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 24 24'%3E%3Cpath d='M4 2l14 10-6 2 4 7-3 2-4-7-5 4z' fill='%23000' stroke='%23FFD400' stroke-width='2'/%3E%3C/svg%3E") 4 4, auto;
}

/* Keyboard-nav mode: promotes the site-wide :focus-visible ring
   (styles.css, near the top) to plain :focus, larger, and reserves
   scroll room above focused elements so the sticky nav never covers
   whatever the toolbar's own Tab handling just moved focus to. */
:root.a11y-kbd :where(a, button, input, select, textarea, [tabindex]):focus {
  outline: 3px solid #1E5AAB; outline-offset: 3px; border-radius: 4px;
}
:root.a11y-kbd :where(a, button, input, select, textarea, [tabindex]) {
  scroll-margin-block: calc(var(--nav-h) + 12px);
}

/* ─── Toolbar UI ───────────────────────────────────────────────────
   Colours here are literal, not the --ink/--cream tokens above, on
   purpose: those are exactly what the five themes reassign, and a
   panel that inverts along with the page it controls would become
   unreadable the moment someone actually used it. Standard
   accessibility blue (#1E5AAB), not the site's gold - it's blue on
   nearly every Israeli site that has one of these, and blending it
   into the brand palette would make it harder to find, which is the
   opposite of the point.
   ───────────────────────────────────────────────────────────────── */
.a11y-trigger {
  position: fixed;
  inset-inline-start: max(1rem, env(safe-area-inset-left, 0px));
  inset-block-end: max(1rem, env(safe-area-inset-bottom, 0px));
  z-index: 150;
  width: 48px; height: 48px; padding: 0;
  display: grid; place-items: center;
  background: #1E5AAB; color: #FFF; border: 2px solid #FFF;
  border-radius: 50%; cursor: pointer;
  box-shadow: 0 4px 16px rgb(0 0 0 / .3);
}
.a11y-trigger svg { width: 28px; height: 28px; fill: #FFF; }
.a11y-trigger:focus-visible { outline: 3px solid #1E5AAB; outline-offset: 3px; }

.a11y-panel {
  position: fixed;
  inset-inline-start: max(1rem, env(safe-area-inset-left, 0px));
  inset-block-end: calc(max(1rem, env(safe-area-inset-bottom, 0px)) + 58px);
  z-index: 160;
  width: min(92vw, 360px);
  max-height: min(80dvh, 640px);
  overflow-y: auto; overflow-x: hidden;
  background: #FFF; color: #1A1A1A;
  border: 1px solid #CCC; border-radius: 14px;
  box-shadow: 0 20px 50px rgb(0 0 0 / .35);
  padding: 1rem;
}
.a11y-panel[hidden] { display: none; }

.a11y-panel__head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .75rem; }
.a11y-panel__title { margin: 0; font-size: 1.05rem; font-weight: 700; }
.a11y-panel__close {
  width: 36px; height: 36px; display: grid; place-items: center;
  background: transparent; border: 1px solid #CCC; border-radius: 50%; cursor: pointer;
}
.a11y-panel__close svg { width: 16px; height: 16px; fill: #1A1A1A; }

.a11y-group { margin-bottom: 1rem; }
.a11y-group__title {
  margin: 0 0 .4rem; font-size: .78rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: #555;
}
.a11y-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }

.a11y-btn {
  display: flex; flex-direction: column; align-items: center; gap: .25rem;
  min-height: 44px; padding: .5rem .4rem;
  font: inherit; font-size: .82rem; text-align: center; line-height: 1.2;
  background: #F4F4F4; color: #1A1A1A;
  border: 1px solid #DDD; border-radius: 10px; cursor: pointer;
}
.a11y-btn[aria-pressed="true"] { background: #1E5AAB; color: #FFF; border-color: #1E5AAB; }
.a11y-btn__key { font-size: .68rem; opacity: .65; }

.a11y-steps { display: flex; align-items: center; gap: .5rem; }
.a11y-steps button {
  width: 44px; height: 44px; display: grid; place-items: center;
  font-size: 1.1rem; font-weight: 700;
  background: #F4F4F4; color: #1A1A1A; border: 1px solid #DDD; border-radius: 8px; cursor: pointer;
}
.a11y-steps__value { flex: 1; text-align: center; font-size: .85rem; }

.a11y-hint { font-size: .76rem; color: #666; margin: .3rem 0 0; }

.a11y-panel__foot {
  display: flex; flex-direction: column; gap: .5rem;
  margin-top: .75rem; padding-top: .75rem; border-top: 1px solid #EEE;
}
.a11y-panel__foot a, .a11y-panel__foot button {
  display: block; width: 100%; padding: .6rem; text-align: center;
  font: inherit; font-size: .88rem; font-weight: 600; text-decoration: none;
  background: #F4F4F4; color: #1A1A1A; border: 1px solid #DDD; border-radius: 10px; cursor: pointer;
}
