From 6c00e1a00d51dde7de22359661b25b875614d127 Mon Sep 17 00:00:00 2001 From: LordSchmackes Date: Thu, 21 May 2026 11:52:40 +0200 Subject: [PATCH] feat(phase-1): Premium design system, CapitoliumPreloader, IndexSectionIndicator, Recipe Showcase Stage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Full CSS rewrite: Warm Ivory/Gold/Steinkohle design tokens, Floema grid, easing library - AuraMarbleBackground: fixed grain texture layer - CapitoliumPreloader: fullscreen counter animation with slide-up exit - LiquidOverlayMenu: fixed hamburger → fullscreen clip-path overlay with SlideUpTextHover nav links - IndexSectionIndicator: fixed left-side section tracker with animated fill line - Recipe Showcase Stage: GSAP ScrollTrigger pinned stage (images enter from right, exit left) with parallax inner-image effect, intro title, progress dots, hint line - LenisSmoothScroll: CDN integration synced with GSAP ticker - CapitoliumRevealButton: scaleY fill reveal on hover for all CTAs - SlideUpTextHover: overlay nav links - UnderlineExpandHover: footer + overlay footer links - head.php: GSAP 3.12.5 + ScrollTrigger + Lenis 1.0.42 CDN; Playfair Display + Manrope fonts - recipe.php: updated to new design system (btn-reveal, pill--gold, Lenis init) - impressum.php / datenschutz.php: migrated to shared head.php partial --- assets/style.css | 2096 ++++++++++++++++++++++++++----------------- datenschutz.php | 79 +- impressum.php | 81 +- index.php | 695 +++++++++++--- partials/footer.php | 69 +- partials/head.php | 29 +- partials/header.php | 135 ++- recipe.php | 137 +-- 8 files changed, 2145 insertions(+), 1176 deletions(-) diff --git a/assets/style.css b/assets/style.css index f3a53d3..caaaa27 100644 --- a/assets/style.css +++ b/assets/style.css @@ -1,33 +1,97 @@ /* ═══════════════════════════════════════════════════════════════ - FlixCooks — Design System + Landing Page + FlixCooks — Premium Design System (Phase 1) + Inspired by Capitolium, fromanother & Floema ═══════════════════════════════════════════════════════════════ */ -/* ── Tokens ─────────────────────────────────────────────────────── */ +/* ── 1. PREMIUM COLOR TOKENS (Warm Ivory + Steinkohle + Gold) ─── */ :root { - --bg: #f0f2f7; - --bg-2: #e5e8ef; - --surface: #ffffff; - --surface-2: #f7f8fb; - --panel: #f9fafc; - --panel-2: #f2f4f8; - --stroke: #d9deea; - --ghost: rgba(107,118,140,0.14); - --ink: #1c1f29; - --muted: #5c6477; - --accent: #6b768c; - --accent-soft: rgba(107,118,140,0.12); - --accent-2: #8ea0c3; - --shadow: 0 10px 28px rgba(12,16,28,0.12); - --radius: 12px; + /* === WARM PREMIUM PALETTE (Light Mode – main brand) === */ + --color-bg-light: #f2efea; /* Warm Ivory / Creme */ + --color-bg-dark: #241f21; /* Steinkohle-Braun */ + --color-accent-gold: #c3a677; /* Edles Mattgold */ + --color-terracotta: #c87a5a; /* Terracotta */ + --color-light-gold: #f0e3cf; /* Helles Creme-Gold */ + --color-white: #ffffff; + --color-text-muted: #a7a0a1; /* Hellgrau */ + --color-text-dark: #58595b; /* Dunkelgrau */ - /* Landing-specific */ - --land-bg: #0d0e11; - --land-text: #f0f2f7; - --land-muted: rgba(240,242,247,0.55); - --land-accent: #e8c87a; - --land-accent2: #c87a5a; + /* === FLOEMA GRID SYSTEM === */ + --grid-gap: clamp(14px, 9.71px + 1.1vw, 28px); + --grid-margin: clamp(16px, 10.15px + 1.5vw, 36px); + --grid-width: calc(100vw - var(--grid-margin) * 2); + + /* === EASING LIBRARY === */ + --ease-out-expo: cubic-bezier(0.165, 0.84, 0.44, 1); + --ease-in-out-quart: cubic-bezier(0.76, 0, 0.24, 1); + --ease-in-out-cubic: cubic-bezier(0.65, 0, 0.35, 1); + --ease-fluid-slide: cubic-bezier(0.19, 1, 0.22, 1); + --ease-overshoot: cubic-bezier(0.34, 1.56, 0.64, 1); + + /* === TYPOGRAPHY === */ + --font-serif-display: 'Playfair Display', 'Times New Roman', serif; + --font-serif-classic: 'Playfair Display', 'Georgia', serif; + --font-sans-clean: 'Manrope', system-ui, -apple-system, sans-serif; + + /* === FUNCTIONAL TOKENS (maps to UI light mode) === */ + --bg: var(--color-bg-light); + --bg-2: #e8e4dc; + --surface: #ffffff; + --surface-2: #f7f3ed; + --panel: #f4f0e9; + --panel-2: #ede9e1; + --stroke: rgba(36,31,33,0.12); + --ghost: rgba(36,31,33,0.07); + --ink: var(--color-bg-dark); + --muted: var(--color-text-dark); + --accent: var(--color-accent-gold); + --accent-soft: rgba(195,166,119,0.14); + --accent-2: #b09060; + --shadow: 0 10px 32px rgba(36,31,33,0.10); + --radius: 14px; + + /* === LANDING TOKENS (dark atmosphere) === */ + --land-bg: #0d0e11; + --land-text: #f0f2f7; + --land-muted: rgba(240,242,247,0.55); + --land-accent: #e8c87a; + --land-accent2: #c87a5a; + --land-blob-a: #4a3a6e; + --land-blob-b: #6b3a2a; + --land-blob-c: #1a3a5a; + --land-chip-bg: rgba(255,255,255,0.07); + --land-chip-border: rgba(255,255,255,0.12); + --land-chip-text: rgba(240,242,247,0.75); + --land-toggle-border: rgba(255,255,255,0.15); + --land-toggle-bg: rgba(255,255,255,0.06); + --land-toggle-color: rgba(240,242,247,0.7); + --land-scroll-line: rgba(240,242,247,0.5); + --land-scroll-text: rgba(240,242,247,0.4); + --land-grain: 0.03; } +/* === LIGHT MODE LANDING TOKENS === */ +:root, +[data-theme="light"] { + --land-bg: #f4f1eb; + --land-text: #1c1f29; + --land-muted: rgba(28,31,41,0.55); + --land-accent: #b07d2a; + --land-accent2: #8a4a20; + --land-blob-a: #c9b8e8; + --land-blob-b: #e8c0a0; + --land-blob-c: #a8c4d8; + --land-chip-bg: rgba(28,31,41,0.06); + --land-chip-border: rgba(28,31,41,0.12); + --land-chip-text: rgba(28,31,41,0.70); + --land-toggle-border: rgba(28,31,41,0.15); + --land-toggle-bg: rgba(28,31,41,0.06); + --land-toggle-color: rgba(28,31,41,0.6); + --land-scroll-line: rgba(28,31,41,0.35); + --land-scroll-text: rgba(28,31,41,0.35); + --land-grain: 0.04; +} + +/* === DARK MODE TOKENS === */ [data-theme="dark"] { --bg: #131519; --bg-2: #0f1114; @@ -39,16 +103,34 @@ --ghost: rgba(180,190,220,0.08); --ink: #dde0ea; --muted: #8892a6; - --accent: #8ea0c3; - --accent-soft: rgba(142,160,195,0.15); - --accent-2: #6b80a4; - --shadow: 0 10px 28px rgba(0,0,0,0.35); + --accent: #c3a677; + --accent-soft: rgba(195,166,119,0.15); + --accent-2: #a08050; + --shadow: 0 10px 32px rgba(0,0,0,0.4); + + --land-bg: #0d0e11; + --land-text: #f0f2f7; + --land-muted: rgba(240,242,247,0.55); + --land-accent: #e8c87a; + --land-accent2: #c87a5a; + --land-blob-a: #4a3a6e; + --land-blob-b: #6b3a2a; + --land-blob-c: #1a3a5a; + --land-chip-bg: rgba(255,255,255,0.07); + --land-chip-border: rgba(255,255,255,0.12); + --land-chip-text: rgba(240,242,247,0.75); + --land-toggle-border: rgba(255,255,255,0.15); + --land-toggle-bg: rgba(255,255,255,0.06); + --land-toggle-color: rgba(240,242,247,0.7); + --land-scroll-line: rgba(240,242,247,0.5); + --land-scroll-text: rgba(240,242,247,0.4); + --land-grain: 0.03; } -/* ── Base reset ──────────────────────────────────────────────────── */ + +/* ── 2. BASE RESET ────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } -/* Prevent accidental horizontal overflow on mobile */ html, body { width: 100%; max-width: 100%; @@ -56,25 +138,23 @@ html, body { } html { - scroll-behavior: smooth; + scroll-behavior: auto; /* Lenis takes over */ scroll-padding-top: 5rem; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body { - font-family: 'Manrope', system-ui, -apple-system, sans-serif; + font-family: var(--font-sans-clean); color: var(--ink); - background: - radial-gradient(circle at 25% 20%, rgba(107,118,140,0.08), transparent 28%), - radial-gradient(circle at 78% 4%, rgba(142,160,195,0.10), transparent 32%), - linear-gradient(140deg, var(--bg), var(--bg-2)); + background: var(--bg); min-height: 100vh; line-height: 1.6; + transition: background-color 0.4s ease, color 0.4s ease; } h1, h2, h3, h4 { - font-family: 'Playfair Display', 'Times New Roman', serif; + font-family: var(--font-serif-display); margin: 0; color: var(--ink); line-height: 1.15; @@ -82,7 +162,7 @@ h1, h2, h3, h4 { } h1 span, h2 span { color: var(--accent); } p { color: var(--muted); line-height: 1.6; } -a { color: var(--ink); text-decoration: none; transition: color 0.18s; } +a { color: var(--ink); text-decoration: none; transition: color 0.22s; } a:hover { color: var(--accent); } img, picture { display: block; max-width: 100%; height: auto; } @@ -93,10 +173,461 @@ img, picture { display: block; max-width: 100%; height: auto; } } } -/* ══════════════════════════════════════════════════════════════════ - LANDING SECTION - ══════════════════════════════════════════════════════════════════ */ +/* ── 3. CAPITOLIUM PRELOADER ─────────────────────────────────── */ +.preloader { + position: fixed; + inset: 0; + z-index: 10000; + background-color: var(--color-bg-dark); + display: flex; + align-items: center; + justify-content: center; + transition: transform 0.9s var(--ease-in-out-quart), + opacity 0.5s ease 0.6s; + will-change: transform; +} +.preloader.loaded { + transform: translateY(-100vh); + opacity: 0; + pointer-events: none; +} +.preloader-content { + text-align: center; + width: clamp(200px, 50vw, 400px); + display: grid; + gap: 1.25rem; +} +.preloader-logo { + font-family: var(--font-serif-display); + font-size: clamp(1.8rem, 4vw, 2.8rem); + text-transform: uppercase; + letter-spacing: 0.28em; + color: var(--color-light-gold); + font-weight: 600; +} +.preloader-logo span { + color: var(--color-accent-gold); + font-style: italic; +} +.preloader-bar { + width: 100%; + height: 1px; + background-color: rgba(240,227,207,0.15); + position: relative; + overflow: hidden; +} +.preloader-fill { + width: 0%; + height: 100%; + background: linear-gradient(90deg, var(--color-accent-gold), var(--color-light-gold)); + transition: width 0.08s linear; + transform-origin: left; +} +.preloader-text { + font-family: var(--font-sans-clean); + font-size: 0.75rem; + letter-spacing: 0.18em; + text-transform: uppercase; + color: rgba(240,227,207,0.45); +} +.preloader-perc { + color: var(--color-accent-gold); + font-weight: 700; +} +/* ── 4. AURA MARBLE BACKGROUND ───────────────────────────────── */ +.bg-marble-container { + position: fixed; + inset: 0; + z-index: -2; + overflow: hidden; + background-color: var(--bg); + pointer-events: none; + transition: background-color 0.4s ease; +} +.bg-marble-grain { + position: absolute; + inset: 0; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); + opacity: 0.035; + mix-blend-mode: overlay; + pointer-events: none; +} + + +/* ── 5. FLOEMA LAYOUT GRID ───────────────────────────────────── */ +.g-row { + display: flex; + flex-flow: row wrap; + padding-left: calc(var(--grid-margin) - var(--grid-gap) * 0.5); + padding-right: calc(var(--grid-margin) - var(--grid-gap) * 0.5); + width: 100%; +} +.g-col { + padding-left: calc(var(--grid-gap) * 0.5); + padding-right: calc(var(--grid-gap) * 0.5); +} +.col-left { flex: 0 0 33.333%; max-width: 33.333%; } +.col-right { flex: 0 0 66.667%; max-width: 66.667%; } +.col-half { flex: 0 0 50%; max-width: 50%; } +.col-full { flex: 0 0 100%; max-width: 100%; } +@media (max-width: 768px) { + .col-left, .col-right, .col-half { flex: 0 0 100%; max-width: 100%; } +} + + +/* ── 6. CAPITOLIUM CLASSIC TYPOGRAPHY ────────────────────────── */ +.editorial-header { + text-align: center; + position: relative; + padding: clamp(3rem, 5vw, 8rem) 1rem; +} +.editorial-script { + font-family: 'Brush Script MT', cursive; + font-size: clamp(8rem, 15vw, 22rem); + color: var(--color-accent-gold); + line-height: 0.3; + display: block; + opacity: 0.65; +} +.editorial-title { + font-family: var(--font-serif-display); + font-size: clamp(2.5rem, 4vw, 5.5rem); + text-transform: uppercase; + letter-spacing: -0.02em; + color: var(--ink); + margin-top: -1rem; +} +.editorial-subtitle { + font-family: var(--font-serif-classic); + font-style: italic; + font-size: 1.15rem; + letter-spacing: 0.1em; + color: var(--color-text-muted); + text-transform: uppercase; + margin-top: 1rem; +} + + +/* ── 7. CAPITOLIUM REVEAL BUTTON ─────────────────────────────── */ +.btn-reveal { + background: transparent; + border: 1px solid var(--color-accent-gold); + color: var(--ink); + padding: 1.15rem 2.5rem; + font-family: var(--font-serif-display); + font-size: 0.88rem; + text-transform: uppercase; + letter-spacing: 0.16em; + position: relative; + overflow: hidden; + display: inline-flex; + align-items: center; + gap: 0.75rem; + transition: color 0.4s var(--ease-out-expo); + z-index: 1; + cursor: pointer; + text-decoration: none; +} +.btn-reveal::before { + content: ""; + position: absolute; + inset: 0; + background-color: var(--color-accent-gold); + transform: scaleY(0); + transform-origin: bottom; + transition: transform 0.45s var(--ease-fluid-slide); + z-index: -1; +} +.btn-reveal-text { + transition: letter-spacing 0.4s var(--ease-fluid-slide), + padding-left 0.4s var(--ease-fluid-slide); +} +.btn-reveal-arrow { + transition: transform 0.4s var(--ease-fluid-slide); + display: inline-block; + font-style: normal; +} +.btn-reveal:hover { color: var(--color-white); } +.btn-reveal:hover::before { transform: scaleY(1); } +.btn-reveal:hover .btn-reveal-text { letter-spacing: 0.24em; padding-left: 0.08em; } +.btn-reveal:hover .btn-reveal-arrow { transform: translateX(6px) scale(1.1); } + + +/* ── 8. SLIDE UP TEXT HOVER ──────────────────────────────────── */ +.slide-hover-link { + display: inline-block; + text-decoration: none; + color: var(--ink); + font-family: var(--font-serif-display); + font-weight: 500; + overflow: hidden; + line-height: 1; +} +.slide-hover-wrapper { + display: block; + position: relative; + overflow: hidden; + height: 1.2em; +} +.slide-text-main, +.slide-text-clone { + display: block; + transition: transform 0.5s var(--ease-out-expo); + line-height: 1.2em; + will-change: transform; +} +.slide-text-clone { + position: absolute; + top: 100%; + left: 0; + width: 100%; + color: var(--color-accent-gold); +} +.slide-hover-link:hover .slide-text-main { transform: translateY(-100%); } +.slide-hover-link:hover .slide-text-clone { transform: translateY(-100%); } + + +/* ── 9. UNDERLINE EXPAND HOVER ───────────────────────────────── */ +.underline-link { + position: relative; + color: currentColor; + text-decoration: none; + display: inline-block; +} +.underline-link::after { + content: ""; + position: absolute; + bottom: -2px; + left: 0; + width: 100%; + height: 1px; + background-color: currentColor; + transform: scaleX(0); + transform-origin: left; + transition: transform 0.5s var(--ease-out-expo); +} +.underline-link:hover::after { transform: scaleX(1); } + + +/* ── 10. FLOEMA NUDGE HOVER ──────────────────────────────────── */ +.nudge-link { + display: inline-block; + transition: margin 0.3s cubic-bezier(0.19, 1, 0.22, 1); + color: var(--ink); + text-decoration: none; +} +.nudge-link:hover { + margin-left: 6px; + color: var(--color-accent-gold); +} + + +/* ── 11. LIQUID OVERLAY MENU ─────────────────────────────────── */ +.nav-trigger { + position: fixed; + top: clamp(1rem, 2vw, 1.75rem); + right: var(--grid-margin); + z-index: 1001; + width: 52px; + height: 52px; + background: rgba(242,239,234,0.88); + border: 1px solid rgba(195,166,119,0.45); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); + transition: background 0.3s ease, border-color 0.3s ease; +} +[data-theme="dark"] .nav-trigger { + background: rgba(26,29,36,0.88); + border-color: rgba(195,166,119,0.3); +} +.nav-trigger:hover { + background: rgba(195,166,119,0.15); +} +.nav-trigger.active { + background: var(--color-accent-gold); + border-color: var(--color-accent-gold); +} + +.nav-burger-lines { + width: 20px; + height: 14px; + position: relative; + display: block; +} +.nav-line { + position: absolute; + width: 100%; + height: 1.5px; + background-color: var(--color-bg-dark); + transition: transform 0.4s var(--ease-fluid-slide), + opacity 0.3s ease, + background-color 0.3s ease; +} +[data-theme="dark"] .nav-line { background-color: var(--color-light-gold); } +.nav-trigger.active .nav-line { background-color: var(--color-white); } +.nav-line--top { top: 0; } +.nav-line--mid { top: 6px; } +.nav-line--bot { top: 12px; } +.nav-trigger.active .nav-line--top { transform: translateY(6px) rotate(45deg); } +.nav-trigger.active .nav-line--mid { opacity: 0; transform: scaleX(0); } +.nav-trigger.active .nav-line--bot { transform: translateY(-6px) rotate(-45deg); } + +/* Logo header (top-left fixed) */ +.nav-logo { + position: fixed; + top: clamp(0.8rem, 1.5vw, 1.5rem); + left: var(--grid-margin); + z-index: 1001; + display: flex; + align-items: center; +} +.nav-logo img { + height: clamp(48px, 7vw, 80px); + width: auto; + display: block; + transition: opacity 0.3s ease; +} +.nav-logo .logo--dark { display: none; } +[data-theme="dark"] .nav-logo .logo--light { display: none; } +[data-theme="dark"] .nav-logo .logo--dark { display: block; } + +/* Overlay */ +.nav-overlay { + position: fixed; + inset: 0; + z-index: 1000; + background-color: var(--color-bg-light); + display: flex; + align-items: center; + justify-content: center; + clip-path: inset(0 0 100% 0); + transition: clip-path 0.8s var(--ease-fluid-slide); + will-change: clip-path; +} +[data-theme="dark"] .nav-overlay { + background-color: #131519; +} +.nav-overlay.open { + clip-path: inset(0 0 0% 0); +} +.nav-overlay-inner { + padding: var(--grid-margin); + text-align: center; + width: 100%; + max-width: 800px; +} +.nav-menu-list { + list-style: none; + padding: 0; + margin: 0; +} +.nav-menu-list li { + margin: clamp(1.5rem, 3vh, 2.5rem) 0; + opacity: 0; + transform: translateY(20px); + transition: opacity 0.4s ease, transform 0.4s var(--ease-out-expo); +} +.nav-overlay.open .nav-menu-list li { + opacity: 1; + transform: translateY(0); +} +.nav-menu-list li:nth-child(1) { transition-delay: 0.15s; } +.nav-menu-list li:nth-child(2) { transition-delay: 0.22s; } +.nav-menu-list li:nth-child(3) { transition-delay: 0.29s; } +.nav-menu-list li:nth-child(4) { transition-delay: 0.36s; } +.nav-menu-list .slide-hover-link { + font-size: clamp(2rem, 4.5vw, 5rem); + color: var(--color-bg-dark); + letter-spacing: -0.02em; +} +[data-theme="dark"] .nav-menu-list .slide-hover-link { + color: var(--color-light-gold); +} +.nav-overlay-footer { + margin-top: clamp(2rem, 4vh, 4rem); + display: flex; + justify-content: center; + gap: 2rem; + opacity: 0; + transform: translateY(10px); + transition: opacity 0.4s ease 0.4s, transform 0.4s var(--ease-out-expo) 0.4s; +} +.nav-overlay.open .nav-overlay-footer { + opacity: 1; + transform: translateY(0); +} +.nav-overlay-footer a { + font-size: 0.85rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--color-text-muted); + transition: color 0.25s ease; +} +.nav-overlay-footer a:hover { color: var(--color-accent-gold); } + +/* Body scroll lock when overlay is open */ +body.nav-open { overflow: hidden; } + + +/* ── 12. INDEX SECTION INDICATOR ─────────────────────────────── */ +.section-indicator { + position: fixed; + left: var(--grid-margin); + top: 50%; + transform: translateY(-50%); + display: flex; + flex-direction: column; + align-items: center; + gap: 0.9rem; + z-index: 100; + font-family: var(--font-sans-clean); + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--color-accent-gold); + pointer-events: none; + opacity: 0; + transition: opacity 0.4s ease; +} +.section-indicator.visible { opacity: 1; } +.indicator-index { + font-size: 0.65rem; + color: rgba(195,166,119,0.6); +} +.indicator-line-wrapper { + width: 1px; + height: 80px; + background-color: rgba(195,166,119,0.18); + position: relative; +} +.indicator-line-fill { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 0%; + background-color: var(--color-accent-gold); + transition: height 0.35s var(--ease-out-expo); +} +.indicator-name { + writing-mode: vertical-rl; + letter-spacing: 0.15em; + color: var(--color-accent-gold); + font-size: 0.65rem; +} +@media (max-width: 960px) { + .section-indicator { display: none; } +} + + +/* ── 13. LANDING SECTION ─────────────────────────────────────── */ .landing { position: relative; width: 100%; @@ -106,6 +637,7 @@ img, picture { display: block; max-width: 100%; height: auto; } display: flex; align-items: center; justify-content: center; + transition: background-color 0.4s ease; } /* Animated gradient blobs */ @@ -125,7 +657,7 @@ img, picture { display: block; max-width: 100%; height: auto; } .blob--a { width: clamp(340px, 50vw, 700px); height: clamp(340px, 50vw, 700px); - background: radial-gradient(circle, #4a3a6e 0%, transparent 70%); + background: radial-gradient(circle, var(--land-blob-a) 0%, transparent 70%); top: -15%; left: -12%; animation: blobA 18s ease-in-out infinite alternate; @@ -133,7 +665,7 @@ img, picture { display: block; max-width: 100%; height: auto; } .blob--b { width: clamp(280px, 40vw, 600px); height: clamp(280px, 40vw, 600px); - background: radial-gradient(circle, #6b3a2a 0%, transparent 70%); + background: radial-gradient(circle, var(--land-blob-b) 0%, transparent 70%); bottom: -10%; right: -8%; animation: blobB 22s ease-in-out infinite alternate; @@ -141,7 +673,7 @@ img, picture { display: block; max-width: 100%; height: auto; } .blob--c { width: clamp(200px, 30vw, 450px); height: clamp(200px, 30vw, 450px); - background: radial-gradient(circle, #1a3a5a 0%, transparent 70%); + background: radial-gradient(circle, var(--land-blob-c) 0%, transparent 70%); top: 40%; left: 55%; animation: blobC 15s ease-in-out infinite alternate; @@ -158,14 +690,15 @@ img, picture { display: block; max-width: 100%; height: auto; } from { transform: translate(0,0) scale(0.95); } to { transform: translate(4%, 10%) scale(1.08); } } +[data-theme="light"] .blob { opacity: 0.45; filter: blur(90px); } -/* Fine grain overlay */ +/* Grain overlay */ .landing::before { content: ''; position: absolute; inset: 0; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E"); - opacity: 0.03; + opacity: var(--land-grain, 0.03); pointer-events: none; z-index: 1; } @@ -183,9 +716,10 @@ img, picture { display: block; max-width: 100%; height: auto; } flex-direction: column; align-items: center; gap: 6px; - background: rgba(255,255,255,0.07); - border: 1px solid rgba(255,255,255,0.12); + background: var(--land-chip-bg); + border: 1px solid var(--land-chip-border); backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); border-radius: 16px; padding: 10px; width: clamp(80px, 10vw, 120px); @@ -194,6 +728,7 @@ img, picture { display: block; max-width: 100%; height: auto; } animation-direction: alternate; opacity: 0; animation-fill-mode: both; + transition: background 0.3s, border-color 0.3s; } .chip img { width: 100%; @@ -202,51 +737,26 @@ img, picture { display: block; max-width: 100%; height: auto; } border-radius: 10px; } .chip span { - color: rgba(240,242,247,0.75); + color: var(--land-chip-text); font-size: clamp(10px, 1.2vw, 13px); font-weight: 700; letter-spacing: 0.04em; } - -.chip--1 { - top: 12%; - left: clamp(4%, 6vw, 8%); - animation-name: floatA; - animation-duration: 8s; - animation-delay: 0.6s; -} -.chip--2 { - bottom: 18%; - left: clamp(3%, 5vw, 7%); - animation-name: floatB; - animation-duration: 10s; - animation-delay: 0.9s; -} -.chip--3 { - top: 10%; - right: clamp(4%, 6vw, 8%); - animation-name: floatC; - animation-duration: 9s; - animation-delay: 1.2s; -} -.chip--4 { - bottom: 14%; - right: clamp(3%, 5vw, 7%); - animation-name: floatA; - animation-duration: 11s; - animation-delay: 0.4s; -} +.chip--1 { top: 12%; left: clamp(4%, 6vw, 8%); animation-name: floatA; animation-duration: 8s; animation-delay: 0.6s; } +.chip--2 { bottom: 18%; left: clamp(3%, 5vw, 7%); animation-name: floatB; animation-duration: 10s; animation-delay: 0.9s; } +.chip--3 { top: 10%; right: clamp(4%, 6vw, 8%); animation-name: floatC; animation-duration: 9s; animation-delay: 1.2s; } +.chip--4 { bottom: 14%; right: clamp(3%, 5vw, 7%); animation-name: floatA; animation-duration: 11s; animation-delay: 0.4s; } @keyframes floatA { from { transform: translateY(0px) rotate(-1deg); opacity: 0.85; } to { transform: translateY(-18px) rotate(1deg); opacity: 1; } } @keyframes floatB { - from { transform: translateY(0px) rotate(1.5deg); opacity: 0.8; } + from { transform: translateY(0px) rotate(1.5deg); opacity: 0.80; } to { transform: translateY(-14px) rotate(-1.5deg); opacity: 1; } } @keyframes floatC { - from { transform: translateY(0px) rotate(-2deg); opacity: 0.9; } + from { transform: translateY(0px) rotate(-2deg); opacity: 0.90; } to { transform: translateY(-22px) rotate(0.5deg); opacity: 1; } } @@ -260,7 +770,6 @@ img, picture { display: block; max-width: 100%; height: auto; } animation: fadeUp 0.9s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0.15s; } - .landing__eyebrow { color: var(--land-muted); font-size: clamp(0.7rem, 1.2vw, 0.85rem); @@ -268,10 +777,10 @@ img, picture { display: block; max-width: 100%; height: auto; } letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 1.25rem; + font-family: var(--font-sans-clean); } - .landing__headline { - font-family: 'Playfair Display', serif; + font-family: var(--font-serif-display); font-size: clamp(2.6rem, 7.5vw, 7rem); font-weight: 600; line-height: 1.05; @@ -298,36 +807,46 @@ img, picture { display: block; max-width: 100%; height: auto; } color: var(--land-muted); font-size: clamp(0.95rem, 1.8vw, 1.15rem); max-width: 520px; - margin: 0 auto 2rem; + margin: 0 auto 2.25rem; opacity: 0; animation: fadeUp 0.7s 0.8s cubic-bezier(0.16,1,0.3,1) both; } - .landing__cta { display: inline-flex; align-items: center; gap: 8px; - padding: clamp(12px,2vw,16px) clamp(22px,3vw,32px); - border-radius: 999px; - background: var(--land-accent); - color: #1a1208; - font-weight: 800; - font-size: clamp(0.875rem,1.4vw,1rem); - letter-spacing: 0.02em; - transition: transform 0.18s, box-shadow 0.18s, background 0.18s; + padding: clamp(12px,2vw,16px) clamp(22px,3vw,36px); + border-radius: 0; + border: 1px solid var(--land-accent); + background: transparent; + color: var(--land-accent); + font-family: var(--font-serif-display); + font-weight: 600; + font-size: clamp(0.8rem,1.2vw,0.95rem); + letter-spacing: 0.18em; + text-transform: uppercase; + position: relative; + overflow: hidden; + transition: color 0.4s var(--ease-out-expo); opacity: 0; animation: fadeUp 0.7s 0.95s cubic-bezier(0.16,1,0.3,1) both; text-decoration: none; + cursor: pointer; + z-index: 1; } -.landing__cta:hover { - background: #f0d490; - color: #1a1208; - transform: translateY(-2px); - box-shadow: 0 8px 28px rgba(232,200,122,0.35); -} -.landing__cta svg { - transition: transform 0.2s; +.landing__cta::before { + content: ""; + position: absolute; + inset: 0; + background: var(--land-accent); + transform: scaleY(0); + transform-origin: bottom; + transition: transform 0.45s var(--ease-fluid-slide); + z-index: -1; } +.landing__cta:hover { color: var(--land-bg); } +.landing__cta:hover::before { transform: scaleY(1); } +.landing__cta svg { transition: transform 0.25s ease; } .landing__cta:hover svg { transform: translateY(3px); } /* Scroll nudge */ @@ -346,337 +865,500 @@ img, picture { display: block; max-width: 100%; height: auto; } .scroll-line { width: 1px; height: 48px; - background: linear-gradient(to bottom, transparent, rgba(240,242,247,0.5)); + background: linear-gradient(to bottom, transparent, var(--land-scroll-line)); animation: scrollPulse 2.5s ease-in-out infinite; } .landing__scroll-nudge span { - color: rgba(240,242,247,0.4); - font-size: 0.65rem; - letter-spacing: 0.2em; + color: var(--land-scroll-text); + font-size: 0.62rem; + letter-spacing: 0.22em; text-transform: uppercase; + font-family: var(--font-sans-clean); } @keyframes scrollPulse { 0%, 100% { opacity: 0.4; transform: scaleY(0.7); transform-origin: top; } - 50% { opacity: 1; transform: scaleY(1); } + 50% { opacity: 1; transform: scaleY(1); } } -/* Theme toggle — fixed top-right, always visible */ -.theme-toggle { - position: fixed; - top: 1.25rem; - right: 1.5rem; - z-index: 1000; - width: 40px; - height: 40px; - border-radius: 50%; - border: 1px solid var(--land-toggle-border); - background: var(--land-toggle-bg); - color: var(--land-toggle-color); + +/* ── 14. RECIPE SHOWCASE STAGE ───────────────────────────────── */ +.recipe-stage { + position: relative; + width: 100%; + height: 100dvh; + background: var(--color-bg-dark); + overflow: hidden; display: flex; align-items: center; justify-content: center; - cursor: pointer; - backdrop-filter: blur(10px); - transition: background 0.18s, color 0.18s, border-color 0.18s; -} -.theme-toggle:hover { - background: var(--land-chip-border); - color: var(--land-text); -} -/* Once scrolled past landing, adapt to site theme */ -.theme-toggle.on-site { - border-color: var(--stroke); - background: var(--surface); - color: var(--ink); -} -.theme-toggle.on-site:hover { - background: var(--panel-2); - color: var(--accent); } -/* Keyframes shared */ -@keyframes fadeUp { - from { opacity: 0; transform: translateY(24px); } - to { opacity: 1; transform: translateY(0); } -} -@keyframes lineIn { - from { opacity: 0; transform: translateY(20px) skewY(1deg); } - to { opacity: 1; transform: translateY(0) skewY(0deg); } +/* Stage background grain */ +.recipe-stage::before { + content: ''; + position: absolute; + inset: 0; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E"); + opacity: 0.035; + pointer-events: none; + z-index: 0; } -/* ══════════════════════════════════════════════════════════════════ - SCROLL REVEAL (for cards below landing) - ══════════════════════════════════════════════════════════════════ */ +/* Stage intro text */ +.recipe-stage__intro { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 2; + text-align: center; + padding: var(--grid-margin); +} +.recipe-stage__intro-eyebrow { + font-family: var(--font-sans-clean); + font-size: clamp(0.65rem, 1vw, 0.8rem); + letter-spacing: 0.25em; + text-transform: uppercase; + color: rgba(195,166,119,0.65); + margin-bottom: 1rem; +} +.recipe-stage__intro-title { + font-family: var(--font-serif-display); + font-size: clamp(2.2rem, 6vw, 6.5rem); + font-weight: 600; + line-height: 1.05; + color: var(--color-light-gold); + letter-spacing: -0.01em; +} +.recipe-stage__intro-title em { + color: var(--color-accent-gold); + font-style: italic; +} +.recipe-stage__intro-line { + width: 60px; + height: 1px; + background: var(--color-accent-gold); + margin: 1.5rem auto; + opacity: 0.5; + transform-origin: left; +} + +/* Slide container */ +.recipe-stage__slides { + position: absolute; + inset: 0; + z-index: 3; +} + +/* Individual slide */ +.recipe-stage__slide { + position: absolute; + inset: 0; + display: grid; + grid-template-columns: 1fr 1fr; + align-items: center; + will-change: transform, opacity; + overflow: hidden; +} +@media (max-width: 768px) { + .recipe-stage__slide { grid-template-columns: 1fr; } +} + +/* Slide image side */ +.recipe-stage__slide-image { + position: relative; + height: 100dvh; + overflow: hidden; +} +.recipe-stage__slide-image img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center; + display: block; + will-change: transform; +} +.recipe-stage__slide-image::after { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient( + to right, + rgba(36,31,33,0.85) 0%, + rgba(36,31,33,0.15) 60%, + transparent 100% + ); +} +@media (max-width: 768px) { + .recipe-stage__slide-image { + height: 45dvh; + position: absolute; + inset: 0; + z-index: 0; + } + .recipe-stage__slide-image::after { + background: linear-gradient(to bottom, transparent 30%, rgba(36,31,33,0.92) 100%); + } +} + +/* Slide copy side */ +.recipe-stage__slide-copy { + position: relative; + z-index: 2; + padding: clamp(2rem, 5vw, 5rem) clamp(1.5rem, 4vw, 4rem); +} +@media (max-width: 768px) { + .recipe-stage__slide-copy { + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 3; + padding: 2rem 1.5rem 3rem; + } +} +.recipe-stage__slide-num { + font-family: var(--font-sans-clean); + font-size: 0.7rem; + letter-spacing: 0.2em; + text-transform: uppercase; + color: rgba(195,166,119,0.55); + margin-bottom: 0.75rem; +} +.recipe-stage__slide-category { + font-family: var(--font-sans-clean); + font-size: 0.75rem; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--color-accent-gold); + margin-bottom: 1rem; + display: flex; + align-items: center; + gap: 0.6rem; +} +.recipe-stage__slide-category::before { + content: ''; + display: block; + width: 24px; + height: 1px; + background: var(--color-accent-gold); +} +.recipe-stage__slide-title { + font-family: var(--font-serif-display); + font-size: clamp(1.8rem, 3.5vw, 4rem); + font-weight: 600; + line-height: 1.1; + color: var(--color-light-gold); + margin-bottom: 1.25rem; + letter-spacing: -0.01em; +} +.recipe-stage__slide-desc { + font-family: var(--font-sans-clean); + font-size: clamp(0.85rem, 1.2vw, 1rem); + line-height: 1.7; + color: rgba(240,227,207,0.65); + max-width: 44ch; + margin-bottom: 1.75rem; +} +.recipe-stage__slide-meta { + display: flex; + flex-wrap: wrap; + gap: 1.25rem; + margin-bottom: 2rem; +} +.recipe-stage__slide-meta-item { + font-family: var(--font-sans-clean); + font-size: 0.78rem; + letter-spacing: 0.08em; + color: rgba(195,166,119,0.7); + display: flex; + align-items: center; + gap: 0.4rem; + text-transform: uppercase; +} +.recipe-stage__slide-meta-item strong { + color: var(--color-accent-gold); +} +.recipe-stage__slide-cta { + display: inline-flex; + align-items: center; + gap: 0.75rem; + font-family: var(--font-serif-display); + font-size: 0.82rem; + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--color-light-gold); + border: 1px solid rgba(195,166,119,0.45); + padding: 0.9rem 2rem; + position: relative; + overflow: hidden; + transition: color 0.4s var(--ease-out-expo); + text-decoration: none; + z-index: 1; +} +.recipe-stage__slide-cta::before { + content: ""; + position: absolute; + inset: 0; + background: var(--color-accent-gold); + transform: scaleX(0); + transform-origin: left; + transition: transform 0.45s var(--ease-fluid-slide); + z-index: -1; +} +.recipe-stage__slide-cta:hover { color: var(--color-bg-dark); } +.recipe-stage__slide-cta:hover::before { transform: scaleX(1); } + +/* Stage progress bar (bottom) */ +.recipe-stage__progress { + position: absolute; + bottom: 2rem; + left: 50%; + transform: translateX(-50%); + z-index: 10; + display: flex; + align-items: center; + gap: 0.6rem; +} +.recipe-stage__progress-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: rgba(195,166,119,0.3); + transition: background 0.3s ease, transform 0.3s ease; +} +.recipe-stage__progress-dot.active { + background: var(--color-accent-gold); + transform: scale(1.5); +} + +/* Slide scroll hint */ +.recipe-stage__hint { + position: absolute; + bottom: 2rem; + right: var(--grid-margin); + z-index: 10; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + opacity: 0.4; +} +.recipe-stage__hint span { + font-size: 0.6rem; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--color-accent-gold); + writing-mode: vertical-rl; + font-family: var(--font-sans-clean); +} +.recipe-stage__hint-line { + width: 1px; + height: 40px; + background: linear-gradient(to bottom, var(--color-accent-gold), transparent); + animation: scrollPulse 2s ease-in-out infinite; +} + +/* ── 15. SCROLL REVEAL ───────────────────────────────────────── */ .reveal-target { opacity: 0; - transform: translateY(28px); - transition: opacity 0.55s cubic-bezier(0.16,1,0.3,1), - transform 0.55s cubic-bezier(0.16,1,0.3,1); + transform: translateY(32px); + transition: opacity 0.6s var(--ease-out-expo), + transform 0.6s var(--ease-out-expo); } .reveal-target.revealed { opacity: 1; transform: translateY(0); } -/* ══════════════════════════════════════════════════════════════════ - EXISTING SITE STYLES (unchanged from original) - ══════════════════════════════════════════════════════════════════ */ - -#recipes { - padding: 0 24px 64px; -} +/* ── 16. SITE HEADER (legacy – hidden; nav-logo + nav-trigger replace it) ── */ .site-header { - max-width: 1200px; - margin: 24px auto 12px; - padding: 10px 20px; - border: 1px solid rgba(28,32,52,0.08); - border-radius: 14px; - background: rgba(255,255,255,0.9); - backdrop-filter: blur(12px); - display: flex; - flex-direction: column; - gap: 12px; - box-shadow: var(--shadow); -} -[data-theme="dark"] .site-header { - background: rgba(26,29,36,0.92); - border-color: rgba(255,255,255,0.06); -} -.site-header__top { - display: flex; - align-items: center; - gap: 12px; -} -.site-header .logo { display: inline-flex; align-items: center; } -.site-header .logo img { display: block; height: clamp(56px,8vw,96px); width: auto; } -.site-header .logo .logo--dark { display: none; } -[data-theme="dark"] .site-header .logo .logo--light { display: none; } -[data-theme="dark"] .site-header .logo .logo--dark { display: block; } -.header-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; } -.lang-toggle { - padding: 8px 12px; - border-radius: 12px; - background: rgba(28,32,52,0.06); - font-weight: 700; - letter-spacing: 0.04em; - color: var(--ink); -} -.lang-toggle:hover { background: var(--accent-soft); color: var(--ink); } -.menu-toggle { - display: none !important; - align-items: center; - gap: 8px; - padding: 8px 12px; - border-radius: 12px; - border: 1px solid rgba(28,32,52,0.08); - background: transparent; - color: var(--ink); - font-weight: 700; - cursor: pointer; -} -.menu-toggle__label { display: none; } -.menu-toggle:hover { background: var(--accent-soft); } -.site-nav { display: flex; gap: 12px; flex-wrap: wrap; } -.site-nav a { padding: 8px 12px; border-radius: 12px; transition: background 0.18s; } -.site-nav a:hover { background: var(--accent-soft); } - -.hero { - max-width: 1200px; - margin: 24px auto 56px; - display: grid; - grid-template-columns: minmax(320px,1fr) minmax(280px,0.9fr); - gap: 24px; - align-items: stretch; + display: none; /* Replaced by LiquidOverlayMenu */ } -.coming-strip { - max-width: 1200px; - margin: 18px auto 12px; - padding: 14px 16px; - background: var(--surface); - border: 1px solid var(--stroke); - border-radius: 14px; - display: grid; - gap: 10px; -} -.coming-strip__head { display: flex; align-items: center; gap: 10px; } -.coming-strip__head small { color: var(--muted); } -.coming-strip__row { - display: grid; - grid-auto-flow: column; - grid-auto-columns: minmax(120px,1fr); - gap: 12px; - overflow-x: auto; - padding-bottom: 6px; - scrollbar-color: #4f5664 transparent; -} -.coming-strip__row::-webkit-scrollbar { height: 8px; } -.coming-strip__row::-webkit-scrollbar-track { background: transparent; } -.coming-strip__row::-webkit-scrollbar-thumb { background: #4f5664; border-radius: 999px; } -.coming-chip { - background: var(--panel); - border: 1px solid var(--stroke); - border-radius: 12px; - padding: 8px; - display: grid; - gap: 8px; - box-shadow: 0 6px 14px rgba(12,16,28,0.06); -} -.coming-chip__image img { - width: 100%; - aspect-ratio: 9/16; - object-fit: cover; - border-radius: 10px; - background: var(--panel-2); - display: block; -} -.coming-chip__title { font-weight: 700; color: var(--ink); font-size: 14px; } -.coming-features { - max-width: 1200px; - margin: 40px auto 56px; - padding: 22px; - background: var(--surface); - border: 1px solid var(--stroke); - border-radius: var(--radius); - box-shadow: var(--shadow); - display: grid; - gap: 18px; -} -.feature-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); - gap: 14px; -} -.feature-card { - padding: 14px 16px; - background: var(--panel); - border: 1px solid var(--stroke); - border-radius: 12px; - display: grid; - gap: 10px; - align-items: center; -} -.feature-icon { - width: 40px; - height: 40px; - display: grid; - place-items: center; - border-radius: 10px; - background: var(--accent-soft); - font-size: 18px; +/* ── 17. SHARED COMPONENTS ───────────────────────────────────── */ +.sr-only { + position: absolute; width: 1px; height: 1px; padding: 0; + margin: -1px; overflow: hidden; clip: rect(0,0,0,0); + white-space: nowrap; border: 0; } -.hero-copy { padding: 12px; order: 1; } -.hero-copy h1 { font-size: clamp(32px,4vw,48px); line-height: 1.1; margin: 8px 0 12px; } +/* Eyebrow labels */ .eyebrow { text-transform: uppercase; letter-spacing: 0.18em; - font-weight: 600; - color: var(--muted); - font-size: 12px; + font-weight: 700; + color: var(--color-accent-gold); + font-size: 0.72rem; + font-family: var(--font-sans-clean); } + +/* Pills */ +.pill { + display: inline-block; + padding: 5px 10px; + border-radius: 999px; + background: var(--accent-soft); + color: var(--ink); + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.06em; + font-family: var(--font-sans-clean); +} +.pill--ghost { background: var(--ghost); color: var(--muted); } +.pill--gold { background: rgba(195,166,119,0.15); color: var(--color-accent-gold); border: 1px solid rgba(195,166,119,0.3); } + + +/* ── 18. SEARCH BAR ──────────────────────────────────────────── */ .search { margin: 18px 0 8px; display: flex; gap: 8px; } .search input { flex: 1; - padding: 14px 16px; + padding: 13px 16px; border: 1px solid var(--stroke); - border-radius: 14px; - font-size: 15px; + border-radius: 0; + font-size: 0.9rem; background: var(--surface); color: var(--ink); - font-family: inherit; + font-family: var(--font-sans-clean); + transition: border-color 0.22s ease; } -.search input:focus { outline: 2px solid var(--accent-2); outline-offset: 2px; } +.search input:focus { outline: none; border-color: var(--color-accent-gold); } .search button { - padding: 14px 18px; - border: 1px solid var(--stroke); - border-radius: 14px; - background: var(--panel); + padding: 13px 18px; + border: 1px solid var(--color-accent-gold); + background: transparent; color: var(--ink); font-weight: 700; + font-size: 0.82rem; + letter-spacing: 0.1em; + text-transform: uppercase; cursor: pointer; - font-family: inherit; - transition: background 0.18s; + font-family: var(--font-sans-clean); + transition: background 0.25s ease, color 0.25s ease; } -.search button:hover { background: var(--panel-2); } -.tag-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; } -.tag { - padding: 8px 12px; - border-radius: 12px; - background: var(--panel); - color: var(--ink); - font-weight: 600; - font-size: 13px; - border: 1px solid var(--stroke); - transition: background 0.18s; -} -.tag:hover { background: var(--panel-2); color: var(--ink); } -.tag.active { background: var(--accent); color: white; } -.tag.clear { background: transparent; border: 1px dashed var(--stroke); color: var(--muted); } +.search button:hover { background: var(--color-accent-gold); color: var(--color-white); } + +/* ── 19. TAG SYSTEM ──────────────────────────────────────────── */ +.tag-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; } +.tag { + padding: 7px 14px; + border: 1px solid var(--stroke); + background: transparent; + color: var(--muted); + font-weight: 600; + font-size: 0.78rem; + letter-spacing: 0.06em; + text-transform: uppercase; + font-family: var(--font-sans-clean); + transition: border-color 0.22s ease, color 0.22s ease, background 0.22s ease; + text-decoration: none; +} +.tag:hover { border-color: var(--color-accent-gold); color: var(--color-accent-gold); } +.tag.active { background: var(--color-accent-gold); color: var(--color-white); border-color: var(--color-accent-gold); } +.tag.clear { background: transparent; border-style: dashed; } + + +/* ── 20. CARDS ───────────────────────────────────────────────── */ +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px,1fr)); + gap: 20px; +} +.grid--tight { grid-template-columns: repeat(auto-fill, minmax(230px,1fr)); gap: 14px; } + +.card { + background: var(--surface); + overflow: hidden; + border: 1px solid var(--stroke); + display: flex; + flex-direction: column; + transition: transform 0.3s var(--ease-out-expo), + box-shadow 0.3s var(--ease-out-expo); +} +.card:hover { transform: translateY(-4px); box-shadow: 0 18px 40px rgba(36,31,33,0.12); } +[data-theme="dark"] .card:hover { box-shadow: 0 18px 40px rgba(0,0,0,0.4); } +.card__image { position: relative; display: block; overflow: hidden; } +.card__image img { + width: 100%; + aspect-ratio: 4/3; + object-fit: cover; + object-position: center; + display: block; + background: var(--panel); + transition: transform 0.6s var(--ease-out-expo); +} +.card:hover .card__image img { transform: scale(1.04); } +.card__body { padding: 18px; display: grid; gap: 10px; flex: 1; } +.card h3 { margin: 0; font-size: 1.2rem; } +.card h4 { margin: 0; font-size: 1rem; } +.card--bare { border: 1px solid var(--stroke); background: var(--panel); } +.card .pill { position: absolute; bottom: 10px; left: 10px; } + +.meta { display: flex; flex-wrap: wrap; gap: 12px; color: var(--muted); font-size: 0.78rem; } +.meta--row { gap: 16px; } +.tags { display: flex; flex-wrap: wrap; gap: 6px; } + + +/* ── 21. HERO CARD (featured) ────────────────────────────────── */ .hero-card { background: var(--surface); - border-radius: var(--radius); overflow: hidden; - box-shadow: 0 10px 24px rgba(12,16,28,0.08); border: 1px solid var(--stroke); display: grid; grid-template-rows: auto 1fr; - order: 2; } .hero-card img { width: 100%; - aspect-ratio: 9/16; - object-fit: contain; - background: var(--surface); - max-height: 520px; + aspect-ratio: 3/2; + object-fit: cover; + background: var(--panel); + display: block; } -.hero-card__body { padding: 18px; display: grid; gap: 10px; } +.hero-card__body { padding: 20px; display: grid; gap: 10px; } -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; -} +/* ── 22. DISCOVER SHELL ──────────────────────────────────────── */ .discover-shell { max-width: 1200px; - margin: 24px auto 40px; + margin: 40px auto 40px; display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.8fr); gap: 24px; align-items: stretch; + padding: 0 var(--grid-margin); } -.discover-shell__main, -.tag-panel, -.empty-state, -.quick-start { +@media (max-width: 900px) { .discover-shell { grid-template-columns: 1fr; gap: 16px; margin: 24px auto; } } + +.discover-shell__main { background: var(--surface); border: 1px solid var(--stroke); - border-radius: var(--radius); - box-shadow: var(--shadow); -} -.discover-shell__main { - padding: 22px; + padding: 28px; display: grid; - gap: 18px; + gap: 20px; +} +.discover-shell__feature { + background: var(--surface); + border: 1px solid var(--stroke); +} +.section-header { + display: flex; + align-items: baseline; + gap: 12px; + margin-bottom: 6px; } .section-header--stack { flex-direction: column; align-items: flex-start; text-align: left; } -.discover-search { - margin: 0; -} +.section-header h2, .section-header h3 { margin: 0; } +.section-header p { margin: 0; } + .discover-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); @@ -686,23 +1368,22 @@ img, picture { display: block; max-width: 100%; height: auto; } padding: 14px; background: var(--panel); border: 1px solid var(--stroke); - border-radius: 14px; display: grid; gap: 4px; } .discover-stat strong { - font-size: clamp(1.1rem, 2vw, 1.5rem); -} -.discover-stat span { - color: var(--muted); - font-size: 14px; + font-size: clamp(1.1rem, 2vw, 1.6rem); + color: var(--ink); + font-family: var(--font-serif-display); } +.discover-stat span { color: var(--muted); font-size: 0.8rem; } + .tag-panel { - padding: 16px; + background: var(--surface); + border: 1px solid var(--stroke); + padding: 20px; display: grid; - gap: 12px; - box-shadow: none; - border-radius: 16px; + gap: 14px; } .tag-panel__head { display: flex; @@ -710,563 +1391,322 @@ img, picture { display: block; max-width: 100%; height: auto; } align-items: center; gap: 12px; } -.tag-panel__head h3 { - margin: 0; -} -.tag-row--panel { - margin-top: 0; -} -.quick-start { - max-width: 1200px; - margin: 0 auto 40px; - padding: 22px; - display: grid; - gap: 18px; -} -.empty-state { - padding: 22px; - display: grid; - gap: 12px; - text-align: center; -} -.empty-state h3, -.empty-state p { - margin: 0; -} -.section-header { - max-width: 1200px; - margin: 0 auto 12px; - display: flex; - align-items: baseline; - gap: 12px; -} -.section-header h2, .section-header h3 { margin: 0; } -.section-header p { margin: 0; color: var(--muted); } +.tag-panel__head h3 { margin: 0; } +.tag-row--panel { margin-top: 0; } -.latest, .basics, .more { - max-width: 1200px; - margin: 0 auto 56px; -} -.grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(260px,1fr)); - gap: 18px; -} -.grid--tight { grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); } +.discover-search { margin: 0; } -.card { + +/* ── 23. COMING SOON STRIP ───────────────────────────────────── */ +.coming-strip { + max-width: 1200px; + margin: 0 auto 0; + padding: 20px var(--grid-margin); background: var(--surface); - border-radius: var(--radius); - overflow: hidden; - box-shadow: 0 8px 20px rgba(12,16,28,0.08); + border-top: 1px solid var(--stroke); + border-bottom: 1px solid var(--stroke); + display: grid; + gap: 14px; +} +.coming-strip__head { display: flex; align-items: center; gap: 10px; } +.coming-strip__head small { color: var(--muted); font-size: 0.8rem; } +.coming-strip__row { + display: grid; + grid-auto-flow: column; + grid-auto-columns: minmax(130px,1fr); + gap: 14px; + overflow-x: auto; + padding-bottom: 6px; + scrollbar-color: rgba(195,166,119,0.3) transparent; +} +.coming-strip__row::-webkit-scrollbar { height: 4px; } +.coming-strip__row::-webkit-scrollbar-track { background: transparent; } +.coming-strip__row::-webkit-scrollbar-thumb { background: rgba(195,166,119,0.3); border-radius: 999px; } +.coming-chip { + background: var(--panel); border: 1px solid var(--stroke); - display: flex; - flex-direction: column; - transition: transform 0.18s, box-shadow 0.18s; + padding: 10px; + display: grid; + gap: 8px; } -.card:hover { transform: translateY(-3px); box-shadow: 0 14px 32px rgba(12,16,28,0.14); } -.card__image { position: relative; display: block; } -.card__image img { +.coming-chip__image img { width: 100%; - aspect-ratio: 9/16; - max-height: 260px; - object-fit: contain; - object-position: right center; + aspect-ratio: 4/3; + object-fit: cover; display: block; - background: var(--surface); + background: var(--panel-2); } -.pill { - display: inline-block; - padding: 6px 10px; - border-radius: 999px; - background: var(--accent-soft); - color: var(--ink); - font-size: 12px; - font-weight: 700; - letter-spacing: 0.02em; -} -.pill--ghost { background: var(--ghost); color: var(--muted); } -.card__body { padding: 16px; display: grid; gap: 10px; } -.card h3 { margin: 0; font-size: 20px; } -.meta { display: flex; flex-wrap: wrap; gap: 12px; color: var(--muted); font-size: 13px; } -.meta--row { gap: 16px; } -.tags { display: flex; flex-wrap: wrap; gap: 8px; } -.card--bare { border: 1px solid var(--stroke); box-shadow: none; background: var(--panel); } +.coming-chip__title { font-weight: 700; color: var(--ink); font-size: 0.82rem; font-family: var(--font-sans-clean); } + +/* ── 24. LATEST / RECIPE GRID SECTION ───────────────────────── */ +.latest { + max-width: 1200px; + margin: 40px auto 60px; + padding: 0 var(--grid-margin); +} +.latest .section-header { margin-bottom: 24px; } + + +/* ── 25. COMING FEATURES SECTION ─────────────────────────────── */ +.coming-features { + max-width: 1200px; + margin: 0 auto 80px; + padding: 0 var(--grid-margin); +} +.coming-features .section-header { margin-bottom: 24px; } +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px,1fr)); + gap: 16px; +} +.feature-card { + padding: 20px 22px; + background: var(--surface); + border: 1px solid var(--stroke); + display: grid; + gap: 10px; +} +.feature-card:hover { border-color: rgba(195,166,119,0.45); } +.feature-icon { + font-size: 1.5rem; + line-height: 1; +} +.feature-card p { font-size: 0.9rem; } + + +/* ── 26. BUTTON (general legacy) ─────────────────────────────── */ .button { display: inline-flex; align-items: center; justify-content: center; - padding: 12px 16px; - border-radius: 12px; + padding: 11px 20px; background: transparent; color: var(--ink); font-weight: 700; + font-size: 0.82rem; + letter-spacing: 0.08em; + text-transform: uppercase; text-decoration: none; border: 1px solid var(--stroke); cursor: pointer; - transition: background 0.18s, border-color 0.18s; + font-family: var(--font-sans-clean); + transition: border-color 0.22s, background 0.22s, color 0.22s; } -.button:hover { background: var(--panel-2); border-color: #c6cede; color: var(--ink); } +.button:hover { border-color: var(--color-accent-gold); color: var(--color-accent-gold); } -/* ── Recipe page ─────────────────────────────────────────────────── */ + +/* ── 27. RECIPE PAGE ──────────────────────────────────────────── */ .recipe { max-width: 1100px; - margin: 0 auto 64px; + margin: 120px auto 80px; background: var(--surface-2); - border-radius: var(--radius); - box-shadow: var(--shadow); - overflow: hidden; + border: 1px solid var(--stroke); } .recipe__hero { display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px,1fr)); + grid-template-columns: repeat(auto-fit, minmax(300px,1fr)); align-items: stretch; } .recipe__hero img { width: 100%; - aspect-ratio: 9/16; - max-height: 640px; - object-fit: contain; - background: var(--surface); + aspect-ratio: 4/3; + object-fit: cover; + display: block; } .recipe__hero__copy { - padding: 24px; + padding: 32px; display: grid; - gap: 12px; - background: linear-gradient(140deg, var(--panel), var(--panel-2)); + gap: 14px; + background: var(--panel); } -.lede { font-size: 18px; line-height: 1.6; } +.lede { font-size: 1.05rem; line-height: 1.7; } .recipe__body { display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px,1fr)); - gap: 14px; - padding: 22px; + grid-template-columns: repeat(auto-fit, minmax(300px,1fr)); + gap: 16px; + padding: 28px; } .panel { - padding: 18px; + padding: 20px; background: var(--panel); - border-radius: 12px; border: 1px solid var(--stroke); } -.ingredients { - list-style: none; - padding: 0; - margin: 0; - display: grid; - gap: 8px; -} +.panel h2 { margin-bottom: 1rem; font-size: 1.1rem; text-transform: uppercase; letter-spacing: 0.1em; } +.ingredients { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; } .ingredients li { - padding: 8px 10px; - background: var(--panel-2); - border-radius: 10px; + padding: 9px 12px; + background: var(--surface); border: 1px solid var(--stroke); + font-size: 0.88rem; } -.steps { padding-left: 20px; display: grid; gap: 10px; } -.steps li { padding: 6px 0; } -.more { padding: 0 12px 24px; } +.steps { padding-left: 22px; display: grid; gap: 12px; } +.steps li { padding: 4px 0; line-height: 1.65; font-size: 0.9rem; } +.more { padding: 28px; border-top: 1px solid var(--stroke); } -/* ── Footer ──────────────────────────────────────────────────────── */ + +/* ── 28. FOOTER ───────────────────────────────────────────────── */ .site-footer { - max-width: 1100px; - margin: 0 auto 24px; - padding: 24px; - background: var(--surface-2); - border-radius: var(--radius); - box-shadow: var(--shadow); + max-width: 1200px; + margin: 0 auto 60px; + padding: 32px var(--grid-margin); + border-top: 1px solid var(--stroke); display: grid; - gap: 12px; - border: 1px solid var(--stroke); + gap: 16px; } .footer-meta { color: var(--muted); display: flex; align-items: center; - gap: 12px; + gap: 16px; + flex-wrap: wrap; + font-size: 0.82rem; +} +.footer-links { + display: flex; + gap: 1.5rem; flex-wrap: wrap; } -.contact-link { font-weight: 700; color: var(--ink); } -.contact-link:hover { color: var(--accent); } - -.not-found { - max-width: 800px; - margin: 120px auto; - text-align: center; - display: grid; - gap: 12px; +.footer-links a { + font-size: 0.8rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--muted); } +.contact-link { font-weight: 700; color: var(--ink); } -/* ── Back to top ─────────────────────────────────────────────────── */ + +/* ── 29. BACK TO TOP ──────────────────────────────────────────── */ #backToTop { position: fixed; right: 18px; bottom: 18px; - min-width: 44px; + width: 44px; height: 44px; - padding: 0 14px; - border-radius: 999px; border: 1px solid var(--stroke); background: var(--surface); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; - gap: 8px; - font-weight: 800; - font-size: 14px; - white-space: nowrap; cursor: pointer; - box-shadow: 0 10px 24px rgba(0,0,0,0.2); + box-shadow: var(--shadow); opacity: 0; transform: translateY(12px); transition: opacity 0.25s ease, transform 0.25s ease; z-index: 999; + font-size: 1.1rem; } #backToTop.show { opacity: 1; transform: translateY(0); } -#backToTop:hover { background: var(--panel-2); } +#backToTop:hover { border-color: var(--color-accent-gold); color: var(--color-accent-gold); } -@media (max-width: 900px) { - .discover-shell { - grid-template-columns: 1fr; - gap: 16px; - margin: 16px auto 32px; - } - .discover-shell__main, - .quick-start, - .coming-features, - .empty-state { - padding: 18px; - } +/* ── 30. THEME TOGGLE ────────────────────────────────────────── */ +.theme-toggle { + position: fixed; + bottom: 1.25rem; + right: 1.25rem; + z-index: 1000; + width: 42px; + height: 42px; + border-radius: 50%; + border: 1px solid var(--stroke); + background: var(--surface); + color: var(--ink); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background 0.2s, color 0.2s, border-color 0.2s; +} +.theme-toggle:hover { border-color: var(--color-accent-gold); color: var(--color-accent-gold); } - .discover-stats { - grid-template-columns: 1fr; - } - .tag-panel__head { - flex-direction: column; - align-items: flex-start; - } +/* ── 31. NOT FOUND ───────────────────────────────────────────── */ +.not-found { + max-width: 800px; + margin: 160px auto; + text-align: center; + display: grid; + gap: 14px; + padding: 0 var(--grid-margin); } -@media (max-width: 480px) { - .discover-shell__main, - .quick-start, - .coming-features, - .empty-state, - .tag-panel { - padding: 14px; - } +.empty-state { + padding: 28px; + background: var(--surface); + border: 1px solid var(--stroke); + display: grid; + gap: 12px; + text-align: center; } -/* ══════════════════════════════════════════════════════════════════ - RESPONSIVE - ══════════════════════════════════════════════════════════════════ */ -/* Hide chips on small screens to avoid clutter */ +/* ── 32. LEGAL PAGES ─────────────────────────────────────────── */ +.legal-page { max-width: 900px; margin: 140px auto 80px; padding: 0 var(--grid-margin); } +.legal-card { background: var(--surface); border: 1px solid var(--stroke); padding: 28px; } +.legal-item { display: grid; grid-template-columns: 200px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--stroke); } +.legal-item:last-child { border-bottom: none; } +.legal-label { font-weight: 700; color: var(--ink); font-size: 0.85rem; } +.legal-section { margin-top: 24px; } +.legal-section h2 { margin: 0 0 12px; font-size: 1.1rem; text-transform: uppercase; letter-spacing: 0.1em; } +@media (max-width: 600px) { .legal-item { grid-template-columns: 1fr; } } + + +/* ── 33. ADMIN OVERRIDE ──────────────────────────────────────── */ +/* Admin uses its own inline styles; body override for admin only */ + + +/* ── 34. KEYFRAMES ───────────────────────────────────────────── */ +@keyframes fadeUp { + from { opacity: 0; transform: translateY(24px); } + to { opacity: 1; transform: translateY(0); } +} +@keyframes lineIn { + from { opacity: 0; transform: translateY(20px) skewY(1deg); } + to { opacity: 1; transform: translateY(0) skewY(0deg); } +} +@keyframes slideInRight { + from { transform: translateX(80px); opacity: 0; } + to { transform: translateX(0); opacity: 1; } +} +@keyframes slideOutLeft { + from { transform: translateX(0); opacity: 1; } + to { transform: translateX(-80px); opacity: 0; } +} + + +/* ── 35. RESPONSIVE ──────────────────────────────────────────── */ @media (max-width: 600px) { .landing__chips { display: none; } .landing__headline { font-size: clamp(2.2rem, 12vw, 4rem); } + .discover-shell { padding: 0 12px; } + .latest { padding: 0 12px; } + .coming-features { padding: 0 12px; } + .discover-stats { grid-template-columns: repeat(2, 1fr); } } -@media (max-width: 900px) { - #recipes { padding: 0 14px 40px; } - .site-header { padding: 10px 14px; gap: 10px; border-radius: 18px; } - .site-header .logo img { height: clamp(64px,20vw,112px); } - .menu-toggle { display: inline-flex !important; } - .menu-toggle__label { display: inline; } - .site-nav { - width: 100%; - display: grid; - grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); - gap: 8px; - max-height: 0; - overflow: hidden; - transition: max-height 0.25s ease; - } - .site-nav[data-collapsed="false"] { max-height: 200px; } - .site-nav a { background: var(--panel); } - - .coming-strip { padding: 12px; gap: 8px; } - .coming-strip__row { - grid-auto-columns: minmax(132px,46vw); - gap: 10px; - scroll-snap-type: x proximity; - } - .coming-chip { scroll-snap-align: start; } - .coming-chip__image img { aspect-ratio: 4/3; } - .coming-chip__title { font-size: 13px; } - .coming-features { padding: 18px; margin: 32px auto 44px; } - .feature-grid { grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); } - - .hero { - grid-template-columns: 1fr; - gap: 18px; - margin: 20px auto 40px; - } - .hero-card, .hero-copy { order: unset; } - .hero-copy { padding: 0 6px; text-align: center; } - .hero-copy h1 { font-size: clamp(30px,9vw,40px); } - .search { flex-direction: column; gap: 10px; } - .search button { width: 100%; } - .section-header { align-items: center; text-align: center; } - .tag-row { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; } - .tag-row .tag { flex: 0 0 auto; } - .hero-card img { max-height: 240px; object-fit: cover; object-position: center; } - .section-header { flex-direction: column; align-items: center; gap: 6px; } - .section-header p { font-size: 14px; } - .grid, .grid--tight, .recipe__body { grid-template-columns: 1fr; } - .recipe { margin: 0 auto 40px; } - .recipe__body { padding: 16px; } - .card__image img { max-height: 220px; object-fit: cover; object-position: center; } - #backToTop { min-width: 44px; width: 44px; padding: 0; font-size: 0; gap: 0; } - #backToTop::before { content: "\2191"; font-size: 18px; line-height: 1; } -} - -@media (max-width: 480px) { - #recipes { padding: 0 12px 32px; } - .hero { gap: 16px; } - .coming-strip__row { grid-auto-columns: 128px; } - .coming-chip__image img { aspect-ratio: 1/1; } - .hero-card img { max-height: 220px; } - .hero-copy { text-align: center; } - .card__body { padding: 14px; } +@media (max-width: 768px) { + .recipe { margin: 80px auto 40px; } .recipe__hero { grid-template-columns: 1fr; } - .recipe__hero img { max-height: 260px; object-fit: cover; object-position: center; order: 1; } - .recipe__hero__copy { order: 2; } + .recipe__hero img { aspect-ratio: 16/9; } + .recipe__body { padding: 16px; gap: 12px; } + .discover-stats { grid-template-columns: 1fr; } + .tag-panel__head { flex-direction: column; align-items: flex-start; } } -/* ══════════════════════════════════════════════════════════════════ - LANDING — LIGHT MODE ADAPTATION - ══════════════════════════════════════════════════════════════════ */ - -/* Light mode landing tokens */ -:root, -[data-theme="light"] { - --land-bg: #f4f1eb; - --land-text: #1c1f29; - --land-muted: rgba(28,31,41,0.55); - --land-accent: #b07d2a; - --land-accent2: #8a4a20; - --land-blob-a: #c9b8e8; - --land-blob-b: #e8c0a0; - --land-blob-c: #a8c4d8; - --land-chip-bg: rgba(28,31,41,0.06); - --land-chip-border: rgba(28,31,41,0.12); - --land-chip-text: rgba(28,31,41,0.7); - --land-toggle-border: rgba(28,31,41,0.15); - --land-toggle-bg: rgba(28,31,41,0.06); - --land-toggle-color: rgba(28,31,41,0.6); - --land-scroll-line: rgba(28,31,41,0.35); - --land-scroll-text: rgba(28,31,41,0.35); - --land-grain: 0.04; -} - -[data-theme="dark"] { - --land-bg: #0d0e11; - --land-text: #f0f2f7; - --land-muted: rgba(240,242,247,0.55); - --land-accent: #e8c87a; - --land-accent2: #c87a5a; - --land-blob-a: #4a3a6e; - --land-blob-b: #6b3a2a; - --land-blob-c: #1a3a5a; - --land-chip-bg: rgba(255,255,255,0.07); - --land-chip-border: rgba(255,255,255,0.12); - --land-chip-text: rgba(240,242,247,0.75); - --land-toggle-border: rgba(255,255,255,0.15); - --land-toggle-bg: rgba(255,255,255,0.06); - --land-toggle-color: rgba(240,242,247,0.7); - --land-scroll-line: rgba(240,242,247,0.5); - --land-scroll-text: rgba(240,242,247,0.4); - --land-grain: 0.03; -} - -/* Smooth theme transition on landing */ -.landing { - transition: background-color 0.4s ease; -} - -/* Use variables everywhere in landing */ -.landing { - background: var(--land-bg); -} - -.landing__eyebrow { - color: var(--land-muted); -} - -.landing__headline { - color: var(--land-text); -} - -.landing__sub { - color: var(--land-muted); -} - -.landing__cta { - background: var(--land-accent); - color: var(--land-bg); -} - -[data-theme="light"] .landing__cta { - color: #fff8ee; -} - -.landing__cta:hover { - filter: brightness(1.08); - background: var(--land-accent); - color: inherit; -} - -/* Blob colors via variables */ -.blob--a { - background: radial-gradient(circle, var(--land-blob-a, #4a3a6e) 0%, transparent 70%); -} -.blob--b { - background: radial-gradient(circle, var(--land-blob-b, #6b3a2a) 0%, transparent 70%); -} -.blob--c { - background: radial-gradient(circle, var(--land-blob-c, #1a3a5a) 0%, transparent 70%); -} - -/* Light mode blobs slightly more opaque */ -[data-theme="light"] .blob { - opacity: 0.45; - filter: blur(90px); -} - -/* Chip styles via variables */ -.chip { - background: var(--land-chip-bg); - border-color: var(--land-chip-border); - transition: background 0.3s, border-color 0.3s; -} -.chip span { - color: var(--land-chip-text); -} - -/* Scroll nudge */ -.scroll-line { - background: linear-gradient(to bottom, transparent, var(--land-scroll-line)); -} -.landing__scroll-nudge span { - color: var(--land-scroll-text); -} - -/* Theme toggle */ -.theme-toggle { - border-color: var(--land-toggle-border); - background: var(--land-toggle-bg); - color: var(--land-toggle-color); - transition: background 0.18s, color 0.18s, border-color 0.18s; -} -.theme-toggle:hover { - background: var(--land-chip-border); - color: var(--land-text); -} - -/* ══════════════════════════════════════════════════════════════════ - MOBILE IMPROVEMENTS - ══════════════════════════════════════════════════════════════════ */ - @media (max-width: 900px) { - /* More padding around the whole site content */ - #recipes-start { - padding: 0 6px 40px; - } - - /* Header more compact */ - .site-header { - margin: 12px 8px; - padding: 10px 14px; - } - - /* Coming strip full width */ - .coming-strip { - margin: 10px 0; - } - - /* Hero section stacks cleanly */ - .hero { - margin: 16px 0 32px; - gap: 14px; - } - - /* Featured card image not too tall */ - .hero-card img { - max-height: 200px; - object-fit: cover; - object-position: center; - } - - /* Recipe grid single column with less gap */ - .grid { - gap: 12px; - } - - /* Card images proportional */ - .card__image img { - max-height: 200px; - object-fit: cover; - object-position: center; - aspect-ratio: 4/3; - } - - /* Section headers compact */ - .section-header { - margin-bottom: 8px; - } - - /* Landing chips hidden on very small screens */ - .landing__chips { - display: none; - } - - /* Landing headline smaller */ - .landing__headline { - font-size: clamp(2rem, 10vw, 3.5rem); - } - - /* Landing CTA full width */ - .landing__cta { - width: 100%; - justify-content: center; - } + .landing__chips { display: none; } + .landing__headline { font-size: clamp(2rem, 10vw, 3.5rem); } + .latest .section-header, + .coming-features .section-header { flex-direction: column; gap: 4px; } + .coming-strip { padding: 16px var(--grid-margin); } + .coming-strip__row { grid-auto-columns: minmax(130px,44vw); scroll-snap-type: x proximity; } + .coming-chip { scroll-snap-align: start; } } @media (max-width: 480px) { - #recipes-start { - padding: 0 4px 32px; - } - - .site-header { - margin: 8px 4px; - border-radius: 12px; - } - - .coming-strip__row { - grid-auto-columns: 110px; - } - - .coming-chip__image img { - aspect-ratio: 1/1; - } - - /* Recipe body panels stack */ - .recipe__body { - grid-template-columns: 1fr; - padding: 12px; - gap: 10px; - } - - .recipe__hero img { - max-height: 240px; - object-fit: cover; - } - - /* Feature cards single column */ - .feature-grid { - grid-template-columns: 1fr; - } + .recipe__body { grid-template-columns: 1fr; } + .feature-grid { grid-template-columns: 1fr; } + .coming-features { margin-bottom: 40px; } } diff --git a/datenschutz.php b/datenschutz.php index c110c28..65a86ba 100644 --- a/datenschutz.php +++ b/datenschutz.php @@ -1,34 +1,29 @@ $lang === 'de' ? 'Datenschutzerklärung' : 'Privacy Policy', + 'title' => $lang === 'de' ? 'Datenschutzerklärung' : 'Privacy Policy', 'controller' => $lang === 'de' ? 'Verantwortlicher' : 'Controller', - 'address' => $lang === 'de' ? 'Adresse' : 'Address', - 'contact' => $lang === 'de' ? 'Kontakt für Datenschutz' : 'Privacy contact', - 'hosting' => $lang === 'de' ? 'Hosting' : 'Hosting', - 'logs' => $lang === 'de' ? 'Server-Logs' : 'Server logs', - 'cookies' => $lang === 'de' ? 'Cookies' : 'Cookies', - 'purposes' => $lang === 'de' ? 'Zwecke der Datenverarbeitung' : 'Purposes of processing', - 'rights' => $lang === 'de' ? 'Ihre Rechte' : 'Your rights', + 'address' => $lang === 'de' ? 'Adresse' : 'Address', + 'contact' => $lang === 'de' ? 'Kontakt für Datenschutz' : 'Privacy contact', + 'hosting' => $lang === 'de' ? 'Hosting' : 'Hosting', + 'logs' => $lang === 'de' ? 'Server-Logs' : 'Server logs', + 'cookies' => $lang === 'de' ? 'Cookies' : 'Cookies', + 'purposes' => $lang === 'de' ? 'Zwecke der Datenverarbeitung' : 'Purposes of processing', + 'rights' => $lang === 'de' ? 'Ihre Rechte' : 'Your rights', 'last_updated' => $lang === 'de' ? 'Stand' : 'Last updated', ]; function privacy_item(string $label, ?string $value): void { $value = trim((string) $value); - if ($value === '') { - return; - } + if ($value === '') return; echo ''; } @@ -43,29 +38,15 @@ if (!empty($privacy['log_retention_days'])) { : 'Server logs (IP address, timestamp, URL, user agent) are kept for security and deleted after ') . intval($privacy['log_retention_days']) . ($lang === 'de' ? ' Tagen gelöscht.' : ' days.'); } + +$pageTitle = e($t['title']) . ' | FlixCooks'; +$description = $lang === 'de' + ? 'Informationen gemäß DSGVO und TKG über die Verarbeitung personenbezogener Daten.' + : 'Information per GDPR and TKG on how personal data is processed.'; + +include __DIR__ . '/partials/head.php'; +include __DIR__ . '/partials/header.php'; ?> - - - - - - <?php echo e($t['title']); ?> | FlixCooks - - - - -

- - + diff --git a/impressum.php b/impressum.php index 79c742f..d15a9f8 100644 --- a/impressum.php +++ b/impressum.php @@ -1,60 +1,41 @@ $lang === 'de' ? 'Impressum' : 'Imprint', - 'owner' => $lang === 'de' ? 'Medieninhaber' : 'Media owner', - 'address' => $lang === 'de' ? 'Adresse' : 'Address', - 'contact' => $lang === 'de' ? 'Kontakt' : 'Contact', - 'legal' => $lang === 'de' ? 'Rechtliches' : 'Legal', - 'purpose' => $lang === 'de' ? 'Unternehmensgegenstand / Blattlinie' : 'Business purpose / editorial line', - 'authority' => $lang === 'de' ? 'Aufsichts-/Gewerbebehörde' : 'Supervisory authority', + 'title' => $lang === 'de' ? 'Impressum' : 'Imprint', + 'owner' => $lang === 'de' ? 'Medieninhaber' : 'Media owner', + 'address' => $lang === 'de' ? 'Adresse' : 'Address', + 'contact' => $lang === 'de' ? 'Kontakt' : 'Contact', + 'legal' => $lang === 'de' ? 'Rechtliches' : 'Legal', + 'purpose' => $lang === 'de' ? 'Unternehmensgegenstand / Blattlinie' : 'Business purpose / editorial line', + 'authority' => $lang === 'de' ? 'Aufsichts-/Gewerbebehörde' : 'Supervisory authority', 'membership' => $lang === 'de' ? 'WKO-Mitgliedschaft' : 'Chamber membership', - 'uid' => $lang === 'de' ? 'UID' : 'VAT ID', - 'odr' => $lang === 'de' ? 'Verbraucherstreitbeilegung / ODR' : 'Consumer dispute resolution / ODR', + 'uid' => $lang === 'de' ? 'UID' : 'VAT ID', + 'odr' => $lang === 'de' ? 'Verbraucherstreitbeilegung / ODR' : 'Consumer dispute resolution / ODR', 'last_updated' => $lang === 'de' ? 'Stand' : 'Last updated', ]; function legal_item(string $label, ?string $value): void { $value = trim((string) $value); - if ($value === '') { - return; - } + if ($value === '') return; echo ''; } + +$pageTitle = e($t['title']) . ' | FlixCooks'; +$description = $lang === 'de' + ? 'Pflichtangaben für diese Website gemäß ECG, MedienG und GewO.' + : 'Mandatory website information in line with Austrian ECG, Media Act and Trade Regulation.'; + +include __DIR__ . '/partials/head.php'; +include __DIR__ . '/partials/header.php'; ?> - - - - - - <?php echo e($t['title']); ?> | FlixCooks - - - - -

