anaygupta commited on
Commit
b1973fa
·
verified ·
1 Parent(s): af43eb2

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +427 -397
index.html CHANGED
@@ -9,23 +9,31 @@
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Playfair+Display:wght@600;700&display=swap" rel="stylesheet">
10
  <style>
11
  :root{
12
- --bg:#f7f8fb;
13
- --bg2:#eef7f3;
14
  --card:#ffffff;
15
- --text:#122033;
16
- --muted:#667085;
17
- --muted2:#8a94a6;
18
- --line:#e7ebf2;
19
- --shadow: 0 20px 45px rgba(18,32,51,.08);
20
- --shadow-soft: 0 10px 24px rgba(18,32,51,.06);
 
 
 
21
  --green:#3fb487;
22
- --green-dark:#20936a;
 
23
  --mint:#e8f8f1;
 
24
  --amber:#fff4de;
25
  --amber-text:#a86c0b;
26
  --blue:#eef3ff;
27
  --blue-text:#4057c7;
28
- --radius: 24px;
 
 
 
 
29
  }
30
 
31
  * { box-sizing: border-box; }
@@ -34,420 +42,449 @@
34
  font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
35
  color: var(--text);
36
  background:
37
- radial-gradient(circle at top left, rgba(63,180,135,.12), transparent 30%),
38
- radial-gradient(circle at top right, rgba(64,87,199,.10), transparent 26%),
39
- linear-gradient(180deg, #fbfcfe 0%, var(--bg) 100%);
40
  min-height: 100vh;
 
41
  }
42
 
43
  .shell{
44
- max-width: 1220px;
45
  margin: 0 auto;
46
- padding: 24px;
47
  }
48
 
 
49
  .topbar{
50
  display:flex;
51
  justify-content:space-between;
52
  align-items:center;
53
  gap:16px;
54
- margin-bottom: 26px;
55
  }
56
-
57
  .brand{
58
  display:flex;
59
  align-items:center;
60
  gap:14px;
61
  }
62
  .brand-mark{
63
- width: 46px;
64
- height: 46px;
65
- border-radius: 16px;
66
- background:
67
- linear-gradient(135deg, rgba(63,180,135,.18), rgba(64,87,199,.12)),
68
- #fff;
69
- border: 1px solid rgba(63,180,135,.18);
70
  display:grid;
71
  place-items:center;
72
- box-shadow: var(--shadow-soft);
73
- font-size: 22px;
74
- }
75
- .brand-name{
76
- line-height:1;
77
  }
78
  .brand-name h1{
79
  margin:0;
80
  font-family: "Playfair Display", serif;
81
- font-size: 28px;
82
  letter-spacing: -0.03em;
83
  font-weight: 700;
 
84
  }
85
  .brand-name span{
86
  display:block;
87
- margin-top: 4px;
88
  color: var(--muted);
89
  font-size: 13px;
90
  }
91
-
92
  .top-pill{
93
  display:inline-flex;
94
  align-items:center;
95
  gap:8px;
96
- padding: 11px 14px;
97
  border-radius: 999px;
98
  border: 1px solid var(--line);
99
- background: rgba(255,255,255,.85);
100
  color: var(--muted);
101
- font-size: 13px;
102
- box-shadow: 0 8px 20px rgba(18,32,51,.04);
 
 
 
 
 
 
 
103
  }
104
 
 
105
  .hero{
106
  display:grid;
107
- grid-template-columns: 1.15fr .85fr;
108
- gap: 22px;
109
- align-items: stretch;
110
- margin-bottom: 22px;
111
- }
112
-
113
- .hero-card, .panel, .section-card{
114
- background: rgba(255,255,255,.92);
115
- border: 1px solid rgba(231,235,242,.9);
116
- border-radius: var(--radius);
117
- box-shadow: var(--shadow);
118
- backdrop-filter: blur(14px);
119
- }
120
-
121
- .hero-card{
122
- padding: 34px;
123
  }
124
-
125
  .eyebrow{
126
  display:inline-flex;
127
  align-items:center;
128
  gap:8px;
129
- font-size: 12px;
130
  font-weight: 700;
131
- letter-spacing: .08em;
132
  text-transform: uppercase;
133
- color: var(--green-dark);
134
  background: var(--mint);
135
- border: 1px solid rgba(63,180,135,.16);
136
- padding: 8px 12px;
137
  border-radius: 999px;
138
- margin-bottom: 18px;
139
  }
140
-
141
- .hero-card h2{
142
  margin: 0;
143
- font-size: clamp(34px, 4.4vw, 58px);
144
  line-height: 1.02;
145
- letter-spacing: -0.05em;
 
146
  }
147
- .hero-card h2 em{
148
  font-family: "Playfair Display", serif;
149
- font-style: normal;
150
- color: var(--green-dark);
 
151
  }
152
- .hero-card p{
153
- margin: 16px 0 0;
154
- max-width: 62ch;
155
  font-size: 16px;
156
- line-height: 1.7;
157
  color: var(--muted);
158
  }
159
 
