@niro53/store-tools 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1243 @@
1
+ /* ─────────────────────────────────────────────────────────────────────────
2
+ * @niro/store-tools — shared scene styles
3
+ * Apple-style aesthetic: hairline borders, grouped inset tables, soft
4
+ * layered shadows, tinted-glyph icons, single-accent emphasis.
5
+ * Renders into 1320×2868 (iPhone 6.9" App Store) or 1024×500 (Play feature).
6
+ *
7
+ * Injected by render.ts via Playwright addStyleTag BEFORE each app's own
8
+ * styles.css — override :root tokens in your per-app styles.css if needed.
9
+ * ──────────────────────────────────────────────────────────────────────── */
10
+
11
+ @import url("https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Unbounded:wght@600;700;800&family=DM+Mono:wght@400;500;700&display=swap");
12
+
13
+ :root {
14
+ /* Colors */
15
+ --emerald: #3db84a;
16
+ --emerald-light: #4bc957;
17
+ --emerald-glow: rgba(61, 184, 74, 0.4);
18
+ --emerald-subtle: rgba(61, 184, 74, 0.15);
19
+ --amber: #fdb970;
20
+ --amber-glow: rgba(253, 185, 112, 0.35);
21
+ --amber-subtle: rgba(253, 185, 112, 0.15);
22
+ --coral: #d85a4a;
23
+ --coral-subtle: rgba(216, 90, 74, 0.15);
24
+ --blue: #5e93f0;
25
+ --blue-subtle: rgba(94, 147, 240, 0.15);
26
+ --purple: #9d6ff0;
27
+ --purple-subtle: rgba(157, 111, 240, 0.15);
28
+ --teal: #52d1c8;
29
+ --teal-subtle: rgba(82, 209, 200, 0.15);
30
+ --pink: #f070ae;
31
+ --pink-subtle: rgba(240, 112, 174, 0.15);
32
+ --bg-deep: #18161f;
33
+ --bg-card: #24212e;
34
+ --bg-card-hover: #2d2939;
35
+ --border: #3a3642;
36
+
37
+ /* iOS hairlines */
38
+ --hairline: rgba(255, 255, 255, 0.08);
39
+ --hairline-strong: rgba(255, 255, 255, 0.14);
40
+ --divider: rgba(255, 255, 255, 0.06);
41
+ --surface-translucent: rgba(255, 255, 255, 0.04);
42
+
43
+ /* Text */
44
+ --text: #eeecf2;
45
+ --text-secondary: #8a8795;
46
+ --text-muted: #6b6874;
47
+
48
+ /* Shadows */
49
+ --shadow-card: 0 0.5px 0 rgba(255, 255, 255, 0.05) inset, 0 4px 12px rgba(0, 0, 0, 0.18);
50
+ --shadow-floating: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 12px 32px rgba(0, 0, 0, 0.42);
51
+
52
+ /* Radii */
53
+ --r-tile: 14px;
54
+ --r-card: 22px;
55
+ --r-pill: 999px;
56
+ --r-sheet: 28px;
57
+
58
+ /* Fonts */
59
+ --font-display: "Unbounded", system-ui, sans-serif;
60
+ --font-body: "Outfit", system-ui, sans-serif;
61
+ --font-mono: "DM Mono", ui-monospace, monospace;
62
+ }
63
+
64
+ * {
65
+ box-sizing: border-box;
66
+ }
67
+
68
+ html,
69
+ body {
70
+ margin: 0;
71
+ padding: 0;
72
+ font-family: var(--font-body);
73
+ color: var(--text);
74
+ -webkit-font-smoothing: antialiased;
75
+ text-rendering: optimizeLegibility;
76
+ }
77
+
78
+ /* ───── Screen canvas (1320×2868 — iPhone 6.9" required for App Store) ───
79
+ Play Store variants are produced by clipping the top 1320×2640 of this
80
+ same canvas in render.js (no layout change needed). */
81
+ .screen {
82
+ position: relative;
83
+ width: 1320px;
84
+ height: 2868px;
85
+ overflow: hidden;
86
+ font-family: var(--font-body);
87
+ }
88
+
89
+ .screen .grain {
90
+ position: absolute;
91
+ inset: 0;
92
+ opacity: 0.018;
93
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
94
+ background-size: 200px 200px;
95
+ pointer-events: none;
96
+ }
97
+
98
+ .screen .orb {
99
+ position: absolute;
100
+ border-radius: 50%;
101
+ transform: translate(-50%, -50%);
102
+ pointer-events: none;
103
+ }
104
+
105
+ .screen .vignette {
106
+ position: absolute;
107
+ inset: 0;
108
+ background: radial-gradient(ellipse 90% 80% at 50% 40%, transparent 50%, rgba(8, 6, 14, 0.55) 100%);
109
+ pointer-events: none;
110
+ }
111
+
112
+ .screen .headline-area {
113
+ position: absolute;
114
+ top: 70px;
115
+ left: 0;
116
+ right: 0;
117
+ text-align: center;
118
+ padding: 0 50px;
119
+ z-index: 2;
120
+ font-family: var(--font-display);
121
+ }
122
+
123
+ .screen .brand {
124
+ display: flex;
125
+ align-items: center;
126
+ justify-content: center;
127
+ gap: 14px;
128
+ margin-bottom: 28px;
129
+ }
130
+
131
+ .screen .brand svg {
132
+ width: 62px;
133
+ height: 80px;
134
+ }
135
+
136
+ .screen .brand-name {
137
+ font-size: 48px;
138
+ font-weight: 700;
139
+ letter-spacing: -1px;
140
+ color: var(--text);
141
+ }
142
+
143
+ .screen .headline {
144
+ font-size: 124px;
145
+ font-weight: 800;
146
+ line-height: 1.04;
147
+ letter-spacing: -4px;
148
+ margin-bottom: 24px;
149
+ color: var(--text);
150
+ }
151
+
152
+ .screen .subline {
153
+ font-size: 48px;
154
+ font-weight: 400;
155
+ color: var(--text-secondary);
156
+ line-height: 1.35;
157
+ letter-spacing: -0.6px;
158
+ font-family: var(--font-body);
159
+ }
160
+
161
+ .screen .phone-stage {
162
+ position: absolute;
163
+ bottom: -280px;
164
+ left: 0;
165
+ right: 0;
166
+ display: flex;
167
+ justify-content: center;
168
+ z-index: 1;
169
+ }
170
+
171
+ /* ───── Phone mockup (1140×2470) ─────────────────────────────────────── */
172
+ .phone {
173
+ width: 1140px;
174
+ height: 2470px;
175
+ border-radius: 78px;
176
+ border: 3px solid #3a3840;
177
+ background: var(--bg-deep);
178
+ position: relative;
179
+ overflow: hidden;
180
+ flex-shrink: 0;
181
+ box-shadow:
182
+ 0 0 0 1px rgba(255, 255, 255, 0.06),
183
+ 0 8px 30px rgba(0, 0, 0, 0.4),
184
+ 0 40px 90px rgba(0, 0, 0, 0.5),
185
+ 0 80px 160px rgba(0, 0, 0, 0.3),
186
+ 0 0 120px var(--phone-glow, var(--emerald-glow));
187
+ }
188
+
189
+ .phone .island {
190
+ position: absolute;
191
+ top: 0;
192
+ left: 50%;
193
+ transform: translateX(-50%);
194
+ width: 260px;
195
+ height: 52px;
196
+ background: #0a0a0c;
197
+ border-radius: 0 0 28px 28px;
198
+ z-index: 10;
199
+ }
200
+
201
+ .phone .bezel-highlight {
202
+ position: absolute;
203
+ top: 0;
204
+ left: 0;
205
+ right: 0;
206
+ height: 2px;
207
+ background: linear-gradient(90deg, transparent 20%, rgba(255, 255, 255, 0.08) 50%, transparent 80%);
208
+ z-index: 11;
209
+ border-radius: 78px 78px 0 0;
210
+ }
211
+
212
+ .phone .inner {
213
+ width: 100%;
214
+ height: 100%;
215
+ padding-top: 64px;
216
+ overflow: hidden;
217
+ position: relative;
218
+ }
219
+
220
+ /* ───── Status bar ───────────────────────────────────────────────────── */
221
+ .statusbar {
222
+ display: flex;
223
+ justify-content: space-between;
224
+ align-items: center;
225
+ padding: 6px 40px 14px;
226
+ font-size: 28px;
227
+ font-weight: 600;
228
+ color: var(--text);
229
+ font-variant-numeric: tabular-nums;
230
+ }
231
+
232
+ .statusbar .icons {
233
+ display: flex;
234
+ gap: 8px;
235
+ align-items: center;
236
+ color: var(--text);
237
+ }
238
+
239
+ /* ───── App header ───────────────────────────────────────────────────── */
240
+ .app-header {
241
+ padding: 20px 40px 24px;
242
+ display: flex;
243
+ align-items: center;
244
+ justify-content: space-between;
245
+ font-family: var(--font-display);
246
+ }
247
+
248
+ .app-header h2 {
249
+ font-size: 56px;
250
+ font-weight: 700;
251
+ color: var(--text);
252
+ margin: 0;
253
+ letter-spacing: -1px;
254
+ }
255
+
256
+ .app-header .actions {
257
+ display: flex;
258
+ gap: 14px;
259
+ }
260
+
261
+ .header-icon {
262
+ width: 60px;
263
+ height: 60px;
264
+ border-radius: 50%;
265
+ background: var(--bg-card);
266
+ border: 1px solid var(--hairline);
267
+ display: flex;
268
+ align-items: center;
269
+ justify-content: center;
270
+ color: var(--text-secondary);
271
+ }
272
+
273
+ /* ───── Greeting (dashboard only) ────────────────────────────────────── */
274
+ .greeting {
275
+ padding: 12px 40px 8px;
276
+ font-size: 42px;
277
+ color: var(--text-secondary);
278
+ font-weight: 400;
279
+ }
280
+ .greeting strong {
281
+ color: var(--text);
282
+ font-weight: 600;
283
+ }
284
+
285
+ /* ───── Stat cards (Apple-style tile with tinted glyph) ──────────────── */
286
+ .stat-grid {
287
+ display: grid;
288
+ grid-template-columns: 1fr 1fr;
289
+ gap: 16px;
290
+ padding: 22px 40px;
291
+ }
292
+
293
+ .stat-card {
294
+ background: var(--bg-card);
295
+ border: 1px solid var(--hairline);
296
+ border-radius: var(--r-card);
297
+ padding: 26px 28px;
298
+ position: relative;
299
+ overflow: hidden;
300
+ box-shadow: var(--shadow-card);
301
+ }
302
+
303
+ .stat-card .icon-tile {
304
+ width: 56px;
305
+ height: 56px;
306
+ border-radius: var(--r-tile);
307
+ display: flex;
308
+ align-items: center;
309
+ justify-content: center;
310
+ margin-bottom: 18px;
311
+ }
312
+
313
+ .stat-card .label {
314
+ font-size: 26px;
315
+ color: var(--text-muted);
316
+ font-weight: 500;
317
+ margin-bottom: 10px;
318
+ letter-spacing: -0.2px;
319
+ }
320
+
321
+ .stat-card .value {
322
+ font-family: var(--font-display);
323
+ font-size: 62px;
324
+ font-weight: 700;
325
+ letter-spacing: -2px;
326
+ color: var(--text);
327
+ font-variant-numeric: tabular-nums;
328
+ line-height: 1.02;
329
+ }
330
+
331
+ .stat-card .sub {
332
+ font-size: 22px;
333
+ color: var(--text-muted);
334
+ margin-top: 8px;
335
+ letter-spacing: -0.1px;
336
+ }
337
+
338
+ .stat-card .badge {
339
+ display: inline-flex;
340
+ align-items: center;
341
+ gap: 6px;
342
+ font-size: 20px;
343
+ font-weight: 600;
344
+ padding: 6px 14px;
345
+ border-radius: var(--r-pill);
346
+ margin-top: 10px;
347
+ letter-spacing: -0.1px;
348
+ }
349
+
350
+ /* ───── Card (generic Apple-card wrapper) ────────────────────────────── */
351
+ .card {
352
+ background: var(--bg-card);
353
+ border: 1px solid var(--hairline);
354
+ border-radius: var(--r-card);
355
+ padding: 32px;
356
+ box-shadow: var(--shadow-card);
357
+ }
358
+
359
+ .card-title {
360
+ font-size: 38px;
361
+ font-weight: 700;
362
+ color: var(--text);
363
+ margin-bottom: 6px;
364
+ font-family: var(--font-display);
365
+ letter-spacing: -0.8px;
366
+ }
367
+
368
+ .card-subtitle {
369
+ font-size: 26px;
370
+ color: var(--text-muted);
371
+ margin-bottom: 32px;
372
+ letter-spacing: -0.1px;
373
+ }
374
+
375
+ /* ───── Spending chart (dashboard) ───────────────────────────────────── */
376
+ .bar-chart {
377
+ height: 220px;
378
+ display: flex;
379
+ align-items: flex-end;
380
+ gap: 10px;
381
+ }
382
+
383
+ .bar-chart .col {
384
+ flex: 1;
385
+ display: flex;
386
+ flex-direction: column;
387
+ align-items: center;
388
+ gap: 10px;
389
+ }
390
+
391
+ .bar-chart .bar {
392
+ width: 100%;
393
+ border-radius: 8px;
394
+ background: var(--surface-translucent);
395
+ border: 1px solid var(--hairline);
396
+ }
397
+
398
+ .bar-chart .bar.current {
399
+ background: var(--emerald);
400
+ border: none;
401
+ }
402
+
403
+ .bar-chart .month-label {
404
+ font-size: 24px;
405
+ color: var(--text-muted);
406
+ font-weight: 500;
407
+ font-family: var(--font-mono);
408
+ letter-spacing: -0.2px;
409
+ }
410
+
411
+ .bar-chart .month-label.current {
412
+ color: var(--text);
413
+ font-weight: 700;
414
+ }
415
+
416
+ /* ───── Section header (iOS uppercase) ───────────────────────────────── */
417
+ .section-header {
418
+ font-size: 30px;
419
+ font-weight: 600;
420
+ color: var(--text-muted);
421
+ text-transform: uppercase;
422
+ letter-spacing: 1.5px;
423
+ margin-bottom: 14px;
424
+ padding-left: 6px;
425
+ display: flex;
426
+ justify-content: space-between;
427
+ align-items: baseline;
428
+ }
429
+
430
+ .section-header .action {
431
+ font-size: 26px;
432
+ color: var(--emerald-light);
433
+ font-weight: 600;
434
+ text-transform: none;
435
+ letter-spacing: -0.2px;
436
+ }
437
+
438
+ /* ───── Grouped inset list ───────────────────────────────────────────── */
439
+ .grouped-list {
440
+ background: var(--bg-card);
441
+ border: 1px solid var(--hairline);
442
+ border-radius: var(--r-card);
443
+ overflow: hidden;
444
+ box-shadow: var(--shadow-card);
445
+ }
446
+
447
+ .grouped-list > * + * {
448
+ border-top: 1px solid var(--divider);
449
+ }
450
+
451
+ /* ───── Subscription list row ────────────────────────────────────────── */
452
+ .sub-row {
453
+ display: flex;
454
+ align-items: center;
455
+ gap: 22px;
456
+ padding: 22px 26px;
457
+ background: transparent;
458
+ }
459
+
460
+ .sub-row .logo {
461
+ width: 84px;
462
+ height: 84px;
463
+ border-radius: var(--r-tile);
464
+ display: flex;
465
+ align-items: center;
466
+ justify-content: center;
467
+ flex-shrink: 0;
468
+ }
469
+
470
+ .sub-row .meta {
471
+ flex: 1;
472
+ min-width: 0;
473
+ }
474
+
475
+ .sub-row .name {
476
+ font-size: 36px;
477
+ font-weight: 600;
478
+ color: var(--text);
479
+ margin-bottom: 6px;
480
+ letter-spacing: -0.4px;
481
+ }
482
+
483
+ .sub-row .row-2 {
484
+ font-size: 26px;
485
+ color: var(--text-muted);
486
+ display: flex;
487
+ align-items: center;
488
+ gap: 12px;
489
+ letter-spacing: -0.1px;
490
+ }
491
+
492
+ .sub-row .pill {
493
+ font-size: 22px;
494
+ font-weight: 600;
495
+ padding: 4px 12px;
496
+ border-radius: var(--r-pill);
497
+ letter-spacing: -0.1px;
498
+ }
499
+
500
+ .sub-row .right {
501
+ text-align: right;
502
+ }
503
+
504
+ .sub-row .amount {
505
+ font-family: var(--font-display);
506
+ font-size: 40px;
507
+ font-weight: 700;
508
+ color: var(--text);
509
+ letter-spacing: -0.8px;
510
+ font-variant-numeric: tabular-nums;
511
+ }
512
+
513
+ .sub-row .cycle {
514
+ font-size: 24px;
515
+ color: var(--text-muted);
516
+ letter-spacing: -0.1px;
517
+ }
518
+
519
+ .sub-row .days {
520
+ font-size: 22px;
521
+ font-weight: 600;
522
+ padding: 4px 12px;
523
+ border-radius: var(--r-pill);
524
+ display: inline-block;
525
+ margin-top: 8px;
526
+ letter-spacing: -0.1px;
527
+ }
528
+
529
+ /* ───── Filter pills (subscriptions) ─────────────────────────────────── */
530
+ .filter-pills {
531
+ display: flex;
532
+ gap: 12px;
533
+ padding: 10px 40px 20px;
534
+ overflow: hidden;
535
+ }
536
+
537
+ .filter-pills .pill {
538
+ padding: 14px 28px;
539
+ border-radius: 100px;
540
+ font-size: 26px;
541
+ font-weight: 600;
542
+ white-space: nowrap;
543
+ border: 1.5px solid var(--hairline);
544
+ color: var(--text-secondary);
545
+ background: transparent;
546
+ }
547
+
548
+ .filter-pills .pill.active {
549
+ border-color: var(--emerald);
550
+ color: #0a0a0c;
551
+ background: var(--emerald);
552
+ box-shadow: 0 0 20px var(--emerald-glow);
553
+ }
554
+
555
+ /* ───── Donut chart (insights) ───────────────────────────────────────── */
556
+ .donut-row {
557
+ display: flex;
558
+ align-items: center;
559
+ gap: 32px;
560
+ }
561
+
562
+ .donut {
563
+ width: 230px;
564
+ height: 230px;
565
+ position: relative;
566
+ flex-shrink: 0;
567
+ }
568
+
569
+ .donut svg {
570
+ width: 100%;
571
+ height: 100%;
572
+ transform: rotate(-90deg);
573
+ }
574
+
575
+ .donut .center {
576
+ position: absolute;
577
+ top: 50%;
578
+ left: 50%;
579
+ transform: translate(-50%, -50%);
580
+ text-align: center;
581
+ }
582
+
583
+ .donut .total {
584
+ font-family: var(--font-display);
585
+ font-size: 42px;
586
+ font-weight: 700;
587
+ letter-spacing: -1px;
588
+ color: var(--text);
589
+ }
590
+
591
+ .donut .label {
592
+ font-size: 22px;
593
+ color: var(--text-muted);
594
+ }
595
+
596
+ .legend {
597
+ display: flex;
598
+ flex-direction: column;
599
+ gap: 14px;
600
+ }
601
+
602
+ .legend .item {
603
+ display: flex;
604
+ align-items: center;
605
+ gap: 14px;
606
+ font-size: 26px;
607
+ color: var(--text);
608
+ }
609
+
610
+ .legend .dot {
611
+ width: 18px;
612
+ height: 18px;
613
+ border-radius: 6px;
614
+ flex-shrink: 0;
615
+ }
616
+
617
+ .legend .val {
618
+ margin-left: auto;
619
+ font-family: var(--font-display);
620
+ color: var(--text-muted);
621
+ font-size: 24px;
622
+ font-weight: 600;
623
+ }
624
+
625
+ /* ───── Smart tip card (insights) ────────────────────────────────────── */
626
+ .tip-card {
627
+ background: linear-gradient(135deg, rgba(253, 185, 112, 0.12), rgba(253, 185, 112, 0.03));
628
+ border: 1px solid rgba(253, 185, 112, 0.2);
629
+ border-radius: var(--r-card);
630
+ padding: 24px 28px;
631
+ display: flex;
632
+ align-items: flex-start;
633
+ gap: 18px;
634
+ box-shadow: var(--shadow-card);
635
+ }
636
+
637
+ .tip-card .tip-icon {
638
+ width: 54px;
639
+ height: 54px;
640
+ border-radius: var(--r-tile);
641
+ background: rgba(253, 185, 112, 0.18);
642
+ display: flex;
643
+ align-items: center;
644
+ justify-content: center;
645
+ flex-shrink: 0;
646
+ font-size: 28px;
647
+ }
648
+
649
+ .tip-card .tip-title {
650
+ font-size: 30px;
651
+ font-weight: 700;
652
+ margin-bottom: 8px;
653
+ color: var(--amber);
654
+ font-family: var(--font-display);
655
+ }
656
+
657
+ .tip-card .tip-body {
658
+ font-size: 26px;
659
+ color: var(--text-secondary);
660
+ line-height: 1.5;
661
+ }
662
+
663
+ /* ───── Services grid (services) ─────────────────────────────────────── */
664
+ .service-grid {
665
+ display: grid;
666
+ grid-template-columns: 1fr 1fr 1fr;
667
+ gap: 16px;
668
+ padding: 0 40px;
669
+ }
670
+
671
+ .service-card {
672
+ background: var(--bg-card);
673
+ border: 1px solid var(--hairline);
674
+ border-radius: var(--r-card);
675
+ padding: 28px 16px;
676
+ display: flex;
677
+ flex-direction: column;
678
+ align-items: center;
679
+ gap: 14px;
680
+ text-align: center;
681
+ box-shadow: var(--shadow-card);
682
+ }
683
+
684
+ .service-card.selected {
685
+ background: rgba(48, 150, 55, 0.06);
686
+ border-color: var(--emerald);
687
+ box-shadow: 0 0 24px var(--emerald-glow), var(--shadow-card);
688
+ }
689
+
690
+ .service-card .logo {
691
+ width: 72px;
692
+ height: 72px;
693
+ border-radius: var(--r-tile);
694
+ display: flex;
695
+ align-items: center;
696
+ justify-content: center;
697
+ }
698
+
699
+ .service-card .name {
700
+ font-size: 24px;
701
+ font-weight: 700;
702
+ color: var(--text);
703
+ }
704
+
705
+ .service-card .price {
706
+ font-size: 20px;
707
+ color: var(--text-muted);
708
+ font-family: var(--font-mono);
709
+ }
710
+
711
+ .search-bar {
712
+ background: var(--bg-card);
713
+ border: 1px solid var(--hairline);
714
+ border-radius: var(--r-tile);
715
+ padding: 18px 24px;
716
+ display: flex;
717
+ align-items: center;
718
+ gap: 14px;
719
+ margin: 0 40px 22px;
720
+ box-shadow: var(--shadow-card);
721
+ }
722
+
723
+ .search-bar .placeholder {
724
+ font-size: 26px;
725
+ color: var(--text-muted);
726
+ }
727
+
728
+ /* ───── Calendar (calendar) ──────────────────────────────────────────── */
729
+ .cal-card {
730
+ background: var(--bg-card);
731
+ border: 1px solid var(--hairline);
732
+ border-radius: var(--r-card);
733
+ margin: 0 40px;
734
+ padding: 28px;
735
+ box-shadow: var(--shadow-card);
736
+ }
737
+
738
+ .cal-header {
739
+ font-size: 36px;
740
+ font-weight: 700;
741
+ color: var(--text);
742
+ margin-bottom: 22px;
743
+ display: flex;
744
+ align-items: center;
745
+ justify-content: space-between;
746
+ font-family: var(--font-display);
747
+ letter-spacing: -0.5px;
748
+ }
749
+
750
+ .cal-arrows {
751
+ display: flex;
752
+ gap: 10px;
753
+ }
754
+
755
+ .cal-arrows .arrow {
756
+ width: 42px;
757
+ height: 42px;
758
+ border-radius: 12px;
759
+ background: var(--surface-translucent);
760
+ border: 1px solid var(--hairline);
761
+ display: flex;
762
+ align-items: center;
763
+ justify-content: center;
764
+ color: var(--text-secondary);
765
+ font-size: 22px;
766
+ }
767
+
768
+ .cal-grid {
769
+ display: grid;
770
+ grid-template-columns: repeat(7, 1fr);
771
+ gap: 5px;
772
+ text-align: center;
773
+ }
774
+
775
+ .cal-grid .wd {
776
+ font-size: 22px;
777
+ font-weight: 700;
778
+ color: var(--text-muted);
779
+ padding: 10px 0;
780
+ }
781
+
782
+ .cal-grid .day {
783
+ aspect-ratio: 1;
784
+ display: flex;
785
+ align-items: center;
786
+ justify-content: center;
787
+ border-radius: 14px;
788
+ font-size: 26px;
789
+ font-weight: 500;
790
+ color: var(--text-secondary);
791
+ background: transparent;
792
+ position: relative;
793
+ }
794
+
795
+ .cal-grid .day.today {
796
+ background: var(--emerald);
797
+ color: white;
798
+ font-weight: 700;
799
+ }
800
+
801
+ .cal-grid .day.empty {
802
+ color: transparent;
803
+ }
804
+
805
+ .cal-grid .day .dot {
806
+ position: absolute;
807
+ bottom: 5px;
808
+ width: 7px;
809
+ height: 7px;
810
+ border-radius: 50%;
811
+ }
812
+
813
+ /* ───── Reminder row (calendar) ──────────────────────────────────────── */
814
+ .reminder {
815
+ margin: 0 40px 14px;
816
+ }
817
+
818
+ .reminder .row {
819
+ background: var(--bg-card);
820
+ border: 1px solid var(--hairline);
821
+ border-radius: var(--r-card);
822
+ padding: 20px 24px;
823
+ display: flex;
824
+ align-items: center;
825
+ gap: 18px;
826
+ box-shadow: var(--shadow-card);
827
+ }
828
+
829
+ .reminder .icon-tile {
830
+ width: 56px;
831
+ height: 56px;
832
+ border-radius: var(--r-tile);
833
+ display: flex;
834
+ align-items: center;
835
+ justify-content: center;
836
+ flex-shrink: 0;
837
+ }
838
+
839
+ .reminder .body {
840
+ flex: 1;
841
+ }
842
+
843
+ .reminder .title {
844
+ font-size: 28px;
845
+ font-weight: 700;
846
+ color: var(--text);
847
+ margin-bottom: 3px;
848
+ letter-spacing: -0.2px;
849
+ }
850
+
851
+ .reminder .desc {
852
+ font-size: 22px;
853
+ color: var(--text-muted);
854
+ }
855
+
856
+ .reminder .days {
857
+ font-size: 20px;
858
+ font-weight: 700;
859
+ padding: 4px 14px;
860
+ border-radius: var(--r-pill);
861
+ }
862
+
863
+ .list-header {
864
+ padding: 28px 40px 14px;
865
+ font-size: 40px;
866
+ font-weight: 700;
867
+ color: var(--text);
868
+ display: flex;
869
+ justify-content: space-between;
870
+ align-items: baseline;
871
+ font-family: var(--font-display);
872
+ letter-spacing: -0.5px;
873
+ }
874
+
875
+ .list-header .action {
876
+ font-size: 28px;
877
+ color: var(--emerald-light);
878
+ font-weight: 500;
879
+ }
880
+
881
+ /* ───── Savings hero (savings) ───────────────────────────────────────── */
882
+ .savings-hero {
883
+ margin: 0 40px;
884
+ background: linear-gradient(135deg, rgba(48, 150, 55, 0.15) 0%, rgba(48, 150, 55, 0.03) 100%);
885
+ border: 1px solid rgba(48, 150, 55, 0.2);
886
+ border-radius: var(--r-sheet);
887
+ padding: 42px 32px;
888
+ text-align: center;
889
+ position: relative;
890
+ overflow: hidden;
891
+ }
892
+
893
+ .savings-hero::before {
894
+ content: "";
895
+ position: absolute;
896
+ top: -50%;
897
+ left: -50%;
898
+ width: 200%;
899
+ height: 200%;
900
+ background: radial-gradient(circle at 50% 50%, var(--emerald-glow) 0%, transparent 50%);
901
+ opacity: 0.3;
902
+ pointer-events: none;
903
+ }
904
+
905
+ .savings-hero .big {
906
+ position: relative;
907
+ font-family: var(--font-mono);
908
+ font-size: 108px;
909
+ font-weight: 500;
910
+ color: var(--emerald-light);
911
+ letter-spacing: -3px;
912
+ font-variant-numeric: tabular-nums;
913
+ }
914
+
915
+ .savings-hero .small {
916
+ position: relative;
917
+ font-size: 30px;
918
+ color: var(--text-secondary);
919
+ margin-top: 6px;
920
+ }
921
+
922
+ .rec-row {
923
+ margin: 14px 40px 0;
924
+ }
925
+
926
+ .rec-row .row {
927
+ display: flex;
928
+ align-items: center;
929
+ gap: 18px;
930
+ padding: 20px;
931
+ background: var(--bg-card);
932
+ border: 1px solid var(--hairline);
933
+ border-radius: var(--r-card);
934
+ box-shadow: var(--shadow-card);
935
+ }
936
+
937
+ .rec-row .logo {
938
+ width: 64px;
939
+ height: 64px;
940
+ border-radius: var(--r-tile);
941
+ display: flex;
942
+ align-items: center;
943
+ justify-content: center;
944
+ flex-shrink: 0;
945
+ }
946
+
947
+ .rec-row .body {
948
+ flex: 1;
949
+ }
950
+
951
+ .rec-row .title {
952
+ font-size: 28px;
953
+ font-weight: 700;
954
+ color: var(--text);
955
+ margin-bottom: 6px;
956
+ letter-spacing: -0.3px;
957
+ }
958
+
959
+ .rec-row .prices {
960
+ display: flex;
961
+ align-items: center;
962
+ gap: 12px;
963
+ }
964
+
965
+ .rec-row .old {
966
+ font-size: 22px;
967
+ color: var(--text-muted);
968
+ text-decoration: line-through;
969
+ font-family: var(--font-mono);
970
+ }
971
+
972
+ .rec-row .arrow {
973
+ color: var(--text-muted);
974
+ }
975
+
976
+ .rec-row .new {
977
+ font-size: 28px;
978
+ font-weight: 700;
979
+ color: var(--emerald-light);
980
+ font-family: var(--font-mono);
981
+ }
982
+
983
+ .rec-row .pct {
984
+ font-size: 20px;
985
+ font-weight: 700;
986
+ padding: 5px 14px;
987
+ border-radius: var(--r-pill);
988
+ color: var(--emerald-light);
989
+ background: var(--emerald-subtle);
990
+ }
991
+
992
+ .rec-row.unused .row {
993
+ border-color: rgba(251, 173, 96, 0.25);
994
+ }
995
+
996
+ .rec-row.unused .price-strong {
997
+ font-family: var(--font-mono);
998
+ font-size: 28px;
999
+ font-weight: 500;
1000
+ color: var(--coral);
1001
+ }
1002
+
1003
+ .rec-row.unused .price-small {
1004
+ font-size: 20px;
1005
+ color: var(--text-muted);
1006
+ }
1007
+
1008
+ /* ───── Bottom nav ───────────────────────────────────────────────────── */
1009
+ .bottom-nav {
1010
+ position: absolute;
1011
+ bottom: 0;
1012
+ left: 0;
1013
+ right: 0;
1014
+ background: rgba(15, 15, 20, 0.95);
1015
+ backdrop-filter: blur(20px);
1016
+ -webkit-backdrop-filter: blur(20px);
1017
+ border-top: 1px solid var(--hairline);
1018
+ display: flex;
1019
+ justify-content: space-around;
1020
+ padding: 16px 20px 38px;
1021
+ }
1022
+
1023
+ .bottom-nav .item {
1024
+ display: flex;
1025
+ flex-direction: column;
1026
+ align-items: center;
1027
+ gap: 5px;
1028
+ font-size: 20px;
1029
+ color: var(--text-muted);
1030
+ font-weight: 500;
1031
+ }
1032
+
1033
+ .bottom-nav .item.active {
1034
+ color: var(--emerald-light);
1035
+ }
1036
+
1037
+ .bottom-nav .fab {
1038
+ width: 72px;
1039
+ height: 72px;
1040
+ border-radius: 50%;
1041
+ background: var(--emerald);
1042
+ display: flex;
1043
+ align-items: center;
1044
+ justify-content: center;
1045
+ margin-top: -32px;
1046
+ box-shadow: 0 4px 24px var(--emerald-glow);
1047
+ }
1048
+
1049
+ /* ───── Feature graphic (1024×500) ───────────────────────────────────── */
1050
+ .feature {
1051
+ width: 1024px;
1052
+ height: 500px;
1053
+ background: linear-gradient(135deg, #0a0c0a 0%, #0c1210 30%, #0a0a0e 100%);
1054
+ display: flex;
1055
+ align-items: center;
1056
+ justify-content: center;
1057
+ gap: 80px;
1058
+ padding: 0 80px;
1059
+ position: relative;
1060
+ overflow: hidden;
1061
+ }
1062
+
1063
+ .feature .orb-a {
1064
+ position: absolute;
1065
+ width: 400px;
1066
+ height: 400px;
1067
+ background: var(--emerald);
1068
+ opacity: 0.08;
1069
+ border-radius: 50%;
1070
+ filter: blur(100px);
1071
+ right: -100px;
1072
+ bottom: -100px;
1073
+ }
1074
+
1075
+ .feature .orb-b {
1076
+ position: absolute;
1077
+ width: 300px;
1078
+ height: 300px;
1079
+ background: var(--amber);
1080
+ opacity: 0.05;
1081
+ border-radius: 50%;
1082
+ filter: blur(100px);
1083
+ left: -50px;
1084
+ top: -80px;
1085
+ }
1086
+
1087
+ .feature .grain {
1088
+ position: absolute;
1089
+ inset: 0;
1090
+ opacity: 0.028;
1091
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
1092
+ background-size: 200px 200px;
1093
+ pointer-events: none;
1094
+ }
1095
+
1096
+ .feature .left {
1097
+ z-index: 1;
1098
+ }
1099
+
1100
+ .feature .brand-row {
1101
+ display: flex;
1102
+ align-items: center;
1103
+ gap: 20px;
1104
+ margin-bottom: 24px;
1105
+ }
1106
+
1107
+ .feature .brand-row .logo svg {
1108
+ width: 64px;
1109
+ height: 82px;
1110
+ }
1111
+
1112
+ .feature .brand-row .wm {
1113
+ font-size: 48px;
1114
+ font-weight: 800;
1115
+ letter-spacing: -1px;
1116
+ font-family: var(--font-display);
1117
+ background: linear-gradient(180deg, var(--emerald-light) 0%, var(--emerald) 100%);
1118
+ -webkit-background-clip: text;
1119
+ background-clip: text;
1120
+ -webkit-text-fill-color: transparent;
1121
+ color: transparent;
1122
+ }
1123
+
1124
+ .feature .tagline {
1125
+ font-size: 26px;
1126
+ font-weight: 400;
1127
+ color: var(--text-secondary);
1128
+ line-height: 1.5;
1129
+ max-width: 420px;
1130
+ }
1131
+
1132
+ .feature .mini-phone {
1133
+ width: 260px;
1134
+ height: 420px;
1135
+ border-radius: 36px;
1136
+ border: 3px solid #3a3840;
1137
+ background: var(--bg-deep);
1138
+ position: relative;
1139
+ overflow: hidden;
1140
+ flex-shrink: 0;
1141
+ z-index: 1;
1142
+ box-shadow:
1143
+ 0 0 0 1px rgba(255, 255, 255, 0.06),
1144
+ 0 30px 80px rgba(0, 0, 0, 0.5),
1145
+ 0 0 60px var(--emerald-glow);
1146
+ }
1147
+
1148
+ .mini-phone .status {
1149
+ padding: 16px 14px;
1150
+ font-size: 9px;
1151
+ display: flex;
1152
+ justify-content: space-between;
1153
+ color: var(--text-secondary);
1154
+ }
1155
+
1156
+ .mini-phone .body {
1157
+ padding: 4px 16px;
1158
+ }
1159
+
1160
+ .mini-phone .greet {
1161
+ font-size: 13px;
1162
+ color: var(--text-secondary);
1163
+ margin-bottom: 2px;
1164
+ }
1165
+
1166
+ .mini-phone .title {
1167
+ font-size: 18px;
1168
+ font-weight: 700;
1169
+ color: var(--text);
1170
+ margin-bottom: 14px;
1171
+ }
1172
+
1173
+ .mini-phone .stat-row {
1174
+ display: grid;
1175
+ grid-template-columns: 1fr 1fr;
1176
+ gap: 8px;
1177
+ margin-bottom: 12px;
1178
+ }
1179
+
1180
+ .mini-phone .mini-stat {
1181
+ background: var(--bg-card);
1182
+ border: 1px solid var(--hairline);
1183
+ border-radius: 10px;
1184
+ padding: 10px;
1185
+ }
1186
+
1187
+ .mini-phone .mini-stat .l {
1188
+ font-size: 8px;
1189
+ color: var(--text-muted);
1190
+ margin-bottom: 4px;
1191
+ }
1192
+
1193
+ .mini-phone .mini-stat .v {
1194
+ font-family: var(--font-mono);
1195
+ font-size: 16px;
1196
+ font-weight: 500;
1197
+ }
1198
+
1199
+ .mini-phone .mini-stat .v.green {
1200
+ color: var(--emerald-light);
1201
+ }
1202
+
1203
+ .mini-phone .mini-stat .v.blue {
1204
+ color: var(--blue);
1205
+ }
1206
+
1207
+ .mini-phone .mini-sub {
1208
+ background: var(--bg-card);
1209
+ border: 1px solid var(--hairline);
1210
+ border-radius: 8px;
1211
+ padding: 8px 10px;
1212
+ display: flex;
1213
+ align-items: center;
1214
+ gap: 8px;
1215
+ margin-bottom: 6px;
1216
+ }
1217
+
1218
+ .mini-phone .mini-sub .logo {
1219
+ width: 28px;
1220
+ height: 28px;
1221
+ border-radius: 7px;
1222
+ display: flex;
1223
+ align-items: center;
1224
+ justify-content: center;
1225
+ flex-shrink: 0;
1226
+ }
1227
+
1228
+ .mini-phone .mini-sub .name {
1229
+ font-size: 11px;
1230
+ font-weight: 600;
1231
+ color: var(--text);
1232
+ }
1233
+
1234
+ .mini-phone .mini-sub .d {
1235
+ font-size: 8px;
1236
+ color: var(--text-muted);
1237
+ }
1238
+
1239
+ .mini-phone .mini-sub .price {
1240
+ font-family: var(--font-mono);
1241
+ font-size: 11px;
1242
+ color: var(--text);
1243
+ }