/* eslint-disable */
/* 9nguoi10y — mobile-first landing. Five components, curiosity-led. */

const { useState, useEffect, useMemo, useRef } = React;

/* ============================================================
   BACKEND — Google Apps Script Web App endpoint.
   Paste the URL you got after deploying the Apps Script.
   ============================================================ */
const SHEET_URL = "https://script.google.com/macros/s/AKfycbxuwzkpZqpdEquxvVqJRYpu08XTEM2tDO-VuBB_NBJln767Q0IDWNt49wkm4lRKSOQktg/exec";

const sendToSheet = (payload) => {
  try {
    fetch(SHEET_URL, {
      method: "POST",
      mode: "no-cors",
      body: JSON.stringify(payload)
    }).catch(() => {});
  } catch (e) {}
};

/* ============================================================
   ICONS — minimal set
   ============================================================ */
const LICONS = {
  check: <polyline points="20 6 9 17 4 12" />,
  plus: <g><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></g>,
  arrowRight: <g><path d="M5 12h14" /><path d="m12 5 7 7-7 7" /></g>,
  mail: <g><rect x="2" y="4" width="20" height="16" rx="2" /><path d="m22 7-10 6L2 7" /></g>,
  spark: <g><path d="M12 2v6" /><path d="M12 16v6" /><path d="M4.93 4.93l4.24 4.24" /><path d="M14.83 14.83l4.24 4.24" /><path d="M2 12h6" /><path d="M16 12h6" /><path d="M4.93 19.07l4.24-4.24" /><path d="M14.83 9.17l4.24-4.24" /></g>
};
const I = ({ name, size = 18, stroke = 1.5, color = "currentColor", style }) =>
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
style={style} aria-hidden>
    {LICONS[name] || null}
  </svg>;

/* Wordmark — "9nguoi10y" with 9 in --for green, 10 in --against red,
   matching the logo mark. */
const Wordmark = ({ style }) =>
<span style={{
  fontFamily: "var(--font-serif)", fontWeight: 700,
  letterSpacing: "-0.3px", color: "var(--ink)",
  ...style
}}>
    <span style={{ color: "var(--for)" }}>9</span>
    <span>nguoi</span>
    <span style={{ color: "var(--against)" }}>10</span>
    <span>y</span>
  </span>;


/* ============================================================
   DATA — 9 seed topics (same set, trimmed metadata)
   ============================================================ */
const SEED_TOPICS = [
  { id: "t1", category: "Giáo dục",     title: "Đại học có nên là con đường mặc định cho người trẻ?",                                         baseVotes: 412 },
  { id: "t2", category: "Xã hội",       title: "Người nghèo thì không nên có con?",                                                            baseVotes: 287 },
  { id: "t3", category: "Tài chính",   title: "Liệu Bitcoin và các đồng tiền ảo có thực sự mang giá trị?",                                    baseVotes: 196 },
  { id: "t4", category: "Tâm lý",       title: "“Hãy là chính mình” liệu có thật sự là một lời khuyên tốt?",                                  baseVotes: 351 },
  { id: "t5", category: "Giao thông",  title: "Rẽ phải ở nơi có đèn nhưng không có vạch mắt võng — nhường hay không nhường?",               baseVotes: 168 },
  { id: "t6", category: "Tình yêu",     title: "Buổi hẹn đầu tiên — đàn ông trả tiền?",                                                        baseVotes: 524 },
];


const LS_KEY = "9n10y-landing-v2";
const loadState = () => {try {return JSON.parse(localStorage.getItem(LS_KEY) || "{}");} catch {return {};}};
const saveState = (s) => {try {localStorage.setItem(LS_KEY, JSON.stringify(s));} catch {}};

/* ============================================================
   1 · MAST — logo + wordmark only. Tight, top of viewport.
   ============================================================ */
const Mast = () =>
<header style={{
  display: "flex", alignItems: "center", gap: 9,
  padding: "20px 0 0"
}}>
    <img src="assets/logo-mark.svg" width="24" height="24" alt="" style={{ borderRadius: 4 }} />
    <Wordmark style={{ fontSize: 18 }} />
    <span style={{ flex: 1 }} />
    <span style={{
    fontFamily: "var(--font-mono)", fontSize: 10.5,
    letterSpacing: "0.08em", color: "var(--flame)",
    textTransform: "uppercase",
    display: "inline-flex", alignItems: "center", gap: 6
  }}>
      <span style={{
      width: 6, height: 6, borderRadius: 999, background: "var(--flame)",
      boxShadow: "0 0 0 0 rgba(201,123,42,0.45)",
      animation: "pulse 2.2s ease-in-out infinite"
    }} />
      Coming soon
    </span>
  </header>;


