@jungherz-de/glasskit-elements 1.19.2 → 1.20.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/CHANGELOG.md +27 -0
- package/README.md +40 -27
- package/SKILL.md +105 -23
- package/dist/components/base.js +145 -10
- package/dist/components/glk-accordion-item.js +20 -5
- package/dist/components/glk-button.js +69 -2
- package/dist/components/glk-calendar.js +3 -0
- package/dist/components/glk-checkbox.js +12 -2
- package/dist/components/glk-input.js +25 -4
- package/dist/components/glk-modal.js +99 -21
- package/dist/components/glk-pill.js +14 -1
- package/dist/components/glk-popover.js +21 -3
- package/dist/components/glk-radio.js +26 -2
- package/dist/components/glk-range.js +3 -1
- package/dist/components/glk-search.js +14 -1
- package/dist/components/glk-segmented.js +4 -0
- package/dist/components/glk-select.js +8 -2
- package/dist/components/glk-textarea.js +8 -2
- package/dist/components/glk-toggle.js +18 -11
- package/dist/glasskit-elements.esm.js +487 -65
- package/dist/glasskit-elements.js +487 -65
- package/dist/glasskit-elements.min.js +1 -1
- package/package.json +3 -3
- package/src/base.js +144 -9
- package/src/components/buttons/glk-button.js +69 -2
- package/src/components/containers/glk-accordion-item.js +20 -5
- package/src/components/feedback/glk-modal.js +99 -21
- package/src/components/feedback/glk-popover.js +21 -3
- package/src/components/forms/glk-calendar.js +3 -0
- package/src/components/forms/glk-checkbox.js +12 -2
- package/src/components/forms/glk-input.js +25 -4
- package/src/components/forms/glk-radio.js +26 -2
- package/src/components/forms/glk-range.js +3 -1
- package/src/components/forms/glk-search.js +14 -1
- package/src/components/forms/glk-segmented.js +4 -0
- package/src/components/forms/glk-select.js +8 -2
- package/src/components/forms/glk-textarea.js +8 -2
- package/src/components/forms/glk-toggle.js +18 -11
- package/src/components/navigation/glk-pill.js +14 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
var GlassKitElements = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// GlassKit v1.
|
|
4
|
+
// GlassKit v1.20.0 – Constructable Stylesheet
|
|
5
5
|
// Auto-generated by build-styles-js.mjs – do not edit manually.
|
|
6
6
|
|
|
7
7
|
// The [data-theme] blocks that declare --gl-* …
|
|
8
|
-
const tokensCss = ":root,[data-theme=dark]{color-scheme:dark;--gl-color-primary:#f5a623;--gl-color-primary-dark:#d4692a;--gl-color-primary-mid:color-mix(in srgb, var(--gl-color-primary) 32%, var(--gl-color-primary-dark));--gl-color-bg-dark:#0e2530;--gl-color-bg-mid:#1a3d4e;--gl-color-bg-light:#1b3e50;--gl-color-text:#ffffff;--gl-color-text-muted:rgba(255, 255, 255, 0.60);--gl-color-text-on-light:#1a3a4a;--gl-color-text-heading:#ffffff;--gl-color-success:#34c759;--gl-color-error:#ff3b30;--gl-color-warning:#ffcc00;--gl-color-success-dark:#2da44e;--gl-color-error-dark:#d63027;--gl-color-on-primary:#ffffff;--gl-color-on-success:#ffffff;--gl-color-on-error:#ffffff;--gl-color-primary-on-surface:color-mix(in srgb, var(--gl-color-primary) 50%, #ffffff);--gl-color-success-on-surface:color-mix(in srgb, var(--gl-color-success) 62%, #ffffff);--gl-color-error-on-surface:color-mix(in srgb, var(--gl-color-error) 50%, #ffffff);--gl-color-warning-on-surface:color-mix(in srgb, var(--gl-color-warning) 80%, #ffffff);--gl-state-scrim:rgba(0, 0, 0, 0.30);--gl-color-primary-surface:color-mix(in srgb, var(--gl-color-primary) 25%, transparent);--gl-color-primary-border:var(--gl-border-warm);--gl-color-success-surface:color-mix(in srgb, var(--gl-color-success) 15%, transparent);--gl-color-success-border:color-mix(in srgb, var(--gl-color-success) 30%, transparent);--gl-color-error-surface:color-mix(in srgb, var(--gl-color-error) 15%, transparent);--gl-color-error-border:color-mix(in srgb, var(--gl-color-error) 30%, transparent);--gl-color-warning-surface:color-mix(in srgb, var(--gl-color-warning) 15%, transparent);--gl-color-warning-border:color-mix(in srgb, var(--gl-color-warning) 30%, transparent);--gl-surface-1:rgba(255, 255, 255, 0.08);--gl-surface-2:rgba(255, 255, 255, 0.10);--gl-surface-3:rgba(255, 255, 255, 0.14);--gl-surface-4:rgba(255, 255, 255, 0.16);--gl-surface-5:rgba(255, 255, 255, 0.22);--gl-surface-milk:rgba(255, 255, 255, 0.55);--gl-surface-milk-strong:rgba(255, 255, 255, 0.75);--gl-surface-overlay:rgba(0, 0, 0, 0.50);--gl-card-glow-top:rgba(255, 255, 255, 0.32);--gl-card-glow-mid:rgba(255, 255, 255, 0.22);--gl-card-glow-low:rgba(255, 255, 255, 0.14);--gl-card-glow-bottom:rgba(255, 255, 255, 0.08);--gl-card-icon-color:rgba(255, 255, 255, 0.8);--gl-card-text-color:rgba(255, 255, 255, 0.7);--gl-border-subtle:rgba(255, 255, 255, 0.18);--gl-border-medium:rgba(255, 255, 255, 0.30);--gl-border-strong:rgba(255, 255, 255, 0.40);--gl-border-milk:rgba(255, 255, 255, 0.60);--gl-border-warm:color-mix(in srgb, color-mix(in srgb, var(--gl-color-primary) 68%, #ffffff) 35%, transparent);--gl-border-focus:color-mix(in srgb, var(--gl-color-primary) 60%, transparent);--gl-icon-default:rgba(255, 255, 255, 0.6);--gl-icon-muted:rgba(255, 255, 255, 0.45);--gl-icon-strong:rgba(255, 255, 255, 0.8);--gl-icon-on-primary:var(--gl-color-on-primary, #ffffff);--gl-icon-on-secondary:#1a3a4a;--gl-icon-on-tertiary:rgba(255, 255, 255, 0.6);--gl-blur:24px;--gl-blur-light:16px;--gl-blur-soft:12px;--gl-blur-heavy:40px;--gl-radius-pill:50%;--gl-radius-full:9999px;--gl-radius-card:24px;--gl-radius-btn:16px;--gl-radius-input:14px;--gl-radius-sm:12px;--gl-radius-xs:8px;--gl-shadow-card:0 8px 32px rgba(0, 0, 0, 0.18);--gl-shadow-btn:0 4px 16px rgba(0, 0, 0, 0.12);--gl-shadow-btn-primary:0 6px 24px color-mix(in srgb, var(--gl-color-primary-mid) 35%, transparent),0 2px 8px rgba(0, 0, 0, 0.15);--gl-shadow-glow:0 2px 12px rgba(255, 255, 255, 0.08),0 4px 16px rgba(0, 0, 0, 0.15);--gl-shadow-modal:0 24px 80px rgba(0, 0, 0, 0.4),0 8px 32px rgba(0, 0, 0, 0.2);--gl-shadow-toast:0 8px 32px rgba(0, 0, 0, 0.25);--gl-shadow-focus:0 0 0 3px color-mix(in srgb, var(--gl-color-primary) 30%, transparent);--gl-inset-subtle:inset 0 1px 1px rgba(255, 255, 255, 0.10);--gl-inset-medium:inset 0 1px 1px rgba(255, 255, 255, 0.15);--gl-inset-strong:inset 0 1px 2px rgba(255, 255, 255, 0.25);--gl-inset-milk:inset 0 1px 2px rgba(255, 255, 255, 0.40);--gl-bg-aurora-1:rgba(60, 160, 160, 0.25);--gl-bg-aurora-2:rgba(200, 140, 60, 0.12);--gl-bg-aurora-3:rgba(80, 180, 200, 0.18);--gl-bg-light-streak-1:rgba(90, 210, 200, 0.14);--gl-bg-light-streak-2:rgba(110, 200, 190, 0.10);--gl-bg-warm-glow:rgba(220, 160, 70, 0.10);--gl-space-2xs:4px;--gl-space-xs:8px;--gl-space-sm:12px;--gl-space-md:16px;--gl-space-lg:20px;--gl-space-xl:24px;--gl-space-2xl:32px;--gl-space-3xl:40px;--gl-space-4xl:56px;--gl-font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',Roboto,Helvetica,Arial,sans-serif;--gl-font-size-xs:13px;--gl-font-size-sm:14px;--gl-font-size-base:15px;--gl-font-size-btn:16px;--gl-font-size-lg:18px;--gl-font-size-title:24px;--gl-font-size-modal:20px;--gl-font-weight-normal:400;--gl-font-weight-medium:500;--gl-font-weight-semibold:600;--gl-transition:all 0.25s ease;--gl-transition-fast:all 0.15s ease;--gl-transition-modal:all 0.3s cubic-bezier(0.4, 0, 0.2, 1);--gl-tab-bar-height:82px;--gl-tab-bar-floating-bottom:16px;--gl-tab-bar-floating-gap:var(--gl-space-sm);--gl-tab-bar-floating-padding:6px 10px;--gl-tab-bar-floating-radius:var(--gl-radius-full);--gl-tab-bar-accessory-size:56px;--gl-tab-bar-spotlight-color:var(--gl-color-primary);--gl-placeholder:rgba(255, 255, 255, 0.35);--gl-accordion-body-color:var(--gl-color-text-muted);--gl-toggle-thumb-bg:linear-gradient(to bottom,\n rgba(255,255,255,0.9) 0%,\n rgba(255,255,255,0.7) 100%);--gl-range-track-bg:var(--gl-surface-2);--gl-range-track-border:var(--gl-border-subtle)}[data-theme=light]{color-scheme:light;--gl-color-primary:#e8852d;--gl-color-primary-dark:#c96a1e;--gl-color-primary-mid:color-mix(in srgb, var(--gl-color-primary) 52%, var(--gl-color-primary-dark));--gl-color-bg-dark:#e8ecf1;--gl-color-bg-mid:#f0f4f8;--gl-color-bg-light:#f5f7fa;--gl-color-text:#1a2a36;--gl-color-text-muted:rgba(26, 42, 54, 0.55);--gl-color-text-on-light:#1a3a4a;--gl-color-text-heading:#0f1f2a;--gl-color-success:#28a745;--gl-color-error:#dc3545;--gl-color-warning:#e6a800;--gl-color-success-dark:#1e7e34;--gl-color-error-dark:#b02a37;--gl-color-on-primary:#ffffff;--gl-color-on-success:#ffffff;--gl-color-on-error:#ffffff;--gl-color-primary-on-surface:color-mix(in srgb, var(--gl-color-primary) 60%, #000000);--gl-color-success-on-surface:color-mix(in srgb, var(--gl-color-success) 68%, #000000);--gl-color-error-on-surface:color-mix(in srgb, var(--gl-color-error) 82%, #000000);--gl-color-warning-on-surface:color-mix(in srgb, var(--gl-color-warning) 56%, #000000);--gl-state-scrim:rgba(255, 255, 255, 0.30);--gl-color-primary-surface:color-mix(in srgb, var(--gl-color-primary) 25%, transparent);--gl-color-primary-border:var(--gl-border-warm);--gl-color-success-surface:color-mix(in srgb, var(--gl-color-success) 15%, transparent);--gl-color-success-border:color-mix(in srgb, var(--gl-color-success) 30%, transparent);--gl-color-error-surface:color-mix(in srgb, var(--gl-color-error) 15%, transparent);--gl-color-error-border:color-mix(in srgb, var(--gl-color-error) 30%, transparent);--gl-color-warning-surface:color-mix(in srgb, var(--gl-color-warning) 15%, transparent);--gl-color-warning-border:color-mix(in srgb, var(--gl-color-warning) 30%, transparent);--gl-surface-1:rgba(255, 255, 255, 0.50);--gl-surface-2:rgba(255, 255, 255, 0.60);--gl-surface-3:rgba(255, 255, 255, 0.70);--gl-surface-4:rgba(255, 255, 255, 0.75);--gl-surface-5:rgba(255, 255, 255, 0.85);--gl-surface-milk:rgba(255, 255, 255, 0.85);--gl-surface-milk-strong:rgba(255, 255, 255, 0.92);--gl-surface-overlay:rgba(0, 0, 0, 0.25);--gl-card-glow-top:rgba(255, 255, 255, 0.90);--gl-card-glow-mid:rgba(255, 255, 255, 0.78);--gl-card-glow-low:rgba(255, 255, 255, 0.65);--gl-card-glow-bottom:rgba(255, 255, 255, 0.50);--gl-card-icon-color:rgba(26, 42, 54, 0.5);--gl-card-text-color:rgba(26, 42, 54, 0.6);--gl-border-subtle:rgba(0, 0, 0, 0.08);--gl-border-medium:rgba(0, 0, 0, 0.12);--gl-border-strong:rgba(0, 0, 0, 0.15);--gl-border-milk:rgba(0, 0, 0, 0.10);--gl-border-warm:color-mix(in srgb, var(--gl-color-primary) 30%, transparent);--gl-border-focus:color-mix(in srgb, var(--gl-color-primary) 50%, transparent);--gl-icon-default:rgba(26, 42, 54, 0.50);--gl-icon-muted:rgba(26, 42, 54, 0.35);--gl-icon-strong:rgba(26, 42, 54, 0.70);--gl-icon-on-primary:var(--gl-color-on-primary, #ffffff);--gl-icon-on-secondary:#1a3a4a;--gl-icon-on-tertiary:rgba(26, 42, 54, 0.50);--gl-shadow-card:0 4px 20px rgba(0, 0, 0, 0.06);--gl-shadow-btn:0 2px 10px rgba(0, 0, 0, 0.06);--gl-shadow-btn-primary:0 4px 16px color-mix(in srgb, var(--gl-color-primary) 25%, transparent),0 2px 6px rgba(0, 0, 0, 0.08);--gl-shadow-glow:0 2px 8px rgba(0, 0, 0, 0.05),0 4px 12px rgba(0, 0, 0, 0.04);--gl-shadow-modal:0 16px 48px rgba(0, 0, 0, 0.12),0 4px 16px rgba(0, 0, 0, 0.08);--gl-shadow-toast:0 4px 20px rgba(0, 0, 0, 0.10);--gl-shadow-focus:0 0 0 3px color-mix(in srgb, var(--gl-color-primary) 25%, transparent);--gl-inset-subtle:inset 0 1px 1px rgba(255, 255, 255, 0.60);--gl-inset-medium:inset 0 1px 1px rgba(255, 255, 255, 0.70);--gl-inset-strong:inset 0 1px 2px rgba(255, 255, 255, 0.80);--gl-inset-milk:inset 0 1px 2px rgba(255, 255, 255, 0.90);--gl-bg-aurora-1:rgba(100, 200, 220, 0.15);--gl-bg-aurora-2:rgba(240, 180, 100, 0.10);--gl-bg-aurora-3:rgba(120, 200, 230, 0.12);--gl-bg-light-streak-1:rgba(140, 230, 220, 0.10);--gl-bg-light-streak-2:rgba(160, 220, 210, 0.08);--gl-bg-warm-glow:rgba(240, 180, 100, 0.08);--gl-placeholder:rgba(26, 42, 54, 0.30);--gl-accordion-body-color:var(--gl-color-text-muted);--gl-toggle-thumb-bg:linear-gradient(to bottom, #ffffff 0%, #f0f0f0 100%);--gl-range-track-bg:var(--gl-surface-2);--gl-range-track-border:var(--gl-border-subtle)}";
|
|
8
|
+
const tokensCss = ":root,[data-theme=dark]{color-scheme:dark;--gl-color-primary:#f5a623;--gl-color-primary-dark:#d4692a;--gl-color-primary-mid:color-mix(in srgb, var(--gl-color-primary) 32%, var(--gl-color-primary-dark));--gl-color-bg-dark:#0e2530;--gl-color-bg-mid:#1a3d4e;--gl-color-bg-light:#1b3e50;--gl-color-text:#ffffff;--gl-color-text-muted:rgba(255, 255, 255, 0.60);--gl-color-text-on-light:#1a3a4a;--gl-color-text-heading:#ffffff;--gl-select-chevron:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.6)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");--gl-color-success:#34c759;--gl-color-error:#ff3b30;--gl-color-warning:#ffcc00;--gl-color-success-dark:#2da44e;--gl-color-error-dark:#d63027;--gl-color-on-primary:#ffffff;--gl-color-on-success:#ffffff;--gl-color-on-error:#ffffff;--gl-color-primary-on-surface:color-mix(in srgb, var(--gl-color-primary) 50%, #ffffff);--gl-color-success-on-surface:color-mix(in srgb, var(--gl-color-success) 62%, #ffffff);--gl-color-error-on-surface:color-mix(in srgb, var(--gl-color-error) 50%, #ffffff);--gl-color-warning-on-surface:color-mix(in srgb, var(--gl-color-warning) 80%, #ffffff);--gl-state-scrim:rgba(0, 0, 0, 0.30);--gl-color-primary-surface:color-mix(in srgb, var(--gl-color-primary) 25%, transparent);--gl-color-primary-border:var(--gl-border-warm);--gl-color-success-surface:color-mix(in srgb, var(--gl-color-success) 15%, transparent);--gl-color-success-border:color-mix(in srgb, var(--gl-color-success) 30%, transparent);--gl-color-error-surface:color-mix(in srgb, var(--gl-color-error) 15%, transparent);--gl-color-error-border:color-mix(in srgb, var(--gl-color-error) 30%, transparent);--gl-color-warning-surface:color-mix(in srgb, var(--gl-color-warning) 15%, transparent);--gl-color-warning-border:color-mix(in srgb, var(--gl-color-warning) 30%, transparent);--gl-surface-1:rgba(255, 255, 255, 0.08);--gl-surface-2:rgba(255, 255, 255, 0.10);--gl-surface-3:rgba(255, 255, 255, 0.14);--gl-surface-4:rgba(255, 255, 255, 0.16);--gl-surface-5:rgba(255, 255, 255, 0.22);--gl-surface-milk:rgba(255, 255, 255, 0.55);--gl-surface-milk-strong:rgba(255, 255, 255, 0.75);--gl-surface-overlay:rgba(0, 0, 0, 0.50);--gl-card-glow-top:rgba(255, 255, 255, 0.32);--gl-card-glow-mid:rgba(255, 255, 255, 0.22);--gl-card-glow-low:rgba(255, 255, 255, 0.14);--gl-card-glow-bottom:rgba(255, 255, 255, 0.08);--gl-card-icon-color:rgba(255, 255, 255, 0.8);--gl-card-text-color:rgba(255, 255, 255, 0.7);--gl-border-subtle:rgba(255, 255, 255, 0.18);--gl-border-medium:rgba(255, 255, 255, 0.30);--gl-border-strong:rgba(255, 255, 255, 0.40);--gl-border-milk:rgba(255, 255, 255, 0.60);--gl-border-warm:color-mix(in srgb, color-mix(in srgb, var(--gl-color-primary) 68%, #ffffff) 35%, transparent);--gl-border-focus:color-mix(in srgb, var(--gl-color-primary) 60%, transparent);--gl-icon-default:rgba(255, 255, 255, 0.6);--gl-icon-muted:rgba(255, 255, 255, 0.45);--gl-icon-strong:rgba(255, 255, 255, 0.8);--gl-icon-on-primary:var(--gl-color-on-primary, #ffffff);--gl-icon-on-secondary:#1a3a4a;--gl-icon-on-tertiary:rgba(255, 255, 255, 0.6);--gl-blur:24px;--gl-blur-light:16px;--gl-blur-soft:12px;--gl-blur-heavy:40px;--gl-radius-pill:50%;--gl-radius-full:9999px;--gl-radius-card:24px;--gl-radius-btn:16px;--gl-radius-input:14px;--gl-radius-sm:12px;--gl-radius-xs:8px;--gl-shadow-card:0 8px 32px rgba(0, 0, 0, 0.18);--gl-shadow-btn:0 4px 16px rgba(0, 0, 0, 0.12);--gl-shadow-btn-primary:0 6px 24px color-mix(in srgb, var(--gl-color-primary-mid) 35%, transparent),0 2px 8px rgba(0, 0, 0, 0.15);--gl-shadow-glow:0 2px 12px rgba(255, 255, 255, 0.08),0 4px 16px rgba(0, 0, 0, 0.15);--gl-shadow-modal:0 24px 80px rgba(0, 0, 0, 0.4),0 8px 32px rgba(0, 0, 0, 0.2);--gl-shadow-toast:0 8px 32px rgba(0, 0, 0, 0.25);--gl-shadow-focus:0 0 0 3px color-mix(in srgb, var(--gl-color-primary) 30%, transparent);--gl-inset-subtle:inset 0 1px 1px rgba(255, 255, 255, 0.10);--gl-inset-medium:inset 0 1px 1px rgba(255, 255, 255, 0.15);--gl-inset-strong:inset 0 1px 2px rgba(255, 255, 255, 0.25);--gl-inset-milk:inset 0 1px 2px rgba(255, 255, 255, 0.40);--gl-bg-aurora-1:rgba(60, 160, 160, 0.25);--gl-bg-aurora-2:rgba(200, 140, 60, 0.12);--gl-bg-aurora-3:rgba(80, 180, 200, 0.18);--gl-bg-light-streak-1:rgba(90, 210, 200, 0.14);--gl-bg-light-streak-2:rgba(110, 200, 190, 0.10);--gl-bg-warm-glow:rgba(220, 160, 70, 0.10);--gl-space-2xs:4px;--gl-space-xs:8px;--gl-space-sm:12px;--gl-space-md:16px;--gl-space-lg:20px;--gl-space-xl:24px;--gl-space-2xl:32px;--gl-space-3xl:40px;--gl-space-4xl:56px;--gl-font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',Roboto,Helvetica,Arial,sans-serif;--gl-font-size-xs:13px;--gl-font-size-sm:14px;--gl-font-size-base:15px;--gl-font-size-btn:16px;--gl-font-size-lg:18px;--gl-font-size-title:24px;--gl-font-size-modal:20px;--gl-font-weight-normal:400;--gl-font-weight-medium:500;--gl-font-weight-semibold:600;--gl-transition:all 0.25s ease;--gl-transition-fast:all 0.15s ease;--gl-transition-modal:all 0.3s cubic-bezier(0.4, 0, 0.2, 1);--gl-tab-bar-height:82px;--gl-modal-max-width:340px;--gl-tab-bar-floating-bottom:16px;--gl-tab-bar-floating-gap:var(--gl-space-sm);--gl-tab-bar-floating-padding:6px 10px;--gl-tab-bar-floating-radius:var(--gl-radius-full);--gl-tab-bar-accessory-size:56px;--gl-tab-bar-spotlight-color:var(--gl-color-primary);--gl-placeholder:rgba(255, 255, 255, 0.35);--gl-accordion-body-color:var(--gl-color-text-muted);--gl-toggle-thumb-bg:linear-gradient(to bottom,\n rgba(255,255,255,0.9) 0%,\n rgba(255,255,255,0.7) 100%);--gl-range-track-bg:var(--gl-surface-2);--gl-range-track-border:var(--gl-border-subtle)}[data-theme=light]{color-scheme:light;--gl-color-primary:#e8852d;--gl-color-primary-dark:#c96a1e;--gl-color-primary-mid:color-mix(in srgb, var(--gl-color-primary) 52%, var(--gl-color-primary-dark));--gl-color-bg-dark:#e8ecf1;--gl-color-bg-mid:#f0f4f8;--gl-color-bg-light:#f5f7fa;--gl-color-text:#1a2a36;--gl-color-text-muted:rgba(26, 42, 54, 0.55);--gl-color-text-on-light:#1a3a4a;--gl-color-text-heading:#0f1f2a;--gl-select-chevron:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(26,42,54,0.55)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");--gl-color-success:#28a745;--gl-color-error:#dc3545;--gl-color-warning:#e6a800;--gl-color-success-dark:#1e7e34;--gl-color-error-dark:#b02a37;--gl-color-on-primary:#ffffff;--gl-color-on-success:#ffffff;--gl-color-on-error:#ffffff;--gl-color-primary-on-surface:color-mix(in srgb, var(--gl-color-primary) 60%, #000000);--gl-color-success-on-surface:color-mix(in srgb, var(--gl-color-success) 68%, #000000);--gl-color-error-on-surface:color-mix(in srgb, var(--gl-color-error) 82%, #000000);--gl-color-warning-on-surface:color-mix(in srgb, var(--gl-color-warning) 56%, #000000);--gl-state-scrim:rgba(255, 255, 255, 0.30);--gl-color-primary-surface:color-mix(in srgb, var(--gl-color-primary) 25%, transparent);--gl-color-primary-border:var(--gl-border-warm);--gl-color-success-surface:color-mix(in srgb, var(--gl-color-success) 15%, transparent);--gl-color-success-border:color-mix(in srgb, var(--gl-color-success) 30%, transparent);--gl-color-error-surface:color-mix(in srgb, var(--gl-color-error) 15%, transparent);--gl-color-error-border:color-mix(in srgb, var(--gl-color-error) 30%, transparent);--gl-color-warning-surface:color-mix(in srgb, var(--gl-color-warning) 15%, transparent);--gl-color-warning-border:color-mix(in srgb, var(--gl-color-warning) 30%, transparent);--gl-surface-1:rgba(255, 255, 255, 0.50);--gl-surface-2:rgba(255, 255, 255, 0.60);--gl-surface-3:rgba(255, 255, 255, 0.70);--gl-surface-4:rgba(255, 255, 255, 0.75);--gl-surface-5:rgba(255, 255, 255, 0.85);--gl-surface-milk:rgba(255, 255, 255, 0.85);--gl-surface-milk-strong:rgba(255, 255, 255, 0.92);--gl-surface-overlay:rgba(0, 0, 0, 0.25);--gl-card-glow-top:rgba(255, 255, 255, 0.90);--gl-card-glow-mid:rgba(255, 255, 255, 0.78);--gl-card-glow-low:rgba(255, 255, 255, 0.65);--gl-card-glow-bottom:rgba(255, 255, 255, 0.50);--gl-card-icon-color:rgba(26, 42, 54, 0.5);--gl-card-text-color:rgba(26, 42, 54, 0.6);--gl-border-subtle:rgba(0, 0, 0, 0.08);--gl-border-medium:rgba(0, 0, 0, 0.12);--gl-border-strong:rgba(0, 0, 0, 0.15);--gl-border-milk:rgba(0, 0, 0, 0.10);--gl-border-warm:color-mix(in srgb, var(--gl-color-primary) 30%, transparent);--gl-border-focus:color-mix(in srgb, var(--gl-color-primary) 50%, transparent);--gl-icon-default:rgba(26, 42, 54, 0.50);--gl-icon-muted:rgba(26, 42, 54, 0.35);--gl-icon-strong:rgba(26, 42, 54, 0.70);--gl-icon-on-primary:var(--gl-color-on-primary, #ffffff);--gl-icon-on-secondary:#1a3a4a;--gl-icon-on-tertiary:rgba(26, 42, 54, 0.50);--gl-shadow-card:0 4px 20px rgba(0, 0, 0, 0.06);--gl-shadow-btn:0 2px 10px rgba(0, 0, 0, 0.06);--gl-shadow-btn-primary:0 4px 16px color-mix(in srgb, var(--gl-color-primary) 25%, transparent),0 2px 6px rgba(0, 0, 0, 0.08);--gl-shadow-glow:0 2px 8px rgba(0, 0, 0, 0.05),0 4px 12px rgba(0, 0, 0, 0.04);--gl-shadow-modal:0 16px 48px rgba(0, 0, 0, 0.12),0 4px 16px rgba(0, 0, 0, 0.08);--gl-shadow-toast:0 4px 20px rgba(0, 0, 0, 0.10);--gl-shadow-focus:0 0 0 3px color-mix(in srgb, var(--gl-color-primary) 25%, transparent);--gl-inset-subtle:inset 0 1px 1px rgba(255, 255, 255, 0.60);--gl-inset-medium:inset 0 1px 1px rgba(255, 255, 255, 0.70);--gl-inset-strong:inset 0 1px 2px rgba(255, 255, 255, 0.80);--gl-inset-milk:inset 0 1px 2px rgba(255, 255, 255, 0.90);--gl-bg-aurora-1:rgba(100, 200, 220, 0.15);--gl-bg-aurora-2:rgba(240, 180, 100, 0.10);--gl-bg-aurora-3:rgba(120, 200, 230, 0.12);--gl-bg-light-streak-1:rgba(140, 230, 220, 0.10);--gl-bg-light-streak-2:rgba(160, 220, 210, 0.08);--gl-bg-warm-glow:rgba(240, 180, 100, 0.08);--gl-placeholder:rgba(26, 42, 54, 0.30);--gl-accordion-body-color:var(--gl-color-text-muted);--gl-toggle-thumb-bg:linear-gradient(to bottom, #ffffff 0%, #f0f0f0 100%);--gl-range-track-bg:var(--gl-surface-2);--gl-range-track-border:var(--gl-border-subtle)}";
|
|
9
9
|
|
|
10
10
|
// … and everything else, in two pieces around where they were.
|
|
11
11
|
const componentsHead = "[class*=gl-],[class*=glass-],[class*=glass-]::after,[class*=glass-]::before{box-sizing:border-box}";
|
|
12
|
-
const componentsTail = ".glass-bg{background:radial-gradient(ellipse at 20% 40%,var(--gl-bg-aurora-1) 0,transparent 55%),radial-gradient(ellipse at 80% 65%,var(--gl-bg-aurora-2) 0,transparent 50%),radial-gradient(ellipse at 50% 20%,var(--gl-bg-aurora-3) 0,transparent 50%),linear-gradient(170deg,var(--gl-color-bg-light) 0,var(--gl-color-bg-mid) 50%,var(--gl-color-bg-dark) 100%);position:relative;min-height:100vh;overflow-x:hidden;font-family:var(--gl-font-family);color:var(--gl-color-text);-webkit-font-smoothing:antialiased;transition:background .4s,color .3s;isolation:isolate}.glass-bg::before{content:'';position:absolute;top:20%;left:-30%;width:160%;height:55%;background:radial-gradient(ellipse at 35% 45%,var(--gl-bg-light-streak-1) 0,transparent 50%),radial-gradient(ellipse at 65% 55%,var(--gl-bg-light-streak-2) 0,transparent 45%);transform:rotate(-8deg);pointer-events:none;z-index:-1}.glass-bg::after{content:'';position:absolute;top:40%;right:-20%;width:70%;height:50%;background:radial-gradient(ellipse at center,var(--gl-bg-warm-glow) 0,transparent 65%);pointer-events:none;z-index:-1}.glass-bg>*{position:relative}.glass-bg--has-tab-bar{padding-bottom:var(--gl-tab-bar-height)}.glass-bg--has-tab-bar-floating{padding-bottom:calc(var(--gl-tab-bar-accessory-size) + var(--gl-tab-bar-floating-bottom) + var(--gl-space-md))}.glass-nav{display:flex;justify-content:space-between;align-items:center;padding:0 var(--gl-space-xs)}.glass-pill{width:46px;height:46px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-strong);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--gl-transition);color:var(--gl-color-text);box-shadow:var(--gl-shadow-glow),var(--gl-inset-medium);outline:0;-webkit-tap-highlight-color:transparent}.glass-pill:hover{background:var(--gl-surface-5);transform:scale(1.05)}.glass-pill:active{transform:scale(.95)}.glass-pill ::slotted(svg),.glass-pill svg{width:20px;height:20px;fill:none;stroke:var(--gl-color-text);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}.glass-title{text-align:center;color:var(--gl-color-text-heading);font-size:var(--gl-font-size-title);font-weight:var(--gl-font-weight-semibold);line-height:1.3;text-shadow:0 2px 12px rgba(0,0,0,.15);letter-spacing:-.3px}.glass-card{background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-card);padding:var(--gl-space-3xl) var(--gl-space-xl) var(--gl-space-2xl);box-shadow:var(--gl-shadow-card),var(--gl-inset-strong)}.glass-card--glow{position:relative;overflow:hidden;background:linear-gradient(to bottom,var(--gl-card-glow-top) 0,var(--gl-card-glow-mid) 25%,var(--gl-card-glow-low) 55%,var(--gl-card-glow-bottom) 100%)}.glass-card--glow::before{content:'';position:absolute;top:0;left:10%;right:10%;height:1px;background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.5) 30%,rgba(255,255,255,.6) 50%,rgba(255,255,255,.5) 70%,transparent 100%);z-index:1}.glass-card__icon{display:flex;align-items:center;justify-content:center;margin:0 auto var(--gl-space-lg)}.glass-card__icon svg{width:64px;height:64px;stroke:var(--gl-card-icon-color);stroke-width:1.2;fill:none}.glass-card__text{color:var(--gl-card-text-color);font-size:var(--gl-font-size-base);font-weight:var(--gl-font-weight-normal);line-height:1.55;text-align:center}.glass-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;height:56px;border:none;border-radius:var(--gl-radius-btn);font-family:var(--gl-font-family);font-size:var(--gl-font-size-btn);font-weight:var(--gl-font-weight-semibold);cursor:pointer;transition:var(--gl-transition);outline:0;-webkit-tap-highlight-color:transparent}a.glass-btn{display:inline-flex;text-decoration:none}.glass-btn[hidden]{display:none}.glass-btn ::slotted(svg),.glass-btn svg{width:20px;height:20px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-btn--primary{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-mid) 50%,var(--gl-color-primary-dark) 100%);color:var(--gl-color-on-primary,#fff);border:1px solid var(--gl-border-warm);box-shadow:var(--gl-shadow-btn-primary),var(--gl-inset-strong)}.glass-btn--primary ::slotted(svg),.glass-btn--primary svg{fill:var(--gl-icon-on-primary);stroke:var(--gl-icon-on-primary);stroke-width:0}.glass-btn--primary:hover{transform:translateY(-1px)}.glass-btn--primary:active{transform:translateY(1px)}.glass-btn--secondary{background:linear-gradient(to bottom,var(--gl-surface-milk-strong) 0,var(--gl-surface-milk) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-milk);color:var(--gl-color-text-on-light);box-shadow:var(--gl-shadow-btn),var(--gl-inset-milk)}.glass-btn--secondary ::slotted(svg),.glass-btn--secondary svg{fill:none;stroke:var(--gl-icon-on-secondary);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-btn--secondary:hover{transform:translateY(-1px)}.glass-btn--secondary:active{transform:translateY(1px)}.glass-btn--tertiary{background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);color:var(--gl-color-text-muted);box-shadow:0 4px 12px rgba(0,0,0,.1),var(--gl-inset-subtle)}.glass-btn--tertiary ::slotted(svg),.glass-btn--tertiary svg{fill:none;stroke:var(--gl-icon-on-tertiary);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-btn--tertiary:hover{background:var(--gl-surface-4);color:var(--gl-color-text);transform:translateY(-1px)}.glass-btn--tertiary:active{transform:translateY(1px)}.glass-btn--sm{height:44px;font-size:var(--gl-font-size-sm);border-radius:var(--gl-radius-sm)}.glass-btn--lg{height:64px;font-size:var(--gl-font-size-lg)}.glass-btn--auto{width:auto;padding:0 var(--gl-space-xl)}.glass-status{background:var(--gl-surface-1);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);padding:var(--gl-space-md) var(--gl-space-lg);display:flex;align-items:center;gap:var(--gl-space-sm);box-shadow:0 4px 12px rgba(0,0,0,.08),var(--gl-inset-subtle)}.glass-status ::slotted(svg),.glass-status svg{width:20px;height:20px;flex-shrink:0;stroke:var(--gl-icon-muted);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-status p{color:var(--gl-color-text-muted);font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-normal);line-height:1.45}.glass-input-group{display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-label{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-strong);padding-left:var(--gl-space-2xs)}.glass-input{width:100%;height:52px;padding:0 var(--gl-space-md);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-input);color:var(--gl-color-text);font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);transition:var(--gl-transition);outline:0;box-shadow:var(--gl-inset-subtle);-webkit-tap-highlight-color:transparent}.glass-input::placeholder{color:var(--gl-placeholder)}.glass-input[type=date],.glass-input[type=datetime-local],.glass-input[type=month],.glass-input[type=time]{-webkit-appearance:none;appearance:none}.glass-input::-webkit-date-and-time-value{text-align:start}.glass-input:focus{border-color:var(--gl-border-focus);background:var(--gl-surface-3);box-shadow:var(--gl-shadow-focus),var(--gl-inset-medium)}.glass-input:disabled{opacity:.4;cursor:not-allowed}.glass-input--error{border-color:var(--gl-color-error)}.glass-input--error:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--gl-color-error) 25%,transparent),var(--gl-inset-medium)}.glass-hint{font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted);padding-left:var(--gl-space-2xs)}.glass-hint--error{color:var(--gl-color-error)}.glass-textarea{width:100%;min-height:120px;padding:var(--gl-space-md);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-input);color:var(--gl-color-text);font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);line-height:1.5;resize:vertical;transition:var(--gl-transition);outline:0;box-shadow:var(--gl-inset-subtle)}.glass-textarea::placeholder{color:var(--gl-placeholder)}.glass-textarea:focus{border-color:var(--gl-border-focus);background:var(--gl-surface-3);box-shadow:var(--gl-shadow-focus),var(--gl-inset-medium)}.glass-select{width:100%;height:52px;padding:0 var(--gl-space-3xl) 0 var(--gl-space-md);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-input);color:var(--gl-color-text);font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);transition:var(--gl-transition);outline:0;box-shadow:var(--gl-inset-subtle);cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.6)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 16px center}.glass-select:focus{border-color:var(--gl-border-focus);box-shadow:var(--gl-shadow-focus),var(--gl-inset-medium)}.glass-select option{background:var(--gl-color-bg-mid);color:var(--gl-color-text)}.glass-search{position:relative;display:flex;align-items:center}.glass-search__icon{position:absolute;left:var(--gl-space-md);width:18px;height:18px;stroke:var(--gl-icon-muted)!important;stroke-width:2!important;stroke-linecap:round!important;stroke-linejoin:round!important;fill:none!important;pointer-events:none;z-index:2}.glass-search .glass-input{padding-left:44px;border-radius:var(--gl-radius-full)}.glass-toggle{display:inline-flex;align-items:flex-start;gap:var(--gl-space-sm);cursor:pointer;-webkit-tap-highlight-color:transparent}.glass-toggle__input{position:absolute;opacity:0;margin:0;width:52px;height:30px;pointer-events:none}.glass-toggle__track{position:relative;width:52px;height:30px;background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-full);transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle);flex-shrink:0;margin-top:max(0px,calc((1lh - 30px)/ 2))}.glass-toggle__thumb{position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:var(--gl-radius-pill);background:var(--gl-toggle-thumb-bg);box-shadow:0 2px 6px rgba(0,0,0,.2),var(--gl-inset-milk);transition:var(--gl-transition)}.glass-toggle__input:checked+.glass-toggle__track{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border-color:var(--gl-border-warm)}.glass-toggle__input:checked+.glass-toggle__track .glass-toggle__thumb{transform:translateX(22px)}.glass-toggle__input:focus-visible+.glass-toggle__track{box-shadow:var(--gl-shadow-focus)}.glass-toggle__label{font-size:var(--gl-font-size-base);color:var(--gl-color-text);user-select:none;margin-top:max(0px,calc((30px - 1lh)/ 2))}.glass-checkbox{display:inline-flex;align-items:flex-start;gap:var(--gl-space-sm);cursor:pointer;-webkit-tap-highlight-color:transparent}.glass-checkbox__input{position:absolute;opacity:0;margin:0;width:24px;height:24px;pointer-events:none}.glass-checkbox__box{width:24px;height:24px;border-radius:var(--gl-radius-xs);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-medium);display:flex;align-items:center;justify-content:center;transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle);flex-shrink:0;margin-top:max(0px,calc((1lh - 24px)/ 2))}.glass-checkbox__box svg{width:14px;height:14px;stroke:var(--gl-color-on-primary,#ffffff);stroke-width:3;fill:none;stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.5);transition:var(--gl-transition-fast)}.glass-checkbox__input:checked+.glass-checkbox__box{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border-color:var(--gl-border-warm)}.glass-checkbox__input:checked+.glass-checkbox__box svg{opacity:1;transform:scale(1)}.glass-checkbox__input:focus-visible+.glass-checkbox__box{box-shadow:var(--gl-shadow-focus)}.glass-checkbox__label{font-size:var(--gl-font-size-base);color:var(--gl-color-text);user-select:none;margin-top:max(0px,calc((24px - 1lh)/ 2))}.glass-radio{display:inline-flex;align-items:flex-start;gap:var(--gl-space-sm);cursor:pointer;-webkit-tap-highlight-color:transparent}.glass-radio__input{position:absolute;opacity:0;margin:0;width:24px;height:24px;pointer-events:none}.glass-radio__circle{width:24px;height:24px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-medium);display:flex;align-items:center;justify-content:center;transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle);flex-shrink:0;margin-top:max(0px,calc((1lh - 24px)/ 2))}.glass-radio__dot{width:10px;height:10px;border-radius:var(--gl-radius-pill);background:#fff;opacity:0;transform:scale(0);transition:var(--gl-transition-fast)}.glass-radio__input:checked+.glass-radio__circle{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border-color:var(--gl-border-warm)}.glass-radio__input:checked+.glass-radio__circle .glass-radio__dot{opacity:1;transform:scale(1)}.glass-radio__input:focus-visible+.glass-radio__circle{box-shadow:var(--gl-shadow-focus)}.glass-radio__label{font-size:var(--gl-font-size-base);color:var(--gl-color-text);user-select:none;margin-top:max(0px,calc((24px - 1lh)/ 2))}.glass-range-group{display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-range-header{display:flex;justify-content:space-between;align-items:baseline}.glass-range-value{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-primary);font-variant-numeric:tabular-nums}.glass-range{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:var(--gl-radius-full);background:var(--gl-range-track-bg);border:1px solid var(--gl-range-track-border);outline:0;cursor:pointer}.glass-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;box-sizing:border-box;width:26px;height:26px;border-radius:var(--gl-radius-pill);background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border:2px solid rgba(255,255,255,.5);box-shadow:0 2px 8px color-mix(in srgb,var(--gl-color-primary-mid) 35%,transparent),var(--gl-inset-strong);margin-top:-2px;cursor:pointer;transition:var(--gl-transition)}.glass-range::-webkit-slider-thumb:hover{transform:scale(1.1)}.glass-range::-moz-range-thumb{width:26px;height:26px;border-radius:var(--gl-radius-pill);background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border:2px solid rgba(255,255,255,.5);box-shadow:0 2px 8px color-mix(in srgb,var(--gl-color-primary-mid) 35%,transparent);cursor:pointer}.glass-range::-moz-range-track{height:6px;border-radius:var(--gl-radius-full);background:var(--gl-range-track-bg);border:1px solid var(--gl-range-track-border)}.glass-range:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-progress{width:100%;display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-progress__header{display:flex;justify-content:space-between;align-items:baseline}.glass-progress__label{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-strong)}.glass-progress__value{font-size:var(--gl-font-size-xs);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-muted);font-variant-numeric:tabular-nums}.glass-progress__track{width:100%;height:8px;border-radius:var(--gl-radius-full);background:var(--gl-surface-2);border:1px solid var(--gl-border-subtle);overflow:hidden;box-shadow:var(--gl-inset-subtle)}.glass-progress__fill{height:100%;border-radius:var(--gl-radius-full);background:linear-gradient(90deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);box-shadow:0 0 8px color-mix(in srgb,var(--gl-color-primary) 30%,transparent),var(--gl-inset-strong);transition:width .5s cubic-bezier(.4, 0, .2, 1);position:relative}.glass-progress__fill::after{content:'';position:absolute;top:0;left:0;right:0;height:50%;border-radius:var(--gl-radius-full);background:linear-gradient(to bottom,rgba(255,255,255,.3) 0,transparent 100%)}.glass-progress--sm .glass-progress__track{height:4px}.glass-progress--lg .glass-progress__track{height:12px}.glass-progress--success .glass-progress__fill{background:linear-gradient(90deg,var(--gl-color-success) 0,var(--gl-color-success-dark,#2da44e) 100%);box-shadow:0 0 8px color-mix(in srgb,var(--gl-color-success) 30%,transparent),var(--gl-inset-strong)}.glass-progress--error .glass-progress__fill{background:linear-gradient(90deg,var(--gl-color-error) 0,var(--gl-color-error-dark,#d63027) 100%);box-shadow:0 0 8px color-mix(in srgb,var(--gl-color-error) 30%,transparent),var(--gl-inset-strong)}.glass-modal-overlay{position:fixed;inset:0;background:var(--gl-surface-overlay);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));display:flex;align-items:center;justify-content:center;padding:var(--gl-space-lg);z-index:1000;opacity:0;pointer-events:none;transition:var(--gl-transition-modal);font-family:var(--gl-font-family);-webkit-font-smoothing:antialiased}.glass-modal-overlay.is-active{opacity:1;pointer-events:auto}.glass-modal{width:100%;max-width:340px;background:linear-gradient(to bottom,var(--gl-card-glow-top) 0,var(--gl-card-glow-bottom) 100%);backdrop-filter:blur(var(--gl-blur-heavy));-webkit-backdrop-filter:blur(var(--gl-blur-heavy));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-card);overflow:hidden;box-shadow:var(--gl-shadow-modal);transform:scale(.9) translateY(20px);transition:var(--gl-transition-modal);position:relative}.glass-modal-overlay.is-active .glass-modal{transform:scale(1) translateY(0)}.glass-modal::before{content:'';position:absolute;top:0;left:10%;right:10%;height:1px;background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.4) 30%,rgba(255,255,255,.5) 50%,rgba(255,255,255,.4) 70%,transparent 100%)}.glass-modal__header{padding:var(--gl-space-xl) var(--gl-space-xl) var(--gl-space-sm);text-align:center}.glass-modal__title{font-size:var(--gl-font-size-modal);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text)}.glass-modal__body{padding:var(--gl-space-sm) var(--gl-space-xl) var(--gl-space-xl);text-align:center}.glass-modal__body p{color:var(--gl-color-text-muted);font-size:var(--gl-font-size-base);line-height:1.55}.glass-modal__footer{display:flex;border-top:1px solid var(--gl-border-subtle)}.glass-modal__action{flex:1;height:52px;background:0 0;border:none;font-family:var(--gl-font-family);font-size:var(--gl-font-size-btn);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text-muted);cursor:pointer;transition:var(--gl-transition-fast);outline:0}.glass-modal__action:hover{background:var(--gl-surface-1)}.glass-modal__action+.glass-modal__action{border-left:1px solid var(--gl-border-subtle)}.glass-modal__action--primary{color:var(--gl-color-primary);font-weight:var(--gl-font-weight-semibold)}.glass-modal__action--danger{color:var(--gl-color-error);font-weight:var(--gl-font-weight-semibold)}.glass-toast{position:fixed;top:var(--gl-toast-top,var(--gl-space-4xl));left:50%;transform:translateX(-50%) translateY(-20px);min-width:280px;max-width:340px;padding:var(--gl-space-md) var(--gl-space-lg);background:linear-gradient(to bottom,var(--gl-surface-4) 0,var(--gl-surface-2) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1px solid var(--gl-border-medium);border-radius:var(--gl-radius-btn);display:flex;align-items:center;gap:var(--gl-space-sm);box-shadow:var(--gl-shadow-toast),var(--gl-inset-medium);z-index:1100;opacity:0;pointer-events:none;transition:var(--gl-transition-modal);font-family:var(--gl-font-family);-webkit-font-smoothing:antialiased}.glass-toast.is-visible{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}.glass-toast__icon{width:22px;height:22px;flex-shrink:0;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-toast__icon ::slotted(svg){display:block;width:100%;height:100%}.glass-toast--success .glass-toast__icon{stroke:var(--gl-color-success)}.glass-toast--error .glass-toast__icon{stroke:var(--gl-color-error)}.glass-toast--warning .glass-toast__icon{stroke:var(--gl-color-warning)}.glass-toast__text{flex:1 1 auto;min-width:0;font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);line-height:1.4}.glass-toast:has(.glass-toast__action){width:max-content;max-width:min(480px,calc(100% - 2 * var(--gl-space-md)))}.glass-toast--success{--gl-toast-action-surface:var(--gl-color-success-surface);--gl-toast-action-border:var(--gl-color-success-border);--gl-toast-action-ink:var(--gl-color-success-on-surface)}.glass-toast--error{--gl-toast-action-surface:var(--gl-color-error-surface);--gl-toast-action-border:var(--gl-color-error-border);--gl-toast-action-ink:var(--gl-color-error-on-surface)}.glass-toast--warning{--gl-toast-action-surface:var(--gl-color-warning-surface);--gl-toast-action-border:var(--gl-color-warning-border);--gl-toast-action-ink:var(--gl-color-warning-on-surface)}.glass-toast__action,.glass-toast__close{-webkit-appearance:none;appearance:none;flex:none;position:relative;font:inherit;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-toast__action{height:32px;padding:0 14px;border:1px solid var(--gl-toast-action-border,var(--gl-color-primary-border));border-radius:var(--gl-radius-full);background:linear-gradient(var(--gl-toast-action-surface,var(--gl-color-primary-surface)),var(--gl-toast-action-surface,var(--gl-color-primary-surface))),linear-gradient(var(--gl-state-scrim),var(--gl-state-scrim)),var(--gl-state-scrim);color:var(--gl-toast-action-ink,var(--gl-color-primary-on-surface));font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-semibold);white-space:nowrap}.glass-toast__action::after{content:\"\";position:absolute;inset:-6px 0}.glass-toast__action:hover{box-shadow:inset 0 0 0 100px color-mix(in srgb,var(--gl-toast-action-ink,var(--gl-color-primary-on-surface)) 10%,transparent)}.glass-toast__action:active{transform:scale(.96)}.glass-toast__close{width:28px;height:28px;margin:0 -8px 0 -4px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:0 0;color:var(--gl-color-text-muted)}.glass-toast__close::after{content:\"\";position:absolute;inset:-8px}.glass-toast__close:hover{background:var(--gl-surface-3);color:var(--gl-color-text)}.glass-toast__close svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}.glass-toast__action:focus-visible,.glass-toast__close:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-tab-bar{position:fixed;bottom:0;left:0;right:0;height:var(--gl-tab-bar-height);background:linear-gradient(to bottom,var(--gl-surface-3) 0,var(--gl-surface-1) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border-top:1px solid var(--gl-border-subtle);display:flex;justify-content:space-around;align-items:flex-start;padding-top:var(--gl-space-xs);padding-bottom:env(safe-area-inset-bottom,8px);z-index:900;box-shadow:0 -4px 20px rgba(0,0,0,.08),var(--gl-inset-subtle)}.glass-tab-bar__item{display:flex;flex-direction:column;align-items:center;gap:var(--gl-space-2xs);padding:var(--gl-space-2xs) var(--gl-space-sm);background:0 0;border:none;cursor:pointer;transition:var(--gl-transition);outline:0;-webkit-tap-highlight-color:transparent;min-width:60px}.glass-tab-bar__icon{width:24px;height:24px;display:flex;align-items:center;justify-content:center;position:relative}.glass-tab-bar__icon svg{width:24px;height:24px;fill:none;stroke:var(--gl-icon-muted);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:var(--gl-transition)}.glass-tab-bar__label{font-size:10px;font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-muted);transition:var(--gl-transition);letter-spacing:.2px}.glass-tab-bar__item.is-active .glass-tab-bar__icon svg{stroke:var(--gl-color-primary);filter:drop-shadow(0 0 6px color-mix(in srgb, var(--gl-color-primary) 35%, transparent))}.glass-tab-bar__item.is-active .glass-tab-bar__label{color:var(--gl-color-primary)}.glass-tab-bar__item.is-active .glass-tab-bar__icon::after{content:'';position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);width:4px;height:4px;border-radius:var(--gl-radius-pill);background:var(--gl-color-primary);box-shadow:0 0 6px color-mix(in srgb,var(--gl-color-primary) 50%,transparent)}.glass-tab-bar__item:not(.is-active):hover .glass-tab-bar__icon svg{stroke:var(--gl-icon-default)}.glass-tab-bar__item:not(.is-active):hover .glass-tab-bar__label{color:var(--gl-icon-default)}.glass-tab-bar__badge{position:absolute;top:-4px;right:-8px;min-width:16px;height:16px;padding:0 4px;border-radius:var(--gl-radius-full);background:var(--gl-color-error-dark,#d63027);color:#fff;font-size:10px;font-weight:var(--gl-font-weight-semibold);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px color-mix(in srgb,var(--gl-color-error) 40%,transparent)}.glass-tab-bar-dock{position:fixed;left:50%;bottom:calc(var(--gl-tab-bar-floating-bottom) + env(safe-area-inset-bottom,0px));transform:translateX(-50%);display:flex;align-items:center;gap:var(--gl-tab-bar-floating-gap);z-index:900;max-width:calc(100vw - 2 * var(--gl-space-md))}.glass-tab-bar-dock--accessory-left{flex-direction:row-reverse}.glass-tab-bar.glass-tab-bar--floating{position:static;left:auto;right:auto;bottom:auto;height:auto;width:max-content;padding:var(--gl-tab-bar-floating-padding);border-radius:var(--gl-tab-bar-floating-radius);border:1px solid var(--gl-border-subtle);background:linear-gradient(to bottom,var(--gl-surface-3) 0,var(--gl-surface-1) 100%);box-shadow:0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08),var(--gl-inset-subtle);display:flex;justify-content:flex-start;align-items:center;gap:var(--gl-space-2xs)}.glass-tab-bar--floating .glass-tab-bar__item{position:relative;border-radius:var(--gl-radius-full);padding:var(--gl-space-2xs) var(--gl-space-sm);min-width:auto;align-items:center}.glass-tab-bar--floating .glass-tab-bar__item>*{position:relative;z-index:1}.glass-tab-bar--floating .glass-tab-bar__item.is-active::before{content:'';position:absolute;inset:0;border-radius:inherit;background:radial-gradient(circle at center,color-mix(in srgb,var(--gl-tab-bar-spotlight-color) 28%,transparent) 0,color-mix(in srgb,var(--gl-tab-bar-spotlight-color) 10%,transparent) 55%,transparent 100%);pointer-events:none;z-index:0}.glass-tab-bar--floating .glass-tab-bar__item.is-active .glass-tab-bar__icon::after{display:none}.glass-tab-bar__accessory{width:var(--gl-tab-bar-accessory-size);height:var(--gl-tab-bar-accessory-size);border-radius:var(--gl-radius-pill);background:linear-gradient(to bottom,var(--gl-surface-3) 0,var(--gl-surface-1) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1px solid var(--gl-border-subtle);box-shadow:0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08),var(--gl-inset-subtle);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--gl-transition);outline:0;padding:0;-webkit-tap-highlight-color:transparent;flex-shrink:0}.glass-tab-bar__accessory ::slotted(svg),.glass-tab-bar__accessory svg{width:22px;height:22px;fill:none;stroke:var(--gl-icon-default);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:var(--gl-transition)}.glass-tab-bar__accessory:hover{transform:translateY(-1px)}.glass-tab-bar__accessory:hover ::slotted(svg),.glass-tab-bar__accessory:hover svg{stroke:var(--gl-icon-strong)}.glass-tab-bar__accessory:focus-visible{box-shadow:0 8px 32px rgba(0,0,0,.18),var(--gl-shadow-focus),var(--gl-inset-subtle)}.glass-tab-bar__accessory--accent{background:linear-gradient(135deg,var(--gl-color-primary) 0,color-mix(in srgb,var(--gl-color-primary) 70%,transparent) 100%);border-color:color-mix(in srgb,var(--gl-color-primary) 50%,transparent);box-shadow:0 8px 32px color-mix(in srgb,var(--gl-color-primary) 35%,transparent),var(--gl-inset-medium)}.glass-tab-bar__accessory--accent ::slotted(svg),.glass-tab-bar__accessory--accent svg{stroke:var(--gl-color-on-primary,#ffffff)}.glass-tab-bar__accessory--accent:hover ::slotted(svg),.glass-tab-bar__accessory--accent:hover svg{stroke:var(--gl-color-on-primary,#ffffff)}.glass-tab-bar__accessory--success{background:linear-gradient(135deg,var(--gl-color-success) 0,color-mix(in srgb,var(--gl-color-success) 70%,transparent) 100%);border-color:color-mix(in srgb,var(--gl-color-success) 50%,transparent);box-shadow:0 8px 32px color-mix(in srgb,var(--gl-color-success) 35%,transparent),var(--gl-inset-medium)}.glass-tab-bar__accessory--success ::slotted(svg),.glass-tab-bar__accessory--success svg{stroke:var(--gl-color-on-success,#ffffff)}.glass-tab-bar__accessory--error{background:linear-gradient(135deg,var(--gl-color-error) 0,color-mix(in srgb,var(--gl-color-error) 70%,transparent) 100%);border-color:color-mix(in srgb,var(--gl-color-error) 50%,transparent);box-shadow:0 8px 32px color-mix(in srgb,var(--gl-color-error) 35%,transparent),var(--gl-inset-medium)}.glass-tab-bar__accessory--error ::slotted(svg),.glass-tab-bar__accessory--error svg{stroke:var(--gl-color-on-error,#ffffff)}.glass-accordion{display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-accordion__item{background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);overflow:hidden;transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle)}.glass-accordion__item.is-open{background:var(--gl-surface-3);border-color:var(--gl-border-medium);box-shadow:0 4px 16px rgba(0,0,0,.1),var(--gl-inset-medium)}.glass-accordion__trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--gl-space-sm);padding:var(--gl-space-md) var(--gl-space-lg);background:0 0;border:none;cursor:pointer;font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text);text-align:left;outline:0;transition:var(--gl-transition);-webkit-tap-highlight-color:transparent}.glass-accordion__trigger:hover{color:var(--gl-color-primary)}.glass-accordion__trigger-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0}.glass-accordion__trigger-icon svg{width:18px;height:18px;fill:none;stroke:var(--gl-icon-default);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .3s cubic-bezier(.4, 0, .2, 1)}.glass-accordion__item.is-open .glass-accordion__trigger-icon svg{transform:rotate(180deg);stroke:var(--gl-color-primary)}.glass-accordion__content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4, 0, .2, 1)}.glass-accordion__item.is-open .glass-accordion__content{max-height:500px}.glass-accordion__body{padding:0 var(--gl-space-lg) var(--gl-space-lg);color:var(--gl-accordion-body-color);font-size:var(--gl-font-size-sm);line-height:1.6}.glass-badge{--gl-badge-accent:var(--gl-color-primary);--gl-badge-accent-text:var(--gl-color-primary-on-surface, var(--gl-color-primary));display:inline-flex;align-items:center;gap:var(--gl-space-2xs);padding:var(--gl-space-2xs) var(--gl-space-sm);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-full);font-size:var(--gl-font-size-xs);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);box-shadow:var(--gl-inset-subtle)}.glass-badge--primary{--gl-badge-accent:var(--gl-color-primary);--gl-badge-accent-text:var(--gl-color-primary-on-surface, var(--gl-color-primary));background:linear-gradient(135deg,var(--gl-color-primary-surface,rgba(245,166,35,.25)) 0,color-mix(in srgb,var(--gl-color-primary-dark) 20%,transparent) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-primary-border,var(--gl-border-warm));color:var(--gl-color-primary-on-surface,var(--gl-color-primary))}.glass-badge--success{--gl-badge-accent:var(--gl-color-success);--gl-badge-accent-text:var(--gl-color-success-on-surface, var(--gl-color-success));background:linear-gradient(var(--gl-color-success-surface,rgba(52,199,89,.15)) 0,var(--gl-color-success-surface,rgba(52,199,89,.15)) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-success-border,rgba(52,199,89,.3));color:var(--gl-color-success-on-surface,var(--gl-color-success))}.glass-badge--error{--gl-badge-accent:var(--gl-color-error);--gl-badge-accent-text:var(--gl-color-error-on-surface, var(--gl-color-error));background:linear-gradient(var(--gl-color-error-surface,rgba(255,59,48,.15)) 0,var(--gl-color-error-surface,rgba(255,59,48,.15)) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-error-border,rgba(255,59,48,.3));color:var(--gl-color-error-on-surface,var(--gl-color-error))}.glass-badge--warning{--gl-badge-accent:var(--gl-color-warning);--gl-badge-accent-text:var(--gl-color-warning-on-surface, var(--gl-color-warning));background:linear-gradient(var(--gl-color-warning-surface,rgba(255,204,0,.15)) 0,var(--gl-color-warning-surface,rgba(255,204,0,.15)) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-warning-border,rgba(255,204,0,.3));color:var(--gl-color-warning-on-surface,var(--gl-color-warning))}.glass-badge--interactive{font-family:inherit;-webkit-appearance:none;appearance:none;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-badge--interactive:hover{border-color:color-mix(in srgb,var(--gl-badge-accent) 45%,var(--gl-border-subtle));box-shadow:var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 12%,transparent)}.glass-badge--interactive:active{transform:scale(.96)}.glass-badge--interactive:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-inset-subtle)}.glass-badge--selected{border-color:color-mix(in srgb,var(--gl-badge-accent) 55%,transparent);color:var(--gl-badge-accent-text);box-shadow:var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 22%,transparent)}.glass-badge--interactive.glass-badge--selected:hover{box-shadow:var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 30%,transparent)}.glass-badge--interactive.glass-badge--selected:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 22%,transparent)}.glass-divider{height:1px;border:none;background:linear-gradient(90deg,transparent 0,var(--gl-border-subtle) 20%,var(--gl-border-medium) 50%,var(--gl-border-subtle) 80%,transparent 100%)}.glass-avatar{width:44px;height:44px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-strong);display:flex;align-items:center;justify-content:center;overflow:hidden;box-shadow:var(--gl-shadow-glow),var(--gl-inset-medium);flex-shrink:0;font-size:var(--gl-font-size-btn);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text)}.glass-avatar ::slotted(img),.glass-avatar img{width:100%;height:100%;object-fit:cover}.glass-avatar--sm{width:32px;height:32px;font-size:var(--gl-font-size-xs)}.glass-avatar--lg{width:56px;height:56px;font-size:var(--gl-font-size-lg)}.glass-theme-toggle{width:46px;height:46px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-strong);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--gl-transition);box-shadow:var(--gl-shadow-glow),var(--gl-inset-medium);outline:0;-webkit-tap-highlight-color:transparent}.glass-theme-toggle:hover{background:var(--gl-surface-5);transform:scale(1.05)}.glass-theme-toggle:active{transform:scale(.95)}.glass-theme-toggle svg{width:20px;height:20px;fill:none;stroke:var(--gl-color-text);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-theme-toggle .icon-sun{display:none}.glass-theme-toggle .icon-moon,[data-theme=light] .glass-theme-toggle .icon-sun{display:block}[data-theme=light] .glass-theme-toggle .icon-moon{display:none}.glass-popover-anchor{position:relative;display:inline-block}.glass-popover{position:absolute;top:calc(100% + var(--gl-space-xs));left:50%;transform:translateX(-50%) translateY(-4px) scale(.96);transform-origin:top center;min-width:220px;padding:var(--gl-space-sm);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1px solid var(--gl-border-medium);border-radius:var(--gl-radius-card);box-shadow:var(--gl-shadow-card),var(--gl-inset-strong);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s,transform .18s cubic-bezier(.2,.8,.2,1),visibility 0s linear .18s;z-index:50}.glass-popover.is-open{opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0) scale(1);transition:opacity .18s,transform .22s cubic-bezier(.2,.8,.2,1),visibility linear}.glass-popover--top{top:auto;bottom:calc(100% + var(--gl-space-xs));transform-origin:bottom center}.glass-popover--start{left:0;transform:translateY(-4px) scale(.96);transform-origin:top left}.glass-popover--start.is-open{transform:translateY(0) scale(1)}.glass-popover--end{left:auto;right:0;transform:translateY(-4px) scale(.96);transform-origin:top right}.glass-popover--end.is-open{transform:translateY(0) scale(1)}.glass-list{background:var(--gl-surface-1);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);box-shadow:0 4px 12px rgba(0,0,0,.08),var(--gl-inset-subtle);overflow:hidden;display:flex;flex-direction:column;width:100%;margin:0;padding:0;list-style:none}.glass-list--flush{border-radius:0;border-left:none;border-right:none;margin-left:calc(var(--gl-space-lg) * -1);margin-right:calc(var(--gl-space-lg) * -1)}.glass-list--bare{background:0 0;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-radius:0;box-shadow:none}.glass-list__section-header{padding:var(--gl-space-xs) var(--gl-space-lg) var(--gl-space-2xs);font-size:var(--gl-font-size-xs);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-muted);text-transform:uppercase;letter-spacing:.3px}.glass-list__item{position:relative;display:flex;align-items:center;gap:var(--gl-space-sm);padding:var(--gl-space-md) var(--gl-space-lg);min-height:56px;color:var(--gl-color-text);font-size:var(--gl-font-size-base);text-decoration:none;background:0 0;border:none;width:100%;text-align:left;font-family:inherit;list-style:none}.glass-list__item:not(:last-child)::after{content:'';position:absolute;left:calc(var(--gl-space-lg) + 28px + var(--gl-space-sm));right:var(--gl-space-lg);bottom:0;height:1px;background:var(--gl-border-subtle);pointer-events:none}.glass-list__item:not(:has(.glass-list__leading)):not(:last-child)::after{left:var(--gl-space-lg)}.glass-list__item:has(.glass-list__leading--lg):not(:last-child)::after{left:calc(var(--gl-space-lg) + 40px + var(--gl-space-sm))}.glass-list__item--center{justify-content:center;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__item--center>.glass-list__title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__item--interactive{cursor:pointer;transition:background .15s}.glass-list__item--interactive:focus-visible,.glass-list__item--interactive:hover{background:var(--gl-surface-2);outline:0}.glass-list__item--interactive:active{background:var(--gl-surface-3)}.glass-list__item--danger{color:var(--gl-color-error)}.glass-list__item--danger .glass-list__leading,.glass-list__item--danger .glass-list__title{color:inherit}.glass-list__item--accent{color:var(--gl-color-primary)}.glass-list__item--accent .glass-list__leading,.glass-list__item--accent .glass-list__title{color:inherit}.glass-list__leading{flex-shrink:0;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:var(--gl-icon-strong)}.glass-list__leading ::slotted(svg),.glass-list__leading svg{width:24px;height:24px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-list__leading--lg{width:40px;height:40px;border-radius:var(--gl-radius-xs);overflow:hidden}.glass-list__leading--lg ::slotted(svg),.glass-list__leading--lg svg{width:32px;height:32px}.glass-list__leading--lg ::slotted(img),.glass-list__leading--lg img{width:100%;height:100%;object-fit:cover;display:block}.glass-list__content{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:2px;overflow:hidden}.glass-list__title{font-size:var(--gl-font-size-base);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__subtitle{font-size:var(--gl-font-size-sm);color:var(--gl-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__subtitle--wrap{white-space:normal;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.glass-list__trailing{flex-shrink:0;display:flex;align-items:center;gap:var(--gl-space-xs);color:var(--gl-color-text-muted);font-size:var(--gl-font-size-sm)}.glass-list__trailing ::slotted(svg),.glass-list__trailing svg{width:18px;height:18px;stroke:var(--gl-icon-muted);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-list__value{color:var(--gl-color-text-muted);font-size:var(--gl-font-size-sm);white-space:nowrap}.glass-skeleton{display:flex;flex-direction:column;gap:10px}.glass-skeleton__line{height:12px;border-radius:6px;background:linear-gradient(90deg,var(--gl-surface-1) 0,var(--gl-surface-4) 50%,var(--gl-surface-1) 100%);background-size:200% 100%;animation:1.4s ease-in-out infinite glass-skeleton}.glass-skeleton__line--title{height:18px}@keyframes glass-skeleton{from{background-position:200% 0}to{background-position:-200% 0}}.glass-table-wrap{overflow-x:auto;border-radius:var(--gl-radius-sm)}.glass-table{width:100%;border-collapse:collapse;font-size:var(--gl-font-size-sm);color:var(--gl-color-text)}.glass-table th{text-align:left;padding:8px 10px;white-space:nowrap;font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text-muted);border-bottom:1px solid var(--gl-border-medium)}.glass-table td{padding:9px 10px;vertical-align:top;border-bottom:1px solid var(--gl-border-subtle)}.glass-table tbody tr:last-child td{border-bottom:0}.glass-table tbody tr:hover td{background:var(--gl-surface-1)}.glass-table__num{text-align:right;font-variant-numeric:tabular-nums}.glass-table__muted{color:var(--gl-color-text-muted)}.glass-prose{font-size:var(--gl-font-size-base);line-height:1.6;color:var(--gl-color-text)}.glass-prose>:first-child{margin-top:0}.glass-prose>:last-child{margin-bottom:0}.glass-prose h1,.glass-prose h2,.glass-prose h3{color:var(--gl-color-text-heading);line-height:1.25;margin:1.2em 0 .4em}.glass-prose h1{font-size:var(--gl-font-size-title)}.glass-prose h2{font-size:var(--gl-font-size-modal)}.glass-prose h3{font-size:var(--gl-font-size-lg)}.glass-prose blockquote,.glass-prose ol,.glass-prose p,.glass-prose pre,.glass-prose table,.glass-prose ul{margin:0 0 .9em}.glass-prose ol,.glass-prose ul{padding-left:1.3em}.glass-prose strong{color:var(--gl-color-text-heading)}.glass-prose a{color:var(--gl-color-primary);text-decoration:underline;text-underline-offset:2px}.glass-prose code{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:.9em;background:var(--gl-surface-2);padding:1px 5px;border-radius:4px}.glass-prose pre{padding:12px 14px;overflow-x:auto;background:var(--gl-surface-1);border-radius:var(--gl-radius-sm)}.glass-prose pre code{background:0 0;padding:0}.glass-prose blockquote{padding:8px 14px;border-left:3px solid var(--gl-color-primary);background:var(--gl-surface-1);border-radius:0 var(--gl-radius-xs) var(--gl-radius-xs) 0}.glass-prose img{max-width:100%;height:auto;border-radius:var(--gl-radius-sm)}.glass-prose hr{height:1px;border:0;margin:1.2em 0;background:var(--gl-border-subtle)}.glass-prose table{width:100%;border-collapse:collapse}.glass-prose td,.glass-prose th{padding:6px 8px;text-align:left;border-bottom:1px solid var(--gl-border-subtle)}.glass-segmented{display:inline-flex;gap:4px;padding:4px;max-width:100%;background:var(--gl-surface-1);border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);box-shadow:var(--gl-inset-subtle)}.glass-segmented--full{display:flex}.glass-segmented--full .glass-segmented__item{flex:1 1 0}.glass-segmented--scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}.glass-segmented--scroll::-webkit-scrollbar{display:none}.glass-segmented--wrap{flex-wrap:wrap}.glass-segmented__item{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 14px;border:0;border-radius:var(--gl-radius-sm);background:0 0;color:var(--gl-color-text-muted);font-family:inherit;font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);white-space:nowrap;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-segmented__item:hover{color:var(--gl-color-text)}.glass-segmented__item[aria-pressed=true]{background:var(--gl-surface-5);color:var(--gl-color-text-heading);box-shadow:var(--gl-shadow-btn)}.glass-segmented__item:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-segmented__item[aria-pressed=true]:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-shadow-btn)}.glass-segmented__item:disabled{opacity:.45;cursor:not-allowed}.glass-segmented__dot{width:10px;height:10px;border-radius:50%;background:var(--gl-segmented-tone,currentColor)}.glass-segmented__item--success{--gl-segmented-tone:var(--gl-color-success)}.glass-segmented__item--warning{--gl-segmented-tone:var(--gl-color-warning)}.glass-segmented__item--error{--gl-segmented-tone:var(--gl-color-error)}.glass-steps{display:flex;align-items:center;gap:6px;margin:0;padding:0;list-style:none;min-width:0;container-type:inline-size}.glass-steps__item{display:flex;align-items:center;gap:6px;flex:0 1 auto;min-width:0;font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted);white-space:nowrap}.glass-steps__num{flex:none;width:22px;height:22px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--gl-border-medium);font-size:11px;font-weight:var(--gl-font-weight-semibold)}.glass-steps__num svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}.glass-steps__label{min-width:0;overflow:hidden;text-overflow:ellipsis}.glass-steps__item--done .glass-steps__num{background:var(--gl-color-success-surface);border-color:var(--gl-color-success-border);color:var(--gl-color-success-on-surface)}.glass-steps__item--current{color:var(--gl-color-text-heading)}.glass-steps__item--current .glass-steps__num{background:var(--gl-color-primary);border-color:transparent;color:var(--gl-color-on-primary)}.glass-steps__line{flex:1 1 8px;min-width:8px;height:1px;background:var(--gl-border-subtle)}@container (max-width:360px){.glass-steps__label{display:none}.glass-steps__item--current .glass-steps__label{display:inline}}.glass-sheet-overlay{position:fixed;inset:0;z-index:1000;display:flex;align-items:flex-end;justify-content:center;background:var(--gl-surface-overlay);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));font-family:var(--gl-font-family);-webkit-font-smoothing:antialiased;opacity:0;transition:var(--gl-transition-modal);transition-property:opacity}.glass-sheet-overlay[hidden]{display:none}.glass-sheet-overlay.is-active{opacity:1}.glass-sheet{width:min(100%,560px);max-height:88dvh;overflow:auto;padding:8px var(--gl-space-lg) calc(var(--gl-space-lg) + env(safe-area-inset-bottom,0px));background:linear-gradient(to bottom,var(--gl-card-glow-top) 0,var(--gl-card-glow-bottom) 100%);backdrop-filter:blur(var(--gl-blur-heavy));-webkit-backdrop-filter:blur(var(--gl-blur-heavy));color:var(--gl-color-text);border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-card) var(--gl-radius-card) 0 0;box-shadow:var(--gl-shadow-modal)}.glass-sheet-overlay .glass-sheet{transform:translateY(100%);transition:var(--gl-transition-modal);transition-property:transform}.glass-sheet-overlay.is-active .glass-sheet{transform:translateY(0)}.glass-sheet--inline{border-radius:var(--gl-radius-card);box-shadow:var(--gl-shadow-card)}.glass-sheet__grip{width:40px;height:4px;margin:4px auto 12px;border-radius:2px;background:var(--gl-border-strong)}.glass-sheet__title{margin:0 0 8px;font-size:var(--gl-font-size-modal);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-heading)}.glass-sheet__body{font-size:var(--gl-font-size-base);line-height:1.55}.glass-sheet__actions{display:flex;flex-direction:column;gap:8px;margin-top:16px}@media (prefers-reduced-motion:reduce){.glass-skeleton__line{animation:none}.glass-sheet-overlay,.glass-sheet-overlay .glass-sheet{transition:none}}.glass-empty{display:flex;flex-direction:column;align-items:center;gap:8px;padding:28px 16px;text-align:center}.glass-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:50%;background:var(--gl-surface-2);color:var(--gl-icon-default)}.glass-empty__icon ::slotted(svg),.glass-empty__icon svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-empty__title{margin:4px 0 0;font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-heading)}.glass-empty__text{margin:0;max-width:38ch;font-size:var(--gl-font-size-sm);line-height:1.55;color:var(--gl-color-text-muted)}.glass-empty__action{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:8px}.glass-date-strip{display:flex;gap:6px;padding:4px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}.glass-date-strip::-webkit-scrollbar{display:none}.glass-date-strip__day{-webkit-appearance:none;appearance:none;flex:1 0 44px;min-width:44px;display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 4px 6px;border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-input);background:var(--gl-surface-1);color:var(--gl-color-text);font-family:inherit;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-date-strip__day:hover{background:var(--gl-surface-3)}.glass-date-strip__day[aria-pressed=true]{--gl-date-strip-ink:var(--gl-color-on-primary);background:var(--gl-color-primary);color:var(--gl-color-on-primary);border-color:transparent;box-shadow:var(--gl-shadow-btn-primary)}.glass-date-strip__day:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-date-strip__day[aria-pressed=true]:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-shadow-btn-primary)}.glass-date-strip__day:disabled,.glass-date-strip__day[aria-disabled=true]{opacity:.45;cursor:not-allowed}.glass-date-strip__day:disabled:hover,.glass-date-strip__day[aria-disabled=true]:hover{background:var(--gl-surface-1)}.glass-date-strip__day--today .glass-date-strip__num{text-decoration:underline;text-underline-offset:3px}.glass-date-strip__wd{font-size:var(--gl-font-size-xs);opacity:.75;text-transform:uppercase;letter-spacing:.04em}.glass-date-strip__num{font-size:var(--gl-font-size-lg);font-weight:var(--gl-font-weight-semibold);line-height:1.1}.glass-date-strip__mark{width:6px;height:6px;margin-top:2px;border-radius:50%;background:var(--gl-date-strip-tone,transparent)}.glass-date-strip__mark--primary{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-primary))}.glass-date-strip__mark--success{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-success))}.glass-date-strip__mark--warning{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-warning))}.glass-date-strip__mark--error{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-error))}.glass-calendar{display:block}.glass-calendar__head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.glass-calendar__title{flex:1 1 auto;min-width:0;text-align:center;font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-heading);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.glass-calendar__nav{-webkit-appearance:none;appearance:none;flex:none;width:32px;height:32px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-full);background:var(--gl-surface-1);color:var(--gl-color-text);font-family:inherit;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-calendar__nav:hover{background:var(--gl-surface-3)}.glass-calendar__nav:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-calendar__nav svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-calendar__grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}.glass-calendar__wd{padding:4px 0;text-align:center;font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted);text-transform:uppercase;letter-spacing:.04em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.glass-calendar__day{-webkit-appearance:none;appearance:none;aspect-ratio:1;min-width:0;padding:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;border:1px solid transparent;border-radius:var(--gl-radius-sm);background:0 0;color:var(--gl-color-text);font-family:inherit;font-size:var(--gl-font-size-sm);cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-calendar__day:hover{background:var(--gl-surface-2)}.glass-calendar__day--other{opacity:.35}.glass-calendar__day--today{border-color:var(--gl-border-warm)}.glass-calendar__day[aria-pressed=true]{--gl-calendar-ink:var(--gl-color-on-primary);background:var(--gl-color-primary);color:var(--gl-color-on-primary)}.glass-calendar__day:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-calendar__day:disabled,.glass-calendar__day[aria-disabled=true]{opacity:.45;cursor:not-allowed}.glass-calendar__day:disabled:hover,.glass-calendar__day[aria-disabled=true]:hover{background:0 0}.glass-calendar__marks{display:flex;gap:2px;height:5px}.glass-calendar__mark{width:5px;height:5px;border-radius:50%;background:var(--gl-calendar-tone,transparent)}.glass-calendar__mark--primary{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-primary))}.glass-calendar__mark--success{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-success))}.glass-calendar__mark--warning{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-warning))}.glass-calendar__mark--error{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-error))}.glass-image-picker{display:flex;align-items:center;gap:14px}.glass-image-picker__preview{flex:none;width:72px;height:72px;display:flex;align-items:center;justify-content:center;border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-input);background:var(--gl-surface-2);color:var(--gl-icon-muted);overflow:hidden}.glass-image-picker__preview--round{border-radius:50%}.glass-image-picker__preview img{display:block;width:100%;height:100%;object-fit:cover}.glass-image-picker__preview svg{width:28px;height:28px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-image-picker__meta{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:6px}.glass-image-picker__label{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-strong);overflow-wrap:anywhere}.glass-image-picker__hint{font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted)}.glass-image-picker__actions{display:flex;flex-wrap:wrap;gap:8px}.gl-stack{display:flex;flex-direction:column}.gl-row{display:flex;flex-direction:row;align-items:center}.gl-stack--2xs{gap:var(--gl-space-2xs)}.gl-stack--xs{gap:var(--gl-space-xs)}.gl-stack--sm{gap:var(--gl-space-sm)}.gl-stack--md{gap:var(--gl-space-md)}.gl-stack--lg{gap:var(--gl-space-lg)}.gl-stack--xl{gap:var(--gl-space-xl)}.gl-row--xs{gap:var(--gl-space-xs)}.gl-row--sm{gap:var(--gl-space-sm)}.gl-row--md{gap:var(--gl-space-md)}.gl-text-center{text-align:center}.gl-text-muted{color:var(--gl-color-text-muted)}.gl-text-sm{font-size:var(--gl-font-size-sm)}.gl-mt-sm{margin-top:var(--gl-space-sm)}.gl-mt-md{margin-top:var(--gl-space-md)}.gl-mt-lg{margin-top:var(--gl-space-lg)}.gl-mt-xl{margin-top:var(--gl-space-xl)}.gl-mb-sm{margin-bottom:var(--gl-space-sm)}.gl-mb-md{margin-bottom:var(--gl-space-md)}.gl-mb-lg{margin-bottom:var(--gl-space-lg)}.gl-mb-xl{margin-bottom:var(--gl-space-xl)}.gl-px{padding-left:var(--gl-space-lg);padding-right:var(--gl-space-lg)}.gl-w-full{width:100%}.gl-flex-1{flex:1}svg.glass-icon--fill{fill:currentColor;stroke:none}\n";
|
|
12
|
+
const componentsTail = ".glass-bg{background:radial-gradient(ellipse at 20% 40%,var(--gl-bg-aurora-1) 0,transparent 55%),radial-gradient(ellipse at 80% 65%,var(--gl-bg-aurora-2) 0,transparent 50%),radial-gradient(ellipse at 50% 20%,var(--gl-bg-aurora-3) 0,transparent 50%),linear-gradient(170deg,var(--gl-color-bg-light) 0,var(--gl-color-bg-mid) 50%,var(--gl-color-bg-dark) 100%);position:relative;min-height:100vh;overflow-x:hidden;font-family:var(--gl-font-family);color:var(--gl-color-text);-webkit-font-smoothing:antialiased;transition:background .4s,color .3s;isolation:isolate}.glass-bg::before{content:'';position:absolute;top:20%;left:-30%;width:160%;height:55%;background:radial-gradient(ellipse at 35% 45%,var(--gl-bg-light-streak-1) 0,transparent 50%),radial-gradient(ellipse at 65% 55%,var(--gl-bg-light-streak-2) 0,transparent 45%);transform:rotate(-8deg);pointer-events:none;z-index:-1}.glass-bg::after{content:'';position:absolute;top:40%;right:-20%;width:70%;height:50%;background:radial-gradient(ellipse at center,var(--gl-bg-warm-glow) 0,transparent 65%);pointer-events:none;z-index:-1}.glass-bg>*{position:relative}.glass-bg--has-tab-bar{padding-bottom:var(--gl-tab-bar-height)}.glass-bg--has-tab-bar-floating{padding-bottom:calc(var(--gl-tab-bar-accessory-size) + var(--gl-tab-bar-floating-bottom) + var(--gl-space-md))}.glass-nav{display:flex;justify-content:space-between;align-items:center;padding:0 var(--gl-space-xs)}.glass-pill{width:46px;height:46px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-strong);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--gl-transition);color:var(--gl-color-text);box-shadow:var(--gl-shadow-glow),var(--gl-inset-medium);outline:0;-webkit-tap-highlight-color:transparent}.glass-pill:hover{background:var(--gl-surface-5);transform:scale(1.05)}.glass-pill:active{transform:scale(.95)}.glass-pill ::slotted(svg),.glass-pill svg{width:20px;height:20px;fill:none;stroke:var(--gl-color-text);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}.glass-title{text-align:center;color:var(--gl-color-text-heading);font-size:var(--gl-font-size-title);font-weight:var(--gl-font-weight-semibold);line-height:1.3;text-shadow:0 2px 12px rgba(0,0,0,.15);letter-spacing:-.3px}.glass-card{background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-card);padding:var(--gl-space-3xl) var(--gl-space-xl) var(--gl-space-2xl);box-shadow:var(--gl-shadow-card),var(--gl-inset-strong)}.glass-card--glow{position:relative;overflow:hidden;background:linear-gradient(to bottom,var(--gl-card-glow-top) 0,var(--gl-card-glow-mid) 25%,var(--gl-card-glow-low) 55%,var(--gl-card-glow-bottom) 100%)}.glass-card--glow::before{content:'';position:absolute;top:0;left:10%;right:10%;height:1px;background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.5) 30%,rgba(255,255,255,.6) 50%,rgba(255,255,255,.5) 70%,transparent 100%);z-index:1}.glass-card__icon{display:flex;align-items:center;justify-content:center;margin:0 auto var(--gl-space-lg)}.glass-card__icon svg{width:64px;height:64px;stroke:var(--gl-card-icon-color);stroke-width:1.2;fill:none}.glass-card__text{color:var(--gl-card-text-color);font-size:var(--gl-font-size-base);font-weight:var(--gl-font-weight-normal);line-height:1.55;text-align:center}.glass-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;height:56px;border:none;border-radius:var(--gl-radius-btn);font-family:var(--gl-font-family);font-size:var(--gl-font-size-btn);font-weight:var(--gl-font-weight-semibold);cursor:pointer;transition:var(--gl-transition);outline:0;-webkit-tap-highlight-color:transparent}a.glass-btn{display:inline-flex;text-decoration:none}.glass-btn[hidden]{display:none}.glass-btn ::slotted(svg),.glass-btn svg{width:20px;height:20px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-btn--primary{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-mid) 50%,var(--gl-color-primary-dark) 100%);color:var(--gl-color-on-primary,#fff);border:1px solid var(--gl-border-warm);box-shadow:var(--gl-shadow-btn-primary),var(--gl-inset-strong)}.glass-btn--primary ::slotted(svg),.glass-btn--primary svg{fill:var(--gl-icon-on-primary);stroke:var(--gl-icon-on-primary);stroke-width:0}.glass-btn--primary:hover{transform:translateY(-1px)}.glass-btn--primary:active{transform:translateY(1px)}.glass-btn--secondary{background:linear-gradient(to bottom,var(--gl-surface-milk-strong) 0,var(--gl-surface-milk) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-milk);color:var(--gl-color-text-on-light);box-shadow:var(--gl-shadow-btn),var(--gl-inset-milk)}.glass-btn--secondary ::slotted(svg),.glass-btn--secondary svg{fill:none;stroke:var(--gl-icon-on-secondary);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-btn--secondary:hover{transform:translateY(-1px)}.glass-btn--secondary:active{transform:translateY(1px)}.glass-btn--tertiary{background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);color:var(--gl-color-text-muted);box-shadow:0 4px 12px rgba(0,0,0,.1),var(--gl-inset-subtle)}.glass-btn--tertiary ::slotted(svg),.glass-btn--tertiary svg{fill:none;stroke:var(--gl-icon-on-tertiary);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-btn--tertiary:hover{background:var(--gl-surface-4);color:var(--gl-color-text);transform:translateY(-1px)}.glass-btn--tertiary:active{transform:translateY(1px)}.glass-btn--sm{height:44px;font-size:var(--gl-font-size-sm);border-radius:var(--gl-radius-sm)}.glass-btn--lg{height:64px;font-size:var(--gl-font-size-lg)}.glass-btn--auto{width:auto;padding:0 var(--gl-space-xl)}.glass-status{background:var(--gl-surface-1);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);padding:var(--gl-space-md) var(--gl-space-lg);display:flex;align-items:center;gap:var(--gl-space-sm);box-shadow:0 4px 12px rgba(0,0,0,.08),var(--gl-inset-subtle)}.glass-status ::slotted(svg),.glass-status svg{width:20px;height:20px;flex-shrink:0;stroke:var(--gl-icon-muted);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-status p{color:var(--gl-color-text-muted);font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-normal);line-height:1.45}.glass-input-group{display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-label{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-strong);padding-inline-start:var(--gl-space-2xs)}.glass-input{width:100%;height:52px;padding:0 var(--gl-space-md);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-input);color:var(--gl-color-text);font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);transition:var(--gl-transition);outline:0;box-shadow:var(--gl-inset-subtle);-webkit-tap-highlight-color:transparent}.glass-input::placeholder{color:var(--gl-placeholder)}.glass-input[type=date],.glass-input[type=datetime-local],.glass-input[type=month],.glass-input[type=time]{-webkit-appearance:none;appearance:none}.glass-input::-webkit-date-and-time-value{text-align:start}.glass-input:focus{border-color:var(--gl-border-focus);background:var(--gl-surface-3);box-shadow:var(--gl-shadow-focus),var(--gl-inset-medium)}.glass-input:disabled{opacity:.4;cursor:not-allowed}.glass-input--error{border-color:var(--gl-color-error)}.glass-input--error:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--gl-color-error) 25%,transparent),var(--gl-inset-medium)}.glass-hint{font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted);padding-inline-start:var(--gl-space-2xs)}.glass-hint--error{color:var(--gl-color-error)}.glass-textarea{width:100%;min-height:120px;padding:var(--gl-space-md);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-input);color:var(--gl-color-text);font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);line-height:1.5;resize:vertical;transition:var(--gl-transition);outline:0;box-shadow:var(--gl-inset-subtle)}.glass-textarea::placeholder{color:var(--gl-placeholder)}.glass-textarea:focus{border-color:var(--gl-border-focus);background:var(--gl-surface-3);box-shadow:var(--gl-shadow-focus),var(--gl-inset-medium)}.glass-select{width:100%;height:52px;padding:0 var(--gl-space-3xl) 0 var(--gl-space-md);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-input);color:var(--gl-color-text);font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);transition:var(--gl-transition);outline:0;box-shadow:var(--gl-inset-subtle);cursor:pointer;appearance:none;-webkit-appearance:none;background-image:var(--gl-select-chevron, url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.6)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\"));background-repeat:no-repeat;background-position:right 16px center}.glass-select:dir(rtl){padding:0 var(--gl-space-md) 0 var(--gl-space-3xl);background-position:left 16px center}.glass-select:focus{border-color:var(--gl-border-focus);box-shadow:var(--gl-shadow-focus),var(--gl-inset-medium)}.glass-select option{background:var(--gl-color-bg-mid);color:var(--gl-color-text)}.glass-search{position:relative;display:flex;align-items:center}.glass-search__icon{position:absolute;inset-inline-start:var(--gl-space-md);width:18px;height:18px;stroke:var(--gl-icon-muted)!important;stroke-width:2!important;stroke-linecap:round!important;stroke-linejoin:round!important;fill:none!important;pointer-events:none;z-index:2}.glass-search .glass-input{padding-inline-start:44px;border-radius:var(--gl-radius-full)}.glass-toggle{display:inline-flex;align-items:flex-start;gap:var(--gl-space-sm);cursor:pointer;-webkit-tap-highlight-color:transparent}.glass-toggle__input{position:absolute;z-index:1;opacity:0;cursor:inherit;width:52px;height:30px;margin:0;font:inherit;margin-top:max(0px,calc((1lh - 30px)/ 2))}.glass-toggle__track{position:relative;width:52px;height:30px;background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-full);transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle);flex-shrink:0;margin-top:max(0px,calc((1lh - 30px)/ 2))}.glass-toggle__thumb{position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:var(--gl-radius-pill);background:var(--gl-toggle-thumb-bg);box-shadow:0 2px 6px rgba(0,0,0,.2),var(--gl-inset-milk);transition:var(--gl-transition)}.glass-toggle__input:checked+.glass-toggle__track{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border-color:var(--gl-border-warm)}.glass-toggle__input:checked+.glass-toggle__track .glass-toggle__thumb{transform:translateX(22px)}.glass-toggle__thumb:dir(rtl){left:auto;right:3px}.glass-toggle__input:checked+.glass-toggle__track .glass-toggle__thumb:dir(rtl){transform:translateX(-22px)}.glass-toggle__input:focus-visible+.glass-toggle__track{box-shadow:var(--gl-shadow-focus)}.glass-toggle__label{font-size:var(--gl-font-size-base);color:var(--gl-color-text);user-select:none;margin-top:max(0px,calc((30px - 1lh)/ 2))}.glass-checkbox__label:empty,.glass-radio__label:empty,.glass-toggle__label:empty{display:none}.glass-checkbox{display:inline-flex;align-items:flex-start;gap:var(--gl-space-sm);cursor:pointer;-webkit-tap-highlight-color:transparent}.glass-checkbox__input{position:absolute;z-index:1;opacity:0;cursor:inherit;width:24px;height:24px;margin:0;font:inherit;margin-top:max(0px,calc((1lh - 24px)/ 2))}.glass-checkbox__box{width:24px;height:24px;border-radius:var(--gl-radius-xs);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-medium);display:flex;align-items:center;justify-content:center;transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle);flex-shrink:0;margin-top:max(0px,calc((1lh - 24px)/ 2))}.glass-checkbox__box svg{width:14px;height:14px;stroke:var(--gl-color-on-primary,#ffffff);stroke-width:3;fill:none;stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.5);transition:var(--gl-transition-fast)}.glass-checkbox__input:checked+.glass-checkbox__box{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border-color:var(--gl-border-warm)}.glass-checkbox__input:checked+.glass-checkbox__box svg{opacity:1;transform:scale(1)}.glass-checkbox__input:focus-visible+.glass-checkbox__box{box-shadow:var(--gl-shadow-focus)}.glass-checkbox__label{font-size:var(--gl-font-size-base);color:var(--gl-color-text);user-select:none;margin-top:max(0px,calc((24px - 1lh)/ 2))}.glass-radio{display:inline-flex;align-items:flex-start;gap:var(--gl-space-sm);cursor:pointer;-webkit-tap-highlight-color:transparent}.glass-radio__input{position:absolute;z-index:1;opacity:0;cursor:inherit;width:24px;height:24px;margin:0;font:inherit;margin-top:max(0px,calc((1lh - 24px)/ 2))}.glass-radio__circle{width:24px;height:24px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-medium);display:flex;align-items:center;justify-content:center;transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle);flex-shrink:0;margin-top:max(0px,calc((1lh - 24px)/ 2))}.glass-radio__dot{width:10px;height:10px;border-radius:var(--gl-radius-pill);background:#fff;opacity:0;transform:scale(0);transition:var(--gl-transition-fast)}.glass-radio__input:checked+.glass-radio__circle{background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border-color:var(--gl-border-warm)}.glass-radio__input:checked+.glass-radio__circle .glass-radio__dot{opacity:1;transform:scale(1)}.glass-radio__input:focus-visible+.glass-radio__circle{box-shadow:var(--gl-shadow-focus)}.glass-radio__label{font-size:var(--gl-font-size-base);color:var(--gl-color-text);user-select:none;margin-top:max(0px,calc((24px - 1lh)/ 2))}.glass-range-group{display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-range-header{display:flex;justify-content:space-between;align-items:baseline}.glass-range-value{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-primary);font-variant-numeric:tabular-nums}.glass-range{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:var(--gl-radius-full);background:var(--gl-range-track-bg);border:1px solid var(--gl-range-track-border);outline:0;cursor:pointer}.glass-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;box-sizing:border-box;width:26px;height:26px;border-radius:var(--gl-radius-pill);background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border:2px solid rgba(255,255,255,.5);box-shadow:0 2px 8px color-mix(in srgb,var(--gl-color-primary-mid) 35%,transparent),var(--gl-inset-strong);margin-top:-2px;cursor:pointer;transition:var(--gl-transition)}.glass-range::-webkit-slider-thumb:hover{transform:scale(1.1)}.glass-range::-moz-range-thumb{width:26px;height:26px;border-radius:var(--gl-radius-pill);background:linear-gradient(135deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);border:2px solid rgba(255,255,255,.5);box-shadow:0 2px 8px color-mix(in srgb,var(--gl-color-primary-mid) 35%,transparent);cursor:pointer}.glass-range::-moz-range-track{height:6px;border-radius:var(--gl-radius-full);background:var(--gl-range-track-bg);border:1px solid var(--gl-range-track-border)}.glass-range:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-progress{width:100%;display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-progress__header{display:flex;justify-content:space-between;align-items:baseline}.glass-progress__label{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-strong)}.glass-progress__value{font-size:var(--gl-font-size-xs);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-muted);font-variant-numeric:tabular-nums}.glass-progress__track{width:100%;height:8px;border-radius:var(--gl-radius-full);background:var(--gl-surface-2);border:1px solid var(--gl-border-subtle);overflow:hidden;box-shadow:var(--gl-inset-subtle)}.glass-progress__fill{height:100%;border-radius:var(--gl-radius-full);background:linear-gradient(90deg,var(--gl-color-primary) 0,var(--gl-color-primary-dark) 100%);box-shadow:0 0 8px color-mix(in srgb,var(--gl-color-primary) 30%,transparent),var(--gl-inset-strong);transition:width .5s cubic-bezier(.4, 0, .2, 1);position:relative}.glass-progress__fill::after{content:'';position:absolute;top:0;left:0;right:0;height:50%;border-radius:var(--gl-radius-full);background:linear-gradient(to bottom,rgba(255,255,255,.3) 0,transparent 100%)}.glass-progress--sm .glass-progress__track{height:4px}.glass-progress--lg .glass-progress__track{height:12px}.glass-progress--success .glass-progress__fill{background:linear-gradient(90deg,var(--gl-color-success) 0,var(--gl-color-success-dark,#2da44e) 100%);box-shadow:0 0 8px color-mix(in srgb,var(--gl-color-success) 30%,transparent),var(--gl-inset-strong)}.glass-progress--error .glass-progress__fill{background:linear-gradient(90deg,var(--gl-color-error) 0,var(--gl-color-error-dark,#d63027) 100%);box-shadow:0 0 8px color-mix(in srgb,var(--gl-color-error) 30%,transparent),var(--gl-inset-strong)}.glass-progress__fill:dir(rtl){scale:-1 1}.glass-modal-overlay{position:fixed;inset:0;background:var(--gl-surface-overlay);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));display:flex;align-items:center;justify-content:center;padding:var(--gl-space-lg);z-index:1000;opacity:0;pointer-events:none;transition:var(--gl-transition-modal);font-family:var(--gl-font-family);-webkit-font-smoothing:antialiased}.glass-modal-overlay.is-active{opacity:1;pointer-events:auto}dialog.glass-modal-overlay{width:auto;height:auto;max-width:none;max-height:none;margin:0;border:0;color:inherit}dialog.glass-modal-overlay:not([open]){display:none}dialog.glass-modal-overlay::backdrop{background:0 0}.glass-modal{width:100%;max-width:var(--gl-modal-max-width,340px);background:linear-gradient(to bottom,var(--gl-card-glow-top) 0,var(--gl-card-glow-bottom) 100%);backdrop-filter:blur(var(--gl-blur-heavy));-webkit-backdrop-filter:blur(var(--gl-blur-heavy));border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-card);overflow:hidden;box-shadow:var(--gl-shadow-modal);transform:scale(.9) translateY(20px);transition:var(--gl-transition-modal);position:relative}.glass-modal-overlay.is-active .glass-modal{transform:scale(1) translateY(0)}.glass-modal::before{content:'';position:absolute;top:0;left:10%;right:10%;height:1px;background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.4) 30%,rgba(255,255,255,.5) 50%,rgba(255,255,255,.4) 70%,transparent 100%)}.glass-modal__header{padding:var(--gl-space-xl) var(--gl-space-xl) var(--gl-space-sm);text-align:center}.glass-modal__title{font-size:var(--gl-font-size-modal);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text)}.glass-modal__body{padding:var(--gl-space-sm) var(--gl-space-xl) var(--gl-space-xl);text-align:center}.glass-modal__body p{color:var(--gl-color-text-muted);font-size:var(--gl-font-size-base);line-height:1.55}.glass-modal__footer{display:flex;border-top:1px solid var(--gl-border-subtle)}.glass-modal__action{flex:1;height:52px;background:0 0;border:none;font-family:var(--gl-font-family);font-size:var(--gl-font-size-btn);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text-muted);cursor:pointer;transition:var(--gl-transition-fast);outline:0}.glass-modal__action:hover{background:var(--gl-surface-1)}.glass-modal__action+.glass-modal__action{border-inline-start:1px solid var(--gl-border-subtle)}.glass-modal__action--primary{color:var(--gl-color-primary);font-weight:var(--gl-font-weight-semibold)}.glass-modal__action--danger{color:var(--gl-color-error);font-weight:var(--gl-font-weight-semibold)}.glass-toast{position:fixed;top:var(--gl-toast-top,var(--gl-space-4xl));left:50%;transform:translateX(-50%) translateY(-20px);min-width:280px;max-width:340px;padding:var(--gl-space-md) var(--gl-space-lg);background:linear-gradient(to bottom,var(--gl-surface-4) 0,var(--gl-surface-2) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1px solid var(--gl-border-medium);border-radius:var(--gl-radius-btn);display:flex;align-items:center;gap:var(--gl-space-sm);box-shadow:var(--gl-shadow-toast),var(--gl-inset-medium);z-index:1100;opacity:0;pointer-events:none;transition:var(--gl-transition-modal);font-family:var(--gl-font-family);-webkit-font-smoothing:antialiased}.glass-toast.is-visible{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}.glass-toast__icon{width:22px;height:22px;flex-shrink:0;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-toast__icon ::slotted(svg){display:block;width:100%;height:100%}.glass-toast--success .glass-toast__icon{stroke:var(--gl-color-success)}.glass-toast--error .glass-toast__icon{stroke:var(--gl-color-error)}.glass-toast--warning .glass-toast__icon{stroke:var(--gl-color-warning)}.glass-toast__text{flex:1 1 auto;min-width:0;font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);line-height:1.4}.glass-toast:has(.glass-toast__action){width:max-content;max-width:min(480px,calc(100% - 2 * var(--gl-space-md)))}.glass-toast--success{--gl-toast-action-surface:var(--gl-color-success-surface);--gl-toast-action-border:var(--gl-color-success-border);--gl-toast-action-ink:var(--gl-color-success-on-surface)}.glass-toast--error{--gl-toast-action-surface:var(--gl-color-error-surface);--gl-toast-action-border:var(--gl-color-error-border);--gl-toast-action-ink:var(--gl-color-error-on-surface)}.glass-toast--warning{--gl-toast-action-surface:var(--gl-color-warning-surface);--gl-toast-action-border:var(--gl-color-warning-border);--gl-toast-action-ink:var(--gl-color-warning-on-surface)}.glass-toast__action,.glass-toast__close{-webkit-appearance:none;appearance:none;flex:none;position:relative;font:inherit;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-toast__action{height:32px;padding:0 14px;border:1px solid var(--gl-toast-action-border,var(--gl-color-primary-border));border-radius:var(--gl-radius-full);background:linear-gradient(var(--gl-toast-action-surface,var(--gl-color-primary-surface)),var(--gl-toast-action-surface,var(--gl-color-primary-surface))),linear-gradient(var(--gl-state-scrim),var(--gl-state-scrim)),var(--gl-state-scrim);color:var(--gl-toast-action-ink,var(--gl-color-primary-on-surface));font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-semibold);white-space:nowrap}.glass-toast__action::after{content:\"\";position:absolute;inset:-6px 0}.glass-toast__action:hover{box-shadow:inset 0 0 0 100px color-mix(in srgb,var(--gl-toast-action-ink,var(--gl-color-primary-on-surface)) 10%,transparent)}.glass-toast__action:active{transform:scale(.96)}.glass-toast__close{width:28px;height:28px;margin-block:0;margin-inline:-4px -8px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:0 0;color:var(--gl-color-text-muted)}.glass-toast__close::after{content:\"\";position:absolute;inset:-8px}.glass-toast__close:hover{background:var(--gl-surface-3);color:var(--gl-color-text)}.glass-toast__close svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}.glass-toast__action:focus-visible,.glass-toast__close:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-tab-bar{position:fixed;bottom:0;left:0;right:0;height:var(--gl-tab-bar-height);background:linear-gradient(to bottom,var(--gl-surface-3) 0,var(--gl-surface-1) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border-top:1px solid var(--gl-border-subtle);display:flex;justify-content:space-around;align-items:flex-start;padding-top:var(--gl-space-xs);padding-bottom:env(safe-area-inset-bottom,8px);z-index:900;box-shadow:0 -4px 20px rgba(0,0,0,.08),var(--gl-inset-subtle)}.glass-tab-bar__item{display:flex;flex-direction:column;align-items:center;gap:var(--gl-space-2xs);padding:var(--gl-space-2xs) var(--gl-space-sm);background:0 0;border:none;cursor:pointer;transition:var(--gl-transition);outline:0;-webkit-tap-highlight-color:transparent;min-width:60px}.glass-tab-bar__icon{width:24px;height:24px;display:flex;align-items:center;justify-content:center;position:relative}.glass-tab-bar__icon svg{width:24px;height:24px;fill:none;stroke:var(--gl-icon-muted);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:var(--gl-transition)}.glass-tab-bar__label{font-size:10px;font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-muted);transition:var(--gl-transition);letter-spacing:.2px}.glass-tab-bar__item.is-active .glass-tab-bar__icon svg{stroke:var(--gl-color-primary);filter:drop-shadow(0 0 6px color-mix(in srgb, var(--gl-color-primary) 35%, transparent))}.glass-tab-bar__item.is-active .glass-tab-bar__label{color:var(--gl-color-primary)}.glass-tab-bar__item.is-active .glass-tab-bar__icon::after{content:'';position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);width:4px;height:4px;border-radius:var(--gl-radius-pill);background:var(--gl-color-primary);box-shadow:0 0 6px color-mix(in srgb,var(--gl-color-primary) 50%,transparent)}.glass-tab-bar__item:not(.is-active):hover .glass-tab-bar__icon svg{stroke:var(--gl-icon-default)}.glass-tab-bar__item:not(.is-active):hover .glass-tab-bar__label{color:var(--gl-icon-default)}.glass-tab-bar__badge{position:absolute;top:-4px;inset-inline-end:-8px;min-width:16px;height:16px;padding:0 4px;border-radius:var(--gl-radius-full);background:var(--gl-color-error-dark,#d63027);color:#fff;font-size:10px;font-weight:var(--gl-font-weight-semibold);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px color-mix(in srgb,var(--gl-color-error) 40%,transparent)}.glass-tab-bar-dock{position:fixed;left:50%;bottom:calc(var(--gl-tab-bar-floating-bottom) + env(safe-area-inset-bottom,0px));transform:translateX(-50%);display:flex;align-items:center;gap:var(--gl-tab-bar-floating-gap);z-index:900;max-width:calc(100vw - 2 * var(--gl-space-md))}.glass-tab-bar-dock--accessory-left{flex-direction:row-reverse}.glass-tab-bar.glass-tab-bar--floating{position:static;left:auto;right:auto;bottom:auto;height:auto;width:max-content;padding:var(--gl-tab-bar-floating-padding);border-radius:var(--gl-tab-bar-floating-radius);border:1px solid var(--gl-border-subtle);background:linear-gradient(to bottom,var(--gl-surface-3) 0,var(--gl-surface-1) 100%);box-shadow:0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08),var(--gl-inset-subtle);display:flex;justify-content:flex-start;align-items:center;gap:var(--gl-space-2xs)}.glass-tab-bar--floating .glass-tab-bar__item{position:relative;border-radius:var(--gl-radius-full);padding:var(--gl-space-2xs) var(--gl-space-sm);min-width:auto;align-items:center}.glass-tab-bar--floating .glass-tab-bar__item>*{position:relative;z-index:1}.glass-tab-bar--floating .glass-tab-bar__item.is-active::before{content:'';position:absolute;inset:0;border-radius:inherit;background:radial-gradient(circle at center,color-mix(in srgb,var(--gl-tab-bar-spotlight-color) 28%,transparent) 0,color-mix(in srgb,var(--gl-tab-bar-spotlight-color) 10%,transparent) 55%,transparent 100%);pointer-events:none;z-index:0}.glass-tab-bar--floating .glass-tab-bar__item.is-active .glass-tab-bar__icon::after{display:none}.glass-tab-bar__accessory{width:var(--gl-tab-bar-accessory-size);height:var(--gl-tab-bar-accessory-size);border-radius:var(--gl-radius-pill);background:linear-gradient(to bottom,var(--gl-surface-3) 0,var(--gl-surface-1) 100%);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1px solid var(--gl-border-subtle);box-shadow:0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08),var(--gl-inset-subtle);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--gl-transition);outline:0;padding:0;-webkit-tap-highlight-color:transparent;flex-shrink:0}.glass-tab-bar__accessory ::slotted(svg),.glass-tab-bar__accessory svg{width:22px;height:22px;fill:none;stroke:var(--gl-icon-default);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:var(--gl-transition)}.glass-tab-bar__accessory:hover{transform:translateY(-1px)}.glass-tab-bar__accessory:hover ::slotted(svg),.glass-tab-bar__accessory:hover svg{stroke:var(--gl-icon-strong)}.glass-tab-bar__accessory:focus-visible{box-shadow:0 8px 32px rgba(0,0,0,.18),var(--gl-shadow-focus),var(--gl-inset-subtle)}.glass-tab-bar__accessory--accent{background:linear-gradient(135deg,var(--gl-color-primary) 0,color-mix(in srgb,var(--gl-color-primary) 70%,transparent) 100%);border-color:color-mix(in srgb,var(--gl-color-primary) 50%,transparent);box-shadow:0 8px 32px color-mix(in srgb,var(--gl-color-primary) 35%,transparent),var(--gl-inset-medium)}.glass-tab-bar__accessory--accent ::slotted(svg),.glass-tab-bar__accessory--accent svg{stroke:var(--gl-color-on-primary,#ffffff)}.glass-tab-bar__accessory--accent:hover ::slotted(svg),.glass-tab-bar__accessory--accent:hover svg{stroke:var(--gl-color-on-primary,#ffffff)}.glass-tab-bar__accessory--success{background:linear-gradient(135deg,var(--gl-color-success) 0,color-mix(in srgb,var(--gl-color-success) 70%,transparent) 100%);border-color:color-mix(in srgb,var(--gl-color-success) 50%,transparent);box-shadow:0 8px 32px color-mix(in srgb,var(--gl-color-success) 35%,transparent),var(--gl-inset-medium)}.glass-tab-bar__accessory--success ::slotted(svg),.glass-tab-bar__accessory--success svg{stroke:var(--gl-color-on-success,#ffffff)}.glass-tab-bar__accessory--error{background:linear-gradient(135deg,var(--gl-color-error) 0,color-mix(in srgb,var(--gl-color-error) 70%,transparent) 100%);border-color:color-mix(in srgb,var(--gl-color-error) 50%,transparent);box-shadow:0 8px 32px color-mix(in srgb,var(--gl-color-error) 35%,transparent),var(--gl-inset-medium)}.glass-tab-bar__accessory--error ::slotted(svg),.glass-tab-bar__accessory--error svg{stroke:var(--gl-color-on-error,#ffffff)}.glass-accordion{display:flex;flex-direction:column;gap:var(--gl-space-xs)}.glass-accordion__item{background:var(--gl-surface-2);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);overflow:hidden;transition:var(--gl-transition);box-shadow:var(--gl-inset-subtle)}.glass-accordion__item.is-open{background:var(--gl-surface-3);border-color:var(--gl-border-medium);box-shadow:0 4px 16px rgba(0,0,0,.1),var(--gl-inset-medium)}.glass-accordion__trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--gl-space-sm);padding:var(--gl-space-md) var(--gl-space-lg);background:0 0;border:none;cursor:pointer;font-family:var(--gl-font-family);font-size:var(--gl-font-size-base);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text);text-align:start;outline:0;transition:var(--gl-transition);-webkit-tap-highlight-color:transparent}.glass-accordion__trigger:hover{color:var(--gl-color-primary)}.glass-accordion__trigger-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0}.glass-accordion__trigger-icon svg{width:18px;height:18px;fill:none;stroke:var(--gl-icon-default);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .3s cubic-bezier(.4, 0, .2, 1)}.glass-accordion__item.is-open .glass-accordion__trigger-icon svg{transform:rotate(180deg);stroke:var(--gl-color-primary)}.glass-accordion__content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4, 0, .2, 1)}.glass-accordion__item.is-open .glass-accordion__content{max-height:500px}.glass-accordion__body{padding:0 var(--gl-space-lg) var(--gl-space-lg);color:var(--gl-accordion-body-color);font-size:var(--gl-font-size-sm);line-height:1.6}.glass-badge{--gl-badge-accent:var(--gl-color-primary);--gl-badge-accent-text:var(--gl-color-primary-on-surface, var(--gl-color-primary));display:inline-flex;align-items:center;gap:var(--gl-space-2xs);padding:var(--gl-space-2xs) var(--gl-space-sm);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-full);font-size:var(--gl-font-size-xs);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);box-shadow:var(--gl-inset-subtle)}.glass-badge--primary{--gl-badge-accent:var(--gl-color-primary);--gl-badge-accent-text:var(--gl-color-primary-on-surface, var(--gl-color-primary));background:linear-gradient(135deg,var(--gl-color-primary-surface,rgba(245,166,35,.25)) 0,color-mix(in srgb,var(--gl-color-primary-dark) 20%,transparent) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-primary-border,var(--gl-border-warm));color:var(--gl-color-primary-on-surface,var(--gl-color-primary))}.glass-badge--success{--gl-badge-accent:var(--gl-color-success);--gl-badge-accent-text:var(--gl-color-success-on-surface, var(--gl-color-success));background:linear-gradient(var(--gl-color-success-surface,rgba(52,199,89,.15)) 0,var(--gl-color-success-surface,rgba(52,199,89,.15)) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-success-border,rgba(52,199,89,.3));color:var(--gl-color-success-on-surface,var(--gl-color-success))}.glass-badge--error{--gl-badge-accent:var(--gl-color-error);--gl-badge-accent-text:var(--gl-color-error-on-surface, var(--gl-color-error));background:linear-gradient(var(--gl-color-error-surface,rgba(255,59,48,.15)) 0,var(--gl-color-error-surface,rgba(255,59,48,.15)) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-error-border,rgba(255,59,48,.3));color:var(--gl-color-error-on-surface,var(--gl-color-error))}.glass-badge--warning{--gl-badge-accent:var(--gl-color-warning);--gl-badge-accent-text:var(--gl-color-warning-on-surface, var(--gl-color-warning));background:linear-gradient(var(--gl-color-warning-surface,rgba(255,204,0,.15)) 0,var(--gl-color-warning-surface,rgba(255,204,0,.15)) 100%),var(--gl-state-scrim,transparent);border-color:var(--gl-color-warning-border,rgba(255,204,0,.3));color:var(--gl-color-warning-on-surface,var(--gl-color-warning))}.glass-badge--interactive{font-family:inherit;-webkit-appearance:none;appearance:none;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-badge--interactive:hover{border-color:color-mix(in srgb,var(--gl-badge-accent) 45%,var(--gl-border-subtle));box-shadow:var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 12%,transparent)}.glass-badge--interactive:active{transform:scale(.96)}.glass-badge--interactive:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-inset-subtle)}.glass-badge--selected{border-color:color-mix(in srgb,var(--gl-badge-accent) 55%,transparent);color:var(--gl-badge-accent-text);box-shadow:var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 22%,transparent)}.glass-badge--interactive.glass-badge--selected:hover{box-shadow:var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 30%,transparent)}.glass-badge--interactive.glass-badge--selected:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-inset-subtle),inset 0 0 0 100px color-mix(in srgb,var(--gl-badge-accent) 22%,transparent)}.glass-divider{height:1px;border:none;background:linear-gradient(90deg,transparent 0,var(--gl-border-subtle) 20%,var(--gl-border-medium) 50%,var(--gl-border-subtle) 80%,transparent 100%)}.glass-avatar{width:44px;height:44px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));border:1.5px solid var(--gl-border-strong);display:flex;align-items:center;justify-content:center;overflow:hidden;box-shadow:var(--gl-shadow-glow),var(--gl-inset-medium);flex-shrink:0;font-size:var(--gl-font-size-btn);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text)}.glass-avatar ::slotted(img),.glass-avatar img{width:100%;height:100%;object-fit:cover}.glass-avatar--sm{width:32px;height:32px;font-size:var(--gl-font-size-xs)}.glass-avatar--lg{width:56px;height:56px;font-size:var(--gl-font-size-lg)}.glass-theme-toggle{width:46px;height:46px;border-radius:var(--gl-radius-pill);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1.5px solid var(--gl-border-strong);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--gl-transition);box-shadow:var(--gl-shadow-glow),var(--gl-inset-medium);outline:0;-webkit-tap-highlight-color:transparent}.glass-theme-toggle:hover{background:var(--gl-surface-5);transform:scale(1.05)}.glass-theme-toggle:active{transform:scale(.95)}.glass-theme-toggle svg{width:20px;height:20px;fill:none;stroke:var(--gl-color-text);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-theme-toggle .icon-sun{display:none}.glass-theme-toggle .icon-moon,[data-theme=light] .glass-theme-toggle .icon-sun{display:block}[data-theme=light] .glass-theme-toggle .icon-moon{display:none}.glass-popover-anchor{position:relative;display:inline-block}.glass-popover{position:absolute;top:calc(100% + var(--gl-space-xs));left:50%;transform:translateX(-50%) translateY(-4px) scale(.96);transform-origin:top center;min-width:220px;padding:var(--gl-space-sm);background:var(--gl-surface-3);backdrop-filter:blur(var(--gl-blur));-webkit-backdrop-filter:blur(var(--gl-blur));border:1px solid var(--gl-border-medium);border-radius:var(--gl-radius-card);box-shadow:var(--gl-shadow-card),var(--gl-inset-strong);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s,transform .18s cubic-bezier(.2,.8,.2,1),visibility 0s linear .18s;z-index:50}.glass-popover.is-open{opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0) scale(1);transition:opacity .18s,transform .22s cubic-bezier(.2,.8,.2,1),visibility linear}.glass-popover--top{top:auto;bottom:calc(100% + var(--gl-space-xs));transform-origin:bottom center}.glass-popover--start{inset-inline-start:0;inset-inline-end:auto;transform:translateY(-4px) scale(.96);transform-origin:top left}.glass-popover--start:dir(rtl){transform-origin:top right}.glass-popover--start.is-open{transform:translateY(0) scale(1)}.glass-popover--end{inset-inline-start:auto;inset-inline-end:0;transform:translateY(-4px) scale(.96);transform-origin:top right}.glass-popover--end:dir(rtl){transform-origin:top left}.glass-popover--end.is-open{transform:translateY(0) scale(1)}.glass-list{background:var(--gl-surface-1);backdrop-filter:blur(var(--gl-blur-light));-webkit-backdrop-filter:blur(var(--gl-blur-light));border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);box-shadow:0 4px 12px rgba(0,0,0,.08),var(--gl-inset-subtle);overflow:hidden;display:flex;flex-direction:column;width:100%;margin:0;padding:0;list-style:none}.glass-list--flush{border-radius:0;border-left:none;border-right:none;margin-left:calc(var(--gl-space-lg) * -1);margin-right:calc(var(--gl-space-lg) * -1)}.glass-list--bare{background:0 0;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-radius:0;box-shadow:none}.glass-list__section-header{padding:var(--gl-space-xs) var(--gl-space-lg) var(--gl-space-2xs);font-size:var(--gl-font-size-xs);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-muted);text-transform:uppercase;letter-spacing:.3px}.glass-list__item{position:relative;display:flex;align-items:center;gap:var(--gl-space-sm);padding:var(--gl-space-md) var(--gl-space-lg);min-height:56px;color:var(--gl-color-text);font-size:var(--gl-font-size-base);text-decoration:none;background:0 0;border:none;width:100%;text-align:start;font-family:inherit;list-style:none}.glass-list__item:not(:last-child)::after{content:'';position:absolute;inset-inline-start:calc(var(--gl-space-lg) + 28px + var(--gl-space-sm));inset-inline-end:var(--gl-space-lg);bottom:0;height:1px;background:var(--gl-border-subtle);pointer-events:none}.glass-list__item:not(:has(.glass-list__leading:not([hidden]))):not(:last-child)::after{inset-inline-start:var(--gl-space-lg)}.glass-list__item:has(.glass-list__leading--lg:not([hidden])):not(:last-child)::after{inset-inline-start:calc(var(--gl-space-lg) + 40px + var(--gl-space-sm))}.glass-list__item--center{justify-content:center;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__item--center>.glass-list__title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__item--interactive{cursor:pointer;transition:background .15s}.glass-list__item--interactive:focus-visible,.glass-list__item--interactive:hover{background:var(--gl-surface-2);outline:0}.glass-list__item--interactive:active{background:var(--gl-surface-3)}.glass-list__item--danger{color:var(--gl-color-error)}.glass-list__item--danger .glass-list__leading,.glass-list__item--danger .glass-list__title{color:inherit}.glass-list__item--accent{color:var(--gl-color-primary)}.glass-list__item--accent .glass-list__leading,.glass-list__item--accent .glass-list__title{color:inherit}.glass-list__leading{flex-shrink:0;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:var(--gl-icon-strong)}.glass-list__leading[hidden],.glass-list__trailing[hidden]{display:none}.glass-list__leading ::slotted(svg),.glass-list__leading svg{width:24px;height:24px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-list__leading--lg{width:40px;height:40px;border-radius:var(--gl-radius-xs);overflow:hidden}.glass-list__leading--lg ::slotted(svg),.glass-list__leading--lg svg{width:32px;height:32px}.glass-list__leading--lg ::slotted(img),.glass-list__leading--lg img{width:100%;height:100%;object-fit:cover;display:block}.glass-list__content{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:2px;overflow:hidden}.glass-list__title{font-size:var(--gl-font-size-base);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__subtitle{font-size:var(--gl-font-size-sm);color:var(--gl-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.glass-list__subtitle--wrap{white-space:normal;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.glass-list__trailing{flex-shrink:0;display:flex;align-items:center;gap:var(--gl-space-xs);color:var(--gl-color-text-muted);font-size:var(--gl-font-size-sm)}.glass-list__trailing ::slotted(svg),.glass-list__trailing svg{width:18px;height:18px;stroke:var(--gl-icon-muted);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.glass-list__value{color:var(--gl-color-text-muted);font-size:var(--gl-font-size-sm);white-space:nowrap}.glass-skeleton{display:flex;flex-direction:column;gap:10px}.glass-skeleton__line{height:12px;border-radius:6px;background:linear-gradient(90deg,var(--gl-surface-1) 0,var(--gl-surface-4) 50%,var(--gl-surface-1) 100%);background-size:200% 100%;animation:1.4s ease-in-out infinite glass-skeleton}.glass-skeleton__line--title{height:18px}@keyframes glass-skeleton{from{background-position:200% 0}to{background-position:-200% 0}}.glass-table-wrap{overflow-x:auto;border-radius:var(--gl-radius-sm)}.glass-table{width:100%;border-collapse:collapse;font-size:var(--gl-font-size-sm);color:var(--gl-color-text)}.glass-table th{text-align:start;padding:8px 10px;white-space:nowrap;font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text-muted);border-bottom:1px solid var(--gl-border-medium)}.glass-table td{padding:9px 10px;vertical-align:top;border-bottom:1px solid var(--gl-border-subtle)}.glass-table tbody tr:last-child td{border-bottom:0}.glass-table tbody tr:hover td{background:var(--gl-surface-1)}.glass-table__num{text-align:end;font-variant-numeric:tabular-nums}.glass-table__muted{color:var(--gl-color-text-muted)}.glass-prose{font-size:var(--gl-font-size-base);line-height:1.6;color:var(--gl-color-text)}.glass-prose>:first-child{margin-top:0}.glass-prose>:last-child{margin-bottom:0}.glass-prose h1,.glass-prose h2,.glass-prose h3{color:var(--gl-color-text-heading);line-height:1.25;margin:1.2em 0 .4em}.glass-prose h1{font-size:var(--gl-font-size-title)}.glass-prose h2{font-size:var(--gl-font-size-modal)}.glass-prose h3{font-size:var(--gl-font-size-lg)}.glass-prose blockquote,.glass-prose ol,.glass-prose p,.glass-prose pre,.glass-prose table,.glass-prose ul{margin:0 0 .9em}.glass-prose ol,.glass-prose ul{padding-inline-start:1.3em}.glass-prose strong{color:var(--gl-color-text-heading)}.glass-prose a{color:var(--gl-color-primary);text-decoration:underline;text-underline-offset:2px}.glass-prose code{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:.9em;background:var(--gl-surface-2);padding:1px 5px;border-radius:4px}.glass-prose pre{padding:12px 14px;overflow-x:auto;background:var(--gl-surface-1);border-radius:var(--gl-radius-sm)}.glass-prose pre code{background:0 0;padding:0}.glass-prose blockquote{padding:8px 14px;border-inline-start:3px solid var(--gl-color-primary);background:var(--gl-surface-1);border-start-start-radius:0;border-end-start-radius:0;border-start-end-radius:var(--gl-radius-xs);border-end-end-radius:var(--gl-radius-xs)}.glass-prose img{max-width:100%;height:auto;border-radius:var(--gl-radius-sm)}.glass-prose hr{height:1px;border:0;margin:1.2em 0;background:var(--gl-border-subtle)}.glass-prose table{width:100%;border-collapse:collapse}.glass-prose td,.glass-prose th{padding:6px 8px;text-align:start;border-bottom:1px solid var(--gl-border-subtle)}.glass-segmented{display:inline-flex;gap:4px;padding:4px;max-width:100%;background:var(--gl-surface-1);border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-btn);box-shadow:var(--gl-inset-subtle)}.glass-segmented--full{display:flex}.glass-segmented--full .glass-segmented__item{flex:1 1 0}.glass-segmented--scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}.glass-segmented--scroll::-webkit-scrollbar{display:none}.glass-segmented--wrap{flex-wrap:wrap}.glass-segmented__item{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 14px;border:0;border-radius:var(--gl-radius-sm);background:0 0;color:var(--gl-color-text-muted);font-family:inherit;font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);white-space:nowrap;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-segmented__item:hover{color:var(--gl-color-text)}.glass-segmented__item[aria-pressed=true]{background:var(--gl-surface-5);color:var(--gl-color-text-heading);box-shadow:var(--gl-shadow-btn)}.glass-segmented__item:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-segmented__item[aria-pressed=true]:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-shadow-btn)}.glass-segmented__item:disabled{opacity:.45;cursor:not-allowed}.glass-segmented__dot{width:10px;height:10px;border-radius:50%;background:var(--gl-segmented-tone,currentColor)}.glass-segmented__item--success{--gl-segmented-tone:var(--gl-color-success)}.glass-segmented__item--warning{--gl-segmented-tone:var(--gl-color-warning)}.glass-segmented__item--error{--gl-segmented-tone:var(--gl-color-error)}.glass-steps{display:flex;align-items:center;gap:6px;margin:0;padding:0;list-style:none;min-width:0;container-type:inline-size}.glass-steps__item{display:flex;align-items:center;gap:6px;flex:0 1 auto;min-width:0;font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted);white-space:nowrap}.glass-steps__num{flex:none;width:22px;height:22px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--gl-border-medium);font-size:11px;font-weight:var(--gl-font-weight-semibold)}.glass-steps__num svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}.glass-steps__label{min-width:0;overflow:hidden;text-overflow:ellipsis}.glass-steps__item--done .glass-steps__num{background:var(--gl-color-success-surface);border-color:var(--gl-color-success-border);color:var(--gl-color-success-on-surface)}.glass-steps__item--current{color:var(--gl-color-text-heading)}.glass-steps__item--current .glass-steps__num{background:var(--gl-color-primary);border-color:transparent;color:var(--gl-color-on-primary)}.glass-steps__line{flex:1 1 8px;min-width:8px;height:1px;background:var(--gl-border-subtle)}@container (max-width:360px){.glass-steps__label{display:none}.glass-steps__item--current .glass-steps__label{display:inline}}.glass-sheet-overlay{position:fixed;inset:0;z-index:1000;display:flex;align-items:flex-end;justify-content:center;background:var(--gl-surface-overlay);backdrop-filter:blur(var(--gl-blur-soft));-webkit-backdrop-filter:blur(var(--gl-blur-soft));font-family:var(--gl-font-family);-webkit-font-smoothing:antialiased;opacity:0;transition:var(--gl-transition-modal);transition-property:opacity}.glass-sheet-overlay[hidden]{display:none}.glass-sheet-overlay.is-active{opacity:1}.glass-sheet{width:min(100%,560px);max-height:88dvh;overflow:auto;padding:8px var(--gl-space-lg) calc(var(--gl-space-lg) + env(safe-area-inset-bottom,0px));background:linear-gradient(to bottom,var(--gl-card-glow-top) 0,var(--gl-card-glow-bottom) 100%);backdrop-filter:blur(var(--gl-blur-heavy));-webkit-backdrop-filter:blur(var(--gl-blur-heavy));color:var(--gl-color-text);border:1.5px solid var(--gl-border-medium);border-radius:var(--gl-radius-card) var(--gl-radius-card) 0 0;box-shadow:var(--gl-shadow-modal)}.glass-sheet-overlay .glass-sheet{transform:translateY(100%);transition:var(--gl-transition-modal);transition-property:transform}.glass-sheet-overlay.is-active .glass-sheet{transform:translateY(0)}.glass-sheet--inline{border-radius:var(--gl-radius-card);box-shadow:var(--gl-shadow-card)}.glass-sheet__grip{width:40px;height:4px;margin:4px auto 12px;border-radius:2px;background:var(--gl-border-strong)}.glass-sheet__title{margin:0 0 8px;font-size:var(--gl-font-size-modal);font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-heading)}.glass-sheet__body{font-size:var(--gl-font-size-base);line-height:1.55}.glass-sheet__actions{display:flex;flex-direction:column;gap:8px;margin-top:16px}@media (prefers-reduced-motion:reduce){.glass-skeleton__line{animation:none}.glass-sheet-overlay,.glass-sheet-overlay .glass-sheet{transition:none}}.glass-empty{display:flex;flex-direction:column;align-items:center;gap:8px;padding:28px 16px;text-align:center}.glass-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:50%;background:var(--gl-surface-2);color:var(--gl-icon-default)}.glass-empty__icon ::slotted(svg),.glass-empty__icon svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-empty__title{margin:4px 0 0;font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-heading)}.glass-empty__text{margin:0;max-width:38ch;font-size:var(--gl-font-size-sm);line-height:1.55;color:var(--gl-color-text-muted)}.glass-empty__action{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:8px}.glass-date-strip{display:flex;gap:6px;padding:4px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}.glass-date-strip::-webkit-scrollbar{display:none}.glass-date-strip__day{-webkit-appearance:none;appearance:none;flex:1 0 44px;min-width:44px;display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 4px 6px;border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-input);background:var(--gl-surface-1);color:var(--gl-color-text);font-family:inherit;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-date-strip__day:hover{background:var(--gl-surface-3)}.glass-date-strip__day[aria-pressed=true]{--gl-date-strip-ink:var(--gl-color-on-primary);background:var(--gl-color-primary);color:var(--gl-color-on-primary);border-color:transparent;box-shadow:var(--gl-shadow-btn-primary)}.glass-date-strip__day:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-date-strip__day[aria-pressed=true]:focus-visible{box-shadow:var(--gl-shadow-focus),var(--gl-shadow-btn-primary)}.glass-date-strip__day:disabled,.glass-date-strip__day[aria-disabled=true]{opacity:.45;cursor:not-allowed}.glass-date-strip__day:disabled:hover,.glass-date-strip__day[aria-disabled=true]:hover{background:var(--gl-surface-1)}.glass-date-strip__day--today .glass-date-strip__num{text-decoration:underline;text-underline-offset:3px}.glass-date-strip__wd{font-size:var(--gl-font-size-xs);opacity:.75;text-transform:uppercase;letter-spacing:.04em}.glass-date-strip__num{font-size:var(--gl-font-size-lg);font-weight:var(--gl-font-weight-semibold);line-height:1.1}.glass-date-strip__mark{width:6px;height:6px;margin-top:2px;border-radius:50%;background:var(--gl-date-strip-tone,transparent)}.glass-date-strip__mark--primary{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-primary))}.glass-date-strip__mark--success{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-success))}.glass-date-strip__mark--warning{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-warning))}.glass-date-strip__mark--error{--gl-date-strip-tone:var(--gl-date-strip-ink, var(--gl-color-error))}.glass-calendar{display:block}.glass-calendar__head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.glass-calendar__title{flex:1 1 auto;min-width:0;text-align:center;font-weight:var(--gl-font-weight-semibold);color:var(--gl-color-text-heading);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.glass-calendar__nav{-webkit-appearance:none;appearance:none;flex:none;width:32px;height:32px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-full);background:var(--gl-surface-1);color:var(--gl-color-text);font-family:inherit;cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-calendar__nav:hover{background:var(--gl-surface-3)}.glass-calendar__nav:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-calendar__nav svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-calendar__grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}.glass-calendar__wd{padding:4px 0;text-align:center;font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted);text-transform:uppercase;letter-spacing:.04em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.glass-calendar__day{-webkit-appearance:none;appearance:none;aspect-ratio:1;min-width:0;padding:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;border:1px solid transparent;border-radius:var(--gl-radius-sm);background:0 0;color:var(--gl-color-text);font-family:inherit;font-size:var(--gl-font-size-sm);cursor:pointer;transition:var(--gl-transition-fast);outline:0;-webkit-tap-highlight-color:transparent}.glass-calendar__day:hover{background:var(--gl-surface-2)}.glass-calendar__day--other{opacity:.35}.glass-calendar__day--today{border-color:var(--gl-border-warm)}.glass-calendar__day[aria-pressed=true]{--gl-calendar-ink:var(--gl-color-on-primary);background:var(--gl-color-primary);color:var(--gl-color-on-primary)}.glass-calendar__day:focus-visible{box-shadow:var(--gl-shadow-focus)}.glass-calendar__day:disabled,.glass-calendar__day[aria-disabled=true]{opacity:.45;cursor:not-allowed}.glass-calendar__day:disabled:hover,.glass-calendar__day[aria-disabled=true]:hover{background:0 0}.glass-calendar__marks{display:flex;gap:2px;height:5px}.glass-calendar__mark{width:5px;height:5px;border-radius:50%;background:var(--gl-calendar-tone,transparent)}.glass-calendar__mark--primary{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-primary))}.glass-calendar__mark--success{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-success))}.glass-calendar__mark--warning{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-warning))}.glass-calendar__mark--error{--gl-calendar-tone:var(--gl-calendar-ink, var(--gl-color-error))}.glass-image-picker{display:flex;align-items:center;gap:14px}.glass-image-picker__preview{flex:none;width:72px;height:72px;display:flex;align-items:center;justify-content:center;border:1px solid var(--gl-border-subtle);border-radius:var(--gl-radius-input);background:var(--gl-surface-2);color:var(--gl-icon-muted);overflow:hidden}.glass-image-picker__preview--round{border-radius:50%}.glass-image-picker__preview img{display:block;width:100%;height:100%;object-fit:cover}.glass-image-picker__preview svg{width:28px;height:28px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.glass-image-picker__meta{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:6px}.glass-image-picker__label{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-icon-strong);overflow-wrap:anywhere}.glass-image-picker__hint{font-size:var(--gl-font-size-xs);color:var(--gl-color-text-muted)}.glass-image-picker__actions{display:flex;flex-wrap:wrap;gap:8px}.gl-stack{display:flex;flex-direction:column}.gl-row{display:flex;flex-direction:row;align-items:center}.gl-stack--2xs{gap:var(--gl-space-2xs)}.gl-stack--xs{gap:var(--gl-space-xs)}.gl-stack--sm{gap:var(--gl-space-sm)}.gl-stack--md{gap:var(--gl-space-md)}.gl-stack--lg{gap:var(--gl-space-lg)}.gl-stack--xl{gap:var(--gl-space-xl)}.gl-row--xs{gap:var(--gl-space-xs)}.gl-row--sm{gap:var(--gl-space-sm)}.gl-row--md{gap:var(--gl-space-md)}.gl-text-center{text-align:center}.gl-text-muted{color:var(--gl-color-text-muted)}.gl-text-sm{font-size:var(--gl-font-size-sm)}.gl-mt-sm{margin-top:var(--gl-space-sm)}.gl-mt-md{margin-top:var(--gl-space-md)}.gl-mt-lg{margin-top:var(--gl-space-lg)}.gl-mt-xl{margin-top:var(--gl-space-xl)}.gl-mb-sm{margin-bottom:var(--gl-space-sm)}.gl-mb-md{margin-bottom:var(--gl-space-md)}.gl-mb-lg{margin-bottom:var(--gl-space-lg)}.gl-mb-xl{margin-bottom:var(--gl-space-xl)}.gl-px{padding-left:var(--gl-space-lg);padding-right:var(--gl-space-lg)}.gl-w-full{width:100%}.gl-flex-1{flex:1}svg.glass-icon--fill{fill:currentColor;stroke:none}\n";
|
|
13
13
|
|
|
14
14
|
const componentsCss = componentsHead + componentsTail;
|
|
15
15
|
const css = componentsHead + tokensCss + componentsTail;
|
|
@@ -34,18 +34,44 @@ var GlassKitElements = (function (exports) {
|
|
|
34
34
|
// inherits them like any other custom property. They are wrapped in a cascade
|
|
35
35
|
// layer so an ordinary (unlayered) brand stylesheet wins over them, no matter
|
|
36
36
|
// whether it loads before or after this module.
|
|
37
|
+
//
|
|
38
|
+
// Only the custom properties go there. GlassKit's token blocks also set
|
|
39
|
+
// color-scheme, and on the document that is no default: it switches the whole
|
|
40
|
+
// page to dark — native controls, scrollbars, the root text colour, link
|
|
41
|
+
// colours — on pages that never asked for GlassKit's theme. The elements set
|
|
42
|
+
// color-scheme on their own theme wrapper instead (host sheet below).
|
|
43
|
+
//
|
|
44
|
+
// The --gl-* names themselves are still global. A page that declares them
|
|
45
|
+
// itself, or wants them on part of the page only, switches the defaults off
|
|
46
|
+
// with <html data-glk-defaults="off">. The attribute is watched, so it may
|
|
47
|
+
// also be set or removed later.
|
|
37
48
|
|
|
38
49
|
const TOKENS_INJECTED = '__glkDefaultTokensInjected';
|
|
50
|
+
const DEFAULTS_ATTR = 'data-glk-defaults';
|
|
51
|
+
let defaultTokensSheet = null;
|
|
39
52
|
|
|
40
53
|
function injectDefaultTokens() {
|
|
41
54
|
if (typeof document === 'undefined') return; // SSR / non-DOM
|
|
42
55
|
if (globalThis[TOKENS_INJECTED]) return; // another bundle copy did it
|
|
43
56
|
globalThis[TOKENS_INJECTED] = true;
|
|
44
57
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
const tokens = tokensCss.replace(/color-scheme\s*:[^;}]*;?/g, '');
|
|
59
|
+
defaultTokensSheet = new CSSStyleSheet();
|
|
60
|
+
defaultTokensSheet.replaceSync(`@layer glasskit-defaults { ${tokens} }`);
|
|
61
|
+
syncDefaultTokens();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Adopts or drops the default tokens to match <html data-glk-defaults>. */
|
|
65
|
+
function syncDefaultTokens() {
|
|
66
|
+
if (!defaultTokensSheet) return;
|
|
67
|
+
const wanted = document.documentElement.getAttribute(DEFAULTS_ATTR) !== 'off';
|
|
68
|
+
const sheets = document.adoptedStyleSheets;
|
|
69
|
+
if (wanted === sheets.includes(defaultTokensSheet)) return;
|
|
70
|
+
// Add or remove only this sheet — never assign a fresh list — so an app's
|
|
71
|
+
// own adopted sheets survive.
|
|
72
|
+
document.adoptedStyleSheets = wanted
|
|
73
|
+
? [...sheets, defaultTokensSheet]
|
|
74
|
+
: sheets.filter(sheet => sheet !== defaultTokensSheet);
|
|
49
75
|
}
|
|
50
76
|
|
|
51
77
|
injectDefaultTokens();
|
|
@@ -68,31 +94,94 @@ var GlassKitElements = (function (exports) {
|
|
|
68
94
|
}
|
|
69
95
|
|
|
70
96
|
if (typeof window !== 'undefined' && typeof MutationObserver !== 'undefined') {
|
|
71
|
-
const observer = new MutationObserver(
|
|
97
|
+
const observer = new MutationObserver(records => {
|
|
98
|
+
if (records.some(r => r.attributeName === 'data-theme')) syncAllThemes();
|
|
99
|
+
if (records.some(r => r.attributeName === DEFAULTS_ATTR)) syncDefaultTokens();
|
|
100
|
+
});
|
|
72
101
|
observer.observe(document.documentElement, {
|
|
73
102
|
attributes: true,
|
|
74
|
-
attributeFilter: ['data-theme']
|
|
103
|
+
attributeFilter: ['data-theme', DEFAULTS_ATTR]
|
|
75
104
|
});
|
|
76
105
|
}
|
|
77
106
|
|
|
78
107
|
// ── Host Stylesheet ──
|
|
79
108
|
// Sets display:block on all custom elements by default.
|
|
80
109
|
// Inline components (badge, avatar) override this.
|
|
110
|
+
//
|
|
111
|
+
// The wrapper carries the theme's color-scheme, so native parts inside the
|
|
112
|
+
// elements — a select's list, a date picker, scrollbars — match the element,
|
|
113
|
+
// whatever the page around it uses.
|
|
114
|
+
|
|
115
|
+
const wrapperRules = `
|
|
116
|
+
.glk-wrapper { display: contents; }
|
|
117
|
+
.glk-wrapper[data-theme="dark"] { color-scheme: dark; }
|
|
118
|
+
.glk-wrapper[data-theme="light"] { color-scheme: light; }
|
|
119
|
+
`;
|
|
81
120
|
|
|
82
121
|
const hostSheet = new CSSStyleSheet();
|
|
83
122
|
hostSheet.replaceSync(`
|
|
84
123
|
:host { display: block; }
|
|
85
124
|
:host([hidden]) { display: none; }
|
|
86
|
-
|
|
125
|
+
${wrapperRules}
|
|
87
126
|
`);
|
|
88
127
|
|
|
89
128
|
const inlineHostSheet = new CSSStyleSheet();
|
|
90
129
|
inlineHostSheet.replaceSync(`
|
|
91
130
|
:host { display: inline-block; }
|
|
92
131
|
:host([hidden]) { display: none; }
|
|
93
|
-
|
|
132
|
+
${wrapperRules}
|
|
94
133
|
`);
|
|
95
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Host rules for glk-checkbox, glk-radio and glk-toggle. Their control is an
|
|
137
|
+
* inline-flex label inside a block host; sitting on the text baseline it left
|
|
138
|
+
* room for descenders below, so the host was about 4px taller than the
|
|
139
|
+
* control and the control sat high in a centred row. Aligned to the top of
|
|
140
|
+
* its line, the label is as tall as the host.
|
|
141
|
+
*/
|
|
142
|
+
const checkControlSheet = new CSSStyleSheet();
|
|
143
|
+
checkControlSheet.replaceSync(`
|
|
144
|
+
.glass-checkbox, .glass-radio, .glass-toggle { vertical-align: top; }
|
|
145
|
+
`);
|
|
146
|
+
|
|
147
|
+
// ── Clicks Aimed at the Host ──
|
|
148
|
+
// The innermost target of the latest pointerdown anywhere in the document;
|
|
149
|
+
// tracked once, on first use.
|
|
150
|
+
let lastPressed = null;
|
|
151
|
+
let trackingPresses = false;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* For elements whose control is a native input or button inside the shadow
|
|
155
|
+
* root: glk-checkbox, glk-radio, glk-toggle, glk-button. A click aimed at the
|
|
156
|
+
* host itself — host.click(), or the click a <label> around the element or
|
|
157
|
+
* naming it dispatches — reaches only the host. The control never saw it, so
|
|
158
|
+
* nothing changed where a native checkbox toggles and a native button
|
|
159
|
+
* submits. Such a click is handed to the control; the original is stopped, so
|
|
160
|
+
* listeners see one click, the control's.
|
|
161
|
+
*
|
|
162
|
+
* A pointer press on the host's own empty box (the host is a block, the
|
|
163
|
+
* control is narrower) also lands on the host. Chrome cannot tell it apart
|
|
164
|
+
* from a label's click by the event, only by where the pointer went down; it
|
|
165
|
+
* stays a no-op, as before. Returns the teardown.
|
|
166
|
+
*/
|
|
167
|
+
function forwardHostClicks(host, getField) {
|
|
168
|
+
if (!trackingPresses && typeof window !== 'undefined') {
|
|
169
|
+
trackingPresses = true;
|
|
170
|
+
window.addEventListener('pointerdown', e => { lastPressed = e.composedPath()[0]; },
|
|
171
|
+
{ capture: true, passive: true });
|
|
172
|
+
}
|
|
173
|
+
const onClick = (e) => {
|
|
174
|
+
if (e.composedPath()[0] !== host) return; // from inside: the input had it
|
|
175
|
+
if (e.isTrusted && lastPressed === host) return; // a press on the empty box
|
|
176
|
+
const field = getField();
|
|
177
|
+
if (!field || field.disabled) return;
|
|
178
|
+
e.stopImmediatePropagation();
|
|
179
|
+
field.click();
|
|
180
|
+
};
|
|
181
|
+
host.addEventListener('click', onClick);
|
|
182
|
+
return () => host.removeEventListener('click', onClick);
|
|
183
|
+
}
|
|
184
|
+
|
|
96
185
|
// ── Base Class ──
|
|
97
186
|
|
|
98
187
|
class GlkElement extends HTMLElement {
|
|
@@ -115,6 +204,13 @@ var GlassKitElements = (function (exports) {
|
|
|
115
204
|
*/
|
|
116
205
|
static get observesLightDom() { return false; }
|
|
117
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Turned on by elements built around one native field: focus() on the
|
|
209
|
+
* host, a click on the label text and a <label for> outside all land in
|
|
210
|
+
* that field.
|
|
211
|
+
*/
|
|
212
|
+
static get delegatesFocus() { return false; }
|
|
213
|
+
|
|
118
214
|
static get observedAttributes() {
|
|
119
215
|
return [];
|
|
120
216
|
}
|
|
@@ -122,7 +218,7 @@ var GlassKitElements = (function (exports) {
|
|
|
122
218
|
constructor() {
|
|
123
219
|
super();
|
|
124
220
|
this._initialized = false;
|
|
125
|
-
this._shadow = this.attachShadow({ mode: 'open' });
|
|
221
|
+
this._shadow = this.attachShadow({ mode: 'open', delegatesFocus: this.constructor.delegatesFocus });
|
|
126
222
|
const displaySheet = this.constructor.displayInline ? inlineHostSheet : hostSheet;
|
|
127
223
|
const sheets = [componentsSheet, displaySheet];
|
|
128
224
|
const extra = this.constructor.hostStyles;
|
|
@@ -263,14 +359,26 @@ var GlassKitElements = (function (exports) {
|
|
|
263
359
|
|
|
264
360
|
static formAssociated = true;
|
|
265
361
|
|
|
362
|
+
// One native field inside, so focus goes there. The button groups
|
|
363
|
+
// (glk-segmented, glk-calendar) turn this off again: their first button is
|
|
364
|
+
// not the chosen one.
|
|
365
|
+
static get delegatesFocus() { return true; }
|
|
366
|
+
|
|
266
367
|
constructor() {
|
|
267
368
|
super();
|
|
268
369
|
this._internals = this.attachInternals();
|
|
269
370
|
}
|
|
270
371
|
|
|
372
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
373
|
+
super.attributeChangedCallback(name, oldValue, newValue);
|
|
374
|
+
// required, min, pattern, type … all change what counts as valid.
|
|
375
|
+
if (this._initialized) this.syncValidity();
|
|
376
|
+
}
|
|
377
|
+
|
|
271
378
|
get form() { return this._internals.form; }
|
|
272
379
|
get validationMessage() { return this._internals.validationMessage; }
|
|
273
380
|
get validity() { return this._internals.validity; }
|
|
381
|
+
get willValidate() { return this._internals.willValidate; }
|
|
274
382
|
|
|
275
383
|
checkValidity() { return this._internals.checkValidity(); }
|
|
276
384
|
reportValidity() { return this._internals.reportValidity(); }
|
|
@@ -289,11 +397,38 @@ var GlassKitElements = (function (exports) {
|
|
|
289
397
|
|
|
290
398
|
setFormValue(value) {
|
|
291
399
|
this._internals.setFormValue(value);
|
|
400
|
+
this.syncValidity();
|
|
292
401
|
}
|
|
293
402
|
|
|
294
403
|
setValidity(flags, message, anchor) {
|
|
295
404
|
this._internals.setValidity(flags, message, anchor);
|
|
296
405
|
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* The native field whose constraint validation the host reports, or null.
|
|
409
|
+
* Subclasses built around one field return it.
|
|
410
|
+
*/
|
|
411
|
+
get _validityField() { return null; }
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* A form asks the host — checkValidity(), reportValidity(), submitting — and
|
|
415
|
+
* the host knows nothing by itself, so the inner field's verdict is copied
|
|
416
|
+
* over after everything that can change it: a value (every setFormValue
|
|
417
|
+
* lands here), an attribute, a reset. The field is the anchor: the browser's
|
|
418
|
+
* bubble points at it, and reportValidity() focuses it.
|
|
419
|
+
*/
|
|
420
|
+
syncValidity() {
|
|
421
|
+
const field = this._validityField;
|
|
422
|
+
if (!field) return;
|
|
423
|
+
const message = field.validationMessage;
|
|
424
|
+
// A field barred from validation (disabled) can still carry flags, but
|
|
425
|
+
// it has no message, and setValidity() refuses flags without one.
|
|
426
|
+
if (!field.willValidate || field.validity.valid || !message) {
|
|
427
|
+
this._internals.setValidity({});
|
|
428
|
+
} else {
|
|
429
|
+
this._internals.setValidity(field.validity, message, field);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
297
432
|
}
|
|
298
433
|
|
|
299
434
|
class GlkNav extends GlkElement {
|
|
@@ -306,9 +441,13 @@ var GlassKitElements = (function (exports) {
|
|
|
306
441
|
|
|
307
442
|
customElements.define('glk-nav', GlkNav);
|
|
308
443
|
|
|
444
|
+
// Handed down to the native button, which is what assistive technology reads —
|
|
445
|
+
// <glk-popover> sets aria-expanded on its trigger.
|
|
446
|
+
const FORWARDED_ARIA$1 = ['aria-expanded', 'aria-haspopup', 'aria-pressed'];
|
|
447
|
+
|
|
309
448
|
class GlkPill extends GlkElement {
|
|
310
449
|
static get observedAttributes() {
|
|
311
|
-
return ['label', 'disabled'];
|
|
450
|
+
return ['label', 'disabled', ...FORWARDED_ARIA$1];
|
|
312
451
|
}
|
|
313
452
|
|
|
314
453
|
render() {
|
|
@@ -318,6 +457,7 @@ var GlassKitElements = (function (exports) {
|
|
|
318
457
|
|
|
319
458
|
const ariaLabel = this.getAttribute('label');
|
|
320
459
|
if (ariaLabel) this._btn.setAttribute('aria-label', ariaLabel);
|
|
460
|
+
for (const attr of FORWARDED_ARIA$1) this._forward(attr);
|
|
321
461
|
|
|
322
462
|
// Slotted content (SVG icons, text)
|
|
323
463
|
this._btn.appendChild(document.createElement('slot'));
|
|
@@ -346,8 +486,16 @@ var GlassKitElements = (function (exports) {
|
|
|
346
486
|
case 'disabled':
|
|
347
487
|
this._btn.disabled = this.getBoolAttr('disabled');
|
|
348
488
|
break;
|
|
489
|
+
default:
|
|
490
|
+
if (FORWARDED_ARIA$1.includes(name)) this._forward(name);
|
|
349
491
|
}
|
|
350
492
|
}
|
|
493
|
+
|
|
494
|
+
_forward(attr) {
|
|
495
|
+
const value = this.getAttribute(attr);
|
|
496
|
+
if (value === null) this._btn.removeAttribute(attr);
|
|
497
|
+
else this._btn.setAttribute(attr, value);
|
|
498
|
+
}
|
|
351
499
|
}
|
|
352
500
|
|
|
353
501
|
customElements.define('glk-pill', GlkPill);
|
|
@@ -1303,9 +1451,24 @@ var GlassKitElements = (function (exports) {
|
|
|
1303
1451
|
const VARIANTS$3 = ['primary', 'secondary', 'tertiary'];
|
|
1304
1452
|
const SIZES$1 = ['sm', 'md', 'lg', 'auto'];
|
|
1305
1453
|
|
|
1454
|
+
// States that whoever owns the element sets on it — <glk-popover> sets
|
|
1455
|
+
// aria-expanded on its trigger. Assistive technology reads the native button
|
|
1456
|
+
// inside, so they are handed down to it.
|
|
1457
|
+
const FORWARDED_ARIA = ['aria-expanded', 'aria-haspopup', 'aria-pressed'];
|
|
1458
|
+
|
|
1306
1459
|
class GlkButton extends GlkElement {
|
|
1307
1460
|
static get observedAttributes() {
|
|
1308
|
-
return ['variant', 'size', 'disabled', 'type'];
|
|
1461
|
+
return ['variant', 'size', 'disabled', 'type', ...FORWARDED_ARIA];
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
// The native button sits in the shadow root, outside every form. Form
|
|
1465
|
+
// association gives the element its form, so type="submit" and "reset"
|
|
1466
|
+
// can act on it (see _activateForm).
|
|
1467
|
+
static formAssociated = true;
|
|
1468
|
+
|
|
1469
|
+
constructor() {
|
|
1470
|
+
super();
|
|
1471
|
+
this._internals = this.attachInternals();
|
|
1309
1472
|
}
|
|
1310
1473
|
|
|
1311
1474
|
render() {
|
|
@@ -1316,6 +1479,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1316
1479
|
if (this.getBoolAttr('disabled')) {
|
|
1317
1480
|
this._btn.disabled = true;
|
|
1318
1481
|
}
|
|
1482
|
+
for (const attr of FORWARDED_ARIA) this._forward(attr);
|
|
1319
1483
|
|
|
1320
1484
|
this._btn.appendChild(document.createElement('slot'));
|
|
1321
1485
|
this._wrapper.appendChild(this._btn);
|
|
@@ -1329,12 +1493,50 @@ var GlassKitElements = (function (exports) {
|
|
|
1329
1493
|
return;
|
|
1330
1494
|
}
|
|
1331
1495
|
this.emit('glk-click');
|
|
1496
|
+
this._activateForm(e);
|
|
1332
1497
|
};
|
|
1333
1498
|
this._btn.addEventListener('click', this._onClick);
|
|
1499
|
+
// host.click() and a <label> for the element reach the host only.
|
|
1500
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._btn);
|
|
1334
1501
|
}
|
|
1335
1502
|
|
|
1336
1503
|
teardownEvents() {
|
|
1337
1504
|
this._btn?.removeEventListener('click', this._onClick);
|
|
1505
|
+
this._unforwardClicks?.();
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* type="submit" submits the element's form, type="reset" resets it. Both
|
|
1510
|
+
* wait until the click has finished bubbling, so a listener that calls
|
|
1511
|
+
* preventDefault() on the click stops them — as on a native button.
|
|
1512
|
+
*/
|
|
1513
|
+
_activateForm(click) {
|
|
1514
|
+
const type = this.getAttribute('type');
|
|
1515
|
+
const form = this._internals.form;
|
|
1516
|
+
if (!form || (type !== 'submit' && type !== 'reset')) return;
|
|
1517
|
+
// Through the prototype: a control with id or name "reset" or
|
|
1518
|
+
// "requestSubmit" in the form shadows the methods on the form itself.
|
|
1519
|
+
const { reset, requestSubmit } = HTMLFormElement.prototype;
|
|
1520
|
+
setTimeout(() => {
|
|
1521
|
+
if (click.defaultPrevented || this._internals.form !== form) return;
|
|
1522
|
+
if (type === 'reset') {
|
|
1523
|
+
reset.call(form);
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
// requestSubmit() accepts native buttons only as the submitter, so the
|
|
1527
|
+
// submit event is told about this element instead. The listener goes
|
|
1528
|
+
// again right away: a form that fails validation fires no submit event,
|
|
1529
|
+
// and the next submit must not inherit this submitter.
|
|
1530
|
+
const nameSubmitter = (e) => {
|
|
1531
|
+
Object.defineProperty(e, 'submitter', { configurable: true, get: () => this });
|
|
1532
|
+
};
|
|
1533
|
+
form.addEventListener('submit', nameSubmitter, { capture: true });
|
|
1534
|
+
try {
|
|
1535
|
+
requestSubmit.call(form);
|
|
1536
|
+
} finally {
|
|
1537
|
+
form.removeEventListener('submit', nameSubmitter, { capture: true });
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1338
1540
|
}
|
|
1339
1541
|
|
|
1340
1542
|
onAttributeChanged(name) {
|
|
@@ -1350,9 +1552,17 @@ var GlassKitElements = (function (exports) {
|
|
|
1350
1552
|
case 'type':
|
|
1351
1553
|
this._btn.setAttribute('type', this.getAttribute('type') || 'button');
|
|
1352
1554
|
break;
|
|
1555
|
+
default:
|
|
1556
|
+
if (FORWARDED_ARIA.includes(name)) this._forward(name);
|
|
1353
1557
|
}
|
|
1354
1558
|
}
|
|
1355
1559
|
|
|
1560
|
+
_forward(attr) {
|
|
1561
|
+
const value = this.getAttribute(attr);
|
|
1562
|
+
if (value === null) this._btn.removeAttribute(attr);
|
|
1563
|
+
else this._btn.setAttribute(attr, value);
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1356
1566
|
_computeClasses() {
|
|
1357
1567
|
const classes = ['glass-btn'];
|
|
1358
1568
|
const variant = this.getAttribute('variant');
|
|
@@ -1374,6 +1584,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1374
1584
|
|
|
1375
1585
|
get disabled() { return this.getBoolAttr('disabled'); }
|
|
1376
1586
|
set disabled(v) { this.setBoolAttr('disabled', v); }
|
|
1587
|
+
|
|
1588
|
+
get type() { return this.getAttribute('type') || 'button'; }
|
|
1589
|
+
set type(v) { this.setAttribute('type', v); }
|
|
1590
|
+
|
|
1591
|
+
get form() { return this._internals.form; }
|
|
1377
1592
|
}
|
|
1378
1593
|
|
|
1379
1594
|
customElements.define('glk-button', GlkButton);
|
|
@@ -1392,12 +1607,15 @@ var GlassKitElements = (function (exports) {
|
|
|
1392
1607
|
render() {
|
|
1393
1608
|
const group = this.createElement('div', ['glass-input-group']);
|
|
1394
1609
|
|
|
1395
|
-
// Label
|
|
1396
|
-
this.
|
|
1610
|
+
// Label — tied to the field by id, which only has to be unique inside
|
|
1611
|
+
// this shadow root. That gives the field its accessible name, and a click
|
|
1612
|
+
// on the label text focuses it.
|
|
1613
|
+
this._labelEl = this.createElement('label', ['glass-label'], { for: 'field' });
|
|
1397
1614
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
1398
1615
|
|
|
1399
1616
|
// Input
|
|
1400
1617
|
this._input = this.createElement('input', this._computeInputClasses(), {
|
|
1618
|
+
id: 'field',
|
|
1401
1619
|
type: this.getAttribute('type') || 'text'
|
|
1402
1620
|
});
|
|
1403
1621
|
|
|
@@ -1414,8 +1632,8 @@ var GlassKitElements = (function (exports) {
|
|
|
1414
1632
|
if (this.getBoolAttr('required')) this._input.required = true;
|
|
1415
1633
|
for (const attr of FORWARDED) this._forward(attr);
|
|
1416
1634
|
|
|
1417
|
-
// Hint
|
|
1418
|
-
this._hintEl = this.createElement('span', this._computeHintClasses());
|
|
1635
|
+
// Hint — read out with the field as its description
|
|
1636
|
+
this._hintEl = this.createElement('span', this._computeHintClasses(), { id: 'hint' });
|
|
1419
1637
|
this._hintEl.textContent = this.getAttribute('hint') || '';
|
|
1420
1638
|
|
|
1421
1639
|
group.appendChild(this._labelEl);
|
|
@@ -1425,6 +1643,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1425
1643
|
this._group = group;
|
|
1426
1644
|
this._wrapper.appendChild(group);
|
|
1427
1645
|
|
|
1646
|
+
this._applyDescription();
|
|
1428
1647
|
this._syncFormValue();
|
|
1429
1648
|
}
|
|
1430
1649
|
|
|
@@ -1462,12 +1681,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1462
1681
|
case 'error':
|
|
1463
1682
|
this._input.className = this._computeInputClasses().join(' ');
|
|
1464
1683
|
this._hintEl.className = this._computeHintClasses().join(' ');
|
|
1684
|
+
this._applyDescription();
|
|
1465
1685
|
break;
|
|
1466
1686
|
case 'hint':
|
|
1467
1687
|
this._hintEl.textContent = this.getAttribute('hint') || '';
|
|
1468
1688
|
if (this.getAttribute('hint') && !this._hintEl.parentNode) {
|
|
1469
1689
|
this._group.appendChild(this._hintEl);
|
|
1470
1690
|
}
|
|
1691
|
+
this._applyDescription();
|
|
1471
1692
|
break;
|
|
1472
1693
|
case 'disabled':
|
|
1473
1694
|
this._input.disabled = this.getBoolAttr('disabled');
|
|
@@ -1487,6 +1708,19 @@ var GlassKitElements = (function (exports) {
|
|
|
1487
1708
|
}
|
|
1488
1709
|
}
|
|
1489
1710
|
|
|
1711
|
+
/**
|
|
1712
|
+
* The hint describes the field; with `error` set it is the error message
|
|
1713
|
+
* and the field is marked invalid. Server-side errors arrive this way, so
|
|
1714
|
+
* `error` stays a marker for assistive technology and does not block the
|
|
1715
|
+
* form — only the field's own constraints (required, pattern …) do.
|
|
1716
|
+
*/
|
|
1717
|
+
_applyDescription() {
|
|
1718
|
+
if (this.getAttribute('hint')) this._input.setAttribute('aria-describedby', 'hint');
|
|
1719
|
+
else this._input.removeAttribute('aria-describedby');
|
|
1720
|
+
if (this.getBoolAttr('error')) this._input.setAttribute('aria-invalid', 'true');
|
|
1721
|
+
else this._input.removeAttribute('aria-invalid');
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1490
1724
|
_forward(attr) {
|
|
1491
1725
|
const value = this.getAttribute(attr);
|
|
1492
1726
|
if (value === null) this._input.removeAttribute(attr);
|
|
@@ -1505,6 +1739,8 @@ var GlassKitElements = (function (exports) {
|
|
|
1505
1739
|
return classes;
|
|
1506
1740
|
}
|
|
1507
1741
|
|
|
1742
|
+
get _validityField() { return this._input; }
|
|
1743
|
+
|
|
1508
1744
|
_syncFormValue() {
|
|
1509
1745
|
this.setFormValue(this._input.value);
|
|
1510
1746
|
}
|
|
@@ -1537,10 +1773,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1537
1773
|
render() {
|
|
1538
1774
|
const group = this.createElement('div', ['glass-input-group']);
|
|
1539
1775
|
|
|
1540
|
-
this
|
|
1776
|
+
// Tied to the field by an id that only has to be unique in this shadow root.
|
|
1777
|
+
this._labelEl = this.createElement('label', ['glass-label'], { for: 'field' });
|
|
1541
1778
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
1542
1779
|
|
|
1543
|
-
this._textarea = this.createElement('textarea', ['glass-textarea']);
|
|
1780
|
+
this._textarea = this.createElement('textarea', ['glass-textarea'], { id: 'field' });
|
|
1544
1781
|
const placeholder = this.getAttribute('placeholder');
|
|
1545
1782
|
if (placeholder) this._textarea.setAttribute('placeholder', placeholder);
|
|
1546
1783
|
|
|
@@ -1598,9 +1835,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1598
1835
|
this._textarea.value = this.getAttribute('value') || '';
|
|
1599
1836
|
this._syncFormValue();
|
|
1600
1837
|
break;
|
|
1838
|
+
case 'required':
|
|
1839
|
+
this._textarea.required = this.getBoolAttr('required');
|
|
1840
|
+
break;
|
|
1601
1841
|
}
|
|
1602
1842
|
}
|
|
1603
1843
|
|
|
1844
|
+
get _validityField() { return this._textarea; }
|
|
1845
|
+
|
|
1604
1846
|
_syncFormValue() {
|
|
1605
1847
|
this.setFormValue(this._textarea.value);
|
|
1606
1848
|
}
|
|
@@ -1632,10 +1874,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1632
1874
|
render() {
|
|
1633
1875
|
const group = this.createElement('div', ['glass-input-group']);
|
|
1634
1876
|
|
|
1635
|
-
this
|
|
1877
|
+
// Tied to the field by an id that only has to be unique in this shadow root.
|
|
1878
|
+
this._labelEl = this.createElement('label', ['glass-label'], { for: 'field' });
|
|
1636
1879
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
1637
1880
|
|
|
1638
|
-
this._select = this.createElement('select', ['glass-select']);
|
|
1881
|
+
this._select = this.createElement('select', ['glass-select'], { id: 'field' });
|
|
1639
1882
|
|
|
1640
1883
|
const name = this.getAttribute('name');
|
|
1641
1884
|
if (name) this._select.setAttribute('name', name);
|
|
@@ -1723,9 +1966,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1723
1966
|
this._applyValue(this.getAttribute('value'));
|
|
1724
1967
|
this._syncFormValue();
|
|
1725
1968
|
break;
|
|
1969
|
+
case 'required':
|
|
1970
|
+
this._select.required = this.getBoolAttr('required');
|
|
1971
|
+
break;
|
|
1726
1972
|
}
|
|
1727
1973
|
}
|
|
1728
1974
|
|
|
1975
|
+
get _validityField() { return this._select; }
|
|
1976
|
+
|
|
1729
1977
|
_syncFormValue() {
|
|
1730
1978
|
this.setFormValue(this._select.value);
|
|
1731
1979
|
}
|
|
@@ -1751,7 +1999,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1751
1999
|
|
|
1752
2000
|
class GlkSearch extends GlkFormElement {
|
|
1753
2001
|
static get observedAttributes() {
|
|
1754
|
-
return ['placeholder', 'name', 'value', 'disabled'];
|
|
2002
|
+
return ['placeholder', 'name', 'value', 'disabled', 'label'];
|
|
1755
2003
|
}
|
|
1756
2004
|
|
|
1757
2005
|
render() {
|
|
@@ -1767,6 +2015,10 @@ var GlassKitElements = (function (exports) {
|
|
|
1767
2015
|
const placeholder = this.getAttribute('placeholder');
|
|
1768
2016
|
if (placeholder) this._input.setAttribute('placeholder', placeholder);
|
|
1769
2017
|
|
|
2018
|
+
// The search field has no visible label; `label` names it for assistive
|
|
2019
|
+
// technology. Without it the placeholder is all a screen reader can say.
|
|
2020
|
+
this._applyLabel();
|
|
2021
|
+
|
|
1770
2022
|
const name = this.getAttribute('name');
|
|
1771
2023
|
if (name) this._input.setAttribute('name', name);
|
|
1772
2024
|
|
|
@@ -1811,9 +2063,18 @@ var GlassKitElements = (function (exports) {
|
|
|
1811
2063
|
case 'disabled':
|
|
1812
2064
|
this._input.disabled = this.getBoolAttr('disabled');
|
|
1813
2065
|
break;
|
|
2066
|
+
case 'label':
|
|
2067
|
+
this._applyLabel();
|
|
2068
|
+
break;
|
|
1814
2069
|
}
|
|
1815
2070
|
}
|
|
1816
2071
|
|
|
2072
|
+
_applyLabel() {
|
|
2073
|
+
const label = this.getAttribute('label');
|
|
2074
|
+
if (label) this._input.setAttribute('aria-label', label);
|
|
2075
|
+
else this._input.removeAttribute('aria-label');
|
|
2076
|
+
}
|
|
2077
|
+
|
|
1817
2078
|
_syncFormValue() {
|
|
1818
2079
|
this.setFormValue(this._input.value);
|
|
1819
2080
|
}
|
|
@@ -1834,14 +2095,21 @@ var GlassKitElements = (function (exports) {
|
|
|
1834
2095
|
|
|
1835
2096
|
class GlkToggle extends GlkFormElement {
|
|
1836
2097
|
static get observedAttributes() {
|
|
1837
|
-
return ['checked', 'disabled', 'label', 'name', 'value'];
|
|
2098
|
+
return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
|
|
1838
2099
|
}
|
|
1839
2100
|
|
|
2101
|
+
static get hostStyles() { return checkControlSheet; }
|
|
2102
|
+
|
|
1840
2103
|
render() {
|
|
1841
2104
|
const label = this.createElement('label', ['glass-toggle']);
|
|
1842
2105
|
|
|
2106
|
+
// The native checkbox is the switch: role, checked state and name (from
|
|
2107
|
+
// the label around it) all sit on one control. The host has no role of
|
|
2108
|
+
// its own — it used to carry role="switch" as well, and screen readers met
|
|
2109
|
+
// a switch with a checkbox inside.
|
|
1843
2110
|
this._input = this.createElement('input', ['glass-toggle__input'], {
|
|
1844
|
-
type: 'checkbox'
|
|
2111
|
+
type: 'checkbox',
|
|
2112
|
+
role: 'switch'
|
|
1845
2113
|
});
|
|
1846
2114
|
|
|
1847
2115
|
const name = this.getAttribute('name');
|
|
@@ -1860,14 +2128,12 @@ var GlassKitElements = (function (exports) {
|
|
|
1860
2128
|
|
|
1861
2129
|
if (this.getBoolAttr('checked')) this._input.checked = true;
|
|
1862
2130
|
if (this.getBoolAttr('disabled')) this._input.disabled = true;
|
|
2131
|
+
if (this.getBoolAttr('required')) this._input.required = true;
|
|
1863
2132
|
|
|
1864
2133
|
this._defaultChecked = this.getBoolAttr('checked');
|
|
1865
2134
|
this._wrapper.appendChild(label);
|
|
1866
2135
|
|
|
1867
2136
|
this._syncFormValue();
|
|
1868
|
-
this.setAttribute('role', 'switch');
|
|
1869
|
-
this.setAttribute('aria-checked', String(this._input.checked));
|
|
1870
|
-
if (this.getBoolAttr('disabled')) this.setAttribute('aria-disabled', 'true');
|
|
1871
2137
|
}
|
|
1872
2138
|
|
|
1873
2139
|
setupEvents() {
|
|
@@ -1875,16 +2141,17 @@ var GlassKitElements = (function (exports) {
|
|
|
1875
2141
|
this._syncing = true;
|
|
1876
2142
|
this.setBoolAttr('checked', this._input.checked);
|
|
1877
2143
|
this._syncing = false;
|
|
1878
|
-
this.setAttribute('aria-checked', String(this._input.checked));
|
|
1879
2144
|
this._syncFormValue();
|
|
1880
2145
|
this.emit('glk-change', { checked: this._input.checked });
|
|
1881
2146
|
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
1882
2147
|
};
|
|
1883
2148
|
this._input.addEventListener('change', this._onChange);
|
|
2149
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._input);
|
|
1884
2150
|
}
|
|
1885
2151
|
|
|
1886
2152
|
teardownEvents() {
|
|
1887
2153
|
this._input?.removeEventListener('change', this._onChange);
|
|
2154
|
+
this._unforwardClicks?.();
|
|
1888
2155
|
}
|
|
1889
2156
|
|
|
1890
2157
|
onAttributeChanged(name) {
|
|
@@ -1893,12 +2160,10 @@ var GlassKitElements = (function (exports) {
|
|
|
1893
2160
|
switch (name) {
|
|
1894
2161
|
case 'checked':
|
|
1895
2162
|
this._input.checked = this.getBoolAttr('checked');
|
|
1896
|
-
this.setAttribute('aria-checked', String(this._input.checked));
|
|
1897
2163
|
this._syncFormValue();
|
|
1898
2164
|
break;
|
|
1899
2165
|
case 'disabled':
|
|
1900
2166
|
this._input.disabled = this.getBoolAttr('disabled');
|
|
1901
|
-
this.setAttribute('aria-disabled', String(this.getBoolAttr('disabled')));
|
|
1902
2167
|
break;
|
|
1903
2168
|
case 'label':
|
|
1904
2169
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
@@ -1906,9 +2171,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1906
2171
|
case 'name':
|
|
1907
2172
|
this._input.setAttribute('name', this.getAttribute('name') || '');
|
|
1908
2173
|
break;
|
|
2174
|
+
case 'required':
|
|
2175
|
+
this._input.required = this.getBoolAttr('required');
|
|
2176
|
+
break;
|
|
1909
2177
|
}
|
|
1910
2178
|
}
|
|
1911
2179
|
|
|
2180
|
+
get _validityField() { return this._input; }
|
|
2181
|
+
|
|
1912
2182
|
_syncFormValue() {
|
|
1913
2183
|
const val = this.getAttribute('value') || 'on';
|
|
1914
2184
|
this.setFormValue(this._input.checked ? val : null);
|
|
@@ -1917,7 +2187,6 @@ var GlassKitElements = (function (exports) {
|
|
|
1917
2187
|
resetValue() {
|
|
1918
2188
|
this._input.checked = this._defaultChecked;
|
|
1919
2189
|
this.setBoolAttr('checked', this._defaultChecked);
|
|
1920
|
-
this.setAttribute('aria-checked', String(this._defaultChecked));
|
|
1921
2190
|
this._syncFormValue();
|
|
1922
2191
|
}
|
|
1923
2192
|
|
|
@@ -1932,7 +2201,6 @@ var GlassKitElements = (function (exports) {
|
|
|
1932
2201
|
set checked(v) {
|
|
1933
2202
|
if (this._input) this._input.checked = v;
|
|
1934
2203
|
this.setBoolAttr('checked', v);
|
|
1935
|
-
this.setAttribute('aria-checked', String(v));
|
|
1936
2204
|
this._syncFormValue();
|
|
1937
2205
|
}
|
|
1938
2206
|
|
|
@@ -1955,9 +2223,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1955
2223
|
|
|
1956
2224
|
class GlkCheckbox extends GlkFormElement {
|
|
1957
2225
|
static get observedAttributes() {
|
|
1958
|
-
return ['checked', 'disabled', 'label', 'name', 'value'];
|
|
2226
|
+
return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
|
|
1959
2227
|
}
|
|
1960
2228
|
|
|
2229
|
+
static get hostStyles() { return checkControlSheet; }
|
|
2230
|
+
|
|
1961
2231
|
render() {
|
|
1962
2232
|
const label = this.createElement('label', ['glass-checkbox']);
|
|
1963
2233
|
|
|
@@ -1980,6 +2250,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1980
2250
|
|
|
1981
2251
|
if (this.getBoolAttr('checked')) this._input.checked = true;
|
|
1982
2252
|
if (this.getBoolAttr('disabled')) this._input.disabled = true;
|
|
2253
|
+
if (this.getBoolAttr('required')) this._input.required = true;
|
|
1983
2254
|
|
|
1984
2255
|
this._defaultChecked = this.getBoolAttr('checked');
|
|
1985
2256
|
this._wrapper.appendChild(label);
|
|
@@ -1996,10 +2267,12 @@ var GlassKitElements = (function (exports) {
|
|
|
1996
2267
|
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
1997
2268
|
};
|
|
1998
2269
|
this._input.addEventListener('change', this._onChange);
|
|
2270
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._input);
|
|
1999
2271
|
}
|
|
2000
2272
|
|
|
2001
2273
|
teardownEvents() {
|
|
2002
2274
|
this._input?.removeEventListener('change', this._onChange);
|
|
2275
|
+
this._unforwardClicks?.();
|
|
2003
2276
|
}
|
|
2004
2277
|
|
|
2005
2278
|
onAttributeChanged(name) {
|
|
@@ -2019,9 +2292,14 @@ var GlassKitElements = (function (exports) {
|
|
|
2019
2292
|
case 'name':
|
|
2020
2293
|
this._input.setAttribute('name', this.getAttribute('name') || '');
|
|
2021
2294
|
break;
|
|
2295
|
+
case 'required':
|
|
2296
|
+
this._input.required = this.getBoolAttr('required');
|
|
2297
|
+
break;
|
|
2022
2298
|
}
|
|
2023
2299
|
}
|
|
2024
2300
|
|
|
2301
|
+
get _validityField() { return this._input; }
|
|
2302
|
+
|
|
2025
2303
|
_syncFormValue() {
|
|
2026
2304
|
const val = this.getAttribute('value') || 'on';
|
|
2027
2305
|
this.setFormValue(this._input.checked ? val : null);
|
|
@@ -2081,9 +2359,11 @@ var GlassKitElements = (function (exports) {
|
|
|
2081
2359
|
|
|
2082
2360
|
class GlkRadio extends GlkFormElement {
|
|
2083
2361
|
static get observedAttributes() {
|
|
2084
|
-
return ['checked', 'disabled', 'label', 'name', 'value'];
|
|
2362
|
+
return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
|
|
2085
2363
|
}
|
|
2086
2364
|
|
|
2365
|
+
static get hostStyles() { return checkControlSheet; }
|
|
2366
|
+
|
|
2087
2367
|
render() {
|
|
2088
2368
|
const label = this.createElement('label', ['glass-radio']);
|
|
2089
2369
|
|
|
@@ -2138,11 +2418,13 @@ var GlassKitElements = (function (exports) {
|
|
|
2138
2418
|
|
|
2139
2419
|
this._input.addEventListener('change', this._onChange);
|
|
2140
2420
|
this._input.addEventListener('keydown', this._onKeyDown);
|
|
2421
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._input);
|
|
2141
2422
|
}
|
|
2142
2423
|
|
|
2143
2424
|
teardownEvents() {
|
|
2144
2425
|
this._input?.removeEventListener('change', this._onChange);
|
|
2145
2426
|
this._input?.removeEventListener('keydown', this._onKeyDown);
|
|
2427
|
+
this._unforwardClicks?.();
|
|
2146
2428
|
}
|
|
2147
2429
|
|
|
2148
2430
|
/** Shared by user change and arrow-key selection, so both look identical. */
|
|
@@ -2177,6 +2459,26 @@ var GlassKitElements = (function (exports) {
|
|
|
2177
2459
|
}
|
|
2178
2460
|
}
|
|
2179
2461
|
|
|
2462
|
+
get _validityField() { return this._input; }
|
|
2463
|
+
|
|
2464
|
+
/**
|
|
2465
|
+
* Radios are missing a value as a group: one required radio makes the
|
|
2466
|
+
* whole group required, and any checked one satisfies it. Each input here
|
|
2467
|
+
* sits alone in its shadow root, so the group's verdict is worked out across
|
|
2468
|
+
* the elements and handed to every member. The inner input carries
|
|
2469
|
+
* `required` only while the group lacks a value — that way it produces the
|
|
2470
|
+
* browser's own message for it.
|
|
2471
|
+
*/
|
|
2472
|
+
syncValidity() {
|
|
2473
|
+
const group = this._group();
|
|
2474
|
+
const missing = group.some(el => el.hasAttribute('required')) && !group.some(el => el.checked);
|
|
2475
|
+
for (const el of group) {
|
|
2476
|
+
if (!el._input) continue; // not rendered yet; syncs when it is
|
|
2477
|
+
el._input.required = missing;
|
|
2478
|
+
super.syncValidity.call(el);
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2180
2482
|
onAttributeChanged(name) {
|
|
2181
2483
|
if (this._syncing) return;
|
|
2182
2484
|
if (!this._input) return;
|
|
@@ -2250,7 +2552,8 @@ var GlassKitElements = (function (exports) {
|
|
|
2250
2552
|
|
|
2251
2553
|
const header = this.createElement('div', ['glass-range-header']);
|
|
2252
2554
|
|
|
2253
|
-
this
|
|
2555
|
+
// Tied to the slider by an id that only has to be unique in this shadow root.
|
|
2556
|
+
this._labelEl = this.createElement('label', [], { for: 'field' });
|
|
2254
2557
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
2255
2558
|
|
|
2256
2559
|
this._valueEl = this.createElement('span', ['glass-range-value']);
|
|
@@ -2259,6 +2562,7 @@ var GlassKitElements = (function (exports) {
|
|
|
2259
2562
|
header.appendChild(this._valueEl);
|
|
2260
2563
|
|
|
2261
2564
|
this._input = this.createElement('input', ['glass-range'], {
|
|
2565
|
+
id: 'field',
|
|
2262
2566
|
type: 'range',
|
|
2263
2567
|
min: this.getAttribute('min') || '0',
|
|
2264
2568
|
max: this.getAttribute('max') || '100',
|
|
@@ -2388,6 +2692,10 @@ var GlassKitElements = (function (exports) {
|
|
|
2388
2692
|
class GlkSegmented extends GlkFormElement {
|
|
2389
2693
|
static get observedAttributes() { return ['options', 'value', 'full', 'overflow', 'label']; }
|
|
2390
2694
|
|
|
2695
|
+
// A row of buttons with one tab stop: delegated focus would land on the
|
|
2696
|
+
// first button, not the chosen one.
|
|
2697
|
+
static get delegatesFocus() { return false; }
|
|
2698
|
+
|
|
2391
2699
|
render() {
|
|
2392
2700
|
this._group = this.createElement('div', ['glass-segmented'], { role: 'group', part: 'group' });
|
|
2393
2701
|
this._wrapper.appendChild(this._group);
|
|
@@ -2550,6 +2858,9 @@ var GlassKitElements = (function (exports) {
|
|
|
2550
2858
|
return ['month', 'value', 'today', 'min', 'max', 'marks', 'locale', 'week-start', 'label', 'prev-label', 'next-label'];
|
|
2551
2859
|
}
|
|
2552
2860
|
|
|
2861
|
+
// Delegated focus would land on the month arrow, not on the chosen day.
|
|
2862
|
+
static get delegatesFocus() { return false; }
|
|
2863
|
+
|
|
2553
2864
|
render() {
|
|
2554
2865
|
this._root = this.createElement('div', ['glass-calendar'], { part: 'calendar' });
|
|
2555
2866
|
const head = this.createElement('div', ['glass-calendar__head'], { part: 'head' });
|
|
@@ -3008,6 +3319,29 @@ var GlassKitElements = (function (exports) {
|
|
|
3008
3319
|
|
|
3009
3320
|
customElements.define('glk-progress', GlkProgress);
|
|
3010
3321
|
|
|
3322
|
+
// Since 1.20.0 the overlay is a native <dialog>, opened with showModal(). The
|
|
3323
|
+
// browser then does what a modal needs: the dialog lies in the top layer, the
|
|
3324
|
+
// page behind it is inert — for the pointer, the keyboard and screen readers
|
|
3325
|
+
// alike — focus moves in on opening and goes back to where it came from on
|
|
3326
|
+
// closing, and the content is out of reach while the modal is closed.
|
|
3327
|
+
// GlassKit (1.20.0) styles dialog.glass-modal-overlay for this.
|
|
3328
|
+
//
|
|
3329
|
+
// The element keeps the fade: the dialog opens before .is-active is set and
|
|
3330
|
+
// closes only after the overlay has faded (safety net 400 ms; at once under
|
|
3331
|
+
// prefers-reduced-motion). Escape arrives as the dialog's cancel event and
|
|
3332
|
+
// takes the same path as a click on the dimmed area.
|
|
3333
|
+
//
|
|
3334
|
+
// Which element gets the focus on opening, the browsers decide differently:
|
|
3335
|
+
// Chrome takes the first field of the content, Safari the first action. An
|
|
3336
|
+
// element marked autofocus — in the content or among the actions — settles
|
|
3337
|
+
// it in both.
|
|
3338
|
+
|
|
3339
|
+
const CLOSE_FALLBACK_MS = 400;
|
|
3340
|
+
|
|
3341
|
+
function reducedMotion$1() {
|
|
3342
|
+
return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3011
3345
|
class GlkModal extends GlkElement {
|
|
3012
3346
|
static get observedAttributes() {
|
|
3013
3347
|
return ['open', 'title'];
|
|
@@ -3016,13 +3350,13 @@ var GlassKitElements = (function (exports) {
|
|
|
3016
3350
|
static get observesLightDom() { return true; }
|
|
3017
3351
|
|
|
3018
3352
|
render() {
|
|
3019
|
-
this._overlay = this.createElement('
|
|
3353
|
+
this._overlay = this.createElement('dialog', ['glass-modal-overlay'], { part: 'overlay' });
|
|
3020
3354
|
|
|
3021
3355
|
const modal = this.createElement('div', ['glass-modal'], { part: 'modal' });
|
|
3022
3356
|
|
|
3023
|
-
// Header
|
|
3357
|
+
// Header — the title names the dialog
|
|
3024
3358
|
const header = this.createElement('div', ['glass-modal__header'], { part: 'header' });
|
|
3025
|
-
this._titleEl = this.createElement('h2', ['glass-modal__title']);
|
|
3359
|
+
this._titleEl = this.createElement('h2', ['glass-modal__title'], { id: 'title' });
|
|
3026
3360
|
this.takeTitle();
|
|
3027
3361
|
this._applyTitle();
|
|
3028
3362
|
header.appendChild(this._titleEl);
|
|
@@ -3043,10 +3377,8 @@ var GlassKitElements = (function (exports) {
|
|
|
3043
3377
|
|
|
3044
3378
|
this._overlay.appendChild(modal);
|
|
3045
3379
|
this._wrapper.appendChild(this._overlay);
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
this._overlay.classList.add('is-active');
|
|
3049
|
-
}
|
|
3380
|
+
// `open` is applied in setupEvents, which also runs when a moved element
|
|
3381
|
+
// comes back.
|
|
3050
3382
|
}
|
|
3051
3383
|
|
|
3052
3384
|
projectLightDom() {
|
|
@@ -3071,33 +3403,49 @@ var GlassKitElements = (function (exports) {
|
|
|
3071
3403
|
setupEvents() {
|
|
3072
3404
|
// Close on overlay click (outside modal)
|
|
3073
3405
|
this._onOverlayClick = (e) => {
|
|
3074
|
-
if (e.target === this._overlay)
|
|
3075
|
-
this.removeAttribute('open');
|
|
3076
|
-
this.emit('glk-close');
|
|
3077
|
-
}
|
|
3406
|
+
if (e.target === this._overlay) this._dismiss();
|
|
3078
3407
|
};
|
|
3079
3408
|
this._overlay.addEventListener('click', this._onOverlayClick);
|
|
3080
3409
|
|
|
3081
|
-
//
|
|
3082
|
-
this.
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
this.emit('glk-close');
|
|
3086
|
-
}
|
|
3410
|
+
// Escape: the dialog would close at once; it fades out like a click outside.
|
|
3411
|
+
this._onCancel = (e) => {
|
|
3412
|
+
e.preventDefault();
|
|
3413
|
+
this._dismiss();
|
|
3087
3414
|
};
|
|
3088
|
-
|
|
3415
|
+
this._overlay.addEventListener('cancel', this._onCancel);
|
|
3416
|
+
|
|
3417
|
+
// The browser may also close the dialog by itself — Chrome does on a
|
|
3418
|
+
// second Escape without user activation in between, skipping cancel.
|
|
3419
|
+
this._onClose = () => {
|
|
3420
|
+
if (this._overlay.open) return; // a late event from an earlier close
|
|
3421
|
+
this._overlay.classList.remove('is-active');
|
|
3422
|
+
if (this.open) this._dismiss();
|
|
3423
|
+
};
|
|
3424
|
+
this._overlay.addEventListener('close', this._onClose);
|
|
3425
|
+
|
|
3426
|
+
if (this.open) this._show();
|
|
3089
3427
|
}
|
|
3090
3428
|
|
|
3091
3429
|
teardownEvents() {
|
|
3092
3430
|
this._overlay?.removeEventListener('click', this._onOverlayClick);
|
|
3093
|
-
|
|
3431
|
+
this._overlay?.removeEventListener('cancel', this._onCancel);
|
|
3432
|
+
this._overlay?.removeEventListener('close', this._onClose);
|
|
3433
|
+
// Taken out of the document, the dialog leaves the top layer but stays
|
|
3434
|
+
// open — shown in place, not modal. Closed now, it opens as a modal again
|
|
3435
|
+
// when the element comes back.
|
|
3436
|
+
clearTimeout(this._closeTimer);
|
|
3437
|
+
this._overlay?.removeEventListener('transitionend', this._onFaded);
|
|
3438
|
+
this._overlay?.classList.remove('is-active');
|
|
3439
|
+
if (this._overlay?.open) this._overlay.close();
|
|
3094
3440
|
}
|
|
3095
3441
|
|
|
3096
3442
|
onAttributeChanged(name, _old, value) {
|
|
3097
3443
|
if (!this._overlay) return;
|
|
3098
3444
|
switch (name) {
|
|
3099
3445
|
case 'open':
|
|
3100
|
-
|
|
3446
|
+
if (!this.isConnected) return; // setupEvents applies it on connect
|
|
3447
|
+
if (this.open) this._show();
|
|
3448
|
+
else this._hide();
|
|
3101
3449
|
break;
|
|
3102
3450
|
case 'title':
|
|
3103
3451
|
if (this.takeTitle(value)) this._applyTitle();
|
|
@@ -3105,11 +3453,52 @@ var GlassKitElements = (function (exports) {
|
|
|
3105
3453
|
}
|
|
3106
3454
|
}
|
|
3107
3455
|
|
|
3456
|
+
_show() {
|
|
3457
|
+
const dialog = this._overlay;
|
|
3458
|
+
clearTimeout(this._closeTimer);
|
|
3459
|
+
dialog.removeEventListener('transitionend', this._onFaded);
|
|
3460
|
+
if (!dialog.open) {
|
|
3461
|
+
dialog.showModal();
|
|
3462
|
+
// The actions are copies in the shadow root; the originals are not shown.
|
|
3463
|
+
(this._footer.querySelector('[autofocus]') || this.querySelector('[autofocus]'))?.focus();
|
|
3464
|
+
}
|
|
3465
|
+
void dialog.offsetHeight; // reflow, so the fade starts from the closed state
|
|
3466
|
+
requestAnimationFrame(() => {
|
|
3467
|
+
if (this.open) dialog.classList.add('is-active');
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3471
|
+
_hide() {
|
|
3472
|
+
const dialog = this._overlay;
|
|
3473
|
+
dialog.classList.remove('is-active');
|
|
3474
|
+
this._onFaded = (event) => {
|
|
3475
|
+
if (event && event.target !== dialog) return; // the panel's own transition
|
|
3476
|
+
clearTimeout(this._closeTimer);
|
|
3477
|
+
dialog.removeEventListener('transitionend', this._onFaded);
|
|
3478
|
+
if (!this.open && dialog.open) dialog.close();
|
|
3479
|
+
};
|
|
3480
|
+
if (!dialog.open || reducedMotion$1()) {
|
|
3481
|
+
this._onFaded();
|
|
3482
|
+
return;
|
|
3483
|
+
}
|
|
3484
|
+
dialog.addEventListener('transitionend', this._onFaded);
|
|
3485
|
+
this._closeTimer = setTimeout(this._onFaded, CLOSE_FALLBACK_MS);
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3488
|
+
/** Closed by the user — a click outside, Escape. */
|
|
3489
|
+
_dismiss() {
|
|
3490
|
+
this.removeAttribute('open');
|
|
3491
|
+
this.emit('glk-close');
|
|
3492
|
+
}
|
|
3493
|
+
|
|
3108
3494
|
show() { this.setAttribute('open', ''); }
|
|
3109
3495
|
close() { this.removeAttribute('open'); }
|
|
3110
3496
|
|
|
3111
3497
|
_applyTitle() {
|
|
3112
|
-
if (this._titleEl)
|
|
3498
|
+
if (!this._titleEl) return;
|
|
3499
|
+
this._titleEl.textContent = this._title || '';
|
|
3500
|
+
if (this._title) this._overlay.setAttribute('aria-labelledby', 'title');
|
|
3501
|
+
else this._overlay.removeAttribute('aria-labelledby');
|
|
3113
3502
|
}
|
|
3114
3503
|
|
|
3115
3504
|
// `title` is the heading, never a tooltip — see GlkElement.takeTitle().
|
|
@@ -3401,9 +3790,9 @@ var GlassKitElements = (function (exports) {
|
|
|
3401
3790
|
render() {
|
|
3402
3791
|
this._anchor = this.createElement('div', ['glass-popover-anchor']);
|
|
3403
3792
|
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
this._anchor.appendChild(
|
|
3793
|
+
this._triggerSlot = document.createElement('slot');
|
|
3794
|
+
this._triggerSlot.setAttribute('name', 'trigger');
|
|
3795
|
+
this._anchor.appendChild(this._triggerSlot);
|
|
3407
3796
|
|
|
3408
3797
|
this._popover = this.createElement('div', ['glass-popover']);
|
|
3409
3798
|
this._applyPlacement();
|
|
@@ -3427,7 +3816,23 @@ var GlassKitElements = (function (exports) {
|
|
|
3427
3816
|
}
|
|
3428
3817
|
}
|
|
3429
3818
|
|
|
3819
|
+
/**
|
|
3820
|
+
* The trigger says whether the popover is open. It lives in the light DOM,
|
|
3821
|
+
* so aria-expanded goes on it directly; <glk-button> and <glk-pill> hand
|
|
3822
|
+
* it on to their native button. Runs again when the trigger is swapped.
|
|
3823
|
+
*/
|
|
3824
|
+
_applyExpanded() {
|
|
3825
|
+
const open = String(this.getBoolAttr('open'));
|
|
3826
|
+
for (const trigger of this._triggerSlot.assignedElements()) {
|
|
3827
|
+
trigger.setAttribute('aria-expanded', open);
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
|
|
3430
3831
|
setupEvents() {
|
|
3832
|
+
this._onSlotChange = () => this._applyExpanded();
|
|
3833
|
+
this._triggerSlot.addEventListener('slotchange', this._onSlotChange);
|
|
3834
|
+
this._applyExpanded();
|
|
3835
|
+
|
|
3431
3836
|
// Toggle when the slotted trigger is clicked.
|
|
3432
3837
|
this._onTriggerClick = (e) => {
|
|
3433
3838
|
const path = e.composedPath();
|
|
@@ -3459,6 +3864,7 @@ var GlassKitElements = (function (exports) {
|
|
|
3459
3864
|
}
|
|
3460
3865
|
|
|
3461
3866
|
teardownEvents() {
|
|
3867
|
+
this._triggerSlot?.removeEventListener('slotchange', this._onSlotChange);
|
|
3462
3868
|
this.removeEventListener('click', this._onTriggerClick);
|
|
3463
3869
|
document.removeEventListener('click', this._onDocClick);
|
|
3464
3870
|
document.removeEventListener('keydown', this._onKeydown);
|
|
@@ -3470,6 +3876,7 @@ var GlassKitElements = (function (exports) {
|
|
|
3470
3876
|
case 'open': {
|
|
3471
3877
|
const isOpen = this.getBoolAttr('open');
|
|
3472
3878
|
this._popover.classList.toggle('is-open', isOpen);
|
|
3879
|
+
this._applyExpanded();
|
|
3473
3880
|
this.emit(isOpen ? 'glk-open' : 'glk-close');
|
|
3474
3881
|
break;
|
|
3475
3882
|
}
|
|
@@ -3662,17 +4069,19 @@ var GlassKitElements = (function (exports) {
|
|
|
3662
4069
|
|
|
3663
4070
|
render() {
|
|
3664
4071
|
this._item = this.createElement('div', ['glass-accordion__item']);
|
|
3665
|
-
if (this.getBoolAttr('open')) this._item.classList.add('is-open');
|
|
3666
4072
|
|
|
3667
|
-
// Trigger button
|
|
3668
|
-
this._trigger = this.createElement('button', ['glass-accordion__trigger']
|
|
4073
|
+
// Trigger button — says whether its section is open, and which one it is
|
|
4074
|
+
this._trigger = this.createElement('button', ['glass-accordion__trigger'], {
|
|
4075
|
+
type: 'button',
|
|
4076
|
+
'aria-controls': 'content'
|
|
4077
|
+
});
|
|
3669
4078
|
this.takeTitle();
|
|
3670
4079
|
this._triggerText = document.createTextNode(this._title || '');
|
|
3671
4080
|
this._trigger.appendChild(this._triggerText);
|
|
3672
4081
|
this._trigger.insertAdjacentHTML('beforeend', CHEVRON_SVG);
|
|
3673
4082
|
|
|
3674
4083
|
// Content
|
|
3675
|
-
this._content = this.createElement('div', ['glass-accordion__content']);
|
|
4084
|
+
this._content = this.createElement('div', ['glass-accordion__content'], { id: 'content' });
|
|
3676
4085
|
const body = this.createElement('div', ['glass-accordion__body']);
|
|
3677
4086
|
body.appendChild(document.createElement('slot'));
|
|
3678
4087
|
this._content.appendChild(body);
|
|
@@ -3681,6 +4090,19 @@ var GlassKitElements = (function (exports) {
|
|
|
3681
4090
|
this._item.appendChild(this._content);
|
|
3682
4091
|
|
|
3683
4092
|
this._wrapper.appendChild(this._item);
|
|
4093
|
+
this._applyOpen();
|
|
4094
|
+
}
|
|
4095
|
+
|
|
4096
|
+
/**
|
|
4097
|
+
* A closed section is only squeezed to zero height; its links and fields
|
|
4098
|
+
* stayed in the tab order. inert takes them out, and out of the
|
|
4099
|
+
* accessibility tree, until the section opens.
|
|
4100
|
+
*/
|
|
4101
|
+
_applyOpen() {
|
|
4102
|
+
const open = this.getBoolAttr('open');
|
|
4103
|
+
this._item.classList.toggle('is-open', open);
|
|
4104
|
+
this._trigger.setAttribute('aria-expanded', String(open));
|
|
4105
|
+
this._content.inert = !open;
|
|
3684
4106
|
}
|
|
3685
4107
|
|
|
3686
4108
|
setupEvents() {
|
|
@@ -3699,7 +4121,7 @@ var GlassKitElements = (function (exports) {
|
|
|
3699
4121
|
if (!this._item) return;
|
|
3700
4122
|
switch (name) {
|
|
3701
4123
|
case 'open':
|
|
3702
|
-
this.
|
|
4124
|
+
this._applyOpen();
|
|
3703
4125
|
break;
|
|
3704
4126
|
case 'title':
|
|
3705
4127
|
if (this.takeTitle(value)) this._applyTitle();
|