' . e($t['odr']) . '' . e($odrText) . ' consumer-redress.ec.europa.eu'; + echo ''; } legal_item($t['last_updated'], $imprint['last_updated'] ?? ''); ?>
- - + diff --git a/index.php b/index.php index 7bd3a4d..48ff4b0 100644 --- a/index.php +++ b/index.php @@ -3,65 +3,96 @@ require __DIR__ . '/helpers.php'; // Language & inputs $lang = strtolower((string) (filter_input(INPUT_GET, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?: 'en')) === 'de' ? 'de' : 'en'; -$q = trim((string) (filter_input(INPUT_GET, 'q', FILTER_UNSAFE_RAW) ?? '')); -$tag = trim((string) (filter_input(INPUT_GET, 'tag', FILTER_UNSAFE_RAW) ?? '')); +$q = trim((string) (filter_input(INPUT_GET, 'q', FILTER_UNSAFE_RAW) ?? '')); +$tag = trim((string) (filter_input(INPUT_GET, 'tag', FILTER_UNSAFE_RAW) ?? '')); // Language copy $copy = [ 'en' => [ - 'home' => 'Home', - 'latest' => 'Latest', - 'basics' => 'Basics', - 'eyebrow' => 'Seasonal, unfussy, ridiculously tasty.', - 'headline' => 'Cook better weeknights and brighter weekends.', - 'subhead' => 'Search for a craving, filter by vibe, or jump into this week\'s featured recipe.', + 'home' => 'Home', + 'latest' => 'Latest', + 'basics' => 'Basics', + 'eyebrow' => 'Seasonal · Unfussy · Ridiculously tasty.', 'search_placeholder' => 'Search for pasta, brunch, sauce...', - 'search_button' => 'Search', - 'tag_clear' => 'Clear', - 'featured' => 'Featured', - 'latest_drops' => 'Latest drops', - 'count_suffix_default' => ' recipes ready to cook.', + 'search_button' => 'Search', + 'tag_clear' => 'Clear', + 'featured' => 'Featured', + 'latest_drops' => 'Latest drops', + 'count_suffix_default' => ' recipes ready to cook.', 'count_suffix_filtered' => ' recipes matching your filter.', - 'kitchen_basics' => 'Kitchen basics', - 'basics_sub' => 'Quick wins that upgrade everything else.', - 'servings' => 'servings', - 'cook_it' => 'Cook it', - 'coming_features' => 'Coming soon', - 'coming_features_sub' => 'Features I’m shipping next.', + 'kitchen_basics' => 'Kitchen basics', + 'basics_sub' => 'Quick wins that upgrade everything else.', + 'servings' => 'servings', + 'cook_it' => 'Cook it', + 'coming_features' => 'Coming soon', + 'coming_features_sub'=> 'Features I\'m shipping next.', + 'discover_title' => 'Find your next easy favorite.', + 'discover_text' => 'Search, filter by tag, and jump into a recipe.', + 'browse_tags' => 'Browse tags', + 'quick_start_title' => 'Quick start', + 'library_title' => 'Recipe library', + 'library_text' => 'Every recipe, searchable and filterable.', + 'stats_recipes' => 'live recipes', + 'stats_average' => 'avg. total time', + 'stats_tags' => 'browseable tags', + 'empty_title' => 'No recipes found', + 'empty_text' => 'Try another search term or clear the active tag.', + 'view_recipe' => 'View recipe', + 'stage_eyebrow' => 'Our Recipes', + 'stage_title_1' => 'Handcrafted', + 'stage_title_2' => 'dishes.', + 'stage_scroll' => 'scroll', + 'stage_of' => 'of', ], 'de' => [ - 'home' => 'Start', - 'latest' => 'Neueste', - 'basics' => 'Basics', - 'eyebrow' => 'Saisonal, unkompliziert, richtig lecker.', - 'headline' => 'Besser kochen unter der Woche, glänzen am Wochenende.', - 'subhead' => 'Suche nach einem Gericht, filtere nach Stimmung oder starte mit dem Highlight der Woche.', + 'home' => 'Start', + 'latest' => 'Neueste', + 'basics' => 'Basics', + 'eyebrow' => 'Saisonal · Unkompliziert · Richtig lecker.', 'search_placeholder' => 'Suche nach Pasta, Brunch, Sauce...', - 'search_button' => 'Suchen', - 'tag_clear' => 'Zurücksetzen', - 'featured' => 'Highlight', - 'latest_drops' => 'Frisch dazugekommen', - 'count_suffix_default' => ' Rezepte bereit zum Kochen.', + 'search_button' => 'Suchen', + 'tag_clear' => 'Zurücksetzen', + 'featured' => 'Highlight', + 'latest_drops' => 'Frisch dazugekommen', + 'count_suffix_default' => ' Rezepte bereit zum Kochen.', 'count_suffix_filtered' => ' Rezepte passend zum Filter.', - 'kitchen_basics' => 'Küchenbasics', - 'basics_sub' => 'Kleine Tricks, die alles besser machen.', - 'servings' => 'Portionen', - 'cook_it' => 'Nachkochen', - 'coming_features' => 'Demnächst', - 'coming_features_sub' => 'Features, an denen ich gerade baue.', + 'kitchen_basics' => 'Küchenbasics', + 'basics_sub' => 'Kleine Tricks, die alles besser machen.', + 'servings' => 'Portionen', + 'cook_it' => 'Nachkochen', + 'coming_features' => 'Demnächst', + 'coming_features_sub'=> 'Features, an denen ich gerade baue.', + 'discover_title' => 'Finde schnell dein nächstes Lieblingsrezept.', + 'discover_text' => 'Suchen, nach Tag filtern und ins Rezept springen.', + 'browse_tags' => 'Tags entdecken', + 'quick_start_title' => 'Schnell starten', + 'library_title' => 'Rezeptübersicht', + 'library_text' => 'Alle Rezepte, durchsuchbar und filterbar.', + 'stats_recipes' => 'Rezepte online', + 'stats_average' => 'Ø Gesamtzeit', + 'stats_tags' => 'durchsuchbare Tags', + 'empty_title' => 'Keine Rezepte gefunden', + 'empty_text' => 'Probiere einen anderen Suchbegriff oder entferne den aktiven Tag.', + 'view_recipe' => 'Rezept ansehen', + 'stage_eyebrow' => 'Unsere Rezepte', + 'stage_title_1' => 'Handgefertigte', + 'stage_title_2' => 'Gerichte.', + 'stage_scroll' => 'scrollen', + 'stage_of' => 'von', ], ]; $t = $copy[$lang]; -$allRecipes = load_recipes(); -$localizedAll = localize_recipes($allRecipes, $lang); -$recipes = filter_recipes($allRecipes, $q ?: null, $tag ?: null, $lang); -$recipes = array_values(array_filter($recipes, fn($r) => empty($r['coming_soon']))); // hide coming soon from main list +// Data +$allRecipes = load_recipes(); +$localizedAll = localize_recipes($allRecipes, $lang); +$recipes = filter_recipes($allRecipes, $q ?: null, $tag ?: null, $lang); +$recipes = array_values(array_filter($recipes, fn($r) => empty($r['coming_soon']))); -$comingSoon = array_values(array_filter($localizedAll, fn($r) => !empty($r['coming_soon']))); +$comingSoon = array_values(array_filter($localizedAll, fn($r) => !empty($r['coming_soon']))); $placeholderTitle = $lang === 'de' ? 'Bald verfügbar' : 'Coming soon'; $comingSoonDisplay = array_pad($comingSoon, 5, [ - 'hero' => '/assets/placeholder.svg', + 'hero' => '/assets/placeholder.svg', 'title' => $placeholderTitle, ]); @@ -78,11 +109,12 @@ $featured = $featured ? localize_recipe($featured, $lang) : null; // Build tag cloud $allTags = []; foreach ($localizedAll as $recipe) { - foreach ($recipe['tags'] ?? [] as $tTag) { - $allTags[] = $tTag; - } + foreach ($recipe['tags'] ?? [] as $tTag) { $allTags[] = $tTag; } } -$allTags = array_values(array_unique($allTags)); +$allTags = array_values(array_unique($allTags)); + +// Stage recipes (only fully published, non-coming-soon) +$stageRecipes = array_values(array_filter($localizedAll, fn($r) => empty($r['coming_soon']) && !empty($r['title']))); $comingFeatures = $lang === 'de' ? [ @@ -96,68 +128,66 @@ $comingFeatures = $lang === 'de' 'Step-by-step recipe assistant with videos', ]; -$pageTitle = $lang === 'de' +// Meta +$pageTitle = $lang === 'de' ? 'FlixCooks | Moderner Foodblog für schnelle Alltagsküche' : 'FlixCooks | Modern food blog for busy home cooks'; $description = $lang === 'de' - ? 'Frische, schnelle Rezepte mit klaren Schritten und großem Geschmack. Gebaut für Hetzner Webhosting in einfachem PHP.' - : 'Fresh, fast recipes with clear steps, smart prep notes, and big flavor. Built for Hetzner web hosting in plain PHP.'; + ? 'Frische, schnelle Rezepte mit klaren Schritten und großem Geschmack.' + : 'Fresh, fast recipes with clear steps, smart prep notes, and big flavor.'; $langSwitchLabel = $lang === 'de' ? 'DE' : 'EN'; -$langSwitchHref = lang_url($lang === 'de' ? 'en' : 'de'); -$navHome = $t['home']; -$navLatest = $t['latest']; -$navBasics = $t['basics']; +$langSwitchHref = lang_url($lang === 'de' ? 'en' : 'de'); +$navHome = $t['home']; +$navLatest = $t['latest']; +$navBasics = $t['basics']; -$quickStartRecipes = array_slice($recipes, 0, 3); -$latestRecipes = array_slice($recipes, 0, 6); -$recipeCount = count($recipes); -$totalMinutes = array_sum(array_map(fn($recipe) => (int) ($recipe['total_time'] ?? 0), $recipes)); -$averageMinutes = $recipeCount > 0 ? (int) ceil($totalMinutes / $recipeCount) : 0; -$activeTag = $tag !== '' ? $tag : null; -$tagCount = count($allTags); - -$copy['en'] += [ - 'discover_title' => 'Find your next easy favorite.', - 'discover_text' => 'Everything below the landing area is simplified for smaller screens: search, tap a tag, and jump into a recipe without cramped text blocks.', - 'browse_tags' => 'Browse tags', - 'quick_start_title' => 'Quick start', - 'quick_start_text' => 'Open one of the recipes with the shortest path from craving to plate.', - 'library_title' => 'Recipe library', - 'library_text' => 'Clean cards, shorter descriptions, and tap-friendly actions for mobile browsing.', - 'stats_recipes' => 'live recipes', - 'stats_average' => 'avg. total time', - 'stats_tags' => 'browseable tags', - 'empty_title' => 'No recipes found yet', - 'empty_text' => 'Try another search term or clear the active tag to see every recipe again.', - 'view_recipe' => 'View recipe', -]; -$copy['de'] += [ - 'discover_title' => 'Finde schnell dein nächstes Lieblingsrezept.', - 'discover_text' => 'Alles unterhalb der Landingpage ist für kleine Screens vereinfacht: suchen, Tag antippen und ohne gequetschte Textblöcke ins Rezept springen.', - 'browse_tags' => 'Tags entdecken', - 'quick_start_title' => 'Schnell starten', - 'quick_start_text' => 'Öffne eines der Rezepte mit dem kürzesten Weg von Appetit zu Teller.', - 'library_title' => 'Rezeptübersicht', - 'library_text' => 'Saubere Karten, kürzere Beschreibungen und gut tappbare Aktionen für Mobile.', - 'stats_recipes' => 'Rezepte online', - 'stats_average' => 'Ø Gesamtzeit', - 'stats_tags' => 'durchsuchbare Tags', - 'empty_title' => 'Noch keine Rezepte gefunden', - 'empty_text' => 'Probiere einen anderen Suchbegriff oder entferne den aktiven Tag, um wieder alle Rezepte zu sehen.', - 'view_recipe' => 'Rezept ansehen', -]; -$t = $copy[$lang]; +$recipeCount = count($recipes); +$totalMinutes = array_sum(array_map(fn($r) => (int)($r['total_time'] ?? 0), $recipes)); +$averageMinutes = $recipeCount > 0 ? (int)ceil($totalMinutes / $recipeCount) : 0; +$activeTag = $tag !== '' ? $tag : null; +$tagCount = count($allTags); // Small helpers for URLs $langQuery = ['lang' => $lang]; $recipeUrl = fn(array $recipe) => '/recipe.php?' . http_build_query(['slug' => $recipe['slug']] + $langQuery); -$tagUrl = fn(string $tagValue) => '/index.php?' . http_build_query(['tag' => $tagValue] + $langQuery); +$tagUrl = fn(string $tagValue) => '/index.php?' . http_build_query(['tag' => $tagValue] + $langQuery); include __DIR__ . '/partials/head.php'; ?> - -
+ + + + + + + + + +
-

- -

+

Besser kochen @@ -198,30 +224,108 @@ include __DIR__ . '/partials/head.php'; Brighter weekends.

-

- +

+
- +
- -
- + + + + +
+ + +
+

+

+
+

+
+
+ + +
+ $sr): ?> +
+
+ <?php echo e($sr['title']); ?> +
+
+

+ +

+ +

+ +

+ +

+ +

160 ? '…' : ''; ?>

+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ + + + + + + +
+ + + + +
-
+
-

+

@@ -237,18 +341,21 @@ document.getElementById('landingCta').addEventListener('click', function(e){
-
+ +
-

+

-
- # + #
@@ -289,31 +397,36 @@ document.getElementById('landingCta').addEventListener('click', function(e){
-
+ + +

- +
- -
-
+ + +
+

-
+

@@ -361,4 +480,314 @@ document.getElementById('landingCta').addEventListener('click', function(e){
+ + + + + diff --git a/partials/footer.php b/partials/footer.php index a607ef5..870963a 100644 --- a/partials/footer.php +++ b/partials/footer.php @@ -1,79 +1,78 @@ -