/* ============================================================
   2 · HEARTFELT — one sentence, big serif. No info, just a feeling.
   ============================================================ */
const Heartfelt = () =>
<section style={{ padding: "56px 0 0" }}>
    <h1 style={{
      fontFamily: "var(--font-serif)", fontWeight: 600,
      fontSize: "clamp(36px, 10.5vw, 52px)",
      lineHeight: 1.04, letterSpacing: "-0.025em",
      color: "var(--ink)", margin: 0, textWrap: "balance"
    }}>
      <span style={{ display: "block" }}>
        <span style={{ color: "var(--for)" }}>Tranh luận</span>,
      </span>
      <span style={{ display: "block", fontStyle: "italic", fontWeight: 500 }}>
        không <span style={{ color: "var(--against)", fontStyle: "italic" }}>tranh cãi</span>.
      </span>
    </h1>

    <div style={{ margin: "28px 0 0" }}>
      <p style={{
        fontFamily: "var(--font-serif)", fontSize: 18, lineHeight: 1.6,
        color: "var(--ink-2)", margin: 0, textWrap: "pretty"
      }}>
        Tranh luận không cần công kích, mỉa mai hay châm biếm. Đôi khi,
        những cuộc tranh luận còn chẳng phải để phân định kẻ đúng người sai.
      </p>
      <p style={{
        fontFamily: "var(--font-serif)", fontSize: 18, lineHeight: 1.6,
        color: "var(--ink-2)", margin: "20px 0 0", textWrap: "pretty"
      }}>
        Đó là một cơ hội để nhìn thế giới qua lăng kính của người khác —
        những người có trải nghiệm, niềm tin và cách nhìn cuộc sống khác
        với mình, qua đó làm tròn đầy thêm thế giới quan của bản thân.
      </p>
      <p style={{
        fontFamily: "var(--font-serif)", fontSize: 18, lineHeight: 1.6,
        color: "var(--ink)", margin: "20px 0 0", textWrap: "pretty"
      }}>
        <span style={{ color: "var(--for)", fontWeight: 600 }}>9</span> người{" "}
        <span style={{ color: "var(--against)", fontWeight: 600 }}>10</span> ý
        {" "}là nơi dành cho những cuộc đối thoại như thế.
      </p>
      <p style={{
        fontFamily: "var(--font-serif)",
        fontSize: 17, lineHeight: 1.6,
        color: "var(--ink-2)", margin: "14px 0 0", textWrap: "pretty"
      }}>
        Không có mục tiêu phân định ai thắng, ai thua. Chỉ là chia sẻ
        những góc nhìn (dù là đặc thù), để đôi bên có thể tiến gần hơn
        một bước tới sự thật.
      </p>
    </div>
  </section>;
/* ============================================================
   3 · TOPIC PICK — the hook. The user understands the venue by doing.
   ============================================================ */
const TopicPick = ({ topics, voted, votesById, recents, onToggle }) =>
<section style={{ padding: "64px 0 0" }}>
    {/* hairline above to mark a turn */}
    <div style={{ height: 1, background: "var(--rule)", marginBottom: 28 }} />

    <div style={{
    fontFamily: "var(--font-mono)", fontSize: 11,
    letterSpacing: "0.14em", textTransform: "uppercase",
    color: "var(--flame)", marginBottom: 14
  }}>· Mời bạn chọn</div>

    <h2 style={{
      fontFamily: "var(--font-serif)", fontWeight: 600,
      fontSize: "clamp(26px, 7vw, 34px)",
      lineHeight: 1.12, letterSpacing: "-0.015em",
      color: "var(--ink)", margin: 0, textWrap: "balance"
    }}>
      Chủ đề nào khiến bạn <em style={{ fontStyle: "italic" }}>tò mò</em>?
    </h2>

    <p style={{
      fontFamily: "var(--font-serif)", fontStyle: "italic",
      fontSize: 16, lineHeight: 1.5,
      color: "var(--ink-3)", margin: "16px 0 28px", textWrap: "pretty"
    }}>
      Chọn một hoặc nhiều chủ đề bạn quan tâm, đây sẽ là cơ sở để tụi mình tạo nên những "võ đài" tranh luận đầu tiên.
    </p>

    <ul style={{
    listStyle: "none", padding: 0, margin: 0,
    borderTop: "1px solid var(--rule)"
  }}>
      {topics.map((t) =>
        <TopicRow key={t.id} topic={t}
          voted={voted.has(t.id)}
          votes={votesById[t.id]}
          recent={recents.has(t.id)}
          showCounts={voted.size > 0}
          onToggle={() => onToggle(t.id)} />
      )}
    </ul>

    <div style={{
    paddingTop: 14,
    display: "flex", alignItems: "baseline", gap: 6,
    fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--ink-3)",
    letterSpacing: "0.02em"
  }}>
      <span>{voted.size === 0 ?
      "Bạn chưa chọn chủ đề nào." :
      `Bạn đã chọn ${voted.size} chủ đề.`}</span>
    </div>
  </section>;


