/* SubMedium — mobile app (iOS). Reuses data.jsx + styles.css tokens. */
const { useState: useMS, useEffect: useME, useRef: useMR } = React;

/* ---------- atoms ---------- */
function MAvatar({ k, size = 20 }) {
  const s = SRC[k] || { name: k };
  return (
    <span title={s.name} style={{
      width: size, height: size, flex: "0 0 auto",
      display: "inline-flex", alignItems: "center", justifyContent: "center",
      fontFamily: "var(--mono)", fontWeight: 600, fontSize: size * 0.4,
      color: "var(--ink)", background: "var(--paper-2)",
      border: "1px solid var(--line)", borderRadius: 3,
    }}>{initials(s.name)}</span>
  );
}

function MStack({ sources = [], count }) {
  const shown = sources.slice(0, 3);
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
      <span style={{ display: "inline-flex" }}>
        {shown.map((s, i) => (
          <span key={i} style={{ marginLeft: i ? -5 : 0, zIndex: shown.length - i, position: "relative" }}>
            <MAvatar k={s.k} />
          </span>
        ))}
      </span>
      <span className="meta" style={{ color: "var(--ink-2)", fontWeight: 500, fontSize: 11.5 }}>
        {count || sources.length} sources
      </span>
    </span>
  );
}

function MMark() {
  return (
    <svg width="12" height="12" viewBox="0 0 12 12" style={{ flex: "0 0 auto" }}>
      <path d="M6 0 L7.4 4.6 L12 6 L7.4 7.4 L6 12 L4.6 7.4 L0 6 L4.6 4.6 Z" fill="var(--accent)" />
    </svg>
  );
}

function MLive() {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}>
      <span style={{ width: 6, height: 6, borderRadius: 6, background: "var(--down)", animation: "pulse 1.8s infinite" }} />
      <span className="meta" style={{ color: "var(--down)", fontWeight: 600, fontSize: 10 }}>LIVE</span>
    </span>
  );
}

function MImg({ h }) {
  return <div className="imgph" style={{ width: "100%", height: h }}><span className="credit">Wire photo</span></div>;
}

/* ---------- cards ---------- */
function MLead({ s, open }) {
  return (
    <article onClick={open} style={{ cursor: "pointer" }}>
      <MImg h={188} />
      <div style={{ padding: "13px 0 4px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
          <span className="kicker">{s.kicker}</span>
          {s.live && <MLive />}
        </div>
        <h2 className="hl" style={{ fontSize: 26, margin: "0 0 10px" }}>{s.headline}</h2>
        <div style={{ borderTop: "1px solid var(--line)", paddingTop: 10, display: "flex", gap: 7 }}>
          <MMark />
          <p style={{ margin: 0, fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 14.5, lineHeight: 1.45, color: "var(--ink-2)" }}>{s.brief}</p>
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 12 }}>
          <MStack sources={s.sources} count={s.sourceCount} />
          <span className="meta" style={{ fontSize: 11.5 }}>{s.time}</span>
        </div>
      </div>
    </article>
  );
}

