<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, user-scalable=yes" />
    <title>Yafutzu — Torah Study & the Jewish Social Network for Every Jew</title>
    <link rel="canonical" href="https://www.yafutzu.org/" />

    <!-- Primary Meta -->
    <meta name="description" content="Yafutzu — Torah study and the Jewish social network. Find a minyan, map a kosher trip, meet a chavruta, learn daily, connect everywhere." />
    <meta name="author" content="Yafutzu" />

    <!-- Open Graph -->
    <meta property="og:type" content="website" />
    <meta property="og:url" content="https://www.yafutzu.org/" />
    <meta property="og:title" content="Yafutzu — Torah Study and the Jewish World, in One App" />
    <meta property="og:description" content="Yafutzu connects every Jew through Torah study and the Jewish social network. Learn daily, find a minyan, navigate the kosher world, meet a chavruta, plan Jewish travel — one app, every Jew, everywhere." />
    <meta property="og:image" content="https://yafutzu.s3.us-east-2.amazonaws.com/Logos/yafutzu_logo.jpg" />
    <meta property="og:image:width" content="1200" />
    <meta property="og:image:height" content="630" />
    <meta property="og:site_name" content="Yafutzu" />

    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="Yafutzu — Torah, Community & the Jewish World, in One App" />
    <meta name="twitter:description" content="Torah study, minyanim, kosher map, chavruta, travel — Yafutzu connects every Jew, everywhere." />
    <meta name="twitter:image" content="https://yafutzu.s3.us-east-2.amazonaws.com/Logos/yafutzu_logo.jpg" />

    <!-- Theme & PWA -->
    <meta name="theme-color" content="#0A1B28" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="default" />
    <meta name="apple-mobile-web-app-title" content="יפוצו" />
    <link rel="manifest" href="/manifest.json" />
    <link rel="icon" type="image/svg+xml" href="/icons/yafutzu-logo.svg" />
    <link rel="apple-touch-icon" href="/icons/yafutzu-logo.svg" />
    <!-- iOS splash screens — device-sized startup images so the PWA opens with a branded splash, not a white flash -->
    <!-- iPhone 14 Pro Max, 15 Pro Max, 16 Pro Max -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone 14 Pro, 15 Pro, 16 Pro -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone 14 Plus, 13 Pro Max, 12 Pro Max -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone 14, 13, 13 Pro, 12, 12 Pro -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone 13 mini, 12 mini, 11 Pro, XS, X -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone 11 Pro Max, XS Max -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone 11, XR -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" />
    <!-- iPhone 8 Plus, 7 Plus, 6s Plus, 6 Plus -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3)" />
    <!-- iPhone SE (2nd/3rd gen), 8, 7, 6s, 6 -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" />
    <!-- iPad Pro 12.9 -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)" />
    <!-- iPad Pro 11 -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)" />
    <!-- iPad Air, iPad 10.2 -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2)" />
    <!-- Fallback -->
    <link rel="apple-touch-startup-image" href="/icons/yafutzu-logo.svg" />
    <meta name="mobile-web-app-capable" content="yes" />
    <meta name="apple-touch-fullscreen" content="yes" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <!-- Yafutzu type system: Inter Tight (locked, brand), Inter (legacy UI), Frank Ruhl Libre (primary Hebrew), David Libre (alt Hebrew), Heebo (UI Hebrew + display Hebrew at 700-900), Figtree (legacy), Crimson Text (Siddur English serif) -->
    <link href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700;800;900&family=Frank+Ruhl+Libre:wght@300..900&family=David+Libre:wght@400;500;700&family=Heebo:wght@300..900&family=Figtree:wght@400..900&family=Crimson+Text:ital,wght@0,400;0,600;1,400;1,600&family=Crimson+Pro:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=Source+Serif+4:opsz,wght@8..60,400;8..60,500;8..60,600;8..60,700&family=Lora:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400&family=Open+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400&family=Nunito:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=Newsreader:opsz,wght@6..72,400;6..72,500;6..72,600;6..72,700&family=Vollkorn:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Atkinson+Hyperlegible:ital,wght@0,400;0,700;1,400;1,700&family=Rubik:wght@400;500;700&family=Suez+One&family=Noto+Serif+Hebrew:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
    <script type="module" crossorigin src="/assets/index-CIcU19vQ.js"></script>
    <link rel="modulepreload" crossorigin href="/assets/vendor-react-FYUJSupD.js">
    <link rel="modulepreload" crossorigin href="/assets/vendor-media-BTBJCCrq.js">
    <link rel="modulepreload" crossorigin href="/assets/vendor-query-CbIDG3-5.js">
    <link rel="modulepreload" crossorigin href="/assets/vendor-i18n-B7bLpG52.js">
    <link rel="modulepreload" crossorigin href="/assets/vendor-ui-DQschqsr.js">
    <link rel="modulepreload" crossorigin href="/assets/vendor-socket-R9y3iZBt.js">
    <link rel="stylesheet" crossorigin href="/assets/index-BG_LgKTl.css">
  </head>
  <body>
    <div id="root">
      <!-- Pre-JS app shell. Paints at ~TTFB with zero JS/asset dependency so
           users see branding instantly instead of a blank screen during the
           ~3s bundle parse/execute. React's createRoot() clears #root on its
           first render, so this is auto-removed the moment the app mounts.
           No hydration (createRoot, not hydrateRoot) → no mismatch risk. -->
      <div id="yf-splash" style="position:fixed;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#0A1B28;color:#fff;font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;z-index:2147483647">
        <div style="font-size:46px;font-weight:800;letter-spacing:.06em;direction:rtl;line-height:1">יפוצו</div>
        <div style="margin-top:8px;font-size:12px;letter-spacing:.28em;text-transform:uppercase;opacity:.55">Yafutzu</div>
        <div style="margin-top:20px;width:30px;height:30px;border:3px solid rgba(255,255,255,.22);border-top-color:#fff;border-radius:50%;animation:yfspin .8s linear infinite"></div>
      </div>
      <style>@keyframes yfspin{to{transform:rotate(360deg)}}</style>
    </div>
    <script>
      // Register service worker + auto-update on new deploys.
      // When a new SW is found, tell it to skipWaiting() so users get the
      // fresh app shell without needing to close the PWA — critical for
      // mobile PWA installs where users don't see browser refresh cues.
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
          // updateViaCache:'none' tells the browser to bypass its own HTTP
          // cache when fetching sw.js — otherwise browsers cache the SW for
          // up to 24h by default, which means deploys don't reach PWA users
          // until the next day. Critical for iOS Safari + Android Chrome.
          navigator.serviceWorker.register('/sw.js', { updateViaCache: 'none' }).then((reg) => {
            if (!reg) return;

            // Check for updates whenever the tab/PWA becomes visible. This
            // is the real fix — PWAs on mobile get backgrounded constantly,
            // and `reg.update()` on visibility change picks up new deploys
            // within seconds of the user reopening the app.
            document.addEventListener('visibilitychange', () => {
              if (document.visibilityState === 'visible') {
                reg.update().catch(() => {});
              }
            });

            // Fallback poll every 5 minutes while the tab is open (was 30).
            setInterval(() => { reg.update().catch(() => {}); }, 5 * 60 * 1000);

            // When a new SW installs, activate it immediately so the next
            // navigation serves fresh HTML + assets.
            reg.addEventListener('updatefound', () => {
              const nextSW = reg.installing;
              if (!nextSW) return;
              nextSW.addEventListener('statechange', () => {
                if (nextSW.state === 'installed' && navigator.serviceWorker.controller) {
                  // New version ready — activate + reload on next navigation.
                  nextSW.postMessage({ type: 'SKIP_WAITING' });
                }
              });
            });

            // Reload once when the controller changes (new SW took control).
            let reloaded = false;
            navigator.serviceWorker.addEventListener('controllerchange', () => {
              if (reloaded) return;
              reloaded = true;
              window.location.reload();
            });
          }).catch(() => {});
        });
      }
    </script>
  </body>
</html>