/* ============================================================
   TOPIC ROW — tap target ≥ 64px tall, generous on mobile
   ============================================================ */
const TopicRow = ({ topic, voted, votes, recent, showCounts, onToggle }) => {
  const [pressing, setPressing] = useState(false);
  return (
    <li>
      <button onClick={onToggle}
      onTouchStart={() => setPressing(true)}
      onTouchEnd={() => setPressing(false)}
      onTouchCancel={() => setPressing(false)}
      style={{
        width: "100%", textAlign: "left", cursor: "pointer",
        background: voted ? "var(--for-50)" : pressing ? "var(--paper-2)" : "transparent",
        border: 0, borderBottom: "1px solid var(--rule)",
        padding: "18px 4px",
        display: "flex", alignItems: "flex-start", gap: 14,
        transition: "background 0.16s ease",
        minHeight: 72,
        fontFamily: "inherit",
        color: "var(--ink)"
      }}>

        {/* checkbox slot */}
        <span style={{
          flexShrink: 0, marginTop: 2,
          width: 24, height: 24, borderRadius: 4,
          border: voted ? "1.5px solid var(--for)" : "1.5px solid var(--rule-strong)",
          background: voted ? "var(--for)" : "transparent",
          color: "var(--for-ink)",
          display: "inline-flex", alignItems: "center", justifyContent: "center",
          transition: "all 0.18s ease"
        }}>
          {voted && <I name="check" size={14} stroke={2.6} />}
        </span>

        {/* content */}
        <span style={{ flex: 1, minWidth: 0 }}>
          <span style={{
            display: "flex", alignItems: "center", gap: 8,
            fontFamily: "var(--font-mono)", fontSize: 10.5,
            letterSpacing: "0.12em", textTransform: "uppercase",
            color: "var(--ink-3)", marginBottom: 6
          }}>
            <span>{topic.category}</span>
            {recent && showCounts &&
              <span style={{ color: "var(--flame)", letterSpacing: "0.04em" }}>
                + vừa được chọn
              </span>
            }
          </span>
          <span style={{
            display: "block",
            fontFamily: "var(--font-serif)", fontWeight: 500, fontSize: 17,
            lineHeight: 1.34, letterSpacing: "-0.003em",
            color: "var(--ink)", textWrap: "pretty"
          }}>{topic.title}</span>
        </span>

        {/* vote count — hidden until user has voted on at least one */}
        <span style={{
          flexShrink: 0, textAlign: "right", marginTop: 2,
          minWidth: showCounts ? 42 : 0,
          fontFamily: "var(--font-mono)", fontWeight: 600, fontSize: 13.5,
          color: voted ? "var(--for-700)" : "var(--ink-3)",
          letterSpacing: "-0.01em",
          opacity: showCounts ? 1 : 0,
          transition: "opacity 0.35s ease, color 0.2s ease"
        }}>{votes}</span>
      </button>
    </li>);

};

/* ============================================================
   4 · SUGGEST — inline. Expands only if needed.
   ============================================================ */
