// Reseller portal login page.
//
// Wired to the real backend (src/routes/portal.ts) as of Phase 0.
// Phase 0 is password-only — no 2FA yet (the old 6-digit code UI has
// been removed; it'll come back once real TOTP is built in a later phase).
//
// LIGHT/DARK TOGGLE: this page (and ResellerForgotPasswordPage /
// ResellerResetPasswordPage below) render standalone, OUTSIDE
// ResellerShell — there's no sidebar pre-login to host the toggle
// control, so each of these 3 components calls its own
// usePortalTheme(), stamps its own <section data-portal-theme={theme}>
// root, mounts its own <PortalThemeStyles />, and places its own
// <PortalThemeToggle> next to the "secure access" eyebrow tag. All
// three read/write the same localStorage key (see portal-theme.jsx) so
// the choice made here carries straight through to the dashboard/etc.
// once signed in.

function ResellerLoginPage({ onNavigate }) {
  const [theme, toggleTheme] = usePortalTheme();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  // idle → checking-session (on mount) → submitting → error
  const [status, setStatus] = useState("checking-session");
  const [error, setError] = useState("");

  // If there's already a valid session (e.g. the user bookmarked this
  // page, or hit Back after logging in), skip straight to the dashboard
  // instead of showing the login form again.
  useEffect(() => {
    let cancelled = false;
    fetch("/api/portal/me", { credentials: "same-origin" })
      .then((r) => (r.ok ? r.json() : null))
      .then((data) => {
        if (cancelled) return;
        if (data?.user) onNavigate("portal-dashboard");
        else setStatus("idle");
      })
      .catch(() => { if (!cancelled) setStatus("idle"); });
    return () => { cancelled = true; };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  const canSubmit = email.trim() && password.trim() && status !== "submitting";

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setStatus("submitting");
    setError("");
    try {
      const res = await fetch("/api/portal/login", {
        method: "POST",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email.trim(), password }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setError(data.error || "Something went wrong. Please try again.");
        setStatus("idle");
        return;
      }
      onNavigate("portal-dashboard");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setStatus("idle");
    }
  };

  // Avoid flashing the login form for the instant it takes to check for
  // an existing session.
  if (status === "checking-session") {
    return (
      <section data-portal-theme={theme} style={{ background: "var(--pt-bg)", minHeight: "calc(100vh - 88px)" }}>
        <PortalThemeStyles />
      </section>
    );
  }

  return (
    <section data-portal-theme={theme} style={{
      // Full-bleed light surface so the login feels like its own moment,
      // not just another content section.
      background: "var(--pt-bg)",
      color: "var(--pt-fg)",
      // Enough room above the nav, below the footer
      minHeight: "calc(100vh - 88px)",
      padding: "80px 36px 120px",
      display: "flex", alignItems: "center", justifyContent: "center",
      position: "relative",
    }}>
      <PortalThemeStyles />

      {/* Decorative corner crosshairs — same vocabulary as the home hero,
          ties this page into the site's defence-tech identity */}
      <CornerHairlines />

      <div style={{
        width: "100%", maxWidth: 480,
        position: "relative", zIndex: 2,
      }}>
        {/* Tiny system tag above the panel, with the light/dark toggle */}
        <div style={{
          display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10,
          marginBottom: 32,
        }}>
          <div style={{
            display: "flex", alignItems: "center", gap: 10,
            fontFamily: "var(--font-body)", fontSize: 10,
            letterSpacing: "0.32em", textTransform: "uppercase",
            color: "var(--pt-fg-dimmer)", fontWeight: 500,
          }}>
            <LiveDot />
            <span>Reseller portal · secure access</span>
          </div>
          <PortalThemeToggle theme={theme} onToggle={toggleTheme} compact />
        </div>

        <h1 style={{
          fontFamily: "var(--font-display)", fontWeight: 700,
          fontSize: "clamp(40px, 6vw, 64px)", lineHeight: 1,
          letterSpacing: "-0.005em", textTransform: "uppercase",
          margin: "0 0 18px", color: "var(--pt-fg)",
        }}>
          Reseller login.
        </h1>
        <p style={{
          fontFamily: "var(--font-body)", fontSize: 16,
          lineHeight: 1.5, color: "var(--pt-fg-4)",
          margin: "0 0 24px", maxWidth: 420,
        }}>
          Sign in to access deal registration, hardware allocation, pricing schedules, and partner support.
        </p>

        <form onSubmit={handleSubmit} style={{
          background: "var(--pt-surface)",
          border: "1px solid var(--pt-border-3)",
          backdropFilter: "blur(6px)",
          padding: "36px 36px 36px",
        }}>
          {error && (
            <div style={{
              background: "var(--pt-error-bg)",
              border: "1px solid var(--pt-error-border)",
              color: "var(--pt-error-text)",
              padding: "14px 16px",
              marginBottom: 22,
              fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
            }}>
              {error}
            </div>
          )}

          {/* Email */}
          <FieldBlock label="Email">
            <DarkInput
              type="email"
              autoComplete="username"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="jane@partner.co.uk"
            />
          </FieldBlock>

          {/* Password */}
          <FieldBlock label="Password" right={
            <button
              type="button"
              onClick={() => setShowPassword((v) => !v)}
              style={{
                background: "none", border: "none", cursor: "pointer",
                padding: 0,
                fontFamily: "var(--font-body)", fontSize: 10,
                letterSpacing: "0.22em", textTransform: "uppercase",
                color: "var(--pt-fg-dim)", fontWeight: 500,
              }}>
              {showPassword ? "Hide" : "Show"}
            </button>
          }>
            <DarkInput
              type={showPassword ? "text" : "password"}
              autoComplete="current-password"
              required
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              placeholder="••••••••••••"
            />
          </FieldBlock>

          {/* Submit */}
          <button
            type="submit"
            disabled={!canSubmit}
            style={{
              width: "100%", marginTop: 12,
              background: canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)",
              color: canSubmit ? "var(--pt-accent-fg)" : "var(--pt-accent-fg-disabled)",
              border: `1px solid ${canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)"}`,
              padding: "18px 22px",
              cursor: canSubmit ? "pointer" : "not-allowed",
              fontFamily: "var(--font-body)",
              fontSize: 13, fontWeight: 500,
              letterSpacing: "0.22em", textTransform: "uppercase",
              transition: "background 140ms, color 140ms",
            }}>
            {status === "submitting" ? "Signing in…" : "Sign in →"}
          </button>

          {/* Secondary actions */}
          <div style={{
            marginTop: 24, paddingTop: 22,
            borderTop: "1px solid var(--pt-border)",
            display: "flex", justifyContent: "space-between",
            flexWrap: "wrap", gap: 16,
            fontFamily: "var(--font-body)", fontSize: 12,
            letterSpacing: "0.14em", textTransform: "uppercase",
          }}>
            <button
              type="button"
              onClick={() => onNavigate("reseller-forgot-password")}
              style={{
                background: "none", border: "none", padding: 0,
                cursor: "pointer",
                fontFamily: "inherit", fontSize: "inherit", letterSpacing: "inherit",
                color: "var(--pt-fg-4)",
                textDecoration: "underline",
                textDecorationColor: "var(--pt-border-strong)",
                textUnderlineOffset: 4,
              }}>Forgot password?</button>
            <button
              type="button"
              onClick={() => onNavigate("reseller-signup")}
              style={{
                background: "none", border: "none", padding: 0,
                cursor: "pointer",
                fontFamily: "inherit", fontSize: "inherit", letterSpacing: "inherit",
                color: "var(--pt-fg-4)",
                textDecoration: "underline",
                textDecorationColor: "var(--pt-border-strong)",
                textUnderlineOffset: 4,
              }}>Need access? →</button>
          </div>
        </form>

        {/* Staff-only entry point — deliberately understated, not a public
            nav link. Admin sessions live in a completely separate cookie
            (see AUTH_GATED_PAGES in app.jsx), so this never interferes with
            a reseller session on the same device. */}
        <div style={{ textAlign: "center", marginTop: 22 }}>
          <button
            type="button"
            data-testid="admin-login-link"
            onClick={() => onNavigate("admin-login")}
            style={{
              background: "none", border: "none", padding: 0,
              cursor: "pointer",
              fontFamily: "var(--font-body)", fontSize: 11,
              letterSpacing: "0.2em", textTransform: "uppercase",
              color: "var(--pt-fg-faint2)",
            }}>Solo staff login →</button>
        </div>
      </div>
    </section>
  );
}

