// MA-Trip — five mockup screens. Hebrew RTL.
// Influences applied:
//   - Warm marketplace home/itinerary (coral accents, soft cards)
//   - Apple-quiet pill CTAs in action blue
//   - Runway-cinematic dark gallery + memory detail

const { useState } = React;

/* ─────────────────────────── shared atoms ─────────────────────────── */

function Pill({ children, kind = "primary", style = {}, className = "", ...rest }) {
  const glassClass = {
    primary:   "lg-action",
    coral:     "lg-coral",
    secondary: "lg-light",
    ghost:     "lg-dark",
  }[kind] || "lg-action";
  const fg = kind === "secondary" ? "var(--action)" : kind === "ghost" ? "#fff" : "#fff";
  return (
    <button
      className={`${glassClass} ${className}`.trim()}
      style={{
        height: 44, padding: "0 22px", borderRadius: 9999,
        color: fg,
        fontSize: 15, fontWeight: 500, letterSpacing: "-0.01em",
        display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
        cursor: "pointer", fontFamily: "inherit",
        ...style,
      }}
      {...rest}
    >{children}</button>
  );
}

function CircleIcon({ children, size = 40, dark = false, style = {}, className = "", onClick, onKeyDown, ...rest }) {
  const hasVariant = /\blg-(coral|action|dark|light)\b/.test(className);
  const baseClass = hasVariant ? "" : (dark ? "lg-circle-dark" : "lg-circle");
  const isColored = /\blg-(coral|action)\b/.test(className);
  const handleKey = (e) => {
    if ((e.key === "Enter" || e.key === " " || e.key === "Spacebar") && onClick) {
      e.preventDefault();
      onClick(e);
    }
    if (onKeyDown) onKeyDown(e);
  };
  return (
    <div
      className={`${baseClass} ${className}`.trim()}
      role={onClick || rest["data-nav"] ? "button" : undefined}
      tabIndex={onClick || rest["data-nav"] ? 0 : undefined}
      onClick={onClick}
      onKeyDown={onClick || rest["data-nav"] ? handleKey : onKeyDown}
      style={{
        width: size, height: size, borderRadius: 9999,
        color: isColored ? "#fff" : dark ? "#fff" : "var(--ink)",
        display: "flex", alignItems: "center", justifyContent: "center",
        flexShrink: 0,
        ...style,
      }}
      {...rest}
    >{children}</div>
  );
}

