/* global React, ReactDOM, LOGO_PATHS, google */
const { useState, useEffect, useRef, useLayoutEffect } = React;

// ===== Signup API client =====
async function postSignup(body) {
  const res = await fetch("/api/signup", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  let data = null;
  try { data = await res.json(); } catch { /* ignore */ }
  if (!res.ok) {
    const message = (data && data.error) || "Something went wrong. Please try again.";
    throw new Error(message);
  }
  return data;
}

// Wait for the Google Identity Services script to be ready on the page.
function whenGoogleReady(cb) {
  if (typeof window === "undefined") return;
  if (window.google && window.google.accounts && window.google.accounts.id) {
    cb();
    return;
  }
  const start = Date.now();
  const id = setInterval(() => {
    if (window.google && window.google.accounts && window.google.accounts.id) {
      clearInterval(id);
      cb();
    } else if (Date.now() - start > 8000) {
      clearInterval(id);
    }
  }, 100);
}

// ===== Path classification (new SVG, 1704x1654) =====
function classify(p) {
  const f = (p.fill || "").toLowerCase();
  if (p.i === 0) return "skip";
  if (f.startsWith("#c")) return "gold";
  if (f.startsWith("#2")) return "dark";
  if (f.startsWith("#5")) {
    if (p.i === 22 || p.i === 23) return "text-cutout"; // A in MAHJ, D in UNITED
    return "emblem-cutout";
  }
  return "skip";
}
// Approx Y center of each path — used to filter out text (MAHJ/UNITED) in the
// CTA emblem variant (which shows the central mark only).
function pathMeanY(p) {
  const nums = (p.d.match(/(-?\d+\.\d{2,})/g) || []).map(parseFloat);
  const ys = []; for (let j = 1; j < nums.length; j += 2) ys.push(nums[j]);
  const real = ys.filter(y => y > 30 && y < 2000);
  if (!real.length) return 0;
  return real.reduce((a,b) => a+b, 0) / real.length;
}
// Source SVG viewBox is 1704×1654. Emblem occupies roughly Y 460–1200.
// Text top (MAHJ) is Y ~200–400; text bottom (UNITED) is Y ~1280–1420.
function isInEmblemBand(p) {
  const y = pathMeanY(p);
  return y > 450 && y < 1250;
}

// ===== Logo SVG (inline-styled by state) =====
function LogoSVG({ variant, state }) {
  // variant: 'full' (text + emblem) | 'emblem' (CTA tile — emblem only)
  // state:   'hidden' | 'stroking' | 'inked'  | 'engraved' (CTA — carved into bone)
  function pathStyle(kind) {
    const transition = "fill 600ms ease-out 80ms, stroke 400ms ease-out, stroke-width 500ms ease-out 180ms, stroke-dashoffset 900ms cubic-bezier(0.5, 0, 0.4, 1), opacity 280ms ease-out";
    if (kind === "gold") {
      if (state === "hidden") {
        return { transition, fill: "transparent", stroke: "#d7b377", strokeWidth: 5, strokeDasharray: 1, strokeDashoffset: 1, opacity: 0 };
      }
      if (state === "stroking") {
        return { transition, fill: "transparent", stroke: "#d7b377", strokeWidth: 5, strokeDasharray: 1, strokeDashoffset: 0, opacity: 1 };
      }
      if (state === "engraved") {
        return { transition: "none", fill: "#7a1722", stroke: "#7a1722", strokeWidth: 0, strokeDasharray: 1, strokeDashoffset: 0, opacity: 1 };
      }
      // inked
      return { transition, fill: "url(#brass)", stroke: "#c49b54", strokeWidth: 0, strokeDasharray: 1, strokeDashoffset: 0, opacity: 1 };
    }
    if (kind === "dark") {
      // Dark navy backings (under text letters + central disc).
      // Hidden during "hidden" and "stroking" so the stroke draw reads clean;
      // fade in during "inked" beneath the brass fill.
      if (state === "engraved") return { fill: "transparent", opacity: 0, transition: "opacity 200ms ease-out" };
      const show = state === "inked";
      return {
        fill: "#251f4c",
        opacity: show ? 1 : 0,
        transition: "opacity 600ms ease-out 80ms",
      };
    }
    if (kind === "text-cutout") {
      // Letterform interior (A in MAHJ, D in UNITED). Transparent so the actual
      // page ground (oxblood + cloud pattern) shows through and always matches.
      if (state === "engraved") return { fill: "#f4ecd8", opacity: 1, transition: "none" };
      return {
        fill: "transparent",
        opacity: state === "inked" ? 1 : 0,
        transition: "opacity 350ms ease-out 320ms",
      };
    }
    if (kind === "cutout") {
      // Negative space inside the emblem — oxblood, matches outer ground.
      if (state === "engraved") return { fill: "#f4ecd8", opacity: 1, transition: "none" };
      return {
        fill: "#5c131b",
        opacity: state === "inked" ? 1 : 0,
        transition: "opacity 350ms ease-out 320ms",
      };
    }
    return {};
  }

  function ringStyle() {
    if (state === "engraved") {
      return { fill: "none", stroke: "#7a1722", strokeWidth: 8, strokeDasharray: 1, strokeDashoffset: 0, opacity: 1, transition: "none" };
    }
    if (state === "hidden") {
      return {
        fill: "none",
        stroke: "#d7b377",
        strokeWidth: 4,
        strokeDasharray: 1,
        strokeDashoffset: 1,
        opacity: 0,
        transition: "stroke-dashoffset 800ms cubic-bezier(0.5, 0, 0.4, 1) 800ms, opacity 250ms ease-out 800ms, stroke 400ms ease 1500ms",
      };
    }
    if (state === "stroking") {
      return {
        fill: "none",
        stroke: "#d7b377",
        strokeWidth: 4,
        strokeDasharray: 1,
        strokeDashoffset: 0,
        opacity: 1,
        transition: "stroke-dashoffset 800ms cubic-bezier(0.5, 0, 0.4, 1) 800ms, opacity 250ms ease-out 800ms, stroke 400ms ease 1500ms",
      };
    }
    return {
      fill: "none",
      stroke: "#c49b54",
      strokeWidth: 4,
      strokeDasharray: 1,
      strokeDashoffset: 0,
      opacity: 1,
      transition: "stroke-dashoffset 800ms cubic-bezier(0.5, 0, 0.4, 1), opacity 250ms ease-out, stroke 400ms ease",
    };
  }

  return (
    <svg
      viewBox="0 0 1704 1654"
      className="logo-svg"
      xmlns="http://www.w3.org/2000/svg"
      preserveAspectRatio="xMidYMid meet"
    >
      <defs>
        {/* Brass gradient — top lighter, bottom deeper */}
        <linearGradient id="brass" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%"  stopColor="#ecd09b" />
          <stop offset="38%" stopColor="#d8b876" />
          <stop offset="78%" stopColor="#b08947" />
          <stop offset="100%" stopColor="#8a6529" />
        </linearGradient>
        {/* Mask: punch text-cutout shapes out so the page ground shows through. */}
        <mask id="text-cut" maskUnits="userSpaceOnUse" x="0" y="0" width="1704" height="1654">
          <rect x="0" y="0" width="1704" height="1654" fill="white" />
          {LOGO_PATHS.filter(p => classify(p) === "text-cutout").map(p => (
            <path key={"m"+p.i} d={p.d} fill="black" />
          ))}
        </mask>
        {/* Shimmer: a moving bright band masks a brighter "highlight" copy of
            the gold paths, suggesting light traveling across engraved brass. */}
        <linearGradient id="shimmer-band" x1="0" x2="1" y1="0" y2="0">
          <stop offset="0" stopColor="white" stopOpacity="0" />
          <stop offset="0.42" stopColor="white" stopOpacity="0" />
          <stop offset="0.5" stopColor="white" stopOpacity="1" />
          <stop offset="0.58" stopColor="white" stopOpacity="0" />
          <stop offset="1" stopColor="white" stopOpacity="0" />
        </linearGradient>
        <mask id="shimmer-mask" maskUnits="userSpaceOnUse" x="0" y="0" width="1704" height="1654">
          <rect width="1704" height="1654" fill="black" />
          <rect className="shimmer-rect" x="0" y="0" width="1704" height="1654" fill="url(#shimmer-band)" />
        </mask>
      </defs>

      {/* Dark navy disc bodies + emblem oxblood cutouts (rendered beneath gold) */}
      {LOGO_PATHS.map((p) => {
        const k = classify(p);
        if (k !== "dark" && k !== "emblem-cutout") return null;
        if (variant === "emblem" && !isInEmblemBand(p)) return null;
        const kind = k === "dark" ? "dark" : "cutout";
        return <path key={p.i} d={p.d} pathLength="1" style={pathStyle(kind)} />;
      })}

      {/* Gold paths — masked so letterform interiors are true cutouts */}
      <g mask="url(#text-cut)">
        {LOGO_PATHS.map((p) => {
          if (classify(p) !== "gold") return null;
          if (variant === "emblem" && !isInEmblemBand(p)) return null;
          return <path key={p.i} d={p.d} pathLength="1" style={pathStyle("gold")} />;
        })}
      </g>

      {/* Brass shimmer — a brighter overlay copy of the gold paths, masked by
          a horizontal bright band that sweeps across every 8s. Only visible
          once the logo is fully inked. */}
      {state === "inked" && variant === "full" && (
        <g mask="url(#shimmer-mask)" style={{ pointerEvents: "none", mixBlendMode: "screen" }}>
          <g mask="url(#text-cut)">
            {LOGO_PATHS.map((p) => {
              if (classify(p) !== "gold") return null;
              return <path key={"s"+p.i} d={p.d} fill="#ffeec0" opacity="0.85" />;
            })}
          </g>
        </g>
      )}
    </svg>
  );
}

// ===== Single bone tile face (intro 2x2) =====
function Tile({ pos, i }) {
  return (
    <div
      className="tile tile-face"
      data-pos={pos}
      data-i={i}
      style={{
        left: pos === "tl" || pos === "bl" ? "0" : "50%",
        top: pos === "tl" || pos === "tr" ? "0" : "50%",
        width: "50%",
        height: "50%",
        borderRadius:
          pos === "tl" ? "8px 2px 2px 2px"
          : pos === "tr" ? "2px 8px 2px 2px"
          : pos === "br" ? "2px 2px 8px 2px"
          : "2px 2px 2px 8px",
      }}
    >
      <div className="tile-grain"></div>
    </div>
  );
}

// ===== Hero stage =====
function HeroStage({ svgState }) {
  return (
    <div className="logo-stage">
      <div className="tile-cluster">
        <Tile pos="tl" i="0" />
        <Tile pos="tr" i="1" />
        <Tile pos="br" i="2" />
        <Tile pos="bl" i="3" />
      </div>
      <div className="absolute inset-0">
        <LogoSVG variant="full" state={svgState} />
      </div>
    </div>
  );
}

// ===== CTA tile (vertical, mahjong-shaped, carved emblem + 入 + Join the Wall) =====
function CTATile({ open, onOpen, tileRef }) {
  return (
    <div
      ref={tileRef}
      className={`cta-tile tile-face ${open ? "is-open" : ""}`}
      onClick={open ? undefined : onOpen}
      role="button"
      tabIndex={0}
      aria-expanded={open}
      onKeyDown={(e) => {
        if ((e.key === "Enter" || e.key === " ") && !open) {
          e.preventDefault();
          onOpen();
        }
      }}
    >
      <div className="tile-grain"></div>
      <div className="emblem-slot">
        <LogoSVG variant="emblem" state="engraved" />
      </div>
      <div className="cta-rule"></div>
      <div className="cta-han">候 席</div>
      <div className="cta-label">Join the Waitlist</div>
      <div className="cta-arrow" aria-hidden="true">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M3 5 L7 9 L11 5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>
    </div>
  );
}

// ===== Form panel (ink-wash background, contains both input + send tile) =====
function FormPanel({
  open,
  onSubmitEmail,
  onSubmitGoogle,
  submitted,
  email,
  setEmail,
  valid,
  setValid,
  submitting,
  errorMsg,
  googleClientId,
}) {
  const inputRef = useRef(null);
  const googleSlotRef = useRef(null);

  useEffect(() => {
    if (open && inputRef.current && !submitted) {
      const t = setTimeout(() => inputRef.current && inputRef.current.focus(), 380);
      return () => clearTimeout(t);
    }
  }, [open, submitted]);

  // Render the Google Identity button when the form opens and we have a client ID.
  useEffect(() => {
    if (!open || submitted || !googleClientId || !googleSlotRef.current) return;
    let cancelled = false;
    whenGoogleReady(() => {
      if (cancelled || !googleSlotRef.current) return;
      try {
        google.accounts.id.initialize({
          client_id: googleClientId,
          callback: (response) => {
            if (response && response.credential) onSubmitGoogle(response.credential);
          },
          ux_mode: "popup",
          auto_select: false,
        });
        googleSlotRef.current.innerHTML = "";
        google.accounts.id.renderButton(googleSlotRef.current, {
          theme: "filled_black",
          size: "large",
          shape: "pill",
          text: "signin_with",
          logo_alignment: "left",
          width: 280,
        });
      } catch {
        /* GIS not ready or already initialized — silently ignore */
      }
    });
    return () => { cancelled = true; };
  }, [open, submitted, googleClientId, onSubmitGoogle]);

  function handle(e) {
    e.preventDefault();
    if (submitting || submitted) return;
    const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    setValid(ok);
    if (ok) onSubmitEmail(email);
  }

  const helperText = submitted
    ? null
    : errorMsg
      ? errorMsg
      : !valid
        ? "A working address, please."
        : "One letter at the start. Quiet seasonal updates after.";
  const helperColor = errorMsg || !valid ? "#d99b8a" : "rgba(240,230,207,0.5)";

  return (
    <div className={`form-wrap ${open ? "open" : ""}`}>
      <div className="form-panel">
        <span className="form-label">Address · 信</span>
        <form onSubmit={handle} className="flex flex-col sm:flex-row items-stretch gap-3 relative">
          <input
            ref={inputRef}
            type="email"
            required
            value={email}
            onChange={(e) => { setEmail(e.target.value); if (!valid) setValid(true); }}
            placeholder="your.email@studio"
            className="ink-input flex-1"
            aria-label="Email address"
            aria-invalid={!valid}
            disabled={submitted || submitting}
            autoComplete="email"
            spellCheck="false"
          />
          <SubmitTile flipped={submitted} disabled={submitted || submitting} />
        </form>
        <div
          style={{
            position: "relative",
            marginTop: 14,
            fontSize: 13.5,
            color: helperColor,
            fontStyle: "italic",
            letterSpacing: "0.01em",
            minHeight: 18,
          }}
        >
          {helperText}
        </div>

        {!submitted && googleClientId ? (
          <>
            <div className="or-divider"><span>or</span></div>
            <div className="google-slot" ref={googleSlotRef} aria-label="Sign in with Google"></div>
          </>
        ) : null}
      </div>
    </div>
  );
}

// ===== Send tile (smaller companion tile, flips on submit) =====
function SubmitTile({ flipped, disabled }) {
  return (
    <button
      type="submit"
      className={`submit-tile ${flipped ? "flipped" : ""}`}
      disabled={disabled}
      aria-label={flipped ? "Submitted, thank you" : "Submit"}
    >
      <div className="submit-inner">
        <div className="submit-face tile-face">
          <div className="tile-grain"></div>
          <span className="send-han">送</span>
          <span className="send-label">Send</span>
        </div>
        <div className="submit-back tile-face">
          <div className="tile-grain"></div>
          <span className="han-thanks">谢</span>
        </div>
      </div>
    </button>
  );
}

// ===== Confirmation line =====
function Confirmation({ visible, email, wallNumber }) {
  const ordinal = (n) => {
    const s = ["th", "st", "nd", "rd"];
    const v = n % 100;
    return n + (s[(v - 20) % 10] || s[v] || s[0]);
  };
  return (
    <div
      style={{
        marginTop: 14,
        fontSize: 16,
        color: "rgba(240,230,207,0.78)",
        fontStyle: "italic",
        letterSpacing: "0.015em",
        minHeight: 22,
        textAlign: "center",
        opacity: visible ? 1 : 0,
        transform: visible ? "translateY(0)" : "translateY(6px)",
        transition: "opacity 600ms ease 200ms, transform 600ms ease 200ms",
      }}
    >
      Your name is recorded as the{" "}
      <span style={{ color: "var(--gold-bright)", fontStyle: "normal", fontFamily: "'Cormorant Garamond', serif", fontWeight: 500 }}>
        {wallNumber ? ordinal(wallNumber) : "—"}
      </span>{" "}
      tile in the wall.
      <br />
      <span style={{ fontSize: 14, color: "rgba(240,230,207,0.55)" }}>
        We will write to {email ? <span style={{ color: "var(--gold-bright)" }}>{email}</span> : "you"} at the next tile-making.
      </span>
    </div>
  );
}

// ===== App =====
function App() {
  const [phase, setPhase] = useState("pre");
  const [formOpen, setFormOpen] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [submittedEmail, setSubmittedEmail] = useState("");
  const [wallNumber, setWallNumber] = useState(null);
  const [email, setEmail] = useState("");
  const [valid, setValid] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [errorMsg, setErrorMsg] = useState("");
  const [googleClientId, setGoogleClientId] = useState("");

  // Load public Google client ID once on mount
  useEffect(() => {
    let alive = true;
    fetch("/api/config")
      .then((r) => r.ok ? r.json() : null)
      .then((d) => { if (alive && d && d.googleClientId) setGoogleClientId(d.googleClientId); })
      .catch(() => { /* offline / not deployed yet — Google button just won't render */ });
    return () => { alive = false; };
  }, []);

  const stageWrapRef = useRef(null);
  const ctaRef = useRef(null);
  const [settle, setSettle] = useState({ y: 0, scale: 0.22 });

  useLayoutEffect(() => {
    function measure() {
      if (!stageWrapRef.current || !ctaRef.current) return;
      const s = stageWrapRef.current.getBoundingClientRect();
      const c = ctaRef.current.getBoundingClientRect();
      // CTA emblem slot center is ~ (left + width/2, top + 22 + 58)
      const slotCY = c.top + 22 + 58;
      const slotCX = c.left + c.width / 2;
      const stageCY = s.top + s.height / 2;
      const stageCX = s.left + s.width / 2;
      // We want the (full-stage) logo to fit a 116px box. Stage current width ≈ s.width.
      // Logo emblem occupies roughly the bottom 2/3 of the stage at y ~ 612/1274 ≈ 0.48
      const stageWidthPx = s.width;
      const targetWidthPx = 116;
      // The full logo (with text) is wider than the bare emblem; scale so emblem at viewBox center matches slot
      // Visually: target scale that maps the emblem's apparent width (~ 0.78 * stageWidth) to 116
      const scale = targetWidthPx / (stageWidthPx * 0.78);
      // Y offset: distance from stage center to slot center, in unscaled px
      const y = slotCY - stageCY;
      // Slight x offset typically 0 (centered)
      void slotCX; void stageCX;
      setSettle({ y, scale });
    }
    measure();
    const t1 = setTimeout(measure, 100);
    const t2 = setTimeout(measure, 400);
    window.addEventListener("resize", measure);
    return () => {
      clearTimeout(t1); clearTimeout(t2);
      window.removeEventListener("resize", measure);
    };
  }, []);

  function runTimeline() {
    const timers = [];
    timers.push(setTimeout(() => setPhase("tiles"), 80));
    timers.push(setTimeout(() => setPhase("stroking"), 1000));
    timers.push(setTimeout(() => setPhase("inked"), 2050));
    timers.push(setTimeout(() => setPhase("settled"), 2750));
    return timers;
  }

  useEffect(() => {
    const timers = runTimeline();
    return () => timers.forEach(clearTimeout);
  }, []);

  function replay() {
    setPhase("pre");
    setFormOpen(false);
    setSubmitted(false);
    setSubmittedEmail("");
    setEmail("");
    setValid(true);
    setSubmitting(false);
    setErrorMsg("");
    setWallNumber(null);
    setTimeout(() => { runTimeline(); }, 60);
  }

  async function submitWith(body) {
    if (submitting) return;
    setSubmitting(true);
    setErrorMsg("");
    try {
      const data = await postSignup(body);
      setSubmittedEmail(data.email || body.email || "");
      setWallNumber(data.wallNumber || null);
      setSubmitted(true);
    } catch (err) {
      setErrorMsg(err.message || "Something went wrong. Please try again.");
    } finally {
      setSubmitting(false);
    }
  }

  function handleEmailSubmit(submittedAddr) {
    submitWith({ email: submittedAddr });
  }

  function handleGoogleSubmit(credential) {
    submitWith({ credential });
  }

  // Map app phase -> SVG draw state for the HERO logo
  const heroSvgState =
    phase === "stroking" ? "stroking"
    : phase === "inked" || phase === "settled" ? "inked"
    : "hidden";

  return (
    <div
      data-app-state={phase}
      className="relative min-h-screen w-full flex items-center justify-center px-5 py-14"
      style={{ "--settle-y": `${settle.y}px`, "--settle-scale": settle.scale }}
    >
      <div className="flex flex-col items-center w-full max-w-[640px] relative">

        {/* Headline */}
        <div className="reveal text-center px-2" style={{ marginBottom: 22 }}>
          <h1
            className="headline"
            style={{
              fontSize: "clamp(32px, 5.4vw, 50px)",
              lineHeight: 1.08,
              fontWeight: 500,
              letterSpacing: "0.005em",
              margin: 0,
              textWrap: "balance",
            }}
          >
            Every set tells a story.<br />
            Every table{" "}
            <span className="brass-text" style={{ fontStyle: "italic", fontWeight: 400 }}>
              builds a community
            </span>
            .
          </h1>
        </div>

        {/* MAHJ / knot / UNITED — the page's visual anchor; stays put after intro */}
        <div
          ref={stageWrapRef}
          className="relative flex items-center justify-center"
          style={{ marginBottom: 24, minHeight: "clamp(340px, 52vw, 500px)" }}
        >
          <HeroStage svgState={heroSvgState} />
        </div>

        {/* Divider rule */}
        <div className="reveal" style={{ marginTop: 6, marginBottom: 22 }}>
          <div className="gold-rule"></div>
        </div>

        {/* Coming-soon mark */}
        <div className="reveal text-center px-3" style={{ margin: "0 0 22px 0" }}>
          <span
            className="brass-text"
            style={{
              fontFamily: "'Cormorant Garamond', serif",
              fontStyle: "italic",
              fontWeight: 500,
              fontSize: "clamp(22px, 2.9vw, 26px)",
              letterSpacing: "0.3em",
              textTransform: "uppercase",
              textIndent: "0.3em",
              display: "inline-block",
              lineHeight: 1.1,
            }}
          >
            Coming&nbsp;Soon
          </span>
          <div
            className="han-seal"
            style={{
              marginTop: 9,
              fontSize: "clamp(13px, 1.7vw, 15px)",
              letterSpacing: "0.42em",
              textIndent: "0.42em",
              opacity: 0.68,
            }}
          >
            即將開幕
          </div>
        </div>

        {/* Hand-stamped chop seal */}
        <div className="reveal" style={{ marginBottom: 36 }}>
          <div className="chop">
            <span className="chop-glyph">聚</span>
          </div>
        </div>

        {/* CTA + form */}
        <CTATile open={formOpen} onOpen={() => setFormOpen(true)} tileRef={ctaRef} />
        <FormPanel
          open={formOpen}
          submitted={submitted}
          onSubmitEmail={handleEmailSubmit}
          onSubmitGoogle={handleGoogleSubmit}
          email={email}
          setEmail={setEmail}
          valid={valid}
          setValid={setValid}
          submitting={submitting}
          errorMsg={errorMsg}
          googleClientId={googleClientId}
        />
        <Confirmation visible={submitted} email={submittedEmail} wallNumber={wallNumber} />

        {/* Replay link */}
        <button
          onClick={replay}
          className="replay-link"
          style={{
            marginTop: 44,
            background: "transparent",
            border: "none",
            color: "rgba(196,155,84,0.42)",
            fontSize: 12,
            letterSpacing: "0.32em",
            textTransform: "uppercase",
            fontFamily: "'Cormorant Garamond', serif",
            fontStyle: "italic",
            cursor: "pointer",
            opacity: phase === "settled" ? 1 : 0,
            transition: "opacity 800ms ease 700ms, color 250ms",
            padding: 6,
          }}
        >
          replay opening
        </button>
      </div>
    </div>
  );
}

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