function MCard({ s, open, thumb }) {
  return (
    <article onClick={open} style={{ display: "grid", gridTemplateColumns: thumb ? "1fr 96px" : "1fr", gap: 14, cursor: "pointer", padding: "16px 0", borderTop: "1px solid var(--line)" }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
          <span className="kicker">{s.kicker}</span>
          {s.live && <MLive />}
        </div>
        <h3 className="hl clamp-3" style={{ fontSize: 18, margin: "0 0 9px", fontWeight: 540 }}>{s.headline}</h3>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <MStack sources={s.sources} count={s.sourceCount} />
          <span className="meta" style={{ fontSize: 11 }}>{s.time}</span>
        </div>
      </div>
      {thumb && <div style={{ alignSelf: "stretch" }}><div className="imgph" style={{ width: 96, height: "100%", minHeight: 96 }} /></div>}
    </article>
  );
}

/* ---------- coverage spread ---------- */
function MSpread({ sources }) {
  const tags = {};
  sources.forEach((s) => { const t = (SRC[s.k] || {}).tag || "Other"; tags[t] = (tags[t] || 0) + 1; });
  const entries = Object.entries(tags);
  return (
    <div>
      <div style={{ display: "flex", height: 6, borderRadius: 4, overflow: "hidden", border: "1px solid var(--line)" }}>
        {entries.map(([t, n], i) => <div key={t} style={{ flex: n, background: `color-mix(in oklab, var(--accent) ${88 - i * 16}%, var(--paper-3))` }} />)}
      </div>
      <div style={{ display: "flex", flexWrap: "wrap", gap: "4px 12px", marginTop: 9 }}>
        {entries.map(([t, n]) => (
          <span key={t} className="meta" style={{ fontSize: 10.5, display: "inline-flex", alignItems: "center", gap: 5 }}>
            <span style={{ width: 6, height: 6, borderRadius: 2, background: "var(--accent)", opacity: 0.8 }} />{t} · {n}
          </span>
        ))}
      </div>
    </div>
  );
}

function MSourceRow({ s }) {
  const src = SRC[s.k] || { name: s.k };
  return (
    <article style={{ display: "grid", gridTemplateColumns: "auto 1fr", gap: 13, padding: "15px 0", borderTop: "1px solid var(--line)" }}>
      <MAvatar k={s.k} size={34} />
      <div style={{ minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4, flexWrap: "wrap" }}>
          <span style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 13, whiteSpace: "nowrap" }}>{src.name}</span>
          <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--ink-3)", border: "1px solid var(--line)", padding: "1px 5px", borderRadius: 2 }}>{src.tag}</span>
          <span className="meta" style={{ fontSize: 10.5, marginLeft: "auto" }}>{s.time}</span>
        </div>
        <h4 className="hl" style={{ fontSize: 15.5, margin: 0, fontWeight: 540 }}>{s.h}</h4>
      </div>
    </article>
  );
}

/* ---------- screens ---------- */
function MHeader({ section, setSection, query, setQuery, searching, setSearching }) {
  return (
    <div style={{ background: "var(--paper)", paddingTop: 54, boxShadow: "0 1px 0 var(--line-2)" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "6px 18px 10px" }}>
        <div style={{ display: "flex", alignItems: "baseline" }}>
          <span style={{ fontFamily: "var(--serif)", fontWeight: 620, fontSize: 23, letterSpacing: "-0.02em" }}>Sub</span>
          <span style={{ fontFamily: "var(--serif)", fontWeight: 620, fontSize: 23, letterSpacing: "-0.02em", color: "var(--accent)" }}>Medium</span>
          <span style={{ width: 5, height: 5, borderRadius: 5, background: "var(--accent)", marginLeft: 3, alignSelf: "flex-end", marginBottom: 5 }} />
        </div>
        <button onClick={() => setSearching(!searching)} style={{ background: "var(--paper-2)", border: "1px solid var(--line)", borderRadius: 999, width: 34, height: 34, display: "grid", placeItems: "center" }}>
          <svg width="16" height="16" viewBox="0 0 16 16"><circle cx="7" cy="7" r="5" fill="none" stroke="var(--ink-2)" strokeWidth="1.6"/><path d="M11 11l3.5 3.5" stroke="var(--ink-2)" strokeWidth="1.6" strokeLinecap="round"/></svg>
        </button>
      </div>
      {searching && (
        <div style={{ padding: "0 18px 10px" }}>
          <input autoFocus value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search every source…"
            style={{ width: "100%", font: "inherit", fontFamily: "var(--mono)", fontSize: 13, padding: "9px 12px", border: "1px solid var(--line)", background: "var(--paper-2)", color: "var(--ink)", borderRadius: 6, outline: "none", boxSizing: "border-box" }} />
        </div>
      )}
      <div style={{ display: "flex", gap: 4, overflowX: "auto", padding: "0 18px 10px", scrollbarWidth: "none" }}>
        {SECTIONS.map((s) => {
          const active = s === section;
          return (
            <button key={s} onClick={() => setSection(s)} style={{
              flex: "0 0 auto", background: active ? "var(--ink)" : "transparent",
              color: active ? "var(--paper)" : "var(--ink-2)",
              border: "1px solid " + (active ? "var(--ink)" : "var(--line)"),
              borderRadius: 999, padding: "5px 13px", fontSize: 13, fontWeight: active ? 600 : 450,
            }}>{s}</button>
          );
        })}
      </div>
      <hr className="rule" />
    </div>
  );
}