// Simple stroke glyphs — small and consistent
const I = {
  back:    (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M9 6l6 6-6 6" stroke={c} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  close:   (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke={c} strokeWidth="1.8" strokeLinecap="round"/></svg>,
  trash:   (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13M10 11v6M14 11v6" stroke={c} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  edit:    (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M4 20h4l10-10-4-4L4 16v4z" stroke={c} strokeWidth="1.6" strokeLinejoin="round"/><path d="M13 6l4 4" stroke={c} strokeWidth="1.6" strokeLinecap="round"/></svg>,
  comment: (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M4 5h16v11H8l-4 4V5z" stroke={c} strokeWidth="1.6" strokeLinejoin="round"/></svg>,
  heart:   (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M12 20s-7-4.35-7-10a4 4 0 0 1 7-2.65A4 4 0 0 1 19 10c0 5.65-7 10-7 10z" stroke={c} strokeWidth="1.6" strokeLinejoin="round"/></svg>,
  heartF:  (s = 18, c = "var(--coral)") => <svg width={s} height={s} viewBox="0 0 24 24"><path d="M12 20s-7-4.35-7-10a4 4 0 0 1 7-2.65A4 4 0 0 1 19 10c0 5.65-7 10-7 10z" fill={c}/></svg>,
  plus:    (s = 20, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M12 5v14M5 12h14" stroke={c} strokeWidth="1.8" strokeLinecap="round"/></svg>,
  map:     (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2zM9 4v14M15 6v14" stroke={c} strokeWidth="1.5" strokeLinejoin="round"/></svg>,
  cal:     (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><rect x="3.5" y="5" width="17" height="15" rx="2" stroke={c} strokeWidth="1.5"/><path d="M8 3v4M16 3v4M3.5 10h17" stroke={c} strokeWidth="1.5" strokeLinecap="round"/></svg>,
  pin:     (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M12 22s7-7.5 7-13a7 7 0 1 0-14 0c0 5.5 7 13 7 13z" stroke={c} strokeWidth="1.5"/><circle cx="12" cy="9.5" r="2.5" stroke={c} strokeWidth="1.5"/></svg>,
  play:    (s = 26, c = "#fff") => <svg width={s} height={s} viewBox="0 0 24 24"><path d="M8 5v14l11-7z" fill={c}/></svg>,
  bookmark:(s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M6 4h12v18l-6-4-6 4V4z" stroke={c} strokeWidth="1.5" strokeLinejoin="round"/></svg>,
  camera:  (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M4 8h3l2-2h6l2 2h3v11H4z" stroke={c} strokeWidth="1.5" strokeLinejoin="round"/><circle cx="12" cy="13.5" r="3.5" stroke={c} strokeWidth="1.5"/></svg>,
  search:  (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><circle cx="11" cy="11" r="6.5" stroke={c} strokeWidth="1.6"/><path d="M20 20l-3.5-3.5" stroke={c} strokeWidth="1.6" strokeLinecap="round"/></svg>,
  globe:   (s = 36, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke={c} strokeWidth="1.4"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18" stroke={c} strokeWidth="1.4"/></svg>,
  euro:    (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M18 7a6 6 0 1 0 0 10M5 11h9M5 14h9" stroke={c} strokeWidth="1.6" strokeLinecap="round"/></svg>,
  mic:     (s = 18, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><rect x="9" y="3" width="6" height="12" rx="3" stroke={c} strokeWidth="1.6"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3" stroke={c} strokeWidth="1.6" strokeLinecap="round"/></svg>,
  bell:    (s = 22, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M6 16V11a6 6 0 1 1 12 0v5l1.5 2.2H4.5L6 16z" stroke={c} strokeWidth="1.5" strokeLinejoin="round"/><path d="M10 19a2 2 0 1 0 4 0" stroke={c} strokeWidth="1.5" strokeLinecap="round"/></svg>,
  compass: (s = 22, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke={c} strokeWidth="1.5"/><path d="M8.5 15.5l1.7-5.3L15.5 8.5l-1.7 5.3L8.5 15.5z" stroke={c} strokeWidth="1.5" strokeLinejoin="round"/></svg>,
  bag:     (s = 22, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M5 8h14l-1 12H6L5 8z" stroke={c} strokeWidth="1.5" strokeLinejoin="round"/><path d="M9 8V6a3 3 0 1 1 6 0v2" stroke={c} strokeWidth="1.5" strokeLinecap="round"/></svg>,
  clock:   (s = 14, c = "currentColor") => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="8.5" stroke={c} strokeWidth="1.5"/><path d="M12 7.5v5l3.2 2" stroke={c} strokeWidth="1.5" strokeLinecap="round"/></svg>,
};

/* ─── HoursRow — opening-hours field per activity ─── */
function HoursRow({ hours }) {
  if (!hours) return null;

  if (hours.state === "add") {
    return (
      <button style={{
        marginTop: 10,
        display: "inline-flex", alignItems: "center", gap: 6,
        padding: "6px 12px", borderRadius: 9999,
        background: "transparent",
        border: "1px dashed var(--border-strong, #c1c1c1)",
        color: "var(--muted)",
        fontSize: 12, fontWeight: 500, letterSpacing: "-.01em",
      }}>
        {I.clock(13, "var(--muted)")}
        + הוסף שעות פתיחה
      </button>
    );
  }

  const tone = {
    open: { fg: "#0a7a3d", dotBg: "#0a7a3d" },
    flex: { fg: "var(--muted)", dotBg: "var(--muted-soft)" },
  }[hours.state] || { fg: "var(--ink)", dotBg: "var(--muted-soft)" };

  return (
    <div style={{
      marginTop: 10, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap",
    }}>
      <div style={{
        display: "inline-flex", alignItems: "center", gap: 6,
        padding: "5px 10px", borderRadius: 9999,
        background: "var(--surface-soft)",
        fontSize: 12, fontWeight: 500, letterSpacing: "-.01em",
        color: "var(--ink)",
      }}>
        {I.clock(13, tone.fg)}
        <span style={{ color: tone.fg, fontWeight: 600, fontSize: 11, letterSpacing: ".02em" }}>
          {hours.state === "open" ? "פתוח" : "גמיש"}
        </span>
        <span style={{ color: "var(--hairline)", margin: "0 2px" }}>·</span>
        <span className={(hours.value || "").match(/\d/) ? "ltr-inline" : ""}>{hours.value || ""}</span>
      </div>
      {hours.reserved && (
        <div style={{
          display: "inline-flex", alignItems: "center", gap: 6,
          padding: "5px 10px", borderRadius: 9999,
          background: "var(--coral-soft)",
          color: "var(--coral-press)",
          fontSize: 11, fontWeight: 600, letterSpacing: ".02em",
        }}>
          ✓ {hours.reserved}
        </div>
      )}
    </div>
  );
}

function TabBar({ active = "home", dark = false, sticky = false }) {
  const items = [
    { id: "home",    label: "בית",      svg: (c, s) => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M3 11l9-7 9 7v9a1 1 0 0 1-1 1h-5v-6h-6v6H4a1 1 0 0 1-1-1v-9z" stroke={c} strokeWidth="1.7" strokeLinejoin="round"/></svg> },
    { id: "plan",    label: "מסלול",    svg: (c, s) => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2zM9 4v14M15 6v14" stroke={c} strokeWidth="1.7" strokeLinejoin="round"/></svg> },
    { id: "mem",     label: "זיכרונות", svg: (c, s) => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M4 8h3l2-2h6l2 2h3v11H4z" stroke={c} strokeWidth="1.7" strokeLinejoin="round"/><circle cx="12" cy="13.5" r="3.5" stroke={c} strokeWidth="1.7"/></svg> },
    { id: "budget",  label: "תקציב",    svg: (c, s) => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><path d="M18 7a6 6 0 1 0 0 10M5 11h9M5 14h9" stroke={c} strokeWidth="1.7" strokeLinecap="round"/></svg> },
  ];
  return (
    <div
      role="navigation"
      aria-label="ניווט ראשי"
      style={{
      // Static block — the parent wrapper (in app.jsx) already pins us to the
      // viewport bottom via position:fixed. Don't add transform/filter or any
      // other property that creates a new containing block here — that re-introduces
      // the iOS Safari compositor shift across screen transitions.
      paddingBottom: "calc(10px + env(safe-area-inset-bottom, 0px))",
      paddingTop: 10,
      paddingLeft: 12, paddingRight: 12,
      display: "flex", justifyContent: "center",
      width: "100%",
      pointerEvents: "none",
    }}>
      <div className={dark ? "lg-tabbar-dark" : "lg-tabbar"} style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        gap: 4, padding: 6, borderRadius: 9999,
        pointerEvents: "auto",
        width: "min(100%, 360px)",
      }}>
        {items.map(it => {
          const isActive = it.id === active;
          const iconColor = isActive ? "#fff" : (dark ? "rgba(255,255,255,.72)" : "var(--ink)");
          return (
            <div
              key={it.id}
              data-nav={it.id}
              data-nav-replace="1"
              aria-label={it.label}
              aria-current={isActive ? "page" : undefined}
              className={isActive ? "lg-tab-active" : "lg-tab-idle"}
              style={{
                flex: isActive ? "1 1 0" : "0 0 auto",
                minWidth: isActive ? 0 : 50,
                height: 44,
                display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
                padding: isActive ? "0 16px" : "0 12px",
                borderRadius: 9999,
                cursor: "pointer", userSelect: "none",
                transition: "flex .32s var(--glass-ease), padding .32s var(--glass-ease), background .28s ease, box-shadow .28s ease",
                background: isActive
                  ? "linear-gradient(180deg, #ff7a8b 0%, var(--coral) 100%)"
                  : "transparent",
                boxShadow: isActive
                  ? "inset 0 1px 0 rgba(255,255,255,.32), inset 0 -0.5px 0 rgba(0,0,0,.1), 0 6px 18px -4px rgba(255,78,100,.5)"
                  : "none",
                color: iconColor,
              }}
            >
              {it.svg(iconColor, 22)}
              {isActive && (
                <div style={{
                  fontSize: 12.5, fontWeight: 600, letterSpacing: "-.01em",
                  color: "#fff", whiteSpace: "nowrap",
                  animation: "tabLabelIn .35s var(--glass-ease)",
                }}>{it.label}</div>
              )}
            </div>
          );
        })}
      </div>
      <style>{`
        @keyframes tabLabelIn { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: translateX(0); } }
        .lg-tab-idle:active { transform: scale(0.92); }
        .lg-tab-active:active { transform: scale(0.97); }
      `}</style>
    </div>
  );
}

function AvatarPair({ size = 28, names }) {
  const trip = window.Store && window.Store.state && window.Store.state.trip;
  const travelers = (trip && trip.travelers) || [];
  if (!travelers.length) {
    const u = window.currentUser && window.currentUser();
    if (!u) return null;
    return (
      <div style={{
        width: size, height: size, borderRadius: 9999,
        background: u.color || "var(--coral)", color: "#fff",
        fontSize: size * 0.4, fontWeight: 700,
        display: "flex", alignItems: "center", justifyContent: "center",
        border: "2px solid var(--canvas)",
      }}>{(u.name || "?").trim().charAt(0)}</div>
    );
  }
  if (travelers.length > 0) {
    const stack = travelers.slice(0, 3);
    return (
      <div style={{ display: "flex" }}>
        {stack.map((p, i) => (
          <div key={p.id || i} style={{
            width: size, height: size, borderRadius: 9999,
            background: ["var(--coral)", "var(--action)", "#34c759", "#ff9500"][i % 4],
            color: "#fff", fontSize: size * 0.4, fontWeight: 700,
            display: "flex", alignItems: "center", justifyContent: "center",
            marginInlineStart: i > 0 ? -size * 0.25 : 0,
            border: "2px solid var(--canvas)",
            flexShrink: 0,
          }}>{(p.name || "?").trim().charAt(0)}</div>
        ))}
        {travelers.length > 3 && (
          <div style={{
            width: size, height: size, borderRadius: 9999,
            background: "var(--surface-soft)", color: "var(--ink)",
            fontSize: size * 0.35, fontWeight: 700,
            display: "flex", alignItems: "center", justifyContent: "center",
            marginInlineStart: -size * 0.25, border: "2px solid var(--canvas)",
            flexShrink: 0,
          }}>+{travelers.length - 3}</div>
        )}
      </div>
    );
  }
  const fallback = (names || "מ ע").split(" ");
  const [a, b] = fallback;
  return (
    <div style={{ display: "inline-flex", position: "relative", width: size * 1.65, height: size }}>
      <div style={{
        position: "absolute", left: 0, top: 0, width: size, height: size, borderRadius: 9999,
        background: "linear-gradient(135deg, #ff8a5b, #c9446a)",
        color: "#fff", display: "flex", alignItems: "center", justifyContent: "center",
        fontSize: size * 0.42, fontWeight: 600, border: "2px solid #fff",
      }}>{a}</div>
      <div style={{
        position: "absolute", right: 0, top: 0, width: size, height: size, borderRadius: 9999,
        background: "linear-gradient(135deg, #6fa0c8, #2d4d70)",
        color: "#fff", display: "flex", alignItems: "center", justifyContent: "center",
        fontSize: size * 0.42, fontWeight: 600, border: "2px solid #fff",
      }}>{b}</div>
    </div>
  );
}

/* ─────────────────────────── 1) HOME ─────────────────────────── */

/* Lightweight horizontal slider with dots + native scroll-snap.
   Each item: { gradient, eyebrow, title, body, icon, onTap }. */
function InsightSlider({ items, height = 168 }) {
  const trackRef = React.useRef(null);
  const slideRefs = React.useRef([]);
  const [idx, setIdx] = React.useState(0);
  // Active-slide detection via scroll + geometric center distance.
  // - Works identically in RTL and LTR (no scrollLeft sign juggling).
  // - Uses a functional setIdx so we never read a stale `idx` closure
  //   between rapid scroll ticks (the previous IO version had this bug
  //   on the first-slide -> second-slide transition).
  // - Throttled to one update per animation frame.
  React.useEffect(() => {
    const root = trackRef.current;
    if (!root) return;
    let raf = 0;
    const compute = () => {
      const els = slideRefs.current.filter(Boolean);
      if (!els.length) return;
      const rr = root.getBoundingClientRect();
      const cx = rr.left + rr.width / 2;
      let bestI = 0, bestDist = Infinity;
      els.forEach((el, i) => {
        const r = el.getBoundingClientRect();
        const d = Math.abs((r.left + r.width / 2) - cx);
        if (d < bestDist) { bestDist = d; bestI = i; }
      });
      setIdx(prev => prev === bestI ? prev : bestI);
    };
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(compute);
    };
    root.addEventListener("scroll", onScroll, { passive: true });
    // Initial sync — handle the case where mount happens already-scrolled.
    raf = requestAnimationFrame(compute);
    return () => {
      cancelAnimationFrame(raf);
      root.removeEventListener("scroll", onScroll);
    };
  }, [items.length]);
  const goTo = (i) => {
    const el = slideRefs.current[i];
    if (!el) return;
    // scrollIntoView handles RTL correctly across browsers, so we don't
    // have to special-case scrollLeft sign.
    el.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
    if (window._haptic) window._haptic("tap");
  };
  if (!items || !items.length) return null;
  return (
    <div style={{ margin: "0 20px 14px" }}>
      <div ref={trackRef} className="no-scrollbar" style={{
        display: "flex", overflowX: "auto", scrollSnapType: "x mandatory",
        gap: 0, scrollBehavior: "smooth", WebkitOverflowScrolling: "touch",
        borderRadius: 16,
      }}>
        {items.map((it, i) => (
          <div key={i}
            ref={(node) => { slideRefs.current[i] = node; }}
            onClick={() => it.onTap && it.onTap()}
            role={it.onTap ? "button" : undefined}
            tabIndex={it.onTap ? 0 : undefined}
            onKeyDown={(e) => { if (it.onTap && (e.key === "Enter" || e.key === " ")) { e.preventDefault(); it.onTap(); } }}
            className={it.onTap ? "ma-tile-press" : ""}
            style={{
              flex: "0 0 100%", scrollSnapAlign: "center",
              height, borderRadius: 16, padding: "16px 18px",
              background: it.gradient,
              color: "#fff", position: "relative", overflow: "hidden",
              boxShadow: "0 10px 26px -10px rgba(0,0,0,.32)",
              cursor: it.onTap ? "pointer" : "default",
            }}>
            <div className="aurora aurora-soft" aria-hidden="true" />
            <div style={{ position: "relative", display: "flex", flexDirection: "column", height: "100%", justifyContent: "space-between" }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: ".14em", opacity: .9 }}>{it.eyebrow}</div>
                {it.icon && <div style={{ display: "flex", alignItems: "center", justifyContent: "center", lineHeight: 1, opacity: .95 }} aria-hidden="true">{it.icon}</div>}
              </div>
              <div>
                <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: "-.02em", lineHeight: 1.15, textShadow: "0 1px 8px rgba(0,0,0,.18)" }}>{it.title}</div>
                {it.body && <div style={{ fontSize: 13, marginTop: 4, opacity: .92, lineHeight: 1.45 }}>{it.body}</div>}
              </div>
            </div>
          </div>
        ))}
      </div>
      {items.length > 1 && (
        <div role="tablist" aria-label="ניווט בין סליידים" style={{ display: "flex", justifyContent: "center", gap: 6, marginTop: 10 }}>
          {items.map((_, i) => (
            <button key={i} aria-label={`עבור לסלייד ${i + 1}`} aria-current={i === idx ? "true" : undefined}
              onClick={() => goTo(i)}
              style={{
                width: i === idx ? 22 : 6, height: 6, borderRadius: 9999,
                border: "none", padding: 0, cursor: "pointer",
                background: i === idx ? "var(--coral)" : "rgba(0,0,0,.18)",
                transition: "width .28s var(--glass-ease), background .28s ease",
              }} />
          ))}
        </div>
      )}
    </div>
  );
}
window.InsightSlider = InsightSlider;

function HomeScreen() {
  const { useStore, getCountdown, getTripDayInfo } = window;
  // Subscribe to every slice the insight slider reads — was reading
  // Store.state directly inside the IIFE, which bypassed subscription
  // and froze the values at mount.
  const { trip, reminders, memories, activities, expenses, packing, stays } = useStore(s => ({
    trip: s.trip,
    reminders: s.reminders,
    memories: s.memories,
    activities: s.activities,
    expenses: s.expenses,
    packing: s.packing,
    stays: s.stays,
  }));
  const countdown = getCountdown();
  const startInfo = getTripDayInfo(0);
  const endInfo = getTripDayInfo(Math.max(0, trip.days - 1));
  const hasTrip = !!(trip.name && trip.startDate && trip.days > 0);
  const dateRange = hasTrip ? `${startInfo.dayOfMonth}.${startInfo.month} — ${endInfo.dayOfMonth}.${endInfo.month}` : "";
  const openReminders = (reminders || []).filter(r => !r.done);
  const remindersPreview = openReminders.slice(0, 3);
  const recentMemories = (memories || []).slice(0, 6);

  return (
    <div dir="rtl" className="ma-bg-screen ma-bg-home" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", position: "relative", paddingBottom: 90, overflow: "hidden" }}>
      {/* brand + avatars */}
      <div style={{ padding: "0 20px 14px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <img src="assets/logo.png?v=69" alt="MA-Trip" style={{ height: 48, width: "auto", display: "block", filter: "saturate(1.18) drop-shadow(0 6px 14px rgba(0,0,0,.32))" }} />
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <AvatarPair size={32} />
          <button onClick={() => window.A.shareTrip()} aria-label="שיתוף עם מכשיר אחר" style={{
            width: 36, height: 36, borderRadius: 9999, border: "1px solid var(--hairline)",
            background: "var(--surface-soft)", color: "var(--ink)",
            display: "flex", alignItems: "center", justifyContent: "center",
            cursor: "pointer", fontFamily: "inherit",
          }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
              <circle cx="18" cy="5" r="3" stroke="currentColor" strokeWidth="1.6"/>
              <circle cx="6" cy="12" r="3" stroke="currentColor" strokeWidth="1.6"/>
              <circle cx="18" cy="19" r="3" stroke="currentColor" strokeWidth="1.6"/>
              <path d="M8.5 10.5l7-4M8.5 13.5l7 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
            </svg>
          </button>
          {window.ProfileChip && <window.ProfileChip />}
        </div>
      </div>

      {/* greeting */}
      <div style={{ padding: "0 20px 18px" }}>
        <div style={{ fontSize: 13, color: "var(--muted)", letterSpacing: "-.01em" }}>
          {(() => {
            const names = (trip.travelers || []).map(p => p.name);
            if (!names.length) return "שלום";
            if (names.length === 1) return `שלום, ${names[0]}`;
            if (names.length === 2) return `שלום, ${names[0]} ו${names[1]}`;
            return `שלום, ${names.slice(0, 2).join(", ")} ו-${names.length - 2} עוד`;
          })()}
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 2 }}>
          <div style={{ fontSize: 26, fontWeight: 600, letterSpacing: "-.02em" }}>
            {hasTrip ? "הטיול הבא שלכם" : "בואו נתחיל לתכנן"}
          </div>
          {hasTrip && (
            <button onClick={() => window.A.openTripEdit()} aria-label="ערוך / שתף טיול" style={{
              width: 36, height: 36, borderRadius: 9999, border: "none",
              background: "var(--surface-soft)", color: "var(--ink)",
              display: "flex", alignItems: "center", justifyContent: "center",
              cursor: "pointer", fontFamily: "inherit",
            }}>{I.edit(16)}</button>
          )}
        </div>
      </div>

      {hasTrip ? (
        <>
          {/* live insights — swipeable status strip mirrors the auth-screen slide UX */}
          {(() => {
            const totalIls = (expenses || []).reduce((s, e) => s + (parseFloat(e.a) || 0), 0)
              + stays.filter(s => s.paid).reduce((s, st) => s + (parseFloat((st.cost || "").replace(/[^\d.-]/g, "")) || 0), 0);
            const totalBudget = trip.totalBudget || 0;
            const pct = totalBudget > 0 ? Math.min(100, Math.round((totalIls / totalBudget) * 100)) : 0;
            const packedDone = packing.filter(p => p.done).length;
            const packedTotal = packing.length;
            const packedPct = packedTotal > 0 ? Math.round((packedDone / packedTotal) * 100) : 0;
            const slides = [
              {
                eyebrow: countdown.started ? "בעיצומו" : "ספירה לאחור",
                title: countdown.started
                  ? `יום ${Math.max(1, (trip.days || 0) - (countdown.days || 0))} מתוך ${trip.days}`
                  : `${countdown.days} ימים לטיול`,
                body: trip.destinations.slice(0, 2).map(d => window.destName(d)).join(" · ") || "טיול חדש",
                icon: window.BUDGET_ICONS && window.BUDGET_ICONS.plane(28, "#fff"),
                gradient: "linear-gradient(135deg, #ff7a8b 0%, var(--coral) 55%, #c64b78 100%)",
                onTap: () => window._maNavTo && window._maNavTo("plan"),
              },
              {
                eyebrow: "אריזה",
                title: packedTotal === 0 ? "טרם הוספת פריטים" : `${packedDone}/${packedTotal} פריטים ארוזים`,
                body: packedTotal === 0 ? "הקישו להוספת רשימה" : `${packedPct}% מהרשימה מוכן`,
                icon: window.BUDGET_ICONS && window.BUDGET_ICONS.backpack(28, "#fff"),
                gradient: "linear-gradient(135deg, #4ec5c2 0%, #1a6e8f 60%, #6bb6e0 100%)",
                onTap: () => window._maNavTo && window._maNavTo("packing"),
              },
              {
                eyebrow: "תקציב",
                title: totalBudget === 0 ? "טרם הוגדר תקציב" : `נוצלו ${pct}% מהתקציב`,
                body: totalBudget === 0 ? "הקישו להגדרה" : `₪${Math.round(totalIls).toLocaleString()} / ₪${Math.round(totalBudget).toLocaleString()}`,
                icon: window.BUDGET_ICONS && window.BUDGET_ICONS.money(28, "#fff"),
                gradient: "linear-gradient(135deg, #ffd57a 0%, #f6a345 40%, #e0973a 100%)",
                onTap: () => window._maNavTo && window._maNavTo("budget"),
              },
            ];
            return <InsightSlider items={slides} />;
          })()}
          {/* hero trip card */}
          <div data-nav="plan" style={{ margin: "0 20px", borderRadius: 18, overflow: "hidden", position: "relative", height: 320, cursor: "pointer" }}>
            <div className={`ph ${(window.autoDetectCurrency && window.autoDetectCurrency(trip.destinations) === "THB") ? "ph-thai-beach" : "ph-cliff"}`} style={{ position: "absolute", inset: 0 }}>
              <div className="ph-label">{trip.name}</div>
            </div>
            <div style={{ position: "absolute", top: 14, left: 14, right: 14, display: "flex", justifyContent: "space-between" }}>
              <div className="lg-light" style={{ borderRadius: 9999, padding: "5px 12px", fontSize: 11, fontWeight: 600, letterSpacing: ".04em" }}>
                {countdown.started ? "הטיול בעיצומו" : `מתחיל בעוד ${countdown.days} ימים`}
              </div>
              <CircleIcon size={32} dark>{I.heartF(16)}</CircleIcon>
            </div>
            <div style={{ position: "absolute", left: 18, right: 18, bottom: 16, color: "#fff", zIndex: 2 }}>
              <div style={{ fontSize: 11, opacity: .85, fontWeight: 500, letterSpacing: ".06em", textTransform: "uppercase" }}>
                {trip.name} • {startInfo.month} {startInfo.year}
              </div>
              <div style={{ fontSize: 28, fontWeight: 600, letterSpacing: "-.02em", marginTop: 4, lineHeight: 1.1 }}>
                {trip.destinations.slice(0, 3).map(d => window.destName(d)).join(", ")}{trip.destinations.length > 3 ? " ו-" + (trip.destinations.length - 3) + " עוד" : ""}
              </div>
              <div style={{ display: "flex", gap: 14, marginTop: 12, fontSize: 13, opacity: .9 }}>
                <span><span className="ltr-inline">{dateRange}</span></span>
                <span>•</span>
                <span>{trip.days} ימים</span>
                <span>•</span>
                <span>{(activities || []).length} פעילויות</span>
              </div>
            </div>
          </div>

          {/* countdown ribbon */}
          <div className="lg-light" style={{
            margin: "16px 20px 0", borderRadius: 16,
            padding: "14px 16px", display: "flex", alignItems: "center", justifyContent: "space-between",
          }}>
            <div>
              <div style={{ fontSize: 12, color: "var(--coral-press)", fontWeight: 600, letterSpacing: ".04em" }}>הספירה לאחור</div>
              <div style={{ fontSize: 17, fontWeight: 600, marginTop: 2 }}>
                {countdown.started ? "הטיול התחיל" : `${countdown.days} ימים, ${countdown.hours} שעות`}
              </div>
            </div>
            <Pill kind="coral" data-nav="plan" style={{ height: 36, padding: "0 16px", fontSize: 13 }}>פתיחת מסלול</Pill>
          </div>
        </>
      ) : (
        /* Empty state — guide user to create their trip */
        <div className="lg-light" style={{
          margin: "0 20px", borderRadius: 18, padding: "32px 22px",
          textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
        }}>
          <div style={{ width: 64, height: 64, borderRadius: 9999, display: "flex", alignItems: "center", justifyContent: "center", background: "var(--coral-soft)" }}>
            {I.map(28, "var(--coral)")}
          </div>
          <div>
            <div style={{ fontSize: 19, fontWeight: 600, letterSpacing: "-.01em" }}>אין טיול עדיין</div>
            <div style={{ fontSize: 13, color: "var(--muted)", marginTop: 6, lineHeight: 1.5 }}>
              הוסיפי את שם הטיול, התאריכים והיעדים — הכל יסונכרן אוטומטית
            </div>
          </div>
          <Pill kind="coral" onClick={() => window.A.tripWizard()} style={{ marginTop: 4 }}>
            {I.plus(16, "#fff")} צרי טיול חדש
          </Pill>
          <div style={{ fontSize: 12, color: "var(--muted-soft)", marginTop: 4 }}>
            או לחצי על "תכנון" למטה כדי להוסיף יעדים
          </div>
        </div>
      )}

      {/* quick actions — 6 shortcuts in 3×2 grid */}
      <div style={{ marginTop: 22, padding: "0 20px" }}>
        <SectionLabel>קיצורי דרך</SectionLabel>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 10, marginTop: 10 }}>
          {[
            { label: "תכנון",    icon: I.map(22, "var(--coral)"),     nav: "planning" },
            { label: "מקומות",   icon: I.pin(22, "var(--coral)"),     nav: "spots" },
            { label: "מפה",      icon: I.compass(22, "var(--coral)"), nav: "map" },
            { label: "תזכורות",  icon: I.bell(22, "var(--coral)"),    nav: "reminders", badge: openReminders.length || null },
            { label: "תקציב",    icon: I.euro(22, "var(--coral)"),    nav: "budget" },
            { label: "מסמכים",   icon: I.bookmark(22, "var(--coral)"), nav: "docs" },
            { label: "אריזה",    icon: I.bag(22, "var(--coral)"),     nav: "packing" },
            { label: "סיכום",    icon: <svg width="22" height="22" viewBox="0 0 24 24" fill="none"><path d="M4 19V5M10 19V9M16 19V13M22 19H2" stroke="var(--coral)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>, nav: "stats" },
          ].map(q => (
            <button key={q.label} data-nav={q.nav} type="button" aria-label={q.label} className="lg-light" style={{
              borderRadius: 16,
              padding: "16px 12px", display: "flex", flexDirection: "column", alignItems: "center", gap: 8,
              position: "relative", cursor: "pointer",
              color: "var(--ink)", fontFamily: "inherit",
            }}>
              {q.icon}
              <div style={{ fontSize: 13, fontWeight: 500 }}>{q.label}</div>
              {q.badge && (
                <div aria-label={`${q.badge} פתוחות`} style={{
                  position: "absolute", top: 8, insetInlineEnd: 8,
                  minWidth: 18, height: 18, borderRadius: 9999,
                  background: "var(--coral)", color: "#fff",
                  fontSize: 11, fontWeight: 600,
                  display: "flex", alignItems: "center", justifyContent: "center",
                  padding: "0 5px",
                  boxShadow: "0 2px 6px rgba(255,78,100,.4)",
                }}>{q.badge}</div>
              )}
            </button>
          ))}
        </div>
      </div>

      {/* reminders preview — coral-bordered pinned list */}
      <div style={{ marginTop: 24, padding: "0 20px" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
          <SectionLabel>תזכורות לפני הטיסה</SectionLabel>
          <button data-nav="reminders" type="button" style={{
            fontSize: 13, color: "var(--action)", textDecoration: "none", cursor: "pointer",
            background: "transparent", border: "none", padding: "4px 8px",
            fontFamily: "inherit",
          }}>
            {openReminders.length} פעילות
          </button>
        </div>
        {remindersPreview.length === 0 ? (
          <div data-nav="reminders" style={{
            marginTop: 10, borderRadius: 14, padding: "20px 16px",
            border: "1px dashed var(--hairline)", textAlign: "center",
            fontSize: 13, color: "var(--muted)", cursor: "pointer",
          }}>
            אין תזכורות עדיין. הקישו להוסיף.
          </div>
        ) : (
          <div style={{
            marginTop: 10, borderRadius: 14, background: "var(--canvas)",
            border: "1px solid var(--hairline)", overflow: "hidden",
          }}>
            {remindersPreview.map((r, i) => (
              <div key={r.id} data-nav="reminders" style={{
                padding: "13px 14px", display: "flex", alignItems: "center", gap: 12,
                borderBottom: i < remindersPreview.length - 1 ? "1px solid var(--hairline-soft)" : "none",
                background: r.urgent ? "var(--coral-soft)" : "transparent",
                cursor: "pointer",
              }}>
                <div style={{
                  width: 7, height: 7, borderRadius: 9999,
                  background: r.urgent ? "var(--coral)" : "var(--muted-soft)",
                  flexShrink: 0,
                }} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 500, letterSpacing: "-.01em" }}>{r.title}</div>
                  {r.sub && <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 2 }}>{r.sub}</div>}
                </div>
                <div style={{
                  fontSize: 11, fontWeight: 600, letterSpacing: ".06em",
                  color: r.urgent ? "var(--coral-press)" : "var(--muted)",
                  textTransform: "uppercase",
                  whiteSpace: "nowrap",
                }}>{r.when}</div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* recent memories preview (dark thumbnails) */}
      <div style={{ marginTop: 24, padding: "0 20px" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
          <SectionLabel>הזיכרונות האחרונים שלכם</SectionLabel>
          <button data-nav="mem" type="button" style={{
            fontSize: 13, color: "var(--action)", textDecoration: "none", cursor: "pointer",
            background: "transparent", border: "none", padding: "4px 8px",
            fontFamily: "inherit",
          }}>הצג הכל</button>
        </div>
        <div className="no-scrollbar" style={{ display: "flex", gap: 10, marginTop: 12, overflowX: "auto", paddingBottom: 4 }}>
          {recentMemories.length === 0 ? (
            <div data-nav="mem" style={{
              flexShrink: 0, width: "100%", padding: "24px 16px", borderRadius: 14,
              border: "1px dashed var(--hairline)", textAlign: "center",
              fontSize: 13, color: "var(--muted)", cursor: "pointer",
            }}>
              אין זיכרונות עדיין. הקישו להוסיף.
            </div>
          ) : recentMemories.map((m, i) => (
            <div key={m.id} data-nav="memory" style={{ flexShrink: 0, width: 130, cursor: "pointer" }}>
              <div className={`ph ${m.cls || "ph-thai-sunset"}`} style={{ width: 130, height: 170, borderRadius: 12 }} />
              <div style={{ fontSize: 13, fontWeight: 500, marginTop: 8, letterSpacing: "-.01em" }}>{m.title}</div>
              <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 2 }}>{m.sub || ""}</div>
            </div>
          ))}
        </div>
      </div>

      {hasTrip && (
        <button onClick={() => { window.A.quickAddSheet(); window._haptic && window._haptic("tap"); }} className="ma-fab lg-coral" aria-label="הוספה מהירה" style={{
          position: "fixed", bottom: "calc(120px + env(safe-area-inset-bottom, 0px))",
          insetInlineEnd: 20, zIndex: 90,
          width: 56, height: 56, borderRadius: 9999,
          border: "none", color: "#fff", fontSize: 28, fontWeight: 300,
          cursor: "pointer", fontFamily: "inherit",
          boxShadow: "0 12px 28px rgba(255, 78, 100, .45)",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>+</button>
      )}

    </div>
  );
}

function SectionLabel({ children }) {
  return <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--muted)" }}>{children}</div>;
}

/* ─────────────────────────── 2) ITINERARY ─────────────────────────── */

function ItineraryScreen() {
  const { useStore, A, getTripDayInfo, getStayForDay } = window;
  const { day, trip, activities } = useStore(s => ({
    day: s.itineraryDay,
    trip: s.trip,
    activities: s.activities,
  }));
  const items = activities
    .filter(a => a.day === day)
    .sort((a, b) => (a.time || "").localeCompare(b.time || ""));
  const headerInfo = getTripDayInfo(day);
  const stay = getStayForDay(day);
  return (
    <div dir="rtl" className="ma-bg-screen ma-bg-planning" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", paddingBottom: 100, position: "relative", overflow: "hidden" }}>
      {/* header */}
      <div style={{ padding: "4px 20px 12px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <img src="assets/logo.png?v=69" alt="MA-Trip" style={{ height: 48, width: "auto", display: "block", filter: "saturate(1.18) drop-shadow(0 6px 14px rgba(0,0,0,.32))" }} />
        <div style={{ textAlign: "center" }}>
          <div style={{ fontSize: 11, color: "var(--muted)", letterSpacing: ".06em" }}>{trip.name}</div>
          <div style={{ fontSize: 16, fontWeight: 600, marginTop: 2, display: "inline-flex", alignItems: "center", gap: 6 }}>
            <span style={{ color: "var(--coral)", display: "inline-flex" }} aria-hidden="true">
              {window.BUDGET_ICONS && window.BUDGET_ICONS.plane(18, "var(--coral)")}
            </span>
            מסלול הטיול
          </div>
        </div>
        <div style={{ width: 48, height: 48 }} />
      </div>

      {window.QuickNav && <window.QuickNav current="plan" />}

      {trip.days === 0 ? (
        <div className="lg-light" style={{
          margin: "16px 20px", borderRadius: 18, padding: "32px 22px",
          textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
        }}>
          <div style={{ width: 56, height: 56, borderRadius: 9999, display: "flex", alignItems: "center", justifyContent: "center", background: "var(--coral-soft)" }}>
            {I.cal(26, "var(--coral)")}
          </div>
          <div style={{ fontSize: 18, fontWeight: 600 }}>אין ימי טיול</div>
          <div style={{ fontSize: 13, color: "var(--muted)", lineHeight: 1.5 }}>הגדירי תאריך התחלה ומספר ימים</div>
          <Pill kind="coral" onClick={() => window.A.tripWizard()}>
            {I.plus(16, "#fff")} הגדרת טיול
          </Pill>
        </div>
      ) : (
      <>
      {/* days strip */}
      <div className="no-scrollbar" style={{
        padding: "8px 20px 14px", display: "flex", gap: 8, overflowX: "auto",
        borderBottom: "1px solid var(--hairline-soft)",
      }}>
        {Array.from({ length: trip.days }, (_, i) => {
          const info = getTripDayInfo(i);
          const isActive = i === day;
          return (
            <div
              key={i}
              role="button"
              tabIndex={0}
              aria-label={`יום ${i + 1}, ${info.weekday} ${info.dayOfMonth} ${info.month}`}
              aria-pressed={isActive}
              className="ma-chip-press"
              onClick={() => A.setDay(i)}
              onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); A.setDay(i); } }}
              style={{
              width: 52, flexShrink: 0, borderRadius: 12, padding: "10px 0",
              textAlign: "center", position: "relative",
              background: isActive ? "var(--coral)" : "transparent",
              cursor: "pointer",
              color: isActive ? "#fff" : "var(--ink)",
              border: isActive ? "1px solid var(--coral)" : "1px solid var(--hairline)",
              boxShadow: isActive ? "0 6px 16px rgba(255,78,100,.32)" : "none",
            }}>
              <div style={{ fontSize: 10, opacity: isActive ? .85 : .7, fontWeight: 500 }}>{info.weekday}</div>
              <div style={{ fontSize: 18, fontWeight: 600, marginTop: 2 }}>{info.dayOfMonth}</div>
            </div>
          );
        })}
      </div>

      {/* day summary */}
      <div style={{ padding: "16px 20px 6px" }}>
        <div style={{ fontSize: 22, fontWeight: 600, letterSpacing: "-.02em" }}>יום {day + 1}</div>
        <div style={{ fontSize: 13, color: "var(--muted)", marginTop: 4 }}>
          <span className="ltr-inline">{headerInfo.dayOfMonth} {headerInfo.month} {headerInfo.year}</span> • {items.length} פעילויות
        </div>
      </div>

      {/* current stay banner */}
      {stay && (
        <div style={{
          margin: "8px 20px 0", padding: "12px 14px", borderRadius: 12,
          background: "var(--coral-soft)", display: "flex", alignItems: "center", gap: 10,
        }}>
          {I.pin(16, "var(--coral-press)")}
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: "var(--coral-press)" }}>
              מתאחסנים: {stay.destination}{stay.note ? ` · ${stay.note}` : ""}
            </div>
            <div style={{ fontSize: 11, color: "var(--coral-press)", opacity: .8, marginTop: 2 }}>
              לילה {day - stay.startDayIdx + 1} מתוך {stay.nights} · {stay.cost}
            </div>
          </div>
        </div>
      )}

      {/* timeline */}
      <div style={{ padding: "12px 20px 0" }}>
        {items.length === 0 ? (
          <div style={{
            padding: "40px 20px", textAlign: "center", fontSize: 13, color: "var(--muted)",
            border: "1px dashed var(--hairline)", borderRadius: 14, marginTop: 8,
          }}>
            עדיין אין פעילויות ביום {day + 1}.<br/>
            הקישו על «הוסף פעילות» למטה.
          </div>
        ) : items.map((it, i) => (
          <div key={it.id} style={{ display: "flex", gap: 12, marginBottom: 16 }}>
            {/* time column */}
            <div style={{ width: 48, flexShrink: 0, textAlign: "center", paddingTop: 4 }}>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--ink)" }} className="ltr-inline">{it.time || "—"}</div>
              {i < items.length - 1 && (
                <div style={{ width: 1, height: 56, background: "var(--hairline)", margin: "10px auto 0" }} />
              )}
            </div>
            {/* card */}
            <div style={{
              flex: 1, borderRadius: 14, background: "var(--canvas)",
              border: "1px solid var(--hairline)", overflow: "hidden",
            }}>
              <div style={{ padding: "12px 14px", borderInlineStart: it.color ? `4px solid ${it.color}` : "none" }}>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
                    {it.color && <div style={{ width: 8, height: 8, borderRadius: 9999, background: it.color, flexShrink: 0 }} />}
                    <div style={{ fontSize: 15, fontWeight: 600, letterSpacing: "-.01em" }}>{it.title}</div>
                  </div>
                  {window.RowMenu && (
                    <window.RowMenu
                      label={it.title}
                      collection="activities"
                      itemId={it.id}
                      onEdit={() => A.editActivity(it.id)}
                      onDelete={() => A.deleteActivity(it.id)}
                    />
                  )}
                </div>
                {it.loc && (
                  <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 3, display: "flex", alignItems: "center", gap: 4 }}>
                    {I.pin(12, "var(--muted)")} {it.loc}
                  </div>
                )}
                <HoursRow hours={it.hours} />
                {it.note && (
                  <div style={{
                    fontSize: 12, color: "var(--body)", marginTop: 10,
                    padding: "7px 10px 7px 12px", borderRadius: 6,
                    background: "var(--surface-soft)",
                    borderInlineStart: "2px solid var(--coral)",
                    display: "flex", alignItems: "center", gap: 8,
                  }}>
                    <span style={{ fontSize: 10, fontWeight: 700, color: "var(--coral-press)", letterSpacing: ".08em", textTransform: "uppercase", flexShrink: 0 }}>טיפ</span>
                    <span>{it.note}</span>
                  </div>
                )}
              </div>
            </div>
          </div>
        ))}
      </div>

      {/* FAB */}
      <div style={{ position: "sticky", bottom: 100, marginTop: 16, display: "flex", justifyContent: "center", pointerEvents: "none", zIndex: 30 }}>
        <Pill kind="primary" onClick={() => A.addActivity(day)} style={{
          height: 50, padding: "0 28px", fontSize: 15,
          pointerEvents: "auto",
        }}>
          {I.plus(18, "#fff")} הוסף פעילות
        </Pill>
      </div>

      </>
      )}

    </div>
  );
}

/* ─────────────────────────── 3) MEMORIES (dark) ─────────────────────────── */

function MemoriesScreen() {
  const { useStore, A } = window;
  // Subscribe to trip too — header reads trip.name/startDate/days, was
  // bypassing useStore and never re-rendering on edits.
  const state = useStore(s => ({ memories: s.memories, filter: s.memoryFilter, trip: s.trip }));
  const filters = ["הכל", "תמונות", "יומן", "מקומות"];
  const grid = state.memories
    .map(m => ({ id: m.id, cls: m.cls, span: m.span || "sm", label: m.title, sub: m.sub, video: m.video, liked: m.liked, photos: m.photos || [], journal: m.journal, location: m.location }))
    .filter(g => {
      if (state.filter === "הכל") return true;
      if (state.filter === "תמונות") return (g.photos || []).length > 0;
      if (state.filter === "יומן")   return !!(g.journal && g.journal.trim());
      if (state.filter === "מקומות") return !!(g.location && g.location.trim());
      return true;
    });

  return (
    <div dir="rtl" className="ma-bg-screen ma-bg-memories" style={{
      background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", position: "relative", paddingBottom: 100, overflow: "hidden",
    }}>
      {/* header */}
      <div style={{ padding: "4px 20px 8px" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <img src="assets/logo.png?v=69" alt="MA-Trip" style={{ height: 48, width: "auto", display: "block", filter: "saturate(1.18) drop-shadow(0 6px 14px rgba(0,0,0,.32))" }} />
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <CircleIcon
              size={36}
              className="lg-coral"
              data-nav="add"
              style={{ cursor: "pointer" }}
              aria-label="הוסף זיכרון"
            >
              {I.plus(20, "#fff")}
            </CircleIcon>
            <AvatarPair size={32} />
          </div>
        </div>
        <div style={{ marginTop: 14, fontFamily: "var(--font)", fontSize: 32, fontWeight: 600, letterSpacing: "-.02em", lineHeight: 1.0 }}>
          הזיכרונות<br/>שלנו
        </div>
        <div style={{ marginTop: 8, fontSize: 13, color: "var(--muted)" }}>
          {state.memories.length} פריטים • {new Set(state.memories.map(m => (m.sub || "").split("•")[0].trim()).filter(Boolean)).size} מקומות
        </div>
      </div>

      {/* filter strip */}
      <div className="no-scrollbar" style={{ display: "flex", gap: 8, overflowX: "auto", padding: "16px 20px 14px" }}>
        {filters.map((f, i) => {
          const active = f === state.filter;
          return (
            <div key={f}
              role="button"
              tabIndex={0}
              aria-pressed={active}
              aria-label={`סינון ${f}`}
              onClick={() => A.setMemoryFilter(f)}
              onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); A.setMemoryFilter(f); } }}
              className={`lg-chip ma-chip-press ${active ? "is-active" : ""}`}
              style={{
              flexShrink: 0, padding: "8px 14px", borderRadius: 9999,
              fontSize: 13, fontWeight: 500, cursor: "pointer",
            }}>{f}</div>
          );
        })}
      </div>

      {/* trip slice label */}
      <div style={{ padding: "4px 20px 12px", display: "flex", alignItems: "baseline", justifyContent: "space-between" }}>
        <div style={{ fontSize: 11, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--muted)", fontWeight: 600 }}>
          {state.trip.name} · {(state.trip.startDate || "").slice(0, 4)}
        </div>
        <div style={{ fontSize: 11, color: "var(--muted)", fontFamily: "var(--mono)", letterSpacing: ".04em" }}>{state.trip.days} ימים · {grid.length} פריטים</div>
      </div>

      {/* featured memories — swipeable highlights, only when there are 3+ items */}
      {grid.length >= 3 && window.InsightSlider && (() => {
        const liked = state.memories.filter(m => m.liked && (m.photos || []).length > 0);
        const withPhotos = state.memories.filter(m => (m.photos || []).length > 0);
        const pool = (liked.length ? liked : withPhotos).slice(0, 3);
        if (pool.length < 2) return null;
        const slides = pool.map(m => ({
          eyebrow: m.liked ? "♥ אהוב" : "זיכרון",
          title: m.title || "ללא כותרת",
          body: (m.location || "").slice(0, 60) || (m.journal || "").slice(0, 60),
          icon: m.liked
            ? (window.BUDGET_ICONS && window.BUDGET_ICONS.sparkle(26, "#fff"))
            : (window.BUDGET_ICONS && window.BUDGET_ICONS.photo(26, "#fff")),
          gradient: m.liked
            ? "linear-gradient(135deg, #ff7a8b 0%, var(--coral) 55%, #c64b78 100%)"
            : "linear-gradient(135deg, #4ec5c2 0%, #1a6e8f 60%, #6bb6e0 100%)",
          onTap: () => {
            window.A && window.A.openMemory && window.A.openMemory(m.id);
            window._maNavTo && window._maNavTo("memory");
          },
        }));
        return <window.InsightSlider items={slides} height={150} />;
      })()}

      {/* magazine grid — empty state */}
      {grid.length === 0 && (
        <div className="lg-bento" style={{
          margin: "0 20px", padding: "32px 22px",
          textAlign: "center",
          display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
        }}>
          <div style={{
            width: 64, height: 64, borderRadius: 9999,
            background: "linear-gradient(135deg, #ff7a8b, var(--coral))",
            display: "flex", alignItems: "center", justifyContent: "center",
            color: "#fff", fontSize: 28, fontWeight: 300,
            boxShadow: "0 10px 24px -6px rgba(255,78,100,.45)",
          }} aria-hidden="true">✦</div>
          <div style={{ fontSize: 18, fontWeight: 700, letterSpacing: "-.02em" }}>
            כאן יחיה כל זיכרון
          </div>
          <div style={{ fontSize: 13, color: "var(--muted)", lineHeight: 1.55, maxWidth: 280 }}>
            תמונות, הקלטות קוליות, שיר רקע ומקום על המפה — כל יום של הטיול במשפט אחד.
          </div>
          <Pill kind="coral" data-nav="add" style={{ marginTop: 4 }}>
            {I.plus(16, "#fff")} זיכרון ראשון
          </Pill>
        </div>
      )}
      <div className="ma-list-stagger" style={{
        padding: "0 20px",
        display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8,
        gridAutoRows: 92, gridAutoFlow: "dense",
      }}>
        {grid.map((g, i) => {
          const styleBySpan = {
            tall: { gridRow: "span 3" },
            wide: { gridColumn: "span 2", gridRow: "span 2" },
            sm:   { gridRow: "span 2" },
          }[g.span];
          const photoSrc = g.photos && g.photos[0];
          return (
            <div key={g.id || i} data-nav="memory" onClick={() => g.id && A.openMemory(g.id)} className={(photoSrc ? "" : `ph ${g.cls} `) + "ma-tile-press"} style={{
              ...styleBySpan, borderRadius: 8, overflow: "hidden", position: "relative", cursor: "pointer",
              background: photoSrc ? "#000" : undefined,
              ['--i']: Math.min(i, 12),
            }}>
              {photoSrc && (
                <window.MediaImg src={photoSrc} alt={g.label || ""} style={{
                  position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover",
                }} />
              )}
              {g.video && (
                <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center" }}>
                  <div style={{
                    width: 42, height: 42, borderRadius: 9999,
                    background: "rgba(0,0,0,.45)", border: "1px solid rgba(255,255,255,.6)",
                    display: "flex", alignItems: "center", justifyContent: "center", paddingRight: 3,
                    backdropFilter: "blur(6px)",
                  }}>{I.play(18)}</div>
                </div>
              )}
              <div style={{
                position: "absolute", left: 10, right: 10, bottom: 8, zIndex: 2,
                color: "#fff",
              }}>
                <div style={{ fontSize: 13, fontWeight: 500, letterSpacing: "-.01em", textShadow: "0 1px 6px rgba(0,0,0,.45)" }}>{g.label}</div>
                <div style={{ fontSize: 10, opacity: .75, marginTop: 2, fontFamily: "var(--mono)" }}>{g.sub}</div>
              </div>
            </div>
          );
        })}
      </div>

    </div>
  );
}

/* ─────────────────────────── 4) MEMORY DETAIL (dark) ─────────────────────────── */

function MemoryDetailScreen() {
  const { useStore, A } = window;
  const { mem, mid } = useStore(s => {
    const id = s.currentMemoryId;
    // No fallback to memories[0] — that masked deletes (after a delete the
    // user saw a *different* memory and felt stuck on the deleted one).
    const m = id ? s.memories.find(x => x.id === id) : null;
    return { mem: m, mid: id };
  });
  const hadMemRef = React.useRef(false);
  React.useEffect(() => {
    if (mem) { hadMemRef.current = true; return; }
    // Memory disappeared while screen is open (deleted, or id cleared).
    // Pop back so the user lands on the memories grid automatically.
    if (hadMemRef.current && window._maNavBack) {
      hadMemRef.current = false;
      window._maNavBack();
    }
  }, [mem, mid]);

  if (!mem) {
    return (
      <div dir="rtl" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: 40, gap: 16 }}>
        <CircleIcon size={36} data-nav="back" style={{ position: "absolute", top: 14, right: 14, cursor: "pointer" }}>{I.close(18)}</CircleIcon>
        <div style={{ fontSize: 18, fontWeight: 600 }}>אין זיכרון להציג</div>
        <Pill kind="coral" data-nav="add">הוסיפי זיכרון חדש</Pill>
      </div>
    );
  }

  const photos = mem.photos || [];
  const cover = photos[0];

  return (
    <div dir="rtl" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", position: "relative" }}>
      {/* full bleed photo */}
      <div className={cover ? "" : "ph ph-night"} style={{ height: 520, position: "relative", background: cover ? "#000" : undefined }}>
        {cover && <window.MediaImg src={cover} alt={mem.title || "תמונת זיכרון"} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />}
        <div style={{
          position: "absolute", top: 12, left: 14, right: 14,
          display: "flex", justifyContent: "space-between",
        }}>
          <CircleIcon size={36} dark data-nav="back" style={{ cursor: "pointer" }}>
            {I.close(18, "#fff")}
          </CircleIcon>
          <div style={{ display: "flex", gap: 8 }}>
            <CircleIcon size={36} dark onClick={() => A.editMemory(mem.id)} style={{ cursor: "pointer" }} aria-label="ערוך זיכרון">
              {I.edit(18, "#fff")}
            </CircleIcon>
            <CircleIcon size={36} dark onClick={() => A.likeMemory(mem.id)} style={{ cursor: "pointer" }}
              aria-label={mem.liked ? "הסר לייק" : "הוסף לייק"} aria-pressed={!!mem.liked}>
              <span key={mem.liked ? "on" : "off"} className={mem.liked ? "ma-heart-pop" : ""}>
                {mem.liked ? I.heartF(18, "var(--coral)") : I.heart(18, "#fff")}
              </span>
            </CircleIcon>
            <CircleIcon size={36} dark onClick={() => A.deleteMemory(mem.id)} style={{ cursor: "pointer" }} aria-label="מחק זיכרון">
              {I.trash(18, "#fff")}
            </CircleIcon>
          </div>
        </div>
        {photos.length > 1 && (
          <div style={{
            position: "absolute", left: "50%", transform: "translateX(-50%)", bottom: 16,
            padding: "5px 12px", borderRadius: 9999,
            background: "rgba(0,0,0,.45)", backdropFilter: "blur(8px)",
            fontSize: 11, fontFamily: "var(--mono)", letterSpacing: ".04em",
          }}>1 / {photos.length}</div>
        )}
      </div>

      {/* meta + journal */}
      <div style={{ padding: "22px 22px 100px" }}>
        <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--muted)" }}>
          {[mem.location, mem.date].filter(Boolean).join(" • ") || "זיכרון חדש"}
        </div>
        <div style={{ fontSize: 28, fontWeight: 600, letterSpacing: "-.02em", marginTop: 8, lineHeight: 1.1 }}>
          {mem.title}
        </div>

        {/* Audio players — voice note + bg music */}
        {(mem.voiceNote || mem.bgMusic) && (
          <div style={{ marginTop: 18, display: "flex", flexDirection: "column", gap: 10 }}>
            {mem.voiceNote && (
              <window.SpotifyPlayer src={mem.voiceNote.src || mem.voiceNote.dataUrl} title="הקלטה" artist="זיכרון קולי" cover={cover} />
            )}
            {mem.bgMusic && (
              mem.bgMusic.link
                ? <window.MusicEmbed link={mem.bgMusic.link} />
                : <window.SpotifyPlayer
                    src={mem.bgMusic.src || mem.bgMusic.dataUrl}
                    title={(mem.bgMusic.name || "שיר רקע").replace(/\.\w+$/, "")}
                    artist="שיר רקע"
                    coverGradient="linear-gradient(135deg, #2d83ee, #0852b5)"
                  />
            )}
          </div>
        )}

        {mem.journal && (
          <div style={{
            marginTop: 20, fontSize: 15, lineHeight: 1.7,
            color: "var(--body)", letterSpacing: "-.005em",
            whiteSpace: "pre-wrap",
          }}>{mem.journal}</div>
        )}

        {/* comments */}
        {(mem.comments && mem.comments.length > 0) && (
          <div style={{ marginTop: 28 }}>
            <div style={{ fontSize: 11, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--muted)", fontWeight: 600 }}>
              {mem.comments.length} תגובות
            </div>
            <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 10 }}>
              {mem.comments.map(c => (
                <div key={c.id} style={{
                  padding: "12px 14px", borderRadius: 12,
                  background: "var(--surface-soft)", border: "1px solid var(--hairline)",
                  display: "flex", alignItems: "flex-start", gap: 10,
                }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, lineHeight: 1.5, color: "var(--ink)", whiteSpace: "pre-wrap" }}>{c.text}</div>
                    <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 4, fontFamily: "var(--mono)" }}>
                      {(c.ts || "").slice(0, 16).replace("T", " ")}
                    </div>
                  </div>
                  <button onClick={() => A.deleteComment(mem.id, c.id)} aria-label="מחק תגובה" style={{
                    border: "none", background: "transparent", color: "var(--muted)",
                    cursor: "pointer", padding: 4, borderRadius: 6, fontFamily: "inherit",
                  }}>{I.trash(15, "var(--muted)")}</button>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* photo strip — all photos */}
        {photos.length > 1 && (
          <div style={{ marginTop: 28 }}>
            <div style={{ fontSize: 11, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--muted)", fontWeight: 600 }}>
              {photos.length} תמונות
            </div>
            <div className="no-scrollbar" style={{ display: "flex", gap: 8, marginTop: 12, overflowX: "auto" }}>
              {photos.map((p, i) => (
                <div key={(p ? "p-" + p : "i-" + i)} style={{ flexShrink: 0, width: 96, height: 120, borderRadius: 8, overflow: "hidden", background: "#000" }}>
                  <window.MediaImg src={p} alt={`${mem.title || "זיכרון"} — תמונה ${i + 1}`} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                </div>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* bottom action bar — honors safe-area-inset-bottom on iPhone X+ */}
      <div style={{
        position: "absolute", left: 0, right: 0, bottom: 0,
        padding: "16px 20px calc(env(safe-area-inset-bottom, 0px) + 20px)",
        background: "linear-gradient(to top, var(--canvas) 60%, rgba(255,255,255,0))",
        display: "flex", gap: 10, alignItems: "center",
      }}>
        <Pill kind="secondary" onClick={() => A.addCommentToMemory(mem.id)} style={{ flex: 1 }}>
          {I.comment(16, "var(--action)")} הוסף תגובה
        </Pill>
        <Pill kind="primary" data-nav="map" style={{ flex: 1 }}>פתח במפה</Pill>
      </div>
    </div>
  );
}

/* ─────────────── Leaflet map helpers ─────────────── */

// Free reverse-geocode via OpenStreetMap Nominatim. Respects 1 req/sec policy.
// 8s AbortController guards against stalled iOS cellular requests.
async function reverseGeocode(lat, lng) {
  const ac = new AbortController();
  const tid = setTimeout(() => ac.abort(), 8000);
  try {
    const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&accept-language=he,en&zoom=14`, {
      headers: { "Accept": "application/json" },
      signal: ac.signal,
    });
    if (!res.ok) { console.warn("[reverseGeocode] http", res.status); return null; }
    const j = await res.json();
    return {
      name: j.display_name || "",
      short: (j.name || j.address?.city || j.address?.town || j.address?.village || j.address?.county || "") || (j.display_name?.split(",")[0] || ""),
      address: j.address || {},
    };
  } catch (e) {
    console.warn("[reverseGeocode] failed", lat, lng, e && e.name);
    return null;
  } finally {
    clearTimeout(tid);
  }
}
window.reverseGeocode = reverseGeocode;

async function forwardGeocode(query) {
  const ac = new AbortController();
  const tid = setTimeout(() => ac.abort(), 8000);
  try {
    const res = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&accept-language=he,en&limit=5`, {
      headers: { "Accept": "application/json" },
      signal: ac.signal,
    });
    if (!res.ok) { console.warn("[forwardGeocode] http", res.status); return []; }
    const j = await res.json();
    return j.map(r => ({ lat: parseFloat(r.lat), lng: parseFloat(r.lon), name: r.display_name }));
  } catch (e) {
    console.warn("[forwardGeocode] failed", query, e && e.name);
    return [];
  } finally {
    clearTimeout(tid);
  }
}
window.forwardGeocode = forwardGeocode;

/* Modal map for picking a location. Opens with current GPS, draggable pin, reverse-geocoded label.
   Props: { initial: {lat,lng,name} | null, onSave({lat,lng,name}), onClose() } */
function LocationPicker({ initial, onSave, onClose }) {
  const mapRef = React.useRef(null);
  const containerRef = React.useRef(null);
  const markerRef = React.useRef(null);
  const [center, setCenter] = React.useState(initial && initial.lat ? { lat: initial.lat, lng: initial.lng } : null);
  const [label, setLabel] = React.useState(initial?.name || "");
  const [loading, setLoading] = React.useState(!initial?.lat);
  const [searchQuery, setSearchQuery] = React.useState("");
  const [searchResults, setSearchResults] = React.useState([]);

  // Initial: get current GPS if no initial location
  React.useEffect(() => {
    if (initial && initial.lat) return;
    if (!navigator.geolocation) {
      setLoading(false);
      setCenter({ lat: 32.0853, lng: 34.7818 }); // TLV default
      return;
    }
    navigator.geolocation.getCurrentPosition(
      pos => {
        setCenter({ lat: pos.coords.latitude, lng: pos.coords.longitude });
        setLoading(false);
      },
      err => {
        setLoading(false);
        setCenter({ lat: 32.0853, lng: 34.7818 });
        if (window.A) window.A.showToast("לא הצלחתי לקבל מיקום — בחרי על המפה", "info");
      },
      { enableHighAccuracy: true, timeout: 8000, maximumAge: 60000 }
    );
  }, []);

  // Init Leaflet map after center is known
  React.useEffect(() => {
    if (!center || !containerRef.current || mapRef.current || !window.L) return;
    const map = window.L.map(containerRef.current, { zoomControl: false, attributionControl: false })
      .setView([center.lat, center.lng], 14);
    window.L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      maxZoom: 19, attribution: "© OpenStreetMap",
    }).addTo(map);
    const marker = window.L.marker([center.lat, center.lng], { draggable: true }).addTo(map);
    marker.on("dragend", async (e) => {
      const ll = e.target.getLatLng();
      setCenter({ lat: ll.lat, lng: ll.lng });
      const g = await reverseGeocode(ll.lat, ll.lng);
      if (g) setLabel(g.short || g.name);
    });
    map.on("click", async (e) => {
      marker.setLatLng(e.latlng);
      setCenter({ lat: e.latlng.lat, lng: e.latlng.lng });
      const g = await reverseGeocode(e.latlng.lat, e.latlng.lng);
      if (g) setLabel(g.short || g.name);
    });
    mapRef.current = map;
    markerRef.current = marker;
    // Initial reverse-geocode if no label
    if (!label) {
      reverseGeocode(center.lat, center.lng).then(g => { if (g) setLabel(g.short || g.name); });
    }
    // Trigger resize after mount
    const sizeT = setTimeout(() => map.invalidateSize(), 100);
    return () => {
      clearTimeout(sizeT);
      if (mapRef.current) {
        try { mapRef.current.remove(); } catch (_) {}
        mapRef.current = null;
      }
      markerRef.current = null;
    };
  }, [center]);

  const useMyLocation = () => {
    if (!navigator.geolocation) return;
    navigator.geolocation.getCurrentPosition(
      pos => {
        const ll = { lat: pos.coords.latitude, lng: pos.coords.longitude };
        setCenter(ll);
        if (mapRef.current && markerRef.current) {
          mapRef.current.setView([ll.lat, ll.lng], 15);
          markerRef.current.setLatLng([ll.lat, ll.lng]);
        }
        reverseGeocode(ll.lat, ll.lng).then(g => { if (g) setLabel(g.short || g.name); });
      },
      err => { if (window.A) window.A.showToast("צריך לאשר גישה למיקום", "error"); },
      { enableHighAccuracy: true, timeout: 8000, maximumAge: 0 }
    );
  };

  const doSearch = async () => {
    if (!searchQuery.trim()) return;
    const results = await forwardGeocode(searchQuery);
    setSearchResults(results);
  };
  const pickSearchResult = (r) => {
    setSearchResults([]);
    setSearchQuery("");
    setCenter({ lat: r.lat, lng: r.lng });
    setLabel(r.name.split(",")[0]);
    if (mapRef.current && markerRef.current) {
      mapRef.current.setView([r.lat, r.lng], 14);
      markerRef.current.setLatLng([r.lat, r.lng]);
    }
  };

  const save = () => {
    if (!center) return;
    onSave({ lat: center.lat, lng: center.lng, name: label || "" });
    onClose();
  };

  return (
    <div dir="rtl" style={{
      position: "fixed", inset: 0, zIndex: 10000,
      background: "rgba(0,0,0,.5)",
      display: "flex", flexDirection: "column",
    }} onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="lg-light" style={{
        margin: "auto 12px", marginBottom: "calc(12px + env(safe-area-inset-bottom, 0px))",
        borderRadius: 18, overflow: "hidden", display: "flex", flexDirection: "column",
        height: "min(80vh, 700px)", marginTop: "calc(env(safe-area-inset-top, 0px) + 60px)",
      }}>
        {/* Header */}
        <div style={{
          padding: "14px 16px", display: "flex", alignItems: "center", justifyContent: "space-between",
          borderBottom: "0.5px solid rgba(0,0,0,.1)",
        }}>
          <button onClick={onClose} style={{
            background: "transparent", border: "none", color: "#0a66d6",
            fontSize: 16, cursor: "pointer", fontFamily: "inherit", padding: 0,
          }}>ביטול</button>
          <div style={{ fontSize: 16, fontWeight: 600 }}>בחרי מיקום</div>
          <button onClick={save} disabled={!center} style={{
            background: "transparent", border: "none",
            color: center ? "#0a66d6" : "var(--muted-soft)",
            fontSize: 16, fontWeight: 600, cursor: center ? "pointer" : "default", fontFamily: "inherit", padding: 0,
          }}>שמור</button>
        </div>
        {/* Search */}
        <div style={{ padding: "10px 14px", display: "flex", gap: 8, position: "relative" }}>
          <input
            type="text"
            value={searchQuery}
            onChange={e => setSearchQuery(e.target.value)}
            onKeyDown={e => { if (e.key === "Enter") doSearch(); }}
            placeholder="חיפוש מקום, כתובת או עיר..."
            style={{
              flex: 1, padding: "10px 12px", border: "0.5px solid rgba(0,0,0,.15)",
              borderRadius: 10, fontSize: 14, fontFamily: "inherit", direction: "rtl", outline: "none",
            }}
          />
          <button onClick={doSearch} className="lg-light" style={{
            padding: "0 14px", borderRadius: 10, border: "none", cursor: "pointer",
            fontFamily: "inherit", fontSize: 13,
          }}>חפש</button>
          {searchResults.length > 0 && (
            <div className="lg-light" style={{
              position: "absolute", top: 50, left: 14, right: 14, zIndex: 5,
              borderRadius: 12, maxHeight: 220, overflowY: "auto",
            }}>
              {searchResults.map((r, i) => (
                <div key={i} onClick={() => pickSearchResult(r)} style={{
                  padding: "10px 14px", fontSize: 13, cursor: "pointer",
                  borderTop: i > 0 ? "0.5px solid rgba(0,0,0,.06)" : "none",
                }}>{r.name}</div>
              ))}
            </div>
          )}
        </div>
        {/* Map */}
        <div style={{ flex: 1, position: "relative", background: "#e4e8ec" }}>
          {loading && (
            <div style={{
              position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
              fontSize: 13, color: "var(--muted)", zIndex: 2,
            }}>טוען מיקום...</div>
          )}
          <div ref={containerRef} style={{ position: "absolute", inset: 0 }} />
          {/* Floating "Use my location" pill */}
          <button onClick={useMyLocation} className="lg-light" style={{
            position: "absolute", top: 12, insetInlineEnd: 12, zIndex: 1000,
            padding: "8px 14px", borderRadius: 9999, border: "none",
            display: "flex", alignItems: "center", gap: 6, fontSize: 12, fontWeight: 500,
            cursor: "pointer", fontFamily: "inherit",
          }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
              <circle cx="12" cy="12" r="3" fill="var(--action)"/>
              <circle cx="12" cy="12" r="9" stroke="var(--action)" strokeWidth="1.5" fill="none"/>
              <path d="M12 2v3M12 19v3M2 12h3M19 12h3" stroke="var(--action)" strokeWidth="1.5" strokeLinecap="round"/>
            </svg>
            <span>המיקום שלי</span>
          </button>
        </div>
        {/* Label */}
        <div style={{ padding: "12px 16px", background: "rgba(255,255,255,.85)", borderTop: "0.5px solid rgba(0,0,0,.08)" }}>
          <div style={{ fontSize: 11, color: "var(--muted)", marginBottom: 4 }}>המיקום הנבחר</div>
          <div style={{ fontSize: 14, fontWeight: 500, minHeight: 18 }}>
            {label || (center ? `${center.lat.toFixed(4)}, ${center.lng.toFixed(4)}` : "—")}
          </div>
        </div>
      </div>
    </div>
  );
}
window.LocationPicker = LocationPicker;

/* Read-only mini map preview for displaying a saved location */
function MapMini({ lat, lng, height = 160, label = "" }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!ref.current || !window.L || lat == null) return;
    const map = window.L.map(ref.current, { zoomControl: false, attributionControl: false, dragging: false, scrollWheelZoom: false, doubleClickZoom: false, touchZoom: false })
      .setView([lat, lng], 14);
    window.L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 18 }).addTo(map);
    window.L.marker([lat, lng]).addTo(map);
    setTimeout(() => map.invalidateSize(), 100);
    return () => map.remove();
  }, [lat, lng]);
  if (lat == null) return null;
  return (
    <div style={{ position: "relative", borderRadius: 12, overflow: "hidden", height, background: "#e4e8ec" }}>
      <div ref={ref} style={{ position: "absolute", inset: 0 }} />
      {label && (
        <div className="lg-light" style={{
          position: "absolute", bottom: 8, insetInlineStart: 8,
          padding: "5px 10px", borderRadius: 9999, fontSize: 12, fontWeight: 500,
          maxWidth: "60%", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
        }}>{label}</div>
      )}
    </div>
  );
}
window.MapMini = MapMini;

/* ─────────────── Voice recording + bg music + Spotify-style player ─────────────── */

function fmtTime(s) {
  s = Math.max(0, Math.floor(s || 0));
  const m = Math.floor(s / 60), r = s % 60;
  return m + ":" + String(r).padStart(2, "0");
}

function SpotifyPlayer({ src, cover, title = "Voice memo", artist = "אריאל ומישל", coverGradient }) {
  const audioRef = React.useRef(null);
  const [playing, setPlaying] = React.useState(false);
  const [t, setT] = React.useState(0);
  const [dur, setDur] = React.useState(0);

  // Resolve "idb://..." refs to blob: URLs so the <audio> element can play them.
  // dataURLs and remote URLs pass through unchanged.
  const initialResolved = (window.MaMedia && window.MaMedia.resolveSync)
    ? window.MaMedia.resolveSync(src) : src;
  const [resolvedSrc, setResolvedSrc] = React.useState(initialResolved);
  React.useEffect(() => {
    let alive = true;
    if (!src) { setResolvedSrc(null); return; }
    if (window.MaMedia && window.MaMedia.isRef && window.MaMedia.isRef(src)) {
      const cached = window.MaMedia.resolveSync(src);
      if (cached) { setResolvedSrc(cached); return; }
      window.MaMedia.getURL(src).then(url => { if (alive) setResolvedSrc(url); }).catch(() => {});
    } else {
      setResolvedSrc(src);
    }
    return () => { alive = false; };
  }, [src]);

  React.useEffect(() => {
    const a = audioRef.current;
    if (!a) return;
    const onTime = () => setT(a.currentTime);
    const onMeta = () => setDur(isFinite(a.duration) ? a.duration : 0);
    const onEnd = () => { setPlaying(false); a.currentTime = 0; setT(0); };
    a.addEventListener("timeupdate", onTime);
    a.addEventListener("loadedmetadata", onMeta);
    a.addEventListener("ended", onEnd);
    return () => { a.removeEventListener("timeupdate", onTime); a.removeEventListener("loadedmetadata", onMeta); a.removeEventListener("ended", onEnd); };
  }, [resolvedSrc]);

  // Decode the audio once and downsample to ~64 amplitude peaks for a tiny
  // static waveform. Skipped silently if WebAudio is unavailable or decode
  // fails (e.g. on iOS Safari with HEIC/oddball codecs).
  const [peaks, setPeaks] = React.useState(null);
  React.useEffect(() => {
    let alive = true;
    setPeaks(null);
    if (!resolvedSrc || (typeof window.AudioContext === "undefined" && typeof window.webkitAudioContext === "undefined")) return;
    const AC = window.AudioContext || window.webkitAudioContext;
    (async () => {
      // iOS Safari caps concurrent AudioContexts at ~6 — every leaked context
      // permanently kills a slot. Always close in `finally`, even on decode error.
      let ctx = null;
      try {
        const resp = await fetch(resolvedSrc);
        const buf = await resp.arrayBuffer();
        ctx = new AC();
        const audioBuf = await ctx.decodeAudioData(buf);
        const ch = audioBuf.getChannelData(0);
        const BUCKETS = 64;
        const step = Math.max(1, Math.floor(ch.length / BUCKETS));
        const out = new Float32Array(BUCKETS);
        for (let i = 0; i < BUCKETS; i++) {
          let max = 0;
          const start = i * step;
          const end = Math.min(ch.length, start + step);
          for (let j = start; j < end; j++) {
            const v = Math.abs(ch[j]);
            if (v > max) max = v;
          }
          out[i] = max;
        }
        if (alive) setPeaks(out);
      } catch (e) {
        console.warn("[SpotifyPlayer] waveform decode failed:", e);
      } finally {
        if (ctx) { try { await ctx.close(); } catch (e) {} }
      }
    })();
    return () => { alive = false; };
  }, [resolvedSrc]);

  const toggle = () => {
    const a = audioRef.current;
    if (!a) return;
    if (playing) { a.pause(); setPlaying(false); }
    else { a.play().then(() => setPlaying(true)).catch(() => setPlaying(false)); }
  };
  const seek = (e) => {
    const a = audioRef.current;
    if (!a || !dur) return;
    const rect = e.currentTarget.getBoundingClientRect();
    const x = (e.clientX || (e.touches && e.touches[0].clientX) || 0) - rect.left;
    const ratio = Math.max(0, Math.min(1, x / rect.width));
    a.currentTime = ratio * dur;
    setT(a.currentTime);
  };
  const pct = dur ? (t / dur) * 100 : 0;

  return (
    <div className="lg-light" style={{
      borderRadius: 18, padding: 14, display: "flex", flexDirection: "column", gap: 12,
    }}>
      <audio ref={audioRef} src={resolvedSrc || undefined} preload="metadata" />
      <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
        {/* cover */}
        <div style={{
          width: 56, height: 56, borderRadius: 12, flexShrink: 0, overflow: "hidden",
          background: cover ? "#000" : (coverGradient || "linear-gradient(135deg, #ff7a8b, #c9446a)"),
          display: "flex", alignItems: "center", justifyContent: "center",
          boxShadow: "0 6px 14px -4px rgba(0,0,0,.2)",
        }}>
          {cover
            ? (window.MediaImg
                ? <window.MediaImg src={cover} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                : <img src={cover} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />)
            : <span style={{ fontSize: 22 }}>{title === "שיר רקע" ? "🎵" : "🎙"}</span>}
        </div>
        {/* meta */}
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 600, letterSpacing: "-.01em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{title}</div>
          <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{artist}</div>
        </div>
        {/* play */}
        <button onClick={toggle} aria-label={playing ? "השהה" : "נגן"} className="lg-coral" style={{
          width: 46, height: 46, borderRadius: 9999, padding: 0,
          display: "flex", alignItems: "center", justifyContent: "center",
          cursor: "pointer", flexShrink: 0,
        }}>
          {playing
            ? <svg width="18" height="18" viewBox="0 0 24 24"><rect x="6" y="5" width="4.5" height="14" rx="1" fill="#fff"/><rect x="13.5" y="5" width="4.5" height="14" rx="1" fill="#fff"/></svg>
            : <svg width="18" height="18" viewBox="0 0 24 24" style={{ marginInlineEnd: -2 }}><path d="M7 5v14l12-7z" fill="#fff"/></svg>}
        </button>
      </div>

      {/* progress — waveform when decoded, fallback to slim gradient bar */}
      {peaks ? (
        <div onClick={seek} style={{
          display: "flex", alignItems: "center", gap: 2,
          height: 38, cursor: dur ? "pointer" : "default",
        }}>
          {Array.from(peaks).map((p, i) => {
            const played = (i / peaks.length) <= (pct / 100);
            // Floor to ensure even silent samples render a visible nub.
            const h = Math.max(3, Math.round(p * 36));
            return (
              <div key={i} style={{
                flex: 1, height: h, borderRadius: 9999,
                background: played
                  ? "linear-gradient(180deg, var(--coral), #ff9bab)"
                  : "rgba(0,0,0,.14)",
                transition: "background .12s ease",
              }} />
            );
          })}
        </div>
      ) : (
        <div onClick={seek} style={{
          position: "relative", height: 6, borderRadius: 9999,
          background: "rgba(0,0,0,.08)", cursor: dur ? "pointer" : "default",
        }}>
          <div style={{
            position: "absolute", insetInlineStart: 0, top: 0, bottom: 0, width: pct + "%",
            borderRadius: 9999, background: "linear-gradient(90deg, var(--coral), #ff9bab)",
          }} />
          {dur > 0 && (
            <div style={{
              position: "absolute", insetInlineStart: `calc(${pct}% - 6px)`, top: -4,
              width: 14, height: 14, borderRadius: 9999, background: "#fff",
              boxShadow: "0 2px 6px rgba(0,0,0,.25), inset 0 0.5px 0 rgba(255,255,255,.9)",
            }} />
          )}
        </div>
      )}
      <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--muted)", fontFamily: "var(--mono)" }}>
        <span>{fmtTime(t)}</span>
        <span>{fmtTime(dur)}</span>
      </div>
    </div>
  );
}
window.SpotifyPlayer = SpotifyPlayer;

function VoiceRecorder({ draft }) {
  const A = window.A;
  const fileRef = React.useRef(null); // fallback for browsers without MediaRecorder
  const [mediaState, setMediaState] = React.useState("idle"); // idle | starting | recording
  const [elapsed, setElapsed] = React.useState(0);
  const recRef = React.useRef(null);
  const timerRef = React.useRef(null);

  // Cleanup on unmount — kill timer + stop recorder so it doesn't leak.
  React.useEffect(() => () => {
    if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; }
    const h = recRef.current;
    if (h && h !== "starting" && h.recorder && h.recorder.state === "recording") {
      try { h.recorder.stop(); } catch (e) {}
    }
  }, []);

  // Audio-only recording via MediaRecorder. NEVER touches camera.
  // State machine: idle → starting (mic permission/init) → recording → idle.
  // Critical iOS fix: don't show "stop" UI until the recorder is actually started,
  // otherwise a user tap during the permission prompt hits a null recRef and the
  // UI sticks in fake-recording forever.
  const startMediaRec = async () => {
    if (!navigator.mediaDevices || !window.MediaRecorder) {
      // Final fallback: pick existing audio file (no capture → no camera)
      fileRef.current?.click();
      return;
    }
    if (recRef.current) return; // already starting or recording — ignore double-tap
    recRef.current = "starting";
    setMediaState("starting");
    setElapsed(0);
    try {
      const handle = await window._recordAudio(120); // up to 2 min
      recRef.current = handle;
      setMediaState("recording");
      timerRef.current = setInterval(() => setElapsed(e => e + 1), 1000);
      const out = await handle.result;
      clearInterval(timerRef.current); timerRef.current = null;
      setMediaState("idle");
      recRef.current = null;
      A.setDraftVoiceNote({ ...out });
      A.showToast("ההקלטה נשמרה", "info");
    } catch (err) {
      if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; }
      setMediaState("idle");
      recRef.current = null;
      const msg = err && err.name === "NotAllowedError"
        ? "צריך לאשר גישה למיקרופון"
        : err && err.name === "NotFoundError"
        ? "לא נמצא מיקרופון"
        : (err && err.message) || "הקלטה נכשלה";
      A.showToast(msg, "error");
    }
  };
  const stopMediaRec = () => {
    const h = recRef.current;
    if (h && h !== "starting" && h.recorder) {
      try { h.recorder.stop(); } catch (e) {}
    }
  };

  const onFile = async (e) => {
    const f = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!f) return;
    try {
      const data = await window._readFileAsDataUrl(f);
      if (data.sizeKb > 8192) { A.showToast("הקובץ גדול מ-8MB", "error"); return; }
      A.setDraftVoiceNote({ dataUrl: data.dataUrl, mime: data.mime || "audio/m4a", sizeKb: data.sizeKb, durSec: 0 });
      A.showToast("ההקלטה נוספה", "info");
    } catch (err) {
      A.showToast("נכשלה הטעינה", "error");
    }
  };

  if (draft && draft.voiceNote) {
    return (
      <div style={{ marginTop: 12 }}>
        <SpotifyPlayer src={draft.voiceNote.src || draft.voiceNote.dataUrl} title="הקלטה שלי" artist="זיכרון קולי" />
        <div style={{ marginTop: 8, display: "flex", justifyContent: "center" }}>
          <button onClick={() => A.removeDraftVoiceNote()} className="lg-light" style={{
            padding: "6px 14px", borderRadius: 9999, border: "0.5px solid rgba(0,0,0,.1)",
            fontSize: 12, color: "var(--coral)", fontFamily: "inherit", cursor: "pointer",
          }}>מחקי הקלטה</button>
        </div>
      </div>
    );
  }

  return (
    <div style={{ marginTop: 12 }}>
      {/* Fallback file input — no `capture` so iOS shows audio file picker, not camera */}
      <input ref={fileRef} type="file" accept="audio/*" onChange={onFile} style={{ display: "none" }} />
      {mediaState === "recording" ? (
        <button onClick={stopMediaRec} className="lg-coral" style={{
          width: "100%", height: 56, borderRadius: 16,
          display: "flex", alignItems: "center", justifyContent: "center", gap: 12,
          color: "#fff", fontWeight: 600, fontFamily: "inherit", cursor: "pointer", border: "none",
        }}>
          <span style={{ width: 12, height: 12, borderRadius: 9999, background: "#fff", animation: "pulse 1s ease-in-out infinite" }} />
          <span>מקליט · {fmtTime(elapsed)}</span>
          <span style={{ opacity: .9, fontSize: 13 }}>הקישי לעצור</span>
        </button>
      ) : mediaState === "starting" ? (
        <button disabled className="lg-light" style={{
          width: "100%", height: 56, borderRadius: 16,
          display: "flex", alignItems: "center", justifyContent: "center", gap: 10,
          fontSize: 14, fontWeight: 500, fontFamily: "inherit", color: "var(--muted)", border: "none",
          opacity: .8,
        }}>
          <span style={{
            width: 14, height: 14, borderRadius: 9999,
            border: "2px solid var(--coral)", borderTopColor: "transparent",
            animation: "spin 0.8s linear infinite",
          }} />
          <span>מאתחל מיקרופון…</span>
        </button>
      ) : (
        <button onClick={startMediaRec} className="lg-light" style={{
          width: "100%", height: 56, borderRadius: 16,
          display: "flex", alignItems: "center", justifyContent: "center", gap: 10,
          fontSize: 14, fontWeight: 500, fontFamily: "inherit", cursor: "pointer", color: "var(--ink)", border: "none",
        }}>
          {I.mic(18, "var(--coral)")}
          <span>הקלטה קולית</span>
        </button>
      )}
      <style>{`@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}@keyframes spin{to{transform:rotate(360deg)}}`}</style>
    </div>
  );
}
window.VoiceRecorder = VoiceRecorder;

