/* ==================== BASE ====================
 * Reset, fonts, RTL foundations, motion policy.
 * ============================================== */

/* Tel Aviv Eclectic — the site's face, split across two files.
 *
 * THE `unicode-range` LINES BELOW ARE LOAD-BEARING. Each file claims the other
 * script's codepoints in its cmap and maps them to BLANK glyphs, so a browser
 * believes it has coverage and never falls back. Measured:
 *   - the Latin file draws 'אוהד שפינדל' with 0 ink but 105px of advance
 *   - the Hebrew file draws 'Ohad ABC'   with 0 ink
 * Drop either range and half the site's text silently turns invisible while
 * still taking up space — it reads as a broken layout, not a missing font.
 * The two ranges are kept disjoint so there is no ambiguity about which file
 * serves a given character. Re-test both scripts after touching this.
 *
 * Both are declared `font-weight: 400` — a single static weight each, with no
 * variable axis. Declaring `100 900` would tell the browser every weight
 * already exists and it would stop synthesising bold, flattening every
 * heading (measured: 0% extra ink at 800, vs +23% when declared honestly). */

/* Hebrew — all body copy, headings and navigation. */
@font-face {
  font-family: 'Tel Aviv Eclectic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/telaviv-eclectichebrewno.2.woff2') format('woff2');
  unicode-range: U+0590-05FF, U+20AA, U+FB1D-FB4F;
}

/* Latin, digits and punctuation — emails, URLs, numbers. */
@font-face {
  font-family: 'Tel Aviv Eclectic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/telaviv-eclecticlatinno.2.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+2215;
}

/* Heebo is now only a last-resort fallback for anything neither file covers.
   Not preloaded; browsers fetch a fallback face solely if a glyph needs it. */
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/heebo-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/heebo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

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

* { margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: 'Tel Aviv Eclectic', 'Heebo', 'Segoe UI', system-ui, -apple-system, sans-serif;
  font-size: var(--fs-body);
  line-height: 1.85;
  letter-spacing: 0.012em;
  color: var(--text-primary);
  background: var(--bg-primary);
  direction: rtl;
  min-height: 100dvh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Keep content clear of the mobile tab bar and the iPhone home indicator. */
  padding-block-end: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom));
}

@media (min-width: 861px) {
  body { padding-block-end: 0; }
}

/* Tracking is opened up slightly rather than tightened. Tel Aviv Eclectic is a
   geometric face with tight default sidebearings; the negative letter-spacing a
   normal sans wants would close the Hebrew counters up. */
h1, h2, h3, h4 {
  line-height: 1.3;
  font-weight: 800;
  letter-spacing: 0.005em;
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }

p { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }

button, input, textarea, select {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}

button { cursor: pointer; }

img, svg, picture { max-width: 100%; display: block; }

ul, ol { list-style: none; }

::selection {
  background: var(--accent-secondary);
  color: var(--on-accent);
}

:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Latin runs (emails, URLs, numbers) inside RTL Hebrew need their own direction
   or the punctuation lands on the wrong side. */
.ltr {
  direction: ltr;
  unicode-bidi: isolate;
  display: inline-block;
}

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: clamp(18px, 5vw, 40px);
}

.skip-link {
  position: absolute;
  inset-block-start: -100px;
  inset-inline-start: 12px;
  z-index: 999;
  padding: 12px 20px;
  border-radius: var(--radius-sm);
  background: var(--accent-primary);
  color: var(--on-accent);
  font-weight: 700;
  transition: inset-block-start var(--dur-fast);
}
.skip-link:focus { inset-block-start: 12px; }

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

/* ==================== BACKGROUND FIELD ====================
 * Orbs are radial-gradients, not blurred elements. A real filter: blur()
 * on something this large repaints on every frame; a gradient is free.
 * ========================================================== */

/* -2 so the arcade cast (.arcade-bg, z-index -1) paints above the orbs while
   both stay behind every piece of page text. */
.bg-field {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
}

.orb {
  position: absolute;
  border-radius: 50%;
  opacity: 0.5;
  will-change: transform;
  /* Set by motion.js for the parallax effect. */
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
}

.orb-1 {
  width: 62vmax; height: 62vmax;
  inset-block-start: -22vmax; inset-inline-end: -18vmax;
  background: radial-gradient(circle closest-side, rgba(255, 138, 91, 0.34), transparent 72%);
  animation: drift-a 22s var(--ease-in-out) infinite alternate;
}
.orb-2 {
  width: 54vmax; height: 54vmax;
  inset-block-end: -20vmax; inset-inline-start: -16vmax;
  /* Metal, not purple — this orb carries the palette's slate tone. */
  background: radial-gradient(circle closest-side, rgba(110, 102, 137, 0.5), transparent 72%);
  animation: drift-b 27s var(--ease-in-out) infinite alternate;
}
.orb-3 {
  width: 42vmax; height: 42vmax;
  inset-block-start: 32%; inset-inline-start: 28%;
  background: radial-gradient(circle closest-side, rgba(255, 95, 150, 0.24), transparent 72%);
  animation: drift-c 19s var(--ease-in-out) infinite alternate;
}

/* The orbs animate their own drift via a second transform layer so the
   JS parallax (on .orb) and the CSS drift never fight over one property. */
@keyframes drift-a { to { translate: -6vmax 5vmax; } }
@keyframes drift-b { to { translate: 7vmax -4vmax; } }
@keyframes drift-c { to { translate: -5vmax -6vmax; scale: 1.14; } }

.bg-grain {
  position: absolute;
  inset: 0;
  opacity: 0.4;
  background-image: radial-gradient(var(--sheen) 1px, transparent 1px);
  background-size: 3px 3px;
  mix-blend-mode: overlay;
}

/* ==================== SCROLL REVEAL ====================
 * The house pattern: .reveal + IntersectionObserver -> .visible
 * --i on a child staggers it within its group.
 * ======================================================= */

.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity var(--dur-slow) var(--ease-out-expo),
    transform var(--dur-slow) var(--ease-out-expo);
  transition-delay: calc(var(--i, 0) * 70ms);
}

.reveal.visible {
  opacity: 1;
  transform: none;
}

/* ==================== MOTION POLICY ====================
 * Nothing above is load-bearing for comprehension, so when the OS asks for
 * less motion we cut all of it — not just soften it. motion.js checks the
 * same query and never attaches its listeners.
 * ======================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  .reveal { opacity: 1; transform: none; }
  .orb { animation: none; transform: none; }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
