feat(ux): rename creativity levels with descriptive labels and inline descriptions

- "Use What I Have" / "Allow Swaps" / "Get Creative" / "Surprise Me 🎲"
- Active level shows a one-liner description beneath the selector
- Hover tooltips repeat the description for mouse users
- Label changed from "Creativity Level" to "How far should we stretch?"
- Wildcard confirmation copy updated to match new framing
This commit is contained in:
pyr0ball 2026-04-08 15:03:51 -07:00
parent e203ad4bdc
commit 74a7c068bc

View file

@ -40,23 +40,26 @@
<!-- Level Selector --> <!-- Level Selector -->
<div class="form-group"> <div class="form-group">
<label class="form-label">Creativity Level</label> <label class="form-label">How far should we stretch?</label>
<div class="flex flex-wrap gap-sm"> <div class="flex flex-wrap gap-sm">
<button <button
v-for="lvl in levels" v-for="lvl in levels"
:key="lvl.value" :key="lvl.value"
:class="['btn', 'btn-secondary', { active: recipesStore.level === lvl.value }]" :class="['btn', 'btn-secondary', { active: recipesStore.level === lvl.value }]"
@click="recipesStore.level = lvl.value" @click="recipesStore.level = lvl.value"
:title="lvl.description"
> >
{{ lvl.label }} {{ lvl.label }}
</button> </button>
</div> </div>
<p v-if="activeLevel" class="level-description text-sm text-secondary mt-xs">
{{ activeLevel.description }}
</p>
</div> </div>
<!-- Wildcard warning --> <!-- Surprise Me confirmation -->
<div v-if="recipesStore.level === 4" class="status-badge status-warning wildcard-warning"> <div v-if="recipesStore.level === 4" class="status-badge status-warning wildcard-warning">
Wildcard mode uses LLM to generate creative recipes with whatever you have. Results may be The AI will freestyle recipes from whatever you have. Results can be unusual that's part of the fun.
unusual.
<label class="flex-start gap-sm mt-xs"> <label class="flex-start gap-sm mt-xs">
<input type="checkbox" v-model="recipesStore.wildcardConfirmed" /> <input type="checkbox" v-model="recipesStore.wildcardConfirmed" />
<span>I understand, go for it</span> <span>I understand, go for it</span>
@ -644,12 +647,14 @@ function onCooked(recipe: RecipeSuggestion) {
} }
const levels = [ const levels = [
{ value: 1, label: '1 — From Pantry' }, { value: 1, label: 'Use What I Have', description: 'Finds recipes you can make right now using exactly what\'s in your pantry.' },
{ value: 2, label: '2 — Creative Swaps' }, { value: 2, label: 'Allow Swaps', description: 'Same as above, plus recipes where one or two ingredients can be substituted.' },
{ value: 3, label: '3 — AI Scaffold' }, { value: 3, label: 'Get Creative', description: 'AI builds recipes in your chosen cuisine style from what you have. Requires paid tier.' },
{ value: 4, label: '4 — Wildcard 🎲' }, { value: 4, label: 'Surprise Me 🎲', description: 'Fully AI-generated — open-ended and occasionally unexpected. Requires paid tier.' },
] ]
const activeLevel = computed(() => levels.find(l => l.value === recipesStore.level))
const cuisineStyles = [ const cuisineStyles = [
{ id: 'italian', label: 'Italian' }, { id: 'italian', label: 'Italian' },
{ id: 'mediterranean', label: 'Mediterranean' }, { id: 'mediterranean', label: 'Mediterranean' },
@ -796,6 +801,11 @@ onMounted(async () => {
margin-left: var(--spacing-xs); margin-left: var(--spacing-xs);
} }
.level-description {
font-style: italic;
line-height: 1.4;
}
.wildcard-warning { .wildcard-warning {
display: block; display: block;
margin-bottom: var(--spacing-md); margin-bottom: var(--spacing-md);