/* Parse Spotify or Apple Music share link → returns {service, id, embed} or null */
function parseMusicLink(url) {
  if (!url) return null;
  url = url.trim();
  // Spotify: https://open.spotify.com/track/{id}?si=...
  let m = url.match(/open\.spotify\.com\/(track|playlist|album|episode)\/([a-zA-Z0-9]+)/i);
  if (m) {
    return {
      service: "spotify", kind: m[1], id: m[2], url,
      embed: `https://open.spotify.com/embed/${m[1]}/${m[2]}?utm_source=generator&theme=0`,
    };
  }
  // Apple Music: https://music.apple.com/il/album/.../{albumId}?i={trackId}
  m = url.match(/music\.apple\.com\/(\w+)\/(album|song|playlist)\/[^/]+\/(\d+)(?:\?i=(\d+))?/i);
  if (m) {
    const country = m[1], kind = m[2], albumId = m[3], trackId = m[4];
    const embedPath = trackId ? `${country}/album/_/${albumId}?i=${trackId}` : `${country}/${kind}/_/${albumId}`;
    return {
      service: "apple", kind: trackId ? "song" : kind, id: trackId || albumId, url,
      embed: `https://embed.music.apple.com/${embedPath}`,
    };
  }
  return null;
}
window.parseMusicLink = parseMusicLink;

