@jungherz-de/glasskit 1.3.4 → 1.4.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.
package/SKILL.md ADDED
@@ -0,0 +1,1518 @@
1
+ ---
2
+ name: glasskit-css
3
+ description: GlassKit is a pure CSS glassmorphism component library (v1.4.0) with 24 components, Dark & Light mode, design tokens, and BEM-like naming. Use this reference whenever generating HTML that uses GlassKit classes to ensure correct structure, nesting, modifiers, and token usage.
4
+ ---
5
+
6
+ # GlassKit CSS – AI Component Reference
7
+
8
+ > **Purpose:** This document is an AI-optimized reference for generating correct GlassKit HTML markup.
9
+ > It replaces the need to parse `docs.html` and provides copy-paste-ready structures, rules, and composition patterns.
10
+
11
+ ---
12
+
13
+ ## 1. Setup & Boilerplate
14
+
15
+ ### Including the Library
16
+
17
+ ```html
18
+ <!-- CDN (recommended) -->
19
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.4/glasskit.min.css">
20
+
21
+ <!-- Local -->
22
+ <link rel="stylesheet" href="glasskit.css">
23
+
24
+ <!-- Optional: Load custom theme after base library -->
25
+ <link rel="stylesheet" href="theme-override.css">
26
+ ```
27
+
28
+ ### Minimal Template
29
+
30
+ ```html
31
+ <!DOCTYPE html>
32
+ <html lang="en" data-theme="dark">
33
+ <head>
34
+ <meta charset="UTF-8">
35
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
36
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.4/glasskit.min.css">
37
+ </head>
38
+ <body>
39
+ <div class="glass-bg">
40
+ <!-- All content goes here -->
41
+ </div>
42
+ </body>
43
+ </html>
44
+ ```
45
+
46
+ ### Naming Convention
47
+
48
+ - **Prefix:** All components use `glass-` (e.g. `glass-card`, `glass-btn`)
49
+ - **Utilities:** Use `gl-` (e.g. `gl-stack`, `gl-row`, `gl-mt-md`)
50
+ - **BEM logic:** `glass-component__element--modifier`
51
+ - Element: `glass-card__text`, `glass-modal__header`
52
+ - Modifier: `glass-btn--primary`, `glass-avatar--lg`
53
+ - **State classes:** `is-active`, `is-open`, `is-visible` (standalone, not BEM)
54
+
55
+ ### Theming
56
+
57
+ The theme is controlled via `data-theme` on `<html>`:
58
+
59
+ ```html
60
+ <!-- Dark Mode (default) -->
61
+ <html data-theme="dark">
62
+
63
+ <!-- Light Mode -->
64
+ <html data-theme="light">
65
+ ```
66
+
67
+ Toggle theme via JavaScript:
68
+
69
+ ```js
70
+ function toggleTheme() {
71
+ const html = document.documentElement;
72
+ const current = html.getAttribute('data-theme');
73
+ html.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 2. Design Tokens
80
+
81
+ All visual values are controlled via CSS Custom Properties. For custom theming, override them in a `theme-override.css`.
82
+
83
+ ### Colors
84
+
85
+ | Token | Dark | Light | Usage |
86
+ |---|---|---|---|
87
+ | `--gl-color-primary` | `#f5a623` | `#e8852d` | Primary color, buttons, active elements |
88
+ | `--gl-color-primary-dark` | `#d4692a` | `#c96a1e` | Gradient end value |
89
+ | `--gl-color-primary-mid` | `#e07a24` | `#d97826` | Gradient midpoint |
90
+ | `--gl-color-text` | `#ffffff` | `#1a2a36` | Default text color |
91
+ | `--gl-color-text-muted` | `rgba(255,255,255,0.60)` | `rgba(26,42,54,0.55)` | Secondary text |
92
+ | `--gl-color-text-heading` | `#ffffff` | `#0f1f2a` | Headings |
93
+ | `--gl-color-success` | `#34c759` | `#28a745` | Success |
94
+ | `--gl-color-error` | `#ff3b30` | `#dc3545` | Error |
95
+ | `--gl-color-warning` | `#ffcc00` | `#e6a800` | Warning |
96
+
97
+ ### Glass Surfaces
98
+
99
+ | Token | Dark | Usage |
100
+ |---|---|---|
101
+ | `--gl-surface-1` | `rgba(255,255,255, 0.08)` | Subtlest surface (status) |
102
+ | `--gl-surface-2` | `rgba(255,255,255, 0.10)` | Default (inputs, cards) |
103
+ | `--gl-surface-3` | `rgba(255,255,255, 0.14)` | Nav pills, badges |
104
+ | `--gl-surface-4` | `rgba(255,255,255, 0.16)` | Hover states |
105
+ | `--gl-surface-5` | `rgba(255,255,255, 0.22)` | Strong hover |
106
+ | `--gl-surface-milk` | `rgba(255,255,255, 0.55)` | Milky |
107
+ | `--gl-surface-milk-strong` | `rgba(255,255,255, 0.75)` | Secondary button |
108
+ | `--gl-surface-overlay` | `rgba(0,0,0, 0.50)` | Modal overlay |
109
+
110
+ ### Borders
111
+
112
+ | Token | Value |
113
+ |---|---|
114
+ | `--gl-border-subtle` | `rgba(255,255,255, 0.18)` |
115
+ | `--gl-border-medium` | `rgba(255,255,255, 0.30)` |
116
+ | `--gl-border-strong` | `rgba(255,255,255, 0.40)` |
117
+ | `--gl-border-milk` | `rgba(255,255,255, 0.60)` |
118
+ | `--gl-border-warm` | `rgba(255,200,100, 0.35)` |
119
+ | `--gl-border-focus` | `rgba(245,166,35, 0.60)` |
120
+
121
+ ### Blur
122
+
123
+ | Token | Value |
124
+ |---|---|
125
+ | `--gl-blur` | `24px` (default) |
126
+ | `--gl-blur-light` | `16px` |
127
+ | `--gl-blur-soft` | `12px` |
128
+ | `--gl-blur-heavy` | `40px` |
129
+
130
+ ### Radii
131
+
132
+ | Token | Value | Usage |
133
+ |---|---|---|
134
+ | `--gl-radius-xs` | `8px` | Small elements |
135
+ | `--gl-radius-sm` | `12px` | Badges, small containers |
136
+ | `--gl-radius-input` | `14px` | Inputs, textareas |
137
+ | `--gl-radius-btn` | `16px` | Buttons |
138
+ | `--gl-radius-card` | `24px` | Cards |
139
+ | `--gl-radius-full` | `9999px` | Fully rounded |
140
+ | `--gl-radius-pill` | `50%` | Circle shape |
141
+
142
+ ### Spacing
143
+
144
+ | Token | Value |
145
+ |---|---|
146
+ | `--gl-space-2xs` | `4px` |
147
+ | `--gl-space-xs` | `8px` |
148
+ | `--gl-space-sm` | `12px` |
149
+ | `--gl-space-md` | `16px` |
150
+ | `--gl-space-lg` | `20px` |
151
+ | `--gl-space-xl` | `24px` |
152
+ | `--gl-space-2xl` | `32px` |
153
+ | `--gl-space-3xl` | `40px` |
154
+ | `--gl-space-4xl` | `56px` |
155
+
156
+ ### Shadows
157
+
158
+ | Token | Usage |
159
+ |---|---|
160
+ | `--gl-shadow-card` | Cards |
161
+ | `--gl-shadow-btn` | Default buttons |
162
+ | `--gl-shadow-btn-primary` | Primary button (orange glow) |
163
+ | `--gl-shadow-glow` | Glow effect |
164
+ | `--gl-shadow-modal` | Modal dialog |
165
+ | `--gl-shadow-toast` | Toast notifications |
166
+ | `--gl-shadow-focus` | Focus ring |
167
+
168
+ ### Typography
169
+
170
+ | Token | Value |
171
+ |---|---|
172
+ | `--gl-font-size-xs` | `13px` |
173
+ | `--gl-font-size-sm` | `14px` |
174
+ | `--gl-font-size-base` | `15px` |
175
+ | `--gl-font-size-btn` | `16px` |
176
+ | `--gl-font-size-lg` | `18px` |
177
+ | `--gl-font-size-title` | `24px` |
178
+ | `--gl-font-size-modal` | `20px` |
179
+ | `--gl-font-weight-normal` | `400` |
180
+ | `--gl-font-weight-medium` | `500` |
181
+ | `--gl-font-weight-semibold` | `600` |
182
+
183
+ ---
184
+
185
+ ## 3. Component Catalog
186
+
187
+ ### 3.1 Background
188
+
189
+ The outermost container element. Creates the aurora background with light effects. **Must always be used as the wrapper for all content.**
190
+
191
+ ```html
192
+ <div class="glass-bg">
193
+ <!-- All content goes here -->
194
+ </div>
195
+ ```
196
+
197
+ With Tab-Bar (adds bottom padding):
198
+
199
+ ```html
200
+ <div class="glass-bg glass-bg--has-tab-bar">
201
+ <!-- Content -->
202
+ <nav class="glass-tab-bar">...</nav>
203
+ </div>
204
+ ```
205
+
206
+ | Class | Description |
207
+ |---|---|
208
+ | `.glass-bg` | Full-screen background with aurora light effects |
209
+ | `.glass-bg--has-tab-bar` | Modifier: bottom padding for tab bar (82px) |
210
+
211
+ ---
212
+
213
+ ### 3.2 Navigation Bar
214
+
215
+ Transparent navigation bar. Typically contains `glass-pill` buttons.
216
+
217
+ ```html
218
+ <nav class="glass-nav">
219
+ <button class="glass-pill">
220
+ <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
221
+ </button>
222
+ <button class="glass-pill">
223
+ <svg viewBox="0 0 24 24"><!-- Icon --></svg>
224
+ </button>
225
+ </nav>
226
+ ```
227
+
228
+ | Class | Description |
229
+ |---|---|
230
+ | `.glass-nav` | Flex container with `space-between`, padding |
231
+
232
+ ---
233
+
234
+ ### 3.3 Pill Button
235
+
236
+ Round glass icon buttons (46×46px). Used in nav bars and as standalone action buttons.
237
+
238
+ ```html
239
+ <button class="glass-pill">
240
+ <svg viewBox="0 0 24 24"><!-- Icon SVG --></svg>
241
+ </button>
242
+ ```
243
+
244
+ | Class | Description |
245
+ |---|---|
246
+ | `.glass-pill` | Round glass button (46×46px) |
247
+ | `.glass-theme-toggle` | Specialized pill with automatic moon/sun switch |
248
+
249
+ Theme Toggle (specialized pill):
250
+
251
+ ```html
252
+ <button class="glass-theme-toggle" onclick="toggleTheme()">
253
+ <svg class="icon-moon" viewBox="0 0 24 24">
254
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
255
+ </svg>
256
+ <svg class="icon-sun" viewBox="0 0 24 24">
257
+ <circle cx="12" cy="12" r="5"/>
258
+ <line x1="12" y1="1" x2="12" y2="3"/>
259
+ <line x1="12" y1="21" x2="12" y2="23"/>
260
+ <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
261
+ <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
262
+ <line x1="1" y1="12" x2="3" y2="12"/>
263
+ <line x1="21" y1="12" x2="23" y2="12"/>
264
+ <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
265
+ <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
266
+ </svg>
267
+ </button>
268
+ ```
269
+
270
+ ---
271
+
272
+ ### 3.4 Tab Bar
273
+
274
+ Fixed bottom navigation with glass background. Requires `glass-bg--has-tab-bar` on the background container.
275
+
276
+ ```html
277
+ <nav class="glass-tab-bar">
278
+ <button class="glass-tab-bar__item is-active">
279
+ <span class="glass-tab-bar__icon">
280
+ <svg viewBox="0 0 24 24"><!-- Icon --></svg>
281
+ </span>
282
+ <span class="glass-tab-bar__label">Home</span>
283
+ </button>
284
+ <button class="glass-tab-bar__item">
285
+ <span class="glass-tab-bar__icon">
286
+ <svg viewBox="0 0 24 24"><!-- Icon --></svg>
287
+ <span class="glass-tab-bar__badge">3</span>
288
+ </span>
289
+ <span class="glass-tab-bar__label">Contracts</span>
290
+ </button>
291
+ <button class="glass-tab-bar__item">
292
+ <span class="glass-tab-bar__icon">
293
+ <svg viewBox="0 0 24 24"><!-- Icon --></svg>
294
+ </span>
295
+ <span class="glass-tab-bar__label">Profile</span>
296
+ </button>
297
+ </nav>
298
+ ```
299
+
300
+ | Class | Description |
301
+ |---|---|
302
+ | `.glass-tab-bar` | Container: fixed bottom, glass blur |
303
+ | `.glass-tab-bar__item` | Individual tab |
304
+ | `.glass-tab-bar__item.is-active` | Active tab (primary color) |
305
+ | `.glass-tab-bar__icon` | Icon wrapper |
306
+ | `.glass-tab-bar__badge` | Numeric badge inside icon |
307
+ | `.glass-tab-bar__label` | Text label below icon |
308
+
309
+ ---
310
+
311
+ ### 3.5 Title
312
+
313
+ Page title with text shadow effect.
314
+
315
+ ```html
316
+ <h1 class="glass-title">Page Title</h1>
317
+ ```
318
+
319
+ | Class | Description |
320
+ |---|---|
321
+ | `.glass-title` | Large title (24px, bold, text-shadow) |
322
+
323
+ ---
324
+
325
+ ### 3.6 Card
326
+
327
+ Glassmorphism container for content. Optionally with glow effect (frosted glass gradient + light streak).
328
+
329
+ ```html
330
+ <!-- Standard Card -->
331
+ <div class="glass-card">
332
+ <p class="glass-card__text">Content</p>
333
+ </div>
334
+
335
+ <!-- Glow Card with Icon -->
336
+ <div class="glass-card glass-card--glow">
337
+ <div class="glass-card__icon">
338
+ <svg viewBox="0 0 64 64"><!-- Icon SVG --></svg>
339
+ </div>
340
+ <p class="glass-card__text">Description text goes here.</p>
341
+ </div>
342
+ ```
343
+
344
+ | Class | Description |
345
+ |---|---|
346
+ | `.glass-card` | Base glass container (border-radius: 24px) |
347
+ | `.glass-card--glow` | Frosted glass gradient with light streak effect |
348
+ | `.glass-card__icon` | Centered icon wrapper (SVG, 48×48px) |
349
+ | `.glass-card__text` | Description text (muted) |
350
+
351
+ ---
352
+
353
+ ### 3.7 Buttons
354
+
355
+ Full-width buttons (56px height) with three variants and size modifiers.
356
+
357
+ ```html
358
+ <!-- Primary: Color gradient, main action -->
359
+ <button class="glass-btn glass-btn--primary">
360
+ <svg viewBox="0 0 24 24"><!-- Optional: Icon --></svg>
361
+ Primary Action
362
+ </button>
363
+
364
+ <!-- Secondary: Milky white -->
365
+ <button class="glass-btn glass-btn--secondary">Secondary Action</button>
366
+
367
+ <!-- Tertiary: Subtle glass -->
368
+ <button class="glass-btn glass-btn--tertiary">Tertiary Action</button>
369
+
370
+ <!-- Sizes -->
371
+ <button class="glass-btn glass-btn--primary glass-btn--sm">Small (44px)</button>
372
+ <button class="glass-btn glass-btn--primary glass-btn--lg">Large (64px)</button>
373
+
374
+ <!-- Auto-width (instead of full-width) -->
375
+ <button class="glass-btn glass-btn--primary glass-btn--auto">Auto</button>
376
+ ```
377
+
378
+ | Class | Description |
379
+ |---|---|
380
+ | `.glass-btn` | Base (56px height, width: 100%) |
381
+ | `.glass-btn--primary` | Color gradient (orange) |
382
+ | `.glass-btn--secondary` | Milky white, dark text |
383
+ | `.glass-btn--tertiary` | Subtle glass, more transparent |
384
+ | `.glass-btn--sm` | 44px height |
385
+ | `.glass-btn--lg` | 64px height |
386
+ | `.glass-btn--auto` | Width: auto instead of 100% |
387
+
388
+ **Important:** Buttons default to `width: 100%`. Use `--auto` for inline/auto-width buttons.
389
+
390
+ ---
391
+
392
+ ### 3.8 Badge
393
+
394
+ Tags and labels.
395
+
396
+ ```html
397
+ <span class="glass-badge">Default</span>
398
+ <span class="glass-badge glass-badge--primary">Active</span>
399
+ <span class="glass-badge glass-badge--success">Done</span>
400
+ <span class="glass-badge glass-badge--error">Error</span>
401
+ ```
402
+
403
+ | Class | Description |
404
+ |---|---|
405
+ | `.glass-badge` | Default (subtle glass) |
406
+ | `.glass-badge--primary` | Primary color |
407
+ | `.glass-badge--success` | Green |
408
+ | `.glass-badge--error` | Red |
409
+
410
+ ---
411
+
412
+ ### 3.9 Avatar
413
+
414
+ Glass circles in three sizes. For initials, icons, or images.
415
+
416
+ ```html
417
+ <div class="glass-avatar glass-avatar--sm">S</div>
418
+ <div class="glass-avatar">M</div>
419
+ <div class="glass-avatar glass-avatar--lg">L</div>
420
+ ```
421
+
422
+ | Class | Description |
423
+ |---|---|
424
+ | `.glass-avatar` | Default size (medium) |
425
+ | `.glass-avatar--sm` | Small |
426
+ | `.glass-avatar--lg` | Large |
427
+
428
+ ---
429
+
430
+ ### 3.10 Divider
431
+
432
+ Horizontal separator line with fade effect.
433
+
434
+ ```html
435
+ <hr class="glass-divider">
436
+ ```
437
+
438
+ ---
439
+
440
+ ### 3.11 Status Notice
441
+
442
+ Info/notice card with icon and text.
443
+
444
+ ```html
445
+ <div class="glass-status">
446
+ <svg viewBox="0 0 24 24">
447
+ <circle cx="12" cy="12" r="10"/>
448
+ <line x1="12" y1="16" x2="12" y2="12"/>
449
+ <line x1="12" y1="8" x2="12" y2="8"/>
450
+ </svg>
451
+ <p>No documents captured yet.</p>
452
+ </div>
453
+ ```
454
+
455
+ | Class | Description |
456
+ |---|---|
457
+ | `.glass-status` | Container with subtle glass surface |
458
+
459
+ ---
460
+
461
+ ### 3.12 Modal
462
+
463
+ Centered dialog with blur overlay. Controlled via the `is-active` state class on the overlay.
464
+
465
+ ```html
466
+ <div class="glass-modal-overlay is-active">
467
+ <div class="glass-modal">
468
+ <div class="glass-modal__header">
469
+ <h2 class="glass-modal__title">Delete contract?</h2>
470
+ </div>
471
+ <div class="glass-modal__body">
472
+ <p>This action cannot be undone.</p>
473
+ </div>
474
+ <div class="glass-modal__footer">
475
+ <button class="glass-modal__action">Cancel</button>
476
+ <button class="glass-modal__action glass-modal__action--primary">Confirm</button>
477
+ </div>
478
+ </div>
479
+ </div>
480
+ ```
481
+
482
+ Danger variant:
483
+
484
+ ```html
485
+ <button class="glass-modal__action glass-modal__action--danger">Delete</button>
486
+ ```
487
+
488
+ | Class | Description |
489
+ |---|---|
490
+ | `.glass-modal-overlay` | Fullscreen container with blur |
491
+ | `.glass-modal-overlay.is-active` | Visible + animated |
492
+ | `.glass-modal` | Dialog box |
493
+ | `.glass-modal__header` | Header area |
494
+ | `.glass-modal__title` | Title (20px, bold) |
495
+ | `.glass-modal__body` | Content area |
496
+ | `.glass-modal__footer` | Action bar |
497
+ | `.glass-modal__action` | Action button in footer |
498
+ | `.glass-modal__action--primary` | Primary action (colored) |
499
+ | `.glass-modal__action--danger` | Dangerous action (red) |
500
+
501
+ **Important:** `is-active` goes on `.glass-modal-overlay`, **not** on `.glass-modal`.
502
+
503
+ JavaScript to open/close:
504
+
505
+ ```js
506
+ // Open
507
+ document.querySelector('.glass-modal-overlay').classList.add('is-active');
508
+ // Close
509
+ document.querySelector('.glass-modal-overlay').classList.remove('is-active');
510
+ ```
511
+
512
+ ---
513
+
514
+ ### 3.13 Toast
515
+
516
+ Temporary notification. Visible via `is-visible`. Three variants.
517
+
518
+ ```html
519
+ <div class="glass-toast glass-toast--success is-visible">
520
+ <svg class="glass-toast__icon" viewBox="0 0 24 24"><!-- Icon --></svg>
521
+ <span class="glass-toast__text">Saved successfully!</span>
522
+ </div>
523
+ ```
524
+
525
+ | Class | Description |
526
+ |---|---|
527
+ | `.glass-toast` | Base container |
528
+ | `.glass-toast--success` | Green accent |
529
+ | `.glass-toast--error` | Red accent |
530
+ | `.glass-toast--warning` | Yellow accent |
531
+ | `.glass-toast.is-visible` | Visible + faded in |
532
+ | `.glass-toast__icon` | Icon (SVG) |
533
+ | `.glass-toast__text` | Message text |
534
+
535
+ ---
536
+
537
+ ### 3.14 Input
538
+
539
+ Text fields with glass background. Wrapped in a `glass-input-group` with label and optional hint.
540
+
541
+ ```html
542
+ <div class="glass-input-group">
543
+ <label class="glass-label">Contract Name</label>
544
+ <input class="glass-input" type="text" placeholder="e.g. Rental Agreement">
545
+ <span class="glass-hint">Optional help text</span>
546
+ </div>
547
+ ```
548
+
549
+ Error state:
550
+
551
+ ```html
552
+ <div class="glass-input-group">
553
+ <label class="glass-label">Email</label>
554
+ <input class="glass-input glass-input--error" type="email" value="invalid@">
555
+ <span class="glass-hint glass-hint--error">Please enter a valid email address</span>
556
+ </div>
557
+ ```
558
+
559
+ Disabled:
560
+
561
+ ```html
562
+ <input class="glass-input" type="text" disabled>
563
+ ```
564
+
565
+ | Class | Description |
566
+ |---|---|
567
+ | `.glass-input-group` | Wrapper for label + input + hint |
568
+ | `.glass-label` | Label (small, muted, uppercase) |
569
+ | `.glass-input` | Text input (glass background) |
570
+ | `.glass-input--error` | Red border for error state |
571
+ | `.glass-hint` | Help text below input |
572
+ | `.glass-hint--error` | Red help text |
573
+
574
+ ---
575
+
576
+ ### 3.15 Textarea
577
+
578
+ Multi-line text field.
579
+
580
+ ```html
581
+ <textarea class="glass-textarea" placeholder="Optional notes…"></textarea>
582
+ ```
583
+
584
+ | Class | Description |
585
+ |---|---|
586
+ | `.glass-textarea` | Multi-line glass input |
587
+
588
+ ---
589
+
590
+ ### 3.16 Select
591
+
592
+ Dropdown with glass styling and custom chevron.
593
+
594
+ ```html
595
+ <select class="glass-select">
596
+ <option>Please select…</option>
597
+ <option>Insurance</option>
598
+ <option>Rental Agreement</option>
599
+ </select>
600
+ ```
601
+
602
+ | Class | Description |
603
+ |---|---|
604
+ | `.glass-select` | Styled dropdown |
605
+
606
+ ---
607
+
608
+ ### 3.17 Search
609
+
610
+ Search field with embedded search icon.
611
+
612
+ ```html
613
+ <div class="glass-search">
614
+ <svg class="glass-search__icon" viewBox="0 0 24 24">
615
+ <circle cx="11" cy="11" r="8"/>
616
+ <line x1="21" y1="21" x2="16.65" y2="16.65"/>
617
+ </svg>
618
+ <input class="glass-input" type="search" placeholder="Search contracts…">
619
+ </div>
620
+ ```
621
+
622
+ | Class | Description |
623
+ |---|---|
624
+ | `.glass-search` | Wrapper (position: relative) |
625
+ | `.glass-search__icon` | Positioned search icon (left) |
626
+
627
+ **Important:** The input inside `.glass-search` uses the regular `.glass-input` class.
628
+
629
+ ---
630
+
631
+ ### 3.18 Toggle Switch
632
+
633
+ iOS-style switch.
634
+
635
+ ```html
636
+ <label class="glass-toggle">
637
+ <input class="glass-toggle__input" type="checkbox" checked>
638
+ <span class="glass-toggle__track">
639
+ <span class="glass-toggle__thumb"></span>
640
+ </span>
641
+ <span class="glass-toggle__label">Notifications</span>
642
+ </label>
643
+ ```
644
+
645
+ | Class | Description |
646
+ |---|---|
647
+ | `.glass-toggle` | Outer label (flex container) |
648
+ | `.glass-toggle__input` | Hidden checkbox input |
649
+ | `.glass-toggle__track` | Visible track |
650
+ | `.glass-toggle__thumb` | Movable thumb |
651
+ | `.glass-toggle__label` | Text label |
652
+
653
+ **State:** `:checked` on the input activates the toggle visually.
654
+
655
+ ---
656
+
657
+ ### 3.19 Checkbox
658
+
659
+ Animated checkbox with checkmark SVG.
660
+
661
+ ```html
662
+ <label class="glass-checkbox">
663
+ <input class="glass-checkbox__input" type="checkbox" checked>
664
+ <span class="glass-checkbox__box">
665
+ <svg viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>
666
+ </span>
667
+ <span class="glass-checkbox__label">Accept terms of service</span>
668
+ </label>
669
+ ```
670
+
671
+ | Class | Description |
672
+ |---|---|
673
+ | `.glass-checkbox` | Outer label |
674
+ | `.glass-checkbox__input` | Hidden checkbox input |
675
+ | `.glass-checkbox__box` | Visible box with checkmark SVG |
676
+ | `.glass-checkbox__label` | Text label |
677
+
678
+ ---
679
+
680
+ ### 3.20 Radio Button
681
+
682
+ Animated radio button with dot.
683
+
684
+ ```html
685
+ <label class="glass-radio">
686
+ <input class="glass-radio__input" type="radio" name="group" checked>
687
+ <span class="glass-radio__circle">
688
+ <span class="glass-radio__dot"></span>
689
+ </span>
690
+ <span class="glass-radio__label">Option A</span>
691
+ </label>
692
+
693
+ <label class="glass-radio">
694
+ <input class="glass-radio__input" type="radio" name="group">
695
+ <span class="glass-radio__circle">
696
+ <span class="glass-radio__dot"></span>
697
+ </span>
698
+ <span class="glass-radio__label">Option B</span>
699
+ </label>
700
+ ```
701
+
702
+ | Class | Description |
703
+ |---|---|
704
+ | `.glass-radio` | Outer label |
705
+ | `.glass-radio__input` | Hidden radio input |
706
+ | `.glass-radio__circle` | Visible circle |
707
+ | `.glass-radio__dot` | Inner dot (visible on :checked) |
708
+ | `.glass-radio__label` | Text label |
709
+
710
+ **Important:** Radio buttons in the same group need the same `name` attribute value.
711
+
712
+ ---
713
+
714
+ ### 3.21 Range Slider
715
+
716
+ Slider with gradient thumb. Used in a group with header and value display.
717
+
718
+ ```html
719
+ <div class="glass-range-group">
720
+ <div class="glass-range-header">
721
+ <label class="glass-label">Image Quality</label>
722
+ <span class="glass-range-value" id="range-val">75%</span>
723
+ </div>
724
+ <input class="glass-range" type="range" min="0" max="100" value="75"
725
+ oninput="document.getElementById('range-val').textContent = this.value + '%'">
726
+ </div>
727
+ ```
728
+
729
+ | Class | Description |
730
+ |---|---|
731
+ | `.glass-range-group` | Wrapper |
732
+ | `.glass-range-header` | Flex container for label + value |
733
+ | `.glass-range-value` | Value display (right) |
734
+ | `.glass-range` | The actual slider |
735
+
736
+ ---
737
+
738
+ ### 3.22 Progress Bar
739
+
740
+ Progress bar with optional shimmer effect.
741
+
742
+ ```html
743
+ <div class="glass-progress">
744
+ <div class="glass-progress__header">
745
+ <span class="glass-progress__label">Upload</span>
746
+ <span class="glass-progress__value">68%</span>
747
+ </div>
748
+ <div class="glass-progress__track">
749
+ <div class="glass-progress__fill" style="width: 68%"></div>
750
+ </div>
751
+ </div>
752
+ ```
753
+
754
+ | Class | Description |
755
+ |---|---|
756
+ | `.glass-progress` | Base container |
757
+ | `.glass-progress--sm` | Narrow track (4px) |
758
+ | `.glass-progress--lg` | Wide track (12px) |
759
+ | `.glass-progress--success` | Green bar |
760
+ | `.glass-progress--error` | Red bar |
761
+ | `.glass-progress__header` | Flex container for label + value |
762
+ | `.glass-progress__label` | Label (left) |
763
+ | `.glass-progress__value` | Percentage value (right) |
764
+ | `.glass-progress__track` | Background track |
765
+ | `.glass-progress__fill` | Filled area (width via `style="width: X%"`) |
766
+
767
+ **Important:** Progress width is controlled via inline `style="width: X%"` on `.glass-progress__fill`.
768
+
769
+ ---
770
+
771
+ ### 3.23 Accordion
772
+
773
+ Collapsible content sections. Controlled via `is-open` on items.
774
+
775
+ ```html
776
+ <div class="glass-accordion">
777
+ <div class="glass-accordion__item is-open">
778
+ <button class="glass-accordion__trigger" onclick="this.parentElement.classList.toggle('is-open')">
779
+ <span>Question one?</span>
780
+ <span class="glass-accordion__trigger-icon">
781
+ <svg viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg>
782
+ </span>
783
+ </button>
784
+ <div class="glass-accordion__content">
785
+ <div class="glass-accordion__body">
786
+ The answer to question one.
787
+ </div>
788
+ </div>
789
+ </div>
790
+
791
+ <div class="glass-accordion__item">
792
+ <button class="glass-accordion__trigger" onclick="this.parentElement.classList.toggle('is-open')">
793
+ <span>Question two?</span>
794
+ <span class="glass-accordion__trigger-icon">
795
+ <svg viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg>
796
+ </span>
797
+ </button>
798
+ <div class="glass-accordion__content">
799
+ <div class="glass-accordion__body">
800
+ The answer to question two.
801
+ </div>
802
+ </div>
803
+ </div>
804
+ </div>
805
+ ```
806
+
807
+ | Class | Description |
808
+ |---|---|
809
+ | `.glass-accordion` | Container |
810
+ | `.glass-accordion__item` | Individual item |
811
+ | `.glass-accordion__item.is-open` | Expanded item |
812
+ | `.glass-accordion__trigger` | Clickable header button |
813
+ | `.glass-accordion__trigger-icon` | Chevron icon (rotates on open) |
814
+ | `.glass-accordion__content` | Wrapper for animated height |
815
+ | `.glass-accordion__body` | Actual content |
816
+
817
+ ---
818
+
819
+ ### 3.24 List
820
+
821
+ iOS-style grouped settings list. Items can carry a leading icon, a title with optional subtitle, and a trailing element (chevron, value, button). Dividers between items are drawn automatically via `::after` &mdash; **never add divider markup manually**.
822
+
823
+ ```html
824
+ <!-- Settings-style list with icons + subtitles + trailing -->
825
+ <ul class="glass-list">
826
+ <li class="glass-list__item glass-list__item--interactive">
827
+ <span class="glass-list__leading">
828
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
829
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
830
+ <polyline points="7 10 12 15 17 10"/>
831
+ <line x1="12" y1="15" x2="12" y2="3"/>
832
+ </svg>
833
+ </span>
834
+ <div class="glass-list__content">
835
+ <div class="glass-list__title">iOS 26.4 Update</div>
836
+ <div class="glass-list__subtitle">2.1 GB · Available now</div>
837
+ </div>
838
+ <div class="glass-list__trailing">
839
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
840
+ <polyline points="9 18 15 12 9 6"/>
841
+ </svg>
842
+ </div>
843
+ </li>
844
+
845
+ <li class="glass-list__item glass-list__item--interactive">
846
+ <span class="glass-list__leading">
847
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
848
+ <rect x="2" y="5" width="20" height="14" rx="2"/>
849
+ <line x1="2" y1="10" x2="22" y2="10"/>
850
+ </svg>
851
+ </span>
852
+ <div class="glass-list__content">
853
+ <div class="glass-list__title">Apple One</div>
854
+ <div class="glass-list__subtitle">Family — renews Apr 28</div>
855
+ </div>
856
+ <div class="glass-list__trailing">$22.95</div>
857
+ </li>
858
+
859
+ <li class="glass-list__item glass-list__item--center glass-list__item--interactive">
860
+ View all subscriptions
861
+ </li>
862
+ </ul>
863
+ ```
864
+
865
+ ```html
866
+ <!-- Compact menu (centered text only, no icons) -->
867
+ <ul class="glass-list">
868
+ <li class="glass-list__item glass-list__item--center glass-list__item--interactive">Share</li>
869
+ <li class="glass-list__item glass-list__item--center glass-list__item--interactive">Duplicate</li>
870
+ <li class="glass-list__item glass-list__item--center glass-list__item--interactive">Delete</li>
871
+ </ul>
872
+ ```
873
+
874
+ | Class | Description |
875
+ |---|---|
876
+ | `.glass-list` | Grouped surface container |
877
+ | `.glass-list--flush` | Edge-to-edge variant (no side margin / radius). Assumes parent has `--gl-space-lg` horizontal padding. |
878
+ | `.glass-list--bare` | Strips background, border & shadow &mdash; for embedding inside `.glass-popover` or `.glass-card`. |
879
+ | `.glass-list__item` | List row (use `<li>`, `<a>`, or `<button>`) |
880
+ | `.glass-list__item--interactive` | Adds hover / focus / active states |
881
+ | `.glass-list__item--center` | Centered single-text variant with ellipsis truncation |
882
+ | `.glass-list__leading` | Leading slot (28×28, holds an icon SVG) |
883
+ | `.glass-list__content` | Flexible middle slot — takes remaining width, enables truncation |
884
+ | `.glass-list__title` | Primary text (medium weight, ellipsis) |
885
+ | `.glass-list__subtitle` | Secondary text (small, muted, ellipsis) |
886
+ | `.glass-list__trailing` | Trailing slot — chevron, value, button, badge |
887
+
888
+ **Notes:**
889
+ - Dividers are auto-rendered via `::after`. The last item never has a divider.
890
+ - Items **with** a `__leading` slot get an icon-aligned divider inset; items **without** a leading slot get a standard left/right padding inset (handled via `:has()`).
891
+ - SVG icon convention: `24px` for leading, `18px` for trailing, `stroke: currentColor`, `stroke-width: 2`.
892
+ - Use `<ul>` + `<li>` for semantic lists. For interactive rows wrap in `<a>` or `<button>` instead of `<li>` if a single-row list is needed.
893
+
894
+ ---
895
+
896
+ ### 3.25 Popover
897
+
898
+ Anchored dropdown / menu container. Wrap a trigger button and a `.glass-popover` inside a `.glass-popover-anchor`. Visibility is controlled via `.is-open` &mdash; toggling requires a tiny bit of JavaScript.
899
+
900
+ ```html
901
+ <div class="glass-popover-anchor">
902
+ <button class="glass-btn glass-btn--secondary glass-btn--auto"
903
+ onclick="gkTogglePopover(this, event)">
904
+ Open menu
905
+ </button>
906
+ <div class="glass-popover">
907
+ <ul class="glass-list glass-list--bare">
908
+ <li class="glass-list__item glass-list__item--interactive">
909
+ <span class="glass-list__leading">
910
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
911
+ <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
912
+ <polyline points="16 6 12 2 8 6"/>
913
+ <line x1="12" y1="2" x2="12" y2="15"/>
914
+ </svg>
915
+ </span>
916
+ <div class="glass-list__content"><div class="glass-list__title">Share</div></div>
917
+ </li>
918
+ <li class="glass-list__item glass-list__item--interactive">
919
+ <div class="glass-list__content"><div class="glass-list__title">Duplicate</div></div>
920
+ </li>
921
+ <li class="glass-list__item glass-list__item--interactive">
922
+ <div class="glass-list__content"><div class="glass-list__title">Delete</div></div>
923
+ </li>
924
+ </ul>
925
+ </div>
926
+ </div>
927
+
928
+ <script>
929
+ // ⚠️ Do NOT name this function `togglePopover` — it collides with the
930
+ // native HTMLElement.togglePopover() method from the HTML Popover API.
931
+ function gkTogglePopover(btn, e) {
932
+ const popover = btn.nextElementSibling;
933
+ const wasOpen = popover.classList.contains('is-open');
934
+ document.querySelectorAll('.glass-popover.is-open')
935
+ .forEach(p => p.classList.remove('is-open'));
936
+ if (!wasOpen) popover.classList.add('is-open');
937
+ if (e) e.stopPropagation();
938
+ }
939
+ document.addEventListener('click', e => {
940
+ if (!e.target.closest('.glass-popover-anchor')) {
941
+ document.querySelectorAll('.glass-popover.is-open')
942
+ .forEach(p => p.classList.remove('is-open'));
943
+ }
944
+ });
945
+ </script>
946
+ ```
947
+
948
+ | Class | Description |
949
+ |---|---|
950
+ | `.glass-popover-anchor` | Positioning context — wraps trigger + popover |
951
+ | `.glass-popover` | Floating glass surface, hidden until `.is-open` |
952
+ | `.glass-popover.is-open` | Visible state — fade + scale animation |
953
+ | `.glass-popover--top` | Opens upward (above the trigger) |
954
+ | `.glass-popover--start` | Aligns left edge with trigger |
955
+ | `.glass-popover--end` | Aligns right edge with trigger |
956
+
957
+ **Note:** name your toggle function anything except `togglePopover` &mdash; that name collides with the native `HTMLElement.togglePopover()` method (HTML Popover API) and inline `onclick` handlers will throw `NotSupportedError`. Use a prefix like `gkTogglePopover` or `myToggle`.
958
+
959
+ ---
960
+
961
+ ## 4. Utility Classes
962
+
963
+ ### Stack (Vertical)
964
+
965
+ Flexbox column with gap.
966
+
967
+ ```html
968
+ <div class="gl-stack gl-stack--md">
969
+ <div>Item 1</div>
970
+ <div>Item 2</div>
971
+ </div>
972
+ ```
973
+
974
+ | Class | Gap |
975
+ |---|---|
976
+ | `.gl-stack` | Default |
977
+ | `.gl-stack--2xs` | 4px |
978
+ | `.gl-stack--xs` | 8px |
979
+ | `.gl-stack--sm` | 12px |
980
+ | `.gl-stack--md` | 16px |
981
+ | `.gl-stack--lg` | 20px |
982
+ | `.gl-stack--xl` | 24px |
983
+
984
+ ### Row (Horizontal)
985
+
986
+ Flexbox row with gap.
987
+
988
+ ```html
989
+ <div class="gl-row gl-row--sm">
990
+ <span class="glass-badge">Tag 1</span>
991
+ <span class="glass-badge">Tag 2</span>
992
+ </div>
993
+ ```
994
+
995
+ | Class | Gap |
996
+ |---|---|
997
+ | `.gl-row` | Default |
998
+ | `.gl-row--xs` | 8px |
999
+ | `.gl-row--sm` | 12px |
1000
+ | `.gl-row--md` | 16px |
1001
+
1002
+ ### Margin
1003
+
1004
+ | Class | Value |
1005
+ |---|---|
1006
+ | `.gl-mt-sm` | margin-top: 12px |
1007
+ | `.gl-mt-md` | margin-top: 16px |
1008
+ | `.gl-mt-lg` | margin-top: 20px |
1009
+ | `.gl-mt-xl` | margin-top: 24px |
1010
+ | `.gl-mb-sm` | margin-bottom: 12px |
1011
+ | `.gl-mb-md` | margin-bottom: 16px |
1012
+ | `.gl-mb-lg` | margin-bottom: 20px |
1013
+ | `.gl-mb-xl` | margin-bottom: 24px |
1014
+
1015
+ ### Text
1016
+
1017
+ | Class | Description |
1018
+ |---|---|
1019
+ | `.gl-text-center` | text-align: center |
1020
+ | `.gl-text-muted` | Muted text color |
1021
+ | `.gl-text-sm` | Smaller font size |
1022
+
1023
+ ### Layout
1024
+
1025
+ | Class | Description |
1026
+ |---|---|
1027
+ | `.gl-px` | Horizontal padding |
1028
+ | `.gl-w-full` | width: 100% |
1029
+ | `.gl-flex-1` | flex: 1 |
1030
+
1031
+ ---
1032
+
1033
+ ## 5. State Classes Overview
1034
+
1035
+ | State Class | Used on | Description |
1036
+ |---|---|---|
1037
+ | `.is-active` | `.glass-modal-overlay`, `.glass-tab-bar__item` | Element is active/visible |
1038
+ | `.is-open` | `.glass-accordion__item`, `.glass-popover` | Accordion item expanded / popover visible |
1039
+ | `.is-visible` | `.glass-toast` | Toast is visible |
1040
+ | `:checked` | Toggle, Checkbox, Radio (on the input) | Native checked state |
1041
+ | `:focus` | Input, Textarea, Select, Range | Focus ring |
1042
+ | `:disabled` | `.glass-input` | Disabled input |
1043
+
1044
+ ---
1045
+
1046
+ ## 6. Composition Patterns
1047
+
1048
+ ### Login Screen
1049
+
1050
+ ```html
1051
+ <div class="glass-bg">
1052
+ <nav class="glass-nav">
1053
+ <button class="glass-pill">
1054
+ <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
1055
+ </button>
1056
+ <button class="glass-theme-toggle" onclick="toggleTheme()">
1057
+ <svg class="icon-moon" viewBox="0 0 24 24"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
1058
+ <svg class="icon-sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="5"/></svg>
1059
+ </button>
1060
+ </nav>
1061
+
1062
+ <h1 class="glass-title">Sign In</h1>
1063
+
1064
+ <div class="gl-stack gl-stack--md">
1065
+ <div class="glass-input-group">
1066
+ <label class="glass-label">Email</label>
1067
+ <input class="glass-input" type="email" placeholder="name@example.com">
1068
+ </div>
1069
+ <div class="glass-input-group">
1070
+ <label class="glass-label">Password</label>
1071
+ <input class="glass-input" type="password" placeholder="••••••••">
1072
+ </div>
1073
+ </div>
1074
+
1075
+ <div class="gl-stack gl-stack--sm gl-mt-lg">
1076
+ <button class="glass-btn glass-btn--primary">Log In</button>
1077
+ <button class="glass-btn glass-btn--tertiary">Forgot password?</button>
1078
+ </div>
1079
+ </div>
1080
+ ```
1081
+
1082
+ ### Dashboard with Cards
1083
+
1084
+ ```html
1085
+ <div class="glass-bg glass-bg--has-tab-bar">
1086
+ <nav class="glass-nav">
1087
+ <h1 class="glass-title">Dashboard</h1>
1088
+ <button class="glass-pill">
1089
+ <svg viewBox="0 0 24 24"><!-- Settings Icon --></svg>
1090
+ </button>
1091
+ </nav>
1092
+
1093
+ <div class="gl-stack gl-stack--md">
1094
+ <div class="glass-card glass-card--glow">
1095
+ <div class="glass-card__icon">
1096
+ <svg viewBox="0 0 64 64"><!-- Icon --></svg>
1097
+ </div>
1098
+ <p class="glass-card__text">Capture and upload documents.</p>
1099
+ </div>
1100
+
1101
+ <div class="glass-card glass-card--glow">
1102
+ <div class="glass-card__icon">
1103
+ <svg viewBox="0 0 64 64"><!-- Icon --></svg>
1104
+ </div>
1105
+ <p class="glass-card__text">Manage and archive contracts.</p>
1106
+ </div>
1107
+ </div>
1108
+
1109
+ <nav class="glass-tab-bar">
1110
+ <button class="glass-tab-bar__item is-active">
1111
+ <span class="glass-tab-bar__icon"><svg viewBox="0 0 24 24"><!-- Home --></svg></span>
1112
+ <span class="glass-tab-bar__label">Home</span>
1113
+ </button>
1114
+ <button class="glass-tab-bar__item">
1115
+ <span class="glass-tab-bar__icon"><svg viewBox="0 0 24 24"><!-- Docs --></svg></span>
1116
+ <span class="glass-tab-bar__label">Contracts</span>
1117
+ </button>
1118
+ <button class="glass-tab-bar__item">
1119
+ <span class="glass-tab-bar__icon"><svg viewBox="0 0 24 24"><!-- Profile --></svg></span>
1120
+ <span class="glass-tab-bar__label">Profile</span>
1121
+ </button>
1122
+ </nav>
1123
+ </div>
1124
+ ```
1125
+
1126
+ ### Form Page
1127
+
1128
+ ```html
1129
+ <div class="glass-bg">
1130
+ <nav class="glass-nav">
1131
+ <button class="glass-pill">
1132
+ <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
1133
+ </button>
1134
+ </nav>
1135
+
1136
+ <h1 class="glass-title">New Contract</h1>
1137
+
1138
+ <div class="gl-stack gl-stack--md">
1139
+ <div class="glass-input-group">
1140
+ <label class="glass-label">Contract Name</label>
1141
+ <input class="glass-input" type="text" placeholder="e.g. Rental Agreement">
1142
+ </div>
1143
+
1144
+ <div class="glass-input-group">
1145
+ <label class="glass-label">Category</label>
1146
+ <select class="glass-select">
1147
+ <option>Please select…</option>
1148
+ <option>Insurance</option>
1149
+ <option>Rental Agreement</option>
1150
+ <option>Employment Contract</option>
1151
+ </select>
1152
+ </div>
1153
+
1154
+ <div class="glass-input-group">
1155
+ <label class="glass-label">Notes</label>
1156
+ <textarea class="glass-textarea" placeholder="Optional notes…"></textarea>
1157
+ </div>
1158
+
1159
+ <label class="glass-toggle">
1160
+ <input class="glass-toggle__input" type="checkbox">
1161
+ <span class="glass-toggle__track"><span class="glass-toggle__thumb"></span></span>
1162
+ <span class="glass-toggle__label">Enable reminder</span>
1163
+ </label>
1164
+
1165
+ <hr class="glass-divider">
1166
+
1167
+ <button class="glass-btn glass-btn--primary">Save</button>
1168
+ <button class="glass-btn glass-btn--tertiary">Cancel</button>
1169
+ </div>
1170
+ </div>
1171
+ ```
1172
+
1173
+ ### Delete Confirmation (Modal)
1174
+
1175
+ ```html
1176
+ <div class="glass-modal-overlay is-active">
1177
+ <div class="glass-modal">
1178
+ <div class="glass-modal__header">
1179
+ <h2 class="glass-modal__title">Delete contract?</h2>
1180
+ </div>
1181
+ <div class="glass-modal__body">
1182
+ <p>Do you want to permanently delete this contract? This action cannot be undone.</p>
1183
+ </div>
1184
+ <div class="glass-modal__footer">
1185
+ <button class="glass-modal__action" onclick="closeModal()">Cancel</button>
1186
+ <button class="glass-modal__action glass-modal__action--danger" onclick="deleteContract()">Delete</button>
1187
+ </div>
1188
+ </div>
1189
+ </div>
1190
+ ```
1191
+
1192
+ ### Settings Page
1193
+
1194
+ ```html
1195
+ <div class="glass-bg">
1196
+ <nav class="glass-nav">
1197
+ <button class="glass-pill">
1198
+ <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
1199
+ </button>
1200
+ </nav>
1201
+
1202
+ <h1 class="glass-title">Settings</h1>
1203
+
1204
+ <div class="gl-stack gl-stack--md">
1205
+ <label class="glass-toggle">
1206
+ <input class="glass-toggle__input" type="checkbox" checked>
1207
+ <span class="glass-toggle__track"><span class="glass-toggle__thumb"></span></span>
1208
+ <span class="glass-toggle__label">Push Notifications</span>
1209
+ </label>
1210
+
1211
+ <hr class="glass-divider">
1212
+
1213
+ <label class="glass-toggle">
1214
+ <input class="glass-toggle__input" type="checkbox">
1215
+ <span class="glass-toggle__track"><span class="glass-toggle__thumb"></span></span>
1216
+ <span class="glass-toggle__label">Dark Mode</span>
1217
+ </label>
1218
+
1219
+ <hr class="glass-divider">
1220
+
1221
+ <div class="glass-range-group">
1222
+ <div class="glass-range-header">
1223
+ <label class="glass-label">Font Size</label>
1224
+ <span class="glass-range-value">100%</span>
1225
+ </div>
1226
+ <input class="glass-range" type="range" min="80" max="150" value="100">
1227
+ </div>
1228
+
1229
+ <hr class="glass-divider">
1230
+
1231
+ <div class="glass-accordion">
1232
+ <div class="glass-accordion__item">
1233
+ <button class="glass-accordion__trigger" onclick="this.parentElement.classList.toggle('is-open')">
1234
+ <span>Advanced Settings</span>
1235
+ <span class="glass-accordion__trigger-icon">
1236
+ <svg viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg>
1237
+ </span>
1238
+ </button>
1239
+ <div class="glass-accordion__content">
1240
+ <div class="glass-accordion__body">
1241
+ Advanced options go here…
1242
+ </div>
1243
+ </div>
1244
+ </div>
1245
+ </div>
1246
+ </div>
1247
+ </div>
1248
+ ```
1249
+
1250
+ ### iOS-style Settings Screen (List + Popover)
1251
+
1252
+ A grouped settings screen using `glass-list` for the rows and `glass-popover` for an inline action menu. Reproduces the layout of native iOS Settings screens.
1253
+
1254
+ ```html
1255
+ <div class="glass-bg">
1256
+ <nav class="glass-nav">
1257
+ <button class="glass-pill">
1258
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1259
+ <polyline points="15 18 9 12 15 6"/>
1260
+ </svg>
1261
+ </button>
1262
+ <h1 class="glass-title">Settings</h1>
1263
+
1264
+ <!-- Inline action menu (popover) -->
1265
+ <div class="glass-popover-anchor">
1266
+ <button class="glass-pill" onclick="gkTogglePopover(this, event)" aria-label="More">
1267
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1268
+ <circle cx="12" cy="5" r="1.5" fill="currentColor"/>
1269
+ <circle cx="12" cy="12" r="1.5" fill="currentColor"/>
1270
+ <circle cx="12" cy="19" r="1.5" fill="currentColor"/>
1271
+ </svg>
1272
+ </button>
1273
+ <div class="glass-popover glass-popover--end">
1274
+ <ul class="glass-list glass-list--bare">
1275
+ <li class="glass-list__item glass-list__item--interactive">
1276
+ <div class="glass-list__content"><div class="glass-list__title">Edit profile</div></div>
1277
+ </li>
1278
+ <li class="glass-list__item glass-list__item--interactive">
1279
+ <div class="glass-list__content"><div class="glass-list__title">Sign out</div></div>
1280
+ </li>
1281
+ </ul>
1282
+ </div>
1283
+ </div>
1284
+ </nav>
1285
+
1286
+ <!-- Account section -->
1287
+ <p class="gl-text-muted gl-text-sm gl-mb-sm">ACCOUNT</p>
1288
+ <ul class="glass-list gl-mb-lg">
1289
+ <li class="glass-list__item glass-list__item--interactive">
1290
+ <span class="glass-list__leading">
1291
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1292
+ <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
1293
+ <circle cx="12" cy="7" r="4"/>
1294
+ </svg>
1295
+ </span>
1296
+ <div class="glass-list__content">
1297
+ <div class="glass-list__title">Marcel Jungherz</div>
1298
+ <div class="glass-list__subtitle">marcel@jungherz.com</div>
1299
+ </div>
1300
+ <div class="glass-list__trailing">
1301
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1302
+ <polyline points="9 18 15 12 9 6"/>
1303
+ </svg>
1304
+ </div>
1305
+ </li>
1306
+ <li class="glass-list__item glass-list__item--interactive">
1307
+ <span class="glass-list__leading">
1308
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1309
+ <rect x="2" y="5" width="20" height="14" rx="2"/>
1310
+ <line x1="2" y1="10" x2="22" y2="10"/>
1311
+ </svg>
1312
+ </span>
1313
+ <div class="glass-list__content">
1314
+ <div class="glass-list__title">Subscriptions</div>
1315
+ </div>
1316
+ <div class="glass-list__trailing">
1317
+ $34.94
1318
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1319
+ <polyline points="9 18 15 12 9 6"/>
1320
+ </svg>
1321
+ </div>
1322
+ </li>
1323
+ </ul>
1324
+
1325
+ <!-- Notifications section -->
1326
+ <p class="gl-text-muted gl-text-sm gl-mb-sm">NOTIFICATIONS</p>
1327
+ <ul class="glass-list gl-mb-lg">
1328
+ <li class="glass-list__item glass-list__item--interactive">
1329
+ <span class="glass-list__leading">
1330
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1331
+ <path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/>
1332
+ <path d="M13.73 21a2 2 0 0 1-3.46 0"/>
1333
+ </svg>
1334
+ </span>
1335
+ <div class="glass-list__content"><div class="glass-list__title">Push notifications</div></div>
1336
+ <div class="glass-list__trailing">On</div>
1337
+ </li>
1338
+ <li class="glass-list__item glass-list__item--interactive">
1339
+ <span class="glass-list__leading">
1340
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1341
+ <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
1342
+ <polyline points="22 6 12 13 2 6"/>
1343
+ </svg>
1344
+ </span>
1345
+ <div class="glass-list__content"><div class="glass-list__title">Email digest</div></div>
1346
+ <div class="glass-list__trailing">Weekly</div>
1347
+ </li>
1348
+ <li class="glass-list__item glass-list__item--center glass-list__item--interactive">
1349
+ Reset to defaults
1350
+ </li>
1351
+ </ul>
1352
+ </div>
1353
+ ```
1354
+
1355
+ Key points in this composition:
1356
+
1357
+ - **Two grouped sections** — labeled by small uppercase muted text above each list, matching iOS settings.
1358
+ - **Auto-dividers** — no `<hr>` between rows; the `::after` pseudo-element handles them.
1359
+ - **Mixed trailing types** — chevron, value text, value + chevron, all in the same list.
1360
+ - **Centered destructive action** — last item uses `--center` for a "Reset to defaults" style row, gets a full-width divider above (no leading icon → standard padding inset).
1361
+ - **Popover in nav** — `glass-popover--end` aligns the menu to the right edge of the trigger so it doesn't overflow the viewport.
1362
+ - **Bare list inside popover** — `glass-list--bare` strips the inner glass surface so the popover stays the only glass layer.
1363
+
1364
+ ---
1365
+
1366
+ ### Progress + Toast
1367
+
1368
+ ```html
1369
+ <!-- Progress -->
1370
+ <div class="glass-progress glass-progress--success">
1371
+ <div class="glass-progress__header">
1372
+ <span class="glass-progress__label">Upload</span>
1373
+ <span class="glass-progress__value">100%</span>
1374
+ </div>
1375
+ <div class="glass-progress__track">
1376
+ <div class="glass-progress__fill" style="width: 100%"></div>
1377
+ </div>
1378
+ </div>
1379
+
1380
+ <!-- Toast (shown via JS) -->
1381
+ <div class="glass-toast glass-toast--success is-visible">
1382
+ <svg class="glass-toast__icon" viewBox="0 0 24 24">
1383
+ <polyline points="20 6 9 17 4 12"/>
1384
+ </svg>
1385
+ <span class="glass-toast__text">Upload successful!</span>
1386
+ </div>
1387
+ ```
1388
+
1389
+ ---
1390
+
1391
+ ## 7. Rules & Common Mistakes
1392
+
1393
+ ### ✅ Always follow
1394
+
1395
+ 1. **`glass-bg` as outermost container** – Without the background wrapper, the aurora background is missing and glass effects won't render correctly.
1396
+ 2. **`glass-bg--has-tab-bar`** – When a tab bar is present, this modifier must be set on `glass-bg`, otherwise the tab bar covers the bottom content.
1397
+ 3. **Buttons are full-width** – `glass-btn` has `width: 100%`. Always add `glass-btn--auto` for inline buttons.
1398
+ 4. **Wrap inputs in `glass-input-group`** – For correct label/hint spacing.
1399
+ 5. **Place state classes correctly:**
1400
+ - `is-active` → on `.glass-modal-overlay` (not on `.glass-modal`)
1401
+ - `is-active` → on `.glass-tab-bar__item`
1402
+ - `is-open` → on `.glass-accordion__item`
1403
+ - `is-open` → on `.glass-popover` (not on the trigger or anchor)
1404
+ - `is-visible` → on `.glass-toast`
1405
+ 6. **SVG icons** – GlassKit uses inline SVGs (stroke-based, not fill). Typical attributes: `viewBox="0 0 24 24"`, stroke via `currentColor`.
1406
+ 7. **`data-theme`** – Always set on `<html>`, never on `<body>` or deeper elements.
1407
+ 8. **List dividers are automatic** – Never add a `<hr>` or divider element between `.glass-list__item`s. The divider is rendered via `::after` and respects `:has(.glass-list__leading)` for the inset.
1408
+ 9. **Popover toggle naming** – Never name your popover toggle JS function `togglePopover`. It collides with the native `HTMLElement.togglePopover()` method. Use a prefix like `gkTogglePopover`.
1409
+
1410
+ ### ❌ Common Mistakes
1411
+
1412
+ | Mistake | Correction |
1413
+ |---|---|
1414
+ | `is-active` on `.glass-modal` instead of `.glass-modal-overlay` | Set `is-active` on the overlay |
1415
+ | `glass-btn` without variant (`--primary` etc.) | Always specify a variant |
1416
+ | Inputs without `glass-input-group` wrapper | Wrap in `glass-input-group` |
1417
+ | `glass-tab-bar` without `glass-bg--has-tab-bar` | Add modifier to the background container |
1418
+ | `data-theme` on `<body>` | Set on `<html>` |
1419
+ | Progress width via class instead of inline style | Use `style="width: X%"` on `.glass-progress__fill` |
1420
+ | Toggle without `__track > __thumb` nesting | Follow correct BEM hierarchy |
1421
+ | Manually adding `<hr>` or divider element between `.glass-list__item`s | Remove it — dividers are automatic via `::after` |
1422
+ | Putting `glass-list` inside `glass-popover` without `--bare` | Add `.glass-list--bare` to strip the double glass surface |
1423
+ | JS function named `togglePopover()` | Rename to `gkTogglePopover()` or similar to avoid native API clash |
1424
+ | Putting `.is-open` on the trigger button instead of `.glass-popover` | The state class belongs on the popover element |
1425
+
1426
+ ---
1427
+
1428
+ ## 8. Quick Class Reference
1429
+
1430
+ | Component | Base Class | Modifiers / States |
1431
+ |---|---|---|
1432
+ | Background | `.glass-bg` | `--has-tab-bar` |
1433
+ | Navigation | `.glass-nav` | – |
1434
+ | Pill Button | `.glass-pill` | – |
1435
+ | Theme Toggle | `.glass-theme-toggle` | – |
1436
+ | Title | `.glass-title` | – |
1437
+ | Card | `.glass-card` | `--glow` |
1438
+ | Button | `.glass-btn` | `--primary`, `--secondary`, `--tertiary`, `--sm`, `--lg`, `--auto` |
1439
+ | Badge | `.glass-badge` | `--primary`, `--success`, `--error` |
1440
+ | Avatar | `.glass-avatar` | `--sm`, `--lg` |
1441
+ | Divider | `.glass-divider` | – |
1442
+ | Status | `.glass-status` | – |
1443
+ | Input | `.glass-input` | `--error`, `:disabled` |
1444
+ | Input Group | `.glass-input-group` | – |
1445
+ | Label | `.glass-label` | – |
1446
+ | Hint | `.glass-hint` | `--error` |
1447
+ | Textarea | `.glass-textarea` | – |
1448
+ | Select | `.glass-select` | – |
1449
+ | Search | `.glass-search` | – |
1450
+ | Toggle | `.glass-toggle` | `:checked` |
1451
+ | Checkbox | `.glass-checkbox` | `:checked` |
1452
+ | Radio | `.glass-radio` | `:checked` |
1453
+ | Range | `.glass-range` | – |
1454
+ | Progress | `.glass-progress` | `--sm`, `--lg`, `--success`, `--error` |
1455
+ | Modal | `.glass-modal-overlay` | `.is-active` |
1456
+ | Toast | `.glass-toast` | `--success`, `--error`, `--warning`, `.is-visible` |
1457
+ | Tab Bar | `.glass-tab-bar` | `.is-active` on items |
1458
+ | Accordion | `.glass-accordion` | `.is-open` on items |
1459
+ | List | `.glass-list` | `--flush`, `--bare`, `__item--interactive`, `__item--center` |
1460
+ | Popover | `.glass-popover` | `--top`, `--start`, `--end`, `.is-open` |
1461
+
1462
+ ---
1463
+
1464
+ ## 9. Web Components / Shadow DOM
1465
+
1466
+ GlassKit ships a Constructable Stylesheet for Shadow DOM usage:
1467
+
1468
+ ```js
1469
+ import { glassSheet } from '@jungherz-de/glasskit/glasskit-styles.js';
1470
+
1471
+ class MyCard extends HTMLElement {
1472
+ constructor() {
1473
+ super();
1474
+ const shadow = this.attachShadow({ mode: 'open' });
1475
+ shadow.adoptedStyleSheets = [glassSheet];
1476
+ shadow.innerHTML = `
1477
+ <div class="glass-card glass-card--glow">
1478
+ <p class="glass-card__text"><slot></slot></p>
1479
+ </div>
1480
+ `;
1481
+ }
1482
+ }
1483
+ customElements.define('my-card', MyCard);
1484
+ ```
1485
+
1486
+ | Export | Type | Description |
1487
+ |---|---|---|
1488
+ | `glassSheet` | `CSSStyleSheet` | Constructable Stylesheet for `adoptedStyleSheets` |
1489
+ | `css` | `string` | CSS as string (fallback) |
1490
+
1491
+ **Note:** CSS Custom Properties (`--gl-*`) penetrate the shadow boundary automatically. Theme switching works globally.
1492
+
1493
+ ---
1494
+
1495
+ ## 10. Custom Theming
1496
+
1497
+ Load custom brand colors via `theme-override.css` after the base library:
1498
+
1499
+ ```css
1500
+ :root {
1501
+ --gl-color-primary: #007AFF;
1502
+ --gl-color-primary-dark: #0055CC;
1503
+ --gl-color-primary-mid: #0066E0;
1504
+
1505
+ --gl-border-warm: rgba(0, 122, 255, 0.35);
1506
+ --gl-border-focus: rgba(0, 122, 255, 0.60);
1507
+
1508
+ --gl-shadow-btn-primary: 0 6px 24px rgba(0, 100, 220, 0.35),
1509
+ 0 2px 8px rgba(0, 0, 0, 0.15);
1510
+ --gl-shadow-focus: 0 0 0 3px rgba(0, 122, 255, 0.3);
1511
+ }
1512
+ ```
1513
+
1514
+ Included theme templates in `theme-override.css`:
1515
+ - 🔵 Ocean Blue
1516
+ - 🟢 Emerald Green
1517
+ - 🌹 Rose
1518
+ - 🎨 Custom (empty, ready to fill)