PageSourceSearch

https://popiah.dev/

html popiah.dev collected 2026-10-04 19:20:36 UTC 61,713 bytes, 947 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5  <meta charset="UTF-8">
6  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'sha256-g5a3SrOYIecCloZ8S7M4xdT1pbYi6e7mjHrmwphRxfE=' https://static.cloudflareinsights.com; worker-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: blob: https://images.unsplash.com; manifest-src 'self'; connect-src 'self' ws: wss: https://cloudflareinsights.com https://fonts.googleapis.com https://fonts.gstatic.com https://api.groq.com https://generativelanguage.googleapis.com https://api.openai.com;">
7  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
8  <meta name="apple-mobile-web-app-capable" content="yes">
9<meta name="mobile-web-app-capable" content="yes">
10  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
11  <meta name="apple-mobile-web-app-title" content="Chef Popiah">
12  <meta name="format-detection" content="telephone=no">
13  <meta name="description" content="Chef Popiah: Your intelligent AI sous-chef and interactive kitchen companion. Cook delicious recipes step-by-step with smart timers.">
14  <meta name="keywords" content="chef popiah, ai sous chef, culinary assistant, smart kitchen timer, interactive recipe copilot, cooking clock">
15  <meta name="author" content="popiah.dev">
16  <meta property="og:title" content="Chef Popiah — AI Sous-Chef & Kitchen Companion">
17  <meta property="og:type" content="website">
18
19  <title>Chef Popiah — AI Sous-Chef & Kitchen Companion</title>
20  <link rel="icon" type="image/svg+xml" href="favicon.svg">
21  <link rel="apple-touch-icon" href="favicon.svg">
22  <link rel="manifest" href="manifest.json">
23  <meta name="theme-color" content="#ff5f56">
24  <!-- Open Graph / Social Sharing -->
25  <meta property="og:title" content="Chef Popiah — AI Sous-Chef & Kitchen Companion">
26  <meta property="og:description" content="Chef Popiah: Your intelligent AI sous-chef and interactive kitchen companion. Cook delicious recipes step-by-step with smart timers.">
27  <meta property="og:type" content="website">
28  <meta property="og:url" content="https://popiah.dev">
29  <meta name="twitter:card" content="summary">
30  <meta name="twitter:title" content="Chef Popiah — AI Sous-Chef & Kitchen Companion">
31  <meta name="twitter:description" content="Chef Popiah: Your intelligent AI sous-chef and interactive kitchen companion. Cook delicious recipes step-by-step with smart timers.">
32  <link rel="stylesheet" href="index.css?v=2.1.0">
33
34
35
36  <!-- Structured Data -->
37  
37<script type="application/ld+json">
38   {
39    "@context": "https://schema.org",
40    "@type": "WebApplication",
41    "name": "Chef Popiah",
42    "url": "https://popiah.dev",
43    "description": "Your intelligent AI sous-chef and interactive kitchen companion. Cook delicious recipes step-by-step with smart timers.",
44    "applicationCategory": "LifestyleApplication",
45    "operatingSystem": "Web",
46    "browserRequirements": "Requires JavaScript",
47    "author": {
48      "@type": "Organization",
49      "name": "popiah.dev"
50    }
51  }
52  </script>
52
53
54  
54<script src="error-tracker.js?v=2.1.0"></script>
54
55  
55<script src="mascot-init.js?v=2.1.0"></script>
55
56</head>
57<body>
58  <div id="ambient-glow" class="ambient-glow"></div>
59
60  <!-- Centered Brand Showcase -->
61  <div class="brand-showcase-container">
62    <div class="brand-card">
63      <svg class="brand-card-border-svg">
64        <rect class="brand-card-border-rect" rx="16" ry="16" vector-effect="non-scaling-stroke"></rect>
65      </svg>
66      <button class="timer-settings-btn transition-transform active:scale-90" id="timer-settings-toggle" title="Settings">
67        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
68          <circle cx="12" cy="12" r="3"></circle>
69          <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
70        </svg>
71      </button>
72      <button class="theme-toggle-btn transition-transform active:scale-90" id="theme-toggle" title="Switch Theme (☀️ Warm Kitchen / 🌙 Midnight Chef)">
73        <svg class="theme-icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
74          <circle cx="12" cy="12" r="5"></circle>
75          <line x1="12" y1="1" x2="12" y2="3"></line>
76          <line x1="12" y1="21" x2="12" y2="23"></line>
77          <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
78          <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
79          <line x1="1" y1="12" x2="3" y2="12"></line>
80          <line x1="21" y1="12" x2="23" y2="12"></line>
81          <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
82          <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
83        </svg>
84        <svg class="theme-icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;">
85          <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
86        </svg>
87      </button>
88      <button class="pip-toggle-btn transition-transform active:scale-90" id="pip-toggle" title="Float Window (Always on Top)">
89        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
90          <rect x="2" y="2" width="20" height="20" rx="2" ry="2"></rect>
91          <rect x="13" y="13" width="9" height="9" rx="1" ry="1" fill="currentColor" fill-opacity="0.25"></rect>
92        </svg>
93      </button>
94      <button class="clock-toggle-btn transition-transform active:scale-90" id="clock-toggle" title="Kitchen Timer Mode">
95        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
96          stroke-linecap="round" stroke-linejoin="round">
97          <circle cx="12" cy="12" r="10"></circle>
98          <polyline points="12 6 12 12 16 14"></polyline>
99        </svg>
100      </button>
101      
102      <!-- Glassmorphic Settings Overlay -->
103      <div class="timer-settings-panel" id="timer-settings-panel">
104        <div class="settings-header">
105          <div class="settings-header-center">
106            <div class="settings-header-badge">
107              <svg class="settings-header-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
108                <circle cx="12" cy="12" r="3"></circle>
109                <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 
1090 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
110              </svg>
111              <span>Preferences</span>
112            </div>
113            <div class="settings-title">Settings</div>
114          </div>
115          <button type="button" class="settings-close-btn transition-all duration-150 active:scale-90" id="settings-close-btn" aria-label="Close Settings" title="Close Settings (Esc)">✕</button>
116        </div>
117
118        <div class="settings-content-flow">
119          <!-- Card 1: Appearance & Ambience -->
120          <div class="settings-section-card">
121            <div class="settings-card-header">
122              <span class="settings-card-icon">🎨</span>
123              <div class="settings-subtitle">Appearance & Ambience</div>
124            </div>
125
126            <!-- Theme Row (Full-width Justified Stack) -->
127            <div class="settings-stacked-row select-row">
128              <div class="settings-label-wrap">
129                <label for="theme-select">Visual Theme</label>
130                <span class="settings-hint-text">Atmospheric lighting & palette</span>
131              </div>
132              <select id="theme-select" class="sr-only">
133                <option value="warm-kitchen">☀️ Warm Kitchen (Daylight)</option>
134                <option value="midnight">🌙 Midnight Chef (Dark)</option>
135              </select>
136              <div class="settings-segmented-control grid grid-cols-2 p-1 bg-black/40 rounded-xl border border-white/10 w-full" id="theme-segmented-control" role="radiogroup" aria-label="Theme selection">
137                <button type="button" class="theme-segment-btn flex items-center justify-center gap-1.5 py-1.5 px-2 rounded-lg text-xs font-semibold transition-all" data-value="warm-kitchen">
138                  <span>☀️</span> Warm Kitchen
139                </button>
140                <button type="button" class="theme-segment-btn flex items-center justify-center gap-1.5 py-1.5 px-2 rounded-lg text-xs font-medium transition-all" data-value="midnight">
141                  <span>🌙</span> Midnight Chef
142                </button>
143              </div>
144            </div>
145
146            <div class="settings-card-divider"></div>
147
148            <!-- Mascot Row -->
149            <div class="settings-row select-row">
150              <div class="settings-label-wrap">
151                <label for="mascot-select">Mascot Companion</label>
152                <span class="settings-hint-text">Animated sous-chef cat</span>
153              </div>
154              <div class="settings-custom-select-wrap">
155                <select id="mascot-select" class="settings-styled-select">
156                  <option value="abyssinian">🦊 Red Abyssinian</option>
157                  <option value="tuxedo">🐈‍⬛ Tuxedo Cat</option>
158                </select>
159                <svg class="select-chevron" width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
160                  <polyline points="6 9 12 15 18 9"></polyline>
161                </svg>
162              </div>
163            </div>
164          </div>
165
166          <div class="settings-divider"></div>
167
168          <!-- Card 2: Kitchen Timer & Measurements -->
169          <div class="settings-section-card">
170            <div class="settings-card-header">
171              <span class="settings-card-icon">⏱️</span>
172              <div class="settings-subtitle">Kitchen Timer & Measurements</div>
173            </div>
174
175            <!-- Units Row (Full-width Justified Stack) -->
176            <div class="settings-stacked-row select-row">
177              <div class="settings-label-wrap">
178                <label for="units-select">Units System</label>
179                <span class="settings-hint-text">Recipe ingredient measurements</span>
180              </div>
181              <select id="units-select" class="sr-only">
182                <option value="metric">Metric / SI (g, ml, °C)</option>
183                <option value="imperial">Imperial / US (oz, cup, °F)</option>
184              </select>
185              <div class="settings-segmented-control grid grid-cols-2 p-1 bg-black/40 rounded-xl border border-white/10 w-full" id="units-segmented-control" role="radiogroup" aria-label="Units selection">
186                <button type="button" class="units-segment-btn flex items-center justify-center gap-1.5 py-1.5 px-2 rounded-lg text-xs font-semibold transition-all" data-value="metric">
187                  <span>⚖️</span> Metric (g/ml)
188                </button>
189                <button type="button" class="units-segment-btn flex items-center justify-center gap-1.5 py-1.5 px-2 rounded-lg text-xs font-medium transition-all" data-value="imperial">
190                  <span>📏</span> Imperial (oz/cup)
191                </button>
192              </div>
193            </div>
194
195            <div class="settings-card-divider"></div>
196
197            <!-- Default Kitchen Timer Row -->
198            <div class="settings-row number-row" id="focus-settings-row">
199              <div class="settings-label-wrap">
200                <label for="focus-input">Quick Timer Duration</label>
201                <span class="settings-hint-text">Default kitchen timer interval (1-180 min)</span>
202              </div>
203              <div class="settings-stepper">
204                <button type="button" class="stepper-btn stepper-minus" data-target="focus-input" data-step="5" aria-label="Decrease timer minutes">−</button>
205                <div class="stepper-input-box">
206                  <input type="number" id="focus-input" min="1" max="180" value="15">
207                  <span class="stepper-unit">min</span>
208                </div>
209                <button type="button" class="stepper-btn stepper-plus" data-target="focus-input" data-step="5" aria-label="Increase timer minutes">+</button>
210              </div>
211            </div>
212          </div>
213
214          <div class="settings-divider"></div>
215
216          <!-- Card 3: Sous-Chef Intelligence -->
217          <div class="settings-section-card">
218            <div class="settings-card-header">
219              <span class="settings-card-icon">✨</span>
220              <div class="settings-subtitle">Sous-Chef Intelligence</div>
221            </div>
222
223            <div class="settings-row select-row">
224              <div class="settings-label-wrap">
225                <label for="ai-provider-select">AI Engine</label>
226                <span class="settings-hint-text" id="ai-engine-hint">Chef Popiah Cloud (Built-in)</span>
227              </div>
228              <div class="settings-custom-select-wrap">
229                <select id="ai-provider-select" class="settings-styled-select">
230                  <option value="edge" selected>⚡ Chef Popiah Cloud (Built-in)</option>
231                  <option value="local">🖥️ Your Local LLM (Ollama / LM Studio / vLLM)</option>
232                  <option value="gemini" disabled>✨ Google Gemini (BYOK - Coming Soon)</option>
233                  <option value="openai" disabled>🤖 OpenAI (BYOK - Coming Soon)</option>
234                  <option value="groq" disabled>⚡ Groq (BYOK - Coming Soon)</option>
235                </select>
236                <svg class="select-chevron" width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
237                  <polyline points="6 9 12 15 18 9"></polyline>
238                </svg>
239              </div>
240            </div>
241
242            <!-- Local LLM Configuration (Shown when "Your Local LLM" is selected) -->
243            <div id="local-ai-config-section" style="display: none; width: 100%; flex-direction: column; gap: 10px;">
244              <div class="settings-row text-row" id="local-ai-endpoint-row">
245                <div class="settings-label-wrap">
246                  <label for="local-ai-url-input">Endpoint URL</label>
247                  <span class="settings-hint-text">Ollama, LM Studio, or vLLM</span>
248                </div>
249                <div class="settings-key-input-wrap">
250                  <input type="text" id="local-ai-url-input" placeholder="http://localhost:11434/v1" autocomplete="off" spellcheck="false">
251                </div>
252              </div>
253
254              <div class="settings-row text-row" id="local-ai-model-row">
255                <div class="settings-label-wrap">
256                  <label for="local-ai-model-input">Model Name</label>
257                  <span class="settings-hint-text">Model loaded in local runner</span>
258                </div>
259                <div class="settings-key-input-wrap">
260                  <input type="text" id="local-ai-model-input" placeholder="llama3.2" autocomplete="off" spellcheck="false">
261                </div>
262              </div>
263
264              <div class="settings-row text-row" id="local-ai-key-row">
265                <div class="settings-label-wrap">
266                  <label for="local-ai-key-input">API Key (Optional)</label>
267                  <span class="settings-hint-text">Only if your server requires auth</span>
268                </div>
269                <div class="settings-key-input-wrap">
270                  <input type="password" id="local-ai-key-input" placeholder="Optional (e.g. ollama, vllm)" autocomplete="off">
271                </div>
272              </div>
273
274              <div class="settings-row actions-row" style="margin-top: 4px; justify-content: space-between; align-items: center;">
275                <div class="settings-label-wrap">
276                  <span class="settings-hint-text" style="font-size: 0.68rem; color: #94a3b8;">🔒 Direct browser connection</span>
277                </div>
278                <button type="button" class="settings-test-btn" id="local-ai-test-btn" style="padding: 5px 12px; font-size: 0.72rem; font-weight: 600; border-radius: 8px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.08); color: #fed7aa; cursor: pointer; transition: all 0.2s;">
279                  🔌 Test Connection
280                </button>
281              </div>
282              <div id="local-ai-test-result" style="display: none; font-size: 0.72rem; padding: 6px 10px; border-radius: 8px; margin-top: 4px; line-height: 1.4;"></div>
283              <div class="settings-hint" style="margin-top: 4px; font-size: 0.65rem; color: #71717a; line-height: 1.35;">
284                💡 <strong>Tip:</strong> Ensure your local runner has CORS enabled (e.g. <code>OLLAMA_ORIGINS="*"</code> for Ollama, or "Enable CORS" in LM Studio).
285              </div>
286            </div>
287
288            <div class="settings-row text-row" id="ai-key-row" style="display: none;">
289              <div class="settings-label-wrap">
290                <label for="ai-api-key-input">API Key</label>
291                <span class="settings-hint-text">🔒 Stored locally in browser</span>
292              </div>
293              <div class="settings-key-input-wrap">
294                <input type="password" id="ai-api-key-input" placeholder="Paste API key..." autocomplete="off">
295              </div>
296            </div>
297          </div>
298
299          <div class="settings-divider"></div>
300
301          <!-- Card 4: Dietary & Allergens -->
302          <div class="settings-section-card" id="guardrails-settings-card">
303            <div class="settings-card-header">
304              <span class="settings-card-icon">🛡️</span>
305              <div class="settings-subtitle" id="guardrails-settings-section">Dietary & Allergens</div>
306            </div>
307            <div class="settings-hint">Persistent rules for all recipes</div>
308
309            <div class="settings-row switch-row checkbox-row">
310              <div class="settings-label-wrap">
311                <label for="guardrail-halal">🕌 Halal (No Pork/Alcohol)</label>
312                <span class="settings-hint-text">Zero pork, lard, bacon, or cooking alcohol</span>
313              </div>
314              <label class="settings-toggle-switch" for="guardrail-halal">
315                <input type="checkbox" id="guardrail-halal" class="settings-toggle-input">
316                <span class="settings-toggle-track"></span>
317              </label>
318            </div>
319
320            <div class="settings-card-divider"></div>
321
322            <div class="settings-row switch-row checkbox-row">
323              <div class="settings-label-wrap">
324                <label for="guardrail-kosher">✡️ Kosher (No Pork/Shellfish)</label>
325                <span class="settings-hint-text">Zero pork, zero shellfish, separated dairy</span>
326              </div>
327              <label class="settings-toggle-switch" for="guardrail-kosher">
328                <input type="checkbox" id="guardrail-kosher" class="settings-toggle-input">
329                <span class="settings-toggle-track"></span>
330              </label>
331            </div>
332
333            <div class="settings-card-divider"></div>
334
335            <div class="settings-allergens-wrap">
336              <div class="settings-sublabel">Allergen Exclusions:</div>
337              <div class="settings-allergens-chips" id="settings-allergens-chips">
338                <button type="button" class="allergen-chip" data-allergen="peanuts">🥜 Peanuts</button>
339                <button type="button" class="allergen-chip" data-allergen="tree-nuts">🌰 Tree Nuts</button>
340                <button type="button" class="allergen-chip" data-allergen="shellfish">🦐 Shellfish</button>
341                <button type="button" class="allergen-chip" data-allergen="gluten">🌾 Gluten</button>
342                <button type="button" class="allergen-chip" data-allergen="dairy">🥛 Dairy</button>
343                <button type="button" class="allergen-chip" data-allergen="soy">🫘 Soy</button>
344                <button type="button" class="allergen-chip" data-allergen="eggs">🥚 Eggs</button>
345                <button type="button" class="allergen-chip" data-allergen="sesame">🌿 Sesame</button>
346              </div>
347            </div>
348          </div>
349        </div>
350
351        <!-- Sticky Actions & Version Footer -->
352        <div class="settings-actions-footer">
353          <div class="settings-actions">
354            <button class="settings-cancel-btn transition-all duration-150 active:scale-95" id="settings-cancel-btn">Cancel</button>
355            <button class="settings-save-btn transition-all duration-150 active:scale-95" id="settings-save-btn">Save</button>
356          </div>
357          <div class="settings-version-info">
358            v2.1.0 • Sep 13, 2026
359          </div>
360        </div>
361      </div>
362      <!-- Culinary Sous-Chef HUD Bar (Compact horizontal header in recipe mode) -->
363      <div class="recipe-hud-bar" id="recipe-hud-bar">
364        <div class="hud-left-group">
365          <div class="logo-wrapper">
366          <!-- SVG Red Abyssinian Cat Logo with code elements -->
367          <svg viewBox="0 2 100 70" fill="none" xmlns="http://www.w3.org/2000/svg">
368            <defs>
369              <linearGradient id="cat-grad-l" x1="0%" y1="0%" x2="0%" y2="100%">
370                <stop offset="0%" stop-color="var(--cat-fur-l-start, hsl(18, 90%, 58%))" />
371                <stop offset="100%" stop-color="var(--cat-fur-l-end, hsl(18, 90%, 48%))" />
372              </linearGradient>
373              <linearGradient id="cat-grad-r" x1="0%" y1="0%" x2="0%" y2="100%">
374                <stop offset="0%" stop-color="var(--cat-fur-r-start, hsl(18, 85%, 52%))" />
375                <stop offset="100%" stop-color="var(--cat-fur-r-end, hsl(18, 85%, 42%))" />
376              </linearGradient>
377              <radialGradient id="eye-glow" cx="40%" cy="40%" r="60%">
378                <stop offset="0%" stop-color="var(--cat-eye-start, hsl(42, 100%, 72%))" />
379                <stop offset="100%" stop-color="var(--cat-eye-end, hsl(38, 95%, 48%))" />
380              </radialGradient>
381              <filter id="eye-blur" filterUnits="userSpaceOnUse" x="0" y="0" width="100" height="70">
382                <feGaussianBlur stdDeviation="1.5" />
383              </filter>
384            </defs>
385            <!-- Left Ear -->
386            <!-- Curved Left Ear (Default) -->
387            <path class="cat-ear-l cat-ear-l-curved" d="M 28 42 c -1.4987 -3.0214, -7.3610 -14.1069, -8.9925 -18.1282 c -1.6315 -4.0213, -1.7318 -5.4579, -0.7963 -5.9997 c 0.9356 -0.5418, 3.1120 0.3805, 6.4100 2.7487 c 3.2980 2.3682, 11.1483 9.5505, 13.3788 11.3792 Z" fill="url(#cat-grad-l)" stroke="var(--border-glass-bright)"
388              stroke-width="1.2" stroke-linejoin="round" />
389            <path class="cat-ear-l cat-ear-l-curved" d="M 26 38 c -0.7273 -2.0094, -3.6486 -9.3976, -4.3639 -12.0561 c -0.7153 -2.6586, -0.6352 -3.5874, 0.0721 -3.8953 c 0.7073 -0.3079, 2.1252 0.3801, 4.1723 2.0474 c 2.0472 1.6673, 6.7587 6.6303, 8.1196 7.9040 Z" fill="var(--cat-inner-ear, #4A1505)" opacity="0.65" />
390            <!-- Pointy Left Ear (Focus Mode) -->
391            <path class="cat-ear-l cat-ear-l-pointy" d="M38 32 L12 12 L28 42 Z" fill="url(#cat-grad-l)" stroke="var(--border-glass-bright)"
392              stroke-width="1.2" stroke-linejoin="round" />
393            <path class="cat-ear-l cat-ear-l-pointy" d="M34 32 L18 18 L26 38 Z" fill="var(--cat-inner-ear, #4A1505)" opacity="0.65" />
394
395            <!-- Right Ear -->
396            <!-- Curved Right Ear (Default) -->
397            <path class="cat-ear-r cat-ear-r-curved" d="M 72 42 c 1.4987 -3.0214, 7.3610 -14.1069, 8.9925 -18.1282 c 1.6315 -4.0213, 1.7318 -5.4579, 0.7963 -5.9997 c -0.9356 -0.5418, -3.1120 0.3805, -6.4100 2.7487 c -3.2980 2.3682, -11.1483 9.5505, -13.3788 11.3792 Z" fill="url(#cat-grad-r)" stroke="var(--border-glass-bright)"
398              stroke-width="1.2" stroke-linejoin="round" />
399            <path class="cat-ear-r cat-ear-r-curved" d="M 74 38 c 0.7273 -2.0094, 3.6486 -9.3976, 4.3639 -12.0561 c 0.7153 -2.6586, 0.6352 -3.5874, -0.0721 -3.8953 c -0.7073 -0.3079, -2.1252 0.3801, -4.1723 2.0474 c -2.0472 1.6673, -6.7587 6.6303, -8.1196 7.9040 Z" fill="var(--cat-inner-ear, #4A1505)" opacity="0.8" />
400            <!-- Pointy Right Ear (Focus Mode) -->
401            <path class="cat-ear-r cat-ear-r-pointy" d="M62 32 L88 12 L72 42 Z" fill="url(#cat-grad-r)" stroke="var(--border-glass-bright)"
402              stroke-width="1.2" stroke-linejoin="round" />
403            <path class="cat-ear-r cat-ear-r-pointy" d="M66 32 L82 18 L74 38 Z" fill="var(--cat-inner-ear, #4A1505)" opacity="0.8" />
404
405            <!-- Head split (3D Bisection Fold) -->
406            <path d="M50 30 L28 42 L50 68 Z" fill="url(#cat-grad-l)" stroke="var(--border-glass)" stroke-width="0.5"
407              stroke-linejoin="round" />
408            <path d="M50 30 L72 42 L50 68 Z" fill="url(#cat-grad-r)" stroke="var(--border-glass)" stroke-width="0.5"
409              stroke-linejoin="round" />
410
411            <!-- Face Patch (toggled and styled via CSS) -->
412            <path class="cat-face-patch" d="M50 46 L42 60 L50 68 L58 60 Z" />
413
414            <!-- Golden Almond Eyes -->
415            <path class="cat-eye-glow cat-eye-iris-l" d="M36 44 Q43 40 46 47 Q41 50 36 44 Z" fill="var(--cat-eye-glow, hsl(42, 95%, 52%))"
416              stroke="var(--cat-eye-glow, hsl(42, 95%, 52%))" stroke-width="2.5" stroke-linejoin="round" filter="url
416(#eye-blur)" />
417            <path class="cat-eye-glow cat-eye-iris-r" d="M64 44 Q57 40 54 47 Q59 50 64 44 Z" fill="var(--cat-eye-glow, hsl(42, 95%, 52%))"
418              stroke="var(--cat-eye-glow, hsl(42, 95%, 52%))" stroke-width="2.5" stroke-linejoin="round" filter="url(#eye-blur)" />
419
420            <path class="cat-eye cat-eye-iris-l" d="M36 44 Q43 40 46 47 Q41 50 36 44 Z" fill="url(#eye-glow)" />
421            <ellipse class="cat-eye cat-pupil-l" cx="41.5" cy="45" rx="0.6" ry="2.2" fill="var(--cat-pupil, #0c0806)" />
422            <circle class="cat-eye cat-eye-highlight" cx="40.5" cy="44" r="0.8" fill="white" opacity="0.9" />
423
424            <path class="cat-eye cat-eye-iris-r" d="M64 44 Q57 40 54 47 Q59 50 64 44 Z" fill="url(#eye-glow)" />
425            <ellipse class="cat-eye cat-pupil-r" cx="58.5" cy="45" rx="0.6" ry="2.2" fill="var(--cat-pupil, #0c0806)" />
426            <circle class="cat-eye cat-eye-highlight" cx="57.5" cy="44" r="0.8" fill="white" opacity="0.9" />
427
428            <!-- Nose -->
429            <path d="M48 56 L52 56 L50 59 Z" fill="var(--cat-nose, #5C3218)" />
430
431            <!-- Developer Whiskers (Code Angle Brackets) -->
432            <path class="cat-whisker" d="M22 52 L10 60 L22 68" stroke="var(--cat-whisker, var(--primary))" stroke-width="2.5"
433              stroke-linecap="round" stroke-linejoin="round" />
434            <path class="cat-whisker" d="M78 52 L90 60 L78 68" stroke="var(--cat-whisker, var(--primary))" stroke-width="2.5"
435              stroke-linecap="round" stroke-linejoin="round" />
436          </svg>
437        </div>
438        <span class="hud-brand-tag transition-all duration-200" id="hud-brand-tag" title="Chef Popiah Culinary Assistant">Chef Popiah</span>
439      </div>
440      <h1 class="brand-title">Chef <span>Popiah</span></h1>
441      <div class="hud-center-group">
442        <div class="clock-display" id="clock-time"><span class="clock-unit-hrs">00</span><span
443            class="clock-colon">:</span><span class="clock-unit-mins">00</span></div>
444        <button type="button" class="hud-timer-pause-btn transition-all duration-150 active:scale-90" id="hud-timer-pause-btn" title="Pause / Resume Cooking Timer" aria-label="Pause or Resume Timer" style="display: none;">
445          <span class="hud-pause-icon">⏸️</span>
446          <span class="hud-play-icon" style="display: none;">▶️</span>
447        </button>
448        <span class="hud-step-badge transition-all duration-150 active:scale-95 select-none" id="hud-step-badge" style="display: none;">0/0 done</span>
449        <div class="clock-meta" id="clock-meta">
450          <span id="clock-date"></span>
451          <span class="clock-meta-divider">•</span>
452          <div class="clock-session-wrap">
453            <span id="clock-session" title="Kitchen timer active • Scroll wheel or drag to adjust • Click to reset">Timer: 15:00</span>
454            <button type="button" class="picker-wheel-trigger" id="picker-wheel-trigger" title="Open Picker Wheel (Scroll or Drag to spin)">
455              <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
456                <circle cx="12" cy="12" r="9"></circle>
457                <polyline points="12 6 12 12 15 15"></polyline>
458              </svg>
459            </button>
460          </div>
461        </div>
462      </div>
463      <div class="hud-right-group" id="hud-right-group">
464        <button type="button" class="hud-action-btn transition-all duration-150 active:scale-95" id="hud-settings-btn" title="Settings" aria-label="Settings">
465          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
466            <circle cx="12" cy="12" r="3"></circle>
467            <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
468          </svg>
469        </button>
470        <button type="button" class="hud-action-btn transition-all duration-150 active:scale-95" id="hud-pip-btn" title="Float Window (Always on Top)" aria-label="Picture in Picture">
471          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
472            <rect x="2" y="2" width="20" height="20" rx="2" ry="2"></rect>
473            <rect x="13" y="13" width="9" height="9" rx="1" ry="1" fill="currentColor" fill-opacity="0.25"></rect>
474          </svg>
475        </button>
476        <button type="button" class="hud-action-btn hud-close-btn transition-all duration-150 active:scale-90" id="hud-close-recipe-btn" title="Exit Recipe" aria-label="Close Recipe">✕</button>
477      </div>
478    </div>
479    <!-- Thin Step Progress Line -->
480    <div class="hud-progress-line-track" id="hud-progress-line-track" style="display: none;">
481      <div class="hud-progress-line-fill" id="hud-progress-line-fill" style="width: 0%;"></div>
482    </div>
483      <div class="timer-adjust-bubble" id="timer-adjust-bubble" aria-live="polite"></div>
484
485      <!-- Interactive 3D Timer Picker Wheel -->
486      <div class="timer-picker-wheel" id="timer-picker-wheel" aria-label="Timer Picker Wheel">
487        <div class="picker-wheel-card">
488          <div class="picker-wheel-header">
489            <button type="button" class="picker-wheel-close transition-all duration-150 active:scale-90" id="picker-wheel-close" title="Done (Esc)">✓ Done</button>
490          </div>
491          
492          <div class="picker-wheel-cylinder-wrapper" id="picker-wheel-wrapper">
493            <div class="picker-wheel-lens"></div>
494            <div class="picker-wheel-cylinder" id="picker-wheel-cylinder">
495              <!-- Drum slats rendered dynamically with 3D rotation -->
496            </div>
497          </div>
498        </div>
499      </div>
500
501      <!-- Interactive 3D Servings / Pax Picker Wheel -->
502      <div class="servings-picker-wheel" id="servings-picker-wheel" aria-label="Servings Picker Wheel">
503        <div class="picker-wheel-card">
504          <div class="picker-wheel-header">
505            <button type="button" class="picker-wheel-close transition-all duration-150 active:scale-90" id="servings-wheel-close" title="Done (Esc)">✓ Done</button>
506          </div>
507          
508          <div class="picker-wheel-cylinder-wrapper" id="servings-wheel-wrapper">
509            <div class="picker-wheel-lens"></div>
510            <div class="picker-wheel-cylinder" id="servings-wheel-cylinder">
511              <!-- Drum slats rendered dynamically with 3D rotation (1 to 16) -->
512            </div>
513          </div>
514        </div>
515      </div>
516
517      <!-- Interactive 3D Dietary Preference Picker Wheel -->
518      <div class="diet-picker-wheel" id="diet-picker-wheel" aria-label="Dietary Preference Picker Wheel">
519        <div class="picker-wheel-card">
520          <div class="picker-wheel-header">
521            <button type="button" class="picker-wheel-close transition-all duration-150 active:scale-90" id="diet-wheel-close" title="Done (Esc)">✓ Done</button>
522          </div>
523          
524          <div class="picker-wheel-cylinder-wrapper" id="diet-wheel-wrapper">
525            <div class="picker-wheel-lens"></div>
526            <div class="picker-wheel-cylinder" id="diet-wheel-cylinder">
527              <!-- Drum slats rendered dynamically with 3D rotation -->
528            </div>
529          </div>
530        </div>
531      </div>
532
533      <!-- Interactive 3D Recipe Type / Category Picker Wheel -->
534      <div class="type-picker-wheel" id="type-picker-wheel" aria-label="Recipe Type Picker Wheel">
535        <div class="picker-wheel-card">
536          <div class="picker-wheel-header">
537            <button type="button" class="picker-wheel-close transition-all duration-150 active:scale-90" id="type-wheel-close" title="Done (Esc)">✓ Done</button>
538          </div>
539          
540          <div class="picker-wheel-cylinder-wrapper" id="type-wheel-wrapper">
541            <div class="picker-wheel-lens"></div>
542            <div class="picker-wheel-cylinder" id="type-wheel-cylinder">
543              <!-- Drum slats rendered dynamically with 3D rotation -->
544            </div>
545          </div>
546        </div>
547      </div>
548
549      <!-- Interactive 3D Time Budget Picker Wheel -->
550      <div class="time-picker-wheel" id="time-picker-wheel" aria-label="Time Budget Picker Wheel">
551        <div class="picker-wheel-card">
552          <div class="picker-wheel-header">
553            <button type="button" class="picker-wheel-close transition-all duration-150 active:scale-90" id="time-wheel-close" title="Done (Esc)">✓ Done</button>
554          </div>
555          
556          <div class="picker-wheel-cylinder-wrapper" id="time-wheel-wrapper">
557            <div class="picker-wheel-lens"></div>
558            <div class="picker-wheel-cylinder" id="time-wheel-cylinder">
559              <!-- Drum slats rendered dynamically with 3D rotation -->
560            </div>
561          </div>
562        </div>
563      </div>
564      <div class="clock-quote" id="clock-quote"></div>
565
566      <!-- Chef Popiah: Recipe & Timed Cooking Assistant -->
567      <div class="recipe-copilot" id="recipe-copilot">
568        <div class="recipe-input-wrapper">
569          <div class="recipe-input-top-row relative w-full min-w-0">
570            <div class="recipe-input-prefix shrink-0" title="Chef Popiah AI Copilot">
571              <svg class="recipe-prefix-icon" width="16" height="16" viewB
571ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
572                <circle cx="11" cy="11" r="8"></circle>
573                <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
574              </svg>
575            </div>
576            <textarea id="recipe-input" class="recipe-input flex-1 min-w-0 w-0 placeholder:text-slate-500 text-slate-100" rows="1" 
577              placeholder="What taste are you craving? (e.g. sizzling spicy, savory umami)..." 
578              maxlength="500" autocomplete="off" spellcheck="false"></textarea>
579            <button id="recipe-clear-input" class="recipe-clear-input shrink-0 relative z-10 transition-all duration-150 hover:scale-110 active:scale-95" type="button" title="Clear input" style="display: none;">
580              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
581                <line x1="18" y1="6" x2="6" y2="18"></line>
582                <line x1="6" y1="6" x2="18" y2="18"></line>
583              </svg>
584            </button>
585            <button id="recipe-cook-btn" class="recipe-cook-btn shrink-0 relative z-10 whitespace-nowrap transition-all duration-200 active:scale-[0.96]" title="Cook up re
585cipe with timers (Enter)">
586              <svg class="cook-icon shrink-0" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
587                <path d="M12 2a5 5 0 0 0-5 5c0 1.93 1.1 3.6 2.7 4.4L9 21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1l-.7-9.6A5 5 0 0 0 17 7a5 5 0 0 0-5-5Z"/>
588                <path d="M8 7h8"/>
589              </svg>
590              <span class="cook-label whitespace-nowrap">Cook</span>
591              <kbd class="cook-kbd-hint shrink-0">↵</kbd>
592            </button>
593          </div>
594
595          <!-- Integrated Bottom Toolbar: Pax & Diet on left, Surprise on right -->
596          <div class="recipe-input-bottom-bar">
597            <div class="recipe-toolbar-capsule transition-all duration-200 hover:border-white/20" id="recipe-toolbar-capsule">
598              <!-- Pax Quick Trigger -->
599              <button id="recipe-servings-btn" class="recipe-servings-btn transition-all duration-150 active:scale-95" type="button" 
600                title="Portions: 2 pax • Click to roll 3D wheel or scroll mouse" 
601                aria-label="Serving size: 2 pax" aria-expanded="false" aria-haspopup="dialog">
602                <span class="toolbar-label">Pax</span>
603                <span class="servings-num" id="recipe-servings-num">2</span>
604                <svg class="servings-chevron" width="7" height="7" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round">
605                  <polyline points="6 9 12 15 18 9"></polyline>
606                </svg>
607              </button>
608
609              <span class="toolbar-divider" aria-hidden="true"></span>
610
611              <!-- Dietary Preference Quick Trigger -->
612              <button id="recipe-diet-btn" class="recipe-diet-btn transition-all duration-150 active:scale-95" type="button" 
613                title="Dietary preference: click to roll 3D wheel or scroll mouse" 
614                aria-label="Dietary preference: Any Diet" aria-expanded="false" aria-haspopup="dialog">
615                <span class="toolbar-label">Diet</span>
616                <span class="diet-icon" id="recipe-diet-icon" style="display: none;" aria-hidden="true">🍽️</span>
617                <span class="diet-label" id="recipe-diet-label">Any</span>
618                <svg class="diet-chevron" width="7" height="7" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round">
619                  <polyline points="6 9 12 15 18 9"></polyline>
620                </svg>
621              </button>
622
623              <span class="toolbar-divider" aria-hidden="true"></span>
624
625              <!-- Category / Type Quick Trigger -->
626              <button id="recipe-type-btn" class="recipe-type-btn transition-all duration-150 active:scale-95" type="button" 
627                title="Recipe type: click to roll 3D wheel or scroll mouse" 
628                aria-label="Recipe type: All" aria-expanded="false" aria-haspopup="dialog">
629                <span class="toolbar-label">Type</span>
630                <span class="type-label" id="recipe-type-label">All</span>
631                <svg class="type-chevron" width="7" height="7" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round">
632                  <polyline points="6 9 12 15 18 9"></polyline>
633                </svg>
634              </button>
635
636              <span class="toolbar-divider" aria-hidden="true"></span>
637
638              <!-- Time Limit Quick Trigger -->
639              <button id="recipe-time-btn" class="recipe-time-btn transition-all duration-150 active:scale-95" type="button" 
640                title="Time budget: click to roll 3D wheel or scroll mouse" 
641                aria-label="Time budget: Any" aria-expanded="false" aria-haspopup="dialog">
642                <span class="toolbar-label">Time</span>
643                <span class="time-label" id="recipe-time-label">Any</span>
644                <svg class="time-chevron" width="7" height="7" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round">
645                  <polyline points="6 9 12 15 18 9"></polyline>
646                </svg>
647              </button>
648            </div>
649
650            <div class="recipe-input-actions">
651              <!-- Persistent Dietary Guardrails Micro-Indicator -->
652              <div class="recipe-guardrails-wrapper" id="recipe-guardrails-wrapper" style="display: none;">
653                <button id="recipe-guardrails-btn" class="recipe-guardrails-btn transition-all duration-150 active:scale-95" type="button" 
654                  title="Dietary Guardrails Active • Tap to view" 
655                  aria-label="Active dietary guardrails" aria-haspopup="dialog" aria-expanded="false">
656                  <span class="guardrails-shield-icon" aria-hidden="true">🛡️</span>
657                  <span class="guardrails-icons-stack" id="recipe-guardrails-icons"></span>
658                </button>
659              </div>
660
661              <button id="recipe-surprise-btn" class="recipe-surprise-btn transition-all duration-150 active:scale-95" type="button" title="Surprise me with a mouth-watering flavor craving!" aria-label="Surprise craving">
662                <span class="surprise-icon">🎲</span>
663              </button>
664              <button id="recipe-mode-toggle" class="recipe-mode-toggle is-fallback transition-all duration-150 active:scale-95" type="button" style="display: none;" title="AI unavailable — operating on local fallback. Click to restore AI.">
665                <span class="mode-icon">⚡</span>
666                <span class="mode-label">Fallback</span>
667              </button>
668            </div>
669          </div>
670
671          <!-- Floating Glass Tooltip for Active Dietary Guardrails -->
672          <div class="recipe-guardrails-tooltip" id="recipe-guardrails-tooltip" role="tooltip" aria-hidden="true">
673            <div class="guardrails-tooltip-header">
674              <div class="guardrails-tooltip-title-wrap">
675                <span class="guardrails-tooltip-shield" aria-hidden="true">🛡️</span>
676                <span class="guardrails-tooltip-title">Active Guardrails</span>
677              </div>
678              <button type="button" class="guardrails-tooltip-close" id="guardrails-tooltip-close" aria-label="Close active guardrails tooltip">✕</button>
679            </div>
680            <ul class="guardrails-tooltip-list" id="recipe-guardrails-list"></ul>
681            <div class="guardrails-tooltip-footer">
682              <button type="button" class="guardrails-configure-btn" id="guardrails-configure-btn">
683                <span>Configure in Settings</span>
684                <span class="configure-arrow" aria-hidden="true">→</span>
685              </button>
686            </div>
687          </div>
688        </div>
689
690        <!-- Sensory Craving Quick-Chips (Dynamic AI Appetite Stimulators) -->
691        <div class="recipe-prompt-suggestions" id="recipe-prompt-suggestions" aria-label="Culinary Craving Inspirations">
692          <div class="suggestions-header" id="suggestions-header">
693            <div class="suggestions-header-left">
694              <span class="suggestions-title-tag" id="suggestions-title-tag">
695                <span class="suggestions-sparkle">✨</span> Fresh Cravings
696              </span>
697            </div>
698
699            <div class="suggestions-header-right">
700              <button type="button" class="suggestions-roll-btn transition-all duration-150 active:scale-90" id="suggestions-roll-btn" title="Roll new AI craving recommendations">
701                <svg class="roll-icon" width="11" height="11" viewB
701ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
702                  <path d="M21.5 2v6h-6M21.34 15.57a10 10 0 1 1-.57-8.38l5.67-5.67"/>
703                </svg>
704                <span>Roll</span>
705              </button>
706            </div>
707          </div>
708          <div class="suggestions-chips-track" id="suggestions-chips-track">
709            <button type="button" class="prompt-chip" data-prompt="Sizzling garlic butter stir-fry noodles with crispy shallots">
710              <span class="chip-flame">🔥</span> <span class="chip-title">Sizzling Garlic Butter</span>
711            </button>
712            <button type="button" class="prompt-chip" data-prompt="Rich umami miso ramen broth with charred scallions and soft egg">
713              <span class="chip-flame">🍜</span> <span class="chip-title">Rich Umami Miso</span>
714            </button>
715            <button type="button" class="prompt-chip" data-prompt="Crispy pan-seared lemon herb salmon with honey Dijon glaze">
716              <span class="chip-flame">🍋</span> <span class="chip-title">Charred Herb Salmon</span>
717            </button>
718          </div>
719        </div>
720
721        <!-- Tailwind Skeleton Shimmer Loader for Zero-CLS AI Generation -->
722        <div class="recipe-skeleton-loader animate-pulse flex-col gap-3 p-4 rounded-2xl bg-white/[0.04] border border-white/10 w-full" id="recipe-skeleton-loader" style="display: none;">
723          <div class="flex items-center justify-between">
724            <div class="h-6 bg-white/15 rounded-lg w-2/3"></div>
725            <div class="h-5 bg-white/10 rounded-full w-16"></div>
726          </div>
727          <div class="flex gap-2">
728            <div class="h-5 bg-white/10 rounded-full w-20"></div>
729            <div class="h-5 bg-white/10 rounded-full w-16"></div>
730            <div class="h-5 bg-white/10 rounded-full w-24"></div>
731          </div>
732          <div class="h-24 bg-white/[0.04] rounded-xl w-full"></div>
733          <div class="space-y-2 mt-2">
734            <div class="h-4 bg-white/10 rounded w-full"></div>
735            <div class="h-4 bg-white/10 rounded w-4/5"></div>
736            <div class="h-4 bg-white/10 rounded w-3/5"></div>
737          </div>
738        </div>
739
740        <!-- Recipe Card Container -->
741        <div class="recipe-card-container" id="recipe-card-container" style="display: none;">
742          <div class="recipe-header">
743            <div class="recipe-title-group">
744              <h3 class="recipe-title" id="recipe-title">Dish Title</h3>
745              <div class="recipe-badges">
746                <span class="recipe-badge source" id="recipe-source" style="display: none;">✨ AI</span>
747                <span class="recipe-badge time" id="recipe-time">⏱️ 15 min</span>
748                <span class="recipe-badge highlight" id="recipe-taste-badge" style="display: none;"></span>
749                <span class="recipe-badge diet" id="recipe-diet" style="display: none;">
750                  <span id="recipe-diet-badge-text">🕌 Halal</span>
751                </span>
752                <button type="button" class="recipe-badge servings interactive" id="recipe-servings" title="Click or scroll to adjust servings (scale ingredients)">
753                  <span id="recipe-servings-badge-text">2 pax</span>
754                  <span class="badge-chevron">▾</span>
755                </button>
756              </div>
757            </div>
758            <button class="recipe-clear-btn transition-all duration-150 active:scale-90" id="recipe-clear-btn" title="Clear recipe">×</button>
759          </div>
760
761          <!-- Dynamic Servings Scale Banner -->
762          <div class="recipe-servings-scale-banner" id="recipe-servings-scale-banner" style="display: none;">
763            <div class="scale-banner-info">
764              <span class="scale-banner-icon">⚖️</span>
765              <span class="scale-banner-text" id="recipe-scale-banner-text">Ingredients mathematically scaled for 4 pax</span>
766            </div>
767            <button type="button" class="scale-banner-recook-btn transition-all duration-150 active:scale-95" id="recipe-scale-recook-btn" title="Reset ingredients mathematically to original portions">↩️ Reset portions</button>
768          </div>
769
770          <!-- User's Full Prompt Callout (never hidden or truncated) -->
771          <div class="recipe-prompt-callout" id="recipe-prompt-callout" style="display: none;" title="Click to edit or reprompt this recipe">
772            <div class="prompt-callout-header">
773              <div class="prompt-callout-header-left">
774                <span class="prompt-callout-icon">💬</span>
775                <span class="prompt-callout-label">Prompt</span>
776              </div>
777              <div class="prompt-callout-badges">
778                <span class="prompt-callout-diet-badge" id="prompt-callout-diet-badge" style="display: none;">🕌 Halal</span>
779                <span class="prompt-callout-servings-badge" id="prompt-callout-servings-badge">2 pax</span>
780              </div>
781            </div>
782            <p class="prompt-callout-text" id="recipe-prompt-callout-text"></p>
783          </div>
784
785          <!-- Responsive 2-Column Culinary Grid for Screen Estate Maximization -->
786          <div class="recipe-grid-layout" id="recipe-grid-layout">
787            <div class="recipe-grid-col-side" id="recipe-grid-col-side">
788              <!-- Mouth-Watering Dish Presentation Showcase -->
789              <div class="recipe-hero-card" id="recipe-hero-card" style="display: none;">
790                <div class="recipe-hero-media" id="recipe-hero-media">
791                  <img class="recipe-hero-img" id="recipe-hero-img" alt="Finished dish presentation" loading="eager" decoding="async" />
792                  <div class="recipe-hero-placeholder" id="recipe-hero-placeholder">
793                    <div class="recipe-hero-shimmer"></div>
794                    <div class="recipe-hero-loader-body">
795                      <span class="recipe-hero-spinner-icon">🐾</span>
796                      <span class="recipe-hero-loader-text">Chef Popiah is plating your dish...</span>
797                      <span class="recipe-hero-loader-sub">Generating mouth-watering culinary visual</span>
798                    </div>
799                  </div>
800                  <div class="recipe-hero-badge-pill" id="recipe-hero-badge-pill">
801                    <span class="badge-dot"></span>
802                    <span id="recipe-hero-badge-text">✨ Freshly Plated</span>
803                  </div>
804                  <div class="recipe-hero-controls">
805                    <button type="button" class="recipe-hero-action-btn transition-all duration-150 active:scale-95" id="recipe-hero-zoom-btn" title="Inspect full dish photograph in lightbox">
806                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
807                        <circle cx="11" cy="11" r="8"></circle>
808                        <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
809                        <line x1="11" y1="8" x2="11" y2="14"></line>
810                        <line x1="8" y1="11" x2="14" y2="11"></line>
811                      </svg>
812                      <span>Zoom</span>
813                    </button>
814                    <button type="button" class="recipe-hero-action-btn transition-all duration-150 active:scale-95" id="recipe-hero-regen-btn" title="Generate another culinary photography shot">
815                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
816                        <path d="M23 4v6h-6"></path>
817                        <path d="M1 20v-6h6"></path>
818                        <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
819                      </svg>
820                      <span>Re-plate</span>
821                    </button>
822                  </div>
823                  <div class="recipe-hero-attribution" id="recipe-hero-attribution" style="display: none;">
824                    <span class="recipe-hero-attr-text" id="recipe-hero-attr-text"></span>
825                  </div>
826                </div>
827              </div>
828
829              <p class="recipe-summary" id="recipe-summary"></p>
830
831              <!-- Mise en Place: Interactive Ingredients Prep & Smart Pantry Assistant -->
832              <div class="recipe-ingredients-section" id="recipe-ingredients-section">
833                <div class="recipe-ingredients-header">
834                  <div class="recipe-ingredients-header-left">
835                    <button type="button" class="recipe-ingredients-collapse-btn p-1 rounded-md hover:bg-white/10 text-neutral-400 hover:text-white transition-all mr-1 cursor-pointer" id="recipe-ingredients-collapse-btn" aria-label="Toggle ingredients collapse" title="Collapse / Expand ingredients" aria-expanded="true">
836                      <svg class="w-3.5 h-3.5 transition-transform duration-200" id="recipe-ing-collapse-icon" viewB
836ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
837                        <polyline points="6 9 12 15 18 9"></polyline>
838                      </svg>
839                    </button>
840                    <span class="recipe-section-label flex items-center gap-1.5"><span class="text-amber-500">🔪</span> Mise en Place</span>
841                    <span class="recipe-ingredients-count-badge" id="recipe-ingredients-count-badge" title="Mise en place prep status">0/0 prepped</span>
842                  </div>
843                  <div class="recipe-ingredients-header-actions">
844                    <button type="button" class="recipe-ing-toggle-btn" id="recipe-ing-toggle-all" title="Toggle check/uncheck all ingredients">
845                      Check all
846                    </button>
847                  </div>
848                </div>
849
850                <!-- Vertical interactive checklist -->
851                <div class="recipe-ingredients-list" id="recipe-ingredients-list" role="list" aria-label="Ingredients checklist">
852                  <!-- Rendered dynamically as checklist rows -->
853                </div>
854
855                <!-- Kept for backward compatibility if queried -->
856                <div class="recipe-ingredients-pills" id="recipe-ingredients-pills" style="display: none;"></div>
857
858                <!-- Dynamic Missing Ingredients Banner (adapts recipe or replaces missing items) -->
859                <div class="recipe-missing-banner" id="recipe-missing-banner" style="display: none;">
860                  <div class="missing-banner-content">
861                    <div class="missing-banner-header">
862                      <span class="missing-banner-icon" id="recipe-missing-banner-icon">💡</span>
863                      <div class="missing-banner-text-group">
864                        <span class="missing-banner-title" id="recipe-missing-banner-title">Missing Ingredients</span>
865                        <span class="missing-banner-desc" id="recipe-missing-banner-desc">Missing 1 item</span>
866                      </div>
867                    </div>
868                    <div class="missing-banner-actions">
869                      <button type="button" class="missing-banner-btn missing-sub-btn" id="recipe-missing-sub-btn" title="Ask Chef Popiah to swap missing items with pantry alternatives">
870                        🔄 Replace with alternatives
871                      </button>
872                      <button type="button" class="missing-banner-btn missing-pivot-btn" id="recipe-missing-pivot-btn" style="display: none;" title="Invent a new dish using your available pantry ingredients">
873                        🪄 Pivot to alternative dish
874                      </button>
875                      <button type="button" class="missing-banner-btn missing-omit-btn" id="recipe-missing-omit-btn" title="Ask Chef Popiah to adapt recipe to cook without missing ingredients">
876                        ✨ Cook without missing
877                      </button>
878                    </div>
879                  </div>
880                </div>
881              </div>
882            </div>
883
884            <div class="recipe-grid-col-main" id="recipe-grid-col-main">
885              <!-- Step-by-Step Timed Cooking Instructions -->
886              <div class="recipe-steps-section">
887                <div class="recipe-steps-header">
888                  <span class="recipe-section-label">Cooking Steps</span>
889                  <span class="recipe-progress-text" id="recipe-progress-text">0/4 done</span>
890                </div>
891                <ul class="recipe-steps-list" id="recipe-steps-list"></ul>
892              </div>
893
894              <div class="recipe-chef-tip" id="recipe-chef-tip"></div>
895            </div>
896          </div>
897        </div>
898
899        <!-- Compact Recipe HUD for Picture-in-Picture mode -->
900        <div class="recipe-pip-hud" id="recipe-pip-hud" style="display: none;">
901          <div class="recipe-pip-header">
902            <span class="recipe-pip-dish" id="recipe-pip-dish">Dish Name</span>
903            <span class="recipe-pip-badge" id="recipe-pip-badge">Step 1/4</span>
904          </div>
905          <div class="recipe-pip-step-row">
906            <input type="checkbox" id="recipe-pip-cb" class="recipe-pip-cb">
907            <span class="recipe-pip-instruction" id="recipe-pip-instruction">Cooking step</span>
908            <button class="recipe-pip-timer-btn" id="recipe-pip-timer-btn" title="Start this step timer">⏱️ 3m</button>
909          </div>
910        </div>
911      </div>
912    </div>
913  </div>
914
915  <!-- Dish Showcase Lightbox Modal -->
916  <div class="dish-lightbox-modal" id="dish-lightbox-modal" style="display: none;" role="dialog" aria-modal="true" aria-hidden="true" aria-label="Dish photograph full view">
917    <div class="dish-lightbox-backdrop" id="dish-lightbox-backdrop"></div>
918    <div class="dish-lightbox-content">
919      <button type="button" class="dish-lightbox-close transition-all duration-200 active:scale-90" id="dish-lightbox-close" title="Close photo view (Esc)">×</button>
920      <div class="dish-lightbox-image-wrap">
921        <img class="dish-lightbox-img" id="dish-lightbox-img" alt="Finished dish full presentation" />
922      </div>
923      <div class="dish-lightbox-footer">
924        <div class="dish-lightbox-info">
925          <h4 class="dish-lightbox-title" id="dish-lightbox-title">Dish Title</h4>
926          <span class="dish-lightbox-subtitle" id="dish-lightbox-subtitle">Award-winning culinary presentation</span>
927          <div class="dish-lightbox-attribution" id="dish-lightbox-attribution" style="display: none;">
928            <span class="dish-lightbox-attr-text" id="dish-lightbox-attr-text"></span>
929          </div>
930        </div>
931        <div class="dish-lightbox-actions">
932          <a class="dish-lightbox-download-btn transition-all duration-200 hover:scale-[1.03] active:scale-95" id="dish-lightbox-download-btn" download="chef-popiah-dish.png" target="_blank" rel="noopener">
933            ⬇ Save Photo
934          </a>
935        </div>
936      </div>
937    </div>
938  </div>
939
940  <!-- Floating Glass Toast Notification Pill -->
941  <div id="toast-container" class="fixed bottom-6 left-1/2 -translate-x-1/2 z-50 pointer-events-none flex flex-col items-center gap-2 max-w-[92vw]" aria-live="polite"></div>
942
943  
943<script src="app.js?v=2.1.0"></script>
vendor: 1 bytes, line 943
943
944<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"4c9eed491d2f41e0a473912ad5b6ada6","r":1,"spa":2}' crossorigin="anonymous"></script>
944
945</body>
946
947</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.