feat(ui): implement InstaChef design system
Some checks failed
Build & Push Docker Image / test-and-build (push) Failing after 38s
Some checks failed
Build & Push Docker Image / test-and-build (push) Failing after 38s
- Replace Tailwind with IC CSS design tokens (purple/pink/orange brand gradient, Lilita One / DM Sans / JetBrains Mono fonts, light+dark theme via data-theme) - Add all SVG icon components (ic/Bell, BellOff, Check, Chevron, Clipboard, Close, Download, External, Filter, Link, Plus, Retry, Search, Settings, Share, Spark, Trash, PhasePrepping, PhaseSimmering, PhasePlating) - Add shared primitives: Chip, RecipeThumb (deterministic gradient swatch), CookingPot (animated SVG), PhaseTrack, SectionHead - Add TopBar with LIVE indicator and notification bell - Add CookingHero: animated hero card for in-progress items - Add TimelineRow: queue list row with status badges - Add EmptyState: gradient hero + dismissible How it works card - Add RecipeSheet: bottom-sheet detail overlay with phase progress - Add AddUrlScreen: full-page URL input with clipboard paste - Add NotificationsScreen: push toggle + SSE status - Rewrite +page.svelte: screen router (home/addurl/notifs) + RecipeSheet; preserves all SSE, retry, remove, filter, auto-subscribe logic - Rewrite share/+page.svelte: uses AddUrlScreen shell, preserves Share Target logic and auto-process on URL param - Rewrite InstallPrompt.svelte: InstallSheet bottom-sheet design, all PWA logic intact - Update manifest.json theme_color to #FFF8F5 - 282 unit tests passing (unchanged) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1 +1,171 @@
|
||||
@import 'tailwindcss';
|
||||
/* ─── InstaChef design system ─────────────────────────────────────────────── */
|
||||
|
||||
/* Brand + shared tokens (theme-independent) */
|
||||
:root {
|
||||
--grad-1: #833AB4;
|
||||
--grad-2: #C13584;
|
||||
--grad-3: #E1306C;
|
||||
--grad-4: #FD7E14;
|
||||
--grad-5: #FCAF45;
|
||||
--brand-gradient: linear-gradient(135deg, var(--grad-1) 0%, var(--grad-3) 45%, var(--grad-4) 75%, var(--grad-5) 100%);
|
||||
--brand-gradient-soft: linear-gradient(135deg, #FCE9F3 0%, #FFEAD8 100%);
|
||||
|
||||
--purple: #833AB4;
|
||||
--pink: #E1306C;
|
||||
--orange: #FD7E14;
|
||||
--yellow: #FCAF45;
|
||||
--berry: #C13584;
|
||||
|
||||
--status-pending: #FCAF45;
|
||||
--status-success: #2EA56A;
|
||||
--status-error: #E64B4B;
|
||||
|
||||
--font-display: "Lilita One", "Caprasimo", system-ui, sans-serif;
|
||||
--font-body: "DM Sans", -apple-system, system-ui, sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, monospace;
|
||||
}
|
||||
|
||||
/* Light theme */
|
||||
.ic-root[data-theme="light"] {
|
||||
--bg: #FFF8F5;
|
||||
--bg-tint: #FFEFE4;
|
||||
--surface: #FFFFFF;
|
||||
--surface-2: #FDF1EC;
|
||||
--surface-3: #F7E5DC;
|
||||
--ink: #1A0B1F;
|
||||
--ink-2: #3A2A40;
|
||||
--muted: #7A6B7D;
|
||||
--muted-2: #A8989C;
|
||||
--border: rgba(26, 11, 31, 0.08);
|
||||
--border-strong: rgba(26, 11, 31, 0.14);
|
||||
--shadow-sm: 0 1px 2px rgba(26, 11, 31, 0.04), 0 2px 8px rgba(26, 11, 31, 0.04);
|
||||
--shadow-md: 0 4px 12px rgba(26, 11, 31, 0.06), 0 12px 32px rgba(26, 11, 31, 0.05);
|
||||
--shadow-lg: 0 12px 28px rgba(193, 53, 132, 0.18), 0 24px 60px rgba(131, 58, 180, 0.15);
|
||||
}
|
||||
|
||||
/* Dark theme */
|
||||
.ic-root[data-theme="dark"] {
|
||||
--bg: #110510;
|
||||
--bg-tint: #1A0A1F;
|
||||
--surface: #1F0F24;
|
||||
--surface-2: #2A1730;
|
||||
--surface-3: #371E3E;
|
||||
--ink: #FCEFE5;
|
||||
--ink-2: #E0D2DA;
|
||||
--muted: #A38FA8;
|
||||
--muted-2: #6E5A73;
|
||||
--border: rgba(255, 235, 245, 0.08);
|
||||
--border-strong: rgba(255, 235, 245, 0.16);
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.3);
|
||||
--shadow-lg: 0 12px 28px rgba(225, 48, 108, 0.35), 0 24px 60px rgba(131, 58, 180, 0.3);
|
||||
}
|
||||
|
||||
/* ─── Base reset ──────────────────────────────────────────────────────────── */
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ic-root {
|
||||
font-family: var(--font-body);
|
||||
color: var(--ink);
|
||||
background: var(--bg);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
/* ─── Utility classes ─────────────────────────────────────────────────────── */
|
||||
.ic-display {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.005em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ic-grad-text {
|
||||
background: var(--brand-gradient);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.ic-scroll {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
.ic-scroll::-webkit-scrollbar { display: none; }
|
||||
|
||||
button.ic-btn {
|
||||
background: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/* ─── Animations ──────────────────────────────────────────────────────────── */
|
||||
@keyframes ic-steam {
|
||||
0% { transform: translateY(0) translateX(0) scale(0.6); opacity: 0; }
|
||||
25% { opacity: 0.85; }
|
||||
100% { transform: translateY(-44px) translateX(var(--drift, 4px)) scale(1.4); opacity: 0; }
|
||||
}
|
||||
.ic-steam {
|
||||
animation: ic-steam 2.4s ease-out infinite;
|
||||
animation-delay: var(--delay, 0s);
|
||||
}
|
||||
|
||||
@keyframes ic-bubble {
|
||||
0%, 100% { transform: translateY(0) scale(1); }
|
||||
50% { transform: translateY(-2px) scale(1.05); }
|
||||
}
|
||||
.ic-bubble { animation: ic-bubble 1.6s ease-in-out infinite; }
|
||||
|
||||
@keyframes ic-chop {
|
||||
0%, 100% { transform: rotate(-30deg) translateY(0); }
|
||||
50% { transform: rotate(-8deg) translateY(-2px); }
|
||||
}
|
||||
.ic-chop { animation: ic-chop 0.9s cubic-bezier(.7,0,.3,1) infinite; transform-origin: bottom right; }
|
||||
|
||||
@keyframes ic-shimmer {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(200%); }
|
||||
}
|
||||
.ic-shimmer { animation: ic-shimmer 2s ease-in-out infinite; }
|
||||
|
||||
@keyframes ic-pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.55; transform: scale(0.95); }
|
||||
}
|
||||
.ic-pulse { animation: ic-pulse 1.4s ease-in-out infinite; }
|
||||
|
||||
@keyframes ic-slide-up {
|
||||
from { transform: translateY(100%); }
|
||||
to { transform: translateY(0); }
|
||||
}
|
||||
.ic-slide-up { animation: ic-slide-up 0.32s cubic-bezier(.2,.7,.2,1); }
|
||||
|
||||
@keyframes ic-fade {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
.ic-fade { animation: ic-fade 0.24s ease-out; }
|
||||
|
||||
@keyframes ic-pop {
|
||||
0% { transform: scale(0.6); opacity: 0; }
|
||||
60% { transform: scale(1.08); opacity: 1; }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
.ic-pop { animation: ic-pop 0.4s cubic-bezier(.2,1.4,.4,1); }
|
||||
|
||||
@keyframes ic-live {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.3; }
|
||||
}
|
||||
.ic-live { animation: ic-live 1.4s ease-in-out infinite; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user