/* ──────────── Forgot password (request link) ──────────── */
// Step 1 of the reset flow: collect an email, POST it to
// /api/portal/forgot-password. The backend always returns the same
// generic "if that email exists, we've sent a link" response (see that
// route's comment) — this page shows that same message whether or not
// the account actually existed, so no client-side branching on
// existence is possible even if someone inspects the response.
function ResellerForgotPasswordPage({ onNavigate }) {
  const [theme, toggleTheme] = usePortalTheme();
  const [email, setEmail] = useState("");
  const [status, setStatus] = useState("idle"); // idle → submitting → sent
  const [error, setError] = useState("");

  const canSubmit = email.trim() && status !== "submitting";

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setStatus("submitting");
    setError("");
    try {
      const res = await fetch("/api/portal/forgot-password", {
        method: "POST",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email.trim() }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setError(data.error || "Something went wrong. Please try again.");
        setStatus("idle");
        return;
      }
      setStatus("sent");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setStatus("idle");
    }
  };

  return (
    <section data-portal-theme={theme} style={{
      background: "var(--pt-bg)", color: "var(--pt-fg)", minHeight: "calc(100vh - 88px)",
      padding: "80px 36px 120px",
      display: "flex", alignItems: "center", justifyContent: "center",
      position: "relative",
    }}>
      <PortalThemeStyles />
      <CornerHairlines />
      <div style={{ width: "100%", maxWidth: 480, position: "relative", zIndex: 2 }}>
        <div style={{
          display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, marginBottom: 32,
        }}>
          <div style={{
            display: "flex", alignItems: "center", gap: 10,
            fontFamily: "var(--font-body)", fontSize: 10,
            letterSpacing: "0.32em", textTransform: "uppercase",
            color: "var(--pt-fg-dimmer)", fontWeight: 500,
          }}>
            <LiveDot />
            <span>Reseller portal · secure access</span>
          </div>
          <PortalThemeToggle theme={theme} onToggle={toggleTheme} compact />
        </div>

        <h1 style={{
          fontFamily: "var(--font-display)", fontWeight: 700,
          fontSize: "clamp(36px, 5.5vw, 56px)", lineHeight: 1,
          letterSpacing: "-0.005em", textTransform: "uppercase",
          margin: "0 0 18px", color: "var(--pt-fg)",
        }}>
          Reset your password.
        </h1>

        {status === "sent" ? (
          <div style={{
            background: "var(--pt-contrast-bg)",
            border: "1px solid var(--pt-contrast-bg)",
            padding: "36px",
          }}>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 16, lineHeight: 1.6,
              color: "var(--pt-contrast-fg-dim)", margin: "0 0 24px",
            }}>
              If <strong style={{ color: "var(--pt-contrast-fg)" }}>{email.trim()}</strong> matches an active reseller account, we've sent a password reset
              link to it. The link expires in 45 minutes.
            </p>
            <button
              type="button"
              onClick={() => onNavigate("reseller-login")}
              style={{
                background: "var(--pt-contrast-fg)", color: "var(--pt-contrast-bg)", border: "1px solid var(--pt-contrast-fg)",
                padding: "16px 22px", cursor: "pointer",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
              }}>Back to sign in →</button>
          </div>
        ) : (
          <>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 16,
              lineHeight: 1.5, color: "var(--pt-fg-4)",
              margin: "0 0 24px", maxWidth: 420,
            }}>
              Enter the email address on your reseller account and we'll send you a link to reset your password.
            </p>

            <form onSubmit={handleSubmit} style={{
              background: "var(--pt-surface)",
              border: "1px solid var(--pt-border-3)",
              backdropFilter: "blur(6px)",
              padding: "36px",
            }}>
              {error && (
                <div style={{
                  background: "var(--pt-error-bg)",
                  border: "1px solid var(--pt-error-border)",
                  color: "var(--pt-error-text)", padding: "14px 16px", marginBottom: 22,
                  fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
                }}>
                  {error}
                </div>
              )}

              <FieldBlock label="Email">
                <DarkInput
                  type="email"
                  autoComplete="username"
                  required
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  placeholder="jane@partner.co.uk"
                />
              </FieldBlock>

              <button
                type="submit"
                disabled={!canSubmit}
                style={{
                  width: "100%", marginTop: 12,
                  background: canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)",
                  color: canSubmit ? "var(--pt-accent-fg)" : "var(--pt-accent-fg-disabled)",
                  border: `1px solid ${canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)"}`,
                  padding: "18px 22px",
                  cursor: canSubmit ? "pointer" : "not-allowed",
                  fontFamily: "var(--font-body)",
                  fontSize: 13, fontWeight: 500,
                  letterSpacing: "0.22em", textTransform: "uppercase",
                  transition: "background 140ms, color 140ms",
                }}>
                {status === "submitting" ? "Sending…" : "Send reset link →"}
              </button>

              <div style={{
                marginTop: 24, paddingTop: 22,
                borderTop: "1px solid var(--pt-border)",
                textAlign: "center",
                fontFamily: "var(--font-body)", fontSize: 12,
                letterSpacing: "0.14em", textTransform: "uppercase",
              }}>
                <button
                  type="button"
                  onClick={() => onNavigate("reseller-login")}
                  style={{
                    background: "none", border: "none", padding: 0,
                    cursor: "pointer",
                    fontFamily: "inherit", fontSize: "inherit", letterSpacing: "inherit",
                    color: "var(--pt-fg-4)",
                    textDecoration: "underline",
                    textDecorationColor: "var(--pt-border-strong)",
                    textUnderlineOffset: 4,
                  }}>← Back to sign in</button>
              </div>
            </form>
          </>
        )}
      </div>
    </section>
  );
}