const Suggest = ({ onSubmit }) => {
  const [open, setOpen] = useState(false);
  const [text, setText] = useState("");
  const [justSubmitted, setJustSubmitted] = useState(false);
  const wordCount = text.trim() ? text.trim().split(/\s+/).length : 0;
  const valid = wordCount >= 5;

  const handleSubmit = () => {
    if (!valid) return;
    sendToSheet({ suggested: text, source: 'suggest' });
    onSubmit({ text });
    setText("");
    setJustSubmitted(true);
    setTimeout(() => setJustSubmitted(false), 3500);
  };

  if (!open) {
    return (
      <section style={{ padding: "32px 0 0" }}>
        <button onClick={() => setOpen(true)} style={{
          width: "100%", textAlign: "left", cursor: "pointer",
          padding: "16px 16px", borderRadius: 2,
          background: "transparent",
          border: "1px dashed var(--rule-strong)",
          display: "flex", alignItems: "center", gap: 12,
          fontFamily: "var(--font-serif)", fontStyle: "italic", fontSize: 15.5,
          color: "var(--ink-3)",
          transition: "background 0.16s ease, color 0.16s ease"
        }}
        onMouseEnter={(e) => {e.currentTarget.style.background = "var(--paper-2)";e.currentTarget.style.color = "var(--ink-2)";}}
        onMouseLeave={(e) => {e.currentTarget.style.background = "transparent";e.currentTarget.style.color = "var(--ink-3)";}}>
          <I name="plus" size={16} stroke={1.6} />
          <span>Hoặc đề xuất một chủ đề bạn muốn nghe tranh luận.</span>
        </button>
      </section>);
  }

  return (
    <section style={{ padding: "32px 0 0" }}>
      <div style={{
        background: "var(--card)", border: "1px solid var(--rule-strong)",
        borderRadius: 2, padding: "14px 16px 12px"
      }}>
        <div style={{
          display: "flex", alignItems: "center", gap: 8, marginBottom: 6
        }}>
          <span style={{
            fontFamily: "var(--font-mono)", fontSize: 10.5,
            letterSpacing: "0.14em", textTransform: "uppercase",
            color: justSubmitted ? "var(--for-700)" : "var(--ink-3)",
            transition: "color 0.3s ease"
          }}>
            {justSubmitted ? "✓ ĐÃ NHẬN — MỜI BẠN ĐỀ XUẤT TIẾP" : "ĐỀ XUẤT CHỦ ĐỀ"}
          </span>
          <span style={{ flex: 1 }} />
          <button onClick={() => setOpen(false)} style={{
            background: "transparent", border: 0, cursor: "pointer",
            fontFamily: "var(--font-sans)", fontSize: 12, color: "var(--ink-4)",
            padding: 0
          }}>đóng</button>
        </div>

        <textarea
          autoFocus
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="Một câu hỏi hoặc một câu khẳng định — viết theo cách bạn muốn."
          rows={3}
          style={{
            width: "100%", boxSizing: "border-box",
            padding: "8px 0", border: 0, outline: "none",
            background: "transparent", resize: "none",
            fontFamily: "var(--font-serif)", fontWeight: 500, fontSize: 17,
            lineHeight: 1.42, letterSpacing: "-0.003em", color: "var(--ink)"
          }} />

        <div style={{
          display: "flex", alignItems: "center", gap: 10, marginTop: 4,
          paddingTop: 8, borderTop: "1px solid var(--rule)"
        }}>
          <span style={{
            fontFamily: "var(--font-mono)", fontSize: 10.5,
            color: valid ? "var(--for)" : "var(--ink-4)"
          }}>
            {wordCount} từ {valid ? "✓" : "· ít nhất 5 từ"}
          </span>
          <span style={{ flex: 1 }} />
          <button onClick={handleSubmit}
          disabled={!valid}
          style={{
            padding: "9px 14px", borderRadius: 2, border: 0,
            background: valid ? "var(--ink)" : "var(--paper-3)",
            color: valid ? "var(--paper)" : "var(--ink-4)",
            fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 13,
            cursor: valid ? "pointer" : "not-allowed",
            display: "inline-flex", alignItems: "center", gap: 6,
            transition: "all 0.15s ease"
          }}>
            Gửi
            <I name="arrowRight" size={13} />
          </button>
        </div>
      </div>
    </section>);
};

/* ============================================================
   5 · WAITLIST — single field. Personal, low-friction.
   ============================================================ */
