/* Shared primitives for all SCOTUSWatch site variations */

// ---------- Real app icons ----------
// SCOTUSWatch ships a light/dark icon pair (used on iOS and Android).
// The tan/blue icon is for light mode; the navy/gold icon is for dark mode.
// The Windows app uses the light variant only.
const SCOTUSIcon = ({ size = 64, radius = 14, theme = "light", forceVariant }) => {
  const variant = forceVariant ?? (theme === "dark" ? "dark" : "light");
  const src = variant === "dark"
    ? "assets/icon-scotuswatch-android.png"  // navy + gold (dark mode pair)
    : "assets/icon-scotuswatch-ios.png";     // tan + blue (light mode pair)
  return (
    <img
      src={src}
      alt="SCOTUSWatch"
      width={size}
      height={size}
      style={{
        width: size, height: size,
        borderRadius: radius,
        flexShrink: 0,
        display: "block",
        objectFit: "cover",
      }}
    />
  );
};

const MyNewMusicIcon = ({ size = 48 }) => (
  <img src="assets/icon-mynewmusic.png" alt="My New Music" width={size} height={size}
       style={{ width: size, height: size, borderRadius: size * 0.22, flexShrink: 0, display: "block" }} />
);

const VigilIcon = ({ size = 48 }) => (
  <img src="assets/icon-vigil.png" alt="Vigil Auto Refresh" width={size} height={size}
       style={{ width: size, height: size, borderRadius: size * 0.22, flexShrink: 0, display: "block" }} />
);

// ---------- iPhone frame with rotating screenshot slot ----------
const IPhoneFrame = ({
  width = 280,
  tilt = 0,
  children,
  shadow = true,
  bezel = "#1a1a1c",
}) => {
  const height = width * 2.06;
  return (
    <div
      style={{
        width,
        height,
        borderRadius: width * 0.16,
        background: bezel,
        padding: width * 0.025,
        transform: `rotate(${tilt}deg)`,
        boxShadow: shadow
          ? "0 30px 60px -15px rgba(0,0,0,0.55), 0 10px 25px -10px rgba(0,0,0,0.4)"
          : "none",
        position: "relative",
        flexShrink: 0,
      }}
    >
      <div
        style={{
          width: "100%",
          height: "100%",
          borderRadius: width * 0.135,
          background: "#000",
          overflow: "hidden",
          position: "relative",
        }}
      >
        {/* Dynamic island */}
        <div
          style={{
            position: "absolute",
            top: width * 0.035,
            left: "50%",
            transform: "translateX(-50%)",
            width: width * 0.32,
            height: width * 0.085,
            borderRadius: width * 0.05,
            background: "#000",
            zIndex: 5,
          }}
        />
        {children}
      </div>
    </div>
  );
};

// ---------- Android (Pixel-style) frame ----------
const AndroidFrame = ({ width = 280, tilt = 0, children, bezel = "#1a1a1c" }) => {
  const height = width * 2.16;
  return (
    <div
      style={{
        width,
        height,
        borderRadius: width * 0.11,
        background: bezel,
        padding: width * 0.022,
        transform: `rotate(${tilt}deg)`,
        boxShadow: "0 30px 60px -15px rgba(0,0,0,0.55), 0 10px 25px -10px rgba(0,0,0,0.4)",
        flexShrink: 0,
      }}
    >
      <div
        style={{
          width: "100%",
          height: "100%",
          borderRadius: width * 0.095,
          background: "#000",
          overflow: "hidden",
          position: "relative",
        }}
      >
        {/* Punch-hole camera */}
        <div
          style={{
            position: "absolute",
            top: width * 0.04,
            left: "50%",
            transform: "translateX(-50%)",
            width: width * 0.05,
            height: width * 0.05,
            borderRadius: "50%",
            background: "#0a0a0a",
            zIndex: 5,
            boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.08)",
          }}
        />
        {children}
      </div>
    </div>
  );
};

// ---------- Real screenshot wrapper (used when we have actual captures) ----------
const RealScreenshot = ({ src, alt }) => (
  <img
    src={src}
    alt={alt || ""}
    style={{
      width: "100%",
      height: "100%",
      objectFit: "cover",
      objectPosition: "top",
      display: "block",
    }}
  />
);

