feat(planner): align tile design with spec
Front face: - Full dual gradient overlay (dark top 32% → transparent → dark bottom 55%) - Day abbreviation + date number pill at top of each tile - Recipe name 13px/weight-300 with text-shadow - Meta line (cookTimeMin · effort) below name - Glassmorphism tag pills (protein + cuisine only) - State rings via box-shadow (yellow for today, green for selected) - Dimming (opacity 0.42) on non-selected filled tiles Back face: - Koch-Modus as green primary button - Entfernen as red outline (transparent bg) - All buttons 11px / weight 500 EmptyDayTile: add day header + spec-aligned suggestion list layout Page: remove external column header (now rendered inside each tile) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { computeReasoningTags } from './reasoningTags';
|
||||
import { formatDayAbbr } from '$lib/planner/week';
|
||||
|
||||
interface TagItem {
|
||||
id?: string;
|
||||
@@ -46,44 +47,52 @@
|
||||
let reasoningTags = $derived(
|
||||
topSuggestion ? computeReasoningTags(slotMap, topSuggestion.recipe) : []
|
||||
);
|
||||
|
||||
const dayAbbr = $derived(slotDate ? formatDayAbbr(slotDate, 'short') : '');
|
||||
const dateNum = $derived(slotDate ? slotDate.slice(-2).replace(/^0/, '') : '');
|
||||
</script>
|
||||
|
||||
<div
|
||||
data-testid="empty-day-tile"
|
||||
role="group"
|
||||
class="h-full flex flex-col gap-2 p-3"
|
||||
style="border: 1px dashed var(--color-border);"
|
||||
class="h-full flex flex-col overflow-hidden"
|
||||
style="border: 1.5px dashed var(--color-border); border-radius: 10px; background: var(--color-surface); box-shadow: 0 1px 3px rgba(28,28,24,.06);"
|
||||
>
|
||||
<!-- Day header -->
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; padding: 7px 8px 0; flex-shrink: 0;">
|
||||
<span style="font-size: 9px; text-transform: uppercase; letter-spacing: .06em; color: var(--color-text-muted); font-weight: 500;">{dayAbbr}</span>
|
||||
<span style="font-size: 10px; font-weight: 500; color: var(--color-text-muted);">{dateNum}</span>
|
||||
</div>
|
||||
|
||||
<!-- CTA -->
|
||||
{#if isPlanner}
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Gericht wählen"
|
||||
onclick={() => onaddrecipe?.()}
|
||||
class="self-start font-[var(--font-sans)] text-[13px] text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors"
|
||||
>
|
||||
+ Gericht wählen
|
||||
</button>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8px 6px 6px; gap: 2px; flex-shrink: 0; border-bottom: 1px solid var(--color-border);">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Gericht wählen"
|
||||
onclick={() => onaddrecipe?.()}
|
||||
style="background: none; border: none; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 2px;"
|
||||
>
|
||||
<span style="font-size: 18px; color: var(--color-border); line-height: 1;">+</span>
|
||||
<span style="font-size: 9px; color: var(--color-text-muted); font-family: var(--font-sans);">Gericht wählen</span>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if topSuggestion}
|
||||
<p class="font-[var(--font-display)] text-[12px] text-[var(--color-text-muted)] leading-snug">
|
||||
{topSuggestion.recipe.name}
|
||||
</p>
|
||||
|
||||
{#if reasoningTags.length > 0}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<div style="display: flex; flex-direction: column; padding: 5px 7px 6px; flex: 1; overflow: hidden;">
|
||||
<div style="font-size: 8px; font-weight: 500; letter-spacing: .07em; text-transform: uppercase; color: var(--color-text-muted); padding: 3px 0 5px; border-bottom: 1px solid var(--color-subtle, var(--color-border)); margin-bottom: 2px;">Vorschlag</div>
|
||||
<div style="display: flex; align-items: center; gap: 4px; padding: 5px 0;">
|
||||
<span style="font-family: var(--font-display); font-size: 11px; font-weight: 300; color: var(--color-text); flex: 1; line-height: 1.2;">{topSuggestion.recipe.name}</span>
|
||||
{#each reasoningTags as tag (tag.id)}
|
||||
<span
|
||||
data-testid="reasoning-tag"
|
||||
class="inline-block rounded px-1.5 py-0.5 font-[var(--font-sans)] text-[11px] font-medium"
|
||||
style={tag.color === 'green'
|
||||
? 'background: var(--green-tint); color: var(--green-dark);'
|
||||
: 'background: var(--yellow-tint); color: var(--yellow-text);'}
|
||||
style="font-size: 8px; font-weight: 500; padding: 1px 4px; border-radius: 2px; white-space: nowrap; flex-shrink: 0; {tag.color === 'green' ? 'background: var(--green-tint); color: var(--green-dark);' : 'background: var(--yellow-tint); color: var(--yellow-text);'}"
|
||||
>
|
||||
{tag.label}
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user