feat(auth): add BrandPanel component for signup screen
Renders brand identity with logo, app name, tagline, and feature icons on green-dark background. Responsive: banner on mobile, 440px column on desktop. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
32
frontend/src/lib/auth/BrandPanel.svelte
Normal file
32
frontend/src/lib/auth/BrandPanel.svelte
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-[var(--green-dark)] flex flex-col items-center justify-center
|
||||||
|
px-6 py-7 text-center
|
||||||
|
md:w-[440px] md:min-h-screen md:px-10 md:py-12"
|
||||||
|
>
|
||||||
|
<span class="text-[28px] md:text-[64px]" aria-hidden="true">🥗</span>
|
||||||
|
|
||||||
|
<h1
|
||||||
|
class="mt-2 font-[var(--font-display)] text-[22px] font-medium tracking-[-0.02em] text-white
|
||||||
|
md:mt-3 md:text-[36px]"
|
||||||
|
>
|
||||||
|
Mealprep
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p class="mt-1 text-[12px] text-[var(--green-light)] md:mt-2 md:text-[15px]">
|
||||||
|
Plan meals, eat well, waste less
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="mt-8 hidden gap-3 md:flex">
|
||||||
|
{#each [{ emoji: '📅', label: 'Plan' }, { emoji: '🍳', label: 'Cook' }, { emoji: '🛒', label: 'Shop' }] as feature (feature.label)}
|
||||||
|
<div
|
||||||
|
class="flex flex-col items-center gap-1 rounded-lg bg-white/10 px-4 py-3"
|
||||||
|
>
|
||||||
|
<span class="text-[18px]">{feature.emoji}</span>
|
||||||
|
<span class="text-[10px] text-[var(--green-light)]">{feature.label}</span>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
34
frontend/src/lib/auth/BrandPanel.test.ts
Normal file
34
frontend/src/lib/auth/BrandPanel.test.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { render, screen } from '@testing-library/svelte';
|
||||||
|
import BrandPanel from './BrandPanel.svelte';
|
||||||
|
|
||||||
|
describe('BrandPanel', () => {
|
||||||
|
it('renders the app name', () => {
|
||||||
|
render(BrandPanel);
|
||||||
|
expect(screen.getByText('Mealprep')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the tagline', () => {
|
||||||
|
render(BrandPanel);
|
||||||
|
expect(screen.getByText('Plan meals, eat well, waste less')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the logo emoji', () => {
|
||||||
|
render(BrandPanel);
|
||||||
|
expect(screen.getByText('🥗')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders three feature icons with labels', () => {
|
||||||
|
render(BrandPanel);
|
||||||
|
expect(screen.getByText('Plan')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Cook')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Shop')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders feature emojis', () => {
|
||||||
|
render(BrandPanel);
|
||||||
|
expect(screen.getByText('📅')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('🍳')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('🛒')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user