160
- .hero-grid{
161
- display:grid;
162
- grid-template-columns: repeat(3, minmax(0, 1fr));
163
- gap: 12px;
164
- margin-top: 22px;
165
- }
166
- .mini-card{
167
- border-radius: 18px;
168
- background: linear-gradient(180deg, #fff 0%, #fbfcff 100%);
169
  border: 1px solid var(--line);
170
- padding: 16px;
171
- min-height: 112px;
172
- }
173
- .mini-card .k{
174
- display:inline-flex;
175
- padding: 7px 10px;
176
- border-radius: 999px;
177
- font-size: 12px;
178
- font-weight: 700;
179
- margin-bottom: 10px;
180
- }
181
- .k-green{ background: var(--mint); color: var(--green-dark); }
182
- .k-blue{ background: var(--blue); color: var(--blue-text); }
183
- .k-amber{ background: var(--amber); color: var(--amber-text); }
184
- .mini-card strong{
185
- display:block;
186
- font-size: 14px;
187
- margin-bottom: 5px;
188
- }
189
- .mini-card span{
190
- color: var(--muted);
191
- font-size: 13px;
192
- line-height: 1.5;
193
- }
194
-
195
- .side-card{
196
- padding: 22px;
197
- display:flex;
198
- flex-direction:column;
199
- gap: 16px;
200
- }
201
-
202
- .side-block{
203
- border: 1px solid var(--line);
204
- background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
205
- border-radius: 20px;
206
- padding: 16px;
207
- }
208
-
209
- .side-title{
210
- margin:0 0 8px;
211
- font-size: 14px;
212
- font-weight: 700;
213
- color: #26344a;
214
- }
215
- .side-text{
216
- margin:0;
217
- color: var(--muted);
218
- font-size: 13px;
219
- line-height: 1.6;
220
- }
221
-
222
- .quick-tries{
223
- display:flex;
224
- flex-wrap:wrap;
225
- gap:10px;
226
- margin-top: 14px;
227
  }
228
 
229
- .chip{
230
- appearance:none;
231
- border: 1px solid var(--line);
232
- background: #fff;
233
- color: #344055;
234
- border-radius: 999px;
235
- padding: 10px 14px;
236
- font-size: 13px;
237
- font-weight: 600;
238
- cursor:pointer;
239
- transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
240
- box-shadow: 0 6px 16px rgba(18,32,51,.04);
241
- }
242
- .chip:hover{
243
- transform: translateY(-1px);
244
- border-color: rgba(63,180,135,.35);
245
- box-shadow: 0 10px 20px rgba(18,32,51,.08);
246
- }
247
-
248
- .main{
249
- display:grid;
250
- grid-template-columns: 1fr;
251
- gap: 22px;
252
- }
253
-
254
- .section-card{
255
- padding: 22px;
256
  }
257
-
258
- .section-head{
259
  display:flex;
260
  justify-content:space-between;
261
- align-items:flex-end;
262
- gap: 14px;
263
- margin-bottom: 16px;
 
264
  }
265
-
266
- .section-head h3{
267
  margin:0;
268
- font-size: 18px;
269
- letter-spacing: -0.03em;
 
270
  }
271
- .section-head p{
272
- margin:6px 0 0;
273
  color: var(--muted);
274
- font-size: 14px;
275
- line-height: 1.5;
276
  }
277
 
278
  .segmented{
279
  display:inline-flex;
280
- gap: 8px;
281
- padding: 6px;
282
  border-radius: 999px;
283
- background: #f3f5f9;
284
  border: 1px solid var(--line);
285
  }
286
-
287
  .diet-btn{
288
  border: 0;
289
  background: transparent;
290
  color: var(--muted);
291
- padding: 10px 16px;
292
  border-radius: 999px;
293
  font-size: 13px;
294
- font-weight: 700;
295
  cursor: pointer;
296
- transition: all .15s ease;
297
  }
298
- .diet-btn.active-vegan{ background: var(--mint); color: var(--green-dark); box-shadow: inset 0 0 0 1px rgba(63,180,135,.16); }
299
- .diet-btn.active-keto{ background: var(--amber); color: var(--amber-text); box-shadow: inset 0 0 0 1px rgba(166,108,11,.12); }
300
- .diet-btn.active-both{ background: var(--blue); color: var(--blue-text); box-shadow: inset 0 0 0 1px rgba(64,87,199,.12); }
 
301
 
302
- .editor{
303
- display:grid;
304
- grid-template-columns: 1.1fr .9fr;
305
- gap: 18px;
306
- align-items:start;
307
  }
308
-
309
  textarea{
310
  width: 100%;
311
- min-height: 220px;
312
  resize: vertical;
313
- border-radius: 20px;
314
  border: 1px solid var(--line);
315
- background: linear-gradient(180deg, #fff 0%, #fbfcff 100%);
316
  color: var(--text);
317
- padding: 18px 18px 16px;
318
  font: inherit;
319
  font-size: 15px;
320
- line-height: 1.7;
321
  outline:none;
322
- box-shadow: 0 8px 20px rgba(18,32,51,.03);
323
  }
324
  textarea:focus{
325
- border-color: rgba(63,180,135,.35);
326
  box-shadow: 0 0 0 4px rgba(63,180,135,.10);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  }
328
- textarea::placeholder{
329
- color:#97a3b5;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  }
 
331
 
332
  .input-actions{
333
- margin-top: 14px;
334
  display:flex;
335
  flex-wrap:wrap;
336
  gap: 10px;
337
  align-items:center;
338
  justify-content:space-between;
339
  }
340
-
341
  .helper{
342
  display:flex;
343
  flex-wrap:wrap;
344
- gap:8px;
345
  color: var(--muted);
346
- font-size: 13px;
 
 
 
 
 
 
347
  }
 
 
 
 
 
 
 
 
 
 
 
348
 
349
  .action-row{
350
  display:flex;
351
  gap: 10px;
352
  align-items:center;
353
  }
354
-
355
  .primary{
356
  border: none;
357
- border-radius: 16px;
358
- padding: 14px 20px;
359
- font-weight: 800;
360
  font-size: 14px;
361
  cursor:pointer;
362
  color:#fff;
363
- background: linear-gradient(135deg, var(--green) 0%, #2ea274 100%);
364
- box-shadow: 0 12px 26px rgba(63,180,135,.25);
365
- transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
 
 
 
366
  }
367
  .primary:hover{
368
  transform: translateY(-1px);
369
- box-shadow: 0 16px 32px rgba(63,180,135,.28);
370
- filter: brightness(1.01);
371
  }
 
 
372
 
373
  .ghost{
374
  border: 1px solid var(--line);
375
  background:#fff;
376
- color:#334155;
377
- border-radius: 16px;
378
- padding: 14px 18px;
379
- font-weight: 700;
380
  font-size: 14px;
381
  cursor:pointer;
382
- transition: background .15s ease, transform .15s ease;
383
  }
384
  .ghost:hover{
385
- transform: translateY(-1px);
386
- background:#f8fafc;
387
  }
388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  .error{
390
  display:none;
391
- margin-top: 12px;
392
- border: 1px solid rgba(210,73,91,.18);
393
- background: rgba(252,237,239,.85);
394
- color: #a13a4d;
395
- border-radius: 16px;
396
  padding: 12px 14px;
397
  font-size: 13px;
 
398
  }
399
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  .results-wrap{
401
  display:none;
 
402
  }
403
-
404
  .stats{
405
  display:grid;
406
- grid-template-columns: repeat(3, minmax(0, 1fr));
407
  gap: 12px;
408
- margin-bottom: 16px;
409
  }
410
  .stat{
411
  border: 1px solid var(--line);
412
- background: #fff;
413
- border-radius: 18px;
414
- padding: 16px;
415
  }
416
  .stat .num{
417
- font-size: 26px;
418
  font-weight: 800;
419
  letter-spacing: -0.04em;
 
420
  }
421
  .stat .lbl{
422
  color: var(--muted);
423
- font-size: 12px;
424
  text-transform: uppercase;
425
  letter-spacing: .08em;
426
- margin-top: 4px;
 
427
  }
428
 
429
  .results-head{
430
  display:flex;
431
  justify-content:space-between;
432
- align-items:center;
433
  gap:12px;
434
  margin-bottom: 16px;
 
435
  }
436
  .results-head h3{
437
  margin:0;
438
  font-size: 20px;
439
  letter-spacing: -0.03em;
 
 
 
 
 
 
440
  }
441
  .badge{
442
  display:inline-flex;
443
  align-items:center;
444
  gap:8px;
445
  font-size: 12px;
446
- font-weight: 800;
447
- padding: 9px 12px;
448
  border-radius: 999px;
449
  }
450
- .badge-vegan{ background: var(--mint); color: var(--green-dark); }
451
  .badge-keto{ background: var(--amber); color: var(--amber-text); }
452
  .badge-both{ background: var(--blue); color: var(--blue-text); }
453
 
@@ -457,9 +494,14 @@
457
  }
458
  .item{
459
  overflow:hidden;
460
- border-radius: 18px;
461
  border: 1px solid var(--line);
462
  background: #fff;
 
 
 
 
 
463
  }
464
  .item-top{
465
  display:flex;
@@ -468,6 +510,7 @@
468
  gap:12px;
469
  padding: 14px 16px;
470
  cursor:pointer;
 
471
  }
472
  .item-left{
473
  display:flex;
@@ -476,115 +519,111 @@
476
  min-width: 0;
477
  }
478
  .dot{
479
- width: 10px;
480
- height: 10px;
481
  border-radius:999px;
482
  flex:0 0 auto;
 
 
 
 
 
 
 
 
483
  }
484
  .dot-ok{ background: var(--green); }
 
485
  .dot-swap{ background: #f0a84c; }
 
486
  .dot-warn{ background: #f36f7f; }
 
487
 
488
  .item-name{
489
- font-weight: 700;
490
- font-size: 14px;
491
  white-space:nowrap;
492
  overflow:hidden;
493
  text-overflow:ellipsis;
494
  }
 
 
 
 
 
 
495
  .item-status{
496
- color: var(--muted2);
497
  font-size: 12px;
498
- white-space: nowrap;
499
  }
 
 
 
 
 
 
 
500
 
501
  .item-body{
502
  display:none;
503
  border-top: 1px solid var(--line);
504
- background: linear-gradient(180deg, #fbfcff 0%, #ffffff 100%);
505
- padding: 16px;
506
- }
507
- .item-body.open{
508
- display:block;
509
  }
 
510
 
511
  .label{
512
- font-size: 11px;
513
  text-transform: uppercase;
514
- letter-spacing: .08em;
515
- color: #94a0b5;
516
- margin-bottom: 5px;
517
- font-weight: 800;
518
  }
519
  .value{
520
  font-size: 15px;
521
- font-weight: 700;
522
- color: #203045;
523
  line-height: 1.55;
524
- margin-bottom: 12px;
 
 
 
 
 
525
  }
526
  .meta{
527
- font-size: 12px;
528
- color: var(--muted2);
529
  display:flex;
530
  flex-wrap:wrap;
531
- gap: 10px;
532
  }
533
  .meta span{
534
- background:#f7f9fc;
535
  border: 1px solid var(--line);
536
  border-radius: 999px;
537
- padding: 7px 10px;
538
- }
539
-
540
- .loading{
541
- display:none;
542
- align-items:center;
543
- gap:10px;
544
- font-size: 13px;
545
- color: var(--muted);
546
- }
547
- .spinner{
548
- width: 16px;
549
- height: 16px;
550
- border-radius: 999px;
551
- border: 2px solid rgba(63,180,135,.18);
552
- border-top-color: var(--green);
553
- animation: spin .8s linear infinite;
554
  }
555
- @keyframes spin{ to { transform: rotate(360deg); } }
556
 
557
- @media (max-width: 980px){
558
- .hero, .editor{
559
- grid-template-columns: 1fr;
560
- }
561
- .hero-grid, .stats{
562
- grid-template-columns: 1fr;
563
- }
564
- .topbar{
565
- align-items:flex-start;
566
- flex-direction:column;
567
- }
568
  }
569
 
570
- @media (max-width: 640px){
571
- .shell{ padding: 14px; }
572
- .hero-card, .side-card, .section-card{ padding: 18px; }
573
- .hero-card h2{ font-size: 32px; }
574
- .section-head, .results-head, .input-actions{
575
- flex-direction:column;
576
- align-items:flex-start;
577
- }
578
- .action-row{
579
- width: 100%;
580
- flex-direction:column;
581
- align-items:stretch;
582
- }
583
- .action-row .primary,
584
- .action-row .ghost{
585
- width:100%;
586
  justify-content:center;
587
  }
 
588
  }
589
  </style>
590
  </head>
@@ -598,61 +637,38 @@
598
  <span>Recipe adaptation that feels simple.</span>
599
  </div>
600
  </div>
601
- <div class="top-pill">Same-page workflow • Fast recipe swaps • Built for vegan and keto</div>
602
  </div>
603
 
604
  <section class="hero">
605
- <div class="hero-card">
606
- <div class="eyebrow">Diet-friendly cooking, without the guesswork</div>
607
- <h2>Turn any recipe into a <em>clear</em>, useful adaptation.</h2>
608
- <p>
609
- Paste a recipe, choose a diet, and get ingredient-by-ingredient substitutions with short instructions.
610
- </p>
611
-
612
- <div class="hero-grid">
613
- <div class="mini-card">
614
- <div class="k k-green">Swaps</div>
615
- <strong>Ingredient-level results</strong>
616
- <span>Each item gets its own card with the substitute and usage note.</span>
617
- </div>
618
- <div class="mini-card">
619
- <div class="k k-blue">Context</div>
620
- <strong>Recipe type</strong>
621
- <span>Results can adapt to baking or cooking based on the recipe text.</span>
622
- </div>
623
- <div class="mini-card">
624
- <div class="k k-amber">Review</div>
625
- <strong>Clear output</strong>
626
- <span>Open each card to see the substitute, instruction, and source.</span>
627
- </div>
628
- </div>
629
- </div>
630
-
631
- <aside class="hero-card side-card">
632
- <div class="side-block">
633
- <h3 class="side-title">Try a recipe</h3>
634
- <p class="side-text">Pick a sample to test the adapter.</p>
635
- <div class="quick-tries">
636
- <button class="chip" onclick="fillExample('fettuccine alfredo')">Fettucine Alfredo</button>
637
- <button class="chip" onclick="fillExample('pancakes')">Pancakes</button>
638
- <button class="chip" onclick="fillExample('butter chicken')">Butter Chicken</button>
639
- </div>
640
- </div>
641
 
642
- <div class="side-block">
643
- <h3 class="side-title">How it works</h3>
644
- <p class="side-text">
645
- Paste a recipe, choose a diet, and review the ingredient cards.
646
- </p>
647
- </div>
648
- </aside>
 
 
 
 
 
 
 
 
 
649
  </section>
650
 
651
- <section class="section-card">
652
- <div class="section-head">
653
  <div>
654
  <h3>Adapt a recipe</h3>
655
- <p>Paste a recipe, choose a diet, and review the ingredient cards.</p>
656
  </div>
657
  <div class="segmented" role="tablist" aria-label="Diet mode">
658
  <button class="diet-btn active-vegan" data-diet="vegan" onclick="setDiet(this)">Vegan</button>
@@ -661,40 +677,43 @@
661
  </div>
662
  </div>
663
 
664
- <div class="editor">
665
- <div>
666
- <textarea id="recipeInput" placeholder="Paste your recipe here."></textarea>
667
-
668
- <div class="input-actions">
669
- <div class="helper" aria-live="polite">
670
- <span>Paste a recipe</span>
671
- <span>Choose a diet</span>
672
- <span>Review the swaps</span>
673
- </div>
674
- <div class="action-row">
675
- <button class="ghost" onclick="clearInput()">Clear</button>
676
- <button class="primary" id="submitBtn" onclick="run()">Adapt recipe</button>
677
- </div>
678
- </div>
679
-
680
- <div class="loading" id="loading">
681
- <div class="spinner"></div>
682
- <div>Adapting recipe…</div>
683
- </div>
684
-
685
- <div class="error" id="errBox"></div>
686
- </div>
687
 
688
- <div class="side-block">
689
- <h3 class="side-title">Results</h3>
690
- <p class="side-text">
691
- You will see a summary, then ingredient cards with the substitute, notes, and source.
692
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
693
  </div>
694
  </div>
 
 
 
 
 
 
 
695
  </section>
696
 
697
- <section class="section-card results-wrap" id="resultsWrap">
698
  <div class="stats">
699
  <div class="stat">
700
  <div class="num" id="statTotal">—</div>
@@ -713,7 +732,7 @@
713
  <div class="results-head">
714
  <div>
715
  <h3 id="resultTitle">Adapted recipe</h3>
716
- <p id="resultSubtitle" style="margin:6px 0 0;color:var(--muted);font-size:14px;">Open any card to inspect the substitution, notes, and source.</p>
717
  </div>
718
  <div class="badge" id="resultBadge"></div>
719
  </div>
@@ -733,12 +752,13 @@ function setDiet(btn) {
733
 
734
  function fillExample(name) {
735
  const examples = {
736
- "fettuccine alfredo": "24 ounces fettuccine, 1 cup butter, 1 pint heavy cream, 1 cup grated Pecorino romano, 1 cup grated Parmesan",
737
  "pancakes": "1 cup all-purpose flour, 1 tbsp white sugar, 1 tsp baking powder, 1 cup milk, 2 tbsp melted butter",
738
- "butter chicken": "450g Chicken Breast, 2 tbsp Butter, 1 cup Tomato Puree, half cup Heavy Cream, half cup Yogurt"
739
  };
740
- document.getElementById("recipeInput").value = examples[name] || "";
741
- document.getElementById("recipeInput").focus();
 
742
  }
743
 
744
  function clearInput() {
@@ -748,7 +768,9 @@ function clearInput() {
748
 
749
  function toggleCard(id) {
750
  const el = document.getElementById("body-" + id);
 
751
  if (el) el.classList.toggle("open");
 
752
  }
753
 
754
  function normalizeResponse(data) {
@@ -785,9 +807,10 @@ function recipeTypeLabel(recipeType) {
785
  }
786
 
787
  function setLoading(on) {
788
- document.getElementById("loading").style.display = on ? "inline-flex" : "none";
789
- document.getElementById("submitBtn").disabled = on;
790
- document.getElementById("submitBtn").style.opacity = on ? "0.78" : "1";
 
791
  }
792
 
793
  function run() {
@@ -850,24 +873,31 @@ function renderResults(data) {
850
  list.innerHTML = "";
851
 
852
  data.ingredients.forEach((r, i) => {
853
- const dotClass = r.compliant ? "dot dot-ok" : (r.confidence && r.confidence < 0.6 ? "dot dot-warn" : "dot dot-swap");
854
- const statusText = r.compliant ? "compatible" : "substitution suggested";
 
 
 
 
855
 
856
  const item = document.createElement("div");
857
  item.className = "item";
858
  item.innerHTML = `
859
- <div class="item-top" onclick="toggleCard(${i})">
860
  <div class="item-left">
861
  <span class="${dotClass}"></span>
862
  <div class="item-name">${escapeHtml(r.original)}</div>
863
  </div>
864
- <div class="item-status">${statusText}</div>
 
 
 
865
  </div>
866
  <div class="item-body" id="body-${i}">
867
  <div class="label">${r.compliant ? "Result" : "Use instead"}</div>
868
  <div class="value">${escapeHtml(r.substitute || r.original)}</div>
869
  <div class="label">How to use</div>
870
- <div class="value" style="font-weight:600;color:#435166">${escapeHtml(r.instructions || "No details provided.")}</div>
871
  <div class="meta">
872
  <span>Source: ${escapeHtml(r.source || "lookup")}</span>
873
  ${r.matched_ingredient ? `<span>Matched: ${escapeHtml(r.matched_ingredient)}</span>` : ""}
 
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Playfair+Display:wght@600;700&display=swap" rel="stylesheet">
10
  <style>
11
  :root{
12
+ --bg:#fafbfc;
 
13
  --card:#ffffff;
14
+ --text:#0f1a2e;
15
+ --text-soft:#3a4a63;
16
+ --muted:#6b7689;
17
+ --muted2:#9aa3b5;
18
+ --line:#eaedf3;
19
+ --line-soft:#f2f4f8;
20
+ --shadow-lg: 0 24px 60px -20px rgba(15,26,46,.18);
21
+ --shadow-md: 0 10px 30px -10px rgba(15,26,46,.10);
22
+ --shadow-sm: 0 2px 8px rgba(15,26,46,.04);
23
  --green:#3fb487;
24
+ --green-dark:#1f8d63;
25
+ --green-darker:#176b4a;
26
  --mint:#e8f8f1;
27
+ --mint-soft:#f3fbf7;
28
  --amber:#fff4de;
29
  --amber-text:#a86c0b;
30
  --blue:#eef3ff;
31
  --blue-text:#4057c7;
32
+ --rose:#fcedef;
33
+ --rose-text:#bd4b60;
34
+ --radius-lg: 22px;
35
+ --radius-md: 16px;
36
+ --radius-sm: 12px;
37
  }
38
 
39
  * { box-sizing: border-box; }
 
42
  font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
43
  color: var(--text);
44
  background:
45
+ radial-gradient(1200px 600px at 10% -10%, rgba(63,180,135,.10), transparent 60%),
46
+ radial-gradient(900px 500px at 100% 0%, rgba(64,87,199,.07), transparent 55%),
47
+ var(--bg);
48
  min-height: 100vh;
49
+ -webkit-font-smoothing: antialiased;
50
  }
51
 
52
  .shell{
53
+ max-width: 1180px;
54
  margin: 0 auto;
55
+ padding: 28px 24px 64px;
56
  }
57
 
58
+ /* ---------- Top bar ---------- */
59
  .topbar{
60
  display:flex;
61
  justify-content:space-between;
62
  align-items:center;
63
  gap:16px;
64
+ margin-bottom: 36px;
65
  }
 
66
  .brand{
67
  display:flex;
68
  align-items:center;
69
  gap:14px;
70
  }
71
  .brand-mark{
72
+ width: 44px;
73
+ height: 44px;
74
+ border-radius: 14px;
75
+ background: linear-gradient(135deg, #ffffff 0%, #f1f9f5 100%);
76
+ border: 1px solid rgba(63,180,135,.22);
 
 
77
  display:grid;
78
  place-items:center;
79
+ box-shadow: var(--shadow-sm);
80
+ font-size: 20px;
 
 
 
81
  }
82
  .brand-name h1{
83
  margin:0;
84
  font-family: "Playfair Display", serif;
85
+ font-size: 26px;
86
  letter-spacing: -0.03em;
87
  font-weight: 700;
88
+ line-height: 1;
89
  }
90
  .brand-name span{
91
  display:block;
92
+ margin-top: 5px;
93
  color: var(--muted);
94
  font-size: 13px;
95
  }
 
96
  .top-pill{
97
  display:inline-flex;
98
  align-items:center;
99
  gap:8px;
100
+ padding: 9px 14px;
101
  border-radius: 999px;
102
  border: 1px solid var(--line);
103
+ background: rgba(255,255,255,.7);
104
  color: var(--muted);
105
+ font-size: 12.5px;
106
+ font-weight: 500;
107
+ }
108
+ .top-pill::before{
109
+ content:"";
110
+ width:7px; height:7px;
111
+ border-radius:50%;
112
+ background: var(--green);
113
+ box-shadow: 0 0 0 4px rgba(63,180,135,.15);
114
  }
115
 
116
+ /* ---------- Hero ---------- */
117
  .hero{
118
  display:grid;
119
+ grid-template-columns: 1fr;
120
+ gap: 14px;
121
+ margin-bottom: 28px;
122
+ text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
123
  }
 
124
  .eyebrow{
125
  display:inline-flex;
126
  align-items:center;
127
  gap:8px;
128
+ font-size: 11.5px;
129
  font-weight: 700;
130
+ letter-spacing: .12em;
131
  text-transform: uppercase;
132
+ color: var(--green-darker);
133
  background: var(--mint);
134
+ border: 1px solid rgba(63,180,135,.18);
135
+ padding: 7px 12px;
136
  border-radius: 999px;
137
+ margin: 0 auto;
138
  }
139
+ .hero h2{
 
140
  margin: 0;
141
+ font-size: clamp(36px, 5vw, 60px);
142
  line-height: 1.02;
143
+ letter-spacing: -0.045em;
144
+ font-weight: 700;
145
  }
146
+ .hero h2 em{
147
  font-family: "Playfair Display", serif;
148
+ font-style: italic;
149
+ color: var(--green-darker);
150
+ font-weight: 600;
151
  }
152
+ .hero p{
153
+ margin: 4px auto 0;
154
+ max-width: 58ch;
155
  font-size: 16px;
156
+ line-height: 1.65;
157
  color: var(--muted);
158
  }
159
 
160
+ /* ---------- Card ---------- */
161
+ .card{
162
+ background: var(--card);
 
 
 
 
 
 
163
  border: 1px solid var(--line);
164
+ border-radius: var(--radius-lg);
165
+ box-shadow: var(--shadow-md);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  }
167
 
168
+ /* ---------- Composer ---------- */
169
+ .composer{
170
+ padding: 26px;
171
+ margin-bottom: 22px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  }
173
+ .composer-head{
 
174
  display:flex;
175
  justify-content:space-between;
176
+ align-items:center;
177
+ gap:14px;
178
+ margin-bottom: 18px;
179
+ flex-wrap:wrap;
180
  }
181
+ .composer-head h3{
 
182
  margin:0;
183
+ font-size: 17px;
184
+ letter-spacing: -0.02em;
185
+ font-weight: 700;
186
  }
187
+ .composer-head p{
188
+ margin:4px 0 0;
189
  color: var(--muted);
190
+ font-size: 13.5px;
 
191
  }
192
 
193
  .segmented{
194
  display:inline-flex;
195
+ gap: 4px;
196
+ padding: 4px;
197
  border-radius: 999px;
198
+ background: var(--line-soft);
199
  border: 1px solid var(--line);
200
  }
 
201
  .diet-btn{
202
  border: 0;
203
  background: transparent;
204
  color: var(--muted);
205
+ padding: 9px 16px;
206
  border-radius: 999px;
207
  font-size: 13px;
208
+ font-weight: 600;
209
  cursor: pointer;
210
+ transition: all .18s ease;
211
  }
212
+ .diet-btn:hover{ color: var(--text); }
213
+ .diet-btn.active-vegan{ background: #fff; color: var(--green-darker); box-shadow: 0 1px 3px rgba(15,26,46,.08); }
214
+ .diet-btn.active-keto{ background: #fff; color: var(--amber-text); box-shadow: 0 1px 3px rgba(15,26,46,.08); }
215
+ .diet-btn.active-both{ background: #fff; color: var(--blue-text); box-shadow: 0 1px 3px rgba(15,26,46,.08); }
216
 
217
+ .textarea-wrap{
218
+ position: relative;
 
 
 
219
  }
 
220
  textarea{
221
  width: 100%;
222
+ min-height: 180px;
223
  resize: vertical;
224
+ border-radius: var(--radius-md);
225
  border: 1px solid var(--line);
226
+ background: #fcfcfd;
227
  color: var(--text);
228
+ padding: 16px 18px;
229
  font: inherit;
230
  font-size: 15px;
231
+ line-height: 1.65;
232
  outline:none;
233
+ transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
234
  }
235
  textarea:focus{
236
+ border-color: rgba(63,180,135,.45);
237
  box-shadow: 0 0 0 4px rgba(63,180,135,.10);
238
+ background: #fff;
239
+ }
240
+ textarea::placeholder{ color:#a3adbe; }
241
+
242
+ /* Quick try chips */
243
+ .tries-row{
244
+ display:flex;
245
+ align-items:center;
246
+ gap:10px;
247
+ margin-top: 14px;
248
+ flex-wrap:wrap;
249
+ }
250
+ .tries-label{
251
+ font-size: 12.5px;
252
+ font-weight: 600;
253
+ color: var(--muted);
254
  }
255
+ .chip{
256
+ appearance:none;
257
+ border: 1px solid var(--line);
258
+ background: #fff;
259
+ color: var(--text-soft);
260
+ border-radius: 999px;
261
+ padding: 8px 13px;
262
+ font-size: 12.5px;
263
+ font-weight: 600;
264
+ cursor:pointer;
265
+ transition: all .15s ease;
266
+ display:inline-flex;
267
+ align-items:center;
268
+ gap:6px;
269
+ }
270
+ .chip:hover{
271
+ border-color: rgba(63,180,135,.4);
272
+ background: var(--mint-soft);
273
+ color: var(--green-darker);
274
+ transform: translateY(-1px);
275
  }
276
+ .chip-icon{ font-size: 13px; }
277
 
278
  .input-actions{
279
+ margin-top: 18px;
280
  display:flex;
281
  flex-wrap:wrap;
282
  gap: 10px;
283
  align-items:center;
284
  justify-content:space-between;
285
  }
 
286
  .helper{
287
  display:flex;
288
  flex-wrap:wrap;
289
+ gap:6px;
290
  color: var(--muted);
291
+ font-size: 12.5px;
292
+ align-items:center;
293
+ }
294
+ .helper .step{
295
+ display:inline-flex;
296
+ align-items:center;
297
+ gap:6px;
298
  }
299
+ .step-num{
300
+ width:18px; height:18px;
301
+ border-radius:50%;
302
+ background: var(--mint);
303
+ color: var(--green-darker);
304
+ font-weight:700;
305
+ font-size: 11px;
306
+ display:grid;
307
+ place-items:center;
308
+ }
309
+ .helper .sep{ color: var(--muted2); }
310
 
311
  .action-row{
312
  display:flex;
313
  gap: 10px;
314
  align-items:center;
315
  }
 
316
  .primary{
317
  border: none;
318
+ border-radius: var(--radius-md);
319
+ padding: 13px 22px;
320
+ font-weight: 700;
321
  font-size: 14px;
322
  cursor:pointer;
323
  color:#fff;
324
+ background: linear-gradient(135deg, var(--green) 0%, var(--green-dark) 100%);
325
+ box-shadow: 0 8px 20px -4px rgba(63,180,135,.45);
326
+ transition: all .18s ease;
327
+ display:inline-flex;
328
+ align-items:center;
329
+ gap:8px;
330
  }
331
  .primary:hover{
332
  transform: translateY(-1px);
333
+ box-shadow: 0 12px 28px -4px rgba(63,180,135,.55);
 
334
  }
335
+ .primary:active{ transform: translateY(0); }
336
+ .primary:disabled{ cursor: not-allowed; }
337
 
338
  .ghost{
339
  border: 1px solid var(--line);
340
  background:#fff;
341
+ color: var(--text-soft);
342
+ border-radius: var(--radius-md);
343
+ padding: 13px 18px;
344
+ font-weight: 600;
345
  font-size: 14px;
346
  cursor:pointer;
347
+ transition: all .15s ease;
348
  }
349
  .ghost:hover{
350
+ background: var(--line-soft);
351
+ border-color: #d8dde6;
352
  }
353
 
354
+ .loading{
355
+ display:none;
356
+ margin-top: 14px;
357
+ align-items:center;
358
+ gap:10px;
359
+ font-size: 13px;
360
+ color: var(--muted);
361
+ }
362
+ .spinner{
363
+ width: 16px;
364
+ height: 16px;
365
+ border-radius: 999px;
366
+ border: 2px solid rgba(63,180,135,.18);
367
+ border-top-color: var(--green);
368
+ animation: spin .8s linear infinite;
369
+ }
370
+ @keyframes spin{ to { transform: rotate(360deg); } }
371
+
372
  .error{
373
  display:none;
374
+ margin-top: 14px;
375
+ border: 1px solid rgba(189,75,96,.22);
376
+ background: var(--rose);
377
+ color: var(--rose-text);
378
+ border-radius: var(--radius-md);
379
  padding: 12px 14px;
380
  font-size: 13px;
381
+ font-weight: 500;
382
  }
383
 
384
+ /* ---------- Feature row (replaces hero mini-cards) ---------- */
385
+ .feature-row{
386
+ display:grid;
387
+ grid-template-columns: repeat(3, 1fr);
388
+ gap: 14px;
389
+ margin-bottom: 28px;
390
+ }
391
+ .feature{
392
+ background: #fff;
393
+ border: 1px solid var(--line);
394
+ border-radius: var(--radius-md);
395
+ padding: 18px;
396
+ transition: transform .2s ease, box-shadow .2s ease;
397
+ }
398
+ .feature:hover{
399
+ transform: translateY(-2px);
400
+ box-shadow: var(--shadow-md);
401
+ }
402
+ .feature-icon{
403
+ width: 36px;
404
+ height: 36px;
405
+ border-radius: 10px;
406
+ display:grid;
407
+ place-items:center;
408
+ font-size: 16px;
409
+ margin-bottom: 12px;
410
+ }
411
+ .feature-icon.g{ background: var(--mint); }
412
+ .feature-icon.b{ background: var(--blue); }
413
+ .feature-icon.a{ background: var(--amber); }
414
+ .feature h4{
415
+ margin: 0 0 4px;
416
+ font-size: 14px;
417
+ font-weight: 700;
418
+ letter-spacing: -0.01em;
419
+ }
420
+ .feature p{
421
+ margin: 0;
422
+ color: var(--muted);
423
+ font-size: 13px;
424
+ line-height: 1.55;
425
+ }
426
+
427
+ /* ---------- Results ---------- */
428
  .results-wrap{
429
  display:none;
430
+ padding: 26px;
431
  }
 
432
  .stats{
433
  display:grid;
434
+ grid-template-columns: repeat(3, 1fr);
435
  gap: 12px;
436
+ margin-bottom: 20px;
437
  }
438
  .stat{
439
  border: 1px solid var(--line);
440
+ background: linear-gradient(180deg, #fff 0%, #fafbfd 100%);
441
+ border-radius: var(--radius-md);
442
+ padding: 16px 18px;
443
  }
444
  .stat .num{
445
+ font-size: 28px;
446
  font-weight: 800;
447
  letter-spacing: -0.04em;
448
+ line-height: 1;
449
  }
450
  .stat .lbl{
451
  color: var(--muted);
452
+ font-size: 11.5px;
453
  text-transform: uppercase;
454
  letter-spacing: .08em;
455
+ font-weight: 600;
456
+ margin-top: 6px;
457
  }
458
 
459
  .results-head{
460
  display:flex;
461
  justify-content:space-between;
462
+ align-items:flex-start;
463
  gap:12px;
464
  margin-bottom: 16px;
465
+ flex-wrap:wrap;
466
  }
467
  .results-head h3{
468
  margin:0;
469
  font-size: 20px;
470
  letter-spacing: -0.03em;
471
+ font-weight: 700;
472
+ }
473
+ .results-head p{
474
+ margin:6px 0 0;
475
+ color: var(--muted);
476
+ font-size: 13.5px;
477
  }
478
  .badge{
479
  display:inline-flex;
480
  align-items:center;
481
  gap:8px;
482
  font-size: 12px;
483
+ font-weight: 700;
484
+ padding: 8px 12px;
485
  border-radius: 999px;
486
  }
487
+ .badge-vegan{ background: var(--mint); color: var(--green-darker); }
488
  .badge-keto{ background: var(--amber); color: var(--amber-text); }
489
  .badge-both{ background: var(--blue); color: var(--blue-text); }
490
 
 
494
  }
495
  .item{
496
  overflow:hidden;
497
+ border-radius: var(--radius-md);
498
  border: 1px solid var(--line);
499
  background: #fff;
500
+ transition: border-color .15s ease, box-shadow .15s ease;
501
+ }
502
+ .item:hover{
503
+ border-color: #dde2eb;
504
+ box-shadow: var(--shadow-sm);
505
  }
506
  .item-top{
507
  display:flex;
 
510
  gap:12px;
511
  padding: 14px 16px;
512
  cursor:pointer;
513
+ user-select: none;
514
  }
515
  .item-left{
516
  display:flex;
 
519
  min-width: 0;
520
  }
521
  .dot{
522
+ width: 9px;
523
+ height: 9px;
524
  border-radius:999px;
525
  flex:0 0 auto;
526
+ position: relative;
527
+ }
528
+ .dot::after{
529
+ content:"";
530
+ position: absolute;
531
+ inset: -4px;
532
+ border-radius: 50%;
533
+ opacity: .25;
534
  }
535
  .dot-ok{ background: var(--green); }
536
+ .dot-ok::after{ background: var(--green); }
537
  .dot-swap{ background: #f0a84c; }
538
+ .dot-swap::after{ background: #f0a84c; }
539
  .dot-warn{ background: #f36f7f; }
540
+ .dot-warn::after{ background: #f36f7f; }
541
 
542
  .item-name{
543
+ font-weight: 600;
544
+ font-size: 14.5px;
545
  white-space:nowrap;
546
  overflow:hidden;
547
  text-overflow:ellipsis;
548
  }
549
+ .item-right{
550
+ display:flex;
551
+ align-items:center;
552
+ gap:10px;
553
+ flex-shrink: 0;
554
+ }
555
  .item-status{
556
+ color: var(--muted);
557
  font-size: 12px;
558
+ font-weight: 500;
559
  }
560
+ .chevron{
561
+ width: 16px;
562
+ height: 16px;
563
+ color: var(--muted2);
564
+ transition: transform .2s ease;
565
+ }
566
+ .item-top.open .chevron{ transform: rotate(180deg); }
567
 
568
  .item-body{
569
  display:none;
570
  border-top: 1px solid var(--line);
571
+ background: #fcfcfd;
572
+ padding: 18px;
 
 
 
573
  }
574
+ .item-body.open{ display:block; }
575
 
576
  .label{
577
+ font-size: 10.5px;
578
  text-transform: uppercase;
579
+ letter-spacing: .1em;
580
+ color: var(--muted2);
581
+ margin-bottom: 6px;
582
+ font-weight: 700;
583
  }
584
  .value{
585
  font-size: 15px;
586
+ font-weight: 600;
587
+ color: var(--text);
588
  line-height: 1.55;
589
+ margin-bottom: 14px;
590
+ }
591
+ .value.soft{
592
+ font-weight: 500;
593
+ color: var(--text-soft);
594
+ font-size: 14px;
595
  }
596
  .meta{
597
+ font-size: 11.5px;
598
+ color: var(--muted);
599
  display:flex;
600
  flex-wrap:wrap;
601
+ gap: 6px;
602
  }
603
  .meta span{
604
+ background: #fff;
605
  border: 1px solid var(--line);
606
  border-radius: 999px;
607
+ padding: 5px 10px;
608
+ font-weight: 500;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  }
 
610
 
611
+ @media (max-width: 880px){
612
+ .feature-row, .stats{ grid-template-columns: 1fr; }
613
+ .topbar{ flex-direction: column; align-items:flex-start; }
614
+ .composer-head{ flex-direction: column; align-items:flex-start; }
 
 
 
 
 
 
 
615
  }
616
 
617
+ @media (max-width: 560px){
618
+ .shell{ padding: 18px 14px 40px; }
619
+ .composer, .results-wrap{ padding: 20px; }
620
+ .input-actions{ flex-direction: column; align-items:stretch; }
621
+ .action-row{ width:100%; }
622
+ .action-row .primary, .action-row .ghost{
623
+ flex: 1;
 
 
 
 
 
 
 
 
 
624
  justify-content:center;
625
  }
626
+ .tries-row{ flex-direction: column; align-items: flex-start; }
627
  }
628
  </style>
629
  </head>
 
637
  <span>Recipe adaptation that feels simple.</span>
638
  </div>
639
  </div>
640
+ <div class="top-pill">Built for vegan and keto cooking</div>
641
  </div>
642
 
643
  <section class="hero">
644
+ <span class="eyebrow">Diet-friendly cooking, without the guesswork</span>
645
+ <h2>Turn any recipe into a <em>clear</em> adaptation.</h2>
646
+ <p>Paste a recipe, choose a diet, and get ingredient-by-ingredient substitutions with short, practical instructions.</p>
647
+ </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
 
649
+ <section class="feature-row">
650
+ <div class="feature">
651
+ <div class="feature-icon g">🔄</div>
652
+ <h4>Ingredient-level swaps</h4>
653
+ <p>Each item gets its own card with the substitute and a short usage note.</p>
654
+ </div>
655
+ <div class="feature">
656
+ <div class="feature-icon b">📖</div>
657
+ <h4>Context aware</h4>
658
+ <p>Results adapt to baking or cooking based on what you paste in.</p>
659
+ </div>
660
+ <div class="feature">
661
+ <div class="feature-icon a">✓</div>
662
+ <h4>Clear, reviewable output</h4>
663
+ <p>Open any card to inspect the substitute, instructions, and source.</p>
664
+ </div>
665
  </section>
666
 
667
+ <section class="card composer">
668
+ <div class="composer-head">
669
  <div>
670
  <h3>Adapt a recipe</h3>
671
+ <p>Paste anything from a recipe post or notes app, then pick a diet.</p>
672
  </div>
673
  <div class="segmented" role="tablist" aria-label="Diet mode">
674
  <button class="diet-btn active-vegan" data-diet="vegan" onclick="setDiet(this)">Vegan</button>
 
677
  </div>
678
  </div>
679
 
680
+ <div class="textarea-wrap">
681
+ <textarea id="recipeInput" placeholder="Paste your recipe here. For example: 2 cups flour, 2 eggs, 1/2 cup butter, 1 cup milk, vanilla extract..."></textarea>
682
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
683
 
684
+ <div class="tries-row">
685
+ <span class="tries-label">Try a sample:</span>
686
+ <button class="chip" onclick="fillExample('alfredo')"><span class="chip-icon">🍝</span>Fettuccine Alfredo</button>
687
+ <button class="chip" onclick="fillExample('pancakes')"><span class="chip-icon">🥞</span>Pancakes</button>
688
+ <button class="chip" onclick="fillExample('butter chicken')"><span class="chip-icon">🍛</span>Butter Chicken</button>
689
+ </div>
690
+
691
+ <div class="input-actions">
692
+ <div class="helper" aria-live="polite">
693
+ <span class="step"><span class="step-num">1</span>Paste recipe</span>
694
+ <span class="sep">·</span>
695
+ <span class="step"><span class="step-num">2</span>Choose diet</span>
696
+ <span class="sep">·</span>
697
+ <span class="step"><span class="step-num">3</span>Review swaps</span>
698
+ </div>
699
+ <div class="action-row">
700
+ <button class="ghost" onclick="clearInput()">Clear</button>
701
+ <button class="primary" id="submitBtn" onclick="run()">
702
+ <span>Adapt recipe</span>
703
+ <span aria-hidden="true">→</span>
704
+ </button>
705
  </div>
706
  </div>
707
+
708
+ <div class="loading" id="loading">
709
+ <div class="spinner"></div>
710
+ <div>Adapting recipe…</div>
711
+ </div>
712
+
713
+ <div class="error" id="errBox"></div>
714
  </section>
715
 
716
+ <section class="card results-wrap" id="resultsWrap">
717
  <div class="stats">
718
  <div class="stat">
719
  <div class="num" id="statTotal">—</div>
 
732
  <div class="results-head">
733
  <div>
734
  <h3 id="resultTitle">Adapted recipe</h3>
735
+ <p id="resultSubtitle">Review each ingredient and expand any card for details.</p>
736
  </div>
737
  <div class="badge" id="resultBadge"></div>
738
  </div>
 
752
 
753
  function fillExample(name) {
754
  const examples = {
755
+ "alfredo": "24 ounces fettuccine, 1 cup butter, 1 pint heavy cream, 1 cup grated Pecorino romano, 1 cup grated Parmesan",
756
  "pancakes": "1 cup all-purpose flour, 1 tbsp white sugar, 1 tsp baking powder, 1 cup milk, 2 tbsp melted butter",
757
+ "butter chicken": "450g chicken breast, 2 tbsp butter, 1 cup tomato puree, 1/2 cup heavy cream, 1/2 cup yogurt"
758
  };
759
+ const ta = document.getElementById("recipeInput");
760
+ ta.value = examples[name] || "";
761
+ ta.focus();
762
  }
763
 
764
  function clearInput() {
 
768
 
769
  function toggleCard(id) {
770
  const el = document.getElementById("body-" + id);
771
+ const top = document.getElementById("top-" + id);
772
  if (el) el.classList.toggle("open");
773
+ if (top) top.classList.toggle("open");
774
  }
775
 
776
  function normalizeResponse(data) {
 
807
  }
808
 
809
  function setLoading(on) {
810
+ document.getElementById("loading").style.display = on ? "flex" : "none";
811
+ const btn = document.getElementById("submitBtn");
812
+ btn.disabled = on;
813
+ btn.style.opacity = on ? "0.7" : "1";
814
  }
815
 
816
  function run() {
 
873
  list.innerHTML = "";
874
 
875
  data.ingredients.forEach((r, i) => {
876
+ const dotClass = r.compliant
877
+ ? "dot dot-ok"
878
+ : (r.confidence && r.confidence < 0.6 ? "dot dot-warn" : "dot dot-swap");
879
+ const statusText = r.compliant ? "compatible" : "swap suggested";
880
+
881
+ const chevron = `<svg class="chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>`;
882
 
883
  const item = document.createElement("div");
884
  item.className = "item";
885
  item.innerHTML = `
886
+ <div class="item-top" id="top-${i}" onclick="toggleCard(${i})">
887
  <div class="item-left">
888
  <span class="${dotClass}"></span>
889
  <div class="item-name">${escapeHtml(r.original)}</div>
890
  </div>
891
+ <div class="item-right">
892
+ <div class="item-status">${statusText}</div>
893
+ ${chevron}
894
+ </div>
895
  </div>
896
  <div class="item-body" id="body-${i}">
897
  <div class="label">${r.compliant ? "Result" : "Use instead"}</div>
898
  <div class="value">${escapeHtml(r.substitute || r.original)}</div>
899
  <div class="label">How to use</div>
900
+ <div class="value soft">${escapeHtml(r.instructions || "No details provided.")}</div>
901
  <div class="meta">
902
  <span>Source: ${escapeHtml(r.source || "lookup")}</span>
903
  ${r.matched_ingredient ? `<span>Matched: ${escapeHtml(r.matched_ingredient)}</span>` : ""}