const Waitlist = ({ onSubmit, submitted, hasVoted, voted }) => {
  const [email, setEmail] = useState("");
  const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());

  if (submitted) {
    return (
      <section style={{ padding: "56px 0 0" }}>
        <div style={{
          padding: "26px 22px", textAlign: "left",
          background: "var(--paper-2)",
          border: "1px solid var(--rule)", borderRadius: 2,
          display: "flex", gap: 16, alignItems: "flex-start"
        }}>
          <span style={{
            flexShrink: 0,
            display: "inline-flex", alignItems: "center", justifyContent: "center",
            width: 36, height: 36, borderRadius: 999,
            background: "var(--for-50)", color: "var(--for-700)",
            marginTop: 2
          }}>
            <I name="check" size={18} stroke={2.4} />
          </span>
          <div>
            <h3 style={{
              fontFamily: "var(--font-serif)", fontWeight: 700, fontSize: 20,
              color: "var(--ink)", margin: "0 0 6px", letterSpacing: "-0.01em"
            }}>Bạn đã có chỗ trong nhóm đầu tiên.</h3>
            <p style={{
              fontFamily: "var(--font-serif)", fontStyle: "italic", fontSize: 14.5,
              color: "var(--ink-3)", margin: 0, lineHeight: 1.5
            }}>
              Khi 9nguoi10y ra mắt, chúng tôi sẽ gửi bạn lời mời đầu tiên.
            </p>
          </div>
        </div>
      </section>);

  }

  return (
    <section style={{ padding: "56px 0 0" }}>
      <div style={{ height: 1, background: "var(--rule)", marginBottom: 28 }} />

      <h2 style={{
        fontFamily: "var(--font-serif)", fontWeight: 600,
        fontSize: "clamp(24px, 6.5vw, 30px)",
        lineHeight: 1.18, letterSpacing: "-0.015em",
        color: "var(--ink)", margin: 0, textWrap: "balance"
      }}>
        Trở thành người đầu tiên trải nghiệm <Wordmark style={{ fontSize: "inherit", fontWeight: 600 }} />
      </h2>
      <p style={{
        fontFamily: "var(--font-serif)", fontSize: 16, lineHeight: 1.6,
        color: "var(--ink-2)", margin: "14px 0 22px", textWrap: "pretty"
      }}>
        Hãy để lại email hoặc một phương thức liên lạc — bạn sẽ trở thành một
        trong những người đầu tiên bước vào nền tảng này, đọc những cuộc tranh
        luận đầu tiên, và cất lên góc nhìn của riêng mình.
      </p>

      <form onSubmit={(e) => {
        e.preventDefault();
        if (valid) {
          sendToSheet({
            email: email.trim(),
            topics: voted ? [...voted] : [],
            source: 'waitlist'
          });
          onSubmit(email);
        }
      }}
      style={{
        display: "flex", flexDirection: "column", gap: 10
      }}>
        <label style={{
          display: "flex", alignItems: "center", gap: 10,
          padding: "0 14px",
          border: "1px solid var(--rule-strong)", borderRadius: 2,
          background: "var(--card)",
          height: 52
        }}>
          <I name="mail" size={16} color="var(--ink-3)" />
          <input
            type="email"
            inputMode="email"
            autoComplete="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="ten@email.com"
            style={{
              flex: 1, padding: "0", border: 0, outline: "none",
              background: "transparent",
              fontFamily: "var(--font-serif)", fontSize: 17, color: "var(--ink)",
              minWidth: 0
            }} />
        </label>

        <button type="submit" disabled={!valid} style={{
          height: 52, padding: "0 18px",
          border: 0, borderRadius: 2,
          background: valid ? "var(--ink)" : "var(--paper-3)",
          color: valid ? "var(--paper)" : "var(--ink-4)",
          fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 15,
          cursor: valid ? "pointer" : "not-allowed",
          display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
          transition: "all 0.15s ease"
        }}>
          Đăng ký ngay
          <I name="arrowRight" size={15} />
        </button>
      </form>
    </section>);

};

/* ============================================================
   FOOTER — tiny, just the idiom credit
   ============================================================ */