function MFeed({ section, query, open, searching, setSearching, setSection, setQuery }) {
  let list = STORIES;
  if (section !== "Top") list = STORIES.filter((s) => s.section === section);
  if (query.trim()) { const q = query.toLowerCase(); list = STORIES.filter((s) => (s.headline + s.dek + s.kicker).toLowerCase().includes(q)); }
  const data = list.length ? list : STORIES;
  const [lead, ...rest] = data;
  return (
    <>
      <MHeader section={section} setSection={setSection} query={query} setQuery={setQuery} searching={searching} setSearching={setSearching} />
      <div style={{ padding: "16px 18px 28px" }}>
        {query.trim() && <div className="meta" style={{ marginBottom: 12 }}>{data.length} results for “{query}”</div>}
        <MLead s={lead} open={() => open(lead)} />
        <div style={{ marginTop: 8 }}>
          {rest.map((s, i) => <MCard key={s.id} s={s} open={() => open(s)} thumb={s.image} />)}
        </div>
      </div>
    </>
  );
}

function MCluster({ s, back, open }) {
  const ref = useMR(null);
  useME(() => { if (ref.current) ref.current.scrollTop = 0; }, [s.id]);
  const related = STORIES.filter((x) => x.section === s.section && x.id !== s.id).slice(0, 3);
  return (
    <div ref={ref} style={{ height: "100%", overflowY: "auto" }}>
      <div style={{ position: "sticky", top: 0, zIndex: 5, background: "color-mix(in oklab, var(--paper) 88%, transparent)", backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)", paddingTop: 52 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 18px 10px" }}>
          <button onClick={back} style={{ background: "var(--paper-2)", border: "1px solid var(--line)", borderRadius: 999, width: 34, height: 34, display: "grid", placeItems: "center" }}>
            <svg width="16" height="16" viewBox="0 0 16 16"><path d="M10 2L4 8l6 6" stroke="var(--ink)" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
          </button>
          <span className="meta" style={{ fontSize: 11.5 }}>{s.sourceCount} sources · updated {s.time} ago</span>
        </div>
        <hr className="rule" />
      </div>

      <div style={{ padding: "16px 18px 30px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 10 }}>
          <span className="kicker">{s.kicker}</span>{s.live && <MLive />}
        </div>
        <h1 className="hl" style={{ fontSize: 28, margin: "0 0 12px" }}>{s.headline}</h1>
        <p className="dek" style={{ fontSize: 17, margin: "0 0 18px" }}>{s.dek}</p>
        {s.image && <div style={{ marginBottom: 18 }}><MImg h={196} /></div>}

        <div style={{ background: "var(--paper-2)", border: "1px solid var(--line)", borderRadius: 6, padding: "16px 16px", marginBottom: 24 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 10, flexWrap: "wrap" }}>
            <MMark /><span className="kicker" style={{ color: "var(--ink)" }}>The Brief</span>
            <span className="meta" style={{ fontSize: 10 }}>· from {s.sourceCount} sources</span>
          </div>
          <p style={{ margin: "0 0 14px", fontFamily: "var(--serif)", fontSize: 16.5, lineHeight: 1.5, color: "var(--ink)" }}>{s.brief}</p>
          <MSpread sources={s.sources} />
        </div>

        <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 2, gap: 12 }}>
          <h2 style={{ fontFamily: "var(--serif)", fontSize: 19, fontWeight: 600, margin: 0, whiteSpace: "nowrap" }}>All coverage</h2>
          <span className="meta" style={{ fontSize: 10.5, whiteSpace: "nowrap" }}>newest first</span>
        </div>
        {s.sources.map((src, i) => <MSourceRow key={i} s={src} />)}
        {s.sourceCount > s.sources.length && (
          <div style={{ borderTop: "1px solid var(--line)", paddingTop: 15 }}>
            <button style={{ fontFamily: "var(--sans)", fontSize: 13, fontWeight: 500, color: "var(--accent-2)", background: "none", border: 0, padding: 0 }}>Show {s.sourceCount - s.sources.length} more sources →</button>
          </div>
        )}

        {related.length > 0 && (
          <div style={{ marginTop: 26 }}>
            <div className="kicker" style={{ marginBottom: 2 }}>More in {s.section}</div>
            {related.map((r) => <MCard key={r.id} s={r} open={() => open(r)} />)}
          </div>
        )}
      </div>
    </div>
  );
}