function MusicEmbed({ link, height = 152 }) {
  if (!link || !link.embed) return null;
  return (
    <iframe
      src={link.embed}
      width="100%" height={height}
      style={{ border: "none", borderRadius: 14, display: "block", overflow: "hidden", colorScheme: "normal" }}
      allow="autoplay; encrypted-media; clipboard-write; fullscreen; picture-in-picture"
      loading="lazy"
      title={link.service === "spotify" ? "Spotify" : "Apple Music"}
    />
  );
}
window.MusicEmbed = MusicEmbed;

function BgMusicPicker({ draft }) {
  const A = window.A;

  const promptForLink = (service) => {
    const labelMap = {
      spotify: "Spotify",
      apple:   "Apple Music",
    };
    const placeholder = service === "spotify"
      ? "https://open.spotify.com/track/..."
      : "https://music.apple.com/...";
    A.openEditSheet({
      title: `שיר רקע מ-${labelMap[service]}`,
      submitLabel: "חברי",
      fields: [
        { key: "url", label: `הדביקי קישור שיתוף מ-${labelMap[service]}`, type: "text", required: true, autoFocus: true, placeholder },
      ],
      onSubmit: (v) => {
        const parsed = parseMusicLink(v.url);
        if (!parsed) { A.showToast("קישור לא תקין", "error"); return; }
        if (service === "spotify" && parsed.service !== "spotify") { A.showToast("צריך קישור Spotify", "error"); return; }
        if (service === "apple" && parsed.service !== "apple") { A.showToast("צריך קישור Apple Music", "error"); return; }
        A.setDraftBgMusic({ link: parsed });
        A.showToast(`שיר רקע מ-${labelMap[service]} נוסף`, "info");
      },
    });
  };

  const open = (s) => {
    // Open Spotify/Apple Music search in a new tab to make it easy to grab a link
    if (s === "spotify") {
      window.open("https://open.spotify.com/search", "_blank", "noopener");
    } else {
      window.open("https://music.apple.com/il/search?term=", "_blank", "noopener");
    }
  };

  if (draft && draft.bgMusic) {
    const link = draft.bgMusic.link;
    return (
      <div style={{ marginTop: 10 }}>
        {link ? <MusicEmbed link={link} /> : (
          <SpotifyPlayer src={draft.bgMusic.src || draft.bgMusic.dataUrl} title={(draft.bgMusic.name || "שיר רקע").replace(/\.\w+$/, "")} artist="שיר רקע" coverGradient="linear-gradient(135deg, #2d83ee, #0852b5)" />
        )}
        <div style={{ marginTop: 8, display: "flex", justifyContent: "center" }}>
          <button onClick={() => A.removeDraftBgMusic()} className="lg-light" style={{
            padding: "6px 14px", borderRadius: 9999, border: "0.5px solid rgba(0,0,0,.1)",
            fontSize: 12, color: "var(--coral)", fontFamily: "inherit", cursor: "pointer",
          }}>הסירי שיר רקע</button>
        </div>
      </div>
    );
  }

  return (
    <div style={{ marginTop: 8, display: "flex", flexDirection: "column", gap: 8 }}>
      <div style={{ display: "flex", gap: 8 }}>
        <button onClick={() => promptForLink("spotify")} className="lg-light" style={{
          flex: 1, height: 46, borderRadius: 14, border: "none",
          display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
          fontSize: 13, fontWeight: 600, fontFamily: "inherit", cursor: "pointer", color: "#1db954",
        }}>
          <svg width="18" height="18" viewBox="0 0 168 168" fill="#1db954"><path d="M83.996.277C37.747.277.253 37.77.253 84.019c0 46.251 37.494 83.741 83.743 83.741 46.254 0 83.744-37.49 83.744-83.741 0-46.246-37.49-83.738-83.745-83.738l.001-.004zm38.404 120.78a5.217 5.217 0 0 1-7.18 1.73c-19.662-12.01-44.414-14.73-73.564-8.07a5.222 5.222 0 0 1-6.249-3.93 5.213 5.213 0 0 1 3.926-6.25c31.9-7.291 59.263-4.15 81.337 9.34 2.46 1.51 3.24 4.72 1.73 7.18zm10.25-22.805c-1.89 3.075-5.91 4.045-8.98 2.155-22.51-13.839-56.823-17.846-83.448-9.764-3.453 1.043-7.1-.903-8.148-4.35a6.538 6.538 0 0 1 4.354-8.143c30.413-9.228 68.222-4.758 94.072 11.127 3.07 1.89 4.04 5.91 2.15 8.976v-.001zm.88-23.744c-26.99-16.031-71.52-17.505-97.289-9.684-4.138 1.255-8.514-1.081-9.768-5.219a7.835 7.835 0 0 1 5.221-9.771c29.581-8.98 78.756-7.245 109.83 11.202a7.823 7.823 0 0 1 2.74 10.733c-2.2 3.722-7.02 4.949-10.73 2.739z"/></svg>
          <span>Spotify</span>
        </button>
        <button onClick={() => promptForLink("apple")} className="lg-light" style={{
          flex: 1, height: 46, borderRadius: 14, border: "none",
          display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
          fontSize: 13, fontWeight: 600, fontFamily: "inherit", cursor: "pointer",
          background: "linear-gradient(180deg, #fc3158, #f80c4a)", color: "#fff",
        }}>
          <span style={{ fontSize: 16 }}>🎵</span>
          <span>Apple Music</span>
        </button>
      </div>
      <div style={{ display: "flex", gap: 8, fontSize: 11, color: "var(--muted)", justifyContent: "center" }}>
        <span style={{ cursor: "pointer", textDecoration: "underline" }} onClick={() => open("spotify")}>חפש ב-Spotify</span>
        <span>·</span>
        <span style={{ cursor: "pointer", textDecoration: "underline" }} onClick={() => open("apple")}>חפש ב-Apple Music</span>
      </div>
    </div>
  );
}
window.BgMusicPicker = BgMusicPicker;

