PageSourceSearch

https://capstonetechno.onrender.com/

html capstonetechno.onrender.com collected 2026-10-03 11:39:23 UTC 230,283 bytes, 3,140 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
6<meta name="description" content="Bloom - Handcrafted bouquets, pre-ordered for every moment. WCAG 2.1 AA accessible. ">
7<meta name="theme-color" content="#0B0516" media="(prefers-color-scheme: dark)">
8<meta name="theme-color" content="#0B0516">
9<meta name="color-scheme" content="dark">
10<meta property="og:title" content="Bloom - Pre-Order Flowers & Gifts">
11<meta property="og:description" content="Custom bouquets for every moment. WCAG 2.1 AA accessible. ">
12<meta property="og:type" content="website">
13<meta property="og:image" content="/img/hero-flowers.webp">
14<meta name="twitter:card" content="summary_large_image">
15<title>Bloom - Pre-Order Flowers & Gifts</title>
16<link rel="canonical" href="https://capstonetechno.onrender.com/">
17<link rel="alternate" hreflang="en" href="https://capstonetechno.onrender.com/">
18<link rel="alternate" hreflang="en-PH" href="https://capstonetechno.onrender.com/?lang=en-PH">
19<link rel="alternate" hreflang="fil-PH" href="https://capstonetechno.onrender.com/?lang=fil">
20<link rel="alternate" hreflang="es" href="https://capstonetechno.onrender.com/?lang=es">
21<link rel="alternate" hreflang="ja" href="https://capstonetechno.onrender.com/?lang=ja">
22<link rel="alternate" hreflang="x-default" href="https://capstonetechno.onrender.com/">
23<link rel="preconnect" href="https://fonts.googleapis.com">
24<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
25<link rel="dns-prefetch" href="https://fonts.googleapis.com">
26<link rel="preload" href="/img/hero-flowers.webp" as="image" fetchpriority="high">
27<link rel="preload" href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;0,900&family=Barlow+Condensed:wght@700;900&family=DM+Sans:opsz,[email protected],400;9..40,500&display=swap" as="style">
28<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;0,900&family=Barlow+Condensed:wght@700;900&family=DM+Sans:opsz,[email protected],400;9..40,500&display=swap">
29<script type="application/ld+json">
30{"@context":"https://schema.org","@type":"Organization","name":"Bloom","url":"/","logo":"/img/hero-flowers.webp","description":"Handcrafted bouquets, pre-ordered for every moment. WCAG 2.1 AA accessible. A BSIT Capstone project by STI College Lipa.","sameAs":["https://instagram.com/","https://facebook.com/"],"address":{"@type":"PostalAddress","addressCountry":"PH","addressRegion":"Batangas","addressLocality":"Lipa City"},"areaServed":["Metro Manila","Batangas","Cebu"]}
31</script>
vendor: 2 bytes, line 31
31
32<script type="application/ld+json">
33{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"/"},{"@type":"ListItem","position":2,"name":"Catalog","item":"/catalog.html"}]}
34</script>
vendor: 2 bytes, line 34
34
35<script type="application/ld+json">
36{"@context":"https://schema.org","@type":"Product","name":"Bloom Handcrafted Bouquets","image":"/img/hero-flowers.webp","description":"Pre-order handcrafted bouquets and floral arrangements with careful handling and dedicated delivery windows across our service areas.","brand":{"@type":"Brand","name":"Bloom"},"offers":{"@type":"AggregateOffer","priceCurrency":"PHP","lowPrice":"1650","highPrice":"4200","offerCount":"40"},"aggregateRating":{"@type":"AggregateRating","ratingValue":"4.86","reviewCount":"487","bestRating":"5","worstRating":"1"}}
37</script>
vendor: 2 bytes, line 37
37
38<script type="application/ld+json">
39{"@context":"https://schema.org","@type":"WebSite","name":"Bloom","url":"/","potentialAction":{"@type":"SearchAction","target":"/catalog.html?search={search_term_string}","query-input":"required name=search_term_string"}}
40</script>
vendor: 2 bytes, line 40
40
41<script type="application/ld+json">
42{"@context":"https://schema.org","@type":"LocalBusiness","name":"Bloom Florist","image":"/img/hero-flowers.webp","priceRange":"₱₱","telephone":"+63","address":{"@type":"PostalAddress","addressCountry":"PH","addressRegion":"Batangas","addressLocality":"Lipa City"},"openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],"opens":"08:00","closes":"20:00"}],"aggregateRating":{"@type":"AggregateRating","ratingValue":"4.86","reviewCount":"487"}}
43</script>
43
44<link rel="stylesheet" href="/css/landing.min.css">
45<link rel="stylesheet" href="/css/phase8.css">
46<link rel="stylesheet" href="/css/wabi-sabi.min.css">
47<link rel="stylesheet" href="/css/atelier-persona.css">
48<link rel="manifest" href="/manifest.json">
49<link rel="apple-touch-icon" href="/img/hero-flowers.webp">
50<style>
51@property --sh { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
52@property --px { syntax: '<number>'; inherits: true; initial-value: 0; }
53@property --py { syntax: '<number>'; inherits: true; initial-value: 0; }
54:root {
55  --p5: #E61A1A;
56  --p5d: #A81010;
57  --p5l: #FF3B3B;
58  --pk: oklch(58% .22 348);
59  --pk2: oklch(48% .22 340);
60  --pu: oklch(40% .24 292);
61  --pu2: oklch(26% .18 292);
62  --gd: oklch(84% .17 86);
63  --mn: oklch(76% .15 172);
64  --bg: oklch(11% .06 292);
65  --bg2: oklch(15% .07 292);
66  --bg3: oklch(19% .08 292);
67  --ink: #0B0516;
68  --paper: #F8F3E8;
69  --cr: oklch(68% .22 27);
70  --gl: rgba(255,255,255,.055);
71  --glb: rgba(255,255,255,.09);
72  --gls: rgba(255,255,255,.025);
73  --r: 20px;
74  --rs: 12px;
75  --rx: 8px;
76  --ease: cubic-bezier(.23,1,.32,1);
77  --spring: cubic-bezier(.34,1.56,.64,1);
78  --p5ease: cubic-bezier(.17,.67,.32,1.27);
79  --fd: 'Playfair Display', Georgia, serif;
80  --fc: 'Barlow Condensed', Impact, sans-serif;
81  --fb: 'DM Sans', system-ui, sans-serif;
82  --text: #fff;
83  --text-muted: rgba(255,255,255,.6);
84  --text-dim: rgba(255,255,255,.50);
85}
86[data-theme="light"] {
87  --bg: #FEFCF9;
88  --bg2: #F5F0EB;
89  --bg3: #EDE6DF;
90  --ink: #1A1220;
91  --paper: #FFFFFF;
92  --gl: rgba(0,0,0,.04);
93  --glb: rgba(0,0,0,.08);
94  --gls: rgba(0,0,0,.02);
95  --text: #1A1220;
96  --text-muted: rgba(26,18,32,.6);
97  --text-dim: rgba(26,18,32,.4);
98  --nav-bg: rgba(254,252,249,.92);
99  --card-bg: rgba(0,0,0,.03);
100  --card-border: rgba(0,0,0,.08);
101  --input-bg: rgba(0,0,0,.04);
102  --input-border: rgba(0,0,0,.12);
103  --shadow-color: rgba(0,0,0,.08);
104}
105* { box-sizing: border-box; margin: 0; padding: 0; }
106*::before, *::after { box-sizing: border-box; }
107html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; color-scheme: dark; interpolate-size: allow-keywords; scrollbar-width: none; -ms-overflow-style: none; }
108html::-webkit-scrollbar { display: none !important; }
109html { overflow-x: clip; max-width: 100%; width: 100%; }
110body { background: var(--bg); color: var(--text, #fff); font-family: var(--fb); overflow-x: clip; min-height: 100dvh; width: 100%; max-width: 100vw; margin: 0; padding: 0; }
111body.modal-open { overflow: hidden; }
112@media (pointer: fine) { body { cursor: none; } button, a, input, textarea, [role="button"] { cursor: none; } }
113@media (prefers-reduced-motion: reduce) {
114  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
115}
116::selection { background: rgba(230,26,26,.35); color: #fff; }
117[data-theme="light"] { color-scheme: light; }
118[data-theme="light"] body { color: var(--text); }
119[data-theme="light"] #nav { background: rgba(254,252,249,.92); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); }
120[data-theme="light"] #nav.sc { background: rgba(254,252,249,.95); }
121[data-theme="light"] #nav.sc::after { background: linear-gradient(90deg, transparent, var(--p5), var(--pk), transparent); }
122[data-theme="light"] .n-links a { color: rgba(26,18,32,.6); }
123[data-theme="light"] .n-links a:hover { color: var(--text); background: rgba(0,0,0,.05); }
124[data-theme="light"] .n-logo { -webkit-text-fill-color: var(--text); color: var(--text); background: none; }
125[data-theme="light"] .n-logo::before { color: var(--p5); -webkit-text-fill-color: var(--p5); }
126[data-theme="light"] .hmb span { background: var(--text); }
127[data-theme="light"] .n-acts .btn-g { background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.1); color: rgba(26,18,32,.7); }
128[data-theme="light"] .n-acts .btn-g:hover { background: rgba(0,0,0,.08); color: var(--text); }
129[data-theme="light"] .btn-g { background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.1); color: rgba(26,18,32,.7); }
130[data-theme="light"] .btn-g:hover { background: rgba(0,0,0,.08); color: var(--text); }
131[data-theme="light"] .n-srch-panel { background: rgba(255,255,255,.97); border-color: rgba(0,0,0,.1); }
132[data-theme="light"] .n-srch-inp { background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.12); color: var(--text); }
133[data-theme="light"] .lang-dd { background: rgba(255,255,255,.97); border-color: rgba(0,0,0,.1); }
134[data-theme="light"] .lang-opt { color: rgba(26,18,32,.6); }
135[data-theme="light"] .lang-opt:hover { color: var(--text); }
136[data-theme="light"] .mob-menu { background: rgba(255,255,255,.97); }
137[data-theme="light"] .mob-inner a { color: rgba(26,18,32,.6); }
138[data-theme="light"] .mob-inner a:hover { color: var(--text); }
139[data-theme="light"] .hero-photo::before { background: linear-gradient(to right, var(--bg) 0%, rgba(254,252,249,.72) 25%, rgba(254,252,249,.15) 60%, transparent 100%); }
140[data-theme="light"] .hero-photo::after { background: linear-gradient(to bottom, rgba(254,252,249,.5) 0%, transparent 20%, transparent 80%, rgba(254,252,249,.62) 100%); }
141[data-theme="light"] .hero-hl { color: var(--text); }
142[data-theme="light"] .hero-hl em { color: rgba(26,18,32,.7); }
143[data-theme="light"] .hero-sub { color: rgba(26,18,32,.6); }
144[data-theme="light"] .hero-eyebrow-tag { background: rgba(230,26,26,.1); border-color: rgba(230,26,26,.25); color: var(--p5d); }
145[data-theme="light"] .hero-eyebrow-sub { color: rgba(26,18,32,.5); }
146[data-theme="light"] .trust-item { color: rgba(26,18,32,.55); }
147[data-theme="light"] .hero-countdown { color: rgba(26,18,32,.7); }
148[data-theme="light"] .sec-title { color: var(--text); }
149[data-theme="light"] .sec-sub { color: rgba(26,18,32,.72); }
150[data-theme="light"] .p-card { background: rgba(0,0,0,.03); border-color: rgba(0,0,0,.08); }
151[data-theme="light"] .p-card:hover { border-color: rgba(230,26,26,.3); box-shadow: 0 10px 40px rgba(0,0,0,.08); }
152[data-theme="light"] .p-name { color: var(--text); }
153[data-theme="light"] .p-cat { color: rgba(26,18,32,.5); }
154[data-theme="light"] .p-empty { color: rgba(26,18,32,.45); }
155[data-theme="light"] .p-err { color: var(--cr); }
156[data-theme="light"] .stats-strip { background: var(--bg2); }
157[data-theme="light"] .stats-strip::before { background: linear-gradient(135deg, rgba(230,26,26,.03), rgba(188,49,148,.02)); }
158[data-theme="light"] .stat-item { background: transparent; }
159[data-theme="light"] .stat-num { background: linear-gradient(135deg, var(--text), rgba(26,18,32,.68)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
160[data-theme="light"] .stat-lbl { color: rgba(26,18,32,.55); }
161[data-theme="light"] .stat-src { color: rgba(26,18,32,.45); }
162[data-theme="light"] .stat-src a { color: var(--p5d); border-bottom-color: rgba(230,26,26,.3); }
163[data-theme="light"] .stat-bar { background: rgba(0,0,0,.06); }
164[data-theme="light"] .stat-icon { filter: grayscale(.15); }
165[data-theme="light"] .feat-sec { background: var(--bg2); }
166[data-theme="light"] .feat-sec::before { mix-blend-mode: normal; }
167[data-theme="light"] .feat-card { background: rgba(255,255,255,.7); border-color: rgba(0,0,0,.08); }
168[data-theme="light"] .feat-card:hover { background: rgba(255,255,255,.9); border-color: rgba(230,26,26,.3); box-shadow: 0 16px 48px rgba(0,0,0,.08); }
169[data-theme="light"] .feat-t { color: var(--text); }
170[data-theme="light"] .feat-d { color: rgba(26,18,32,.6); }
171[data-theme="light"] .feat-card:hover .feat-d { color: rgba(26,18,32,.8); }
172[data-theme="light"] .feat-ico { background: linear-gradient(135deg, rgba(230,26,26,.12), rgba(188,49,148,.08)); border-color: rgba(230,26,26,.25); }
173[data-theme="light"] .feat-ico svg { color: var(--p5d); }
174[data-theme="light"] .rev-sec { background: var(--bg); }
175[data-theme="light"] .rev-card { background: rgba(0,0,0,.03); border-color: rgba(0,0,0,.08); }
176[data-theme="light"] .rev-body { color: rgba(26,18,32,.72); }
177[data-theme="light"] .rev-name { color: var(--text); }
178[data-theme="light"] .rev-role { color: rgba(26,18,32,.5); }
179[data-theme="light"] .rev-card::before { color: rgba(230,26,26,.2); }
180[data-theme="light"] .rev-stars span { color: #d4940a !important; }
181[data-theme="light"] .rev-stars span[style*="0.2"] { color: rgba(26,18,32,.15) !important; }
182[data-theme="light"] .fact-card { background: rgba(255,255,255,.7); border-color: rgba(0,0,0,.1); }
183[data-theme="light"] .fact-card::before { background: linear-gradient(to bottom, var(--p5), var(--pk)); }
184[data-theme="light"] .fact-k { color: var(--p5d); -webkit-text-fill-color: var(--p5d); }
185[data-theme="light"] .fact-t { color: var(--text); }
186[data-theme="light"] .fact-d { color: rgba(26,18,32,.65); }
187[data-theme="light"] .fact-src { color: rgba(26,18,32,.5); }
188[data-theme="light"] .fact-src a { color: var(--p5d); border-bottom-color: rgba(230,26,26,.35); }
189[data-theme="light"] .facts-sec { background: var(--bg2); border-top-color: rgba(0,0,0,.06); border-bottom-color: rgba(0,0,0,.06); }
190[data-theme="light"] .subs-sec { background: var(--bg2); }
191[data-theme="light"] .subs-card { background: rgba(255,255,255,.6); border-color: rgba(0,0,0,.08); color: var(--text); }
192[data-theme="light"] .subs-card:hover { border-color: rgba(230,26,26,.3); }
193[data-theme="light"] .subs-card.selected { border-color: var(--p5); background: rgba(255,255,255,.85); }
194[data-theme="light"] .subs-card-name { color: var(--text); }
195[data-theme="light"] .subs-card-name em { background: rgba(230,26,26,.1); color: var(--p5d); }
196[data-theme="light"] .subs-card-price { color: var(--text); -webkit-text-fill-color: var(--text); }
197[data-theme="light"] .subs-card-price small { color: rgba(26,18,32,.5); }
198[data-theme="light"] .subs-card-d { color: rgba(26,18,32,.6); }
199[data-theme="light"] .subs-card-feats span { color: rgba(26,18,32,.55); background: rgba(0,0,0,.04); }
200[data-theme="light"] .subs-card-feats span svg { color: #0a8f6a; }
201[data-theme="light"] .bloom-foot { background: var(--bg2); }
202[data-theme="light"] .foot-brand { color: var(--text); -webkit-text-fill-color: var(--text); background: none; }
203[data-theme="light"] .foot-tag { color: rgba(26,18,32,.55); }
204[data-theme="light"] .foot-col h4 { color: var(--text); }
205[data-theme="light"] .foot-col a { color: rgba(26,18,32,.55); }
206[data-theme="light"] .foot-col a:hover { color: var(--text); }
207[data-theme="light"] .foot-bottom { border-top-color: rgba(0,0,0,.08); color: rgba(26,18,32,.4); }
208[data-theme="light"] .foot-soc a { background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.08); color: rgba(26,18,32,.5); }
209[data-theme="light"] .foot-soc a:hover { background: rgba(230,26,26,.1); color: var(--p5); border-color: rgba(230,26,26,.25); }
210[data-theme="light"] .nl-inp { background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.1); color: var(--text); }
211[data-theme="light"] .btt { background: var(--p5); border-color: var(--p5d); color: #fff; }
212[data-theme="light"] .overlay .modal { background: #fff; border-color: rgba(0,0,0,.1); }
213[data-theme="light"] .m-cls { background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.1); color: var(--text); }
214[data-theme="light"] .m-sub { color: rgba(26,18,32,.6); }
215[data-theme="light"] .fi-lbl { color: rgba(26,18,32,.6); }
216[data-theme="light"] .fi-inp { background: rgba(0,0,0,.03); border-color: rgba(0,0,0,.1); color: var(--text); }
217[data-theme="light"] .div-lbl { color: rgba(26,18,32,.4); }
218[data-theme="light"] .div-lbl::before, [data-theme="light"] .div-lbl::after { background: rgba(0,0,0,.1); }
219[data-theme="light"] .a-tab { color: rgba(26,18,32,.55); }
220[data-theme="light"] .occ-btn { border-color: rgba(0,0,0,.1); background: rgba(0,0,0,.02); color: rgba(26,18,32,.7); }
221[data-theme="light"] .occ-btn:hover { border-color: rgba(230,26,26,.3); background: rgba(230,26,26,.05); color: var(--text); }
222[data-theme="light"] .occ-btn.selected { border-color: var(--p5); background: rgba(230,26,26,.08); color: var(--text); }
223[data-theme="light"] .pw-tog { color: rgba(26,18,32,.5); }
224[data-theme="light"] .pw-tog:hover { color: var(--text); }
225[data-theme="light"] .fpl-btn { color: rgba(26,18,32,.55); }
226[data-theme="light"] .fpl-btn:hover { color: var(--p5); }
227[data-theme="light"] .str-lbl { color: rgba(26,18,32,.5); }
228[data-theme="light"] .toast { background: rgba(255,255,255,.96); border-color: rgba(0,0,0,.1); color: var(--text); box-shadow: 0 10px 40px rgba(0,0,0,.12); }
229[data-theme="light"] .cat-tab { border-color: rgba(0,0,0,.08); background: rgba(0,0,0,.03); color: rgba(26,18,32,.72); }
230[data-theme="light"] .cat-tab:hover { color: var(--text); }
231[data-theme="light"] .cat-tab.active { color: #fff; background: linear-gradient(135deg, var(--p5d), var(--p5)); border-color: var(--p5); }
232[data-theme="light"] .wl-btn { background: rgba(0,0,0,.03); border-color: rgba(0,0,0,.08); color: rgba(26,18,32,.45); }
233[data-theme="light"] .bloom-academic-badge { background: linear-gradient(135deg, rgba(254,252,249,.96), rgba(245,240,235,.96)); border-top-color: rgba(0,0,0,.08); color: rgba(26,18,32,.6); }
234[data-theme="light"] .bloom-academic-badge-close { color: rgba(26,18,32,.4); }
235[data-theme="light"] .bloom-academic-badge-close:hover { color: var(--text); }
236[data-theme="light"] .p5-sec-div { background: linear-gradient(90deg, transparent, rgba(230,26,26,.25), transparent); }
237[data-theme="light"] .delivery-bar { background: rgba(255,255,255,.95); color: rgba(26,18,32,.6); border-bottom-color: rgba(0,0,0,.08); }
238[data-theme="light"] .delivery-pill { background: rgba(230,26,26,.08); border-color: rgba(230,26,26,.2); color: var(--p5d); }
239[data-theme="light"] .dlv-fld { background: rgba(0,0,0,.03); border-color: rgba(0,0,0,.08); }
240[data-theme="light"] .dlv-fld input, [data-theme="light"] .dlv-fld select { color: var(--text); }
241[data-theme="light"] .dlv-fld label { color: rgba(26,18,32,.5); }
242[data-theme="light"] .dlv-eta { color: #0a8f6a; }
243[data-theme="light"] .hc-card { background: rgba(255,255,255,.6); border-color: rgba(0,0,0,.08); }
244[data-theme="light"] .hc-card:hover { border-color: rgba(230,26,26,.25); box-shadow: 0 8px 32px rgba(0,0,0,.06); }
245[data-theme="light"] .hc-title { color: var(--text); }
246[data-theme="light"] .hc-desc { color: rgba(26,18,32,.55); }
247[data-theme="light"] .hc-status { color: rgba(26,18,32,.5); }
248[data-theme="light"] .hero-hl { color: var(--text); text-shadow: none; }
249[data-theme="light"] .hero-sub { color: rgba(26,18,32,.65); text-shadow: none; }
250[data-theme="light"] .hero-eyebrow-sub { color: rgba(26,18,32,.5); }
251[data-theme="light"] .g-txt { background: linear-gradient(135deg, var(--p5d) 0%, var(--p5) 50%, var(--pk2) 100%); background-size: 250% auto; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
252[data-theme="light"] .trust-item { color: rgba(26,18,32,.5); }
253[data-theme="light"] .trust-item svg { color: #0a8f6a; }
254[data-theme="light"] .hero-countdown { background: rgba(230,26,26,.06); border-color: rgba(230,26,26,.18); }
255[data-theme="light"] .cd-lbl { color: rgba(26,18,32,.5); }
256[data-theme="light"] .cd-num { color: var(--p5d); }
257[data-theme="light"] .corp-list li { color: rgba(26,18,32,.65); }
258[data-theme="light"] .corp-list svg { color: #0a8f6a; }
259[data-theme="light"] .sec-title { color: var(--text); }
260[data-theme="light"] .sec-sub { color: rgba(26,18,32,.72); }
261[data-theme="light"] .tag-p { color: #A81010; }
262[data-theme="light"] .voice-fab { box-shadow: 0 8px 24px rgba(230,26,26,.3); }
263[data-theme="light"] .p-price { color: #a97800; }
264[data-theme="light"] .p-stars span { color: #d4940a; }
265[data-theme="light"] ::-webkit-scrollbar-track { background: var(--bg); }
266::-webkit-scrollbar { width: 6px; height: 6px; }
267::-webkit-scrollbar-track { background: var(--bg); }
268::-webkit-scrollbar-thumb { background: linear-gradient(var(--p5), var(--pk)); border-radius: 2px; }
269a { text-decoration: none; color: inherit; }
270button { font-family: var(--fb); background: none; border: none; color: inherit; }
271input, textarea, select { font-family: var(--fb); }
272img { max-width: 100%; display: block; }
273:focus-visible { outline: 2px solid var(--p5l); outline-offset: 3px; border-radius: 4px; }
274.sr { position: absolute; width:
274 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
275.c-dot { width: 8px; height: 8px; background: #fff; border-radius: 50%; position: fixed; pointer-events: none; z-index: 99999; transform: translate3d(-50%,-50%,0); transition: width .2s, height .2s, background .2s; will-change: transform; }
276.c-ring { width: 36px; height: 36px; border: 1.5px solid rgba(255,255,255,.45); border-radius: 50%; position: fixed; pointer-events: none; z-index: 99998; transform: translate3d(-50%,-50%,0); transition: transform .16s var(--ease), width .28s, height .28s, border-color .28s; will-change: transform; }
277body.c-hover .c-dot { width: 14px; height: 14px; background: var(--p5); }
278body.c-hover .c-ring { width: 52px; height: 52px; border-color: rgba(230,26,26,.7); }
279@media (pointer: coarse), (hover: none) { .c-dot, .c-ring { display: none !important; } }
280#sbar { position: fixed; top: 0; left: 0; height: 3px; background: linear-gradient(90deg, var(--p5), var(--pk), var(--mn)); transform-origin: 0 50%; width: 100%; z-index: 9999; box-shadow: 0 0 10px rgba(230,26,26,.5); transform: scaleX(0); }
281@supports (animation-timeline: scroll()) {
282  #sbar { animation: sb-grow linear both; animation-timeline: scroll(root); }
283  @keyframes sb-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
284}
285.skip { position: fixed; top: -80px; left: 20px; z-index: 99990; padding: 10px 20px; background: var(--p5); color: #fff; border-radius: 8px; font-weight: 700; transition: top .2s; text-decoration: none; }
286.skip:focus { top: 20px; }
287.con { max-width: 1280px; margin: 0 auto; padding: 0 40px; }
288@media (max-width: 768px) { .con { padding: 0 20px; } }
289.p5-slash { position: absolute; width: 3px; background: var(--p5); border-radius: 2px; transform: rotate(-18deg); pointer-events: none; }
290.p5-diamond { position: absolute; width: 8px; height: 8px; background: var(--p5); transform: rotate(45deg); pointer-events: none; }
291.p5-label { font-family: var(--fc); font-weight: 900; font-style: italic; font-size: .7rem; letter-spacing: .15em; text-transform: uppercase; color: var(--p5); }
292.p5-splat { position: absolute; pointer-events: none; width: 120px; height: 120px; filter: drop-shadow(0 0 10px rgba(230,26,26,.4)); }
293#nav { position: fixed; top: 0; left: 0; right: 0; z-index: 1000; height: 68px; display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 0 40px; transition: background .4s, backdrop-filter .4s; }
294#nav::after { content: ''; position: absolute; bottom: 0; left: -2%; right: -2%; height: 2px; background: linear-gradient(90deg, transparent, var(--p5), var(--pk), transparent); opacity: 0; transition: opacity .4s; transform: skewY(-0.8deg); filter: drop-shadow(0 0 4px rgba(230,26,26,.4)); }
295#nav.sc { background: rgba(11,5,22,.88); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); }
296#nav.sc::after { opacity: 1; }
297.n-logo { font-family: var(--fd); font-size: 1.3rem; font-weight: 900; letter-spacing: -.03em; background: linear-gradient(135deg, #fff 0%, var(--pk) 60%, var(--p5) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; position: relative; flex-shrink: 0; }
298.n-logo::before { content: '//'; font-family: var(--fc); font-style: italic; font-size: .7rem; position: absolute; top: -4px; left: -14px; color: var(--p5); opacity: .8; -webkit-text-fill-color: var(--p5); }
299.n-links { display: flex; align-items: center; gap: 2px; list-style: none; }
300.n-links a { padding: 8px 14px; border-radius: var(--rx); font-size: .85rem; font-weight: 500; color: rgba(255,255,255,.6); transition: all .2s; position: relative; }
301.n-links a:hover, .n-links a:focus-visible { color: #fff; background: var(--gl); }
302.n-links a::after { content: attr(data-label); font-family: var(--fc); font-style: italic; font-weight: 900; font-size: .6rem; color: var(--p5); position: absolute; top: 2px; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity .2s; pointer-events: none; letter-spacing: .1em; text-transform: uppercase; }
303.n-links a:hover::after, .n-links a:focus-visible::after { opacity: 1; }
304.n-acts { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
305.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 20px; border-radius: var(--rs); font-family: var(--fb); font-size: .86rem; font-weight: 600; transition: transform .25s var(--ease), box-shadow .25s var(--ease), background .2s; position: relative; overflow: hidden; white-space: nowrap; }
306.btn::before { content: ''; position: absolute; inset: 0; background: rgba(255,255,255,0); transition: background .2s; pointer-events: none; }
307.btn:hover::before, .btn:focus-visible::before { background: rgba(255,255,255,.06); }
308.btn-p { background: linear-gradient(135deg, var(--p5d), var(--p5)); color: #fff; box-shadow: 0 4px 20px rgba(230,26,26,.35); }
309.btn-p:hover, .btn-p:focus-visible { transform: translateY(-2px); box-shadow: 0 8px 28px rgba(230,26,26,.5); }
310.btn-g { background: var(--gl); border: 1px solid var(--glb); color: rgba(255,255,255,.75); }
311.btn-g:hover, .btn-g:focus-visible { background: rgba(255,255,255,.1); color: #fff; }
312.btn-sm { padding: 8px 14px; font-size: .8rem; height: 36px; }
313.btn-lg { padding: 13px 30px; font-size: .95rem; border-radius: var(--r); }
314.cart-wrap { position: relative; }
315.cart-badge { position: absolute; top: -6px; right: -6px; background: var(--p5); color: #fff; font-size: .62rem; font-weight: 700; min-width: 16px; height: 16px; border-radius: 100px; display: inline-flex; align-items: center; justify-content: center; padding: 0 4px; }
316.n-srch-wrap { position: relative; }
317.n-srch-panel { position: absolute; top: 120%;
317 right: 0; width: min(340px, 90vw); background: rgba(11,5,22,.97); border: 1px solid var(--glb); border-radius: var(--r); padding: 12px; z-index: 200; opacity: 0; pointer-events: none; transform: translateY(-8px) scale(.97); transition: all .22s var(--ease); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); }
318.n-srch-panel.open { opacity: 1; pointer-events: all; transform: none; }
319.n-srch-inp { width: 100%; background: var(--gl); border: 1px solid var(--glb); border-radius: var(--rs); padding: 10px 14px; color: #fff; font-size: .88rem; outline: none; transition: border-color .2s; }
320.n-srch-inp:focus { border-color: var(--p5); box-shadow: 0 0 0 3px rgba(230,26,26,.12); }
321.srch-item { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border-radius: var(--rs); color: #fff; transition: background .15s; width: 100%; text-align: left; font-size: .85rem; }
322.srch-item:hover, .srch-item:focus-visible { background: var(--gl); }
323.srch-item mark { background: rgba(230,26,26,.3); color: #fff; border-radius: 3px; padding: 0 2px; }
324.lang-dd { position: absolute; top: 110%; right: 0; background: rgba(16,7,30,.97); border: 1px solid var(--glb); border-radius: var(--rs); min-width: 168px; z-index: 100; opacity: 0; pointer-events: none; transform: translateY(-5px) scale(.96); transition: all .18s var(--ease); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); overflow: hidden; list-style: none; }
325.lang-dd.open { opacity: 1; pointer-events: all; transform: none; }
326.lang-opt { padding: 11px 14px; font-size: .86rem; color: rgba(255,255,255,.72); transition: background .15s; display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; }
327.lang-opt:hover, .lang-opt:focus-visible { background: rgba(230,26,26,.14); color: #fff; }
328.hmb { display: none; flex-direction: column; gap: 5px; padding: 6px; border-radius: var(--rx); }
329.hmb span { display: block; width: 20px; height: 2px; background: #fff; border-radius: 2px; transition: all .3s var(--ease); }
330.hmb[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
331.hmb[aria-expanded="true"] span:nth-child(2) { opacity: 0; transform: scaleX(0); }
332.hmb[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
333.mob-menu { position: fixed; inset: 0; z-index: 1500; background: rgba(8,3,16,.97); backdrop-filter: blur(32px); -webkit-backdrop-filter: blur(32px); display: flex; flex-direction: column; align-items: center; justify-content: center; transform: translateX(100%); transition: transform .42s var(--ease); }
334.mob-menu.open { transform: none; }
335.mob-inner { text-align: center; width: 100%; max-width: 300px; }
336.mob-inner ul { list-style: none; display: flex; flex-direction: column; gap: 4px; margin-bottom: 32px; }
337.mob-inner a { color: rgba(255,255,255,.85); font-size: 1.4rem; font-weight: 700; font-family: var(--fd); padding: 13px 22px; display: block; border-radius: var(--r); transition: all .2s; }
338.mob-inner a:hover, .mob-inner a:focus-visible { color: #fff; background: var(--gl); }
339.mob-acts { display: flex; flex-direction: column; gap: 10px; }
340.mob-close { position: absolute; top: 22px; right: 22px; background: var(--gl); border: 1px solid var(--glb); color: #fff; font-size: 1.1rem; width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: all .2s; }
341.mob-close:hover, .mob-close:focus-visible { background: rgba(230,26,26,.2); }
342.hero { min-height: 100dvh; display: flex; align-items: center; position: relative; overflow: hidden; padding-top: 68px; perspective: 1400px; perspective-origin: 50% 50%; background: var(--ethereal-obsidian); }
343.hero-bg { position: absolute; inset: 0; background: radial-gradient(at 0% 0%, hsla(328,100%,15%,0.3) 0, transparent 50%), radial-gradient(at 100% 0%, hsla(272,100%,15%,0.3) 0, transparent 50%); }
344.hero-bg::before { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 20% 30%, var(--ethereal-glow-pink), transparent 50%), radial-gradient(circle at 80% 70%, var(--ethereal-glow-red), transparent 50%); filter: blur(80px); opacity: 0.5; animation: etherealPulse 15s ease-in-out infinite alternate; }
345@keyframes etherealPulse { from { transform: scale(1); opacity: 0.4; } to { transform: scale(1.1); opacity: 0.7; } }
346.hero-photo { position: absolute; top: 0; right: 0; width: 62%; height: 100%; background-image: url('/img/hero-flowers.webp'); background-size: cover; background-position: center center; clip-path: polygon(15% 0, 100% 0, 100% 100%, 0 100%); transform: translate3d(calc(var(--px,0) * 12px), calc(var(--py,0) * 8px), 0) scale(1.04); transition: transform .22s linear; will-change: transform; filter: saturate(1.1) brightness(0.95); }
347.hero-photo::before { content: ''; position: absolute; inset: 0; background: linear-gradient(to right, var(--ethereal-obsidian) 0%, rgba(5,2,10,0.85) 20%, rgba(5,2,10,0.3) 50%, rgba(5,2,10,0.1) 75%, transparent 100%); z-index: 1; }
348.hero-photo::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(5,2,10,0.3) 0%, transparent 20%, transparent 80%, rgba(5,2,10,0.4) 100%); z-index: 1; }
349.hero-slash-1 { position: absolute; left: 42%; top: -5%; width: 4px; height: 110%; background: linear-gradient(to bottom, transparent, var(--p5), var(--pk), transparent); transform: skewX(-8deg) rotate(-3deg); z-index: 3; opacity: .4; pointer-events: none; filter: drop-shadow(0 0 12px var(--p5)); }
350.hero-scanlines { position: absolute; inset: 0; z-index: 5; pointer-events: none; opacity: .08; background: repeating-linear-gradient(0deg, transparent 0, transparent 3px, rgba(255,255,255,.5) 3px, rgba(255,255,255,.5) 4px); mix-blend-mode: overlay; }
351.hero-noise { position: absolute; inset: 0; z-index: 4; pointer-events: none; opacity: .06; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.8'/%3E%3C/svg%3E"); }
352.hero-grid { position: relative; z-index: 4; width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; padding: 80px 0 60px; transform-style: preserve-3d; }
353.hero-left { transform: translate3d(calc(var(--px,0) * -6px), calc(var(--py,0) * -4px), 0); transition: transform .22s linear; will-change: transform; }
354.hero-eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 24px; flex-wrap: wrap; }
355.hero-eyebrow-tag { font-family: var(--fc); font-style: italic; font-weight: 900; font-size: .68rem; letter-spacing: .18em; text-transform: uppercase; color: #fff; background: var(--p5); padding: 5px 14px 5px 16px; position: relative; white-space: nowrap; clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%); transform: skewX(-6deg); }
356.hero-eyebrow-tag > * { transform: skewX(6deg); display: inline-block; }
357.hero-eyebrow-tag::after { display: none; }
358.hero-eyebrow-sub { font-size: .78rem; color: rgba(255,255,255,.62); font-weight: 500; padding-left: 6px; white-space: nowrap; }
359.hero-hl { font-family: var(--fd); font-size: clamp(2.1rem, 5.2vw, 5rem); line-height: 1.15; font-weight: 900; letter-spacing: -.03em; margin-bottom: 24px; padding-bottom: 0.1em; overflow: visible; text-shadow: 0 4px 16px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.3); display: flex; flex-direction: column; align-items: flex-start; gap: 0.02em; }
360.hero-hl em { font-style: italic; font-weight: 400; color: rgba(255,255,255,.85); text-shadow: 0 2px 8px rgba(0,0,0,0.4); }
361.g-txt { background: linear-gradient(135deg, #fff 0%, var(--pk) 35%, var(--p5) 70%, var(--pk) 100%); background-size: 250% auto; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; animation: txt-shine 5s linear infinite; padding-bottom: 0.15em; margin-bottom: -0.15em; display: inline-block; text-shadow: none !important; filter: none !important; }
362#typer { display: inline-grid; align-items: start; justify-items: start; vertical-align: baseline; }
363#typer .g-txt { grid-area: 1/1; opacity: 0; visibility: hidden; transform: translateY(8px); transition: opacity .3s var(--ease), transform .3s var(--ease); }
364#typer .g-txt.active { opacity: 1; visibility: visible; transform: none; }
365@keyframes txt-shine { to { background-position: 250% center; } }
366.hero-sub { font-size: 1.05rem; line-height: 1.72; color: rgba(255,255,255,0.85); max-width: 480px; margin-bottom: 36px; text-wrap: pretty; text-shadow: 0 1px 3px rgba(0,0,0,0.5); }
367.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 36px; }
368.trust { display: flex; flex-wrap: wrap; gap: 18px; }
369.trust-item { display: flex; align-items: center; gap: 7px; font-size: .75rem; font-weight: 500; color: rgba(255,255,255,.58); }
370.trust-item svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--mn); }
371.hero-countdown { display: inline-flex; align-items: center; gap: 14px; margin-bottom: 28px; background: rgba(230,26,26,.1); border: 1px solid rgba(230,26,26,.28); border-radius: 100px; padding: 7px 18px; }
372.cd-lbl { font-family: var(--fc); font-style: italic; font-weight: 700; font-size: .72rem; letter-spacing: .1em; color: rgba(255,255,255,.5); text-transform: uppercase; }
373.cd-units { display: flex; align-items: center; gap: 5px; }
374.cd-num { font-family: var(--fc); font-weight: 900; font-size: 1.1rem; color: var(--p5); min-width: 1.4em; text-align: center; font-variant-numeric: tabular-nums; }
375.cd-sub { font-size: .6rem; color: rgba(255,255,255,.35); display: block; line-height: 1; letter-spacing: .05em; text-transform: uppercase; text-align: center; }
376.cd-sep { color: var(--p5); font-weight: 900; font-family: var(--fc); }
377.hero-cards { position: relative; height: 520px; transform-style: preserve-3d; perspective: 1200px; }
378.h-card { position: absolute; background: linear-gradient(135deg, rgba(255,255,255,.08), rgba(255,255,255,.02)); border: 1px solid rgba(255,255,255,.15); border-radius: 24px; backdrop-filter: blur(24px) saturate(1.2); -webkit-backdrop-filter: blur(24px) saturate(1.2); padding: 22px; transition: box-shadow .4s var(--ease), border-color .4s; transform-style: preserve-3d; will-change: transform; overflow: visible; box-shadow: 0 16px 40px rgba(0,0,0,.2), inset 0 1px 0 rgba(255,255,255,.1); }
379.h-card::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 20px rgba(230,26,26,.05); pointer-events: none; }
380.h-card::before { content: ''; position: absolute; inset: 0; background: radial-gradient(800px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.12), transparent 40%), radial-gradient(400px circle at var(--mx,50%) var(--my,50%), rgba(230,26,26,.15), transparent 40%); opacity: 0; transition: opacity .4s var(--ease); pointer-events: none; border-radius: inherit; z-index: 3; mix-blend-mode: overlay; }
381.h-card:hover::before { opacity: 1; }
382.h-card:hover { box-shadow: 0 32px 80px rgba(168,16,16,.3), inset 0 1px 0 rgba(255,255,255,.2); border-color: rgba(230,26,26,.4); }
383.h-card-img { width: 100%; height: 120px; object-fit: cover; border-radius: 14px; margin-bottom: 12px; transition: transform .6s var(--spring), filter .6s var(--ease); transform: translateZ(20px); filter: brightness(0.95); box-shadow: 0 8px 24px rgba(0,0,0,.2); }
384.h-card:hover .h-card-img { transform: translateZ(40px) scale(1.08); filter: brightness(1.1); box-shadow: 0 16px 32px rgba(230,26,26,.3); }
385.hc-1 { width: 230px; top: 70px; left: 35%; transform: translateX(-50%) translateZ(60px); text-align: center; animation: ag1 8s ease-in-out infinite; z-index: 2; }
386.hc-2 { width: 210px; top: 0px; right: -15px; transform: translateZ(20px); animation: ag2 11s ease-in-out infinite; z-index: 5; }
387.hc-3 { width: 220px; bottom: 10px; left: -15px; transform: translateZ(35px); animation: ag3 9s ease-in-out infinite; z-index: 3; }
388@keyframes ag1 { 0%,100%{transform:translateX(-50%) translateY(0) translateZ(60px) rotate(-2deg) rotateX(4deg)} 50%{transform:translateX(-50%) translateY(-28px) translateZ(80px) rotate(1.5deg) rotateX(-2deg)} }
389@keyframes ag2 { 0%,100%{transform:translateY(0) translateZ(20px) rotate(3deg) rotateY(-4deg)} 50%{transform:translateY(-32px) translateZ(40px) rotate(-1.5deg) rotateY(2deg)} }
390@keyframes ag3 { 0%,100%{transform:translateY(0) translateZ(35px) rotate(-3deg) rotateX(-3deg)} 50%{transform:translateY(-24px) translateZ(55px) rotate(2deg) rotateX(2deg)} }
391.hc-pulse { position: absolute; top: -8px; right: -8px; width: 16px; height: 16px; background: var(--p5); border-radius: 50%; box-shadow: 0 0 12px var(--p5); transform: translateZ(30px); z-index: 5; }
392.hc-pulse::before { content: ''; position: absolute; inset: -6px; border-radius: 50%; background: rgba(230,26,26,.4); animation: ping 2s cubic-bezier(0, 0, 0.2, 1) infinite; }
393@keyframes ping { 0%{transform:scale(0.8);opacity:1} 100%{transform:scale(2.8);opacity:0}
393 }
394.hc-name { font-family: var(--fd); font-size: 1.05rem; font-weight: 700; margin-bottom: 6px; transform: translateZ(15px); text-shadow: 0 2px 8px rgba(0,0,0,.5); line-height: 1.3; }
395.hc-price { font-size: 1.05rem; font-weight: 700; color: var(--gd); transform: translateZ(15px); line-height: 1.3; margin-top: 2px; text-shadow: 0 1px 4px rgba(0,0,0,0.4); }
396.hc-meta { font-size: .75rem; color: rgba(255,255,255,.65); margin-top: 6px; transform: translateZ(10px); line-height: 1.4; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
397.hc-tag { display: inline-block; font-family: var(--fc); font-style: italic; font-weight: 700; font-size: .7rem; color: #fff; background: linear-gradient(135deg, var(--p5), var(--pk)); letter-spacing: .1em; padding: 5px 14px 5px 16px; margin-bottom: 10px; text-transform: uppercase; transform: translateZ(25px) skewX(-6deg); box-shadow: 0 4px 12px rgba(230,26,26,.3); clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%); white-space: nowrap; }
398.hc-sub { font-size: .85rem; font-weight: 600; color: rgba(255,255,255,.8); transform: translateZ(15px); line-height: 1.4; }
399.hc-status { font-size: .8rem; font-weight: 600; color: var(--mn); margin-top: 6px; display: flex; align-items: center; gap: 6px; transform: translateZ(15px); line-height: 1.4; }
400.hc-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--mn); box-shadow: 0 0 10px var(--mn); animation: ping2 2s ease-out infinite; flex-shrink: 0; }
401@keyframes ping2 { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.4;transform:scale(0.8)} }
402canvas#ptcl { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; }
403.stats-strip { background: var(--bg2); border-top: 1px solid var(--glb); border-bottom: 1px solid var(--glb); position: relative; overflow: hidden; margin-left: 0; margin-right: 0; }
404.stats-strip .con { max-width: 100%; width: 100%; padding: 0; margin: 0; }
405.stats-strip::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(230,26,26,.04), rgba(188,49,148,.03)); }
406.stats-inner { display: grid; grid-template-columns: repeat(4, 1fr); position: relative; z-index: 1; width: 100%; }
407.stat-item { padding: 36px 24px; text-align: center; position: relative; }
408.stat-item:not(:last-child)::after { content: ''; position: absolute; right: 0; top: 20%; bottom: 20%; width: 1px; background: var(--glb); }
409.stat-icon { font-size: 1.4rem; margin-bottom: 8px; display: block; }
410.stat-num { font-family: var(--fc); font-style: italic; font-weight: 900; font-size: clamp(1.6rem, 3.4vw, 2.6rem); line-height: 1; margin-bottom: 5px; background: linear-gradient(135deg, #fff, rgba(255,255,255,.68)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-variant-numeric: tabular-nums; }
411.stat-bar { height: 3px; max-width: 140px; background: rgba(255,255,255,.07); border-radius: 2px; margin: 12px auto 0; overflow: hidden; }
412.stat-bar-fill { height: 100%; width: 0; border-radius: 2px; background: linear-gradient(90deg, var(--p5), var(--pk)); transition: width 1.8s var(--ease); }
413.stat-lbl { font-family: var(--fc); font-style: italic; font-size: .72rem; letter-spacing: .12em; color: rgba(255,255,255,.58); text-transform: uppercase; margin-top: 10px; }
414.stat-src { font-size: .62rem; color: rgba(255,255,255,.48); margin-top: 6px; letter-spacing: .05em; }
415.stat-src a { color: rgba(255,255,255,.5); border-bottom: 1px dotted rgba(255,255,255,.2); }
416.stat-src a:hover { color: var(--p5l); border-bottom-color: var(--p5); }
417.bloom-academic-badge { position: fixed; bottom: 0; left: 0; right: 0; z-index: 99998; background: linear-gradient(135deg, rgba(5,2,10,0.95), rgba(30,10,40,0.95)); backdrop-filter: blur(12px); border-top: 1px solid rgba(230,26,26,.2); padding: 8px 16px; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: .72rem; color: rgba(255,255,255,.55); letter-spacing: .03em; text-align: center; line-height: 1.5; }
418.bloom-academic-badge span { color: var(--p5l); font-weight: 600; }
419.bloom-academic-badge-close { background: none; border: none; color: rgba(255,255,255,.4); cursor: pointer; font-size: 1rem; padding: 0 4px; margin-left: 8px; }
420.bloom-academic-badge-close:hover { color: #fff; }
421.ai-gen-label { position: absolute; top: 8px; left: 8px; z-index: 5; display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px; border-radius: 6px; background: rgba(0,0,0,.65); backdrop-filter: blur(6px); border: 1px solid rgba(255,255,255,.1); font-size: .62rem; font-weight: 600; color: rgba(255,255,255,.7); letter-spacing: .06em; text-transform: uppercase; pointer-events: none; }
422.sec-pad { padding: 96px 0; }
423.sec-hd { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 48px; flex-wrap: wrap; gap: 16px; }
424.sec-title { font-family: var(--fd); font-size: clamp(1.7rem, 3.2vw, 2.6rem); font-weight: 900; line-height: 1.1; letter-spacing: -.03em; text-wrap: balance; }
425.sec-sub { font-size: .9rem; color: rgba(255,255,255,.78); line-height: 1.7; margin-top: 8px; max-width: 440px; text-wrap: pretty; }
426.tag { display: inline-flex; align-items: center; gap: 6px; font-family: var(--fc); font-style: italic; font-weight: 700; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; padding: 5px 16px 5px 18px; margin-bottom: 12px; transform: skewX(-6deg); clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%); white-space: nowrap; }
427.tag-p { background: rgba(230,26,26,.15); border: 1px solid rgba(230,26,26,.3); color: #FFB3B3; }
428.tag-m { background: rgba(0,212,170,.12); border: 1px solid rgba(0,212,170,.25); color: var(--mn); }
429.tag-a { background: rgba(124,58,237,.14); border: 1px solid rgba(124,58,237,.3); color: #a78bfa; }
430.cat-wrap { display: flex; align-items: center; gap: 8px; margin-bottom: 46px; }
431.cat-tabs { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding: 3px 0; scroll-behavior: smooth; }
432.cat-tabs::-webkit-scrollbar { display: none; }
433.cat-tab { padding: 8px 18px; border-radius: 100px; font-family: var(--fc); font-style: italic; font-weight: 700; font-size: .84rem; letter-spacing: .05em; border: 1px solid var(--glb); background: var(--gl); color: rgba(255,255,255,.82); white-space: nowrap; transition: all .22s var(--ease); flex-shrink: 0; text-transform: uppercase; }
434.cat-tab:hover, .cat-tab:focus-visible { background: rgba(255,255,255,.08); color: rgba(255,255,255,.78); }
435.cat-tab.active { background: linear-gradient(135deg, rgba(230,26,26,.22), rgba(188,49,148,.15)); border-color: rgba(230,26,26,.45); color: #fff; }
436.cat-cnt { font-size: .7rem; color: rgba(255,255,255,.38); margin-left: 3px; font-style: normal; font-weight: 400; }
437.cat-arrow { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: var(--gl); border: 1px solid var(--glb); color: #fff; flex-shrink: 0; transition: all .2s; font-size: 1rem; }
438.cat-arrow:hover, .cat-arrow:focus-visible { background: rgba(255,255,255,.14); }
439.cat-arrow:disabled { opacity: .3; }
440.p-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; min-height: 280px; perspective: 1000px; }
441.p-card { background: var(--gl); border: 1px solid var(--glb); border-radius: var(--r); padding: 20px; position: relative; transform-style: preserve-3d; opacity: 0; transition: box-shadow .5s var(--spring), border-color .4s, opacity .5s, transform .5s var(--spring); }
442.p-card.vis { opacity: 1; }
443.p-card:hover { border-color: rgba(230,26,26,.4); box-shadow: 0 24px 60px rgba(168,16,16,.3), inset 0 1px 0 rgba(255,255,255,.1); z-index: 10; }
444.p-shine { position: absolute; inset: 0; border-radius: var(--r); background: radial-gradient(circle at 50% -20%, rgba(255,255,255,.15) 0%, transparent 60%); opacity: 0; transition: opacity .4s; pointer-events: none; }
445.p-card:hover .p-shine { opacity: 1; }
446.p5-corner { position: absolute; top: 0; left: 0; width: 0; height: 0; border-top: 28px solid var(--p5); border-right: 28px solid transparent; border-radius: var(--r) 0 0 0; opacity: 0; transition: opacity .4s; }
447.p-card:hover .p5-corner { opacity: .8; filter: drop-shadow(2px 2px 4px rgba(230,26,26,.5)); }
448.p-badge { position: absolute; top: 10px; left: 10px; background: linear-gradient(135deg, var(--p5), var(--pk)); color: #fff; font-family: var(--fc); font-style: italic; font-weight: 900; font-size: .66rem; padding: 4px 12px 4px 14px; letter-spacing: .05em; text-transform: uppercase; z-index: 2; transform: translateZ(20px) skewX(-6deg); box-shadow: 0 4px 10px rgba(230,26,26,.3); clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%); white-space: nowrap; }
449.wl-btn { position: absolute; top: 10px; right: 10px; background: rgba(255,255,255,.07); border: 1px solid var(--glb); border-radius: 50%; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,.4); transition: all .3s var(--spring); z-index: 2; transform: translateZ(20px); backdrop-filter: blur(4px); }
450.wl-btn:hover, .wl-btn:focus-visible, .wl-btn.on { color: #fff; background: linear-gradient(135deg, var(--p5d), var(--p5)); border-color: transparent; box-shadow: 0 4px 12px rgba(230,26,26,.4); transform: translateZ(25px) scale(1.1); }
451.wl-pop { animation: wpop .5s var(--spring); }
452@keyframes wpop { 0%{transform:translateZ(20px) scale(1)} 50%{transform:translateZ(30px) scale(1.4)} 100%{transform:translateZ(25px) scale(1.1)} }
453.p-img { height: 180px; border-radius: 14px; overflow: hidden; background: rgba(230,26,26,.05); margin-bottom: 14px; position: relative; transform: translateZ(15px); transition: transform .4s var(--spring), box-shadow .4s; }
454.p-card:hover .p-img { transform: translateZ(30px); box-shadow: 0 12px 24px rgba(0,0,0,.3); }
455.p-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease), filter .8s var(--ease); filter: brightness(0.9); }
456.p-card:hover .p-img img { transform: scale(1.1); filter: brightness(1.05); }
457.p-img-ph { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: rgba(230,26,26,.35); font-size: 2.4rem; }
458.p-name { font-family: var(--fd); font-size: 1.05rem; font-weight: 700; margin-bottom: 4px; line-height: 1.3; transform: translateZ(20px); transition: transform .4s var(--spring), text-shadow .4s; }
459.p-card:hover .p-name { transform: translateZ(35px); text-shadow: 0 2px 4px rgba(0,0,0,.4); }
460.p-cat { font-family: var(--fc); font-style: italic; font-size: .75rem; color: rgba(255,255,255,.5); letter-spacing: .05em; text-transform: uppercase; margin-bottom: 8px; transform: translateZ(10px); transition: transform .4s var(--spring); }
461.p-card:hover .p-cat { transform: translateZ(25px); color: rgba(255,255,255,.7); }
462.p-stars { display: flex; gap: 1px; margin-bottom: 10px; font-size: .88rem; }
463.p-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
464.p-price { font-family: var(--fc); font-weight: 900; color: var(--gd); font-size: 1.1rem; font-variant-numeric: tabular-nums; }
465.p-add { background: linear-gradient(135deg, var(--p5d), var(--p5)); color: #fff; padding: 6px 14px; border-radius: 8px; font-size: .78rem; font-weight: 700; letter-spacing: .03em; transition: transform .2s, box-shadow .2s; }
466.p-add:hover, .p-add:focus-visible { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(230,26,26,.45); }
467.p-add:disabled { opacity: .5; }
468.p-empty { grid-column: 1 / -1; text-align: center; padding: 60px 20px; color: rgba(255,255,255,.45); font-size: .9rem; }
469.p-err { grid-column: 1 / -1; text-align: center; padding: 60px 20px; color: var(--cr); font-size: .9rem; }
470.p-skel { background: var(--gl); border: 1px solid var(--glb); border-radius: var(--r); padding: 20px; }
471.p-skel-img { height: 180px; border-radius: 14px; background: linear-gradient(90deg, var(--gl) 0%, rgba(255,255,255,.08) 50%, var(--gl) 100%); background-size: 200% 100%; animation: sk 1.4s ease-in-out infinite; margin-bottom: 14px; }
472.p-skel-t { height: 14px; border-radius: 4px; background: var(--gl); animation: sk 1.4s ease-in-out infinite; background-size: 200% 100%; background-image: linear-gradient(90deg, var(--gl) 0%, rgba(255,255,255,.08) 50%, var(--gl) 100%); margin-bottom: 8px; width: 70%; }
473.p-skel-s { height: 10px; border-radius: 4px; background: var(--gl); animation: sk 1.4s ease-in-out infinite; background-size: 200% 100%; background-image: linear-gradient(90deg, var(--gl) 0%, rgba(255,255,255,.08) 50%, var(--gl) 100%); width: 40%; }
474@keyframes sk { 0%{background-position:200% 0} 100%{background-position:-200% 0} }
475.feat-sec { background: var(--bg2); position: relative; overflow: hidden; perspective: 1200px; }
476.feat-sec::before { content: ''; position: absolute; top: -100px; left: 50%; transform: translateX(-50%); width: 700px; height: 700px; background: radial-gradient(circle, rgba(230,26,26,.08), transparent 60%); pointer-events: none; mix-blend-mode: screen; animation: p5GlowPulse 8s ease-in-out infinite; }
477.feat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; position: relative; z-index: 1; }
478.feat-card { background: linear-gradient(135deg, rgba(255,255,255,.04), rgba(255,255,255,.01)); border: 1px solid rgba(255,255,255,.08); border-radius: var(--r); padding: 32px 28px; position: relative; transition: transform .5s var(--spring), border-color .4s, box-shadow .5s, background .4s; opacity: 0; transform: translateY(30px) rotateX(10deg); transform-style: preserve-3d; }
479.feat-card.vis { opacity: 1; transform: translateY(0) rotateX(0); }
480.feat-card:hover { transform: translateY(-10px) translateZ(30px) rotateX(4deg); border-color: rgba(230,26,26,.4); box-shadow: 0 24px 60px rgba(168,16,16,.25), inset 0 1px 0 rgba(255,255,255,.1); background: linear-gradient(135deg, rgba(230,26,26,.08), rgba(255,255,255,.02)); z-index: 10; }
481.feat-ico { width: 56px; height: 56px; border-radius: 14px; background: linear-gradient(135deg, rgba(230,26,26,.25), rgba(188,49,148,.15)); border: 1px solid rgba(230,26,26,.4); display: flex; align-items: center; justify-content: center; margin-bottom: 24px; color: var(--p5l); transform: translateZ(20px); transition: transform .4s var(--spring), box-shadow .4s, background .4s; box-shadow: 0 8px 20px rgba(230,26,26,.15); }
482.feat-card:hover .feat-ico { transform: translateZ(40px) scale(1.1); box-shadow: 0 12px 28px rgba(230,26,26,.35); background: linear-gradient(135deg, var(--p5d), var(--p5)); color: #fff; border-color: transparent; }
483.feat-ico svg { width: 24px; height: 24px; }
484.feat-t { font-family: var(--fd); font-size: 1.15rem; font-weight: 700; margin-bottom: 12px; transform: translateZ(15px); transition: transform .4s var(--spring); }
485.feat-card:hover .feat-t { transform: translateZ(30px); text-shadow: 0 2px 4px rgba(0,0,0,.3); }
486.feat-d { font-size: .88rem; color: rgba(255,255,255,.6); line-height: 1.7; transform: translateZ(5px); transition: transform .4s var(--spring), color .4s; }
487.feat-card:hover .feat-d { transform: translateZ(20px); color: rgba(255,255,255,.8); }
488.rev-sec { background: var(--bg); }
489.rev-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
490.rev-card { background: var(--gl); border: 1px solid var(--glb); border-radius: var(--r); padding: 28px; position: relative; opacity: 0; transform: translateY(16px); transition: opacity .5s var(--ease), transform .5s var(--ease); }
491.rev-card.vis { opacity: 1; transform: translateY(0); }
492.rev-card::before { content: '"'; position: absolute; top: 14px; right: 22px; font-family: var(--fd); font-size: 4rem; color: rgba(230,26,26,.18); line-height: 1; font-weight: 900; }
493.rev-stars { display: flex; gap: 2px; margin-bottom: 14px; font-size: .95rem; }
494.rev-body { font-size: .9rem; line-height: 1.7; color: rgba(255,255,255,.76); margin-bottom: 18px; text-wrap: pretty; }
495.rev-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
496.rev-name { font-family: var(--fd); font-weight: 700; font-size: .9rem; }
497.rev-role { font-size: .72rem; color: rgba(255,255,255,.4); margin-top: 2px; }
498.rev-mob { display: none; align-items: center; justify-content: center; gap: 12px
498; margin-top: 22px; }
499.rev-navb { width: 36px; height: 36px; border-radius: 50%; background: var(--gl); border: 1px solid var(--glb); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1rem; }
500.rev-navb:hover, .rev-navb:focus-visible { background: rgba(230,26,26,.16); }
501.rev-dots { display: flex; gap: 6px; }
502.rev-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--glb); transition: background .2s, width .2s; }
503.rev-dot.active { background: var(--p5); width: 24px; border-radius: 4px; }
504.facts-sec { background: var(--bg3); border-top: 1px solid var(--glb); border-bottom: 1px solid var(--glb); position: relative; }
505.facts-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
506.fact-card { padding: 28px 28px 28px 32px; border-radius: var(--r); background: var(--gl); border: 1px solid var(--glb); position: relative; overflow: hidden; }
507.fact-card::before { content: ''; position: absolute; top: -4px; left: 0; width: 4px; height: calc(100% + 8px); background: linear-gradient(to bottom, var(--p5), var(--pk)); transform: skewY(-4deg); }
508.fact-k { font-family: var(--fc); font-style: italic; font-weight: 900; font-size: 2.4rem; line-height: 1; color: #fff; margin-bottom: 8px; }
509.fact-t { font-family: var(--fd); font-weight: 700; font-size: 1rem; margin-bottom: 10px; }
510.fact-d { font-size: .82rem; color: rgba(255,255,255,.58); line-height: 1.7; margin-bottom: 12px; }
511.fact-src { font-size: .7rem; color: rgba(255,255,255,.4); }
512.fact-src a { color: rgba(255,255,255,.58); border-bottom: 1px dotted rgba(255,255,255,.2); }
513.fact-src a:hover, .fact-src a:focus-visible { color: var(--p5l); border-bottom-color: var(--p5); }
514.corp-sec { background: var(--bg); }
515.corp-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 60px; align-items: start; }
516.corp-photo { border-radius: var(--r); overflow: hidden; aspect-ratio: 4/3; position: relative; background: var(--gl); min-height: 320px; }
517.corp-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
518.corp-photo::after { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, transparent 50%, rgba(230,26,26,.2) 100%); }
519.corp-list { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 24px; margin-bottom: 28px; }
520.corp-list li { display: flex; align-items: flex-start; gap: 12px; font-size: .9rem; color: rgba(255,255,255,.72); line-height: 1.6; }
521.corp-list svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--mn); margin-top: 3px; }
522.bloom-foot { background: var(--ink); padding: 72px 0 32px; border-top: 1px solid var(--glb); }
523.foot-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 48px; }
524.foot-brand { font-family: var(--fd); font-size: 1.4rem; font-weight: 900; margin-bottom: 14px; background: linear-gradient(135deg, #fff 0%, var(--pk) 60%, var(--p5) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
525.foot-tag { font-size: .85rem; color: rgba(255,255,255,.54); line-height: 1.7; margin-bottom: 18px; max-width: 340px; text-wrap: pretty; }
526.nl-form { display: flex; gap: 8px; max-width: 340px; align-items: stretch; height: 40px; }
527.nl-inp { flex: 1; background: var(--gl); border: 1px solid var(--glb); border-radius: var(--rs); padding: 0 14px; color: #fff; font-size: .86rem; outline: none; transition: border-color .2s; height: 100%; }
528.nl-form .btn { height: 100%; padding: 0 18px; align-items: center; }
529.nl-inp:focus { border-color: var(--p5); box-shadow: 0 0 0 3px rgba(230,26,26,.12); }
530.foot-col h4 { font-family: var(--fd); font-size: .95rem; font-weight: 700; margin-bottom: 16px; }
531.foot-col ul { list-style: none; display: flex; flex-direction: column; gap: 10px; }
532.foot-col a { font-size: .82rem; color: rgba(255,255,255,.52); transition: color .2s; }
533.foot-col a:hover, .foot-col a:focus-visible { color: var(--p5l); }
534.foot-bottom { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-top: 24px; border-top: 1px solid var(--glb); font-size: .76rem; color: rgba(255,255,255,.4); flex-wrap: wrap; }
535.foot-soc { display: flex; gap: 10px; }
536.foot-soc a { width: 34px; height: 34px; border-radius: 50%; background: var(--gl); border: 1px solid var(--glb); display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,.6); transition: all .2s; }
537.foot-soc a:hover, .foot-soc a:focus-visible { background: rgba(230,26,26,.16); color: #fff; border-color: rgba(230,26,26,.4); }
538.foot-soc svg { width: 14px; height: 14px; }
539.btt { position: fixed; bottom: 28px; right: 28px; width: 46px; height: 46px; border-radius: 50%; background: linear-gradient(135deg, var(--p5d), var(--p5)); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.1rem; opacity: 0; pointer-events: none; transition: all .3s var(--ease); z-index: 900; box-shadow: 0 6px 20px rgba(230,26,26,.35); }
540.btt.vis { opacity: 1; pointer-events: all; }
541.btt:hover, .btt:focus-visible { transform: translateY(-4px); box-shadow: 0 10px 28px rgba(230,26,26,.55); }
542.overlay { position: fixed; inset: 0; z-index: 2000; background: rgba(6,2,14,.82); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); display: none; align-items: center; justify-content: center; padding: 20px; }
543.overlay.open { display: flex; animation: ofade .22s var(--ease); }
544@keyframes ofade { from{opacity:0}
544 to{opacity:1} }
545.modal { background: linear-gradient(180deg, var(--bg2), var(--bg)); border: 1px solid var(--glb); border-radius: var(--r); padding: 36px; max-width: 440px; width: 100%; position: relative; animation: mpop .32s var(--spring); max-height: 90vh; overflow-y: auto; }
546@keyframes mpop { from{opacity:0;transform:translateY(20px) scale(.96)} to{opacity:1;transform:none} }
547.m-hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
548.m-cls { background: var(--gl); border: 1px solid var(--glb); color: #fff; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: .9rem; transition: all .2s; }
549.m-cls:hover, .m-cls:focus-visible { background: rgba(230,26,26,.2); }
550.m-sub { font-size: .9rem; color: rgba(255,255,255,.6); margin-bottom: 22px; line-height: 1.6; }
551.sl-btn { width: 100%; justify-content: center; margin-bottom: 16px; background: #fff; color: var(--ink); }
552.sl-btn:hover { background: rgba(255,255,255,.92); }
553.div-lbl { text-align: center; font-size: .75rem; color: rgba(255,255,255,.4); margin: 16px 0; position: relative; letter-spacing: .1em; text-transform: uppercase; }
554.div-lbl::before, .div-lbl::after { content: ''; position: absolute; top: 50%; width: calc(50% - 30px); height: 1px; background: var(--glb); }
555.div-lbl::before { left: 0; }
556.div-lbl::after { right: 0; }
557.fi { margin-bottom: 14px; }
558.fi-lbl { display: block; font-size: .78rem; color: rgba(255,255,255,.64); margin-bottom: 6px; font-weight: 500; }
559.fi-wrap { position: relative; }
560.fi-inp { width: 100%; background: var(--gl); border: 1px solid var(--glb); border-radius: var(--rs); padding: 11px 14px; color: #fff; font-size: .9rem; outline: none; transition: border-color .2s; }
561.fi-inp:focus { border-color: var(--p5); box-shadow: 0 0 0 3px rgba(230,26,26,.12); }
562.fi-inp[aria-invalid="true"] { border-color: var(--cr); }
563.fe { font-size: .72rem; color: var(--cr); margin-top: 5px; display: block; min-height: 14px; }
564.pw-tog { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); color: rgba(255,255,255,.5); font-size: .75rem; padding: 4px 8px; }
565.pw-tog:hover { color: #fff; }
566.fpl-btn { font-size: .76rem; color: rgba(255,255,255,.6); margin-bottom: 12px; padding: 0; }
567.fpl-btn:hover, .fpl-btn:focus-visible { color: var(--p5l); }
568.str-bar { height: 3px; background: var(--gl); border-radius: 2px; overflow: hidden; margin-top: 6px; margin-bottom: 4px; }
569.str-fill { height: 100%; width: 0; transition: width .3s, background .3s; }
570.str-lbl { font-size: .7rem; color: rgba(255,255,255,.5); }
571.a-tabs { display: flex; gap: 3px; background: var(--gl); border-radius: var(--rs); padding: 3px; margin-bottom: 22px; }
572.a-tab { flex: 1; padding: 8px 14px; border-radius: 9px; font-size: .82rem; font-weight: 600; color: rgba(255,255,255,.55); transition: all .2s; }
573.a-tab.active { background: linear-gradient(135deg, var(--p5d), var(--p5)); color: #fff; box-shadow: 0 4px 14px rgba(230,26,26,.3); }
574.occ-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 20px 0; }
575.occ-btn { padding: 18px 14px; border-radius: var(--rs); border: 1.5px solid var(--glb); background: var(--gl); color: rgba(255,255,255,.8); font-size: .9rem; font-weight: 600; transition: all .24s var(--spring); text-align: center; line-height: 1.3; }
576.occ-btn:hover, .occ-btn:focus-visible { border-color: rgba(230,26,26,.45); background: rgba(230,26,26,.1); color: #fff; transform: translateY(-2px); }
577.occ-btn.selected { border-color: var(--p5); background: linear-gradient(135deg, rgba(230,26,26,.18), rgba(168,16,16,.1)); color: #fff; box-shadow: 0 0 0 3px rgba(230,26,26,.18); }
578.occ-emj { font-size: 1.4rem; display: block; margin-bottom: 6px; }
579.toast-con { position: fixed; top: 88px; right: 24px; z-index: 3000; display: flex; flex-direction: column; gap: 10px; max-width: 360px; pointer-events: none; }
580.toast { background: rgba(16,7,30,.96); border: 1px solid var(--glb); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); border-radius: var(--rs); padding: 14px 18px; font-size: .85rem; color: #fff; box-shadow: 0 10px 40px rgba(0,0,0,.4); animation: tslide .3s var(--spring); display: flex; align-items: flex-start; gap: 10px; pointer-events: all; }
581.toast-success { border-left: 3px solid var(--mn); transform: skewX(-1deg); }
582.toast-error { border-left: 3px solid var(--cr); transform: skewX(-1deg); }
583.toast-info { border-left: 3px solid var(--p5l); transform: skewX(-1deg); }
584.toast-ico { flex-shrink: 0; }
585@keyframes tslide { from{transform:translateX(60px);opacity:0}
585 to{transform:none;opacity:1} }
586.anim-in { opacity: 0; transform: translateY(20px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
587.anim-in.vis { opacity: 1; transform: none; }
588@supports (animation-timeline: view()) {
589  .anim-auto { animation: reveal linear both; animation-timeline: view(); animation-range: entry 10% cover 30%; }
590  @keyframes reveal { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: none; } }
591}
592@starting-style { .overlay.open { opacity: 0; } }
593.p5-sec-div { position: relative; height: 80px; overflow: visible; display: flex; align-items: center; justify-content: center; opacity: 1; margin: 0; }
594.p5-sec-div::before { content: ''; position: absolute; left: -5%; top: 50%; width: 110%; height: 3px; background: linear-gradient(90deg, transparent 0%, rgba(230,26,26,0.15) 10%, var(--p5) 30%, var(--pk) 50%, var(--p5) 70%, rgba(230,26,26,0.15) 90%, transparent 100%); transform: skewY(-1.8deg); filter: drop-shadow(0 0 6px rgba(230,26,26,.45)); }
595.p5-sec-div::after { content: ''; position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; background: var(--p5); transform: translate(-50%, -50%) rotate(45deg) skewY(-1.8deg); box-shadow: 0 0 18px 4px rgba(230,26,26,.6), 0 0 40px 8px rgba(230,26,26,.2); }
596.p5-glow { position: absolute; width: 300px; height: 300px; border-radius: 50%; background: radial-gradient(circle, rgba(230,26,26,.12), transparent 70%); pointer-events: none; filter: blur(40px); animation: p5GlowPulse 4s ease-in-out infinite; }
597@keyframes p5GlowPulse { 0%,100% { opacity: .4; transform: scale(1); } 50% { opacity: .7; transform: scale(1.15); } }
598.p5-tilt { transform-style: preserve-3d; transition: transform .4s var(--spring); }
599.p5-tilt:hover { transform: perspective(800px) rotateX(var(--tiltX, 0deg)) rotateY(var(--tiltY, 0deg)) scale(1.02); }
600.p5-tilt-inner { transform: translateZ(30px); }
601.magnetic-btn { position: relative; transition: transform .3s var(--spring); }
602.magnetic-btn:hover { transform: translate(var(--magX, 0), var(--magY, 0)) scale(1.04); }
603.magnetic-btn::after { content: ''; position: absolute; inset: -2px; border-radius: inherit; background: linear-gradient(135deg, var(--p5), var(--pk), var(--p5)); opacity: 0; z-index: -1; filter: blur(8px); transition: opacity .3s; }
604.magnetic-btn:hover::after { opacity: .6; }
605.ripple-effect { position: relative; overflow: hidden; }
606.ripple-effect .ripple { position: absolute; border-radius: 50%; background: rgba(230,26,26,.35); transform: scale(0); animation: rippleAnim .6s ease-out forwards; pointer-events: none; }
607@keyframes rippleAnim { to { transform: scale(4); opacity: 0; } }
608.glass-ethereal { background: linear-gradient(135deg, rgba(255,255,255,.06), rgba(255,255,255,.02)); border: 1px solid rgba(255,255,255,.1); backdrop-filter: blur(24px) saturate(1.4); -webkit-backdrop-filter: blur(24px) saturate(1.4); box-shadow: 0 8px 32px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.1); }
609.shimmer { position: relative; overflow: hidden; }
610.shimmer::after { content: ''; position: absolute; top: 0; left: -100%; width: 60%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,.06), transparent); animation: shimmerSlide 3s ease-in-out infinite; }
611@keyframes shimmerSlide { 0% { left: -100%; } 100% { left: 200%; } }
612.float-y { animation: floatY 6s ease-in-out infinite; }
613@keyframes floatY { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
614.hero-3d-scene { perspective: 1200px; perspective-origin: 50% 40%; }
615.stagger-1 { transition-delay: .05s; }
616.stagger-2 { transition-delay: .1s; }
617.stagger-3 { transition-delay: .15s; }
618.stagger-4 { transition-delay: .2s; }
619.stagger-5 { transition-delay: .25s; }
620.stagger-6 { transition-delay: .3s; }
621.stagger-7 { transition-delay: .35s; }
622.stagger-8 { transition-delay: .4s; }
623.p5-line-h { height: 3px; background: linear-gradient(90deg, transparent, var(--p5), var(--pk), transparent); margin: 0 auto; transform: skewY(-1.8deg); filter: drop-shadow(0 0 4px rgba(230,26,26,.3)); }
624.p5-line-v { width: 3px; background: linear-gradient(to bottom, transparent, var(--p5), transparent); transform: skewX(-4deg); }
625.hero-orb { position: absolute; border-radius: 50%; filter: blur(80px); pointer-events: none; will-change: transform; }
626.hero-orb-1 { width: 600px; height: 600px; background: radial-gradient(circle, rgba(230,26,26,.15), transparent 70%); top: -200px; right: -150px; animation: orbDrift1 22s ease-in-out infinite; mix-blend-mode: screen; filter: blur(40px); pointer-events: none; }
627.hero-orb-2 { width: 500px; height: 500px; background: radial-gradient(circle, rgba(188,49,148,.12), transparent 70%); bottom: -150px; left: 5%; animation: orbDrift2 26s ease-in-out infinite; mix-blend-mode: screen; filter: blur(50px); pointer-events: none; }
628@keyframes orbDrift1 { 0%,100% { transform: translate3d(0,0,0) scale(1) rotate(0deg); opacity: 0.7; } 33% { transform: translate3d(60px,-50px,40px) scale(1.15) rotate(10deg); opacity: 1; filter: blur(30px); } 66% { transform: translate3d(-30px,40px,-20px) scale(.9) rotate(-5deg); opacity: 0.6; filter: blur(50px); } }
629@keyframes orbDrift2 { 0%,100% { transform: translate3d(0,0,0) scale(1); opacity: 0.6; } 50% { transform: translate3d(-50px,-40px,30px) scale(1.2); opacity: 0.9; filter: blur(35px); } }
630.p5-card-enter { opacity: 0; transform: translateY(40px) rotateX(8deg); transition: opacity .7s var(--ease), transform .7s var(--ease); }
631.p5-card-enter.vis { opacity: 1; transform: translateY(0) rotateX(0); }
632input:-webkit-autofill,
633input:-webkit-autofill:hover,
634input:-webkit-autofill:focus {
635  -webkit-text-fill-color: #fff;
636  -webkit-box-shadow: 0 0 0 1000px var(--bg2) inset;
637  transition: background-color 5000s ease-in-out 0s;
638}
639@supports (padding: env(safe-area-inset-bottom)) {
640  .bloom-foot { padding-bottom: calc(32px + env(safe-area-inset-bottom)); }
641  .btt { bottom: calc(28px + env(safe-area-inset-bottom)); }
642  #nav { padding-left: max(40px, env(safe-area-inset-left)); padding-right: max(40px, env(safe-area-inset-right)); }
643}
644@media (max-width: 1100px) {
645  .p-grid { grid-template-columns: repeat(3, 1fr); }
646  .feat-grid { grid-template-columns: repeat(2, 1fr); }
647  .facts-grid { grid-template-columns: repeat(3, 1fr); }
648}
649@media (max-width: 900px) {
650  .n-links { display: none; }
651  .hmb { display: flex; }
652  .hero-grid { grid-template-columns: 1fr; padding: 40px 0; }
653  .hero-photo { width: 100%; clip-path: none; opacity: .65; }
654  .hero-slash-1 { display: none; }
655  .hero-cards { display: none; }
656  .stats-inner { grid-template-columns: repeat(2, 1fr); }
657  .stat-item:nth-child(2)::after { display: none; }
658  .p-grid { grid-template-columns: repeat(2, 1fr); }
659  .feat-grid { grid-template-columns: 1fr 1fr; }
660  .rev-grid { grid-template-columns: 1fr; }
661  .rev-grid .rev-card { display: none; }
662  .rev-grid .rev-card.mob-active { display: block; }
663  .rev-mob { display: flex; }
664  .facts-grid { grid-template-columns: 1fr; }
665  .corp-grid { grid-template-columns: 1fr; gap: 32px; }
666  .foot-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
667  #nav { padding: 0 20px; }
668  .n-acts #authBtn, .n-acts #langWrap, .n-acts #wlBtnNav { display: none !important; }
669  .sec-pad { padding: 72px 0; }
670  .toast-con { top: 76px; right: 14px; left: 14px; max-width: none; }
671}
672@media (max-width: 560px) {
673  .p-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
674  .p-card { padding: 14px; }
675  .p-img { height: 140px; }
676  .feat-grid { grid-template-columns: 1fr; }
677  .foot-grid { grid-template-columns: 1fr; }
678  .stat-num { font-size: 1.5rem; }
679}
680#bloomBoot { position: fixed; inset: 0; background: radial-gradient(circle at 50% 50%, oklch(13% .07 292) 0%, var(--bg) 70%); z-index: 100000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 28px; transition: opacity .6s var(--ease), visibility .6s; }
681#bloomBoot.gone { opacity: 0; visibility: hidden; pointer-events: none; }
682.bloom-flower { position: relative; width: 140px; height: 140px; transform-style: preserve-3d; animation: bloomSpin 8s linear infinite; }
683.bloom-petal { position: absolute; left: 50%; top: 50%; width: 56px; height: 80px; margin: -40px 0 0 -28px; background: linear-gradient(180deg, var(--p5l), var(--p5d)); border-radius: 100% 100% 60% 60% / 70% 70% 60% 60%; transform-origin: 50% 100%; opacity: 0; box-shadow: inset -6px -8px 18px rgba(0,0,0,.32), 0 6px 14px rgba(230,26,26,.35); animation: petalBloom 2.4s var(--p5ease) forwards; }
684.bloom-petal:nth-child(1) { transform: rotate(0deg) translateY(-30px); animation-delay: 0s; }
685.bloom-petal:nth-child(2) { transform: rotate(45deg) translateY(-30px); animation-delay: .12s; }
686.bloom-petal:nth-child(3) { transform: rotate(90deg) translateY(-30px); animation-delay: .24s; }
687.bloom-petal:nth-child(4) { transform: rotate(135deg) translateY(-30px); animation-delay: .36s; }
688.bloom-petal:nth-child(5) { transform: rotate(180deg) translateY(-30px); animation-delay: .48s; }
689.bloom-petal:nth-child(6) { transform: rotate(225deg) translateY(-30px); animation-delay: .6s; }
690.bloom-petal:nth-child(7) { transform: rotate(270deg) translateY(-30px); animation-delay: .72s; }
691.bloom-petal:nth-child(8) { transform: rotate(315deg) translateY(-30px); animation-delay: .84s; }
692.bloom-core { position: absolute; left: 50%; top: 50%; width: 40px; height: 40px; margin: -20px 0 0 -20px; background: radial-gradient(circle, var(--gd), var(--p5)); border-radius: 50%; box-shadow: 0 0 30px rgba(230,26,26,.6), inset 0 0 12px rgba(0,0,0,.3); transform: scale(0); animation: coreBloom 1.6s var(--spring) .9s forwards; }
693@keyframes petalBloom { 0% { opacity: 0; transform: rotate(var(--r,0deg)) translateY(0) scale(.2); } 60% { opacity: 1; transform: rotate(var(--r,0deg)) translateY(-30px) scale(1.08); } 100% { opacity: 1; transform: rotate(var(--r,0deg)) translateY(-30px) scale(1); } }
694@keyframes coreBloom { to { transform: scale(1); } }
695@keyframes bloomSpin { to { transform: rotateZ(360deg); } }
696.bloom-petal:nth-child(1) { --r: 0deg; } .bloom-petal:nth-child(2) { --r: 45deg; } .bloom-petal:nth-child(3) { --r: 90deg; } .bloom-petal:nth-child(4) { --r: 135deg; } .bloom-petal:nth-child(5) { --r: 180deg; } .bloom-petal:nth-child(6) { --r: 225deg; } .bloom-petal:nth-child(7) { --r: 270deg; } .bloom-petal:nth-child(8) { --r: 315deg; }
697.bloom-boot-txt { font-family: var(--fc); font-style: italic; font-weight: 900; letter-spacing: .3em; color: rgba(255,255,255,.55); font-size: .8rem; text-transform: uppercase; animation: bootPulse 2s ease-in-out infinite; }
698@keyframes bootPulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
699.bloom-boot-bar { width: 220px; height: 2px; background: rgba(255,255,255,.06); border-radius: 1px; overflow: hidden; }
700.bloom-boot-bar i { display: block; width: 30%; height: 100%; background: linear-gradient(90deg, var(--p5), var(--pk), var(--p5)); animation: bootSlide 1.6s ease-in-out infinite; }
701@keyframes bootSlide { 0% { transform: translateX(-100%); } 100% { transform: translateX(380%); } }
702.p-skel { background: var(--gl); border: 1px solid var(--glb); border-radius: var(--r); padding: 20px; position: relative; overflow: hidden; }
703.p-skel-img { height: 180px; border-radius: 14px; background: radial-gradient(circle at 50% 50%, rgba(230,26,26,.18), rgba(11,5,22,.4)); position: relative; overflow: hidden; margin-bottom: 14px; }
704.p-skel-img::before { content: ''; position: absolute; inset: 0; background: conic-gradient(from 0deg, transparent 0%, rgba(230,26,26,.12) 25%, transparent 50%); animation: skelSpin 1.6s linear infinite; }
705.p-skel-img::after { content: '\1F339'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: rgba(230,26,26,.45); font-size: 2.2rem; animation: skelBloom 1.8s ease-in-out infinite; }
706@keyframes skelSpin { to { transform: rotate(360deg); } }
707@keyframes skelBloom { 0%,100% { transform: scale(.85); opacity: .35; } 50% { transform: scale(1.1); opacity: .9; } }
708.delivery-bar { position: sticky; top: 68px; z-index: 990; background: linear-gradient(90deg, oklch(15% .08 292 / .96), oklch(11% .06 292 / .92)); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-bottom: 2px solid rgba(230,26,26,.22); padding: 10px 0; transition: transform .3s var(--ease); }
709.delivery-bar.hide { transform: translateY(-100%); }
710.delivery-inner { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: center; }
711.delivery-pill { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; background: rgba(230,26,26,.12); border: 1px solid rgba(230,26,26,.28); border-radius: 100px; font-family: var(--fc); font-style: italic; font-weight: 700; font-size: .72rem; color: var(--p5l); letter-spacing: .12em; text-transform: uppercase; }
712.delivery-pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--mn); box-shadow: 0 0 8px var(--mn); animation: ping2 1.6s ease-out infinite; }
713.delivery-fields { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
714.dlv-fld { display: flex; align-items: center; gap: 8px; background: var(--gl); border: 1px solid var(--glb); border-radius: 10px; padding: 6px 12px; transition: border-color .2s; }
715.dlv-fld:focus-within { border-color: var(--p5); box-shadow: 0 0 0 3px rgba(230,26,26,.12); }
716.dlv-fld svg { width: 14px; height: 14px; color: var(--p5l); flex-shrink: 0; }
717.dlv-fld label { font-size: .68rem; color: rgba(255,255,255,.5); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
718.dlv-fld input, .dlv-fld select { background: transparent; border: none; color: #fff; font-size: .82rem; font-weight: 600; outline: none; min-width: 0; padding: 2px 0; cursor: pointer; }
719.dlv-fld select option { background: var(--bg2); color: #fff; }
720.dlv-eta { font-size: .76rem; color: var(--mn); font-weight: 600; }
721.dlv-eta strong { font-family: var(--fc); font-style: italic; font-weight: 900; }
722@media (max-width: 768px) {
723  .delivery-inner { gap: 8px; }
724  .delivery-pill { font-size: .64rem; padding: 4px 10px; }
725  .dlv-fld { padding: 5px 10px; }
726  .dlv-fld label { display: none; }
727}
728.subs-sec { background: var(--bg2); position: relative; overflow: hidden; }
729.subs-sec::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, var(--p5), var(--pk), transparent); opacity: .4; }
730.subs-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 56px; align-items: center; }
731.subs-photo { position: relative; border-radius: var(--r); overflow: hidden; aspect-ratio: 4/3; box-shadow: 0 30px 80px rgba(168,16,16,.32); transform: rotate(-1.5deg); }
732.subs-photo img { width: 100%; height: 100%; object-fit: cover; }
733.subs-photo::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, transparent 50%, rgba(230,26,26,.18)); }
734.subs-photo::after { content: 'WEEKLY'; position: absolute; top: 18px; left: 18px; font-family: var(--fc); font-style: italic; font-weight: 900; font-size: .76rem; letter-spacing: .15em; color: #fff; background: var(--p5); padding: 5px 16px 5px 18px; transform: skewX(-6deg); clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%); }
735.subs-cards { display: flex; flex-direction: column; gap: 14px; }
736.subs-card { background: var(--gl); border: 1px solid var(--glb); border-radius: var(--r); padding: 22px; cursor: pointer; transition: all .25s var(--ease); position: relative; overflow: hidden; }
737.subs-card::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(230,26,26,.06), transparent 60%); opacity: 0; transition: opacity .3s; }
738.subs-card:hover { border-color: rgba(230,26,26,.4); transform: translateX(6px); }
739.subs-card:hover::before { opacity: 1; }
740.subs-card.selected { border-color: var(--p5); background: rgba(230,26,26,.1); box-shadow: 0 12px 36px rgba(230,26,26,.22); }
741.subs-card-hd { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 8px; position: relative; }
742.subs-card-name { font-family: var(--fd); font-size: 1.15rem; font-weight: 700; }
743.subs-card-name em { font-family: var(--fc); font-style: italic; color: var(--p5l); font-weight: 900; font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; padding: 2px 8px; background: rgba(230,26,26,.18); border-radius: 3px; margin-left: 8px; vertical-align: middle; }
744.subs-card-price { font-family: var(--fc); font-style: italic; font-weight: 900; font-size: 1.4rem; color: var(--gd); white-space: nowrap; }
745.subs-card-price small { font-size: .65rem; color: rgba(255,255,255,.45); font-weight: 600; letter-spacing: .05em; }
746.subs-card-d { font-size: .82rem; color: rgba(255,255,255,.6); line-height: 1.6; margin-bottom: 12px; position: relative; }
747.subs-card-feats { display: flex; flex-wrap: wrap; gap: 6px; position: relative; }
748.subs-card-feats span { font-size: .7rem; color: rgba(255,255,255,.55); padding: 3px 10px; background: rgba(255,255,255,.05); border-radius: 100px; }
749.subs-cta { display: flex; gap: 10px; margin-top: 8px; }
750.subs-cta .btn { flex: 1; justify-content: center; }
751@media (max-width: 900px) {
752  .subs-grid { grid-template-columns: 1fr; gap: 32px; }
753  #scGridWrap { grid-template-columns: 1fr !important; }
754  .subs-photo { aspect-ratio: 16/9; }
755}
756.wl-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 100vw); background: rgba(11,5,22,.97); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px); border-left: 1px solid rgba(230,26,26,.22); transform: translateX(100%); transition: transform .42s var(--ease); z-index: 1400; display: flex; flex-direction: column; }
757.wl-drawer.open { transform: none; }
758.wl-drawer-hd { padding: 22px 24px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--glb); }
759.wl-drawer-hd h3 { font-family: var(--fd); font-weight: 900; font-size: 1.2rem; }
760.wl-drawer-hd small { display: block; font-family: var(--fc); font-style: italic; font-size: .68rem; color: var(--p5l); letter-spacing: .15em; text-transform: uppercase; margin-top: 2px; }
761.wl-drawer-cls { width: 36px; height: 36px; border-radius: 50%; background: var(--gl); border: 1px solid var(--glb); color: #fff; display: flex; align-items: center; justify-content: center; transition: all .2s; }
762.wl-drawer-cls:hover { background: rgba(230,26,26,.18); }
763.wl-drawer-body { flex: 1; overflow-y: auto; padding: 16px 20px; }
764.wl-empty { text-align: center; padding: 60px 24px; color: rgba(255,255,255,.4); }
765.wl-empty-ico { font-size: 3rem; color: rgba(230,26,26,.4); margin-bottom: 14px; }
766.wl-row { display: flex; gap: 12px; padding: 12px; border-radius: var(--rs); transition: background .2s; align-items: center; }
767.wl-row:hover { background: var(--gl); }
768.wl-row-img { width: 60px; height: 60px; border-radius: 10px; overflow: hidden; background: var(--gl); flex-shrink: 0; }
769.wl-row-img img { width: 100%; height: 100%; object-fit: cover; }
770.wl-row-body { flex: 1; min-width: 0; }
771.wl-row-name { font-weight: 600; font-size: .88rem; margin-bottom: 2px; }
772.wl-row-price { font-family: var(--fc); font-weight: 900; color: var(--gd); font-size: .92rem; font-style: italic; }
773.wl-row-x { background: var(--gl); border: 1px solid var(--glb); border-radius: 50%; width: 28px; height: 28px; color: rgba(255,255,255,.5); display: flex; align-items: center; justify-content: center; transition: all .2s; flex-shrink: 0; font-size: .8rem; }
774.wl-row-x:hover { background: rgba(230,26,26,.2); color: #fff; }
775.wl-drawer-ft { padding: 18px 24px; border-top: 1px solid var(--glb); }
776.voice-fab { position: fixed; bottom: 86px; right: 24px; width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg, var(--p5d), var(--p5)); color: #fff; border: 2px solid rgba(255,255,255,.18); box-shadow: 0 12px 36px rgba(230,26,26,.45); z-index: 990; display: flex; align-items: center; justify-content: center; transition: transform .3s var(--spring), box-shadow .3s, opacity .3s, visibility .3s; opacity: 0; visibility: hidden; }
777.voice-fab.show { opacity: 1; visibility: visible; }
778.voice-fab:hover, .voice-fab:focus-visible { transform: translateY(-3px) scale(1.08); box-shadow: 0 18px 50px rgba(230,26,26,.55); }
779.voice-fab.listening { animation: voicePulse 1.2s ease-in-out infinite; background: linear-gradient(135deg, var(--cr), var(--p5)); }
780@keyframes voicePulse { 0%,100% { box-shadow: 0 12px 36px rgba(230,26,26,.45), 0 0 0 0 rgba(230,26,26,.7); } 50% { box-shadow: 0 12px 36px rgba(230,26,26,.6), 0 0 0 18px rgba(230,26,26,0); } }
781.voice-fab svg { width: 22px; height: 22px; }
782.voice-status { position: fixed; bottom: 158px; right: 24px; background: rgba(11,5,22,.96); border: 1px solid rgba(230,26,26,.32); border-radius: 14px; padding: 10px 16px; max-width: 280px; font-size: .82rem; color: #fff; z-index: 991; opacity: 0; transform: translateY(8px); transition: all .3s var(--ease); pointer-events: none; backdrop-filter: blur(20px); }
783.voice-status.show { opacity: 1; transform: none; pointer-events: all; }
784.voice-status small { display: block; font-family: var(--fc); font-style: italic; font-weight: 700; color: var(--p5l); font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 3px; }
785@media (max-width: 560px) {
786  .voice-fab { bottom: 74px; right: 14px; width: 48px; height: 48px; }
787  .voice-status { right: 14px; bottom: 132px; }
788}
789.vid-msg-block { background: var(--gl); border: 1px dashed var(--glb); border-radius: var(--rs); padding: 16px; margin-top: 16px; }
790.vid-msg-hd { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
791.vid-msg-hd h4 { font-family: var(--fd); font-weight: 700; font-size: .92rem; }
792.vid-msg-hd small { font-size: .7rem; color: rgba(255,255,255,.45); }
793.vid-preview { width: 100%; aspect-ratio: 16/9; background: #000; border-radius: 10px; overflow: hidden; position: relative; margin-bottom: 10px; }
794.vid-preview video { width: 100%; height: 100%; object-fit: cover; display: block; }
795.vid-rec-dot { position: absolute; top: 10px; left: 10px; display: none; align-items: center; gap: 6px; padding: 4px 10px; background: rgba(230,26,26,.92); border-radius: 100px; font-family: var(--fc); font-style: italic; font-weight: 900; font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: #fff; }
796.vid-rec-dot.on { display: inline-flex; }
797.vid-rec-dot::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: #fff; animation: vidPulse 1s ease-in-out infinite; }
798@keyframes vidPulse { 50% { opacity: .35; } }
799.vid-msg-actions { display: flex; gap: 8px; flex-wrap: wrap; }
800.vid-msg-actions .btn { flex: 1; min-width: 110px; justify-content: center; padding: 8px 12px; font-size: .78rem; }
801.err-summary { background: rgba(245,77,77,.08); border: 1px solid rgba(245,77,77,.32); border-left: 4px solid var(--cr); border-radius: var(--rs); padding: 14px 16px; margin-bottom: 16px; display: none; }
802.err-summary.on { display: block; animation: errShake .4s ease-out; }
803.err-summary h4 { font-family: var(--fd); font-weight: 700; font-size: .88rem; color: var(--cr); margin-bottom: 6px; display: flex; align-items: center; gap: 8px; }
804.err-summary ul { list-style: none; padding: 0; margin: 0; }
805.err-summary li { font-size: .8rem; color: rgba(255,255,255,.78); padding: 3px 0; }
806.err-summary li a { color: var(--cr); border-bottom: 1px dotted rgba(245,77,77,.35); }
807.err-summary li a:hover, .err-summary li a:focus-visible { color: #fff; border-bottom-color: #fff; }
808@keyframes errShake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
809.funnel-bar { position: fixed; bottom: 0; left: 0; right: 0; background: rgba(11,5,22,.94); backdrop-filter: blur(18px); border-top: 1px solid rgba(230,26,26,.2); z-index: 985; padding: 8px 16px; transform: translateY(100%); transition: transform .3s var(--ease); display: none; }
810.funnel-bar.show { transform: none; }
811.funnel-track { display: flex; align-items: center; justify-content: space-between; gap: 12px; max-width: 720px; margin: 0 auto; }
812.funnel-step { display: flex; align-items: center; gap: 6px; font-family: var(--fc); font-style: italic; font-weight: 700; font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.4); transition: color .3s; }
813.funnel-step.done { color: var(--mn); }
814.funnel-step.active { color: var(--p5l); }
815.funnel-step::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 0 currentColor; }
816.funnel-step.active::before { animation: ping 1.4s ease-out infinite; }
817.funnel-conn { flex: 1; height: 2px; background: linear-gradient(90deg, currentColor, transparent); opacity: .3; }
818.btn-voice-toggle { position: relative; }
819.btn-voice-toggle.listening::after { content: ''; position: absolute; inset: -3px; border: 2px solid var(--p5); border-radius: var(--rs); animation: voicePulse 1.2s ease-in-out infinite; }
820.subs-card-feats span svg { width: 11px; height: 11px; color: var(--mn); display: inline-block; vertical-align: -2px; margin-right: 3px; }
821.search-results-virt { max-height: 60vh; overflow-y: auto; }
822.search-results-virt::-webkit-scrollbar { width: 4px; }
823@media (max-width: 768px) {
824  .delivery-bar { top: 68px; padding: 8px 0; }
825  .funnel-bar { padding: 6px 10px; }
826  .funnel-step { font-size: .6rem; }
827}
828@media (max-width: 720px) {
829  #voiceNavBtn { display: none !important; }
830}
831@media (max-width: 540px) {
832  #wlBtnNav { display: none !important; }
833}
834.bloom-cookie, #cookieBanner, [class*="cookie-consent"] { opacity: 0; visibility: hidden; transition: opacity .4s ease .2s, visibility 0s linear .6s; }
835.bloom-cookie.ready, #cookieBanner.ready, [class*="cookie-consent"].ready { opacity: 1; visibility: visible; transition: opacity .4s ease, visibility 0s; }
836
837
838#cinematicHero { width: 100% !important; max-width: 100vw !important; overflow-x: clip; left: 0; right: 0; margin: 0; }
839#cinematicHero, #cinematicHero * { box-sizing: border-box; }
840
841@media (max-width: 900px) {
842  #cinematicHero .ch-main-card { width: calc(100% - 20px) !important; height: calc(100dvh - 20px) !important; max-width: calc(100% - 20px) !important; border-radius: 24px !important; }
843  #cinematicHero .ch-mockup-wrapper { height: 320px !important; }
844}
845
846@media (max-width: 640px) {
847  #cinematicHero { height: 100dvh !important; min-height: 100svh !important; }
848  #cinematicHero .ch-main-card { width: calc(100% - 12px) !important; height: calc(100dvh - 12px) !important; border-radius: 20px !important; padding: 0 !important; }
849  #cinematicHero .ch-mockup-wrapper { height: 260px !important; }
850  #cinematicHero .ch-floating-badge { transform: scale(.85); }
851  #cinematicHero .ch-floating-badge[style*="left:-15px"] { left: 4px !important; }
852  #cinematicHero .ch-floating-badge[style*="right:-15px"] { right: 4px !important; }
853  #cinematicHero .ch-card-right-text h2 { font-size: clamp(2.2rem, 12vw, 4rem) !important; }
854  #cinematicHero .ch-hero-text-wrapper h1 { font-size: clamp(1.8rem, 8vw, 3rem) !important; }
855}
856
857@media (max-width: 380px) {
858  #cinematicHero .ch-floating-badge { display: none !important; }
859  #cinematicHero .ch-mockup-wrapper { height: 220px !important; }
860}
861</style>
862</head>
863<body>
864<div id="promoBanner" class="promo-banner" style="display:none; justify-content:center; align-items:center; background:linear-gradient(135deg,var(--p5),oklch(50% .22 340)); color:#fff; font-family:var(--fc); font-weight:700; font-size:0.82rem; letter-spacing:0.08em; text-transform:uppercase; padding:8px 16px; text-align:center; z-index:1000; position:relative; box-shadow:0 4px 15px rgba(230,26,26,0.25);" role="region" aria-label="Announcement">
865  <span data-content-key="banner">🌸 Free delivery on orders over ₱4,350</span>
866</div>
867<div id="bloomBoot" role="status" aria-live="polite" aria-label="Bloom is loading">
868  <div class="bloom-flower" aria-hidden="true">
869    <span class="bloom-petal"></span><span class="bloom-petal"></span><span class="bloom-petal"></span><span class="bloom-petal"></span>
870    <span class="bloom-petal"></span><span class="bloom-petal"></span><span class="bloom-petal"></span><span class="bloom-petal"></span>
871    <span class="bloom-core"></span>
872  </div>
873  <div class="bloom-boot-bar" aria-hidden="true"><i></i></div>
874  <div class="bloom-boot-txt">Crafting your bouquet</div>
875</div>
876<a href="#main" class="skip">Skip to content</a>
877<a href="#shop" class="skip" style="left: 160px">Skip to shop</a>
878<div class="c-ring" id="cRing" aria-hidden="true"></div>
879<div class="c-dot" id="cDot" aria-hidden="true"></div>
880<div id="sbar" aria-hidden="true"></div>
881<nav id="nav" class="bloom-nav" role="navigation" aria-label="Main navigation">
882  <a href="/" class="n-logo">Bloom</a>
883  <button class="hmb" id="hmb" aria-label="Open menu" aria-expanded="false" aria-controls="mobMenu">
884    <span></span><span></span><span></span>
885  </button>
886  <ul class="n-links" role="list">
887    <li><a href="/#shop" data-label="shop" data-i18n="nav.shop">Shop</a></li>
888    <li><a href="/catalog.html" data-label="catalog" data-i18n="nav.catalog">Catalog</a></li>
889    <li><a href="/#subs" data-label="recurring" data-i18n="nav.subscriptions">Subscriptions</a></li>
890    <li><a href="/#corp" data-label="corp" data-i18n="nav.corporate">Corporate</a></li>
891    <li><a href="/#features" data-label="why" data-i18n="nav.why">Why Bloom</a></li>
892  </ul>
893  <div class="n-acts">
894    <div class="n-srch-wrap" id="srchWrap">
895      <button class="btn btn-g btn-sm" id="srchTog" aria-label="Search" aria-expanded="false" aria-controls="srchPanel">
896        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
897      </button>
898      <div class="n-srch-panel" id="srchPanel" role="search" aria-hidden="true">
899        <input type="search" class="n-srch-inp" id="srchInp" placeholder="Search bouquets…" autocomplete="off" aria-label="Search products">
900        <div id="srchRes" role="listbox" style="margin-top:8px"></div>
901      </div>
902    </div>
903    <div style="position:relative" id="langWrap">
904      <button class="btn btn-g btn-sm" id="langBtn" aria-label="Language selector" aria-expanded="false" aria-haspopup="listbox">
905        <span id="langFlag" aria-hidden="true">🇺🇸</span>
906        <span id="langLbl">EN</span>
907      </button>
908      <ul id="langDd" class="lang-dd" role="listbox" aria-hidden="true" inert>
909        <li><button class="lang-opt" role="option" data-lang="en" data-flag="🇺🇸" data-lbl="EN"><span aria-hidden="true">🇺🇸</span> English</button></li>
910        <li><button class="lang-opt" role="option" data-lang="fil" data-flag="🇵🇭" data-lbl="PH"><span aria-hidden="true">🇵🇭</span> Filipino</button></li>
911        <li><button class="lang-opt" role="option" data-lang="es" data-flag="🇪🇸" data-lbl="ES"><span aria-hidden="true">🇪🇸</span> Español</button></li>
912        <li><button class="lang-opt" role="option" data-lang="ja" data-flag="🇯🇵" data-lbl="JA"><span aria-hidden="true">🇯🇵</span> 日本語</button></li>
913      </ul>
914    </div>
915    <button class="btn btn-g btn-sm btn-voice-toggle" id="voiceNavBtn" aria-label="Voice navigation" aria-pressed="false" hidden>
916      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 2a3 3 0 0 0-3 3v6a3 3 0 1 0 6 0V5a3 3 0 0 0-3-3z"/><path d="M19 10v1a7 7 0 0 1-14 0v-1"/><path d="M12 18v4"/><path d="M8 22h8"/></svg>
917    </button>
918    <button class="btn btn-g btn-sm cart-wrap" id="wlBtnNav" aria-label="Open wishlist" aria-haspopup="dialog" aria-controls="wlDrawer" style="position:relative">
919      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" aria-hidden="true"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
920      <span class="cart-badge" id="wlBadge" style="display:none">0</span>
921    </button>
922    <button class="btn btn-g btn-sm" id="themeToggle" aria-label="Toggle theme" data-i18n-aria="theme.toggle">
923      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" id="themeIcon"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>
924    </button>
925    <a href="/cart.html" class="btn btn-g btn-sm cart-wrap" aria-label="Cart" id="cartBtn">
926      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" aria-hidden="true"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
927      <span class="cart-badge" id="cartBadge" style="display:none" aria-live="polite">0</span>
928    </a>
929    <button class="btn btn-p btn-sm" id="authBtn" data-i18n="nav.signin">Sign In</button>
930  </div>
931</nav>
932<div class="mob-menu" id="mobMenu" aria-hidden="true" role="dialog" aria-label="Mobile navigation">
933  <div class="mob-inner">
934    <button class="mob-close" id="mobClose" aria-label="Close menu">✕</button>
935    <ul role="list">
936      <li><a href="/#shop" data-i18n="nav.shop">Shop</a></li>
937      <li><a href="/catalog.html" data-i18n="nav.catalog">Catalog</a></li>
938      <li><a href="/#subs" data-i18n="nav.subscriptions">Subscriptions</a></li>
939      <li><a href="/#corp" data-i18n="nav.corporate">Corporate</a></li>
940      <li><a href="/#features" data-i18n="nav.why">Why Bloom</a></li>
941    </ul>
942    <div class="mob-acts">
943      <button class="btn btn-p" id="authBtnMob" style="justify-content:center">Sign In</button>
944    </div>
945  </div>
946</div>
947<div class="delivery-bar" id="dlvBar" role="region" aria-label="Pre-select your delivery">
948  <div class="con">
949    <div class="delivery-inner">
950      <span class="delivery-pill" aria-hidden="true">Plan first · Browse next</span>
951      <div class="delivery-fields">
952        <label class="dlv-fld" for="dlvDate">
953          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
954          <span><label for="dlvDate">Deliver on</label><br><input type="date" id="dlvDate" aria-label="Delivery date"></span>
955        </label>
956        <label class="dlv-fld" for="dlvLoc">
957          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" aria-hidden="true"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0z"/><circle cx="12" cy="10" r="3"/></svg>
958          <span><label for="dlvLoc">To</label><br>
959            <select id="dlvLoc" aria-label="Delivery location">
960              <option value="metro-manila">Metro Manila</option>
961              <option value="batangas" selected>Batangas</option>
962              <option value="cebu">Cebu City</option>
963              <option value="laguna">Laguna</option>
964              <option value="cavite">Cavite</option>
965              <option value="rizal">Rizal</option>
966              <option value="bulacan">Bulacan</option>
967              <option value="pampanga">Pampanga</option>
968              <option value="baguio">Baguio</option>
969            </select>
970          </span>
971        </label>
972      </div>
973      <div class="dlv-eta" id="dlvEta" aria-live="polite">Lead time: <strong>48h</strong></div>
974    </div>
975  </div>
976</div>
977<main id="main">
978<section id="cinematicHero" aria-label="Cinematic Hero" style="position:relative;width:100%;max-width:100%;height:100dvh;min-height:100svh;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#05020a;font-family:var(--fb);-webkit-font-smoothing:antialiased;perspective:1500px;box-sizing:border-box;margin:0;left:0;right:0">
979  <div class="ch-ethereal-bg" aria-hidden="true">
980    <div class="ch-bg-frame frame-1" data-bg="/img/ch-frame-1.webp" style="background-image: url('/img/ch-frame-1.webp');"></div>
981    <div class="ch-bg-frame frame-2" data-bg="/img/ch-frame-2.webp"></div>
982    <div class="ch-bg-frame frame-3" data-bg="/img/ch-frame-3.webp"></div>
983    <div class="ch-bg-frame frame-4" data-bg="/img/ch-frame-4.webp"></div>
984    <div class="ch-bg-frame frame-5" data-bg="/img/ch-frame-5.webp"></div>
985    
985<script>(function(){function l(){document.querySelectorAll('.ch-bg-frame[data-bg]').forEach(function(e){if(!e.style.backgroundImage){e.style.backgroundImage="url('"+e.dataset.bg+"')";}});}if('requestIdleCallback'in window){requestIdleCallback(l,{timeout:2500});}else{setTimeout(l,1800);}})();</script>
985
986  </div>
987  <div class="ch-film-grain" aria-hidden="true"></div>
988  <div class="ch-bg-grid" style="position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.5" aria-hidden="true"></div>
989  <div class="ch-hero-text-wrapper" style="position:absolute;left:0;right:0;z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;padding:0 16px;will-change:transform">
990    <h1 class="ch-text-track ch-gsap-reveal ch-text-3d-matte" style="font-family:var(--fd);font-size:clamp(2.4rem,5.5vw,6rem);font-weight:700;letter-spacing:-.03em;margin-bottom:8px;line-height:1.1">A small gesture,</h1>
991    <h1 class="ch-text-days ch-gsap-reveal ch-text-silver-matte" style="font-family:var(--fd);font-size:clamp(2.4rem,5.5vw,6rem);font-weight:900;letter-spacing:-.04em;line-height:1.1">a quiet comfort.</h1>
992  </div>
993  <div class="ch-cta-wrapper" style="position:absolute;left:0;right:0;z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;padding:0 16px;pointer-events:auto;will-change:transform" aria-hidden="false">
994    <h2 class="ch-text-silver-matte" style="font-family:var(--fd);font-size:clamp(2rem,5vw,4.5rem);font-weight:700;margin-bottom:24px;letter-spacing:-.03em;line-height:1.1">Browse gently.</h2>
995    <p style="color:var(--text-muted);font-size:clamp(.9rem,1.2vw,1.25rem);margin-bottom:48px;max-width:520px;margin-left:auto;margin-right:auto;font-weight:300;line-height:1.7">Handcrafted bouquets and floral arrangements. Designed with care, delivered gently to the door - no rush, no pressure.</p>
996    <div style="display:flex;flex-direction:column;gap:16px;align-items:center">
997      <a href="#shop" class="ch-btn-modern-light" style="display:inline-flex;align-items:center;justify-content:center;gap:12px;padding:14px 32px;border-radius:20px;text-decoration:none;font-weight:700;font-size:1rem;font-family:var(--fb)">
998        <svg style="width:20px;height:20px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 2v6M12 22v-6M4.22 4.22l4.24 4.24M15.54 15.54l4.24 4.24M2 12h6M22 12h-6M4.22 19.78l4.24-4.24M15.54 8.46l4.24-4.24"/></svg>
999        <span>Browse Bouquets</span>
1000      </a>
1001      <a href="/catalog.html" class="ch-btn-modern-dark" style="display:inline-flex;align-items:center;justify-content:center;gap:12px;padding:14px 32px;border-radius:20px;text-decoration:none;font-weight:700;font-size:1rem;font-family:var(--fb)">
1002        <svg style="width:20px;height:20px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
1003        <span>Full Catalog</span>
1004      </a>
1005    </div>
1006  </div>
1007  <div style="position:absolute;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;pointer-events:none;perspective:1500px">
1008    <div class="ch-main-card ch-depth-card ch-gsap-reveal" style="position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;pointer-events:auto;width:min(92%, 1280px);height:min(92dvh, 900px);max-width:calc(100% - 16px);max-height:calc(100dvh - 16px);border-radius:clamp(20px, 4vw, 32px);box-sizing:border-box" role="complementary" aria-label="Bloom Preview">
1009      <div class="ch-card-sheen" aria-hidden="true"></div>
1010      <div style="position:relative;width:100%;height:100%;max-width:1280px;margin:0 auto;padding:16px;display:flex;flex-direction:column;justify-content:space-evenly;align-items:center;z-index:10">
1011        <div class="ch-card-right-text ch-gsap-reveal" style="display:flex;justify-content:center;z-index:20;width:100%;order:1">
1012          <h2 class="ch-text-card-silver" style="font-family:var(--fc);font-size:clamp(3rem,8vw,8rem);font-weight:900;text-transform:uppercase;letter-spacing:-.06em;line-height:1">Bloom</h2>
1013        </div>
1014        <div class="ch-mockup-wrapper" style="order:2;position:relative;width:100%;height:380px;display:flex;align-items:center;justify-content:center;z-index:10;perspective:1000px">
1015          <div style="position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;transform:scale(.65)">
1016            <div class="ch-mockup-bezel ch-iphone-bezel" style="position:relative;width:280px;height:580px;border-radius:3rem;display:flex;flex-direction:column;will-change:transform;transform-style:preserve-3d">
1017              <div class="ch-hw-btn" style="position:absolute;top:120px;left:-3px;width:3px;height:25px;border-radius:4px 0 0 4px;z-index:0" aria-hidden="true"></div>
1018              <div class="ch-hw-btn" style="position:absolute;top:160px;left:-3px;width:3px;height:45px;border-radius:4px 0 0 4px;z-index:0" aria-hidden="true"></div>
1019              <div class="ch-hw-btn" style="position:absolute;top:220px;left:-3px;width:3px;height:45px;border-radius:4px 0 0 4px;z-index:0" aria-hidden="true"></div>
1020              <div class="ch-hw-btn" style="position:absolute;top:170px;right:-3px;width:3px;height:70px;border-radius:0 4px 4px 0;z-index:0;
1020transform:scaleX(-1)" aria-hidden="true"></div>
1021              <div style="position:absolute;inset:7px;background:#050914;border-radius:2.5rem;overflow:hidden;box-shadow:inset 0 0 15px rgba(0,0,0,1);color:#fff;z-index:10">
1022                <div class="ch-screen-glare" style="position:absolute;inset:0;z-index:40;pointer-events:none" aria-hidden="true"></div>
1023                <div style="position:absolute;top:5px;left:50%;transform:translateX(-50%);width:100px;height:28px;background:#000;border-radius:9999px;z-index:50;display:flex;align-items:center;justify-content:flex-end;padding:0 12px;box-shadow:inset 0 -1px 2px rgba(255,255,255,.1)">
1024                  <div style="width:6px;height:6px;border-radius:50%;background:#22c55e;box-shadow:0 0 8px rgba(34,197,94,.8);animation:ping2 2s ease-out infinite"></div>
1025                </div>
1026                <div style="position:relative;width:100%;height:100%;padding:48px 20px 32px;display:flex;flex-direction:column">
1027                  <div class="ch-phone-widget" style="display:flex;justify-content:space-between;align-items:center;margin-bottom:32px">
1028                    <div style="display:flex;flex-direction:column">
1029                      <span style="font-size:10px;color:#a1a1aa;text-transform:uppercase;letter-spacing:.15em;font-weight:700;margin-bottom:4px">Today</span>
1030                      <span style="font-size:1.25rem;font-weight:700;letter-spacing:-.03em;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.4)">My Bouquet</span>
1031                    </div>
1032                    <div style="width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,.05);color:#e4e4e7;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;border:1px solid rgba(255,255,255,.1);box-shadow:0 4px 12px rgba(0,0,0,.5)">B</div>
1033                  </div>
1034                  <div class="ch-phone-widget" style="position:relative;width:176px;height:176px;margin:0 auto 32px;filter:drop-shadow(0 15px 25px rgba(0,0,0,.8))">
1035                    <svg style="position:absolute;inset:0;width:100%;height:100%" aria-hidden="true">
1036                      <circle cx="88" cy="88" r="64" fill="none" stroke="rgba(255,255,255,.03)" stroke-width="12"/>
1037                      <circle class="ch-progress-ring" cx="88" cy="88" r="64" fill="none" stroke="var(--p5)" stroke-width="12"/>
1038                    </svg>
1039                    <div style="position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:10">
1040                      <span class="ch-counter-val" style="font-size:2.5rem;font-weight:900;letter-spacing:-.04em;color:#fff">0</span>
1041                      <span style="font-size:8px;color:rgba(255,107,107,.5);text-transform:uppercase;letter-spacing:.1em;font-weight:700;margin-top:2px">Orders</span>
1042                    </div>
1043                  </div>
1044                  <div style="display:flex;flex-direction:column;gap:12px">
1045                    <div class="ch-phone-widget ch-widget-depth" style="border-radius:16px;padding:12px;display:flex;align-items:center">
1046                      <div style="width:40px;height:40px;border-radius:12px;background:linear-gradient(135deg,rgba(230,26,26,.2),rgba(230,26,26,.05));display:flex;align-items:center;justify-content:center;margin-right:12px;border:1px solid rgba(230,26,26,.2);box-shadow:inset 0 1px 2px rgba(0,0,0,.3)">
1047                        <svg style="width:16px;height:16px;color:var(--p5l)" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
1048                      </div>
1049                      <div style="flex:1"><div style="height:8px;width:80px;background:#d4d4d8;border-radius:9999px;margin-bottom:8px;box-shadow:inset 0 1px 1px rgba(0,0,0,.2)"></div><div style="height:6px;width:48px;background:#525252;border-radius:9999px;box-shadow:inset 0 1px 1px rgba(0,0,0,.2)"></div></div>
1050                    </div>
1051                    <div class="ch-phone-widget ch-widget-depth" style="border-radius:16px;padding:12px;display:flex;align-items:center">
1052                      <div style="width:40px;height:40px;border-radius:12px;background:linear-gradient(135deg,rgba(16,185,129,.2),rgba(16,185,129,.05));display:flex;align-items:center;justify-content:center;margin-right:12px;border:1px solid rgba(16,185,129,.2);box-shadow:inset 0 1px 2px rgba(0,0,0,.3)">
1053                        <svg style="width:16px;height:16px;color:#34d399" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
1054                      </div>
1055                      <div style="flex:1"><div style="height:8px;width:64px;background:#d4d4d8;border-radius:9999px;margin-bottom:8px;box-shadow:inset 0 1px 1px rgba(0,0,0,.2)"></div><div style="height:6px;width:96px;background:#525252;border-radius:9999px;box-shadow:inset 0 1px 1px rgba(0,0,0,.2)"></div></div>
1056                    </div>
1057                  </div>
1058                  <div style="position:absolute;bottom:8px;left:50%;transform:translateX(-50%);width:120px;height:4px;background:rgba(255,255,255,.2);border-radius:9999px;box-shadow:0 1px 2px rgba(0,0,0,.5)"></div>
1059                </div>
1060              </div>
1061            </div>
1062            <div class="ch-floating-badge ch-floating-ui-badge" style="position:absolute;display:flex;top:24px;left:clamp(0px, -15px, 0px);border-radius:12px;padding:12px;align-items:center;gap:12px;z-index:30;max-width:calc(100% - 16px)">
1063              <div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(180deg,rgba(230,26,26,.2),rgba(230,26,26,.1));display:flex;align-items:center;justify-content:center;border:1px solid rgba(230,26,26,.3);box-shadow:inset 0 1px 2px rgba(0,0,0,.3)"><span style="font-size:1rem" aria-hidden="true">🌸</span></div>
1064              <div><p style="color:#fff;font-size:12px;font-weight:700;letter-spacing:-.02em">Fresh Today</p><p style="color:rgba(255,107,107,.5);font-size:10px;font-weight:500">Freshness modeled</p></div>
1065            </div>
1066            <div class="ch-floating-badge ch-floating-ui-badge" style="position:absolute;display:flex;bottom:48px;right:clamp(0px, -15px, 0px);border-radius:12px;padding:12px;align-items:center;gap:12px;z-index:30;max-width:calc(100% - 16px)">
1067              <div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(180deg,rgba(124,58,237,.2),rgba(124,58,237,.1));display:flex;align-items:center;justify-content:center;border:1px solid rgba(124,58,237,.3);box-shadow:inset 0 1px 2px rgba(0,0,0,.3)"><span style="font-size:1rem" aria-hidden="true">📦</span></div>
1068              <div><p style="color:#fff;font-size:12px;font-weight:700;letter-spacing:-.02em">Delivered</p><p style="color:rgba(255,107,107,.5);font-size:10px;font-weight:500">Photo confirmed</p></div>
1069            </div>
1070          </div>
1071        </div>
1072        <div class="ch-card-left-text ch-gsap-reveal" style="order:3;display:flex;flex-direction:column;justify-content:center;text-align:center;z-index:20;width:100%;padding:0 16px">
1073          <h3 style="color:#fff;font-family:var(--fd);font-size:clamp(1.2rem,2.5vw,2.2rem);font-weight:700;margin-bottom:0;letter-spacing:-.03em">
1073Handcrafted with care.</h3>
1074          <p style="display:none;color:rgba(147,197,253,.7);font-size:clamp(.82rem,.9vw,1rem);font-weight:400;line-height:1.7;max-width:400px;margin:16px auto 0" class="ch-card-desc-desktop">Bloom empowers every flower moment with carefully crafted custom bouquets, built with passion by STI LIPA BSIT students.</p>
1075        </div>
1076      </div>
1077    </div>
1078  </div>
1079</section>
1080<section class="hero" aria-label="Hero" id="heroSec">
1081  <div class="hero-bg" aria-hidden="true" style="position:absolute;inset:0;background: radial-gradient(circle at 10% 20%, rgba(230,26,26,0.12) 0%, transparent 60%), radial-gradient(circle at 90% 80%, rgba(124,58,237,0.1) 0%, transparent 60%), var(--bg); animation: ethereal 20s cubic-bezier(0.4, 0, 0.2, 1) infinite alternate; transform-style: preserve-3d; will-change: filter, transform;"></div>
1082  <style>
1083    @keyframes ethereal { 0% { filter: hue-rotate(0deg) contrast(1); transform: scale(1) translateZ(-20px); opacity: 0.8; } 50% { filter: hue-rotate(20deg) contrast(1.1); transform: scale(1.05) translateZ(10px); opacity: 1; } 100% { filter: hue-rotate(-10deg) contrast(1.05); transform: scale(1.02) translateZ(0); opacity: 0.9; } }
1084  </style>
1085  <div class="hero-photo" id="heroPhoto" aria-hidden="true"></div>
1086  <div class="hero-bokeh" id="heroBokeh" aria-hidden="true" style="position:absolute;inset:0;background-image:none;background-size:cover;background-position:center;opacity:.28;mix-blend-mode:screen;filter:blur(3px) saturate(1.4);z-index:1;pointer-events:none;animation:bokehDrift 28s cubic-bezier(0.4, 0, 0.2, 1) infinite alternate; will-change: transform;"></div>
1087  <style>@keyframes bokehDrift{0%{transform:scale(1.05) translate3d(0,0,0) rotate(0deg); opacity: 0.25}50%{transform:scale(1.1) translate3d(-2%,-1.5%,40px) rotate(1deg); filter:blur(5px) saturate(1.6); opacity: 0.35}100%{transform:scale(1.06) translate3d(1.5%,1%,-20px) rotate(-1deg); filter:blur(4px) saturate(1.3); opacity: 0.28}}@media (prefers-reduced-motion:reduce){.hero-bokeh{animation:none!important}}</style>
1088  <canvas id="ptcl" aria-hidden="true"></canvas>
1089  <div class="hero-noise" aria-hidden="true"></div>
1090  <div class="hero-scanlines" aria-hidden="true"></div>
1091  <div class="hero-slash-1" aria-hidden="true"></div>
1092  <div class="hero-orb hero-orb-1" aria-hidden="true"></div>
1093  <div class="hero-orb hero-orb-2" aria-hidden="true"></div>
1094  <div class="con" style="width:100%">
1095    <div class="hero-grid">
1096      <div class="hero-left">
1097        <div class="hero-countdown" id="cdWrap" aria-live="polite" aria-atomic="true"></div>
1098        <div class="hero-eyebrow">
1099          <span class="hero-eyebrow-tag">Pre-order</span>
1100          <span class="hero-eyebrow-tag">Freshness-first</span>
1101          <span class="hero-eyebrow-tag">Flexible scheduling</span>
1102          <span class="hero-eyebrow-sub" data-content-key="heroBadge">Gentle care · Designed fresh · At your pace</span>
1103        </div>
1104        <h1 class="hero-hl" data-witch-frame="quad">
1105          <span data-content-key="hero_title_1">A small gesture,</span>
1106          <span id="typer" aria-live="polite">
1107            <span class="g-txt active" aria-hidden="false" data-content-key="hero_title_2">a quiet comfort.</span>
1108            <span class="g-txt" aria-hidden="true">a gentle reminder.</span>
1109            <span class="g-txt" aria-hidden="true">a little warmth.</span>
1110            <span class="g-txt" aria-hidden="true">a soft thought.</span>
1111            <span class="g-txt" aria-hidden="true">a peaceful moment.</span>
1112            <span class="g-txt" aria-hidden="true">no pressure at all.</span>
1113          </span>
1114          <em>Whenever you're ready.</em>
1115        </h1>
1116        <p class="hero-sub" data-content-key="hero_subtitle">You don't need a reason to send flowers. Handcrafted and developed by STI LIPA BSIT students, delivered gently to the door - no rush, no pressure. Just a moment of warmth, whenever it feels right.</p>
1117        <div class="hero-cta">
1118          <a href="#shop" class="btn btn-p btn-lg">Browse Gently →</a>
1119          <button class="btn btn-g btn-lg" id="profilingBtn" aria-haspopup="dialog" aria-controls="profMod">Find What Feels Right</button>
1120        </div>
1121        <div class="trust">
1122          <span class="trust-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> Photo confirmation</span>
1123          <span class="trust-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> Flexible delivery windows</span>
1124          <span class="trust-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> We'll make it right</span>
1125        </div>
1126      </div>
1127      <div class="hero-cards" id="heroCards" role="region" aria-label="Featured picks preview">
1128        <article class="h-card hc-1" id="hc1">
1129          <div class="hc-pulse" aria-hidden="true"></div>
1130          <img class="h-card-img" src="/uploads/products/crimson-vow.jpg" alt="Hand-tied bouquet of deep crimson roses with lush dark green leaves" loading="lazy" decoding="async" width="220" height="110" onerror="this.onerror=null;this.style.display='none'">
1131          <div class="hc-name">Crimson Vow</div>
1132          <div class="hc-price">₱2,480</div>
1133          <div class="hc-meta" id="hcLive">Ready within 48 hours</div>
1134        </article>
1135        <article class="h-card hc-2" id="hc2">
1136          <div class="hc-tag">Today's Pick</div>
1137          <img class="h-card-img" src="/uploads/products/neon-blossom.jpg" alt="Vibrant floral arrangement featuring neon pink ranunculus and sunflowers" loading="lazy" decoding="async" width="200" height="110" onerror="this.onerror=null;this.src='/uploads/products/crimson-vow.jpg'">
1138          <div class="hc-sub">Neon Blossom</div>
1139          <div class="hc-status">Fresh and waiting</div>
1140        </article>
1141        <article class="h-card hc-3" id="hc3">
1142          <div class="hc-tag">For Teams</div>
1143          <img class="h-card-img" src="/uploads/products/executive-crimson.jpg" alt="Professional floral arrangement with deep red amaryllis in a black granite vase" loading="lazy" decoding="async" width="210" height="110" onerror="this.onerror=null;this.src='/uploads/products/crimson-vow.jpg'">
1144          <div class="hc-sub">Thoughtful batch orders</div>
1145          <div class="hc-status">At your schedule</div>
1146        </article>
1147      </div>
1148    </div>
1149  </div>
1150</section>
1151<div class="p5-sec-div" aria-hidden="true"></div>
1152<section class="stats-strip" aria-label="Service facts">
1153  <div class="con">
1154    <div class="stats-inner">
1155      <div class="stat-item">
1156        <span class="stat-icon" aria-hidden="true">❄️</span>
1157        <div class="stat-num" id="sCold">Protocol</div>
1158        <div class="stat-bar"><div class="stat-bar-fill" data-w="100"></div></div>
1159        <div class="stat-lbl">Freshness-first logistics</div>
1160        <div class="stat-src">Based on <a href="https://postharvest.ucdavis.edu/" target="_blank" rel="noopener">UC Davis</a> guidelines</div>
1161      </div>
1162      <div class="stat-item">
1163        <span class="stat-icon" aria-hidden="true">📦</span>
1164        <div class="stat-num" id="sOrders">Beta</div>
1165        <div class="stat-bar"><div class="stat-bar-fill" data-w="25"></div></div>
1166        <div class="stat-lbl">Academic prototype</div>
1167        <div class="stat-src">Capstone project · 2026</div>
1168      </div>
1169      <div class="stat-item">
1170        <span class="stat-icon" aria-hidden="true">♿</span>
1171        <div class="stat-num" id="sWcag">AA</div>
1172        <div class="stat-bar"><div class="stat-bar-fill" data-w="95"></div></div>
1173        <div class="stat-lbl">Accessibility target</div>
1174        <div class="stat-src"><a href="https://www.w3.org/TR/WCAG21/" target="_blank" rel="noopener">WCAG 2.1</a> Level AA</div>
1175      </div>
1176      <div class="stat-item">
1177        <span class="stat-icon" aria-hidden="true">🎓</span>
1178        <div class="stat-num" id="sRating">STI</div>
1179        <div class="stat-bar"><div class="stat-bar-fill" data-w="100"></div></div>
1180        <div class="stat-lbl">Built by students</div>
1181        <div class="stat-src"><a href="https://www.sti.edu/campuses-details.asp?campus_id=LIP" target="_blank" rel="noopener">STI College Lipa</a> BSIT</div>
1182      </div>
1183    </div>
1184  </div>
1185</section>
1186<div class="p5-sec-div" aria-hidden="true"></div>
1187<section class="sec-pad" id="shop" aria-label="Shop featured products">
1188  <div class="con">
1189    <div class="sec-hd">
1190      <div>
1191        <span class="tag tag-p">Featured</span>
1192        <h2 class="sec-title">Tell us the occasion. We'll handle the flowers.</h2>
1193        <p class="sec-sub">Browse our catalog, filter by occasion, and choose what feels right. Every order includes a delivery window you pick at checkout, so it arrives when it matters most.</p>
1194      </div>
1195      <a href="/catalog.html" class="btn btn-g">View all →</a>
1196    </div>
1197    <div class="cat-wrap">
1198      <button class="cat-arrow" id="catL" aria-label="Scroll categories left" disabled>‹</button>
1199      <div class="cat-tabs" id="catTabs" role="tablist" aria-label="Product categories">
1200        <button class="cat-tab active" data-cat="all" role="tab" aria-selected="true" id="tab-all">All <span class="cat-cnt" id="cnt-all"></span></button>
1201        <button class="cat-tab" data-cat="bouquets" role="tab" aria-selected="false">💐 Bouquets <span class="cat-cnt" id="cnt-bouquets"></span></button>
1202        <button class="cat-tab" data-cat="arrangements" role="tab" aria-selected="false">🌸 Arrangements <span class="cat-cnt" id="cnt-arrangements"></span></button>
1203        <button class="cat-tab" data-cat="fresh" role="tab" aria-selected="false">🌷 Fresh <span class="cat-cnt" id="cnt-fresh"></span></button>
1204        <button class="cat-tab" data-cat="dried" role="tab" aria-selected="false">🌿 Dried <span class="cat-cnt" id="cnt-dried"></span></button>
1205        <button class="cat-tab" data-cat="corporate" role="tab" aria-selected="false">💼 Corporate <span class="cat-cnt" id="cnt-corporate"></span></button>
1206      </div>
1207      <button class="cat-arrow" id="catR" aria-label="Scroll categories right">›</button>
1208    </div>
1209    <div class="p-grid" id="pGrid" role="tabpanel" aria-labelledby="tab-all" aria-live="polite" aria-busy="true"></div>
1210  </div>
1211</section>
1212<div class="p5-sec-div" aria-hidden="true"></div>
1213<section class="feat-sec sec-pad" id="features" aria-label="Why Bloom" data-atelier-reveal data-atelier-sigil="bloom corner-tr lg">
1214  <div class="con">
1215    <div class="sec-hd" style="flex-direction:column;align-items:flex-start;text-align:left">
1216      <span class="tag tag-m">Our promise</span>
1217      <h2 class="sec-title" style="max-width:680px">What we care about when handling your order.</h2>
1218      <p class="sec-sub" style="max-width:680px">Four things we designed around from day one: keeping flowers fresh, delivering on time, making the site usable for everyone, and being honest about what we can do.</p>
1219    </div>
1220    <div class="feat-grid">
1221      <article class="feat-card anim-in">
1222        <div class="feat-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 2v6M12 22v-6M4.22 4.22l4.24 4.24M15.54 15.54l4.24 4.24M2 12h6M22 12h-6M4.22 19.78l4.24-4.24M15.54 8.46l4.24-4.24"/></svg></div>
1223        <h3 class="feat-t">Keeping flowers fresh</h3>
1224        <p class="feat-d">We follow temperature handling practices recommended by UC Davis postharvest research to help your flowers last longer after delivery.</p>
1225      </article>
1226      <article class="feat-card anim-in">
1227        <div class="feat-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg></div>
1228        <h3 class="feat-t">You pick the delivery time</h3>
1229        <p class="feat-d">At checkout, choose a delivery window that works for you, including evening slots. We do our best to deliver within that window.</p>
1230      </article>
1231      <article class="feat-card anim-in">
1232        <div class="feat-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="4"/></svg></div>
1233        <h3 class="feat-t">Designed for everyone</h3>
1234        <p class="feat-d">This site works with keyboards, screen readers, and respects reduced-motion preferences. We test against WCAG 2.1 AA accessibility standards.</p>
1235      </article>
1236      <article class="feat-card anim-in">
1237        <div class="feat-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="m9 11 3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></div>
1238        <h3 class="feat-t">We show you, not just tell you</h3>
1239        <p class="feat-d">When your order is delivered, we send a photo so you can see it arrived safely. If something doesn't look right, reach out and we'll help fix it.</p>
1240      </article>
1241    </div>
1242  </div>
1243</section>
1244<div class="p5-sec-div" aria-hidden="true"></div>
1245<section class="sec-pad" id="traceability" aria-label="Supply chain traceability" style="background:var(--bg)">
1246  <div class="con">
1247    <div class="sec-hd">
1248      <div>
1249        <span class="tag tag-m">Transparency</span>
1250        <h2 class="sec-title" style="max-width:680px">See where your flowers come from.</h2>
1251        <p class="sec-sub" style="max-width:680px">We work with growers near Lipa City, Batangas. Each order includes a QR code you can scan to see its journey from harvest to your door, with live weather data from Windy.com for each farm location.</p>
1252      </div>
1253    </div>
1254    <div style="max-width:960px;margin:0 auto" id="scGridWrap">
1255      <div id="supplyChainTrace"></div>
1256    </div>
1257  </div>
1258</section>
1259<div class="p5-sec-div" aria-hidden="true"></div>
1260<section class="rev-sec sec-pad" aria-label="Customer stories" data-atelier-reveal data-atelier-sigil="quill corner-tr">
1261  <div class="con">
1262    <div class="sec-hd">
1263      <div>
1264        <span class="tag tag-a">What people say</span>
1265        <h2 class="sec-title">Words from people who trusted us with their moment.</h2>
1266        <p class="sec-sub">These are sample testimonials representing the kind of experiences we aim to deliver. As an academic prototype, real customer reviews will appear here once the platform launches publicly.</p>
1267      </div>
1268    </div>
1269    <div class="rev-grid" id="revGrid" aria-live="polite"></div>
1270    <div class="rev-mob" id="revMob" role="region" aria-label="Review navigation">
1271      <button class="rev-navb" id="revPrev" aria-label="Previous review">‹</button>
1272      <div class="rev-dots" id="revDots" role="tablist"></div>
1273      <button class="rev-navb" id="revNext" aria-label="Next review">›</button>
1274    </div>
1275  </div>
1276</section>
1277<div class="p5-sec-div" aria-hidden="true"></div>
1278<section class="facts-sec sec-pad" aria-label="Verified facts">
1279  <div class="con">
1280    <div class="sec-hd" style="flex-direction:column;align-items:flex-start">
1281      <span class="tag tag-p">How we built this</span>
1282      <h2 class="sec-title wabi-underline" style="max-width:640px">What we used, where we learned it, and why it matters.</h2>
1283    </div>
1284    <div class="facts-grid">
1285      <article class="fact-card">
1286        <div class="fact-k">0 to 4°C</div>
1287        <div class="fact-t">Temperature-aware handling</div>
1288        <div class="fact-d">Flowers last longer when kept cool. We follow the 0 to 4°C recommended range from UC Davis postharvest research to help your arrangement stay fresh.</div>
1289        <div class="fact-src">Source: <a href="https://postharvest.ucdavis.edu/" target="_blank" rel="noopener">UC Davis Postharvest Technology Center</a></div>
1290      </article>
1291      <article class="fact-card">
1292        <div class="fact-k">BSIT</div>
1293        <div class="fact-t">Student-built from scratch</div>
1294        <div class="fact-d">Every line of code, every design decision, and every feature on this platform was built by BSIT students at STI College Lipa as a capstone project.</div>
1295        <div class="fact-src">Source: <a href="https://www.sti.edu/campuses-details.asp?campus_id=LIP" target="_blank" rel="noopener">STI College Lipa</a> · BSIT Program</div>
1296      </article>
1297      <article class="fact-card">
1298        <div class="fact-k">WCAG 2.1</div>
1299        <div class="fact-t">Accessible to more people</div>
1300        <div class="fact-d">We target Level AA. This means the site is designed to be usable by people with visual, motor, and cognitive differences, including keyboard navigation, readable contrast, and screen reader support.</div>
1301        <div class="fact-src">Source: <a href="https://www.w3.org/TR/WCAG21/" target="_blank" rel="noopener">W3C Web Content Accessibility Guidelines 2.1</a></div>
1302      </article>
1303      <article class="fact-card">
1304        <div class="fact-k">SDG 17</div>
1305        <div class="fact-t">Partnerships for the goals</div>
1306        <div class="fact-d">Bloom connects BSIT students with local flower growers in Lipa City and open-source tools like Windy.com and Web Crypto API. This forms a student, community, and technology partnership aligned with UN Sustainable Development Goal 17.</div>
1307        <div class="fact-src">Source: <a href="https://sdgs.un.org/goals/goal17" target="_blank" rel="noopener">UN SDG 17</a> · <a href="https://www.sti.edu/campuses-details.asp?campus_id=LIP" target="_blank" rel="noopener">
1307STI Lipa</a></div>
1308      </article>
1309      <article class="fact-card">
1310        <div class="fact-k">HTTPS + JWT</div>
1311        <div class="fact-t">Your data stays protected</div>
1312        <div class="fact-d">All connections use HTTPS encryption. Your password is hashed with bcrypt (never stored in plain text). Login sessions use secure, HTTP-only tokens that can't be accessed by scripts.</div>
1313        <div class="fact-src">Source: OWASP authentication cheat sheet · <a href="https://owasp.org/www-project-cheat-sheets/" target="_blank" rel="noopener">OWASP</a></div>
1314      </article>
1315      <article class="fact-card">
1316        <div class="fact-k">Photo proof</div>
1317        <div class="fact-t">You'll see it when it arrives</div>
1318        <div class="fact-d">We take a photo when your order is delivered so you know it got there safely. If anything looks off, let us know and we'll work with you to make it right.</div>
1319        <div class="fact-src">Policy: <a href="/returns.html">Bloom Service Promise</a></div>
1320      </article>
1321    </div>
1322  </div>
1323</section>
1324<div class="p5-sec-div" aria-hidden="true"></div>
1325<section class="corp-sec sec-pad" id="corp" aria-label="For teams and groups">
1326  <div class="con">
1327    <div class="corp-grid">
1328      <div class="corp-photo">
1329        <img src="/img/corporate-flowers.jpg" alt="Sleek matching minimalist floral arrangements in matte black vases on a boardroom table" loading="lazy" decoding="async" width="900" height="675" onerror="this.onerror=null;this.src='/img/vow-crimson.png'">
1330      </div>
1331      <div>
1332        <span class="tag tag-a">For Teams</span>
1333        <h2 class="sec-title" style="margin-bottom:16px" data-content-key="corpHeadline">Flowers for your team,<br>without the hassle.</h2>
1334        <p class="sec-sub" style="max-width:none;margin-bottom:18px">Whether you are celebrating a work anniversary, saying thank you to a client, or making someone's Monday better, simply tell us what you need and we will take care of the rest.</p>
1335        <ul class="corp-list">
1336          <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Custom wraps with personal notes, starting at 10 orders</li>
1337          <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Deliver weekly, monthly, or just when you need it</li>
1338          <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>One invoice for the whole batch, easy to export</li>
1339          <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Talk to a real person via email or Viber</li>
1340        </ul>
1341        <a href="mailto:[email protected]?subject=Corporate%20inquiry" class="btn btn-p btn-lg">Get in touch →</a>
1342      </div>
1343    </div>
1344  </div>
1345</section>
1346<div class="p5-sec-div" aria-hidden="true"></div>
1347<section class="subs-sec sec-pad" id="subs" aria-label="Flower subscriptions" data-atelier-reveal data-atelier-sigil="petal corner-bl">
1348  <div class="con">
1349    <div class="sec-hd" style="flex-direction:column;align-items:flex-start;text-align:left;margin-bottom:36px">
1350      <span class="tag tag-m">Recurring · Pause anytime</span>
1351      <h2 class="sec-title" style="max-width:680px">Fresh flowers on repeat, no commitment.</h2>
1352      <p class="sec-sub" style="max-width:640px">Choose how often you'd like flowers, whether weekly, every two weeks, or monthly. You can skip, swap, or cancel anytime with one click. There are no contracts and no penalties.</p>
1353    </div>
1354    <div class="subs-grid">
1355      <div class="subs-photo">
1356        <img src="/uploads/subscriptions/biweekly.jpg" alt="A subscription delivery of fresh seasonal flowers" id="subsPreviewImg" loading="lazy" decoding="async" width="800" height="600" style="transition: opacity 0.2s ease;">
1357      </div>
1358      <div class="subs-cards" role="radiogroup" aria-label="Subscription cadence">
1359        <button type="button" class="subs-card" data-sub="weekly" data-price="1499" role="radio" aria-checked="false">
1360          <div class="subs-card-hd">
1361            <div class="subs-card-name"><span data-content-key="sub_weekly_name">Weekly Bloom</span> <em>Most Loved</em></div>
1362            <div class="subs-card-price"><span data-content-key="sub_weekly_price">₱1,499</span><small> / box</small></div>
1363          </div>
1364          <div class="subs-card-d">A fresh seasonal bouquet delivered to your door every week. Our florist picks the best in season, and 
1364you can swap colors or skip anytime.</div>
1365          <div class="subs-card-feats">
1366            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Free vase, week one</span>
1367            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Skip / pause anytime</span>
1368            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Fresh handling</span>
1369          </div>
1370        </button>
1371        <button type="button" class="subs-card selected" data-sub="biweekly" data-price="2299" role="radio" aria-checked="true">
1372          <div class="subs-card-hd">
1373            <div class="subs-card-name" data-content-key="sub_biweekly_name">Biweekly Refresh</div>
1374            <div class="subs-card-price"><span data-content-key="sub_biweekly_price">₱2,299</span><small> / box</small></div>
1375          </div>
1376          <div class="subs-card-d">A bigger bouquet delivered every two weeks. Great for offices, living rooms, or anywhere that deserves regular fresh flowers.</div>
1377          <div class="subs-card-feats">
1378            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>40% larger</span>
1379            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Locked rate, 12 weeks</span>
1380            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Photo proof</span>
1381          </div>
1382        </button>
1383        <button type="button" class="subs-card" data-sub="monthly" data-price="3499" role="radio" aria-checked="false">
1384          <div class="subs-card-hd">
1385            <div class="subs-card-name" data-content-key="sub_monthly_name">Monthly Statement</div>
1386            <div class="subs-card-price"><span data-content-key="sub_monthly_price">₱3,499</span><small> / box</small></div>
1387          </div>
1388          <div class="subs-card-d">One stunning arrangement each month featuring premium flowers, hand-tied wrapping, and a handwritten note from our team.</div>
1389          <div class="subs-card-feats">
1390            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Premium varietals</span>
1391            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Handwritten note</span>
1392            <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6 9 17l-5-5"/></svg>Free shipping</span>
1393          </div>
1394        </button>
1395        <div class="subs-cta">
1396          <button type="button" class="btn btn-g" id="subsLearn">How it works</button>
1397          <button type="button" class="btn btn-p" id="subsStart">Start subscription →</button>
1398        </div>
1399      </div>
1400    </div>
1401  </div>
1402</section>
1403<div class="p5-sec-div" aria-hidden="true"></div>
1404<section class="sec-pad" id="supportUs" aria-label="Support the project" style="background:var(--bg)">
1405  <div class="con">
1406    <div id="supportUsContent"></div>
1407  </div>
1408</section>
1409<footer class="bloom-foot" role="contentinfo">
1410  <div class="con">
1411    <div class="foot-grid">
1412      <div>
1413        <div class="foot-brand">Bloom</div>
1414        <p class="foot-tag" data-content-key="footerTagline">Fresh flowers, delivered with care. A BSIT capstone project by STI College Lipa.</p>
1415        <form class="nl-form" id="nlForm" aria-label="Newsletter signup">
1416          <input type="email" class="nl-inp" id="nlEmail" placeholder="[email protected]" aria-label="Email address" required>
1417          <button type="submit" class="btn btn-p btn-sm">Join</button>
1418        </form>
1419      </div>
1420      <div class="foot-col">
1421        <h4>Shop</h4>
1422        <ul role="list">
1423          <li><a href="/catalog.html">All products</a></li>
1424          <li><a href="/catalog.html?category=bouquets">Bouquets</a></li>
1425          <li><a href="/catalog.html?category=arrangements">Arrangements</a></li>
1426          <li><a href="/catalog.html?category=corporate">Corporate</a></li>
1427        </ul>
1428      </div>
1429      <div class="foot-col">
1430        <h4>Company</h4>
1431        <ul role="list">
1432          <li><a href="/about.html">Our team</a></li>
1433          <li><a href="/#corp">Corporate</a></li>
1434          <li><a href="/blog.html">Journal</a></li>
1435          <li><a href="/contact.html">Contact</a></li>
1436        </ul>
1437      </div>
1438      <div class="foot-col">
1439        <h4>Support</h4>
1440        <ul role="list">
1441          <li><a href="/support.html#faqSection">FAQ</a></li>
1442          <li><a href="/shipping.html">Shipping</a></li>
1443          <li><a href="/returns.html">Service Promise</a></li>
1444          <li><a href="/privacy.html">Privacy Policy</a></li>
1445          <li><a href="/terms.html">Terms of Service</a></li>
1446          <li><a href="/disclaimer.html">Disclaimer</a></li>
1447          <li><a href="/cookie-policy.html">Cookie Policy</a></li>
1448        </ul>
1449      </div>
1450    </div>
1451    <div class="foot-bottom">
1452      <div>© <span id="yr">2026</span> Bloom · Handcrafted in the Philippines</div>
1453      <div class="foot-soc">
1454        <a href="https://instagram.com/" aria-label="Instagram" target="_blank" rel="noopener noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2" y="2" width="20" height="20" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor"/></svg></a>
1455        <a href="https://facebook.com/" aria-label="Facebook" target="_blank" rel="noopener noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3Z"/></svg></a>
1456        <a href="mailto:[email protected]" aria-label="Email"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 6-10 7L2 6"/></svg></a>
1457      </div>
1458    </div>
1459  </div>
1460</footer>
1461<section class="sec-pad section-lazy" id="recentSec" style="display:none" aria-label="Recently Viewed">
1462  <div class="con">
1463    <div class="sec-hd">
1464      <div>
1465        <div class="tag tag-a"><span aria-hidden="true">//</span> History</div>
1466        <h2 class="sec-title" data-i18n="section.recently">Recently Viewed</h2>
1467      </div>
1468    </div>
1469    <div class="p-grid" id="recentGrid" role="list" aria-live="polite" style="grid-template-columns:repeat(auto-fill,minmax(220px,1fr))"></div>
1470  </div>
1471</section>
1472<button class="btt" id="btt" aria-label="Back to top">↑</button>
1473</main>
1474<div class="overlay" id="exitMod" role="dialog" aria-modal="true" aria-labelledby="exitTitle" aria-hidden="true" style="display:none">
1475  <div class="modal" style="max-width:440px;text-align:center;padding:40px 32px">
1476    <button class="m-cls" id="closeExit" aria-label="Close">✕</button>
1477    <div style="font-size:3rem;margin-bottom:16px" aria-hidden="true">🌸</div>
1478    <h2 id="exitTitle" style="font-family:var(--fd);font-size:1.6rem;font-weight:900;margin-bottom:10px" data-i18n="exit.title">Wait - don't leave empty-handed!</h2>
1479    <p class="m-sub" style="margin-bottom:24px" data-i18n="exit.subtitle">Get 10% off your first order</p>
1480    <div class="fi" style="margin-bottom:16px">
1481      <div class="fi-wrap"><input type="email" class="fi-inp" id="exitEmail" placeholder="[email protected]" aria-label="Email for discount"></div>
1482    </div>
1483    <button class="btn btn-p btn-lg" style="width:100%;justify-content:center;margin-bottom:12px" id="exitCta" data-i18n="exit.cta">Claim My Discount</button>
1484    <button class="btn btn-g btn-sm" style="width:100%;justify-content:center" id="exitDismiss" data-i18n="exit.dismiss">No thanks</button>
1485  </div>
1486</div>
1487<div class="overlay" id="authMod" role="dialog" aria-modal="true" aria-labelledby="authTitle" aria-hidden="true">
1488  <div class="modal">
1489    <div class="m-hd">
1490      <h2 id="authTitle" style="font-family:var(--fd);font-size:1.5rem;font-weight:700">Welcome to Bloom</h2>
1491      <button class="m-cls" id="closeAuth" aria-label="Close dialog">✕</button>
1492    </div>
1493    <div class="a-tabs" role="tablist">
1494      <button class="a-tab active" data-ftab="login" role="tab" aria-selected="true">Sign In</button>
1495      <button class="a-tab" data-ftab="register" role="tab" aria-selected="false">Register</button>
1496      <button class="a-tab" data-ftab="guest" role="tab" aria-selected="false">Guest</button>
1497    </div>
1498    <div class="err-summary" id="loginErrSum" role="alert" aria-live="assertive">
1499      <h4><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>Please fix the following:</h4>
1500      <ul></ul>
1501    </div>
1502    <form id="loginF" onsubmit="event.preventDefault();">
1503      <div class="fi">
1504        <label class="fi-lbl" for="lEmail">Email</label>
1505        <div class="fi-wrap">
1506          <input type="email" class="fi-inp" id="lEmail" placeholder="[email protected]" autocomplete="email" aria-describedby="lEmailE" required>
1507        </div>
1508        <span class="fe" id="lEmailE" role="alert"></span>
1509      </div>
1510      <div class="fi">
1511        <label class="fi-lbl" for="lPass">Password</label>
1512        <div class="fi-wrap">
1513          <input type="password" class="fi-inp" id="lPass" placeholder="••••••••" autocomplete="current-password" aria-describedby="lPassE" required>
1514          <button type="button" class="pw-tog" data-for="lPass" aria-label="Toggle password visibility">show</button>
1515        </div>
1516        <span class="fe" id="lPassE" role="alert"></span>
1517      </div>
1518      <button type="button" class="fpl-btn" id="fplBtn">Forgot password?</button>
1519      <button class="btn btn-p" style="width:100%;justify-content:center;margin-top:6px" id="lSubmit">Sign In →</button>
1520    </form>
1521    <form id="registerF" style="display:none" onsubmit="event.preventDefault();">
1522      <div class="err-summary" id="regErrSum" role="alert" aria-live="assertive">
1523        <h4><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>Please fix the following:</h4>
1524        <ul></ul>
1525      </div>
1526      <div class="fi">
1527        <label class="fi-lbl" for="rName">Name</label>
1528        <div class="fi-wrap"><input type="text" class="fi-inp" id="rName" placeholder="Your name" autocomplete="name" aria-describedby="rNameE" required></div>
1529        <span class="fe" id="rNameE" role="alert"></span>
1530      </div>
1531      <div class="fi">
1532        <label class="fi-lbl" for="rEmail">Email</label>
1533        <div class="fi-wrap"><input type="email" class="fi-inp" id="rEmail" placeholder="[email protected]" autocomplete="email" aria-describedby="rEmailE" required></div>
1534        <span class="fe" id="rEmailE" role="alert"></span>
1535      </div>
1536      <div class="fi">
1537        <label class="fi-lbl" for="rPass">Password</label>
1538        <div class="fi-wrap">
1539          <input type="password" class="fi-inp" id="rPass" placeholder="Min 8 characters" autocomplete="new-password" aria-describedby="rStrE" required minlength="8">
1540          <button type="button" class="pw-tog" data-for="rPass" aria-label="Toggle password visibility">show</button>
1541        </div>
1542        <div id="rStrE" aria-live="polite"><div class="str-bar"><div class="str-fill" id="strFill"></div></div><span class="str-lbl" id="strLbl"></span></div>
1543        <span class="fe" id="rPassE" role="alert"></span>
1544      </div>
1545      <button class="btn btn-p" style="width:100%;justify-content:center;margin-top:6px" id="rSubmit">Create Account →</button>
1546    </form>
1547    <div id="guestF" style="display:none;text-align:center;padding:14px 0">
1548      <p class="m-sub">Browse and pre-order without an account. You can claim your order with the confirmation email later.</p>
1549      <button class="btn btn-p" style="width:100%;justify-content:center" id="gSubmit">Continue as Guest →</button>
1550    </div>
1551  </div>
1552</div>
1553<div class="overlay" id="profMod" role="dialog" aria-modal="true" aria-labelledby="profTitle" aria-hidden="true">
1554  <div class="modal">
1555    <div class="m-hd">
1556      <div>
1557        <h2 id="profTitle" style="font-family:var(--fd);font-size:1.4rem;font-weight:700">What's the occasion?</h2>
1558        <p class="m-sub" style="margin-top:6px;margin-bottom:0">Pick one. We'll tune the catalog and pricing tier to match.</p>
1559      </div>
1560      <button class="m-cls" id="closeProf" aria-label="Close dialog">✕</button>
1561    </div>
1562    <div class="occ-grid" role="radiogroup" aria-label="Occasion">
1563      <button class="occ-btn" data-occ="birthday" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">🎂</span>Birthday</button>
1564      <button class="occ-btn" data-occ="anniversary" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">💐</span>Anniversary</button>
1565      <button class="occ-btn" data-occ="wedding" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">💒</span>Wedding</button>
1566      <button class="occ-btn" data-occ="sympathy" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">🕊️</span>Sympathy</button>
1567      <button class="occ-btn" data-occ="congrats" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">🎓</span>Congrats</button>
1568      <button class="occ-btn" data-occ="just-because" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">🌻</span>Just because</button>
1569      <button class="occ-btn" data-occ="corporate" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">💼</span>Corporate</button>
1570      <button class="occ-btn" data-occ="thanks" role="radio" aria-checked="false"><span class="occ-emj" aria-hidden="true">🙏</span>Thanks</button>
1571    </div>
1572    <div style="display:flex;gap:10px">
1573      <button class="btn btn-g" style="flex:1;justify-content:center" id="profSkip">Skip</button>
1574      <button class="btn btn-p" style="flex:2;justify-content:center" id="profSubmit">Show My Picks →</button>
1575    </div>
1576  </div>
1577</div>
1578<div class="overlay" id="qvMod" role="dialog" aria-modal="true" aria-labelledby="qvTitle" aria-hidden="true">
1579  <div class="modal" style="max-width:560px">
1580    <div class="m-hd">
1581      <h2 id="qvTitle" style="font-family:var(--fd);font-size:1.35rem;font-weight:700"></h2>
1582      <button class="m-cls" id="closeQv" aria-label="Close dialog">✕</button>
1583    </div>
1584    <div id="qvContent"></div>
1585  </div>
1586</div>
1587<div class="overlay" id="fplMod" role="dialog" aria-modal="true" aria-labelledby="fplTitle" aria-hidden="true">
1588  <div class="modal">
1589    <div class="m-hd">
1590      <h2 id="fplTitle" style="font-family:var(--fd);font-size:1.35rem;font-weight:700">Reset Password</h2>
1591      <button class="m-cls" id="closeFpl" aria-label="Close dialog">✕</button>
1592    </div>
1593    <p class="m-sub">Enter your email. We'll send a secure reset link within 60 seconds.</p>
1594    <div class="fi">
1595      <label class="fi-lbl" for="fplEmail">Email</label>
1596      <div class="fi-wrap"><input type="email" class="fi-inp" id="fplEmail" placeholder="[email protected]" required></div>
1597      <span class="fe" id="fplEmailE" role="alert"></span>
1598    </div>
1599    <button class="btn btn-p" style="width:100%;justify-content:center" id="fplSubmit">Send Reset Link →</button>
1600  </div>
1601</div>
1602<div class="wl-drawer" id="wlDrawer" role="dialog" aria-modal="true" aria-labelledby="wlDrawerTitle" aria-hidden="true">
1603  <div class="wl-drawer-hd">
1604    <div>
1605      <h3 id="wlDrawerTitle">Wishlist</h3>
1606      <small><span id="wlCount">0</span> saved</small>
1607    </div>
1608    <button type="button" class="wl-drawer-cls" id="wlDrawerCls" aria-label="Close wishlist">✕</button>
1609  </div>
1610  <div class="wl-drawer-body" id="wlDrawerBody">
1611    <div class="wl-empty" id="wlEmpty">
1612      <div class="wl-empty-ico" aria-hidden="true">♡</div>
1613      <h4 style="font-family:var(--fd);font-weight:700;font-size:1rem;margin-bottom:6px">Nothing saved yet</h4>
1614      <p style="font-size:.84rem;line-height:1.6">Tap the heart on any bouquet to save it. Your wishlist syncs across devices when you sign in.</p>
1615    </div>
1616  </div>
1617  <div class="wl-drawer-ft">
1618    <button type="button" class="btn btn-p" id="wlClear" style="width:100%;justify-content:center" hidden>Clear all</button>
1619  </div>
1620</div>
1621<button type="button" class="voice-fab" id="voiceFab" aria-label="Voice navigation - press and speak" aria-pressed="false" hidden>
1622  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 2a3 3 0 0 0-3 3v6a3 3 0 1 0 6 0V5a3 3 0 0 0-3-3z"/><path d="M19 10v1a7 7 0 0 1-14 0v-1"/><path d="M12 18v4"/><path d="M8 22h8"/></svg>
1623</button>
1624<div class="voice-status" id="voiceStatus" aria-live="polite" role="status"><small>Listening</small><span id="voiceText">Try: "Show bouquets" or "Open cart"</span></div>
1625<div class="funnel-bar" id="funnelBar" aria-label="Browsing progress" role="status">
1626  <div class="funnel-track">
1627    <span class="funnel-step active" data-step="hero">Hero</span>
1628    <span class="funnel-conn" aria-hidden="true"></span>
1629    <span class="funnel-step" data-step="shop">Shop</span>
1630    <span class="funnel-conn" aria-hidden="true"></span>
1631    <span class="funnel-step" data-step="subs">Subscribe</span>
1632    <span class="funnel-conn" aria-hidden="true"></span>
1633    <span class="funnel-step" data-step="cart">Cart</span>
1634    <span class="funnel-conn" aria-hidden="true"></span>
1635    <span class="funnel-step" data-step="checkout">Checkout</span>
1636  </div>
1637</div>
1638<div class="toast-con" id="toastCon" aria-live="polite" aria-atomic="false" role="status"></div>
1639<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/motion.js" defer></script>
vendor: 2 bytes, line 1639
1639
1640<script src="/socket.io/socket.io.js" defer></script>
vendor: 2 bytes, line 1640
1640
1641<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/motion.js"></script>
vendor: 1 bytes, line 1641
1641
1642<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
vendor: 1 bytes, line 1642
1642
1643<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ScrollTrigger.min.js"></script>
vendor: 1 bytes, line 1643
1643
1644<script src="/js/core.bundle.min.js"></script>
vendor: 1 bytes, line 1644
1644
1645<script src="/js/core/AmbientAudio.js" defer></script>
vendor: 2 bytes, line 1645
1645
1646<script src="/js/core/BloomCursor.js" defer></script>
vendor: 2 bytes, line 1646
1646
1647<script src="/js/core/ExhibitTicketing.js" defer></script>
vendor: 2 bytes, line 1647
1647
1648<script src="/js/core/ExpoGallery.js" defer></script>
vendor: 2 bytes, line 1648
1648
1649<script src="/js/core/AtelierForge.js" defer></script>
vendor: 2 bytes, line 1649
1649
1650<script>
1651(function () {
1652  'use strict';
1653  var Api = window.Api;
1654  var Store = window.Store;
1655  function qs(s, r) { return (r || document).querySelector(s); }
1656  function qsa(s, r) { return Array.from((r || document).querySelectorAll(s)); }
1657  function on(el, ev, fn, o) { if (el) el.addEventListener(ev, fn, o || false); }
1658  function reducedMotion() { return window.matchMedia('(prefers-reduced-motion: reduce)').matches; }
1659  function escapeHtml(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c]; }); }
1660  function money(n) { return '\u20B1' + Number(n || 0).toLocaleString('en-PH', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }
1661  var FALLBACK_IMG = '/uploads/products/crimson-vow.jpg';
1662  var FALLBACK_CAT_IMG = {
1663    bouquets: '/uploads/products/crimson-vow.jpg',
1664    arrangements: '/uploads/products/neon-blossom.jpg',
1665    fresh: '/uploads/products/velvet-midnight.jpg',
1666    dried: '/uploads/products/obsidian-rose.jpg',
1667    corporate: '/uploads/products/executive-crimson.jpg'
1668  };
1669  var FALLBACK_PRODUCTS = [];
1670  var FEATURED_REVIEWS = [
1671    { name: 'Maria C.', rating: 5, body: "I ordered flowers for my mom's birthday and they arrived looking even better than the photos. The silk wrap was beautiful and the delivery was right on time.", role: 'Sample · Birthday' },
1672    { name: 'James R.', rating: 5, body: 'We needed 40 matching bouquets for a company event. The ordering process was straightforward and every arrangement looked consistent. Will definitely order again.', role: 'Sample · Corporate' },
1673    { name: 'Ana S.', rating: 5, body: 'Surprised my wife with an evening delivery on our anniversary. Getting the photo confirmation before she even called me was a really nice touch.', role: 'Sample · Anniversary' },
1674    { name: 'Carlo M.', rating: 5, body: 'Sent flowers to a friend who was going through a hard time. Bloom handled the personal note carefully and delivered within the time window I picked.', role: 'Sample · Sympathy' },
1675    { name: 'Rina L.', rating: 5, body: 'Just wanted to brighten up my partner\u2019s Tuesday. Pre-ordered on Saturday, arrived Tuesday evening as planned. Still fresh a week later.', role: 'Sample · Just because' }
1676  ];
1677  var toastCount = 0;
1678  var MAX_TOASTS = 5;
1679  window.showToast = function (msg, type) {
1680    type = type || 'info';
1681    var con = qs('#toastCon');
1682    if (!con) return;
1683    if (toastCount >= MAX_TOASTS) return;
1684    toastCount++;
1685    var icons = { success: '\u2714', error: '\u2715', info: '\u25C6' };
1686    var t = document.createElement('div');
1687    t.className = 'toast toast-' + type;
1688    t.setAttribute('role', type === 'error' ? 'alert' : 'status');
1689    t.innerHTML = '<span class="toast-ico" aria-hidden="true">' + icons[type] + '</span><span>' + escapeHtml(msg) + '</span>';
1690    con.appendChild(t);
1691    setTimeout(function () {
1692      t.style.opacity = '0';
1693      t.style.transform = 'translateX(80px)';
1694      t.style.transition = 'all .3s var(--ease)';
1695      setTimeout(function () { t.remove(); toastCount--; }, 320);
1696    }, 3800);
1697  };
1698  var showToast = window.showToast;
1699  function initCursor() {
1700    if (window.matchMedia('(pointer: coarse)').matches || window.matchMedia('(hover: none)').matches) return;
1701    var dot = qs('#cDot');
1702    var ring = qs('#cRing');
1703    if (!dot || !ring) return;
1704    var mx = window.innerWidth / 2, my = window.innerHeight / 2;
1705    var rx = mx, ry = my;
1706    on(window, 'mousemove', function (e) { mx = e.clientX; my = e.clientY; dot.style.transform = 'translate3d(' + mx + 'px,' + my + 'px,0) translate(-50%,-50%)'; });
1707    (function frame() { rx += (mx - rx) * 0.18; ry += (my - ry) * 0.18; ring.style.transform = 'translate3d(' + rx + 'px,' + ry + 'px,0) translate(-50%,-50%)'; requestAnimationFrame(frame); })();
1708    qsa('a, button, input, textarea, select, [role="button"], [role="tab"], [role="option"]').forEach(function (el) {
1709      on(el, 'pointerenter', function () { document.body.classList.add('c-hover'); });
1710      on(el, 'pointerleave', function () { document.body.classList.remove('c-hover'); });
1711    });
1712    var mo = new MutationObserver(function () {
1713      qsa('a, button, input, textarea, select, [role="button"], [role="tab"], [role="option"]').forEach(function (el) {
1714        if (el._cbnd) return;
1715        el._cbnd = 1;
1716        on(el, 'pointerenter', function () { document.body.classList.add('c-hover'); });
1717        on(el, 'pointerleave', function () { document.body.classList.remove('c-hover'); });
1718      });
1719    });
1720    mo.observe(document.body, { childList: true, subtree: true });
1721  }
1722  function initParticles() {
1723    var c = qs('#ptcl');
1724    if (!c || reducedMotion()) return;
1725    var ctx = c.getContext('2d', { alpha: true });
1726    var parts = [];
1727    var dpr = Math.min(window.devicePixelRatio || 1, 2);
1728    var cores = navigator.hardwareConcurrency || 4;
1729    var mem = navigator.deviceMemory || 4;
1730    var isMobile = window.matchMedia('(max-width: 768px)').matches;
1731    var perfTier = (cores >= 8 && mem >= 8) ? 'high' : (cores >= 4 && mem >= 4) ? 'mid' : 'low';
1732    var baseCount = isMobile ? 18 : (perfTier === 'high' ? 80 : perfTier === 'mid' ? 48 : 24);
1733    var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
1734    if (connection && (connection.saveData || /2g|slow-2g/.test(connection.effectiveType || ''))) baseCount = Math.min(baseCount, 14);
1735    if (window.matchMedia('(prefers-reduced-data: reduce)').matches) baseCount = Math.min(baseCount, 14);
1736    var connectDist = isMobile ? 100 : 140;
1737    var mouseX = -9999, mouseY = -9999, mouseActive = false;
1738    on(c.parentElement || c, 'mousemove', function (e) {
1739      var r = c.getBoundingClientRect();
1740      mouseX = (e.clientX - r.left) * dpr;
1741      mouseY = (e.clientY - r.top) * dpr;
1742      mouseActive = true;
1743    });
1744    on(c.parentElement || c, 'mouseleave', function () { mouseActive = false; });
1745    function size() {
1746      var hero = qs('#heroSec');
1747      if (!hero) return;
1748      var r = hero.getBoundingClientRect();
1749      c.width = r.width * dpr;
1750      c.height = r.height * dpr;
1751      c.style.width = r.width + 'px';
1752      c.style.height = r.height + 'px';
1753    }
1754    size();
1755    on(window, 'resize', size);
1756    var depthLayers = [
1757      { speed: 0.3, sizeMin: 0.4, sizeMax: 1.2, opacity: 0.15, count: Math.floor(baseCount * 0.35) },
1758      { speed: 0.6, sizeMin: 0.8, sizeMax: 2.0, opacity: 0.35, count: Math.floor(baseCount * 0.4) },
1759      { speed: 1.0, sizeMin: 1.4, sizeMax: 3.0, opacity: 0.55, count: Math.floor(baseCount * 0.25) }
1760    ];
1761    var hueChoices = ['p5', 'pk', 'mn', 'gd', 'w'];
1762    depthLayers.forEach(function (layer, li) {
1763      for (var i = 0; i < layer.count; i++) {
1764        var h = hueChoices[Math.floor(Math.random() * hueChoices.length)];
1765        parts.push({
1766          x: Math.random() * (c.width || 1920), y: Math.random() * (c.height || 1080),
1767          r: Math.random() * (layer.sizeMax - layer.sizeMin) + layer.sizeMin,
1768          vx: (Math.random() - 0.5) * 0.4 * layer.speed,
1769          vy: -(Math.random() * 0.5 + 0.08) * layer.speed,
1770          o: Math.random() * layer.opacity + 0.1,
1771          baseO: layer.opacity,
1772          hue: h,
1773          layer: li,
1774          phase: Math.random() * Math.PI * 2,
1775          pulseSpeed: Math.random() * 0.02 + 0.008,
1776          wobbleAmp: Math.random() * 0.3 + 0.1
1777        });
1778      }
1779    });
1780    var auroraPhase = 0;
1781    var time = 0;
1782    var raf;
1783    var visible = true;
1784    var io = new IntersectionObserver(function (es) { es.forEach(function (e) { visible = e.isIntersecting; }); }, { threshold: 0.01 });
1785    io.observe(c);
1786    function getColor(hue, alpha) {
1787      if (hue === 'p5') return 'rgba(230,26,26,' + alpha + ')';
1788      if (hue === 'pk') return 'rgba(238,90,160,' + alpha + ')';
1789      if (hue === 'mn') return 'rgba(0,212,170,' + alpha + ')';
1790      if (hue === 'gd') return 'rgba(255,215,0,' + alpha + ')';
1791      return 'rgba(255,255,255,' + (alpha * 0.7) + ')';
1792    }
1793    function frame() {
1794      raf = requestAnimationFrame(frame);
1795      if (!visible) return;
1796      time += 0.016;
1797      auroraPhase += 0.003;
1798      ctx.clearRect(0, 0, c.width, c.height);
1799      /* --- Ethereal aurora waves --- */
1800      if (!isMobile || perfTier !== 'low') {
1801        ctx.save();
1802        ctx.globalCompositeOperation = 'screen';
1803        for (var aw = 0; aw < 3; aw++) {
1804          var auroraY = c.height * (0.25 + aw * 0.2);
1805          var gradient = ctx.createLinearGradient(0, auroraY - 80 * dpr, 0, auroraY + 80 * dpr);
1806          var auroraColors = [
1807            ['rgba(230,26,26,0.025)', 'rgba(238,90,160,0.04)', 'rgba(230,26,26,0.025)'],
1808            ['rgba(124,58,237,0.02)', 'rgba(0,212,170,0.03)', 'rgba(124,58,237,0.02)'],
1809            ['rgba(238,90,160,0.018)', 'rgba(255,215,0,0.025)', 'rgba(238,90,160,0.018)']
1810          ];
1811          gradient.addColorStop(0, auroraColors[aw][0]);
1812          gradient.addColorStop(0.5, auroraColors[aw][1]);
1813          gradient.addColorStop(1, auroraColors[aw][2]);
1814          ctx.fillStyle = gradient;
1815          ctx.beginPath();
1816          ctx.moveTo(0, auroraY);
1817          for (var ax = 0; ax <= c.width; ax += 4) {
1818            var waveY = auroraY + Math.sin(ax * 0.003 + auroraPhase + aw * 1.8) * 40 * dpr
1819              + Math.sin(ax * 0.007 - auroraPhase * 0.7 + aw) * 20 * dpr
1820              + Math.cos(ax * 0.0015 + time * 0.5) * 30 * dpr;
1821            ctx.lineTo(ax, waveY);
1822          }
1823          ctx.lineTo(c.width, c.height);
1824          ctx.lineTo(0, c.height);
1825          ctx.closePath();
1826          ctx.fill();
1827        }
1828        ctx.restore();
1829      }
1830      /* --- Mouse reactive glow --- */
1831      if (mouseActive && !isMobile) {
1832        ctx.save();
1833        ctx.globalCompositeOperation = 'screen';
1834        var glowRad = 180 * dpr;
1835        var mg = ctx.createRadialGradient(mouseX, mouseY, 0, mouseX, mouseY, glowRad);
1836        mg.addColorStop(0, 'rgba(230,26,26,0.08)');
1837        mg.addColorStop(0.3, 'rgba(238,90,160,0.04)');
1838        mg.addColorStop(0.6, 'rgba(124,58,237,0.02)');
1839        mg.addColorStop(1, 'rgba(0,0,0,0)');
1840        ctx.fillStyle = mg;
1841        ctx.fillRect(mouseX - glowRad, mouseY - glowRad, glowRad * 2, glowRad * 2);
1842        ctx.restore();
1843      }
1844      /* --- Constellation connections --- */
1845      if (perfTier !== 'low') {
1846        ctx.save();
1847        ctx.globalCompositeOperation = 'screen';
1848        var cd2 = connectDist * connectDist * dpr * dpr;
1849        for (var ci = 0; ci < parts.length; ci++) {
1850          for (var cj = ci + 1; cj < parts.length; cj++) {
1851            if (parts[ci].layer !== parts[cj].layer) continue;
1852            var dx = parts[ci].x - parts[cj].x;
1853            var dy = parts[ci].y - parts[cj].y;
1854            var d2 = dx * dx + dy * dy;
1855            if (d2 < cd2) {
1856              var dist = Math.sqrt(d2);
1857              var lineAlpha = (1 - dist / (connectDist * dpr)) * 0.12 * Math.min(parts[ci].o, parts[cj].o);
1858              ctx.beginPath();
1859              ctx.moveTo(parts[ci].x, parts[ci].y);
1860              ctx.lineTo(parts[cj].x, parts[cj].y);
1861              ctx.strokeStyle = getColor(parts[ci].hue, lineAlpha);
1862              ctx.lineWidth = 0.5 * dpr;
1863              ctx.stroke();
1864            }
1865          }
1866        }
1867        ctx.restore();
1868      }
1869      /* --- Particles with glow halos --- */
1870      for (var k = 0; k < parts.length; k++) {
1871        var p = parts[k];
1872        p.phase += p.pulseSpeed;
1873        var pulse = 0.7 + Math.sin(p.phase) * 0.3;
1874        p.x += (p.vx + Math.sin(time * 0.5 + p.phase) * p.wobbleAmp) * dpr;
1875        p.y += p.vy * dpr;
1876        /* Mouse attraction for foreground particles */
1877        if (mouseActive && !isMobile && p.layer === 2) {
1878          var mdx = mouseX - p.x;
1879          var mdy = mouseY - p.y;
1880          var md = Math.sqrt(mdx * mdx + mdy * mdy);
1881          if (md < 200 * dpr && md > 0) {
1882            var force = (1 - md / (200 * dpr)) * 0.4;
1883            p.x += (mdx / md) * force * dpr;
1884            p.y += (mdy / md) * force * dpr;
1885          }
1886        }
1887        if (p.y < -10) { p.y = c.height + 10; p.x = Math.random() * c.width; }
1888        if (p.x < -10) p.x = c.width + 10;
1889        if (p.x > c.width + 10) p.x = -10;
1890        var drawO = p.o * pulse;
1891        /* Glow halo for larger/foreground particles */
1892        if (p.layer >= 1 && p.r > 1.2) {
1893          ctx.save();
1894          ctx.globalCompositeOperation = 'screen';
1895          var gr = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.r * 4 * dpr);
1896          gr.addColorStop(0, getColor(p.hue, drawO * 0.3));
1897          gr.addColorStop(0.5, getColor(p.hue, drawO * 0.08));
1898          gr.addColorStop(1, 'rgba(0,0,0,0)');
1899          ctx.fillStyle = gr;
1900          ctx.fillRect(p.x - p.r * 4 * dpr, p.y - p.r * 4 * dpr, p.r * 8 * dpr, p.r * 8 * dpr);
1901          ctx.restore();
1902        }
1903        ctx.beginPath();
1904        ctx.arc(p.x, p.y, p.r * dpr * (0.9 + pulse * 0.1), 0, Math.PI * 2);
1905        ctx.fillStyle = getColor(p.hue, drawO);
1906        ctx.fill();
1907      }
1908    }
1909    frame();
1910    document.addEventListener('visibilitychange', function () { if (document.hidden) cancelAnimationFrame(raf); else frame(); });
1911  }
1912  function initHeroParallax() {
1913    if (reducedMotion()) return;
1914    var hero = qs('#heroSec');
1915    if (!hero) return;
1916    var tx = 0, ty = 0, cx = 0, cy = 0;
1917    on(hero, 'mousemove', function (e) {
1918      var r = hero.getBoundingClientRect();
1919      tx = ((e.clientX - r.left) / r.width - 0.5) * 2;
1920      ty = ((e.clientY - r.top) / r.height - 0.5) * 2;
1921    });
1922    on(hero, 'mouseleave', function () { tx = 0; ty = 0; });
1923    (function frame() {
1924      cx += (tx - cx) * 0.08;
1925      cy += (ty - cy) * 0.08;
1926      hero.style.setProperty('--px', cx.toFixed(3));
1927      hero.style.setProperty('--py', cy.toFixed(3));
1928      requestAnimationFrame(frame);
1929    })();
1930    qsa('.h-card').forEach(function (card) {
1931      var lx = 0, ly = 0, rx = 0, ry = 0;
1932      on(card, 'mousemove', function (e) {
1933        var r = card.getBoundingClientRect();
1934        lx = ((e.clientX - r.left) / r.width - 0.5) * 2;
1935        ly = ((e.clientY - r.top) / r.height - 0.5) * 2;
1936        card.style.setProperty('--mx', ((lx + 1) * 50) + '%');
1937        card.style.setProperty('--my', ((ly + 1) * 50) + '%');
1938      });
1939      on(card, 'mouseleave', function () { lx = 0; ly = 0; });
1940      (function f() {
1941        rx += (lx - rx) * 0.14;
1942        ry += (ly - ry) * 0.14;
1943        var z = card.classList.contains('hc-1') ? 40 : (card.classList.contains('hc-2') ? 10 : 25);
1944        var tf = 'translateZ(' + z + 'px) rotateY(' + (rx * 6) + 'deg) rotateX(' + (-ry * 6) + 'deg)';
1945        if (card.classList.contains('hc-1')) tf = 'translateX(-50%) ' + tf;
1946        card.style.transform = tf;
1947        requestAnimationFrame(f);
1948      })();
1949    });
1950  }
1951  function initNav() {
1952    var nav = qs('#nav');
1953    var last = 0;
1954    function onScroll() {
1955      var y = window.scrollY || window.pageYOffset;
1956      if (y > 12) nav.classList.add('sc'); else nav.classList.remove('sc');
1957      last = y;
1958    }
1959    onScroll();
1960    on(window, 'scroll', onScroll, { passive: true });
1961    var hmb = qs('#hmb');
1962    var mob = qs('#mobMenu');
1963    var mobCls = qs('#mobClose');
1964    on(hmb, 'click', function () {
1965      var open = mob.classList.toggle('open');
1966      hmb.setAttribute('aria-expanded', String(open));
1967      mob.setAttribute('aria-hidden', String(!open));
1968      document.body.classList.toggle('modal-open', open);
1969    });
1970    on(mobCls, 'click', function () {
1971      mob.classList.remove('open');
1972      hmb.setAttribute('aria-expanded', 'false');
1973      mob.setAttribute('aria-hidden', 'true');
1974      document.body.classList.remove('modal-open');
1975    });
1976    qsa('.mob-inner a').forEach(function (a) {
1977      on(a, 'click', function () {
1978        mob.classList.remove('open');
1979        hmb.setAttribute('aria-expanded', 'false');
1980        mob.setAttribute('aria-hidden', 'true');
1981        document.body.classList.remove('modal-open');
1982      });
1983    });
1984    on(window, 'resize', function () {
1985      if (window.innerWidth > 900 && mob.classList.contains('open')) {
1986        mob.classList.remove('open');
1987        hmb.setAttribute('aria-expanded', 'false');
1988        mob.setAttribute('aria-hidden', 'true');
1989        document.body.classList.remove('modal-open');
1990      }
1991    });
1992  }
1993  function initTyper() {
1994    var el = qs('#typer');
1995    if (!el) return;
1996    var items = el.querySelectorAll('.g-txt');
1997    if (items.length === 0) return;
1998    var i = 0;
1999    function swap() {
2000      items[i].classList.remove('active');
2001      items[i].setAttribute('aria-hidden', 'true');
2002      i = (i + 1) % items.length;
2003      items[i].classList.add('active');
2004      items[i].setAttribute('aria-hidden', 'false');
2005    }
2006    if (!reducedMotion()) setInterval(swap, 3500);
2007  }
2008  function initCountdown() {
2009    var el = qs('#cdWrap');
2010    if (!el) return;
2011    var target = new Date();
2012    target.setDate(target.getDate() + 7);
2013    target.setHours(23, 59, 59, 999);
2014    var cdInterval = null;
2015    function tick() {
2016      var diff = target - new Date();
2017      if (diff <= 0) { el.textContent = 'This week\'s batch is closed - next opens Monday.'; if (cdInterval) { clearInterval(cdInterval); cdInterval = null; } return; }
2018      var d = Math.floor(diff / 864e5);
2019      var h = Math.floor((diff % 864e5) / 36e5);
2020      var m = Math.floor((diff % 36e5) / 6e4);
2021      var s = Math.floor((diff % 6e4) / 1e3);
2022      el.innerHTML = '<span class="cd-lbl">Next batch closes in</span><span class="cd-units">' +
2023        '<span class="cd-num">' + d + '<span class="cd-sub">d</span></span><span class="cd-sep">:</span>' +
2024        '<span class="cd-num">' + String(h).padStart(2, '0') + '<span class="cd-sub">h</span></span><span class="cd-sep">:</span>' +
2025        '<span class="cd-num">' + String(m).padStart(2, '0') + '<span class="cd-sub">m</span></span><span class="cd-sep">:</span>' +
2026        '<span class="cd-num">' + String(s).padStart(2, '0') + '<span class="cd-sub">s</span></span></span>';
2027    }
2028    tick();
2029    cdInterval = setInterval(tick, 1000);
2030  }
2031  function initSearch() {
2032    var wrap = qs('#srchWrap');
2033    var tog = qs('#srchTog');
2034    var panel = qs('#srchPanel');
2035    var inp = qs('#srchInp');
2036    var res = qs('#srchRes');
2037    if (!wrap || !tog || !panel || !inp || !res) return;
2038    var deb = null;
2039    function openP() { panel.classList.add('open'); panel.setAttribute('aria-hidden', 'false'); tog.setAttribute('aria-expanded', 'true'); setTimeout(function () { inp.focus(); }, 80); }
2040    function closeP() { panel.classList.remove('open'); panel.setAttribute('aria-hidden', 'true'); tog.setAttribute('aria-expanded', 'false'); }
2041    on(tog, 'click', function (e) { e.stopPropagation(); panel.classList.contains('open') ? closeP() : openP(); });
2042    on(document, 'click', function (e) { if (wrap && !wrap.contains(e.target)) closeP(); });
2043    on(document, 'keydown', function (e) { if (e.key === 'Escape') closeP(); });
2044    on(inp, 'input', function () {
2045      clearTimeout(deb);
2046      var v = inp.value.trim();
2047      if (!v) { res.innerHTML = ''; return; }
2048      deb = setTimeout(function () { doSearch(v); }, 220);
2049    });
2050    async function doSearch(q) {
2051      res.innerHTML = '<div style="padding:10px;color:rgba(255,255,255,.4);font-size:.82rem">Searching¦</div>';
2052      try {
2053        var d = Api ? await Api.get('/products?search=' + encodeURIComponent(q) + '&limit=6') : { products: filterFallback(q) };
2054        var list = (d && d.products) || d || [];
2055        if (!list.length) { res.innerHTML = '<div style="padding:10px;color:rgba(255,255,255,.4);font-size:.82rem">No matches</div>'; return; }
2056        res.innerHTML = list.map(function (p) {
2057          var n = escapeHtml(p.name || '');
2058          var hl = n.replace(new RegExp('(' + q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'ig'), '<mark>$1</mark>');
2059          return '<button class="srch-item" data-id="' + escapeHtml(p.id) + '"><span style="flex:1">' + hl + '</span><span style="font-size:.76rem;color:var(--gd)">' + money(p.base_price || p.price) + '</span></button>';
2060        }).join('');
2061        qsa('.srch-item', res).forEach(function (b) {
2062          on(b, 'click', function () { window.location.href = '/catalog.html?id=' + encodeURIComponent(b.dataset.id); });
2063        });
2064      } catch (e) {
2065        res.innerHTML = '<div style="padding:10px;color:var(--cr);font-size:.82rem">Search unavailable</div>';
2066      }
2067    }
2068    function filterFallback(q) {
2069      q = q.toLowerCase();
2070      return FALLBACK_PRODUCTS.filter(function (p) { return (p.name || '').toLowerCase().indexOf(q) !== -1 || (p.category || '').toLowerCase().indexOf(q) !== -1; }).slice(0, 6);
2071    }
2072  }
2073  function initLang() {
2074    var btn = qs('#langBtn');
2075    var dd = qs('#langDd');
2076    var flag = qs('#langFlag');
2077    var lbl = qs('#langLbl');
2078    if (!btn || !dd) return;
2079    on(btn, 'click', function (e) {
2080      e.stopPropagation();
2081      var open = dd.classList.toggle('open');
2082      dd.setAttribute('aria-hidden', String(!open));
2083      if (open) dd.removeAttribute('inert'); else dd.setAttribute('inert', '');
2084      btn.setAttribute('aria-expanded', String(open));
2085    });
2086    on(document, 'click', function () { dd.classList.remove('open'); dd.setAttribute('aria-hidden', 'true'); dd.setAttribute('inert', ''); btn.setAttribute('aria-expanded', 'false'); });
2087    qsa('.lang-opt', dd).forEach(function (o) {
2088      on(o, 'click', function (e) {
2089        e.stopPropagation();
2090        flag.textContent = o.dataset.flag;
2091        lbl.textContent = o.dataset.lbl;
2092        dd.classList.remove('open');
2093        dd.setAttribute('aria-hidden', 'true');
2094        dd.setAttribute('inert', '');
2095        btn.setAttribute('aria-expanded', 'false');
2096        if (Store && Store.setLang) Store.setLang(o.dataset.lang);
2097        if (window.I18n) I18n.setLang(o.dataset.lang);
2098        showToast('Language set to ' + o.textContent.trim(), 'info');
2099      });
2100    });
2101  }
2102  var modalStack = [];
2103  function openModal(sel) {
2104    var m = typeof sel === 'string' ? qs(sel) : sel;
2105    if (!m) return;
2106    m.classList.add('open');
2107    m.setAttribute('aria-hidden', 'false');
2108    document.body.classList.add('modal-open');
2109    modalStack.push(m);
2110    var focusable = m.querySelector('input, button, [tabindex]:not([tabindex="-1"])');
2111    if (focusable) setTimeout(function () { focusable.focus(); }, 80);
2112  }
2113  function closeModal(sel) {
2114    var m = typeof sel === 'string' ? qs(sel) : sel;
2115    if (!m) return;
2116    m.classList.remove('open');
2117    m.setAttribute('aria-hidden', 'true');
2118    modalStack = modalStack.filter(function (x) { return x !== m; });
2119    if (!modalStack.length) document.body.classList.remove('modal-open');
2120  }
2121  on(document, 'keydown', function (e) {
2122    if (e.key === 'Escape' && modalStack.length) closeModal(modalStack[modalStack.length - 1]);
2123  });
2124  qsa('.overlay').forEach(function (o) {
2125    on(o, 'click', function (e) { if (e.target === o) closeModal(o); });
2126  });
2127  function initAuth() {
2128    var authBtn = qs('#authBtn');
2129    var authBtnMob = qs('#authBtnMob');
2130    var authMod = qs('#authMod');
2131    on(authBtn, 'click', function () { openModal(authMod); });
2132    on(authBtnMob, 'click', function () {
2133      qs('#mobMenu').classList.remove('open');
2134      qs('#hmb').setAttribute('aria-expanded', 'false');
2135      openModal(authMod);
2136    });
2137    on(qs('#closeAuth'), 'click', function () { closeModal(authMod); });
2138    qsa('.a-tab', authMod).forEach(function (t) {
2139      on(t, 'click', function () {
2140        qsa('.a-tab', authMod).forEach(function (x) { x.classList.remove('active'); x.setAttribute('aria-selected', 'false'); });
2141        t.classList.add('active'); t.setAttribute('aria-selected', 'true');
2142        var f = t.dataset.ftab;
2143        qs('#loginF').style.display = f === 'login' ? 'block' : 'none';
2144        qs('#registerF').style.display = f === 'register' ? 'block' : 'none';
2145        qs('#guestF').style.display = f === 'guest' ? 'block' : 'none';
2146      });
2147    });
2148    qsa('.pw-tog').forEach(function (b) {
2149      on(b, 'click', function () {
2150        var inp = qs('#' + b.dataset.for);
2151        if (!inp) return;
2152        var shown = inp.type === 'text';
2153        inp.type = shown ? 'password' : 'text';
2154        b.textContent = shown ? 'show' : 'hide';
2155      });
2156    });
2157    on(qs('#rPass'), 'input', function () {
2158      var v = this.value;
2159      var s = 0;
2160      if (v.length >= 8) s++;
2161      if (/[a-z]/.test(v) && /[A-Z]/.test(v)) s++;
2162      if (/\d/.test(v)) s++;
2163      if (/[^a-zA-Z0-9]/.test(v)) s++;
2164      var pct = (s / 4) * 100;
2165      var fill = qs('#strFill');
2166      var lbl = qs('#strLbl');
2167      var cols = ['var(--cr)', 'var(--cr)', 'var(--gd)', 'var(--mn)', 'var(--mn)'];
2168      var txt = ['Too short', 'Weak', 'Okay', 'Good', 'Strong'];
2169      if (fill) { fill.style.width = pct + '%'; fill.style.background = cols[s]; }
2170      if (lbl) lbl.textContent = v ? txt[s] : '';
2171    });
2172    function setErr(id, msg) { var el = qs('#' + id); if (el) el.textContent = msg || ''; var inp = qs('#' + id.replace('E', '')); if (inp) inp.setAttribute('aria-invalid', msg ? 'true' : 'false'); }
2173    function clearErrs() { qsa('.fe', authMod).forEach(function (x) { x.textContent = ''; }); qsa('.fi-inp', authMod).forEach(function (x) { x.setAttribute('aria-invalid', 'false'); }); }
2174    on(qs('#lSubmit'), 'click', async function () {
2175      clearErrs();
2176      var em = qs('#lEmail').value.trim();
2177      var pw = qs('#lPass').value;
2178      var ok = true;
2179      if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(em)) { setErr('lEmailE', 'Enter a valid email'); ok = false; }
2180      if (pw.length < 1) { setErr('lPassE', 'Enter your password'); ok = false; }
2181      if (!ok) return;
2182      var btn = this; btn.disabled = true; btn.textContent = 'Signing in¦';
2183      try {
2184        if (!Api) throw new Error('offline');
2185        var r = await Api.post('/auth/login', { email: em, password: pw });
2186        try { localStorage.setItem('bloom_token', r.token); localStorage.setItem('bloom_user', JSON.stringify(r.user)); } catch (e) {}
2187        if (Store) { Store.set('token', r.token); Store.set('user', r.user); }
2188        showToast('Welcome back, ' + (r.user && r.user.name || 'friend') + '!', 'success');
2189        closeModal(authMod);
2190        setTimeout(function () { location.reload(); }, 700);
2191      } catch (e) {
2192        setErr('lPassE', (e && e.message) || 'Sign-in failed');
2193        showToast('Sign-in failed', 'error');
2194      } finally { btn.disabled = false; btn.textContent = 'Sign In →'; }
2195    });
2196    on(qs('#rSubmit'), 'click', async function () {
2197      clearErrs();
2198      var n = qs('#rName').value.trim();
2199      var e = qs('#rEmail').value.trim();
2200      var p = qs('#rPass').value;
2201      var ok = true;
2202      if (n.length < 2) { setErr('rNameE', 'Name required'); ok = false; }
2203      if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)) { setErr('rEmailE', 'Enter a valid email'); ok = false; }
2204      if (p.length < 8) { setErr('rPassE', 'Min 8 characters'); ok = false; }
2205      if (!ok) return;
2206      var btn = this; btn.disabled = true; btn.textContent = 'Creating¦';
2207      try {
2208        if (!Api) throw new Error('offline');
2209        var r = await Api.post('/auth/register', { name: n, email: e, password: p });
2210        try { localStorage.setItem('bloom_token', r.token); localStorage.setItem('bloom_user', JSON.stringify(r.user)); } catch (e) {}
2211        if (Store) { Store.set('token', r.token); Store.set('user', r.user); }
2212        showToast('Welcome to Bloom, ' + (r.user && r.user.name || 'friend') + '!', 'success');
2213        closeModal(authMod);
2214        setTimeout(function () { location.reload(); }, 700);
2215      } catch (err) {
2216        setErr('rEmailE', (err && err.message) || 'Registration failed');
2217        showToast('Could not create account', 'error');
2218      } finally { btn.disabled = false; btn.textContent = 'Create Account →'; }
2219    });
2220    on(qs('#gSubmit'), 'click', function () { showToast('Continuing as guest', 'info'); closeModal(authMod); });
2221    on(qs('#gBtn'), 'click', function () {
2222      if (Api && Api.baseUrl) window.location.href = Api.baseUrl + '/auth/google';
2223      else showToast('Google sign-in unavailable', 'error');
2224    });
2225    on(qs('#fplBtn'), 'click', function () { closeModal(authMod); openModal('#fplMod'); });
2226    on(qs('#closeFpl'), 'click', function () { closeModal('#fplMod'); });
2227    on(qs('#fplSubmit'), 'click', async function () {
2228      var e = qs('#fplEmail').value.trim();
2229      var ee = qs('#fplEmailE');
2230      if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)) { ee.textContent = 'Enter a valid email'; return; }
2231      ee.textContent = '';
2232      var btn = this; btn.disabled = true; btn.textContent = 'Sending¦';
2233      try {
2234        if (Api) await Api.post('/auth/forgot-password', { email: e });
2235        showToast('If an account exists, a reset link is on its way.', 'success');
2236        closeModal('#fplMod');
2237      } catch (err) {
2238        showToast('Could not send reset link', 'error');
2239      } finally { btn.disabled = false; btn.textContent = 'Send Reset Link →'; }
2240    });
2241    try {
2242      var u = JSON.parse(localStorage.getItem('bloom_user') || 'null');
2243      if (u && u.name) {
2244        var first = (u.name || '').split(' ')[0];
2245        if (authBtn) authBtn.textContent = 'Hi, ' + first;
2246        if (authBtnMob) authBtnMob.textContent = 'Hi, ' + first;
2247      }
2248    } catch (e) {}
2249  }
2250  function initProfiling() {
2251    var openBtn = qs('#profilingBtn');
2252    var mod = qs('#profMod');
2253    var cls = qs('#closeProf');
2254    on(openBtn, 'click', function () { openModal(mod); });
2255    on(cls, 'click', function () { closeModal(mod); });
2256    qsa('.occ-btn').forEach(function (b) {
2257      on(b, 'click', function () {
2258        qsa('.occ-btn').forEach(function (x) { x.classList.remove('selected'); x.setAttribute('aria-checked', 'false'); });
2259        b.classList.add('selected');
2260        b.setAttribute('aria-checked', 'true');
2261      });
2262    });
2263    on(qs('#profSkip'), 'click', function () { closeModal(mod); });
2264    on(qs('#profSubmit'), 'click', function () {
2265      var sel = qs('.occ-btn.selected');
2266      if (!sel) { showToast('Pick an occasion first', 'info'); return; }
2267      if (Store && Store.setOccasion) Store.setOccasion(sel.dataset.occ);
2268      closeModal(mod);
2269      window.location.href = '/catalog.html?occasion=' + encodeURIComponent(sel.dataset.occ);
2270    });
2271  }
2272  function renderStars(rating) {
2273    var r = Number(rating) || 0;
2274    var out = '';
2275    for (var i = 0; i < 5; i++) out += '<span style="color:' + (i < Math.round(r) ? 'var(--gd)' : 'rgba(255,255,255,.18)') + '" aria-hidden="true">★</span>';
2276    return out;
2277  }
2278  function renderProduct(p) {
2279    var img = (p.images && p.images[0]) || p.image_url || FALLBACK_CAT_IMG[p.category] || FALLBACK_IMG;
2280    var price = p.base_price || p.price || 0;
2281    var cat = (p.category || '').replace(/^./, function (c) { return c.toUpperCase(); });
2282    var name = escapeHtml(p.name || 'Unnamed');
2283    var badge = p.badge ? '<span class="p-badge">' + escapeHtml(p.badge) + '</span>' : '';
2284    return '<article class="p-card" data-id="' + escapeHtml(p.id) + '" tabindex="0" role="button" aria-label="' + name + ', ' + money(price) + '">' +
2285      '<div class="p-shine" aria-hidden="true"></div>' +
2286      '<div class="p5-corner" aria-hidden="true"></div>' +
2287      badge +
2288      '<button class="wl-btn" aria-label="Add to wishlist" data-id="' + escapeHtml(p.id) + '">♡</button>' +
2289      '<div class="p-img"><img src="' + escapeHtml(img) + '" alt="' + name + '" loading="lazy" decoding="async" width="300" height="180" onerror="this.onerror=null;this.style.display=\'none\';this.parentElement.innerHTML=\'<div class=p-img-ph>🌸</div>\'"></div>' +
2290      '<div class="p-name">' + name + '</div>' +
2291      '<div class="p-cat">' + escapeHtml(cat) + '</div>' +
2292      '<div class="p-stars" role="img" aria-label="' + (p.rating || 0) + ' out of 5">' + renderStars(p.rating) + '</div>' +
2293      '<div class="p-foot"><div class="p-price">' + money(price) + '</div><button class="p-add" data-id="' + escapeHtml(p.id) + '">+ Cart</button></div>' +
2294      '</article>';
2295  }
2296  function renderSkeletons(n) {
2297    var out = '';
2298    for (var i = 0; i < n; i++) out += '<div class="p-skel"><div class="p-skel-img"></div><div class="p-skel-t"></div><div class="p-skel-s"></div></div>';
2299    return out;
2300  }
2301  async function loadFeatured(cat) {
2302    cat = cat || 'all';
2303    var grid = qs('#pGrid');
2304    if (!grid) return;
2305    grid.setAttribute('aria-busy', 'true');
2306    grid.innerHTML = renderSkeletons(8);
2307    var list = [];
2308    try {
2309      if (Api) {
2310        var q = cat !== 'all' ? '?category=' + encodeURIComponent(cat) + '&limit=8' : '?limit=8';
2311        var d = await Api.get('/products' + q);
2312        list = (d && d.products) || d || [];
2313      } else { throw new Error('no-api'); }
2314    } catch (e) {
2315      list = [];
2316    }
2317    if (!list.length) { grid.innerHTML = '<div class="p-empty">No products in this category yet.</div>'; grid.setAttribute('aria-busy', 'false'); return; }
2318    grid.innerHTML = list.map(renderProduct).join('');
2319    grid.setAttribute('aria-busy', 'false');
2320    var cards = qsa('.p-card', grid);
2321    cards.forEach(function (c, i) {
2322      setTimeout(function () { c.classList.add('vis'); }, i * 60);
2323    });
2324    qsa('.p-add', grid).forEach(function (b) {
2325      on(b, 'click', async function (e) {
2326        e.stopPropagation();
2327        var orig = b.textContent;
2328        b.disabled = true; b.textContent = '¦';
2329        try {
2330          if (Api) {
2331            await Api.post('/cart/items', { productId: b.dataset.id, qty: 1 });
2332            var cart = await Api.get('/cart');
2333            if (Store) {
2334              Store.set('cart', cart);
2335              if (Store.updateCartCount) Store.updateCartCount((cart.items || []).reduce(function (s, i) { return s + (i.qty || 1); }, 0));
2336            }
2337            var badge = qs('#cartBadge');
2338            if (badge) {
2339              var cnt = (cart.items || []).reduce(function (s, i) { return s + (i.qty || 1); }, 0);
2340              badge.textContent = cnt;
2341              badge.style.display = cnt > 0 ? 'inline-flex' : 'none';
2342            }
2343          }
2344          showToast('Added to cart', 'success');
2345        } catch (err) {
2346          showToast('Could not add to cart', 'error');
2347        } finally { b.disabled = false; b.textContent = orig; }
2348      });
2349    });
2350    qsa('.wl-btn', grid).forEach(function (b) {
2351      on(b, 'click', async function (e) {
2352        e.stopPropagation();
2353        var card = b.closest('.p-card');
2354        var nameEl = card && card.querySelector('.p-name');
2355        var priceEl = card && card.querySelector('.p-price');
2356        var img = card && card.querySelector('.p-img img');
2357        var item = { id: b.dataset.id, name: nameEl ? nameEl.textContent.trim() : 'Bouquet', price: priceEl ? Number(String(priceEl.textContent).replace(/[^\d.]/g, '')) : 0, image: img ? img.src : '/img/hero-flowers.webp' };
2358        var added = window.addToWishlist ? window.addToWishlist(item) : true;
2359        b.classList.add('wl-pop');
2360        setTimeout(function () { b.classList.remove('wl-pop'); }, 420);
2361        try {
2362          if (Api) {
2363            if (added) await Api.post('/wishlist', { productId: b.dataset.id });
2364            else await Api.delete('/wishlist/' + encodeURIComponent(b.dataset.id));
2365          }
2366          showToast(added ? 'Saved to wishlist' : 'Removed from wishlist', added ? 'success' : 'info');
2367        } catch (err) { showToast(added ? 'Saved locally' : 'Removed', 'info'); }
2368      });
2369    });
2370    qsa('.p-card', grid).forEach(function (c) {
2371      var openQv = function (e) {
2372        if (e.target.closest('button')) return;
2373        openQuickView(c.dataset.id);
2374      };
2375      on(c, 'click', openQv);
2376      on(c, 'keydown', function (e) {
2377        if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openQv(e); }
2378      });
2379    });
2380  }
2381  async function openQuickView(id) {
2382    var mod = qs('#qvMod');
2383    var title = qs('#qvTitle');
2384    var body = qs('#qvContent');
2385    if (!mod || !body) return;
2386    title.textContent = 'Loading¦';
2387    body.innerHTML = '<div style="padding:20px;text-align:center;color:rgba(255,255,255,.4)">Loading¦</div>';
2388    openModal(mod);
2389    var p = null;
2390    try {
2391      if (Api) p = await Api.get('/products/' + encodeURIComponent(id));
2392    } catch (e) {}
2393    if (!p) p = FALLBACK_PRODUCTS.find(function (x) { return x.id === id; });
2394    if (!p) { body.innerHTML = '<p>Could not load this product.</p>'; return; }
2395    title.textContent = p.name;
2396    var img = (p.images && p.images[0]) || FALLBACK_CAT_IMG[p.category] || FALLBACK_IMG;
2397    var lt = (Api ? '48h-14d pre-order window' : '48h minimum lead time');
2398    body.innerHTML =
2399      '<div style="display:grid;grid-template-columns:1fr 1fr;gap:20px">' +
2400      '<div style="border-radius:14px;overflow:hidden;aspect-ratio:1;background:var(--gl)"><img src="' + escapeHtml(img) + '" alt="' + escapeHtml(p.name) + '" style="width:100%;height:100%;object-fit:cover"></div>' +
2401      '<div>' +
2402      '<div class="p-cat" style="margin-bottom:8px">' + escapeHtml(p.category || '') + '</div>' +
2403      '<div style="display:inline-flex;align-items:center">
2403<div class="p-stars" role="img" aria-label="' + (p.rating || 0) + ' out of 5">' + renderStars(p.rating) + '</div><span style="font-size:.78rem;color:rgba(255,255,255,.5);margin-left:6px">' + (p.review_count || 0) + ' reviews</span></div>' +
2404      '<p style="font-size:.88rem;color:rgba(255,255,255,.68);line-height:1.7;margin:14px 0">' + escapeHtml(p.description || 'Handcrafted by Bloom florists. Developed by STI LIPA BSIT students.') + '</p>' +
2405      '<div style="display:flex;align-items:center;gap:6px;font-size:.74rem;color:var(--mn);margin-bottom:14px"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>' + lt + '</div>' +
2406      '<div style="font-family:var(--fc);font-weight:900;font-size:1.8rem;color:var(--gd);margin-bottom:14px">' + money(p.base_price || p.price) + '</div>' +
2407      '<button class="btn btn-p" style="width:100%;justify-content:center" id="qvAdd">Add to cart →</button>' +
2408      '<a href="/catalog.html?id=' + encodeURIComponent(p.id) + '" class="btn btn-g" style="width:100%;justify-content:center;margin-top:8px">View full details</a>' +
2409      '</div></div>' +
2410      buildVideoMessageBlock(p.id);
2411    attachVideoMessageHandlers(p.id);
2412    on(qs('#qvAdd'), 'click', async function () {
2413      var btn = this; btn.disabled = true; btn.textContent = 'Adding¦';
2414      try {
2415        if (Api) {
2416          await Api.post('/cart/items', { productId: p.id, qty: 1 });
2417          var cart = await Api.get('/cart');
2418          if (Store) { Store.set('cart', cart); if (Store.updateCartCount) Store.updateCartCount((cart.items || []).reduce(function (s, i) { return s + (i.qty || 1); }, 0)); }
2419        }
2420        showToast('Added to cart', 'success');
2421        closeModal(mod);
2422      } catch (e) { showToast('Could not add', 'error'); } finally { btn.disabled = false; btn.textContent = 'Add to cart →'; }
2423    });
2424    on(qs('#closeQv'), 'click', function () { closeModal(mod); });
2425  }
2426  function initCategories() {
2427    var tabs = qsa('.cat-tab');
2428    var tabsWrap = qs('#catTabs');
2429    var catL = qs('#catL');
2430    var catR = qs('#catR');
2431    tabs.forEach(function (t) {
2432      on(t, 'click', function () {
2433        tabs.forEach(function (x) { x.classList.remove('active'); x.setAttribute('aria-selected', 'false'); });
2434        t.classList.add('active');
2435        t.setAttribute('aria-selected', 'true');
2436        loadFeatured(t.dataset.cat);
2437      });
2438    });
2439    function updateArrows() {
2440      if (!tabsWrap) return;
2441      var sl = tabsWrap.scrollLeft;
2442      var max = tabsWrap.scrollWidth - tabsWrap.clientWidth;
2443      if (catL) catL.disabled = sl < 4;
2444      if (catR) catR.disabled = sl >= max - 4;
2445    }
2446    on(catL, 'click', function () { tabsWrap.scrollBy({ left: -220, behavior: 'smooth' }); });
2447    on(catR, 'click', function () { tabsWrap.scrollBy({ left: 220, behavior: 'smooth' }); });
2448    if (tabsWrap) { on(tabsWrap, 'scroll', updateArrows, { passive: true }); setTimeout(updateArrows, 200); }
2449  }
2450  function renderReviews() {
2451    var grid = qs('#revGrid');
2452    var dots = qs('#revDots');
2453    if (!grid) return;
2454    grid.innerHTML = FEATURED_REVIEWS.slice(0, 3).map(function (r, i) {
2455      return '<article class="rev-card anim-in ' + (i === 0 ? 'mob-active' : '') + '">' +
2456        '<div class="rev-stars" role="img" aria-label="' + r.rating + ' out of 5">' + renderStars(r.rating) + '</div>' +
2457        '<p class="rev-body">' + escapeHtml(r.body) + '</p>' +
2458        '<div class="rev-foot"><div><div class="rev-name">' + escapeHtml(r.name) + '</div><div class="rev-role">' + escapeHtml(r.role) + '</div></div></div>' +
2459        '</article>';
2460    }).join('');
2461    if (dots) {
2462      dots.innerHTML = FEATURED_REVIEWS.slice(0, 3).map(function (_, i) {
2463        return '<button class="rev-dot ' + (i === 0 ? 'active' : '') + '" role="tab" aria-selected="' + (i === 0 ? 'true' : 'false') + '" aria-label="Review ' + (i + 1) + '" data-i="' + i + '"></button>';
2464      }).join('');
2465      qsa('.rev-dot', dots).forEach(function (d) {
2466        on(d, 'click', function () { setActiveReview(Number(d.dataset.i)); });
2467      });
2468    }
2469    on(qs('#revPrev'), 'click', function () { changeRev(-1); });
2470    on(qs('#revNext'), 'click', function () { changeRev(1); });
2471  }
2472  var revIdx = 0;
2473  function setActiveReview(i) {
2474    revIdx = ((i % 3) + 3) % 3;
2475    qsa('.rev-card').forEach(function (c, k) { c.classList.toggle('mob-active', k === revIdx); });
2476    qsa('.rev-dot').forEach(function (d, k) { d.classList.toggle('active', k === revIdx); d.setAttribute('aria-selected', k === revIdx ? 'true' : 'false'); });
2477  }
2478  function changeRev(d) { setActiveReview(revIdx + d); }
2479  function initStats() {
2480    qsa('.stat-bar-fill').forEach(function (el) {
2481      var obs = new IntersectionObserver(function (ents) {
2482        if (ents[0].isIntersecting) { el.style.width = (el.dataset.w || '85') + '%'; obs.disconnect(); }
2483      }, { threshold: 0.4 });
2484      obs.observe(el);
2485    });
2486  }
2487  function initReveal() {
2488    if (!('IntersectionObserver' in window)) { qsa('.anim-in').forEach(function (el) { el.classList.add('vis'); }); return; }
2489    var obs = new IntersectionObserver(function (ents) {
2490      ents.forEach(function (e) {
2491        if (e.isIntersecting) { e.target.classList.add('vis'); obs.unobserve(e.target); }
2492      });
2493    }, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' });
2494    qsa('.anim-in').forEach(function (el) { obs.observe(el); });
2495  }
2496  function initBtt() {
2497    var b = qs('#btt');
2498    if (!b) return;
2499    on(window, 'scroll', function () {
2500      if (window.scrollY > 520) b.classList.add('vis'); else b.classList.remove('vis');
2501    }, { passive: true });
2502    on(b, 'click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); });
2503  }
2504  function initNewsletter() {
2505    on(qs('#nlForm'), 'submit', async function (e) {
2506      e.preventDefault();
2507      var em = qs('#nlEmail').value.trim();
2508      if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(em)) { showToast('Enter a valid email', 'error'); return; }
2509      var sub = e.target.querySelector('button');
2510      sub.disabled = true; sub.textContent = '¦';
2511      try {
2512        if (Api) await Api.post('/newsletter', { email: em });
2513        showToast('Subscribed. Welcome aboard.', 'success');
2514        qs('#nlEmail').value = '';
2515      } catch (err) { showToast('Could not subscribe right now', 'error'); } finally { sub.disabled = false; sub.textContent = 'Join'; }
2516    });
2517  }
2518  async function loadCart() {
2519    if (!Api) return;
2520    try {
2521      var cart = await Api.get('/cart');
2522      if (Store) Store.set('cart', cart);
2523      var cnt = (cart.items || []).reduce(function (s, i) { return s + (i.qty || 1); }, 0);
2524      var badge = qs('#cartBadge');
2525      if (badge) { badge.textContent = cnt; badge.style.display = cnt > 0 ? 'inline-flex' : 'none'; }
2526    } catch (e) {}
2527  }
2528  async function loadCounts() {
2529    var cats = ['bouquets', 'arrangements', 'fresh', 'dried', 'corporate'];
2530    if (!Api) {
2531      cats.forEach(function (c) {
2532        var el = qs('#cnt-' + c);
2533        if (el) el.textContent = '(' + FALLBACK_PRODUCTS.filter(function (p) { return p.category === c; }).length + ')';
2534      });
2535      var all = qs('#cnt-all'); if (all) all.textContent = '(' + FALLBACK_PRODUCTS.length + ')';
2536      return;
2537    }
2538    try {
2539      var d = await Api.get('/products?limit=200');
2540      var list = (d && d.products) || d || [];
2541      var total = list.length;
2542      var all = qs('#cnt-all'); if (all) all.textContent = total ? '(' + total + ')' : '';
2543      cats.forEach(function (c) {
2544        var n = list.filter(function (p) { return (p.category || '').toLowerCase() === c; }).length;
2545        var el = qs('#cnt-' + c);
2546        if (el) el.textContent = n ? '(' + n + ')' : '';
2547      });
2548    } catch (e) {}
2549  }
2550  async function loadSiteContent() {
2551    if (!Api) return;
2552    try {
2553      var c = await Api.get('/content');
2554      if (!c) return;
2555      document.querySelectorAll('[data-content-key]').forEach(el => {
2556        var key = el.getAttribute('data-content-key');
2557        var dbKey = key;
2558        if (key === 'heroHeadline' && c.heroHeadline === undefined) dbKey = 'hero_title_2';
2559        if (key === 'hero_title_2' && c.hero_title_2 === undefined) dbKey = 'heroHeadline';
2560        
2561        if (c[dbKey] !== undefined && c[dbKey] !== null && c[dbKey] !== '') {
2562          var val = c[dbKey];
2563          if (dbKey.includes('price') || dbKey.includes('Threshold')) {
2564            val = '\u20B1' + Number(val).toLocaleString(undefined, {minimumFractionDigits:0, maximumFractionDigits:2});
2565          }
2566          if (el.tagName === 'INPUT') el.value = val;
2567          else el.textContent = val;
2568        }
2569      });
2570      if (c.bannerActive !== undefined) {
2571        var banner = document.getElementById('promoBanner');
2572        if (banner) banner.style.display = c.bannerActive ? 'flex' : 'none';
2573      }
2574      if (c.instagramUrl) {
2575        document.querySelectorAll('a[href*="instagram.com"]').forEach(el => el.setAttribute('href', c.instagramUrl));
2576      }
2577      if (c.facebookUrl) {
2578        document.querySelectorAll('a[href*="facebook.com"]').forEach(el => el.setAttribute('href', c.facebookUrl));
2579      }
2580    } catch (e) {}
2581  }
2582  function initSocket() {
2583    if (!Store || !Store.on) return;
2584    Store.on('catalog_update', function () {
2585      var act = qs('.cat-tab.active');
2586      loadFeatured(act ? act.dataset.cat : 'all');
2587      loadCounts();
2588    });
2589    Store.on('content_update', loadSiteContent);
2590    Store.on('cart_update', loadCart);
2591  }
2592  function initTilt() {
2593    if (reducedMotion()) return;
2594    qsa('.p5-tilt, .feat-card, .fact-card, .rev-card').forEach(function (card) {
2595      on(card, 'mousemove', function (e) {
2596        var r = card.getBoundingClientRect();
2597        var x = (e.clientX - r.left) / r.width - 0.5;
2598        var y = (e.clientY - r.top) / r.height - 0.5;
2599        card.style.transform = 'perspective(800px) rotateY(' + (x * 8) + 'deg) rotateX(' + (-y * 8) + 'deg) scale(1.02)';
2600      });
2601      on(card, 'mouseleave', function () {
2602        card.style.transform = '';
2603      });
2604    });
2605  }
2606  function initMagnetic() {
2607    if (reducedMotion()) return;
2608    qsa('.btn-p.btn-lg, .magnetic-btn').forEach(function (btn) {
2609      on(btn, 'mousemove', function (e) {
2610        var r = btn.getBoundingClientRect();
2611        var x = e.clientX - r.left - r.width / 2;
2612        var y = e.clientY - r.top - r.height / 2;
2613        btn.style.transform = 'translate(' + (x * 0.15) + 'px,' + (y * 0.15) + 'px) scale(1.04)';
2614      });
2615      on(btn, 'mouseleave', function () {
2616        btn.style.transform = '';
2617      });
2618    });
2619  }
2620  function initRipple() {
2621    on(document, 'click', function (e) {
2622      var btn = e.target.closest('.btn-p, .p-add');
2623      if (!btn) return;
2624      var r = btn.getBoundingClientRect();
2625      var rip = document.createElement('span');
2626      rip.className = 'ripple';
2627      var sz = Math.max(r.width, r.height);
2628      rip.style.width = rip.style.height = sz + 'px';
2629      rip.style.left = (e.clientX - r.left - sz / 2) + 'px';
2630      rip.style.top = (e.clientY - r.top - sz / 2) + 'px';
2631      btn.style.position = 'relative';
2632      btn.style.overflow = 'hidden';
2633      btn.appendChild(rip);
2634      setTimeout(function () { rip.remove(); }, 600);
2635    });
2636  }
2637  var FUNNEL_ORDER = ['hero', 'shop', 'subs', 'cart', 'checkout'];
2638  var funnelState = { hero: false, shop: false, subs: false, cart: false, checkout: false };
2639  function bloomTrack(name, payload) {
2640    payload = payload || {};
2641    try { (window.dataLayer = window.dataLayer || []).push({ event: name, ts: Date.now(), ...payload }); } catch (e) {}
2642    try { if (window.clarity && typeof window.clarity === 'function') window.clarity('event', name); } catch (e) {}
2643    try { if (window.hj && typeof window.hj === 'function') window.hj('event', name); } catch (e) {}
2644    try { if (window.gtag && typeof window.gtag === 'function') window.gtag('event', name, payload); } catch (e) {}
2645  }
2646  window.bloomTrack = bloomTrack;
2647  function initFunnelTracking() {
2648    var bar = qs('#funnelBar');
2649    var sections = [
2650      { id: 'heroSec', step: 'hero' },
2651      { id: 'shop', step: 'shop' },
2652      { id: 'subs', step: 'subs' }
2653    ];
2654    if (!('IntersectionObserver' in window)) return;
2655    var obs = new IntersectionObserver(function (ents) {
2656      ents.forEach(function (e) {
2657        if (!e.isIntersecting) return;
2658        var sec = sections.find(function (s) { return s.id === e.target.id; });
2659        if (!sec) return;
2660        if (!funnelState[sec.step]) {
2661          funnelState[sec.step] = true;
2662          bloomTrack('funnel_' + sec.step + '_view');
2663        }
2664        var idx = FUNNEL_ORDER.indexOf(sec.step);
2665        qsa('.funnel-step').forEach(function (el) {
2666          var i = FUNNEL_ORDER.indexOf(el.dataset.step);
2667          el.classList.toggle('active', i === idx);
2668          el.classList.toggle('done', i < idx && funnelState[el.dataset.step]);
2669        });
2670        if (bar && idx > 0) bar.classList.add('show');
2671      });
2672    }, { threshold: 0.45 });
2673    sections.forEach(function (s) { var el = qs('#' + s.id); if (el) obs.observe(el); });
2674    on(document, 'click', function (e) {
2675      var add = e.target.closest('.p-add, #qvAdd');
2676      if (add) { funnelState.cart = true; bloomTrack('funnel_cart_add'); markFunnel('cart'); }
2677      var checkout = e.target.closest('[href*="checkout" i], #checkoutBtn');
2678      if (checkout) { funnelState.checkout = true; bloomTrack('funnel_checkout_start'); markFunnel('checkout'); }
2679    });
2680  }
2681  function markFunnel(step) {
2682    var idx = FUNNEL_ORDER.indexOf(step);
2683    qsa('.funnel-step').forEach(function (el) {
2684      var i = FUNNEL_ORDER.indexOf(el.dataset.step);
2685      el.classList.toggle('active', i === idx);
2686      el.classList.toggle('done', i < idx);
2687    });
2688  }
2689  function initBloomBoot() {
2690    var boot = qs('#bloomBoot');
2691    if (!boot) return;
2692    function hide() {
2693      boot.classList.add('gone');
2694      setTimeout(function () { boot.style.display = 'none'; }, 700);
2695    }
2696    if (document.readyState === 'complete') setTimeout(hide, 400);
2697    else window.addEventListener('load', function () { setTimeout(hide, 400); });
2698    setTimeout(hide, 4500);
2699  }
2700  var DELIVERY_LEAD = {
2701    'metro-manila': { hours: 48, label: '48h' },
2702    'batangas': { hours: 48, label: '48h' },
2703    'cebu': { hours: 96, label: '4 days' },
2704    'laguna': { hours: 72, label: '3 days' },
2705    'cavite': { hours: 72, label: '3 days' },
2706    'rizal': { hours: 72, label: '3 days' },
2707    'bulacan': { hours: 72, label: '3 days' },
2708    'pampanga': { hours: 96, label: '4 days' },
2709    'baguio': { hours: 120, label: '5 days' }
2710  };
2711  function initDelivery() {
2712    var dateInp = qs('#dlvDate');
2713    var locSel = qs('#dlvLoc');
2714    var etaEl = qs('#dlvEta');
2715    var bar = qs('#dlvBar');
2716    if (!dateInp || !locSel || !etaEl || !bar) return;
2717    var saved = {};
2718    try { saved = JSON.parse(localStorage.getItem('bloom_delivery') || '{}'); } catch (e) {}
2719    var minH = DELIVERY_LEAD[saved.loc || locSel.value]?.hours || 48;
2720    var minDate = new Date(Date.now() + minH * 36e5);
2721    dateInp.min = minDate.toISOString().slice(0, 10);
2722    if (saved.date && new Date(saved.date) >= minDate) dateInp.value = saved.date;
2723    else dateInp.value = minDate.toISOString().slice(0, 10);
2724    if (saved.loc && DELIVERY_LEAD[saved.loc]) locSel.value = saved.loc;
2725    function updateEta() {
2726      var info = DELIVERY_LEAD[locSel.value] || DELIVERY_LEAD['metro-manila'];
2727      var newMin = new Date(Date.now() + info.hours * 36e5);
2728      dateInp.min = newMin.toISOString().slice(0, 10);
2729      if (new Date(dateInp.value) < newMin) dateInp.value = newMin.toISOString().slice(0, 10);
2730      etaEl.innerHTML = 'Lead time: <strong>' + info.label + '</strong>';
2731      try { localStorage.setItem('bloom_delivery', JSON.stringify({ date: dateInp.value, loc: locSel.value })); } catch (e) {}
2732      bloomTrack('delivery_set', { location: locSel.value, date: dateInp.value });
2733    }
2734    on(locSel, 'change', updateEta);
2735    on(dateInp, 'change', updateEta);
2736    updateEta();
2737    var lastY = window.scrollY;
2738    on(window, 'scroll', function () {
2739      var y = window.scrollY;
2740      if (y > 600 && y > lastY) bar.classList.add('hide');
2741      else bar.classList.remove('hide');
2742      lastY = y;
2743    }, { passive: true });
2744  }
2745  function getWishlist() {
2746    try { return JSON.parse(localStorage.getItem('bloom_wishlist') || '[]'); } catch (e) { return []; }
2747  }
2748  function saveWishlist(items) {
2749    try { localStorage.setItem('bloom_wishlist', JSON.stringify(items)); } catch (e) {}
2750    updateWlUi();
2751  }
2752  function updateWlUi() {
2753    var items = getWishlist();
2754    var badge = qs('#wlBadge');
2755    var count = qs('#wlCount');
2756    var clear = qs('#wlClear');
2757    if (badge) { badge.textContent = items.length; badge.style.display = items.length ? 'inline-flex' : 'none'; }
2758    if (count) count.textContent = items.length;
2759    if (clear) clear.hidden = !items.length;
2760    qsa('.wl-btn').forEach(function (b) {
2761      var on = items.some(function (x) { return x.id === b.dataset.id; });
2762      b.classList.toggle('on', on);
2763      b.textContent = on ? '♥' : '♡';
2764    });
2765    var body = qs('#wlDrawerBody');
2766    var empty = qs('#wlEmpty');
2767    if (!body) return;
2768    qsa('.wl-row', body).forEach(function (r) { r.remove(); });
2769    if (!items.length) { if (empty) empty.style.display = ''; return; }
2770    if (empty) empty.style.display = 'none';
2771    items.forEach(function (it) {
2772      var row = document.createElement('div');
2773      row.className = 'wl-row';
2774      row.innerHTML = '<a class="wl-row-img" href="/catalog.html?id=' + encodeURIComponent(it.id) + '">
2774<img src="' + escapeHtml(it.image || '/img/hero-flowers.webp') + '" alt=""></a>' +
2775        '<div class="wl-row-body"><div class="wl-row-name">' + escapeHtml(it.name || 'Bouquet') + '</div><div class="wl-row-price">' + money(it.price || 0) + '</div></div>' +
2776        '<button type="button" class="wl-row-x" aria-label="Remove from wishlist" data-rm="' + escapeHtml(it.id) + '">✕</button>';
2777      body.appendChild(row);
2778    });
2779    qsa('.wl-row-x', body).forEach(function (x) {
2780      on(x, 'click', function () {
2781        var id = x.dataset.rm;
2782        var next = getWishlist().filter(function (i) { return i.id !== id; });
2783        saveWishlist(next);
2784        bloomTrack('wishlist_remove', { id: id });
2785      });
2786    });
2787  }
2788  window.addToWishlist = function (item) {
2789    var items = getWishlist();
2790    if (items.some(function (i) { return i.id === item.id; })) {
2791      saveWishlist(items.filter(function (i) { return i.id !== item.id; }));
2792      return false;
2793    }
2794    items.unshift(item);
2795    saveWishlist(items.slice(0, 100));
2796    bloomTrack('wishlist_add', { id: item.id });
2797    return true;
2798  };
2799  function initWishlist() {
2800    var drawer = qs('#wlDrawer');
2801    var openBtn = qs('#wlBtnNav');
2802    var clsBtn = qs('#wlDrawerCls');
2803    var clear = qs('#wlClear');
2804    if (!drawer) return;
2805    function openD() { drawer.classList.add('open'); drawer.setAttribute('aria-hidden', 'false'); document.body.classList.add('modal-open'); updateWlUi(); bloomTrack('wishlist_open'); }
2806    function closeD() { drawer.classList.remove('open'); drawer.setAttribute('aria-hidden', 'true'); document.body.classList.remove('modal-open'); }
2807    on(openBtn, 'click', openD);
2808    on(clsBtn, 'click', closeD);
2809    on(document, 'keydown', function (e) { if (e.key === 'Escape' && drawer.classList.contains('open')) closeD(); });
2810    on(clear, 'click', function () { saveWishlist([]); showToast('Wishlist cleared', 'info'); });
2811    updateWlUi();
2812    on(document, 'click', function (e) {
2813      var b = e.target.closest('.wl-btn');
2814      if (!b) return;
2815      e.stopPropagation();
2816      var card = b.closest('.p-card');
2817      var nameEl = card && card.querySelector('.p-name');
2818      var priceEl = card && card.querySelector('.p-price');
2819      var img = card && card.querySelector('.p-img img');
2820      var item = { id: b.dataset.id, name: nameEl ? nameEl.textContent.trim() : 'Bouquet', price: priceEl ? Number(String(priceEl.textContent).replace(/[^\d.]/g, '')) : 0, image: img ? img.src : '/img/hero-flowers.webp' };
2821      var added = window.addToWishlist(item);
2822      b.classList.add('wl-pop');
2823      setTimeout(function () { b.classList.remove('wl-pop'); }, 420);
2824      showToast(added ? 'Saved to wishlist' : 'Removed from wishlist', added ? 'success' : 'info');
2825    });
2826  }
2827  function initSubscriptions() {
2828    var sec = qs('#subs');
2829    if (!sec) return;
2830    var cards = qsa('.subs-card', sec);
2831    var startBtn = qs('#subsStart');
2832    var learnBtn = qs('#subsLearn');
2833    var previewImg = qs('#subsPreviewImg');
2834    cards.forEach(function (c) {
2835      on(c, 'click', function () {
2836        cards.forEach(function (x) { x.classList.remove('selected'); x.setAttribute('aria-checked', 'false'); });
2837        c.classList.add('selected');
2838        c.setAttribute('aria-checked', 'true');
2839        var plan = c.dataset.sub;
2840        if (previewImg && plan) {
2841          previewImg.style.opacity = '0';
2842          setTimeout(function() {
2843            previewImg.src = '/uploads/subscriptions/' + plan + '.jpg';
2844            previewImg.style.opacity = '1';
2845          }, 200);
2846        }
2847        bloomTrack('subscription_select', { plan: plan, price: c.dataset.price });
2848      });
2849      on(c, 'keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); c.click(); } });
2850    });
2851    on(startBtn, 'click', async function () {
2852      var sel = qs('.subs-card.selected', sec);
2853      if (!sel) { showToast('Pick a cadence first', 'info'); return; }
2854      var plan = sel.dataset.sub;
2855      var price = sel.dataset.price;
2856      bloomTrack('subscription_start', { plan: plan, price: price });
2857      showToast('Redirecting to secure checkout...', 'success');
2858      window.location.href = '/checkout.html?subscription=' + encodeURIComponent(plan) + '&price=' + encodeURIComponent(price);
2859    });
2860    on(learnBtn, 'click', function () { window.location.href = '/subscriptions.html'; });
2861  }
2862  function buildVideoMessageBlock(productId) {
2863    return '<div id="vmContainer_' + productId + '" style="margin-top: 24px;"></div>';
2864  }
2865  function attachVideoMessageHandlers(productId) {
2866    // Ensure the new robust VideoMessage.js module handles the UI
2867    if (window.BloomVideoMessage) {
2868      window.BloomVideoMessage.attachTo('vmContainer_' + productId);
2869      // Listen for the genuinely recorded Blob and attach it via IndexedDB
2870      // This ensures real persistence across the site without needing a mock backend
2871      document.addEventListener('bloom:video-attached', function (e) {
2872        var blob = e.detail.blob;
2873        if (!blob) return;
2874        try {
2875          var dbReq = indexedDB.open('BloomDB', 1);
2876          dbReq.onupgradeneeded = function(e) { 
2877            e.target.result.createObjectStore('videos'); 
2878          };
2879          dbReq.onsuccess = function(e) {
2880            var db = e.target.result;
2881            var tx = db.transaction('videos', 'readwrite');
2882            tx.objectStore('videos').put(blob, 'vm_' + productId);
2883            bloomTrack('video_message_attached', { productId: productId, size: blob.size });
2884          };
2885        } catch (err) {
2886          console.warn('Could not save video to IndexedDB', err);
2887        }
2888      });
2889    }
2890  }
2891  window.buildVideoMessageBlock = buildVideoMessageBlock;
2892  window.attachVideoMessageHandlers = attachVideoMessageHandlers;
2893  function summarizeFormErrors(formEl, summaryEl) {
2894    var errs = [];
2895    qsa('.fe', formEl).forEach(function (e) {
2896      var msg = (e.textContent || '').trim();
2897      if (!msg) return;
2898      var fi = e.closest('.fi') || formEl;
2899      var inp = fi.querySelector('input,textarea,select');
2900      var labelEl = inp ? formEl.querySelector('label[for="' + inp.id + '"]') : null;
2901      var label = inp ? ((labelEl && labelEl.textContent.trim()) || inp.id) : '';
2902      errs.push({ id: inp ? inp.id : '', label: label, msg: msg });
2903    });
2904    var ul = summaryEl.querySelector('ul');
2905    if (!ul) return;
2906    if (!errs.length) { summaryEl.classList.remove('on'); ul.innerHTML = ''; return; }
2907    ul.innerHTML = errs.map(function (e) {
2908      var anchor = e.id ? '<a href="#' + e.id + '" data-fid="' + e.id + '">' + escapeHtml(e.label || e.id) + '</a>: ' : '';
2909      return '<li>' + anchor + escapeHtml(e.msg) + '</li>';
2910    }).join('');
2911    summaryEl.classList.add('on');
2912    summaryEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
2913    qsa('a[data-fid]', summaryEl).forEach(function (a) {
2914      on(a, 'click', function (ev) { ev.preventDefault(); var t = qs('#' + a.dataset.fid); if (t) { t.focus(); t.scrollIntoView({ behavior: 'smooth', block: 'center' }); } });
2915    });
2916  }
2917  window.summarizeFormErrors = summarizeFormErrors;
2918  function initFormErrSummaries() {
2919    var loginBtn = qs('#lSubmit');
2920    var regBtn = qs('#rSubmit');
2921    var loginSum = qs('#loginErrSum');
2922    var regSum = qs('#regErrSum');
2923    function patch(btn, formId, sumEl) {
2924      if (!btn || !sumEl) return;
2925      var origClick = btn.onclick;
2926      on(btn, 'click', function () {
2927        setTimeout(function () { var f = qs('#' + formId); if (f) summarizeFormErrors(f, sumEl); }, 60);
2928      });
2929    }
2930    patch(loginBtn, 'loginF', loginSum);
2931    patch(regBtn, 'registerF', regSum);
2932  }
2933  function initVirtualization() {
2934    if (!('IntersectionObserver' in window)) return;
2935    var grids = ['pGrid', 'recentGrid'];
2936    grids.forEach(function (id) {
2937      var grid = qs('#' + id);
2938      if (!grid) return;
2939      var obs = new IntersectionObserver(function (ents) {
2940        ents.forEach(function (e) {
2941          var img = e.target.querySelector ? e.target.querySelector('img') : null;
2942          if (e.isIntersecting) {
2943            e.target.style.contentVisibility = 'visible';
2944            if (img && img.dataset.src && !img.src) img.src = img.dataset.src;
2945          } else {
2946            e.target.style.contentVisibility = 'auto';
2947            e.target.style.containIntrinsicSize = '320px';
2948          }
2949        });
2950      }, { rootMargin: '600px 0px', threshold: 0 });
2951      var mo = new MutationObserver(function () {
2952        qsa('.p-card', grid).forEach(function (c) {
2953          if (c._virt) return;
2954          c._virt = 1;
2955          c.style.contentVisibility = 'auto';
2956          c.style.containIntrinsicSize = '320px';
2957          obs.observe(c);
2958        });
2959      });
2960      mo.observe(grid, { childList: true });
2961    });
2962  }
2963  function loadHeatmaps() {
2964    var clarityId = (document.querySelector('meta[name="clarity-id"]') || {}).content;
2965    if (clarityId) {
2966      (function (c, l, a, r, i, t, y) { c[a] = c[a] || function () { (c[a].q = c[a].q || []).push(arguments); }; t = l.createElement(r); t.async = 1; t.src = 'https://www.clarity.ms/tag/' + i; y = l.getElementsByTagName(r)[0]; y.parentNode.insertBefore(t, y); })(window, document, 'clarity', 'script', clarityId);
2967    }
2968    var hjId = (document.querySelector('meta[name="hotjar-id"]') || {}).content;
2969    if (hjId) {
2970      (function (h, o, t, j, a, r) { h.hj = h.hj || function () { (h.hj.q = h.hj.q || []).push(arguments); }; h._hjSettings = { hjid: Number(hjId), hjsv: 6 }; a = o.getElementsByTagName('head')[0]; r = o.createElement('script'); r.async = 1; r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv; a.appendChild(r); })(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
2971    }
2972  }
2973  function initYear() {
2974    var y = qs('#yr');
2975    if (y) y.textContent = new Date().getFullYear();
2976  }
2977  window.addEventListener('unhandledrejection', function (e) {
2978    console.warn('[Bloom] Unhandled promise rejection:', e.reason);
2979  });
2980  window.addEventListener('error', function (e) {
2981    console.warn('[Bloom] Runtime error:', e.message);
2982  });
2983  document.addEventListener('DOMContentLoaded', function () {
2984    Api = window.Api;
2985    Store = window.Store;
2986    initBloomBoot();
2987    initYear();
2988    initCursor();
2989    initNav();
2990    initTyper();
2991    initCountdown();
2992    initParticles();
2993    initHeroParallax();
2994    initSearch();
2995    initLang();
2996    initAuth();
2997    initProfiling();
2998    initCategories();
2999    loadFeatured('all');
3000    loadCounts();
3001    loadCart();
3002    loadSiteContent();
3003    renderReviews();
3004    initStats();
3005    initReveal();
3006    initBtt();
3007    initNewsletter();
3008    initSocket();
3009    initTilt();
3010    initMagnetic();
3011    initRipple();
3012    initDelivery();
3013    initWishlist();
3014    initSubscriptions();
3015    
3016    initFunnelTracking();
3017    initVirtualization();
3018    initFormErrSummaries();
3019    loadHeatmaps();
3020  });
3021})();
3022</script>
vendor: 2 bytes, line 3022
3022
3023<script>
3024if ('serviceWorker' in navigator) {
3025  window.addEventListener('load', function () {
3026  });
3027}
3028var _deferredInstall = null;
3029window.addEventListener('beforeinstallprompt', function (e) {
3030  e.preventDefault();
3031  _deferredInstall = e;
3032});
3033(function () {
3034  var thBtn = document.getElementById('themeToggle');
3035  if (thBtn) {
3036    thBtn.addEventListener('click', function () {
3037      if (window.Store) Store.toggleTheme();
3038    });
3039  }
3040  function renderRecent() {
3041    if (!window.Store) return;
3042    var items = Store.get('recentlyViewed') || [];
3043    var sec = document.getElementById('recentSec');
3044    var grid = document.getElementById('recentGrid');
3045    if (!sec || !grid) return;
3046    if (!items.length) { sec.style.display = 'none'; return; }
3047    sec.style.display = '';
3048    grid.innerHTML = items.slice(0, 6).map(function (p) {
3049      var img = String(p.image || '').replace(/["<>]/g, '');
3050      var name = String(p.name || '').replace(/[<>&"']/g, '');
3051      return '<div class="p-card vis" role="listitem" style="padding:14px">' +
3052        '<div style="aspect-ratio:4/3;border-radius:var(--rs);overflow:hidden;margin-bottom:10px;background:var(--gl)">' +
3053        '<img src="' + img + '" alt="' + name + '" loading="lazy" decoding="async" style="width:100%;height:100%;object-fit:cover" onerror="this.onerror=null;this.style.display=\'none\'">' +
3054        '</div>' +
3055        '<div style="font-weight:600;font-size:.88rem">' + name + '</div>' +
3056        '<div style="font-size:.82rem;color:var(--text-muted)">' + (window.I18n ? I18n.formatMoney(p.price) : '\u20B1' + Number(p.price||0).toFixed(2)) + '</div>' +
3057        '</div>';
3058    }).join('');
3059  }
3060  if (window.Store) Store.on('recentlyViewed', renderRecent);
3061  document.addEventListener('DOMContentLoaded', renderRecent);
3062  var _exitShown = false;
3063  document.addEventListener('mouseleave', function (e) {
3064    if (e.clientY > 10) return;
3065    if (_exitShown) return;
3066    if (window.Store && Store.get('hasSeenExitIntent')) return;
3067    if (window.Store && Store.get('user')) return;
3068    _exitShown = true;
3069    var mod = document.getElementById('exitMod');
3070    if (mod) {
3071      mod.style.display = '';
3072      requestAnimationFrame(function () {
3073        mod.classList.add('open');
3074        mod.setAttribute('aria-hidden', 'false');
3075        document.body.classList.add('modal-open');
3076        var firstFocus = mod.querySelector('input, button');
3077        if (firstFocus) firstFocus.focus();
3078      });
3079    }
3080  });
3081  var exitClose = document.getElementById('closeExit');
3082  var exitDismiss = document.getElementById('exitDismiss');
3083  function closeExit() {
3084    var mod = document.getElementById('exitMod');
3085    if (mod) {
3086      mod.classList.remove('open');
3087      mod.setAttribute('aria-hidden', 'true');
3088      mod.style.display = 'none';
3089    }
3090    document.body.classList.remove('modal-open');
3091    if (window.Store && typeof Store.markExitIntent === 'function') Store.markExitIntent();
3092  }
3093  if (exitClose) exitClose.addEventListener('click', closeExit);
3094  if (exitDismiss) exitDismiss.addEventListener('click', closeExit);
3095  var exitCta = document.getElementById('exitCta');
3096  if (exitCta) {
3097    exitCta.addEventListener('click', function () {
3098      var email = document.getElementById('exitEmail');
3099      if (email && email.value) {
3100        if (window.showToast) showToast('Discount code sent! Check your inbox 🌸', 'success');
3101      }
3102      closeExit();
3103    });
3104  }
3105})();
3106</script>
vendor: 2 bytes, line 3106
3106
3107<script>
3108(function(){
3109  if(sessionStorage.getItem('bloom_badge_dismissed')) return;
3110  var b=document.createElement('div');
3111  b.className='bloom-academic-badge';
3112  b.setAttribute('role','status');
3113  b.innerHTML='🎓 <span>Academic Prototype</span>. This platform is a BSIT Capstone project by STI College Lipa students. All prices, transactions, and metrics are simulated for demonstration purposes only.<button class="bloom-academic-badge-close" aria-label="Dismiss">\u00d7</button>';
3114  document.body.appendChild(b);
3115  b.querySelector('.bloom-academic-badge-close').addEventListener('click',function(){b.remove();sessionStorage.setItem('bloom_badge_dismissed','1');});
3116})();
3117</script>
vendor: 2 bytes, line 3117
3117
3118<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js" defer></script>
vendor: 2 bytes, line 3118
3118
3119<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ScrollTrigger.min.js" defer></script>
vendor: 2 bytes, line 3119
3119
3120<script src="/js/core/VoiceNav.js" defer></script>
vendor: 2 bytes, line 3120
3120
3121<script src="/js/core/VideoMessage.js" defer></script>
vendor: 2 bytes, line 3121
3121
3122<script src="/js/core/SupplyChain.js" defer></script>
vendor: 2 bytes, line 3122
3122
3123<script src="/js/core/SupportUs.js" defer></script>
vendor: 2 bytes, line 3123
3123
3124<script src="/js/cookie-consent.js" defer></script>
vendor: 2 bytes, line 3124
3124
3125<script>
3126(function(){var d=false;function a(){if(d)return;d=true;var s=document.createElement('script');s.src='/js/core/GrainOverlay.js';s.defer=true;document.head.appendChild(s);}if('requestIdleCallback'in window){requestIdleCallback(a,{timeout:3000});}else{window.addEventListener('load',function(){setTimeout(a,1500);});}})();
3127window.addEventListener('load',function(){var b=document.getElementById('heroBokeh');if(b){setTimeout(function(){b.style.backgroundImage="url('/img/hero-bokeh.webp')";},400);}});
3128document.addEventListener('DOMContentLoaded', function () {
3129  if (window.BloomSupplyChain) {
3130    window.BloomSupplyChain.renderTraceability('supplyChainTrace', 'BLOOM-' + Date.now().toString(36).toUpperCase());
3131  }
3132  if (window.BloomSupport) {
3133    window.BloomSupport.renderSupportSection('supportUsContent');
3134    window.BloomSupport.renderFloatingButton();
3135  }
3136});
3137window.addEventListener('load',function(){setTimeout(function(){document.querySelectorAll('.bloom-cookie, #cookieBanner, [class*="cookie-consent"]').forEach(function(e){e.classList.add('ready');});},800);});
3138</script>
3138
3139</body>
3140</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.