diff --git a/app/styles.css b/app/styles.css index 5c748ae..2b3fe56 100644 --- a/app/styles.css +++ b/app/styles.css @@ -2651,6 +2651,24 @@ line-height: 1.45; } + .alpha-gematria-match-meta { + display: flex; + flex-wrap: wrap; + gap: 6px; + } + + .alpha-gematria-match-meta-chip { + display: inline-flex; + align-items: center; + padding: 4px 8px; + border: 1px solid #3f3f46; + border-radius: 999px; + background: #11111a; + color: #d4d4d8; + font-size: 11px; + line-height: 1; + } + .alpha-gematria-match-ciphers { display: flex; flex-wrap: wrap; @@ -2680,6 +2698,18 @@ line-height: 1.45; } + @media (max-width: 900px) { + .alpha-gematria-controls.is-input-priority-mode, + .alpha-gematria-controls:has(.alpha-gematria-cipher:disabled) { + grid-template-columns: minmax(0, 1fr); + } + + .alpha-gematria-controls.is-input-priority-mode .alpha-gematria-field-cipher, + .alpha-gematria-controls:has(.alpha-gematria-cipher:disabled) .alpha-gematria-field-cipher { + display: none; + } + } + .alpha-tabs { display: flex; flex-wrap: wrap; diff --git a/app/ui-alphabet-gematria.js b/app/ui-alphabet-gematria.js index 7ae4a5d..d1a090d 100644 --- a/app/ui-alphabet-gematria.js +++ b/app/ui-alphabet-gematria.js @@ -347,7 +347,7 @@ if (inputLabelEl) { inputLabelEl.textContent = reverseMode ? "Value" - : (anagramMode ? "Letters" : (dictionaryMode ? "Starts With" : "Text")); + : (anagramMode ? "Letters" : (dictionaryMode ? "Pattern" : "Text")); } if (cipherLabelEl) { @@ -357,13 +357,16 @@ if (cipherEl) { const disableCipher = reverseMode || anagramMode || dictionaryMode; cipherEl.disabled = disableCipher; - cipherEl.closest(".alpha-gematria-field")?.classList.toggle("is-disabled", disableCipher); + const cipherFieldEl = cipherEl.closest(".alpha-gematria-field"); + const controlsEl = cipherEl.closest(".alpha-gematria-controls"); + cipherFieldEl?.classList.toggle("is-disabled", disableCipher); + controlsEl?.classList.toggle("is-input-priority-mode", disableCipher); } if (inputEl) { inputEl.placeholder = reverseMode ? "Enter a whole number, e.g. 33" - : (anagramMode ? "Type letters or a word, e.g. listen" : (dictionaryMode ? "Type a word start, e.g. lo" : "Type or paste text")); + : (anagramMode ? "Type letters or a word, e.g. listen" : (dictionaryMode ? "Type a pattern, e.g. lo, *ende, d?nkey" : "Type or paste text")); inputEl.inputMode = reverseMode ? "numeric" : "text"; inputEl.spellcheck = !(reverseMode || anagramMode || dictionaryMode); @@ -429,6 +432,39 @@ return payload; } + function appendWordMetadata(cardEl, match) { + if (!(cardEl instanceof HTMLElement) || !match || typeof match !== "object") { + return; + } + + const gematriaValue = Number(match?.gematriaValue); + const syllableValue = Number(match?.syllableValue); + if (!Number.isFinite(gematriaValue) && !Number.isFinite(syllableValue)) { + return; + } + + const metaEl = document.createElement("div"); + metaEl.className = "alpha-gematria-match-meta"; + + if (Number.isFinite(gematriaValue)) { + const gematriaEl = document.createElement("span"); + gematriaEl.className = "alpha-gematria-match-meta-chip"; + gematriaEl.textContent = `Simple Ordinal ${formatCount(gematriaValue)}`; + metaEl.appendChild(gematriaEl); + } + + if (Number.isFinite(syllableValue)) { + const syllableEl = document.createElement("span"); + syllableEl.className = "alpha-gematria-match-meta-chip"; + syllableEl.textContent = `Syllables ${formatCount(syllableValue)}`; + metaEl.appendChild(syllableEl); + } + + if (metaEl.childElementCount) { + cardEl.appendChild(metaEl); + } + } + function renderReverseLookupMatches(payload, numericValue) { const { resultEl, breakdownEl, matchesEl } = getElements(); if (!resultEl || !breakdownEl || !matchesEl) { @@ -477,6 +513,8 @@ cardEl.appendChild(definitionEl); } + appendWordMetadata(cardEl, match); + const ciphersEl = document.createElement("div"); ciphersEl.className = "alpha-gematria-match-ciphers"; const matchCiphers = Array.isArray(match?.ciphers) ? match.ciphers : []; @@ -590,6 +628,8 @@ cardEl.appendChild(definitionEl); } + appendWordMetadata(cardEl, match); + fragment.appendChild(cardEl); }); @@ -606,18 +646,25 @@ const matches = Array.isArray(payload?.matches) ? payload.matches : []; const count = Number(payload?.count); const displayCount = Number.isFinite(count) ? count : matches.length; - const normalizedPrefix = String(payload?.normalized || state.dictionaryInputText || "").trim().toLowerCase(); + const normalizedPattern = String(payload?.normalized || state.dictionaryInputText || "").trim().toLowerCase(); + const hasWildcard = Boolean(payload?.hasWildcard) || normalizedPattern.includes("*") || normalizedPattern.includes("?"); - resultEl.textContent = normalizedPrefix ? `Starts With: ${normalizedPrefix}` : "Starts With: --"; + resultEl.textContent = normalizedPattern ? `Pattern: ${normalizedPattern}` : "Pattern: --"; if (!displayCount) { - breakdownEl.textContent = "No dictionary words matched this prefix."; + breakdownEl.textContent = hasWildcard + ? "No dictionary words matched this pattern." + : "No dictionary words matched this prefix."; matchesEl.hidden = false; - setMatchesMessage(matchesEl, "Try another word start such as lo, arc, or the."); + setMatchesMessage(matchesEl, hasWildcard + ? "Try another pattern such as *ion, *ende, w*rd, or d?nkey." + : "Try another word start such as lo, arc, or the."); return; } - breakdownEl.textContent = `Found ${formatCount(displayCount)} words that start with \"${normalizedPrefix}\".`; + breakdownEl.textContent = hasWildcard + ? `Found ${formatCount(displayCount)} words that match \"${normalizedPattern}\".` + : `Found ${formatCount(displayCount)} words that start with \"${normalizedPattern}\".`; const fragment = document.createDocumentFragment(); matches.forEach((match) => { @@ -637,6 +684,8 @@ cardEl.appendChild(definitionEl); } + appendWordMetadata(cardEl, match); + fragment.appendChild(cardEl); }); @@ -691,16 +740,16 @@ const rawText = state.dictionaryInputText; if (!String(rawText || "").trim()) { - resultEl.textContent = "Starts With: --"; - breakdownEl.textContent = "Enter opening letters to search for dictionary words by prefix."; + resultEl.textContent = "Pattern: --"; + breakdownEl.textContent = "Enter opening letters or use * and ? wildcards to search dictionary words."; matchesEl.hidden = false; - setMatchesMessage(matchesEl, "Dictionary mode finds words that begin with your text, such as lo -> lore or loom."); + setMatchesMessage(matchesEl, "Dictionary mode supports starts-with searches and wildcards such as lo, *ende, w*rd, or d?nkey."); return; } const requestId = state.dictionaryRequestId + 1; state.dictionaryRequestId = requestId; - resultEl.textContent = "Starts With: --"; + resultEl.textContent = "Pattern: --"; breakdownEl.textContent = "Searching dictionary index..."; matchesEl.hidden = false; setMatchesMessage(matchesEl, "Loading matching words..."); @@ -715,7 +764,7 @@ if (requestId !== state.dictionaryRequestId || !isDictionaryMode()) { return; } - resultEl.textContent = "Starts With: --"; + resultEl.textContent = "Pattern: --"; breakdownEl.textContent = "Dictionary lookup is unavailable right now."; matchesEl.hidden = false; setMatchesMessage(matchesEl, "Unable to load dictionary matches from the API."); diff --git a/index.html b/index.html index ec30c25..d04e950 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@ - +