/* ──────────── Reset password (with token from emailed link) ──────────── */
// Step 2 of the reset flow: reached via the emailed link, which app.jsx
// parses (?resetToken=...&resetType=reseller) into the `token` prop
// before this page ever renders — see readResetLinkFromLocation() in
// app.jsx. If somehow reached with no token (e.g. someone navigates here
// directly without a link), shows a dead-end message instead of a
// pointless form rather than letting a POST with an empty token 400.
function ResellerResetPasswordPage({ onNavigate, token }) {
  const [theme, toggleTheme] = usePortalTheme();
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  const [status, setStatus] = useState("idle"); // idle → submitting → done
  const [error, setError] = useState("");

  const canSubmit = token && password.length >= 10 && password === confirmPassword && status !== "submitting";

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setStatus("submitting");
    setError("");
    try {
      const res = await fetch("/api/portal/reset-password", {
        method: "POST",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ token, password }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setError(data.error || "Something went wrong. Please try again.");
        setStatus("idle");
        return;
      }
      setStatus("done");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setStatus("idle");
    }
  };

  return (
    <section data-portal-theme={theme} style={{
      background: "var(--pt-bg)", color: "var(--pt-fg)", minHeight: "calc(100vh - 88px)",
      padding: "80px 36px 120px",
      display: "flex", alignItems: "center", justifyContent: "center",
      position: "relative",
    }}>
      <PortalThemeStyles />
      <CornerHairlines />
      <div style={{ width: "100%", maxWidth: 480, position: "relative", zIndex: 2 }}>
        <div style={{
          display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, marginBottom: 32,
        }}>
          <div style={{
            display: "flex", alignItems: "center", gap: 10,
            fontFamily: "var(--font-body)", fontSize: 10,
            letterSpacing: "0.32em", textTransform: "uppercase",
            color: "var(--pt-fg-dimmer)", fontWeight: 500,
          }}>
            <LiveDot />
            <span>Reseller portal · secure access</span>
          </div>
          <PortalThemeToggle theme={theme} onToggle={toggleTheme} compact />
        </div>

        <h1 style={{
          fontFamily: "var(--font-display)", fontWeight: 700,
          fontSize: "clamp(36px, 5.5vw, 56px)", lineHeight: 1,
          letterSpacing: "-0.005em", textTransform: "uppercase",
          margin: "0 0 18px", color: "var(--pt-fg)",
        }}>
          Set a new password.
        </h1>

        {!token ? (
          <div style={{
            background: "var(--pt-surface)",
            border: "1px solid var(--pt-border-3)",
            padding: "36px",
          }}>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6,
              color: "var(--pt-fg-4)", margin: "0 0 24px",
            }}>
              This page is only reachable via the link in a password reset email.
            </p>
            <button
              type="button"
              onClick={() => onNavigate("reseller-forgot-password")}
              style={{
                background: "var(--pt-accent-bg)", color: "var(--pt-accent-fg)", border: "1px solid var(--pt-accent-bg)",
                padding: "16px 22px", cursor: "pointer",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
              }}>Request a reset link →</button>
          </div>
        ) : status === "done" ? (
          <div style={{
            background: "var(--pt-contrast-bg)",
            border: "1px solid var(--pt-contrast-bg)",
            padding: "36px",
          }}>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 16, lineHeight: 1.6,
              color: "var(--pt-contrast-fg-dim)", margin: "0 0 24px",
            }}>
              Your password has been reset. You're signed out on every device — sign in below with your new password.
            </p>
            <button
              type="button"
              onClick={() => onNavigate("reseller-login")}
              style={{
                background: "var(--pt-contrast-fg)", color: "var(--pt-contrast-bg)", border: "1px solid var(--pt-contrast-fg)",
                padding: "16px 22px", cursor: "pointer",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
              }}>Sign in →</button>
          </div>
        ) : (
          <form onSubmit={handleSubmit} style={{
            background: "var(--pt-surface)",
            border: "1px solid var(--pt-border-3)",
            backdropFilter: "blur(6px)",
            padding: "36px",
          }}>
            {error && (
              <div style={{
                background: "var(--pt-error-bg)",
                border: "1px solid var(--pt-error-border)",
                color: "var(--pt-error-text)", padding: "14px 16px", marginBottom: 22,
                fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
              }}>
                {error}
              </div>
            )}

            <FieldBlock label="New password" right={
              <button
                type="button"
                onClick={() => setShowPassword((v) => !v)}
                style={{
                  background: "none", border: "none", cursor: "pointer", padding: 0,
                  fontFamily: "var(--font-body)", fontSize: 10,
                  letterSpacing: "0.22em", textTransform: "uppercase",
                  color: "var(--pt-fg-dim)", fontWeight: 500,
                }}>
                {showPassword ? "Hide" : "Show"}
              </button>
            } hint="At least 10 characters.">
              <DarkInput
                type={showPassword ? "text" : "password"}
                autoComplete="new-password"
                required
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                placeholder="••••••••••••"
              />
            </FieldBlock>

            <FieldBlock label="Confirm new password">
              <DarkInput
                type={showPassword ? "text" : "password"}
                autoComplete="new-password"
                required
                value={confirmPassword}
                onChange={(e) => setConfirmPassword(e.target.value)}
                placeholder="••••••••••••"
              />
            </FieldBlock>
            {password && confirmPassword && password !== confirmPassword && (
              <div style={{
                fontFamily: "var(--font-body)", fontSize: 12.5,
                color: "var(--pt-error-text)", margin: "-10px 0 22px",
              }}>Passwords don't match.</div>
            )}

            <button
              type="submit"
              disabled={!canSubmit}
              style={{
                width: "100%", marginTop: 12,
                background: canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)",
                color: canSubmit ? "var(--pt-accent-fg)" : "var(--pt-accent-fg-disabled)",
                border: `1px solid ${canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)"}`,
                padding: "18px 22px",
                cursor: canSubmit ? "pointer" : "not-allowed",
                fontFamily: "var(--font-body)",
                fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
                transition: "background 140ms, color 140ms",
              }}>
              {status === "submitting" ? "Resetting…" : "Reset password →"}
            </button>
          </form>
        )}
      </div>
    </section>
  );
}

/* ──────────── Field block ──────────── */
function FieldBlock({ label, right, hint, children }) {
  return (
    <label style={{ display: "block", marginBottom: 22 }}>
      <div style={{
        display: "flex", justifyContent: "space-between",
        alignItems: "baseline", marginBottom: 10,
      }}>
        <span style={{
          fontFamily: "var(--font-body)", fontSize: 10,
          letterSpacing: "0.28em", textTransform: "uppercase",
          color: "var(--pt-fg-dim)", fontWeight: 500,
        }}>{label}</span>
        {right}
      </div>
      {children}
      {hint && (
        <div style={{
          fontFamily: "var(--font-body)", fontSize: 11.5,
          color: "var(--pt-fg-faint2)", marginTop: 8, lineHeight: 1.5,
        }}>{hint}</div>
      )}
    </label>
  );
}

/* ──────────── Dark input (name kept, styling now light-theme) ──────────── */
function DarkInput({ ...props }) {
  return (
    <input
      {...props}
      style={{
        width: "100%", boxSizing: "border-box",
        background: "var(--pt-surface-2)",
        border: "1px solid var(--pt-border-strong)",
        color: "var(--pt-fg)",
        fontFamily: "var(--font-body)",
        fontSize: 16, padding: "14px 16px",
        outline: "none",
        transition: "border-color 140ms",
      }}
      onFocus={(e) => e.target.style.borderColor = "var(--pt-fg)"}
      onBlur={(e) => e.target.style.borderColor = "var(--pt-border-strong)"}
    />
  );
}