function MForYou({ open }) {
  return (
    <div style={{ height: "100%", overflowY: "auto" }}>
      <div style={{ background: "var(--paper)", paddingTop: 54, boxShadow: "0 1px 0 var(--line-2)" }}>
        <div style={{ padding: "6px 18px 12px" }}>
          <h1 className="hl" style={{ fontSize: 30, margin: "0 0 4px" }}>For You</h1>
          <span className="meta" style={{ fontSize: 11.5 }}>Ranked across {TOPICS.length} topics · refreshed 4 min ago</span>
        </div>
        <hr className="rule" />
      </div>
      <div style={{ padding: "16px 18px 30px" }}>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 7, marginBottom: 22 }}>
          {TOPICS.map((t) => <span key={t} style={{ fontFamily: "var(--sans)", fontSize: 12.5, padding: "6px 12px", border: "1px solid var(--line)", borderRadius: 999, color: "var(--ink-2)", background: "var(--paper-2)" }}>{t}</span>)}
          <span style={{ fontFamily: "var(--sans)", fontSize: 12.5, padding: "6px 12px", border: "1px dashed var(--accent)", borderRadius: 999, color: "var(--accent-2)", fontWeight: 500 }}>+ Add</span>
        </div>

        <div style={{ background: "var(--ink)", color: "var(--paper)", borderRadius: 8, padding: "16px 16px", marginBottom: 22 }}>
          <div className="kicker" style={{ color: "var(--accent-2)", marginBottom: 7 }}>Your Daily Brief</div>
          <p style={{ fontFamily: "var(--serif)", fontSize: 16, lineHeight: 1.45, margin: "0 0 14px", opacity: 0.92 }}>One AI-synthesized digest of everything you follow, ready by 6am.</p>
          <button style={{ background: "var(--paper)", color: "var(--ink)", border: 0, borderRadius: 6, padding: "9px 16px", fontSize: 13.5, fontWeight: 600, width: "100%" }}>Turn on morning digest</button>
        </div>

        <div className="kicker" style={{ marginBottom: 2 }}>Top of your feed</div>
        {STORIES.slice(0, 5).map((s) => <MCard key={s.id} s={s} open={() => open(s)} thumb={s.image} />)}
      </div>
    </div>
  );
}

