A Pen by mode-mercury on CodePen.
Created
June 5, 2025 16:46
-
-
Save mode-mercury/13e73153f92dc8fa3a00004b9119293d to your computer and use it in GitHub Desktop.
Untitled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Onomancy - Name Divination</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: '#5D5CDE', | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| .glow { | |
| box-shadow: 0 0 20px rgba(93, 92, 222, 0.3); | |
| } | |
| .number-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(40px, 1fr)); | |
| gap: 8px; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white min-h-screen transition-colors duration-300"> | |
| <div class="container mx-auto px-4 py-8 max-w-2xl"> | |
| <!-- Header --> | |
| <div class="text-center mb-8"> | |
| <h1 class="text-4xl font-bold bg-gradient-to-r from-primary to-purple-600 bg-clip-text text-transparent mb-2"> | |
| Onomancy | |
| </h1> | |
| <p class="text-gray-600 dark:text-gray-400">Divine the power hidden in names</p> | |
| </div> | |
| <!-- Points Display --> | |
| <div class="bg-gray-50 dark:bg-gray-800 rounded-xl p-6 mb-6 text-center"> | |
| <div class="flex justify-center items-center space-x-8"> | |
| <div> | |
| <p class="text-sm text-gray-600 dark:text-gray-400">Total Points</p> | |
| <p class="text-2xl font-bold text-primary" id="totalPoints">100</p> | |
| </div> | |
| <div> | |
| <p class="text-sm text-gray-600 dark:text-gray-400">Used Points</p> | |
| <p class="text-2xl font-bold text-green-500" id="usedPoints">0</p> | |
| </div> | |
| <div> | |
| <p class="text-sm text-gray-600 dark:text-gray-400">Points Left</p> | |
| <p class="text-3xl font-bold text-orange-500" id="pointsLeft">100</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Name Input --> | |
| <div class="mb-6"> | |
| <label for="nameInput" class="block text-sm font-medium mb-2">Enter a Name or Word</label> | |
| <input | |
| type="text" | |
| id="nameInput" | |
| placeholder="Type a name..." | |
| class="w-full px-4 py-3 text-base border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 focus:ring-2 focus:ring-primary focus:border-transparent transition-all duration-300" | |
| > | |
| </div> | |
| <!-- Letter Values Display --> | |
| <div class="mb-6" id="letterValues" style="display: none;"> | |
| <h3 class="text-lg font-semibold mb-3">Letter Analysis</h3> | |
| <div class="number-grid" id="letterGrid"></div> | |
| </div> | |
| <!-- Results --> | |
| <div class="bg-gradient-to-br from-primary/10 to-purple-600/10 rounded-xl p-6 mb-6" id="results" style="display: none;"> | |
| <h3 class="text-xl font-semibold mb-4">Onomantic Reading</h3> | |
| <div class="grid grid-cols-2 gap-4 mb-4"> | |
| <div class="text-center"> | |
| <p class="text-sm text-gray-600 dark:text-gray-400">Name Value</p> | |
| <p class="text-2xl font-bold text-primary" id="nameValue">0</p> | |
| </div> | |
| <div class="text-center"> | |
| <p class="text-sm text-gray-600 dark:text-gray-400">Life Path</p> | |
| <p class="text-2xl font-bold text-purple-600" id="lifePath">0</p> | |
| </div> | |
| </div> | |
| <div class="border-t border-gray-200 dark:border-gray-700 pt-4"> | |
| <p class="text-sm text-gray-600 dark:text-gray-400 mb-2">Interpretation</p> | |
| <p class="text-gray-800 dark:text-gray-200" id="interpretation"></p> | |
| </div> | |
| </div> | |
| <!-- Reset Button --> | |
| <button | |
| id="resetBtn" | |
| class="w-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 py-3 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors duration-300" | |
| style="display: none;" | |
| > | |
| Reset Points | |
| </button> | |
| <!-- Numerology Reference --> | |
| <div class="mt-8 bg-gray-50 dark:bg-gray-800 rounded-lg p-4"> | |
| <h4 class="font-semibold mb-2">Numerology System</h4> | |
| <p class="text-sm text-gray-600 dark:text-gray-400 mb-2">A=1, B=2, C=3... I=9, J=1, K=2... (Pythagorean)</p> | |
| <div class="text-xs text-gray-500 dark:text-gray-500 grid grid-cols-9 gap-1"> | |
| <span>A=1</span><span>B=2</span><span>C=3</span><span>D=4</span><span>E=5</span><span>F=6</span><span>G=7</span><span>H=8</span><span>I=9</span> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Dark mode detection | |
| if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { | |
| document.documentElement.classList.add('dark'); | |
| } | |
| window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { | |
| if (event.matches) { | |
| document.documentElement.classList.add('dark'); | |
| } else { | |
| document.documentElement.classList.remove('dark'); | |
| } | |
| }); | |
| // Numerology values (Pythagorean system) | |
| const letterValues = { | |
| // Uppercase letters | |
| 'A': 3, 'B': 4, 'C': 1, 'D': 3, 'E': 4, 'F': 3, 'G': 2, 'H': 3, 'I': 1, | |
| 'J': 2, 'K': 3, 'L': 2, 'M': 4, 'N': 3, 'O': 1, 'P': 2, 'Q': 2, 'R': 3, | |
| 'S': 2, 'T': 2, 'U': 2, 'V': 2, 'W': 4, 'X': 2, 'Y': 3, 'Z': 3, | |
| // Lowercase letters | |
| 'a': 2, 'b': 2, 'c': 1, 'd': 2, 'e': 2, 'f': 3, 'g': 2, 'h': 3, 'i': 1, | |
| 'j': 2, 'k': 3, 'l': 1, 'm': 3, 'n': 2, 'o': 1, 'p': 2, 'q': 2, 'r': 2, | |
| 's': 2, 't': 2, 'u': 2, 'v': 2, 'w': 3, 'x': 2, 'y': 3, 'z': 2, | |
| // Numerals | |
| '0': 1, '1': 1, '2': 2, '3': 2, '4': 3, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, | |
| // Common punctuation (approximated) | |
| '.': 1, ',': 1, ':': 2, ';': 2, '!': 2, '?': 3, | |
| '\'': 1, '"': 2, '`': 1, '~': 2, | |
| '-': 1, '_': 1, '=': 2, '+': 2, | |
| '/': 1, '\\': 1, '|': 1, | |
| '(': 1, ')': 1, '[': 2, ']': 2, '{': 3, '}': 3, | |
| '<': 2, '>': 2, | |
| '@': 4, '#': 4, '$': 3, '%': 4, '^': 2, '&': 5, '*': 3 | |
| }; | |
| // Interpretations for life path numbers | |
| const interpretations = { | |
| 1: "Leadership and independence. You forge your own path with determination.", | |
| 2: "Cooperation and harmony. You excel in partnerships and diplomacy.", | |
| 3: "Creativity and expression. You bring joy and inspiration to others.", | |
| 4: "Stability and hard work. You build lasting foundations through dedication.", | |
| 5: "Freedom and adventure. You seek variety and new experiences.", | |
| 6: "Nurturing and responsibility. You care deeply for family and community.", | |
| 7: "Wisdom and spirituality. You seek deeper truths and understanding.", | |
| 8: "Material success and power. You have strong business acumen.", | |
| 9: "Universal love and service. You work for the greater good of humanity." | |
| }; | |
| let totalPoints = 100; | |
| let usedPoints = 0; | |
| const nameInput = document.getElementById('nameInput'); | |
| const letterValuesDiv = document.getElementById('letterValues'); | |
| const letterGrid = document.getElementById('letterGrid'); | |
| const resultsDiv = document.getElementById('results'); | |
| const totalPointsSpan = document.getElementById('totalPoints'); | |
| const usedPointsSpan = document.getElementById('usedPoints'); | |
| const pointsLeftSpan = document.getElementById('pointsLeft'); | |
| const nameValueSpan = document.getElementById('nameValue'); | |
| const lifePathSpan = document.getElementById('lifePath'); | |
| const interpretationP = document.getElementById('interpretation'); | |
| const resetBtn = document.getElementById('resetBtn'); | |
| function calculateNameValue(name) { | |
| const cleanName = name.toUpperCase().replace(/[^A-Z]/g, ''); | |
| let total = 0; | |
| const letterData = []; | |
| for (let char of cleanName) { | |
| const value = letterValues[char] || 0; | |
| total += value; | |
| letterData.push({ letter: char, value: value }); | |
| } | |
| return { total, letterData }; | |
| } | |
| function reduceToSingleDigit(num) { | |
| while (num > 9) { | |
| num = num.toString().split('').reduce((sum, digit) => sum + parseInt(digit), 0); | |
| } | |
| return num; | |
| } | |
| function updateDisplay() { | |
| const name = nameInput.value.trim(); | |
| if (name === '') { | |
| letterValuesDiv.style.display = 'none'; | |
| resultsDiv.style.display = 'none'; | |
| resetBtn.style.display = 'none'; | |
| return; | |
| } | |
| const { total, letterData } = calculateNameValue(name); | |
| const lifePath = reduceToSingleDigit(total); | |
| // Check if we have enough points | |
| if (total > (totalPoints - usedPoints)) { | |
| letterGrid.innerHTML = ` | |
| <div class="col-span-full text-center text-red-500 p-4 bg-red-50 dark:bg-red-900/20 rounded-lg"> | |
| Not enough points! This name requires ${total} points, but you only have ${totalPoints - usedPoints} left. | |
| </div> | |
| `; | |
| letterValuesDiv.style.display = 'block'; | |
| resultsDiv.style.display = 'none'; | |
| return; | |
| } | |
| // Update points | |
| usedPoints += total; | |
| const pointsLeft = totalPoints - usedPoints; | |
| usedPointsSpan.textContent = usedPoints; | |
| pointsLeftSpan.textContent = pointsLeft; | |
| // Display letter values | |
| letterGrid.innerHTML = letterData.map(({ letter, value }) => ` | |
| <div class="bg-white dark:bg-gray-700 rounded-lg p-2 text-center border border-gray-200 dark:border-gray-600"> | |
| <div class="font-bold text-primary">${letter}</div> | |
| <div class="text-sm text-gray-600 dark:text-gray-400">${value}</div> | |
| </div> | |
| `).join(''); | |
| // Display results | |
| nameValueSpan.textContent = total; | |
| lifePathSpan.textContent = lifePath; | |
| interpretationP.textContent = interpretations[lifePath] || "A unique path awaits you."; | |
| letterValuesDiv.style.display = 'block'; | |
| resultsDiv.style.display = 'block'; | |
| resetBtn.style.display = 'block'; | |
| // Add glow effect temporarily | |
| resultsDiv.classList.add('glow'); | |
| setTimeout(() => resultsDiv.classList.remove('glow'), 2000); | |
| } | |
| function resetPoints() { | |
| usedPoints = 0; | |
| usedPointsSpan.textContent = usedPoints; | |
| pointsLeftSpan.textContent = totalPoints; | |
| nameInput.value = ''; | |
| letterValuesDiv.style.display = 'none'; | |
| resultsDiv.style.display = 'none'; | |
| resetBtn.style.display = 'none'; | |
| } | |
| nameInput.addEventListener('input', updateDisplay); | |
| resetBtn.addEventListener('click', resetPoints); | |
| // Initialize display | |
| totalPointsSpan.textContent = totalPoints; | |
| usedPointsSpan.textContent = usedPoints; | |
| pointsLeftSpan.textContent = totalPoints - usedPoints; | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment