From 2d97937499688d165a79f5a7ca5a35727c406ffb Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 20 Nov 2025 16:53:15 -0500 Subject: [PATCH] Improve mobile layout and iconize consumables --- app.js | 45 +++++++++++++-------- style.css | 118 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 124 insertions(+), 39 deletions(-) diff --git a/app.js b/app.js index e4c1fc6..5de15ea 100644 --- a/app.js +++ b/app.js @@ -9,15 +9,15 @@ ]; const SHOP_ITEMS = [ - { id: 'auto_quill', name: "Auto-Quill", type: 'consumable', category: 'Supplies', price: 15, desc: "Writes the first digit." }, - { id: 'choc_frog', name: "Chocolate Frog", type: 'consumable', category: 'Supplies', price: 25, desc: "Clears Dementors instantly." }, - { id: 'liquid_luck', name: "Liquid Luck", type: 'consumable', category: 'Supplies', price: 40, desc: "Solves problem instantly." }, - { id: 'time_turner', name: "Time Turner", type: 'consumable', category: 'Magic Items', price: 60, desc: "Slows Dementors for 5 spells." }, - { id: 'study_spell', name: "Study Spell", type: 'consumable', category: 'Daily Specials', price: 30, desc: "+25 XP instantly (Mon/Thu).", availableDays: ['Mon','Thu'] }, - { id: 'vault_key', name: "Vault Key", type: 'consumable', category: 'Daily Specials', price: 50, desc: "+100 Gold (Sun only).", availableDays: ['Sun'] }, - { id: 'phoenix_feather', name: "Phoenix Feather", type: 'consumable', category: 'Daily Specials', price: 45, desc: "Boost streak to 5 (Tue/Fri).", availableDays: ['Tue','Fri'] }, - { id: 'shield_charm', name: "Shield Charm", type: 'consumable', category: 'Daily Specials', price: 35, desc: "Reset & slow Dementors for 2 turns (Wed/Sat).", availableDays: ['Wed','Sat'] }, - { id: 'astral_map', name: "Astral Map", type: 'consumable', category: 'Daily Specials', price: 40, desc: "Shows a star hint for this question (Sun/Tue/Thu).", availableDays: ['Sun','Tue','Thu'] }, + { id: 'auto_quill', name: "Auto-Quill", type: 'consumable', category: 'Supplies', price: 15, desc: "Writes the first digit.", icon: 'πŸͺΆ' }, + { id: 'choc_frog', name: "Chocolate Frog", type: 'consumable', category: 'Supplies', price: 25, desc: "Clears Dementors instantly.", icon: '🐸' }, + { id: 'liquid_luck', name: "Liquid Luck", type: 'consumable', category: 'Supplies', price: 40, desc: "Solves problem instantly.", icon: 'πŸ€' }, + { id: 'time_turner', name: "Time Turner", type: 'consumable', category: 'Magic Items', price: 60, desc: "Slows Dementors for 5 spells.", icon: '⏳' }, + { id: 'study_spell', name: "Study Spell", type: 'consumable', category: 'Daily Specials', price: 30, desc: "+25 XP instantly (Mon/Thu).", availableDays: ['Mon','Thu'], icon: 'πŸ“˜' }, + { id: 'vault_key', name: "Vault Key", type: 'consumable', category: 'Daily Specials', price: 50, desc: "+100 Gold (Sun only).", availableDays: ['Sun'], icon: 'πŸ—οΈ' }, + { id: 'phoenix_feather', name: "Phoenix Feather", type: 'consumable', category: 'Daily Specials', price: 45, desc: "Boost streak to 5 (Tue/Fri).", availableDays: ['Tue','Fri'], icon: 'πŸͺΆ' }, + { id: 'shield_charm', name: "Shield Charm", type: 'consumable', category: 'Daily Specials', price: 35, desc: "Reset & slow Dementors for 2 turns (Wed/Sat).", availableDays: ['Wed','Sat'], icon: 'πŸ›‘οΈ' }, + { id: 'astral_map', name: "Astral Map", type: 'consumable', category: 'Daily Specials', price: 40, desc: "Shows a star hint for this question (Sun/Tue/Thu).", availableDays: ['Sun','Tue','Thu'], icon: 'πŸ—ΊοΈ' }, // PETS { id: 'pet_owl', name: "Snowy Owl", type: 'pet', category: 'Familiars', price: 120, desc: "Faithful post owl companion.", class: 'pet-owl', icon: 'πŸ¦‰' }, { id: 'pet_cat', name: "Kneazle Cat", type: 'pet', category: 'Familiars', price: 110, desc: "Clever feline lookout.", class: 'pet-cat', icon: '🐈' }, @@ -475,14 +475,27 @@ } consumables.forEach(item => { const qty = state.inventory[item.id] || 0; - const card = document.createElement('div'); - card.className = 'consumable-card'; - card.innerHTML = ` -
${item.name}
-
Owned: ${qty}
- + const wrap = document.createElement('div'); + wrap.className = 'consumable-icon'; + + const btn = document.createElement('button'); + btn.className = 'consumable-icon-btn'; + btn.innerHTML = ` + ${item.icon || '✨'} + ${qty} `; - holder.appendChild(card); + btn.title = `${item.name} (${qty}) - ${item.desc}`; + btn.setAttribute('aria-label', `${item.name}. Owned ${qty}. Tap to use.`); + btn.disabled = qty <= 0; + btn.onclick = () => useConsumable(item.id); + + const label = document.createElement('div'); + label.className = 'consumable-name'; + label.innerText = item.name; + + wrap.appendChild(btn); + wrap.appendChild(label); + holder.appendChild(wrap); }); } diff --git a/style.css b/style.css index aa65814..6dd3bb7 100644 --- a/style.css +++ b/style.css @@ -19,7 +19,9 @@ radial-gradient(circle at 40% 80%, rgba(255, 255, 255, 0.06), transparent 25%); font-family: 'MedievalSharp', cursive; display: flex; justify-content: center; align-items: center; - min-height: 100vh; margin: 0; color: var(--ink); overflow: hidden; + min-height: 100vh; margin: 0; color: var(--ink); + padding: 16px 10px calc(18px + env(safe-area-inset-bottom)); + overflow-x: hidden; overflow-y: auto; transition: background 0.5s, background-image 0.5s; } @@ -237,6 +239,10 @@ box-shadow: 0 0 40px var(--gold); text-align: center; border: 4px double var(--gold); position: relative; z-index: 100; display: flex; flex-direction: column; transition: background 0.3s, border-color 0.3s; + max-height: calc(100vh - 30px); + overflow-y: auto; + overscroll-behavior: contain; + gap: 6px; } .header-info { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; font-family: 'Cinzel', serif; color: var(--burgundy); font-size: 0.9rem; font-weight: bold; } @@ -299,7 +305,7 @@ } #hint-grid { - display: grid; justify-content: center; gap: 3px; margin: 5px auto; max-width: 200px; max-height: 150px; + display: grid; justify-content: center; gap: 3px; margin: 5px auto; max-width: 220px; max-height: clamp(90px, 30vh, 150px); padding: 6px; border-radius: 8px; position: relative; @@ -355,32 +361,68 @@ } .quick-consumables { display: grid; - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); - gap: 6px; + grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); + gap: 8px; margin: 8px 0; + max-height: 180px; + overflow-y: auto; + padding-right: 4px; } - .quick-consumables .consumable-card { - background: rgba(0,0,0,0.08); - border: 1px solid rgba(0,0,0,0.15); - border-radius: 6px; - padding: 6px; - display: flex; flex-direction: column; gap: 4px; - font-size: 0.8rem; + .consumable-icon { + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; } - .quick-consumables .consumable-card h5 { margin: 0; font-size: 0.9rem; } - .quick-consumables .consumable-card .qty { color: #555; } - .quick-consumables .consumable-card button { - padding: 6px; - font-family: 'Cinzel', serif; - border: 1px solid var(--burgundy); - background: var(--gold); - color: #2c2c2c; + .consumable-icon-btn { + width: 64px; + height: 64px; + border-radius: 14px; + border: 2px solid var(--gold); + background: rgba(0, 0, 0, 0.35); + color: #fffdf2; + font-size: 2rem; + display: flex; + align-items: center; + justify-content: center; cursor: pointer; - border-radius: 4px; - font-weight: bold; + position: relative; + box-shadow: 0 0 10px rgba(255, 217, 102, 0.35); + transition: transform 0.15s ease, box-shadow 0.15s ease; } - .quick-consumables .consumable-card button:disabled { - opacity: 0.4; cursor: not-allowed; + .consumable-icon-btn:focus-visible { + outline: 2px solid var(--gold); + outline-offset: 3px; + } + .consumable-icon-btn:active { transform: translateY(1px); } + .consumable-icon-btn:disabled { + opacity: 0.35; + cursor: not-allowed; + box-shadow: none; + } + .consumable-emoji { filter: drop-shadow(0 0 6px rgba(0,0,0,0.25)); } + .consumable-qty { + position: absolute; + top: -6px; + right: -6px; + background: var(--burgundy); + color: var(--gold); + font-size: 0.75rem; + border: 2px solid var(--gold); + border-radius: 999px; + padding: 2px 6px; + box-shadow: 0 0 6px rgba(0,0,0,0.4); + } + .consumable-name { + text-align: center; + font-size: 0.78rem; + color: #fcefd6; + line-height: 1.1; + min-height: 34px; + display: flex; + align-items: center; + justify-content: center; + padding: 0 4px; } #pet-perch { height: 48px; @@ -593,3 +635,33 @@ .swal2-container { z-index: 3000 !important; } + + /* --- RESPONSIVE --- */ + @media (max-width: 768px) { + body { + align-items: flex-start; + padding: 12px 8px calc(16px + env(safe-area-inset-bottom)); + } + .card-container { + width: 100%; + max-width: 520px; + max-height: calc(100vh - 18px); + } + .header-info { flex-wrap: wrap; gap: 6px; } + .equation { font-size: 2.6rem; } + #answer-display { width: 100%; font-size: 2rem; height: 46px; } + .keypad { gap: 6px; } + .key-btn { padding: 12px 0; font-size: 1.3rem; } + .key-btn.key-cast { padding-bottom: 18px; } + #hint-grid { max-width: 240px; max-height: 120px; } + .quick-consumables { max-height: 150px; } + #pet-perch { height: 42px; margin-top: 4px; } + } + + @media (max-width: 420px) { + .equation { font-size: 2.2rem; } + #answer-display { font-size: 1.8rem; height: 42px; } + .shop-btn, .help-btn { width: 36px; height: 36px; font-size: 1.25rem; } + #xp-text { font-size: 0.75rem; padding: 3px 7px; } + .currency-badge { font-size: 0.8rem; } + }