/* ============================================================
   Product (cPanel Hosting), Locations, Contact, Docs, Legal pages
   ============================================================ */

const { useState: useStateX } = React;

/* ---------- Hosting product page ---------- */
function HostingPage() {
  return (
    <main>
      <section style={{ padding: "88px 0 64px", position: "relative", overflow: "hidden" }}>
        <div aria-hidden style={{
          position: "absolute", right: "-15%", top: "-30%",
          width: 700, height: 700,
          background: "radial-gradient(circle, rgba(96,165,250,0.3), transparent 65%)",
          filter: "blur(30px)", pointerEvents: "none",
        }} />
        <div className="wrap" style={{ position: "relative" }}>
          <div className="pill" style={{ marginBottom: 24 }}>
            <span className="dot" /> cPanel shared hosting · LiteSpeed · NVMe
          </div>
          <h1 className="display" style={{ maxWidth: 1000 }}>
            The control panel you<br/>
            know. Faster than <em>ever.</em>
          </h1>
          <p style={{ fontSize: 19, color: "var(--ink-2)", maxWidth: 620, marginTop: 28, lineHeight: 1.55 }}>
            cPanel hosting on LiteSpeed Web Server and pure NVMe storage. Unlimited disk,
            unlimited bandwidth, free SSL, free migration — and a support team that actually
            answers.
          </p>
          <div style={{ marginTop: 32, display: "flex", gap: 12, flexWrap: "wrap" }}>
            <Link to="/pricing" className="btn btn-primary">See pricing <span className="arrow">→</span></Link>
          </div>
        </div>
      </section>

      {/* What's included */}
      <section style={{ padding: "40px 0 80px" }}>
        <div className="wrap">
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14 }}>
            {[
              { t: "LiteSpeed + LSCache", b: "Up to 9× faster than Apache for dynamic PHP. Built-in page cache no plugin can match." },
              { t: "Pure NVMe storage", b: "No spinning disks, no SATA SSDs — every plan on enterprise NVMe with RAID-10 redundancy." },
              { t: "Softaculous 280+ apps", b: "One-click WordPress, Magento, Joomla, Drupal, Ghost, and more. Updates handled for you." },
              { t: "Free SSL (AutoSSL)", b: "Every domain gets a Let's Encrypt cert, auto-renewed. Wildcard support included." },
              { t: "Daily + offsite backups", b: "JetBackup with 7-day retention plus weekly offsite snapshots. One-click restore." },
              { t: "Imunify360 security", b: "Real-time malware scanning, WAF, brute-force protection, reputation management." },
              { t: "Free migration", b: "Point us at your old host — we do the work. Zero downtime cutover on Business+." },
              { t: "cPanel + WHM tools", b: "Email, file manager, DNS, cron, SSH, PHP selector (7.4–8.3), WP Toolkit." },
              { t: "99.9% uptime SLA", b: "If we miss it, you get credit. Published status page with per-datacenter history." },
            ].map((f, i) => (
              <div key={i} style={{
                background: "#fff", border: "1px solid var(--line)",
                borderRadius: 14, padding: 24,
              }}>
                <div className="mono" style={{
                  fontSize: 10, letterSpacing: "0.12em",
                  color: "var(--accent-ink)", marginBottom: 12,
                }}>0{i + 1}</div>
                <h3 style={{ fontSize: 17, marginBottom: 8, letterSpacing: "-0.01em" }}>{f.t}</h3>
                <p style={{ margin: 0, fontSize: 14, color: "var(--ink-2)", lineHeight: 1.55 }}>{f.b}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Migration strip */}
      <section id="migration" style={{ padding: "80px 0", background: "var(--bg-2)", borderTop: "1px solid var(--line)", borderBottom: "1px solid var(--line)" }}>
        <div className="wrap" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 60, alignItems: "center" }}>
          <div>
            <div className="h-eyebrow"><span className="dot" />Free migration</div>
            <h2 style={{
              fontFamily: "var(--font-serif)", fontSize: "clamp(36px, 4.5vw, 56px)",
              letterSpacing: "-0.02em", lineHeight: 1, marginTop: 16,
            }}>
              We'll move your site.<br/>
              <em style={{ color: "var(--accent-ink)", fontStyle: "italic" }}>You pour a coffee.</em>
            </h2>
            <p style={{ color: "var(--ink-2)", marginTop: 18, fontSize: 16, maxWidth: 460 }}>
              Whether it's a cPanel full backup, a WordPress install, a static site, or a
              custom setup — we handle the migration end-to-end. No downtime, no broken
              links.
            </p>
          </div>
          <div style={{ background: "#fff", border: "1px solid var(--line)", borderRadius: 18, padding: 28 }}>
            <ol style={{ padding: 0, margin: 0, listStyle: "none", display: "grid", gap: 18 }}>
              {[
                ["Submit a migration request", "Tell us where your site lives."],
                ["We pull a full backup", "Files, databases, DNS, emails — all of it."],
                ["Staging & sanity check", "We restore on our infra and test everything."],
                ["You point DNS, we monitor", "Zero downtime cutover, 24-hour monitoring."],
              ].map(([t, b], i) => (
                <li key={i} style={{ display: "flex", gap: 14 }}>
                  <div style={{
                    width: 28, height: 28, flexShrink: 0,
                    borderRadius: 999, background: "var(--accent-wash)",
                    color: "var(--accent-ink)",
                    display: "flex", alignItems: "center", justifyContent: "center",
                    fontFamily: "var(--font-mono)", fontSize: 12, fontWeight: 600,
                  }}>{i + 1}</div>
                  <div>
                    <div style={{ fontWeight: 500 }}>{t}</div>
                    <div style={{ color: "var(--ink-3)", fontSize: 14, marginTop: 2 }}>{b}</div>
                  </div>
                </li>
              ))}
            </ol>
          </div>
        </div>
      </section>

      {/* Apps grid */}
      <section style={{ padding: "80px 0" }}>
        <div className="wrap">
          <div className="h-eyebrow"><span className="dot" />One-click apps</div>
          <h2 style={{
            fontFamily: "var(--font-serif)", fontSize: "clamp(36px, 4.5vw, 56px)",
            letterSpacing: "-0.02em", lineHeight: 1, marginTop: 16, marginBottom: 40,
          }}>
            Install anything <em style={{ color: "var(--accent-ink)", fontStyle: "italic" }}>in a click.</em>
          </h2>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 10 }}>
            {["WordPress", "Magento", "Joomla", "Drupal", "Ghost", "PrestaShop",
              "OpenCart", "phpBB", "MediaWiki", "Moodle", "Laravel", "Node.js"].map(app => (
              <div key={app} style={{
                background: "#fff", border: "1px solid var(--line)",
                borderRadius: 10, padding: "18px 16px",
                fontSize: 13, textAlign: "center",
                fontFamily: "var(--font-mono)",
                letterSpacing: "0.02em",
                color: "var(--ink-2)",
              }}>{app}</div>
            ))}
          </div>
          <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 18, textAlign: "center" }}>
            + 268 more via Softaculous
          </div>
        </div>
      </section>
    </main>
  );
}

/* ---------- Locations page ---------- */
function LocationsPage() {
  const dcs = [
    {
      city: "Miami", flag: "🇺🇸", region: "Florida, United States",
      dc: "NAP of the Americas", ip: "xxx.xx.xxx.xx",
      uplink: "100 Gbps", peers: ["Telia", "NTT", "Zayo", "GTT"],
      servers: 18, tz: "UTC−5 (EST)",
    },
    {
      city: "Seattle", flag: "🇺🇸", region: "Washington, United States",
      dc: "Westin Building Exchange", ip: "xxx.xx.xxx.xx",
      uplink: "100 Gbps", peers: ["Telia", "NTT", "Level3", "HE"],
      servers: 14, tz: "UTC−8 (PST)",
    },
    {
      city: "Frankfurt", flag: "🇩🇪", region: "Hesse, Germany",
      dc: "Maincubes FRA01", ip: "xxx.xxx.xx.x",
      uplink: "100 Gbps", peers: ["DE-CIX", "Level3", "NTT", "Cogent"],
      servers: 12, tz: "UTC+1 (CET)",
    },
  ];

  return (
    <main>
      <section style={{ padding: "88px 0 48px" }}>
        <div className="wrap">
          <div className="h-eyebrow"><span className="dot" />Global network</div>
          <h1 className="display" style={{ maxWidth: 1000, marginTop: 16 }}>
            Three datacenters.<br/>
            <em>One fast network.</em>
          </h1>
          <p style={{ fontSize: 19, color: "var(--ink-2)", maxWidth: 640, marginTop: 24, lineHeight: 1.55 }}>
            Pick the region closest to your audience. All regions run identical hardware,
            identical stack, identical pricing — so you can switch or span without surprises.
          </p>
        </div>
      </section>

      <section style={{ padding: "20px 0 60px" }}>
        <div className="wrap">
          <WorldMap />
        </div>
      </section>

      <section style={{ padding: "0 0 60px" }}>
        <div className="wrap">
          <SpeedTester />
        </div>
      </section>

      <section style={{ padding: "0 0 80px" }}>
        <div className="wrap">
          <div style={{ display: "grid", gap: 14 }}>
            {dcs.map(d => (
              <div key={d.city} style={{
                background: "#fff",
                border: "1px solid var(--line)",
                borderRadius: 18,
                padding: 32,
                display: "grid",
                gridTemplateColumns: "1.4fr 1fr 1fr 1fr",
                gap: 32,
                alignItems: "center",
              }}>
                <div>
                  <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 10 }}>
                    <span style={{ fontSize: 28 }}>{d.flag}</span>
                    <h3 style={{ fontSize: 28, letterSpacing: "-0.02em", fontFamily: "var(--font-serif)", fontWeight: 400 }}>{d.city}</h3>
                    <span className="pill"><span className="dot" /> Online</span>
                  </div>
                  <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", lineHeight: 1.8 }}>
                    {d.region}<br/>
                    {d.dc} · {d.tz}
                  </div>
                </div>
                <Field label="Test IP" value={d.ip} />
                <Field label="Uplink" value={d.uplink} />
                <div>
                  <div className="mono" style={{
                    fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase",
                    color: "var(--ink-3)", marginBottom: 8,
                  }}>Carriers</div>
                  <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                    {d.peers.map(p => (
                      <span key={p} style={{
                        fontFamily: "var(--font-mono)", fontSize: 11,
                        padding: "4px 8px", borderRadius: 6,
                        background: "var(--bg-2)", color: "var(--ink-2)",
                      }}>{p}</span>
                    ))}
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>
    </main>
  );
}

function Field({ label, value }) {
  return (
    <div>
      <div className="mono" style={{
        fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase",
        color: "var(--ink-3)", marginBottom: 8,
      }}>{label}</div>
      <div className="mono" style={{ fontSize: 15, color: "var(--ink)" }}>{value}</div>
    </div>
  );
}

/* ---------- Speed tester (real HTTP round-trip) ----------
   Times fetch() against publicly-reachable CORS-friendly endpoints
   geographically near each datacenter. Approximates real network latency. */
function SpeedTester() {
  const targets = [
    {
      city: "Miami", flag: "🇺🇸", region: "Florida, US",
      // Cloudflare anycast — routes to nearest PoP
      url: "https://speed.cloudflare.com/__down?bytes=1024",
      note: "via nearest Cloudflare PoP",
    },
    {
      city: "Seattle", flag: "🇺🇸", region: "Washington, US",
      // Cloudflare Seattle PoP — speed test endpoint, CORS-enabled
      url: "https://speed.cloudflare.com/__down?bytes=1024",
      note: "via nearest Cloudflare PoP",
    },
    {
      city: "Frankfurt", flag: "🇩🇪", region: "Hesse, DE",
      // Cloudflare anycast — routes to nearest PoP
      url: "https://speed.cloudflare.com/__down?bytes=1024",
      note: "via nearest Cloudflare PoP",
    },
  ];

  const [results, setResults] = React.useState(
    Object.fromEntries(targets.map(t => [t.city, { state: "idle", ms: null, samples: [] }]))
  );
  const [running, setRunning] = React.useState(false);

  async function timeOnce(url) {
    const u = url + (url.includes("?") ? "&" : "?") + "t=" + Math.random().toString(36).slice(2);
    const t0 = performance.now();
    try {
      await fetch(u, { method: "GET", mode: "no-cors", cache: "no-store" });
      return performance.now() - t0;
    } catch (e) {
      return null;
    }
  }

  async function runTest() {
    setRunning(true);
    setResults(Object.fromEntries(targets.map(t => [t.city, { state: "running", ms: null, samples: [] }])));

    await Promise.all(targets.map(async (t) => {
      const samples = [];
      // warm-up (DNS/TLS)
      await timeOnce(t.url);
      for (let i = 0; i < 5; i++) {
        const ms = await timeOnce(t.url);
        if (ms != null) samples.push(ms);
        setResults(r => ({ ...r, [t.city]: { state: "running", ms: null, samples: [...samples] } }));
      }
      const sorted = [...samples].sort((a, b) => a - b);
      const median = sorted.length ? sorted[Math.floor(sorted.length / 2)] : null;
      setResults(r => ({
        ...r,
        [t.city]: {
          state: median != null ? "done" : "error",
          ms: median != null ? Math.round(median) : null,
          samples,
        },
      }));
    }));
    setRunning(false);
  }

  // auto-run once on mount
  React.useEffect(() => { runTest(); /* eslint-disable-next-line */ }, []);

  return (
    <div style={{
      background: "var(--ink)",
      color: "#EAF2FF",
      borderRadius: 18,
      padding: 32,
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 16, marginBottom: 28 }}>
        <div>
          <div className="h-eyebrow" style={{ color: "#9CC2FF" }}>
            <span className="dot" style={{ background: "#60A5FA" }} /> Live test
          </div>
          <h2 style={{
            fontFamily: "var(--font-serif)", fontSize: "clamp(28px, 3.4vw, 40px)",
            letterSpacing: "-0.02em", lineHeight: 1.05, marginTop: 12, color: "#fff",
          }}>
            Test the network from <em style={{ color: "#60A5FA" }}>your browser.</em>
          </h2>
          <p style={{ color: "#9CC2FF", marginTop: 10, maxWidth: 560, fontSize: 14 }}>
            Real HTTP round-trip from your browser to public servers near each region.
            5 requests per region; we take the median.
          </p>
        </div>
        <button
          type="button"
          onClick={runTest}
          disabled={running}
          className="btn"
          style={{
            background: running ? "#1f2937" : "#fff",
            color: running ? "#9CC2FF" : "#0A1220",
            cursor: running ? "wait" : "pointer",
          }}
        >
          {running ? "Testing…" : "Run again"} <span className="arrow">→</span>
        </button>
      </div>

      <div style={{ display: "grid", gap: 10 }}>
        {targets.map(t => {
          const r = results[t.city];
          return (
            <div key={t.city} style={{
              display: "grid",
              gridTemplateColumns: "220px 1fr 110px",
              alignItems: "center",
              gap: 16,
              padding: "16px 20px",
              background: "rgba(255,255,255,0.04)",
              border: "1px solid rgba(255,255,255,0.08)",
              borderRadius: 12,
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <span style={{ fontSize: 22 }}>{t.flag}</span>
                <div>
                  <div style={{ fontWeight: 500 }}>{t.city}</div>
                  <div className="mono" style={{ fontSize: 11, color: "#9CC2FF" }}>{t.note}</div>
                </div>
              </div>
              <div style={{
                position: "relative", height: 8, background: "rgba(255,255,255,0.06)", borderRadius: 999, overflow: "hidden",
              }}>
                <div style={{
                  position: "absolute", left: 0, top: 0, bottom: 0,
                  width: r.ms != null ? `${Math.min(100, (r.ms / 400) * 100)}%` : (r.state === "running" ? "30%" : "0%"),
                  background: r.ms != null
                    ? (r.ms < 80 ? "#10B981" : r.ms < 200 ? "#60A5FA" : "#F59E0B")
                    : "#60A5FA",
                  borderRadius: 999,
                  transition: "width 0.4s var(--ease)",
                  animation: r.state === "running" ? "pulse 1.2s ease-in-out infinite" : "none",
                }} />
              </div>
              <div className="mono" style={{ textAlign: "right", fontSize: 14 }}>
                {r.state === "idle" && <span style={{ color: "#5A6778" }}>—</span>}
                {r.state === "running" && <span style={{ color: "#60A5FA" }}>{r.samples.length}/5</span>}
                {r.state === "done" && <span style={{ color: "#fff" }}>{r.ms} ms</span>}
                {r.state === "error" && <span style={{ color: "#F59E0B" }}>blocked</span>}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- Contact page ---------- */
function ContactPage() {
  const [sent, setSent] = useStateX(false);
  const [dept, setDept] = useStateX("sales");

  return (
    <main>
      <section style={{ padding: "88px 0 48px" }}>
        <div className="wrap">
          <div className="h-eyebrow"><span className="dot" />We're here</div>
          <h1 className="display" style={{ maxWidth: 900, marginTop: 16 }}>
            Questions? <em>Talk to us.</em>
          </h1>
          <p style={{ fontSize: 19, color: "var(--ink-2)", maxWidth: 560, marginTop: 24 }}>
            Real humans on the other end. Sales replies within an hour, support within two.
            No bots, no ticket purgatory.
          </p>
        </div>
      </section>

      <section style={{ padding: "20px 0 80px" }}>
        <div className="wrap" style={{ display: "grid", gridTemplateColumns: "1fr 1.3fr", gap: 40 }}>
          {/* Info column */}
          <div>
            <div style={{ background: "#fff", border: "1px solid var(--line)", borderRadius: 18, padding: 28, marginBottom: 14 }}>
              <div className="h-eyebrow" style={{ marginBottom: 14 }}>Get in touch</div>
              <div style={{ display: "grid", gap: 16, fontSize: 14 }}>
                <div>
                  <div style={{ color: "var(--ink-3)", marginBottom: 2 }}>Sales</div>
                  <div className="mono">sales@loominost.com</div>
                </div>
                <div>
                  <div style={{ color: "var(--ink-3)", marginBottom: 2 }}>Support</div>
                  <div className="mono">support@loominost.com</div>
                </div>
                <div>
                  <div style={{ color: "var(--ink-3)", marginBottom: 2 }}>General</div>
                  <div className="mono">hello@loominost.com</div>
                </div>
              </div>
            </div>

            <div style={{ background: "var(--ink)", color: "#E8E3D8", borderRadius: 18, padding: 28 }}>
              <div className="h-eyebrow" style={{ color: "#9a958c", marginBottom: 14 }}><span className="dot" />Response times</div>
              <div style={{ display: "grid", gap: 14, fontSize: 14 }}>
                {[
                  ["Sales", "< 1 hour"],
                  ["Support · Advanced+", "< 2 hours"],
                  ["Support · Basic", "< 8 hours"],
                  ["Abuse reports", "< 24 hours"],
                ].map(([l, v]) => (
                  <div key={l} style={{
                    display: "flex", justifyContent: "space-between",
                    paddingBottom: 10, borderBottom: "1px dashed #2a2a2a",
                  }}>
                    <span style={{ color: "#9a958c" }}>{l}</span>
                    <span className="mono" style={{ color: "var(--accent-glow)" }}>{v}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Form */}
          <form onSubmit={e => { e.preventDefault(); setSent(true); }}
            style={{ background: "#fff", border: "1px solid var(--line)", borderRadius: 18, padding: 32 }}>
            {sent ? (
              <div style={{ padding: "40px 0", textAlign: "center" }}>
                <div style={{
                  width: 56, height: 56, borderRadius: 999,
                  background: "var(--accent-wash)",
                  color: "var(--accent-ink)",
                  margin: "0 auto 20px",
                  display: "flex", alignItems: "center", justifyContent: "center",
                }}>
                  <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                    <path d="M5 12l4 4L19 7" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
                  </svg>
                </div>
                <h3 style={{ fontFamily: "var(--font-serif)", fontSize: 32, letterSpacing: "-0.02em" }}>Message sent.</h3>
                <p style={{ color: "var(--ink-2)", marginTop: 10 }}>We'll get back to you shortly at the email you provided.</p>
                <button type="button" onClick={() => setSent(false)} className="btn btn-ghost" style={{ marginTop: 20 }}>
                  Send another
                </button>
              </div>
            ) : (
              <>
                <div className="h-eyebrow" style={{ marginBottom: 18 }}>Send a message</div>

                <div style={{ display: "flex", gap: 6, marginBottom: 20 }}>
                  {[["sales", "Sales"], ["support", "Support"], ["abuse", "Abuse"]].map(([k, l]) => (
                    <button key={k} type="button" onClick={() => setDept(k)} style={{
                      padding: "8px 14px", borderRadius: 999,
                      border: "1px solid " + (dept === k ? "var(--ink)" : "var(--line)"),
                      background: dept === k ? "var(--ink)" : "transparent",
                      color: dept === k ? "#fff" : "var(--ink-2)",
                      fontFamily: "var(--font-sans)", fontSize: 13,
                      cursor: "pointer",
                    }}>{l}</button>
                  ))}
                </div>

                <div style={{ display: "grid", gap: 14 }}>
                  <InputRow label="Full name" placeholder="Jane Doe" />
                  <InputRow label="Email" type="email" placeholder="you@example.com" />
                  <InputRow label="Domain (optional)" placeholder="yoursite.com" />
                  <div>
                    <label style={lblStyle}>Message</label>
                    <textarea rows="5" placeholder="Tell us what you need…"
                      style={{ ...inputStyle, resize: "vertical", fontFamily: "var(--font-sans)" }} />
                  </div>
                  <button type="submit" className="btn btn-primary" style={{ justifyContent: "center" }}>
                    Send message <span className="arrow">→</span>
                  </button>
                </div>
              </>
            )}
          </form>
        </div>
      </section>
    </main>
  );
}

const lblStyle = {
  display: "block",
  fontFamily: "var(--font-mono)",
  fontSize: 10,
  letterSpacing: "0.12em",
  textTransform: "uppercase",
  color: "var(--ink-3)",
  marginBottom: 6,
};
const inputStyle = {
  width: "100%",
  padding: "12px 14px",
  border: "1px solid var(--line)",
  borderRadius: 10,
  fontSize: 14,
  background: "var(--bg)",
  color: "var(--ink)",
  outline: "none",
  fontFamily: "var(--font-sans)",
};

function InputRow({ label, type = "text", placeholder }) {
  return (
    <div>
      <label style={lblStyle}>{label}</label>
      <input type={type} placeholder={placeholder} style={inputStyle} />
    </div>
  );
}

/* ---------- Docs / KB page ---------- */
function DocsPage() {
  const [q, setQ] = useStateX("");
  const cats = [
    { icon: "◐", title: "Getting started", count: 12, articles: [
      "Creating your first account", "Pointing your domain to Loominost", "Accessing cPanel", "Migrating from another host",
    ]},
    { icon: "◑", title: "WordPress", count: 24, articles: [
      "Installing WordPress via Softaculous", "Enabling LSCache for WordPress", "Moving an existing WP site", "Hardening wp-admin",
    ]},
    { icon: "◒", title: "Email", count: 18, articles: [
      "Creating an email account", "SPF, DKIM & DMARC setup", "Connecting to Outlook / Apple Mail", "Fixing 'email going to spam'",
    ]},
    { icon: "◓", title: "Domains & DNS", count: 15, articles: [
      "Changing nameservers", "Adding an A/CNAME record", "Using external DNS (Cloudflare)", "Subdomain setup",
    ]},
    { icon: "◔", title: "Security", count: 16, articles: [
      "Enabling SSL/HTTPS", "Imunify360 overview", "Two-factor for cPanel", "Responding to a hacked site",
    ]},
    { icon: "◕", title: "Billing", count: 9, articles: [
      "Updating your payment method", "Applying a coupon", "Canceling your account", "Getting an invoice receipt",
    ]},
  ];
  const filtered = q
    ? cats.map(c => ({ ...c, articles: c.articles.filter(a => a.toLowerCase().includes(q.toLowerCase())) })).filter(c => c.articles.length)
    : cats;

  return (
    <main>
      <section style={{ padding: "88px 0 40px" }}>
        <div className="wrap">
          <div className="h-eyebrow"><span className="dot" />Knowledgebase</div>
          <h1 className="display" style={{ maxWidth: 900, marginTop: 16 }}>
            How can we <em>help?</em>
          </h1>
          <div style={{ marginTop: 32, maxWidth: 640, position: "relative" }}>
            <svg style={{ position: "absolute", left: 18, top: "50%", transform: "translateY(-50%)" }}
              width="18" height="18" viewBox="0 0 24 24" fill="none">
              <circle cx="11" cy="11" r="7" stroke="var(--ink-3)" strokeWidth="2"/>
              <path d="M20 20l-3-3" stroke="var(--ink-3)" strokeWidth="2" strokeLinecap="round"/>
            </svg>
            <input
              value={q}
              onChange={e => setQ(e.target.value)}
              placeholder="Search articles… e.g. 'SSL', 'WordPress', 'DNS'"
              style={{
                width: "100%", padding: "18px 20px 18px 48px",
                fontSize: 16, border: "1px solid var(--line)",
                borderRadius: 14, background: "#fff",
                fontFamily: "var(--font-sans)", outline: "none",
              }}/>
          </div>
        </div>
      </section>

      <section style={{ padding: "20px 0 80px" }}>
        <div className="wrap">
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 14 }}>
            {filtered.map(c => (
              <div key={c.title} style={{
                background: "#fff", border: "1px solid var(--line)",
                borderRadius: 18, padding: 28,
              }}>
                <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 18 }}>
                  <span style={{ fontSize: 24, color: "var(--accent-ink)" }}>{c.icon}</span>
                  <span className="mono" style={{ fontSize: 11, color: "var(--ink-3)" }}>{c.articles.length} articles</span>
                </div>
                <h3 style={{ fontSize: 20, letterSpacing: "-0.01em", marginBottom: 14 }}>{c.title}</h3>
                <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "grid", gap: 8 }}>
                  {c.articles.map(a => (
                    <li key={a}>
                      <Link to="/docs/article" style={{
                        fontSize: 14, color: "var(--ink-2)",
                        display: "flex", justifyContent: "space-between",
                        padding: "8px 0", borderBottom: "1px dashed var(--line)",
                      }}>
                        <span>{a}</span>
                        <span style={{ color: "var(--ink-3)" }}>→</span>
                      </Link>
                    </li>
                  ))}
                </ul>
              </div>
            ))}
          </div>

          {filtered.length === 0 && (
            <div style={{ textAlign: "center", padding: 80, color: "var(--ink-3)" }}>
              No articles match "{q}". <a href="https://loominost.com/whmcs/contact.php" style={{ textDecoration: "underline" }}>Contact support</a>?
            </div>
          )}
        </div>
      </section>
    </main>
  );
}

/* ---------- Legal pages (ToS / Privacy / AUP) ---------- */
function LegalPage({ doc }) {
  const docs = {
    tos: {
      title: "Terms of Service",
      updated: "Loominost LLP (LLP0037896-LGN)",
      intro: [
        "Loominost.com provides hosting services to clients worldwide, and we have a responsibility to protect each client and to provide the best services available. All registered clients of Loominost (loominost.com) agree to and are subject to our Acceptable Use Policy, Privacy Policy and the following Terms of Services:",
        "Clients acknowledge that the service provided is of such a nature that service can be interrupted for many reasons other than the negligence of Loominost and that damages resulting from any interruption of service are difficult to ascertain. Therefore, clients agree that Loominost shall not be liable for any damages arising from such causes beyond the direct and exclusive control of Loominost.",
        "Subscriber further acknowledges that Loominost's liability for its own negligence may not in any event exceed an amount equivalent to charges payable by subscriber for services during the period damages occurred. In no event shall Loominost be held liable for any special or consequential damages, loss or injury.",
      ],
      sections: [
        {
          h: "Indemnification Policy",
          p: [
            "You agree to use all Loominost services and facilities at your own risk. Loominost specifically disclaims all warranties of merchantability and fitness for a particular purpose. In no event shall Loominost be liable for any loss, or loss of data, or other commercial damage, including but not limited to special, incidental, consequential or other damages. Clients agree that they shall defend, indemnify, save and hold Loominost harmless from any and all demands, liabilities, losses, costs and claims, including reasonable attorney's fees asserted against Loominost, its agents, its customers, officers and employees, that may arise or result from any service provided, performed, agreed to be performed or any product sold by its customers, its agents, employees or assigns. Clients agree to defend, indemnify and hold harmless Loominost against liabilities arising out of any injury to person or property caused by any products sold or otherwise distributed in connection with Loominost's network.",
            "Loominost reserves the right to intervene with any website/data hosted on its servers/network in the interest of its clients. Any material supplied/hosted by a client that is infringing or allegedly infringing on the proprietary rights of a third party copyright owner are subject to removal from Loominost's servers/network. Loominost shall be the sole judge of what violates this policy.",
          ],
        },
        {
          h: "Billing",
          p: [
            "At this time, we bill monthly, quarterly, semi-annually and annually, depending upon the plan. We provide a 7-day money-back (refund) guarantee. Each refund request must be submitted using our support ticket system located at https://loominost.com/whmcs/contact.php. Each refund request is evaluated on a case by case basis — depending on the situation, no refund, full refund or partial refund will be issued. If a refund is not issued, an account credit may be issued. Loominost will only issue a refund or credit within 7 days after the initial sign up date of the service. Therefore, Loominost retains the right to grant or deny any refund or credit request — not affected by date. For some special offers, the money-back guarantee day will be varied; Domain Name registration/transfer fee(s) and servers are non-refundable. Crypto Currency, AliPay and WeChat payments are non-refundable but may receive an account credit. To prevent abuse, only a client's first invoice is eligible for a refund unless stated otherwise.",
            "We accept Visa, Master Card, American Express, Discover Card, PayPal, AliPay, WeChat and Crypto Currency. All services are setup, free of any fees or charges. Clients are encouraged to pay by PayPal as it is the easiest way to handle payments at this time. There are no contract periods but for each successive period, your contract is automatically renewed unless we are notified otherwise.",
          ],
        },
        {
          h: "Uptime Guarantee",
          p: [
            "Loominost offers each client with a 100% uptime guarantee. In the event that a 100% uptime (measured per month) is not met, clients will be eligible to receive credit(s) based on the situation and amount of downtime. However, credit(s) may not be provided for certain events such as: DDoS (Distributed Denial of Service) attacks, scheduled maintenance, reboots, hardware replacements and null-routes. In order to receive a 'compensation' credit, the client must do so by making a request by opening a billing ticket or by emailing support.",
            "Loominost's network is DDoS (Distributed Denial of Service) protected, but we cannot guarantee any level/type of protection. We are often able to protect against various types of attacks up to 20Gbps. Attacks larger than this will result in the target IP address being null-routed. We are not responsible for any downtime or performance decreases caused by DDoS attacks.",
          ],
        },
        {
          h: "Limitation of Liability",
          p: "Loominost shall not be responsible for any claimed damages, including incidental and consequential damages, which may arise from Loominost servers going off-line or being unavailable for any reason whatsoever. Furthermore, Loominost shall not be responsible for any claimed damages, including incidental or consequential damages, resulting from the corruption or deletion of any web site from one of Loominost servers. All damages shall be limited to the immediate termination of service.",
        },
        {
          h: "Late Payments",
          p: "All services are billed according to the dates they were first activated on. If you do not pay for service renewal within 5 days after deactivation, your service will be suspended. If you do not pay for service renewal within 30 days after deactivation, your service will be terminated. You will receive an email reminder 5 days until deactivation.",
        },
        {
          h: "Disclaimer",
          p: [
            "Loominost cannot be held liable for system downtime, crashes, or data loss. Loominost has the right to terminate, suspend or cancel any client and/or any service without notice or refund. We cannot be held liable for any predicted estimate of profits/income which a client would have gained if their service was functioning. Certain services provided by Loominost are resold. Thus, certain equipment, routing, software, and programming used by Loominost are not directly owned or written by Loominost. Moreover, Loominost holds no responsibility for the use of our clients' accounts.",
            "If any of our terms, policies or conditions are failed to be followed, the client account in question may be deactivated as well as all services/products attached to it. We reserve the right to remove any account without advance notice for any reason without restitution as Loominost sees fit. Loominost is not responsible for any clients' files, data or actions. FURTHERMORE, Loominost retains the right to change any or all of the above Policies, Guidelines, and Disclaimer without notification.",
          ],
        },
      ],
    },
    privacy: {
      title: "Privacy Policy",
      updated: "Updated April 1, 2026",
      sections: [
        { h: "1. What we collect", p: "Account data (name, email, billing address), payment metadata (we do not store full card numbers — these are handled by Stripe or PayPal), and server logs required to operate the service." },
        { h: "2. How we use it", p: "To provision and operate your hosting account, bill you, provide support, and comply with legal obligations. We do not sell your personal data. Ever." },
        { h: "3. Cookies", p: "We use essential cookies for authentication and a minimal set of analytics cookies to understand aggregate site usage. No third-party advertising cookies." },
        { h: "4. Data retention", p: "Account data is retained for the life of your account plus 24 months for tax and legal purposes. Server logs are rotated after 30 days. Backups are retained per plan policy." },
        { h: "5. Your rights (GDPR/CCPA)", p: "You can request access, correction, export, or deletion of your personal data by emailing privacy@loominost.com. We respond within 30 days." },
        { h: "6. Sub-processors", p: "Stripe (payments), PayPal (payments), SendGrid (transactional email), and our datacenter partners. A full list is available on request." },
        { h: "7. Contact", p: "Questions about privacy? Email privacy@loominost.com or write to Loominost LLP, via our listed business address." },
      ],
    },
    aup: {
      title: "Acceptable Use Policy",
      updated: "Loominost LLP (LLP0037896-LGN)",
      intro: [
        "Loominost Hosting provides hosting services to clients worldwide, and we have a responsibility to protect each client and to provide the best services available. All registered clients of Loominost Hosting (loominost.com) agree to and are subject to our Terms of Service, Privacy Policy and the following Acceptable Use Policy:",
        "All services provided by Loominost may be used for lawful purposes only. Transmission, storage, or presentation of any information, data or material in violation of any United States Federal, State or City law is prohibited. Services provided by Loominost that reside outside of the United States must still abide these terms and must not be in violation of any relevant laws of hosting city, state and country. This includes, but is not limited to: copyrighted material, material we judge to be threatening or obscene, or material protected by trade secret and other statute. The subscriber agrees to indemnify and hold harmless Loominost and its employees from any claims resulting from the use of the service which damages the subscriber or any other party.",
        "The provisions of this AUP are intended as guidelines and are not meant to be exhaustive. Generally, conduct that violates law, regulation, or the accepted norms of the Internet community, whether or not expressly mentioned in this AUP, are prohibited. We reserve the right at all times to prohibit activities that damage our or our affiliates' commercial reputation and goodwill. We will be the sole and final arbiter as to what constitutes a violation of our policies.",
      ],
      sections: [
        {
          h: "Spam",
          p: [
            "All users must comply with all relevant legislation and regulations on bulk and commercial e-mail, including but not limited to the CAN-SPAM Act of 2003.",
            "Users may not send mass unsolicited e-mail, which is email that is sent to recipients who have not 'opted-in' to mailings from the user. Users who send mass mailings must maintain complete and accurate records of all consents and opt-ins and provide such records to Loominost upon its request. If a user cannot provide positive and verifiable proof of such consents and opt-ins, we will consider the mass mailing to be unsolicited. Users are prohibited from operating mailing lists, listservs, or mailing services that do not target an audience that has voluntarily signed up for e-mail information using an 'opt-in' process or that has made their e-mail addresses available to a user for distribution of information. Users who operate mailing lists must maintain complete and accurate records of all consents and 'opt-in' elections and provide such records to Loominost upon its request. If a user cannot provide positive and verifiable proof of such consents and 'opt-in' elections, we will consider the list mailing to be unsolicited. Any user-maintained mailing list must also allow any party on the list to remove itself automatically and permanently. Other prohibited activities include, without limitation, the following:",
          ],
          list: [
            "Use of our network for the receipt of replies to unsolicited mass e-mail.",
            "Forgery of e-mail headers (spoofing).",
            "Spamming via third-party proxy, aggregation of proxy lists, or installation of proxy mailing software.",
            "Configuration of a mail server to accept and process third-party messages for sending without user identification and authentication.",
            "Hosting web pages advertised within 'spam e-mail' sent from another network (spamvertising).",
            "Hosting web pages or providing services that support spam.",
            "Any other unsolicited bulk messages, postings, or transmissions through media such as weblog posts, IRC/chat room messages, guestbook entries, HTTP referrer log entries, usenet posts, pop-up messages, instant messages, or SMS messages.",
            "Instructing others in any activity prohibited by this AUP.",
          ],
          after: "If, as a result of your actions, our domains and/or IP address ranges are placed on black hole lists or other mail filtering software systems, your server may be suspended and possibly terminated upon further investigation.",
        },
        {
          h: "Prohibited Uses",
          p: "The following uses are prohibited on our network. Engaging in these activities on our services will result in an account and/or service suspension without notice.",
          list: [
            "Copyrighted content hosting and/or linking to pirated content",
            "Open proxies",
            "Stressers/booter websites",
            "Mail/SMS bombers",
            "Mass mail",
            "Resource intensive activities (CPU, I/O, Network etc)",
            "IP spoofing",
            "Network/port scanning",
            "Distribution of credentials and/or personal information",
            "Denial of Service (D)DoS attacks",
            "TOR exit nodes",
            "Open DNS resolvers",
            "Hola",
            "Kloxo",
            "Virtual currency (*coin) mining",
            "World Community Grid, Folding at Home, or similar software",
            "CrystalMines",
            "HitLeap or any artificial traffic creation",
            "HYIP websites",
            "iBusinessPromoter or similar software",
            "Vulnerability scanning",
            "Bruteforcing",
            "Social media crawlers",
            "Cracking",
            "Botnets",
            "Illegal pornography",
            "Hivemail",
            "Telnet or SSH access scripts",
            "Usenet",
            "Destructive activities including but not limited to phishing, malware and/or distributing malicious content",
            "Illegal activities including but not limited to ponzi schemes, pyramid schemes, phishing, scam websites and pirating software",
            "Video streaming",
            "Content delivery networks (CDN)",
            "LIULIANGKUANG",
            "Multics, CCcam, or any other card sharing software",
            "Chinese private game servers and related websites",
            "Any form of file hosting, file storage, cyberlocker, leeching or similar activity is prohibited",
          ],
          after: "Certain network ports are blocked across our network, this is to ensure that our services are not used for malicious purposes and to protect our machines from potential vulnerabilities. Additional ports may be blocked and/or unblocked without notice to customers.",
        },
        {
          h: "DDoS Attacks",
          p: "Customers that are targeted with frequent and disruptive attacks may have action taken against their service and/or account. If attacks directed towards your service(s) are found to be persistently impacting the performance for other customers and/or our network, you will be notified via ticket and requested to try and prevent further attacks or to relocate to another provider.",
        },
        {
          h: "Fair Usage",
          p: "Unlimited & unmetered claims have software and hardware limitations, and are subject to a discretionary fair use policy by our team. Our hosting plans are intended only to be used for content relevant to a hosted website; any form of backup storage, file locker services, personal media (e.g. photos, movies, music or any other form of media) is not permitted. If you are using more of any resource than is considered realistic or reasonable for the relevant platform then you will be notified via ticket to reduce your usage. If any user's usage of a resource imposes a risk to the integrity of the platform, they may have their service(s) suspended to prevent any disruptions.",
        },
        {
          h: "Account Resources",
          p: [
            "All cPanel accounts are isolated by Linux and have maximum resource limits; the resource limits applied to your service through our plans are not dedicated to you. These are in place to reduce attack disruption and/or abusive behaviour from affecting other customers on the same server.",
            "If you are persistently hitting the resource limits we may notify you and recommend that you upgrade your plan (if applicable), or move to a more suitable environment such as a VPS or dedicated server. We retain the right to modify these resource limits without notice, and to take action against any accounts that are negatively affecting the performance of the server.",
            "Outgoing mail on all of our cPanel servers is limited to 500 emails per hour on each cPanel account; this includes mailman lists and PHP mail.",
          ],
        },
        {
          h: "Backup Policy",
          p: [
            "All of our cPanel servers run daily backups with a retention period of 30 days. Accounts that are using more than 100GB storage and/or 500,000 inodes are excluded from the backup system. These backups are available as a best-effort emergency fail-safe and we cannot guarantee their availability to customers.",
            "We may delete impermissible data from our servers at any time at our discretion without notice. We may also delete the following types of data if we find it to be in an excessive and/or unreasonable capacity:",
          ],
          list: [
            "cPanel or other backups stored locally.",
            "Softaculous backups stored locally.",
            "Softaculous backup temp files.",
            "Common CMS backups stored locally.",
            "Common CMS backup temp files.",
            "Common CMS backup logs.",
            "Large error logs.",
          ],
        },
      ],
    },
  };
  const d = docs[doc] || docs.tos;

  return (
    <main>
      <section style={{ padding: "80px 0 40px" }}>
        <div className="wrap" style={{ maxWidth: 780 }}>
          <div className="h-eyebrow"><span className="dot" />Legal</div>
          <h1 style={{
            fontFamily: "var(--font-serif)", fontSize: "clamp(44px, 5.5vw, 80px)",
            letterSpacing: "-0.02em", lineHeight: 1, marginTop: 16,
          }}>{d.title}</h1>
          <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 14, letterSpacing: "0.04em" }}>
            {d.updated}
          </div>

          <div style={{ display: "flex", gap: 8, marginTop: 28, flexWrap: "wrap" }}>
            {[["tos", "Terms of Service"], ["privacy", "Privacy Policy"], ["aup", "Acceptable Use"]].map(([k, l]) => (
              <Link key={k} to={"/legal/" + k} style={{
                padding: "6px 12px",
                borderRadius: 999,
                fontSize: 12,
                fontFamily: "var(--font-mono)",
                background: doc === k ? "var(--ink)" : "transparent",
                color: doc === k ? "#fff" : "var(--ink-2)",
                border: "1px solid " + (doc === k ? "var(--ink)" : "var(--line)"),
              }}>{l}</Link>
            ))}
          </div>
        </div>
      </section>

      <section style={{ padding: "20px 0 80px" }}>
        <div className="wrap" style={{ maxWidth: 780 }}>
          {d.intro && (
            <div style={{ display: "grid", gap: 18, marginBottom: 48, paddingBottom: 36, borderBottom: "1px solid var(--line)" }}>
              {(Array.isArray(d.intro) ? d.intro : [d.intro]).map((para, i) => (
                <p key={i} style={{ margin: 0, color: "var(--ink-2)", fontSize: 15.5, lineHeight: 1.75 }}>{para}</p>
              ))}
            </div>
          )}
          <div style={{ display: "grid", gap: 36 }}>
            {d.sections.map((s, i) => {
              const paras = Array.isArray(s.p) ? s.p : [s.p];
              return (
                <div key={i}>
                  <h3 style={{
                    fontFamily: "var(--font-sans)", fontSize: 20,
                    letterSpacing: "-0.01em", marginBottom: 12,
                  }}>{s.h}</h3>
                  <div style={{ display: "grid", gap: 14 }}>
                    {paras.map((para, j) => (
                      <p key={j} style={{ margin: 0, color: "var(--ink-2)", fontSize: 15.5, lineHeight: 1.7 }}>{para}</p>
                    ))}
                    {s.list && (
                      <ul style={{
                        margin: "4px 0 0", paddingLeft: 22,
                        color: "var(--ink-2)", fontSize: 15.5, lineHeight: 1.65,
                        display: "grid", gap: 6,
                      }}>
                        {s.list.map((item, k) => (
                          <li key={k}>{item}</li>
                        ))}
                      </ul>
                    )}
                    {s.after && (
                      <p style={{ margin: 0, color: "var(--ink-2)", fontSize: 15.5, lineHeight: 1.7 }}>{s.after}</p>
                    )}
                  </div>
                </div>
              );
            })}
          </div>

          <div style={{
            marginTop: 60, padding: 24,
            background: "var(--bg-2)",
            borderRadius: 14, border: "1px solid var(--line)",
            fontSize: 14, color: "var(--ink-2)",
          }}>
            Questions about this document? Email <span className="mono">legal@loominost.com</span> —
            we'll answer plainly and without the lawyer-speak.
          </div>
        </div>
      </section>
    </main>
  );
}

Object.assign(window, { HostingPage, LocationsPage, DocsPage, LegalPage });