const Footer = () =>
<footer style={{
  padding: "72px 0 56px",
  fontFamily: "var(--font-serif)", fontStyle: "italic", fontSize: 13,
  color: "var(--ink-3)", lineHeight: 1.5
}}>
    <div style={{ marginBottom: 4 }}>
      <span style={{ fontStyle: "normal", fontWeight: 600, color: "var(--ink-2)" }}>"9 người 10 ý"</span> (hay <span style={{ fontStyle: "normal" }}>"chín người mười ý"</span>) là câu thành ngữ diễn tả sự đa dạng trong suy nghĩ và quan điểm. Khi một nhóm thảo luận, mỗi người mang một ý kiến riêng, rất khó để đi đến thống nhất. Việc này đòi hỏi sự lắng nghe và thấu hiểu để tìm ra tiếng nói chung.
    </div>
    <div style={{ fontFamily: "var(--font-mono)", fontStyle: "normal", fontSize: 11, color: "var(--ink-4)" }}>
      © 2026
    </div>
  </footer>;


/* ============================================================
   APP
   ============================================================ */
const App = () => {
  const [voted, setVoted] = useState(new Set());
  const [bonus, setBonus] = useState({});
  const [recents, setRecents] = useState(new Set());
  const [topicSubmitted, setTopicSubmitted] = useState(false);
  const [emailSubmitted, setEmailSubmitted] = useState(false);

  useEffect(() => {
    const s = loadState();
    if (s.voted) setVoted(new Set(s.voted));
    if (s.bonus) setBonus(s.bonus);
    if (s.topicSubmitted) setTopicSubmitted(true);
    if (s.emailSubmitted) setEmailSubmitted(true);
  }, []);

  useEffect(() => {
    saveState({ voted: [...voted], bonus, topicSubmitted, emailSubmitted });
  }, [voted, bonus, topicSubmitted, emailSubmitted]);

  // light, occasional "+1 from someone else" — subtle social proof
  useEffect(() => {
    const tick = () => {
      const id = SEED_TOPICS[Math.floor(Math.random() * SEED_TOPICS.length)].id;
      setBonus((b) => ({ ...b, [id]: (b[id] || 0) + 1 }));
      setRecents((r) => {const n = new Set(r);n.add(id);return n;});
      setTimeout(() => setRecents((r) => {const n = new Set(r);n.delete(id);return n;}), 2400);
    };
    const interval = setInterval(tick, 9000 + Math.random() * 8000);
    return () => clearInterval(interval);
  }, []);

  const votesById = useMemo(() => {
    const m = {};
    SEED_TOPICS.forEach((t) => {
      m[t.id] = t.baseVotes + (bonus[t.id] || 0) + (voted.has(t.id) ? 1 : 0);
    });
    return m;
  }, [bonus, voted]);

  const sortedTopics = useMemo(() => {
    // Keep stable initial order; do not reshuffle while user taps.
    return SEED_TOPICS;
  }, []);

  const toggleVote = (id) => {
    setVoted((prev) => {
      const next = new Set(prev);
      const isVotingOn = !next.has(id);
      if (isVotingOn) {
        next.add(id);
        sendToSheet({
          suggested: '',
          topics: [id],
          source: isVotingOn ? 'vote_on' : 'vote_off'
        });
      } else {
        next.delete(id);
        sendToSheet({
          suggested: '',
          topics: [id],
          source: 'vote_off'
        });
      }
      return next;
    });
  };

  return (
    <div style={{
      minHeight: "100vh", background: "var(--paper)", color: "var(--ink)",
      animation: "pagein 0.6s cubic-bezier(0.22, 1, 0.36, 1) both"
    }}>
      <main style={{
        maxWidth: 520, margin: "0 auto", padding: "0 22px"
      }}>
        <Mast />
        <Heartfelt />
        <TopicPick
          topics={sortedTopics}
          voted={voted}
          recents={recents}
          votesById={votesById}
          onToggle={toggleVote} />
        <Suggest onSubmit={() => setTopicSubmitted(true)} />
        <Waitlist
          submitted={emailSubmitted}
          hasVoted={voted.size > 0}
          voted={voted}
          onSubmit={() => setEmailSubmitted(true)} />
        <Footer />
      </main>

      <style>{`
        @keyframes pagein {
          from { opacity: 0; transform: translateY(8px); }
          to { opacity: 1; transform: translateY(0); }
        }
        @keyframes pulse {
          0%, 100% { box-shadow: 0 0 0 0 rgba(201, 123, 42, 0.45); }
          50%      { box-shadow: 0 0 0 5px rgba(201, 123, 42, 0); }
        }
        ::selection { background: var(--selection-bg); color: var(--ink); }
        @media (hover: hover) {
          button:hover { -webkit-tap-highlight-color: transparent; }
        }
      `}</style>
    </div>);

};

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