/* ---------- tab bar ---------- */
function TabBar({ tab, setTab }) {
  const items = [
    { k: "feed", label: "Today", icon: (a) => <path d="M3 4h14M3 9h14M3 14h9" stroke={a} strokeWidth="1.8" strokeLinecap="round"/> },
    { k: "foryou", label: "For You", icon: (a) => <path d="M10 2.5l2 4 4.4.6-3.2 3.1.8 4.3L10 12.6 6.2 14.5l.8-4.3L3.8 7.1 8 6.5z" fill="none" stroke={a} strokeWidth="1.6" strokeLinejoin="round"/> },
    { k: "search", label: "Search", icon: (a) => <g><circle cx="9" cy="9" r="5.5" fill="none" stroke={a} strokeWidth="1.8"/><path d="M13.5 13.5L17 17" stroke={a} strokeWidth="1.8" strokeLinecap="round"/></g> },
    { k: "saved", label: "Saved", icon: (a) => <path d="M5 3h10v14l-5-3.5L5 17z" fill="none" stroke={a} strokeWidth="1.7" strokeLinejoin="round"/> },
  ];
  return (
    <div style={{ flex: "0 0 auto", borderTop: "1px solid var(--line)", background: "color-mix(in oklab, var(--paper) 92%, transparent)", backdropFilter: "blur(10px)", WebkitBackdropFilter: "blur(10px)", paddingBottom: 26 }}>
      <div style={{ display: "flex" }}>
        {items.map((it) => {
          const active = tab === it.k;
          const col = active ? "var(--accent-2)" : "var(--ink-3)";
          return (
            <button key={it.k} onClick={() => setTab(it.k)} style={{ flex: 1, background: "none", border: 0, padding: "9px 0 4px", display: "flex", flexDirection: "column", alignItems: "center", gap: 3 }}>
              <svg width="20" height="20" viewBox="0 0 20 20">{it.icon(col)}</svg>
              <span style={{ fontFamily: "var(--sans)", fontSize: 10.5, fontWeight: active ? 600 : 450, color: col }}>{it.label}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- app ---------- */
const M_ACCENTS = [
  { name: "Amber", c: "#BE530F" }, { name: "Cobalt", c: "#1F4FB0" },
  { name: "Oxblood", c: "#8E2A24" }, { name: "Forest", c: "#1E6B47" }, { name: "Ink", c: "#2A2722" },
];
const M_DEFAULTS = /*EDITMODE-BEGIN*/{ "edition": "day", "accent": "#BE530F" }/*EDITMODE-END*/;

function MobileApp() {
  const [t, setTweak] = useTweaks(M_DEFAULTS);
  const [tab, setTab] = useMS("feed");
  const [section, setSection] = useMS("Top");
  const [query, setQuery] = useMS("");
  const [searching, setSearching] = useMS(false);
  const [active, setActive] = useMS(null);
  const night = t.edition === "night";

  useME(() => {
    document.documentElement.setAttribute("data-edition", t.edition);
    document.documentElement.style.setProperty("--accent", t.accent);
  }, [t.edition, t.accent]);

  const open = (s) => setActive(s);

  let screen;
  if (active) screen = <MCluster s={active} back={() => setActive(null)} open={open} />;
  else if (tab === "feed" || tab === "search") screen = (
    <MFeed section={section} query={query} open={open}
      searching={searching || tab === "search"} setSearching={setSearching}
      setSection={setSection} setQuery={setQuery} />
  );
  else if (tab === "foryou") screen = <MForYou open={open} />;
  else screen = <MSaved open={open} />;

  return (
    <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", padding: "40px 16px" }}>
      <IOSDevice dark={night}>
        <div style={{ height: "100%", display: "flex", flexDirection: "column", background: "var(--paper)" }}>
          <div style={{ flex: 1, overflowY: "auto", WebkitOverflowScrolling: "touch" }}>
            {screen}
          </div>
          {!active && <TabBar tab={tab === "search" ? "search" : tab} setTab={(k) => { setActive(null); if (k === "search") { setSearching(true); setTab("feed"); } else setTab(k); }} />}
        </div>
      </IOSDevice>

      <TweaksPanel>
        <TweakSection label="Edition" />
        <TweakRadio label="Theme" value={t.edition} options={["day", "night"]} onChange={(v) => setTweak("edition", v)} />
        <TweakSection label="Brand accent" />
        <TweakColor label="Accent" value={t.accent} options={M_ACCENTS.map((a) => a.c)} onChange={(v) => setTweak("accent", v)} />
      </TweaksPanel>
    </div>
  );
}

function MSaved({ open }) {
  return (
    <div style={{ height: "100%", overflowY: "auto" }}>
      <div style={{ background: "var(--paper)", paddingTop: 54, boxShadow: "0 1px 0 var(--line-2)" }}>
        <div style={{ padding: "6px 18px 12px" }}>
          <h1 className="hl" style={{ fontSize: 30, margin: "0 0 4px" }}>Saved</h1>
          <span className="meta" style={{ fontSize: 11.5 }}>Read later · synced across devices</span>
        </div>
        <hr className="rule" />
      </div>
      <div style={{ padding: "16px 18px 30px" }}>
        {STORIES.slice(2, 5).map((s) => <MCard key={s.id} s={s} open={() => open(s)} thumb={s.image} />)}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<MobileApp />);
