Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

// valtown-fresh-02022026 /** @jsxImportSource https://esm.sh/react@18.2.0 */

import React, { useState } from "https://esm.sh/react@18.2.0"; import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";

const NO_PHRASES = [ "No πŸ’”", "Pretty please? πŸ₯Ί", "But we'd be so cute together! πŸ’•", "One more chance, pookie?", "Don't break my heart :(", "What about a maybe?", "Please don't do this to me, I'm fragile", ];

function App() { const [noClicks, setNoClicks] = useState(0); const [yesStep, setYesStep] = useState(0);

const yesButtonSize = noClicks * 20 + 16;

const firstImg = "https://media.tenor.com/VIChDQ6ejRQAAAAj/jumping-bear-hearts-no-png.gif"; const secondImg = "https://media.tenor.com/f1xnRxTRxLAAAAAj/bears-with-kisses-bg.gif";

const handleNo = () => { setNoClicks((prev) => prev + 1); };

const handleYes = () => { setYesStep((prev) => prev + 1); };

const getQuestionText = () => { if (yesStep === 0) return "Will you be my Valentine? πŸ’˜"; if (yesStep === 1) return "Are you sure? πŸ₯Ή"; if (yesStep === 2) return "Are you like really sure Preedy πŸ₯ΉπŸ’–"; return ""; };

return ( <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100vh", textAlign: "center", position: "relative", }} > {yesStep < 3 ? ( <>

{getQuestionText()}

      <div>
        <button
          onClick={handleYes}
          className="pulse"
          style={{
            fontSize: yesButtonSize,
            margin: "10px",
            padding: "10px 20px",
            backgroundColor: "green",
            color: "white",
            border: "none",
            borderRadius: "6px",
            cursor: "pointer",
          }}
        >
          Yes
        </button>

        {yesStep === 0 && (
          <button
            onClick={handleNo}
            style={{
              fontSize: 16,
              margin: "10px",
              padding: "10px 20px",
              backgroundColor: "red",
              color: "white",
              border: "none",
              borderRadius: "6px",
              cursor: "pointer",
            }}
          >
            {noClicks === 0
              ? "No"
              : NO_PHRASES[Math.min(noClicks - 1, NO_PHRASES.length - 1)]}
          </button>
        )}
      </div>
    </>
  ) : (
    <>
      <img src={secondImg} />

      {[...Array(12)].map((_, i) => (
        <div
          key={i}
          className="heart"
          style={{
            left: Math.random() * 100 + "%",
            animationDelay: i * 0.2 + "s",
          }}
        >
          πŸ’–
        </div>
      ))}

      <div
        style={{
          fontSize: 42,
          color: "pink",
          fontWeight: "bold",
          padding: "20px",
        }}
      >
        Yayyyyy πŸ’–πŸŽ‰
        <br />
        that’s why I love you babe πŸ₯ΉπŸ’˜
      </div>
    </>
  )}
</div>

); }

function client() { const root = document.getElementById("root"); if (root) createRoot(root).render(); }

if (typeof document !== "undefined") client();

export default async function server(): Promise { return new Response( `

Valentine πŸ’˜ body { margin: 0; font-family: Arial, sans-serif; overflow: hidden; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } .pulse { animation: pulse 1.2s infinite; } @keyframes float { 0% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(-200px); opacity: 0; } } .heart { position: absolute; bottom: 20px; font-size: 24px; animation: float 3s ease-in forwards; } </style>
`, { headers: { "content-type": "text/html" } } ); }