/* ─────────────────────────── 5) ADD MEMORY ─────────────────────────── */

function AddMemoryScreen() {
  const { useStore, A } = window;
  const draft = useStore(s => s.draftMemory);
  const fileInputRef = React.useRef(null);
  const photos = (draft && draft.photos) || [];

  // Native (Capacitor) path uses MaNative.pickPhoto → real iOS photo picker / camera sheet.
  // Web fallback uses the hidden <input type="file">.
  const openPicker = async () => {
    if (window.MaNative && window.MaNative.isNative) {
      try {
        const file = await window.MaNative.pickPhoto({ source: "gallery" });
        if (file) await A.addDraftPhotos([file]);
        return;
      } catch (e) { console.warn("[MaNative.pickPhoto] failed, falling back to web:", e); }
    }
    if (fileInputRef.current) fileInputRef.current.click();
  };
  const onFiles = (e) => {
    if (e.target.files && e.target.files.length) A.addDraftPhotos(e.target.files);
    e.target.value = "";
  };

  const inputStyle = {
    width: "100%",
    fontSize: 18, fontWeight: 600, letterSpacing: "-.015em",
    border: "none", outline: "none", background: "transparent",
    fontFamily: "inherit", color: "var(--ink)", padding: 0,
    direction: "rtl",
  };
  const textareaStyle = {
    width: "100%", minHeight: 80,
    fontSize: 14, lineHeight: 1.6,
    border: "none", outline: "none", background: "transparent",
    fontFamily: "inherit", color: "var(--body)", padding: 0, resize: "vertical",
    direction: "rtl",
  };

  const pickDateTime = () => {
    A.openEditSheet({
      title: "מתי?",
      submitLabel: "שמרי",
      fields: [
        { key: "date", label: "תאריך", type: "text", value: draft.date || "", placeholder: "16 בנוב׳ 2027", autoFocus: true },
        { key: "time", label: "שעה",   type: "text", value: draft.time || "", placeholder: "21:40" },
      ],
      onSubmit: (v) => A.setDraft({ date: v.date || "", time: v.time || "" }),
    });
  };
  const [showLocPicker, setShowLocPicker] = React.useState(false);
  const pickLocation = () => setShowLocPicker(true);
  const handlePublish = (e) => {
    if (!A.publishMemory()) e.stopPropagation();
  };

  return (
    <div dir="rtl" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", position: "relative", paddingBottom: 130 }}>
      {/* header */}
      <div style={{ padding: "4px 20px 12px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <CircleIcon size={36} data-nav="back" style={{ cursor: "pointer" }}>{I.close(18)}</CircleIcon>
        <div style={{ fontSize: 16, fontWeight: 600, letterSpacing: "-.01em" }}>חוויה חדשה</div>
        <div style={{ fontSize: 14, fontWeight: 500, color: "var(--muted-soft)" }}>טיוטה</div>
      </div>

      {/* hidden file input — iOS Safari opens gallery + camera picker */}
      <input
        ref={fileInputRef}
        type="file"
        accept="image/*"
        multiple
        onChange={onFiles}
        style={{ display: "none" }}
      />

      {/* dropzone */}
      <div style={{ padding: "8px 20px 0" }}>
        <div onClick={openPicker} style={{
          height: 220, borderRadius: 16, position: "relative",
          background: photos.length > 0 ? "#000" : "var(--pane)",
          color: "#fff", overflow: "hidden", cursor: "pointer",
        }}>
          {photos.length > 0 ? (
            <window.MediaImg src={photos[0]} alt="טיוטה — תמונה ראשונה" style={{
              position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover",
            }} />
          ) : (
            <div className="ph ph-beach" style={{ position: "absolute", inset: 0, opacity: .55 }} />
          )}
          <div style={{
            position: "absolute", inset: 0, display: "flex", flexDirection: "column",
            alignItems: "center", justifyContent: "center", gap: 14,
            color: "#fff",
            background: photos.length > 0 ? "linear-gradient(to top, rgba(0,0,0,.55), rgba(0,0,0,.15) 50%, rgba(0,0,0,.35))" : "transparent",
          }}>
            <CircleIcon size={48} dark style={{ background: "rgba(255,255,255,.22)", backdropFilter: "blur(10px)" }}>
              {I.plus(22, "#fff")}
            </CircleIcon>
            <div style={{ textAlign: "center" }}>
              <div style={{ fontSize: 15, fontWeight: 500, letterSpacing: "-.01em" }}>
                {photos.length > 0 ? "הוסיפו עוד תמונה" : "הוסיפו תמונה מהגלריה"}
              </div>
              <div style={{ fontSize: 11, fontFamily: "var(--mono)", opacity: .85, marginTop: 4, letterSpacing: ".04em" }}>
                {photos.length === 0
                  ? "JPG · PNG · HEIC"
                  : photos.length + " תמונות נבחרו · הקישו לעוד"}
              </div>
            </div>
          </div>
          {/* thumb stack at bottom — tap to remove */}
          {photos.length > 0 && (
            <div style={{
              position: "absolute", left: 14, bottom: 12, display: "flex", gap: 4,
            }}>
              {photos.slice(0, 4).map((src, i) => (
                <div key={(src ? "s-" + src : "i-" + i)} onClick={(e) => { e.stopPropagation(); A.removeDraftPhoto(i); }} style={{
                  width: 40, height: 40, borderRadius: 6,
                  border: "1.5px solid #fff", overflow: "hidden",
                  background: "#000", position: "relative", cursor: "pointer",
                }} title="הקישו להסרה">
                  <window.MediaImg src={src} alt={`תמונה ${i + 1}`} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                  <div style={{
                    position: "absolute", inset: 0,
                    background: "rgba(0,0,0,0)", transition: "background .15s",
                  }} />
                </div>
              ))}
              {photos.length > 4 && (
                <div style={{
                  width: 40, height: 40, borderRadius: 6,
                  border: "1.5px solid #fff", background: "rgba(0,0,0,.6)",
                  color: "#fff", fontSize: 12, fontWeight: 700,
                  display: "flex", alignItems: "center", justifyContent: "center",
                }}>+{photos.length - 4}</div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* fields */}
      <div style={{ padding: "20px 20px 0" }}>
        <Field label="כותרת">
          <input
            value={draft.title}
            onChange={e => A.setDraft({ title: e.target.value })}
            placeholder="כותרת הזיכרון"
            style={inputStyle}
          />
        </Field>

        <Field label="תאריך וזמן">
          <div onClick={pickDateTime} style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 15, cursor: "pointer" }}>
            <span className="ltr-inline">{draft.date || "בחר תאריך"}</span>
            <span style={{ color: "var(--muted)" }}>•</span>
            <span className="ltr-inline">{draft.time || "בחר שעה"}</span>
            {I.cal(16, "var(--muted)")}
          </div>
        </Field>

        <Field label="מיקום">
          <div onClick={pickLocation} style={{ display: "flex", alignItems: "center", gap: 8, cursor: "pointer" }}>
            {I.pin(16, "var(--coral)")}
            <span style={{ fontSize: 15 }}>{draft.location || "בחרי על המפה"}</span>
          </div>
          {draft.locationCoords && (
            <div style={{ marginTop: 10 }}>
              <window.MapMini lat={draft.locationCoords.lat} lng={draft.locationCoords.lng} height={140} label={draft.location} />
            </div>
          )}
        </Field>

        <Field label="יומן">
          <textarea
            value={draft.journal}
            onChange={e => A.setDraft({ journal: e.target.value })}
            placeholder="כתבו על החוויה..."
            style={textareaStyle}
          />
          <VoiceRecorder draft={draft} />
          <BgMusicPicker draft={draft} />
        </Field>

        <Field label="משותף עם" last>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <AvatarPair size={28} />
              <span style={{ fontSize: 14 }}>אריאל ומישל</span>
            </div>
            <span style={{ fontSize: 12, color: "var(--action)", fontWeight: 500 }}>שנה</span>
          </div>
        </Field>
      </div>

      {/* save bar */}
      <div style={{
        position: "absolute", left: 0, right: 0, bottom: 0,
        padding: "14px 20px 30px",
        background: "rgba(255,255,255,.92)", backdropFilter: "blur(14px)",
        borderTop: "1px solid var(--hairline-soft)",
        display: "flex", gap: 10,
      }}>
        <Pill kind="secondary" data-nav="back" style={{ flex: 1, borderColor: "var(--hairline)", color: "var(--ink)" }}>שמור טיוטה</Pill>
        <Pill kind="primary" data-nav="mem" data-nav-replace="1" onClick={handlePublish} style={{ flex: 1.4 }}>פרסם זיכרון</Pill>
      </div>

      {showLocPicker && (
        <window.LocationPicker
          initial={draft.locationCoords ? { lat: draft.locationCoords.lat, lng: draft.locationCoords.lng, name: draft.location } : null}
          onSave={(loc) => A.setDraft({ location: loc.name || draft.location, locationCoords: { lat: loc.lat, lng: loc.lng } })}
          onClose={() => setShowLocPicker(false)}
        />
      )}
    </div>
  );
}

function Field({ label, children, last }) {
  return (
    <div style={{
      padding: "14px 0",
      borderBottom: last ? "none" : "1px solid var(--hairline-soft)",
    }}>
      <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--muted)" }}>
        {label}
      </div>
      <div style={{ marginTop: 8 }}>{children}</div>
    </div>
  );
}

function Chip({ children }) {
  return (
    <div style={{
      padding: "6px 12px", borderRadius: 9999,
      background: "var(--surface-soft)", color: "var(--ink)",
      fontSize: 12, fontWeight: 500,
      display: "inline-flex", alignItems: "center", gap: 6,
    }}>{children}</div>
  );
}

/* ─────────────────────────── RowMenu (⋯ → Edit/Delete) ─────────────────────────── */

function RowMenu({ label, collection, itemId, onEdit, onDelete, dark = false, size = 28 }) {
  function open(e) {
    // Stop both the synthetic-event React bubble AND the native DOM bubble.
    // The native one matters because the click-delegation handler on .ma-frame
    // is attached as a React onClick on the parent, but several callsites
    // (rowsToggle, etc.) check the underlying nativeEvent on touchstart/touchend.
    e.stopPropagation();
    if (e.nativeEvent && e.nativeEvent.stopImmediatePropagation) {
      e.nativeEvent.stopImmediatePropagation();
    }
    if (collection && itemId) {
      window.A.askActions(label, { collection, itemId, onEdit, onDelete });
    } else {
      window.A.askEditDelete(label, onEdit, onDelete);
    }
  }
  // The button has an invisible 44×44 hit area (WCAG 2.5.8) while the visual
  // pill stays at `size` (default 28) so the visual layout doesn't shift.
  const hit = 44;
  const pad = Math.max(0, (hit - size) / 2);
  return (
    <button
      onClick={open}
      data-rowmenu="1"
      aria-label={label ? `פעולות עבור ${label}` : "פעולות"}
      style={{
        width: hit, height: hit, padding: pad,
        background: "transparent", border: "none",
        display: "flex", alignItems: "center", justifyContent: "center",
        cursor: "pointer", flexShrink: 0, fontFamily: "inherit",
      }}>
      <span aria-hidden="true" style={{
        width: size, height: size, borderRadius: 9999,
        background: dark ? "rgba(255,255,255,.10)" : "var(--surface-soft)",
        color: dark ? "rgba(255,255,255,.7)" : "var(--muted)",
        display: "flex", alignItems: "center", justifyContent: "center",
      }}>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
          <circle cx="5" cy="12" r="1.8"/>
          <circle cx="12" cy="12" r="1.8"/>
          <circle cx="19" cy="12" r="1.8"/>
        </svg>
      </span>
    </button>
  );
}

/* ───────────────────────── TripStatsScreen ─────────────────────────
   "Year-in-review" / wrap-style recap. Bento cards, premium feel.
   Pulls everything from computeTripStats. CTA to share as text. */
function TripStatsScreen() {
  const { useStore, A } = window;
  // Subscribe to every slice the recap reads, so the screen actually re-renders
  // when memories/expenses/spots/activities mutate. Previous code read
  // window.Store.state directly and bypassed the store subscription, showing
  // stale data after edits.
  const sources = useStore(s => ({
    trip: s.trip, memories: s.memories, expenses: s.expenses,
    activities: s.activities, spots: s.spots, stays: s.stays, rates: s.rates,
    documents: s.documents, packing: s.packing, reminders: s.reminders,
  }));
  const trip = sources.trip;
  const stats = React.useMemo(
    () => (window.computeTripStats ? window.computeTripStats(sources) : null),
    [sources.trip, sources.memories, sources.expenses, sources.activities,
     sources.spots, sources.stays, sources.rates, sources.documents,
     sources.packing, sources.reminders]
  );

  if (!trip || !trip.name) {
    return (
      <div dir="rtl" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", padding: 20 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }}>
          <CircleIcon size={36} data-nav="back" aria-label="חזרה">{I.back(18)}</CircleIcon>
          <div style={{ fontSize: 16, fontWeight: 600 }}>סיכום</div>
          <div style={{ width: 36 }} />
        </div>
        <div className="lg-bento" style={{ padding: "40px 22px", textAlign: "center" }}>
          <div style={{ fontSize: 18, fontWeight: 700, marginBottom: 8 }}>אין עדיין מספיק נתונים</div>
          <div style={{ fontSize: 13, color: "var(--muted)", lineHeight: 1.5 }}>
            צרי טיול והתחילי לתעד — סיכום אוטומטי יופיע כאן.
          </div>
        </div>
      </div>
    );
  }
  if (!stats) return null;

  const Card = ({ children, gradient, style }) => (
    <div className="lg-bento" style={{
      padding: 20, position: "relative", overflow: "hidden",
      ...(gradient ? {
        background: gradient,
        color: "#fff",
      } : {}),
      ...style,
    }}>
      {children}
    </div>
  );

  const fmt = (n) => Math.round(n).toLocaleString("he-IL");

  return (
    <div dir="rtl" style={{ background: "var(--canvas)", color: "var(--ink)", minHeight: "100%", paddingBottom: 32 }}>
      {/* Header */}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "8px 20px 12px" }}>
        <CircleIcon size={36} data-nav="back" aria-label="חזרה">{I.back(18)}</CircleIcon>
        <div style={{ fontSize: 16, fontWeight: 600 }}>סיכום הטיול</div>
        <button onClick={() => A.exportTripAsText && A.exportTripAsText()} aria-label="שיתוף סיכום" style={{
          width: 36, height: 36, borderRadius: 9999, border: "none",
          background: "var(--surface-soft)", color: "var(--ink)",
          display: "flex", alignItems: "center", justifyContent: "center",
          cursor: "pointer", fontFamily: "inherit",
        }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
            <path d="M12 3v12M7 8l5-5 5 5M5 14v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      </div>

      {/* Hero */}
      <div style={{ padding: "0 20px 14px" }}>
        <div className="eyebrow">סיכום</div>
        <div className="display-xl" style={{ marginTop: 6, marginBottom: 6 }}>{trip.name}</div>
        {stats.dateRange && (
          <div style={{ fontSize: 14, color: "var(--muted)", fontFamily: "var(--mono)" }}>{stats.dateRange}</div>
        )}
      </div>

      {/* Bento grid */}
      <div style={{ padding: "0 20px", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, gridAutoFlow: "dense" }}>

        {/* Days card — large */}
        <Card gradient="linear-gradient(135deg, #ff7a8b 0%, #ff4e64 60%, #c64b78 100%)" style={{ gridColumn: "span 2" }}>
          <div className="aurora aurora-soft" />
          <div style={{ position: "relative", zIndex: 1 }}>
            <div className="eyebrow" style={{ color: "rgba(255,255,255,.85)" }}>ימים מתועדים</div>
            <div style={{ fontSize: 56, fontWeight: 800, letterSpacing: "-.04em", marginTop: 4, lineHeight: 1 }} className="num-tabular">
              {stats.daysCount}
            </div>
            {stats.destNames.length > 0 && (
              <div style={{ fontSize: 13, opacity: .92, marginTop: 10, lineHeight: 1.5 }}>
                {stats.destNames.join(" · ")}
              </div>
            )}
            {stats.travelersCount > 0 && (
              <div style={{ fontSize: 12, opacity: .8, marginTop: 6 }}>
                {stats.travelersCount === 1 ? "נוסע יחיד" : `${stats.travelersCount} נוסעים`}
              </div>
            )}
          </div>
        </Card>

        {/* Memories + photos */}
        <Card style={{ gridColumn: "span 2" }}>
          <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 14 }}>
            <div style={{ flex: 1 }}>
              <div className="eyebrow">זיכרונות</div>
              <div style={{ display: "flex", alignItems: "baseline", gap: 12, marginTop: 4 }}>
                <div style={{ fontSize: 44, fontWeight: 800, letterSpacing: "-.035em", lineHeight: 1 }} className="num-tabular">{stats.memoriesCount}</div>
                <div style={{ fontSize: 13, color: "var(--muted)" }}>
                  {stats.photosCount} {stats.photosCount === 1 ? "תמונה" : "תמונות"}
                </div>
              </div>
            </div>
            {stats.recentPhotos.length > 0 && (
              <div style={{ display: "flex", gap: 4, flexShrink: 0 }}>
                {stats.recentPhotos.map((p, i) => (
                  <div key={i} style={{
                    width: 40, height: 50, borderRadius: 8, overflow: "hidden",
                    background: "#000", marginInlineStart: i > 0 ? -16 : 0,
                    border: "2px solid var(--canvas)",
                    transform: `rotate(${(i - 1) * 4}deg)`,
                  }}>
                    <window.MediaImg src={p} alt={`זיכרון אחרון ${i + 1}`} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                  </div>
                ))}
              </div>
            )}
          </div>
        </Card>

        {/* Places */}
        <Card>
          <div className="eyebrow">מקומות</div>
          <div style={{ fontSize: 44, fontWeight: 800, letterSpacing: "-.035em", marginTop: 4, lineHeight: 1 }} className="num-tabular">{stats.spotsCount}</div>
          {stats.spotCatTop.length > 0 && (
            <div style={{ display: "flex", gap: 6, marginTop: 10, flexWrap: "wrap" }}>
              {stats.spotCatTop.map(([cat, n]) => {
                const meta = (window.SPOT_CATEGORIES || []).find(c => c.key === cat);
                return (
                  <div key={cat} style={{
                    fontSize: 11, padding: "4px 8px", borderRadius: 9999,
                    background: "var(--surface-soft)", color: "var(--ink)",
                    fontWeight: 500, display: "inline-flex", alignItems: "center", gap: 4,
                  }}>
                    <span>{meta ? meta.icon : "📍"}</span>
                    <span>{n}</span>
                  </div>
                );
              })}
            </div>
          )}
        </Card>

        {/* Budget */}
        <Card>
          <div className="eyebrow">תקציב</div>
          <div style={{ fontSize: 28, fontWeight: 800, letterSpacing: "-.025em", marginTop: 4, lineHeight: 1.1 }} className="num-tabular">
            {fmt(stats.totalSpent)}<span style={{ fontSize: 14, color: "var(--muted)", marginInlineStart: 4 }}>{stats.currency}</span>
          </div>
          {stats.daysCount > 0 && (
            <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 6 }}>
              ~{fmt(stats.dailyAvg)} {stats.currency} ליום
            </div>
          )}
          {stats.topCat && (
            <div style={{
              marginTop: 10, fontSize: 11, color: "var(--coral)", fontWeight: 600,
              padding: "4px 8px", borderRadius: 9999,
              background: "var(--coral-soft)", display: "inline-block",
            }}>
              שיא: {stats.topCat}
            </div>
          )}
        </Card>

        {/* Top memory */}
        {stats.topMemory && (
          <Card gradient="linear-gradient(135deg, #2d83ee 0%, #0852b5 100%)" style={{ gridColumn: "span 2" }}>
            <div style={{ display: "flex", gap: 14, alignItems: "center" }}>
              {stats.topMemory.photos && stats.topMemory.photos[0] && (
                <div style={{
                  width: 72, height: 72, borderRadius: 14, overflow: "hidden",
                  background: "#000", flexShrink: 0,
                  border: "1.5px solid rgba(255,255,255,.25)",
                }}>
                  <window.MediaImg src={stats.topMemory.photos[0]} alt={stats.topMemory.title || "זיכרון מוביל"} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                </div>
              )}
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="eyebrow" style={{ color: "rgba(255,255,255,.85)" }}>
                  {stats.topMemory.liked ? "הרגע האהוב" : "זיכרון בולט"}
                </div>
                <div style={{ fontSize: 18, fontWeight: 700, marginTop: 4, letterSpacing: "-.02em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                  {stats.topMemory.title}
                </div>
                {stats.topMemory.location && (
                  <div style={{ fontSize: 12, opacity: .88, marginTop: 4 }}>{stats.topMemory.location}</div>
                )}
              </div>
            </div>
          </Card>
        )}

        {/* Share CTA */}
        <Card style={{ gridColumn: "span 2", padding: 0 }}>
          <button onClick={() => A.exportTripAsText && A.exportTripAsText()} className="lg-coral" type="button" style={{
            width: "100%", padding: "18px 20px", borderRadius: 28,
            border: "none", cursor: "pointer", fontFamily: "inherit",
            fontSize: 16, fontWeight: 700, color: "#fff",
            display: "flex", alignItems: "center", justifyContent: "center", gap: 10,
          }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
              <path d="M12 3v12M7 8l5-5 5 5M5 14v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5" stroke="#fff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            שתפי את הסיכום
          </button>
        </Card>
      </div>
    </div>
  );
}
window.TripStatsScreen = TripStatsScreen;

/* ─────────────────────── OnboardingScreen ─────────────────────── */
// First-run intro for couples. 3 slides, swipeable. Final CTA opens tripWizard.
// Gated in app.jsx between auth + main render when state.seenOnboarding is false.
function OnboardingScreen() {
  const [idx, setIdx] = React.useState(0);
  const startX = React.useRef(null);
  const slides = [
    {
      eyebrow: "MA-Trip",
      title: "החיים שלכם, מתועדים יחד",
      body: "תכננו כל יום, סמנו כל מקום, שמרו כל זיכרון — באפליקציה אחת שבנויה לזוגות שמטיילים.",
      gradient: "linear-gradient(135deg, #ff7a8b 0%, #ff4e64 45%, #c64b78 100%)",
      icon: "✦",
    },
    {
      eyebrow: "פיצ׳רים",
      title: "תכננו · שתפו · חוו",
      body: "מסלול יומי, מפת מקומות, סורק מסמכים, רשימת אריזה, תקציב חי, זיכרונות עם תמונות וקול — וקישור שיתוף אחד שמסנכרן הכל.",
      gradient: "linear-gradient(135deg, #4ec5c2 0%, #1a6e8f 60%, #6bb6e0 100%)",
      icon: "✈",
    },
    {
      eyebrow: "מוכנים?",
      title: "בואו ניצור את הטיול הראשון",
      body: "צריך רק שם, תאריך, ויעדים — הכל אחר כך גמיש לחלוטין.",
      gradient: "linear-gradient(135deg, #ffd57a 0%, #f6a345 40%, #e0973a 100%)",
      icon: "✦",
    },
  ];
  const s = slides[idx];
  const isLast = idx === slides.length - 1;

  const onTouchStart = (e) => { startX.current = e.touches[0].clientX; };
  const onTouchEnd = (e) => {
    if (startX.current == null) return;
    const dx = e.changedTouches[0].clientX - startX.current;
    startX.current = null;
    if (Math.abs(dx) < 40) return;
    // RTL: swiping LEFT advances to next; swiping RIGHT goes back
    if (dx < 0 && idx < slides.length - 1) setIdx(idx + 1);
    if (dx > 0 && idx > 0) setIdx(idx - 1);
    if (window._haptic) window._haptic("tap");
  };

  const finish = () => {
    if (window._haptic) window._haptic("success");
    window.A.completeOnboarding();
    setTimeout(() => window.A.tripWizard(), 50);
  };
  const skip = () => {
    if (window._haptic) window._haptic("tap");
    window.A.completeOnboarding();
  };

  return (
    <div dir="rtl" onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} style={{
      position: "relative", width: "100%", minHeight: "100%",
      background: "var(--canvas)",
      color: "#fff",
      display: "flex", flexDirection: "column",
      overflow: "hidden",
    }}>
      {/* Hero gradient + aurora */}
      <div style={{
        position: "absolute", inset: 0, background: s.gradient,
        transition: "background .55s cubic-bezier(.2,.85,.2,1)",
      }}>
        <div className="aurora aurora-soft" />
      </div>

      {/* Skip */}
      <div style={{
        position: "relative", zIndex: 2,
        padding: "calc(env(safe-area-inset-top, 0px) + 14px) 18px 0",
        display: "flex", justifyContent: "flex-start",
      }}>
        <button onClick={skip} style={{
          background: "rgba(0,0,0,.18)", color: "#fff",
          border: "0.5px solid rgba(255,255,255,.22)",
          padding: "8px 14px", borderRadius: 9999,
          fontSize: 13, fontWeight: 500, fontFamily: "inherit",
          cursor: "pointer", backdropFilter: "blur(10px)",
          WebkitBackdropFilter: "blur(10px)",
        }}>דלג</button>
      </div>

      {/* Slide content */}
      <div key={idx} className="ma-screen-anim" style={{
        position: "relative", zIndex: 2,
        flex: 1, display: "flex", flexDirection: "column",
        justifyContent: "center", alignItems: "stretch",
        padding: "20px 24px",
      }}>
        <div style={{
          fontSize: 80, lineHeight: 1, marginBottom: 18,
          textAlign: "start", opacity: .92,
          textShadow: "0 4px 24px rgba(0,0,0,.18)",
        }} aria-hidden="true">{s.icon}</div>
        <div className="eyebrow" style={{ color: "rgba(255,255,255,.85)", marginBottom: 10 }}>{s.eyebrow}</div>
        <div className="display-lg" style={{
          color: "#fff", marginBottom: 14,
          textShadow: "0 2px 16px rgba(0,0,0,.2)",
          letterSpacing: "-.028em",
        }}>{s.title}</div>
        <div style={{
          fontSize: 16, lineHeight: 1.55, color: "rgba(255,255,255,.92)",
          maxWidth: 480,
        }}>{s.body}</div>
      </div>

      {/* Pagination + CTA */}
      <div style={{
        position: "relative", zIndex: 2,
        padding: "0 24px calc(env(safe-area-inset-bottom, 0px) + 28px)",
        display: "flex", flexDirection: "column", gap: 22,
        alignItems: "stretch",
      }}>
        <div style={{ display: "flex", justifyContent: "center", gap: 8 }}>
          {slides.map((_, i) => (
            <button key={i} aria-label={`עבור לשקף ${i + 1}`}
              onClick={() => { setIdx(i); if (window._haptic) window._haptic("tap"); }}
              style={{
                width: i === idx ? 28 : 8, height: 8, borderRadius: 9999,
                border: "none", padding: 0, cursor: "pointer",
                background: i === idx ? "#fff" : "rgba(255,255,255,.4)",
                transition: "width .3s var(--glass-ease), background .3s ease",
              }} />
          ))}
        </div>
        <button onClick={() => isLast ? finish() : (setIdx(idx + 1), window._haptic && window._haptic("tap"))} style={{
          padding: "16px 24px", borderRadius: 16,
          background: "#fff", color: "var(--ink)",
          border: "none", fontSize: 17, fontWeight: 700,
          fontFamily: "inherit", cursor: "pointer",
          boxShadow: "0 10px 28px -6px rgba(0,0,0,.35)",
          letterSpacing: "-.012em",
        }}>{isLast ? "בואו נתחיל" : "הבא"}</button>
      </div>
    </div>
  );
}

/* ─────────────────────────── exports ─────────────────────────── */

Object.assign(window, {
  HomeScreen, ItineraryScreen, MemoriesScreen, MemoryDetailScreen, AddMemoryScreen,
  OnboardingScreen, TripStatsScreen,
  // shared atoms for detail-screens.jsx
  I, Pill, CircleIcon, AvatarPair, SectionLabel, TabBar, RowMenu,
});