// ---------- Mock screenshot content (rotating) ----------
const MockScreenshot = ({ kind, theme = "dark" }) => {
  const bg = theme === "dark" ? "#0a0a0d" : "#f4f4f7";
  const card = theme === "dark" ? "#16161b" : "#ffffff";
  const text = theme === "dark" ? "#f0f0f0" : "#111";
  const muted = theme === "dark" ? "#888" : "#666";
  const accent = "#0a84ff";
  const border = theme === "dark" ? "#26262c" : "#e5e5ea";

  const Wrap = ({ children }) => (
    <div style={{
      width: "100%", height: "100%", background: bg, color: text,
      fontFamily: "Geist, -apple-system, BlinkMacSystemFont, system-ui, sans-serif",
      paddingTop: "12%", display: "flex", flexDirection: "column",
    }}>
      {children}
    </div>
  );

  if (kind === "feed") {
    return (
      <Wrap>
        <div style={{ padding: "0 5% 4%", borderBottom: `1px solid ${border}` }}>
          <div style={{ fontSize: 9, color: muted, fontWeight: 600, letterSpacing: 0.5, textTransform: "uppercase" }}>SCOTUSWatch</div>
          <div style={{ fontSize: 17, fontWeight: 700, marginTop: 2 }}>Recent Activity</div>
        </div>
        <div style={{ padding: "5%", display: "flex", flexDirection: "column", gap: "4%" }}>
          {[
            { tag: "OPINION", t: "Trump v. CASA, Inc.", s: "6–3 · Roberts, C.J." },
            { tag: "ORDER LIST", t: "Orders of Oct 6, 2025", s: "Cert granted in 4 cases" },
            { tag: "STAY", t: "In re Application 25A234", s: "Stay granted pending appeal" },
            { tag: "OPINION", t: "Loper Bright Enterprises", s: "Chevron overruled" },
          ].map((it, i) => (
            <div key={i} style={{ background: card, border: `1px solid ${border}`, borderRadius: 10, padding: "4% 5%" }}>
              <div style={{ fontSize: 8, color: accent, fontWeight: 700, letterSpacing: 0.6 }}>{it.tag}</div>
              <div style={{ fontSize: 11, fontWeight: 600, marginTop: 2, lineHeight: 1.25 }}>{it.t}</div>
              <div style={{ fontSize: 9, color: muted, marginTop: 3 }}>{it.s}</div>
            </div>
          ))}
        </div>
      </Wrap>
    );
  }

  if (kind === "notification") {
    return (
      <div style={{
        width: "100%", height: "100%",
        background: "linear-gradient(180deg, #1c1c2a 0%, #0f0f1a 100%)",
        position: "relative",
        fontFamily: "Geist, -apple-system, system-ui, sans-serif",
      }}>
        <div style={{ position: "absolute", top: "8%", left: 0, right: 0, textAlign: "center", color: "#fff" }}>
          <div style={{ fontSize: 56, fontWeight: 200, letterSpacing: -2 }}>10:04</div>
          <div style={{ fontSize: 11, opacity: 0.8, marginTop: -4 }}>Monday, June 30</div>
        </div>
        <div style={{ position: "absolute", top: "32%", left: "5%", right: "5%", display: "flex", flexDirection: "column", gap: 8 }}>
          {[
            { t: "SCOTUSWatch", s: "New Opinion: Department of State v. AAUP", time: "now" },
            { t: "SCOTUSWatch", s: "Order List published — 12 cases", time: "9:30 AM" },
          ].map((n, i) => (
            <div key={i} style={{
              background: "rgba(255,255,255,0.16)",
              backdropFilter: "blur(20px)",
              borderRadius: 14, padding: "10px 12px",
              color: "#fff",
              boxShadow: "0 1px 0 rgba(255,255,255,0.05) inset",
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
                <div style={{ width: 16, height: 16, borderRadius: 4, background: "#0a1e3d", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
                  <div style={{ width: 8, height: 8, borderRadius: 1, background: "#fff" }} />
                </div>
                <div style={{ fontSize: 9, fontWeight: 600, flex: 1 }}>{n.t}</div>
                <div style={{ fontSize: 8, opacity: 0.7 }}>{n.time}</div>
              </div>
              <div style={{ fontSize: 10, lineHeight: 1.35 }}>{n.s}</div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  if (kind === "opinion") {
    return (
      <Wrap>
        <div style={{ padding: "0 5% 4%", borderBottom: `1px solid ${border}` }}>
          <div style={{ fontSize: 9, color: accent, fontWeight: 700, letterSpacing: 0.6, textTransform: "uppercase" }}>Opinion · Slip Op.</div>
          <div style={{ fontSize: 14, fontWeight: 700, marginTop: 4, lineHeight: 1.2 }}>Trump v. CASA, Inc.</div>
          <div style={{ fontSize: 9, color: muted, marginTop: 4 }}>No. 24A884 · Decided June 27, 2025</div>
        </div>
        <div style={{ padding: "5%", fontSize: 9, lineHeight: 1.5, color: text, opacity: 0.85 }}>
          <div style={{ fontStyle: "italic", marginBottom: 6, opacity: 0.7 }}>Syllabus</div>
          <p style={{ marginBottom: 6 }}>The Government applied for partial stays of three preliminary injunctions issued by district courts blocking enforcement of Executive Order No. 14160…</p>
          <p style={{ marginBottom: 6 }}>Held: The applications for partial stays are granted, but only to the extent that the injunctions are broader than necessary…</p>
          <div style={{ marginTop: "6%", padding: "4%", background: card, border: `1px solid ${border}`, borderRadius: 8 }}>
            <div style={{ fontSize: 8, color: accent, fontWeight: 700, letterSpacing: 0.6 }}>AI SUMMARY</div>
            <div style={{ fontSize: 9, marginTop: 4, lineHeight: 1.45 }}>The Court partially granted the stays, narrowing the scope of nationwide injunctions while preserving relief for the named plaintiffs.</div>
          </div>
        </div>
      </Wrap>
    );
  }

  if (kind === "watched") {
    return (
      <Wrap>
        <div style={{ padding: "0 5% 4%", borderBottom: `1px solid ${border}`, display: "flex", alignItems: "baseline", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontSize: 9, color: muted, fontWeight: 600, letterSpacing: 0.5, textTransform: "uppercase" }}>Watched Cases</div>
            <div style={{ fontSize: 15, fontWeight: 700, marginTop: 2 }}>4 dockets</div>
          </div>
          <div style={{ fontSize: 18, color: accent, fontWeight: 300 }}>＋</div>
        </div>
        <div style={{ padding: "5%", display: "flex", flexDirection: "column", gap: "3.5%" }}>
          {[
            { n: "24-878", t: "Smith v. Arizona", s: "Cert granted · Oct 6", live: true },
            { n: "24-901", t: "United States v. Skrmetti", s: "New filing · 2d ago", live: true },
            { n: "24-1006", t: "FDA v. Wages and White Lion", s: "CVSG pending", live: false },
            { n: "23-1141", t: "Diamond Alternative Energy", s: "GVR · Apr 28", live: false },
          ].map((c, i) => (
            <div key={i} style={{ background: card, border: `1px solid ${border}`, borderRadius: 10, padding: "3.5% 4.5%" }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                <div style={{ fontSize: 8, color: muted, fontFamily: "ui-monospace, monospace" }}>{c.n}</div>
                {c.live && <div style={{ width: 6, height: 6, borderRadius: "50%", background: "#22c55e" }} />}
              </div>
              <div style={{ fontSize: 11, fontWeight: 600, marginTop: 3, fontStyle: "italic" }}>{c.t}</div>
              <div style={{ fontSize: 9, color: muted, marginTop: 2 }}>{c.s}</div>
            </div>
          ))}
        </div>
      </Wrap>
    );
  }

  if (kind === "docket") {
    return (
      <Wrap>
        <div style={{ padding: "0 5% 4%", borderBottom: `1px solid ${border}` }}>
          <div style={{ fontSize: 8, color: muted, fontFamily: "ui-monospace, monospace" }}>NO. 24-878</div>
          <div style={{ fontSize: 13, fontWeight: 700, marginTop: 3, fontStyle: "italic", lineHeight: 1.2 }}>Smith v. Arizona</div>
          <div style={{ fontSize: 9, color: accent, marginTop: 4, fontWeight: 600 }}>● Cert granted</div>
        </div>
        <div style={{ padding: "4% 5%", fontSize: 9 }}>
          <div style={{ color: muted, fontWeight: 600, letterSpacing: 0.5, fontSize: 8, textTransform: "uppercase", marginBottom: 6 }}>Docket Entries</div>
          {[
            { d: "Oct 6", t: "Petition GRANTED.", h: true },
            { d: "Sep 30", t: "Reply of petitioner filed." },
            { d: "Aug 12", t: "Brief of respondent filed." },
            { d: "Jul 2",  t: "Petition for writ of certiorari filed." },
            { d: "Jun 14", t: "Application for extension of time granted." },
          ].map((e, i) => (
            <div key={i} style={{ display: "flex", gap: 8, padding: "5px 0", borderTop: i ? `1px solid ${border}` : "none" }}>
              <div style={{ fontSize: 8, color: muted, width: 32, fontFamily: "ui-monospace, monospace", flexShrink: 0 }}>{e.d}</div>
              <div style={{ fontSize: 9, lineHeight: 1.35, fontWeight: e.h ? 600 : 400, color: e.h ? accent : text }}>{e.t}</div>
            </div>
          ))}
        </div>
      </Wrap>
    );
  }

  return <Wrap><div style={{ padding: "5%" }}>—</div></Wrap>;
};

// ---------- Rotating screenshot ----------
// Items can be either:
//   - a string keyword (uses MockScreenshot)
//   - { src: "path.png", alt: "..." } (uses RealScreenshot)
const RotatingScreenshot = ({ kinds, theme = "dark", interval = 2800 }) => {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setI((x) => (x + 1) % kinds.length), interval);
    return () => clearInterval(id);
  }, [kinds.length, interval]);
  return (
    <div style={{ width: "100%", height: "100%", position: "relative" }}>
      {kinds.map((k, idx) => (
        <div key={(typeof k === "string" ? k : k.src) + idx} style={{
          position: "absolute", inset: 0,
          opacity: idx === i ? 1 : 0,
          transition: "opacity 600ms ease",
        }}>
          {typeof k === "string"
            ? <MockScreenshot kind={k} theme={theme} />
            : <RealScreenshot src={k.src} alt={k.alt} />}
        </div>
      ))}
    </div>
  );
};

// ---------- Walkthrough video ----------
// Replace `src` with the real GitHub URL (release asset or raw file) when ready.
// If `src` is empty/missing, falls back to a static screenshot + play badge so
// the layout still looks complete.
const WalkthroughVideo = ({ src, poster, fallbackImg, label }) => {
  const [failed, setFailed] = React.useState(!src);
  return (
    <div style={{
      position: "relative",
      aspectRatio: "9 / 19.5",
      maxWidth: 280,
      width: "100%",
      borderRadius: 24,
      overflow: "hidden",
      background: "#000",
      boxShadow: "0 30px 60px -15px rgba(0,0,0,0.55), 0 10px 25px -10px rgba(0,0,0,0.4)",
    }}>
      {!failed && src ? (
        <video
          src={src}
          poster={poster}
          autoPlay
          muted
          loop
          playsInline
          preload="metadata"
          onError={() => setFailed(true)}
          style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
        />
      ) : (
        <div style={{ width: "100%", height: "100%", position: "relative" }}>
          {fallbackImg && (
            <img src={fallbackImg} alt={label || "walkthrough"}
                 style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "top", display: "block" }} />
          )}
          <div style={{
            position: "absolute", inset: 0,
            display: "flex", alignItems: "center", justifyContent: "center",
            background: "linear-gradient(180deg, transparent 40%, rgba(0,0,0,0.45) 100%)",
          }}>
            <div style={{
              width: 72, height: 72, borderRadius: "50%",
              background: "rgba(255,255,255,0.92)",
              display: "flex", alignItems: "center", justifyContent: "center",
              boxShadow: "0 8px 24px rgba(0,0,0,0.3)",
            }}>
              <svg viewBox="0 0 24 24" width="32" height="32" fill="#0a84ff">
                <path d="M8 5v14l11-7z" />
              </svg>
            </div>
          </div>
          {!src && (
            <div style={{
              position: "absolute", bottom: 12, left: 12, right: 12,
              padding: "8px 10px",
              background: "rgba(0,0,0,0.6)",
              backdropFilter: "blur(8px)",
              borderRadius: 8,
              color: "#fff", fontSize: 11, textAlign: "center",
              fontFamily: "ui-monospace, monospace",
            }}>📹 video coming soon</div>
          )}
        </div>
      )}
    </div>
  );
};

// Convenience: real screenshots we have on disk.
const AndroidShots = {
  documents: { src: "assets/android-documents.png", alt: "Documents tab" },
  summary:   { src: "assets/android-summary.png",   alt: "AI Summary view" },
  archive:   { src: "assets/android-archive.png",   alt: "Archive search" },
  cases:     { src: "assets/android-cases.png",     alt: "Watched Cases" },
  docket:    { src: "assets/android-docket.png",    alt: "Docket entries" },
};
const IOSShots = {
  documents: { src: "assets/ios-documents.png", alt: "Documents" },
  archive:   { src: "assets/ios-archive.png",   alt: "Archive" },
  cases:     { src: "assets/ios-cases.png",     alt: "Watched Cases" },
  docket:    { src: "assets/ios-docket.png",    alt: "Docket Timeline" },
  summary:   { src: "assets/ios-summary.png",   alt: "AI Summary" },
};

// ---------- Bluesky live feed ----------
// Fetches recent posts from @scotuswatch.bsky.social via the public AT Protocol
// API (no auth required) and renders them inline. Updates every page load.
const BlueskyEmbed = ({ theme = "dark", handle = "scotuswatch.bsky.social", limit = 5 }) => {
  const [posts, setPosts] = React.useState(null);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    const url = `https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${encodeURIComponent(handle)}&limit=${limit}&filter=posts_no_replies`;
    fetch(url)
      .then(r => r.ok ? r.json() : Promise.reject(`HTTP ${r.status}`))
      .then(data => setPosts(data.feed || []))
      .catch(e => setError(String(e)));
  }, [handle, limit]);

  const c = theme === "dark"
    ? { bg: "#16161b", border: "#26262c", text: "#f0f0f3", muted: "#888892", card: "#0e0e12" }
    : { bg: "#ffffff", border: "#e5e5ea", text: "#111114", muted: "#666670", card: "#fafafa" };

  const fmtTime = (iso) => {
    if (!iso) return "";
    const d = new Date(iso);
    const diff = (Date.now() - d.getTime()) / 1000;
    if (diff < 60) return "now";
    if (diff < 3600) return `${Math.floor(diff/60)}m`;
    if (diff < 86400) return `${Math.floor(diff/3600)}h`;
    if (diff < 86400 * 7) return `${Math.floor(diff/86400)}d`;
    return d.toLocaleDateString(undefined, { month: "short", day: "numeric" });
  };

  return (
    <div style={{
      background: c.bg,
      border: `1px solid ${c.border}`,
      borderRadius: 14,
      padding: 20,
      maxHeight: 560,
      overflowY: "auto",
      color: c.text,
    }}>
      {/* Profile header */}
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
        <div style={{
          width: 36, height: 36, borderRadius: "50%",
          background: "#0a1e3d", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
        }}>
          <svg viewBox="0 0 360 320" width="20" height="20"><path d="M180 141.964C163.699 110.262 119.326 49.825 78.857 28.814C50.738 14.419 0 6.980 0 59.371c0 10.783 6.114 90.716 9.696 103.659 12.496 44.695 57.978 56.149 98.179 49.227-76.894 13.118-96.500 56.990-54.241 100.862 79.893 81.955 114.821-20.565 123.366-47.134 8.545 26.569 43.473 129.089 123.366 47.134 42.259-43.872 22.653-87.744-54.241-100.862 40.201 6.922 85.683-4.532 98.179-49.227C351.886 150.087 358 70.154 358 59.371 358 6.980 307.262 14.419 279.143 28.814 238.674 49.825 196.301 110.262 180 141.964z" fill="#0085ff"/></svg>
        </div>
        <div>
          <div style={{ fontWeight: 600, fontSize: 14 }}>SCOTUSWatch</div>
          <div style={{ fontSize: 12, color: c.muted }}>@{handle}</div>
        </div>
        <a
          href={`https://bsky.app/profile/${handle}`}
          target="_blank"
          rel="noopener noreferrer"
          style={{
            marginLeft: "auto",
            background: "#0085ff", color: "#fff",
            fontSize: 12, fontWeight: 600,
            padding: "6px 12px", borderRadius: 999,
            textDecoration: "none",
          }}
        >Follow</a>
      </div>

      {posts === null && !error && (
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {[0, 1, 2].map(i => (
            <div key={i} style={{
              padding: "12px 14px",
              background: c.card,
              border: `1px solid ${c.border}`,
              borderRadius: 10,
              opacity: 0.5,
            }}>
              <div style={{ height: 10, width: "80%", background: c.border, borderRadius: 4, marginBottom: 8 }} />
              <div style={{ height: 10, width: "60%", background: c.border, borderRadius: 4 }} />
            </div>
          ))}
        </div>
      )}

      {error && (
        <div style={{ fontSize: 13, color: c.muted, padding: 12, textAlign: "center" }}>
          Couldn't load posts.{" "}
          <a href={`https://bsky.app/profile/${handle}`} target="_blank" rel="noopener noreferrer" style={{ color: "#0085ff" }}>
            View on Bluesky →
          </a>
        </div>
      )}

      {posts && posts.length > 0 && (
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {posts.map((item, i) => {
            const p = item.post;
            const text = (p?.record?.text || "").trim();
            const when = fmtTime(p?.record?.createdAt || p?.indexedAt);
            const uri = p?.uri || "";
            const rkey = uri.split("/").pop();
            const link = `https://bsky.app/profile/${handle}/post/${rkey}`;
            return (
              <a key={p?.cid || i} href={link} target="_blank" rel="noopener noreferrer"
                 style={{
                   padding: "12px 14px",
                   background: c.card,
                   border: `1px solid ${c.border}`,
                   borderRadius: 10,
                   fontSize: 13,
                   lineHeight: 1.45,
                   textDecoration: "none",
                   color: c.text,
                   display: "block",
                 }}>
                <div style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{text}</div>
                <div style={{ fontSize: 11, color: c.muted, marginTop: 8, display: "flex", gap: 12 }}>
                  <span>{when}</span>
                  {p?.replyCount > 0 && <span>💬 {p.replyCount}</span>}
                  {p?.repostCount > 0 && <span>🔁 {p.repostCount}</span>}
                  {p?.likeCount > 0 && <span>♥ {p.likeCount}</span>}
                </div>
              </a>
            );
          })}
        </div>
      )}

      {posts && posts.length === 0 && !error && (
        <div style={{ fontSize: 13, color: c.muted, padding: 12, textAlign: "center" }}>No posts yet.</div>
      )}
    </div>
  );
};

// ---------- Pill, UpcomingCallout, OtherAppCard helpers ----------
const Pill = ({ children, bg, fg, border }) => (
  <span style={{ fontSize: 12, background: bg, color: fg, border: `1px solid ${border}`, borderRadius: 999, padding: "4px 10px", fontWeight: 600 }}>{children}</span>
);

const UpcomingCallout = ({ c }) => (
  <div style={{
    marginTop: 8,
    padding: "10px 12px",
    background: `linear-gradient(135deg, ${c.accent}18, ${c.accent}05)`,
    border: `1px solid ${c.accent}40`,
    borderRadius: 10,
    fontSize: 13,
    color: c.text,
  }}>
    <strong style={{ color: c.accent }}>New: Watched Cases.</strong>{" "}
    <span style={{ opacity: 0.8 }}>Monitor any docket — get notified of new filings, cert grants/denials, CVSGs, GVRs, and motion rulings. Available now in the Android APK and on iOS via TestFlight (v2.0); arriving on Google Play and the App Store after store review.</span>
  </div>
);

const OtherAppCard = ({ c, icon, title, platform, desc, price, url }) => (
  <div style={{
    background: c.surface, border: `1px solid ${c.border}`,
    borderRadius: 12, padding: "18px 20px",
    display: "flex", flexDirection: "column", gap: 10,
  }}>
    <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
      {icon}
      <div>
        <div style={{ fontSize: 15, fontWeight: 600 }}>{title}</div>
        <div style={{ fontSize: 12, color: c.muted, marginTop: 2 }}>{platform}</div>
      </div>
    </div>
    <p style={{ fontSize: 13, color: c.muted, lineHeight: 1.5, margin: 0 }}>{desc}</p>
    <div style={{ display: "flex", gap: 8, alignItems: "center", marginTop: 4 }}>
      <Pill bg="#1a2a3a" fg="#64b5f6" border="#1e3a5a">{price}</Pill>
      <a href={url} target="_blank" rel="noopener noreferrer" style={{ background: c.accent, color: "#fff", padding: "6px 12px", borderRadius: 999, fontSize: 12, fontWeight: 600, textDecoration: "none" }}>App Store</a>
    </div>
  </div>
);

// Export
// Walkthrough video URLs — served same-origin from the scottsapps.github.io repo.
const WalkthroughVideos = {
  ios:     "combined-ios.mp4",
  android: "combined-android.mp4",
};

Object.assign(window, {
  SCOTUSIcon, MyNewMusicIcon, VigilIcon,
  IPhoneFrame, AndroidFrame, MockScreenshot, RealScreenshot, RotatingScreenshot, BlueskyEmbed,
  AndroidShots, IOSShots, WalkthroughVideo, WalkthroughVideos,
  Pill, UpcomingCallout, OtherAppCard,
});