/* ──────────── Live dot ──────────── */
function LiveDot() {
  return (
    <span style={{
      position: "relative", width: 6, height: 6,
      display: "inline-block",
    }}>
      <span style={{
        position: "absolute", inset: 0,
        background: "var(--pt-fg)", borderRadius: "50%",
      }} />
      <span style={{
        position: "absolute", inset: 0,
        background: "var(--pt-fg-dimmer)", borderRadius: "50%",
        animation: "solo-login-pulse 1.6s cubic-bezier(0,0,0.2,1) infinite",
      }} />
      <style>{`
        @keyframes solo-login-pulse {
          0%   { transform: scale(1);   opacity: 0.7; }
          70%  { transform: scale(2.6); opacity: 0;   }
          100% { transform: scale(2.6); opacity: 0;   }
        }
      `}</style>
    </span>
  );
}

/* ──────────── Corner crosshairs ──────────── */
function CornerHairlines() {
  const arm = 24;
  const off = 28;
  const styleKeys = new Set(["top", "right", "bottom", "left", "width", "height"]);
  const Stroke = (props) => {
    const styleProps = {};
    const domProps = {};
    for (const [k, v] of Object.entries(props)) {
      if (styleKeys.has(k)) styleProps[k] = v;
      else domProps[k] = v;
    }
    return (
      <span
        {...domProps}
        style={{
          position: "absolute",
          background: "var(--pt-border-subtle)",
          ...styleProps,
        }}
      />
    );
  };
  return (
    <div aria-hidden style={{ position: "absolute", inset: 0, pointerEvents: "none", zIndex: 1 }}>
      <Stroke top={off} left={off} width={arm} height={1} />
      <Stroke top={off} left={off} width={1}   height={arm} />
      <Stroke top={off} right={off} width={arm} height={1} />
      <Stroke top={off} right={off} width={1}   height={arm} />
      <Stroke bottom={off} left={off} width={arm} height={1} />
      <Stroke bottom={off} left={off} width={1}   height={arm} />
      <Stroke bottom={off} right={off} width={arm} height={1} />
      <Stroke bottom={off} right={off} width={1}   height={arm} />
    </div>
  );
}

Object.assign(window, { ResellerLoginPage, ResellerForgotPasswordPage, ResellerResetPasswordPage });
