Love Calculator

Written by

in

<p>&lt;!DOCTYPE html&gt;<br>&lt;html lang="en"&gt;<br>&lt;head&gt;<br>&lt;meta charset="UTF-8"&gt;<br>&lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;<br>&lt;meta name="description" content="Free Love Calculator. Enter two names to calculate a fun love match percentage instantly."&gt;<br>&lt;meta name="theme-color" content="#fff4f8"&gt;<br>&lt;title&gt;Love Calculator β€” Calculate Your Love Match&lt;/title&gt;<br>&lt;style&gt;<br>:root{--pink:#e83e7d;--pink2:#ff80ab;--ink:#35243c;--muted:#786c80;--line:#f1dce6;--bg:#fff8fb}<br>*{box-sizing:border-box}<br>body{margin:0;min-height:100vh;padding:24px 14px;display:grid;place-items:center;font-family:system-ui,-apple-system,"Segoe UI",sans-serif;color:var(--ink);background:radial-gradient(circle at 15% 10%,#ffe0ec 0,transparent 32%),radial-gradient(circle at 90% 85%,#e9e1ff 0,transparent 30%),var(--bg)}<br>.wrap{width:min(100%,470px)}<br>.brand{text-align:center;font-weight:800;color:var(--pink);font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-bottom:18px}<br>.card{background:rgba(255,255,255,.94);border:1px solid var(--line);border-radius:26px;padding:clamp(22px,6vw,34px);box-shadow:0 22px 65px #6b234516}<br>h1{text-align:center;font-size:clamp(29px,7vw,39px);line-height:1.15;letter-spacing:-1.3px;margin:0 0 9px}<br>.intro{text-align:center;color:var(--muted);font-size:14px;margin:0 0 27px;line-height:1.6}<br>label{display:block;font-size:13px;font-weight:750;margin:0 0 7px}<br>.field{margin-bottom:17px}<br>.inputbox{position:relative}<br>.inputbox span{position:absolute;left:14px;top:50%;transform:translateY(-50%);font-size:19px}<br>input{width:100%;height:54px;border:1px solid #ead9e4;border-radius:14px;padding:0 14px 0 44px;font:inherit;font-size:15px;color:var(--ink);background:#fffafd;outline:none;transition:.2s}<br>input:focus{border-color:var(--pink);box-shadow:0 0 0 4px #e83e7d1b}<br>input::placeholder{color:#b6a9b9}<br>.heart{text-align:center;color:var(--pink);font-size:25px;margin:-5px 0 13px}<br>.error{min-height:21px;color:#b4234e;font-size:12px;margin:0 0 6px}<br>button{font:inherit;cursor:pointer}<br>.calculate{width:100%;min-height:54px;border:0;border-radius:14px;color:#fff;font-weight:800;font-size:16px;background:linear-gradient(110deg,var(--pink2),#d82e70);box-shadow:0 10px 24px #e83e7d36;transition:transform .2s}<br>.calculate:hover{transform:translateY(-2px)}<br>.note{text-align:center;color:var(--muted);font-size:11px;margin:13px 0 0}<br>#result{display:none;margin-top:18px;text-align:center;animation:appear .35s ease}<br>@keyframes appear{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}<br>.names{font-size:19px;font-weight:800;overflow-wrap:anywhere}<br>.names span{color:var(--pink)}<br>.ring{width:174px;height:174px;position:relative;margin:15px auto 10px;display:grid;place-items:center}<br>.ring svg{width:174px;height:174px;transform:rotate(-90deg)}<br>.track{fill:none;stroke:#f7e5ed;stroke-width:12}<br>.progress{fill:none;stroke:url(#grad);stroke-width:12;stroke-linecap:round;stroke-dasharray:502.65;stroke-dashoffset:502.65;transition:stroke-dashoffset 1s ease}<br>.score{position:absolute;display:flex;flex-direction:column;align-items:center;line-height:1.1}<br>.score strong{font-size:43px;letter-spacing:-1.5px}<br>.score small{color:var(--muted);font-size:11px;margin-top:6px}<br>.verdict{font-size:20px;font-weight:850;margin:6px 0}<br>.message{font-size:13px;line-height:1.6;color:var(--muted);margin:0}<br>.again{margin-top:18px;border:1px solid var(--line);background:#fff4f8;color:#b63369;padding:11px 18px;border-radius:12px;font-weight:750}<br>footer{text-align:center;font-size:11px;color:var(--muted);padding:16px 5px 0}<br>@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}<br>&lt;/style&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>&lt;main class="wrap"&gt;<br>  &lt;div class="brand"&gt;β™₯ Love Match&lt;/div&gt;<br>  &lt;section class="card"&gt;<br>    &lt;h1&gt;Love &lt;span style="color:#e83e7d"&gt;Calculator&lt;/span&gt;&lt;/h1&gt;<br>    &lt;p class="intro"&gt;Enter two names and calculate your playful love match percentage.&lt;/p&gt;<br>    &lt;form id="loveForm" novalidate&gt;<br>      &lt;div class="field"&gt;<br>        &lt;label for="yourName"&gt;Your name&lt;/label&gt;<br>        &lt;div class="inputbox"&gt;&lt;span aria-hidden="true"&gt;😊&lt;/span&gt;&lt;input id="yourName" type="text" maxlength="40" placeholder="Enter your name" autocomplete="given-name" required&gt;&lt;/div&gt;<br>      &lt;/div&gt;<br>      &lt;div class="heart" aria-hidden="true"&gt;β™₯&lt;/div&gt;<br>      &lt;div class="field"&gt;<br>        &lt;label for="theirName"&gt;Their name&lt;/label&gt;<br>        &lt;div class="inputbox"&gt;&lt;span aria-hidden="true"&gt;πŸ’—&lt;/span&gt;&lt;input id="theirName" type="text" maxlength="40" placeholder="Enter their name" autocomplete="off" required&gt;&lt;/div&gt;<br>      &lt;/div&gt;<br>      &lt;p class="error" id="error" role="alert" aria-live="polite"&gt;&lt;/p&gt;<br>      &lt;button class="calculate" type="submit"&gt;Calculate Love β™₯&lt;/button&gt;<br>    &lt;/form&gt;<br>    &lt;div id="result" aria-live="polite"&gt;<br>      &lt;div class="names"&gt;&lt;span id="firstResult"&gt;&lt;/span&gt; &amp;amp; &lt;span id="secondResult"&gt;&lt;/span&gt;&lt;/div&gt;<br>      &lt;div class="ring" role="img" id="scoreGraphic" aria-label="Love score"&gt;<br>        &lt;svg viewBox="0 0 180 180" aria-hidden="true"&gt;<br>          &lt;defs&gt;&lt;linearGradient id="grad" x1="0" y1="0" x2="1" y2="1"&gt;&lt;stop offset="0" stop-color="#ff91b7"/&gt;&lt;stop offset="1" stop-color="#d83170"/&gt;&lt;/linearGradient&gt;&lt;/defs&gt;<br>          &lt;circle class="track" cx="90" cy="90" r="80"&gt;&lt;/circle&gt;<br>          &lt;circle class="progress" id="progress" cx="90" cy="90" r="80"&gt;&lt;/circle&gt;<br>        &lt;/svg&gt;<br>        &lt;div class="score"&gt;&lt;strong id="percentage"&gt;0%&lt;/strong&gt;&lt;small&gt;LOVE MATCH&lt;/small&gt;&lt;/div&gt;<br>      &lt;/div&gt;<br>      &lt;div class="verdict" id="verdict"&gt;&lt;/div&gt;<br>      &lt;p class="message" id="message"&gt;&lt;/p&gt;<br>      &lt;button class="again" type="button" id="again"&gt;↻ Calculate Again&lt;/button&gt;<br>    &lt;/div&gt;<br>    &lt;p class="note"&gt;For entertainment only. A name score cannot predict a real relationship.&lt;/p&gt;<br>  &lt;/section&gt;<br>  &lt;footer&gt;Made with β™₯ for a little fun&lt;/footer&gt;<br>&lt;/main&gt;<br>&lt;script&gt;<br>(() =&gt; {<br>  "use strict";<br>  const $ = id =&gt; document.getElementById(id);<br>  const circumference = 2 * Math.PI * 80;<br>  $("progress").style.strokeDasharray = String(circumference);<br><br>  function normalize(name) {<br>    return name.normalize("NFKC").toLocaleLowerCase().replace(/[\s\p{P}\p{S}\p{N}]/gu, "");<br>  }<br>  function hash(text) {<br>    let h = 2166136261;<br>    for (let i = 0; i &lt; text.length; i++) {<br>      h ^= text.charCodeAt(i);<br>      h = Math.imul(h, 16777619);<br>    }<br>    return h &gt;&gt;&gt; 0;<br>  }<br>  function randomFrom(seed) {<br>    return () =&gt; {<br>      seed = (Math.imul(seed, 1664525) + 1013904223) &gt;&gt;&gt; 0;<br>      return seed / 4294967296;<br>    };<br>  }<br>  function calculate(a, b) {<br>    const first = normalize(a), second = normalize(b);<br>    const rng = randomFrom(hash([first, second].sort().join("|")));<br>    return first === second ? 100 : 35 + Math.floor(rng() * 66);<br>  }<br>  function getVerdict(score) {<br>    if (score &gt;= 90) return ["Magical vibes ✨", "A high score in this playful name game! Enjoy the funβ€”real connection grows through kindness and communication."];<br>    if (score &gt;= 75) return ["Sweet match πŸ’—", "A lovely result for your two names. Remember, a real relationship depends on mutual care and respect."];<br>    if (score &gt;= 60) return ["Lovely potential 🌷", "Take this as a bit of fun. Honest conversations and shared values matter much more than a number."];<br>    if (score &gt;= 45) return ["A fun possibility 😊", "This is only a name game, not a verdict on two people or their relationship."];<br>    return ["Keep it light 🌈", "A name score cannot measure feelings or predict compatibility. Real connections are about how people treat each other."];<br>  }<br><br>  $("loveForm").addEventListener("submit", event =&gt; {<br>    event.preventDefault();<br>    const a = $("yourName").value.trim();<br>    const b = $("theirName").value.trim();<br>    $("error").textContent = "";<br>    if (!a || !b) {<br>      $("error").textContent = "Please enter both names first.";<br>      (!a ? $("yourName") : $("theirName")).focus();<br>      return;<br>    }<br>    if ([a, b].some(name =&gt; Array.from(normalize(name)).length &lt; 2)) {<br>      $("error").textContent = "Each name must contain at least two letters.";<br>      return;<br>    }<br>    const score = calculate(a, b);<br>    const [title, message] = getVerdict(score);<br>    $("firstResult").textContent = a;<br>    $("secondResult").textContent = b;<br>    $("percentage").textContent = score + "%";<br>    $("verdict").textContent = title;<br>    $("message").textContent = message;<br>    $("scoreGraphic").setAttribute("aria-label", "Playful love match score: " + score + " percent");<br>    $("progress").style.strokeDashoffset = String(circumference * (1 - score / 100));<br>    $("result").style.display = "block";<br>    $("result").scrollIntoView({behavior: matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth", block: "nearest"});<br>  });<br><br>  $("again").addEventListener("click", () =&gt; {<br>    $("loveForm").reset();<br>    $("result").style.display = "none";<br>    $("error").textContent = "";<br>    $("progress").style.strokeDashoffset = String(circumference);<br>    $("yourName").focus();<br>  });<br>})();<br>&lt;/script&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;</p>

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *