@jungherz-de/glasskit-elements 1.19.1 → 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 +36 -0
- package/README.md +40 -27
- package/SKILL.md +107 -25
- 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 +7 -4
- package/dist/components/glk-checkbox.js +12 -2
- package/dist/components/glk-date-strip.js +5 -4
- 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/components/shared/{dates-CNWaJf09.js → dates-D4JTqoiG.js} +25 -4
- package/dist/glasskit-elements.esm.js +519 -75
- package/dist/glasskit-elements.js +519 -75
- 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 +6 -3
- 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-date-strip.js +4 -3
- package/src/components/navigation/glk-pill.js +14 -1
- package/src/dates.js +25 -4
|
@@ -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);
|
|
@@ -695,8 +843,8 @@ var GlassKitElements = (function (exports) {
|
|
|
695
843
|
// Date helpers shared by <glk-date-strip> and <glk-calendar>. Everything
|
|
696
844
|
// works on local calendar days — a date is "YYYY-MM-DD" in the element API
|
|
697
845
|
// and a local Date inside — so a day never shifts across midnight the way a
|
|
698
|
-
// UTC timestamp would. Names come from Intl,
|
|
699
|
-
//
|
|
846
|
+
// UTC timestamp would. Names come from Intl, in the language resolveLocale()
|
|
847
|
+
// finds for the element.
|
|
700
848
|
|
|
701
849
|
const pad = n => String(n).padStart(2, '0');
|
|
702
850
|
|
|
@@ -724,8 +872,29 @@ var GlassKitElements = (function (exports) {
|
|
|
724
872
|
}
|
|
725
873
|
}
|
|
726
874
|
|
|
727
|
-
|
|
728
|
-
|
|
875
|
+
/**
|
|
876
|
+
* The language to name days and months in: the element's locale attribute;
|
|
877
|
+
* else the language of the page around it — the lang of the nearest
|
|
878
|
+
* ancestor, looked up across shadow roots through their hosts, so
|
|
879
|
+
* <html lang="de"> reaches an element inside another component's shadow
|
|
880
|
+
* tree and a <section lang="en"> in a German page stays English; else the
|
|
881
|
+
* browser's; else English. An empty lang means "unknown" in HTML and falls
|
|
882
|
+
* through to the browser's language. (Since 1.19.2 — before, the browser's
|
|
883
|
+
* language came right after the attribute.)
|
|
884
|
+
*/
|
|
885
|
+
function resolveLocale(attr, el) {
|
|
886
|
+
if (attr) return attr;
|
|
887
|
+
for (let node = el; node; ) {
|
|
888
|
+
const tagged = node.closest?.('[lang]');
|
|
889
|
+
if (tagged) {
|
|
890
|
+
const lang = tagged.getAttribute('lang').trim();
|
|
891
|
+
if (lang) return lang;
|
|
892
|
+
break;
|
|
893
|
+
}
|
|
894
|
+
const root = node.getRootNode?.();
|
|
895
|
+
node = typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot ? root.host : null;
|
|
896
|
+
}
|
|
897
|
+
return (typeof navigator !== 'undefined' && navigator.language) || 'en';
|
|
729
898
|
}
|
|
730
899
|
|
|
731
900
|
// Intl formatters are cheap to keep and not to make; one set per locale.
|
|
@@ -793,7 +962,8 @@ var GlassKitElements = (function (exports) {
|
|
|
793
962
|
// Attributes: start (YYYY-MM-DD, default today), days (count, default 7),
|
|
794
963
|
// value (YYYY-MM-DD), today (YYYY-MM-DD, default the browser's
|
|
795
964
|
// day), marks (JSON {date: tone | {tone, disabled}}), locale
|
|
796
|
-
// (default the
|
|
965
|
+
// (default the page language, else the browser's), label
|
|
966
|
+
// (aria-label of the group)
|
|
797
967
|
// Properties: value, marks (object or JSON text), locale, label
|
|
798
968
|
// Event: glk-change { value } — only on a change made by the user
|
|
799
969
|
// Part: strip
|
|
@@ -826,7 +996,7 @@ var GlassKitElements = (function (exports) {
|
|
|
826
996
|
}
|
|
827
997
|
|
|
828
998
|
_build() {
|
|
829
|
-
const f = formatters(resolveLocale(this.getAttribute('locale')));
|
|
999
|
+
const f = formatters(resolveLocale(this.getAttribute('locale'), this));
|
|
830
1000
|
const marks = parseJsonObject(this.getAttribute('marks'));
|
|
831
1001
|
const start = parseIso(this.getAttribute('start')) ?? new Date();
|
|
832
1002
|
const today = this.getAttribute('today') || isoDate(new Date());
|
|
@@ -938,7 +1108,7 @@ var GlassKitElements = (function (exports) {
|
|
|
938
1108
|
get marks() { return parseJsonObject(this.getAttribute('marks')); }
|
|
939
1109
|
set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
|
|
940
1110
|
|
|
941
|
-
get locale() { return resolveLocale(this.getAttribute('locale')); }
|
|
1111
|
+
get locale() { return resolveLocale(this.getAttribute('locale'), this); }
|
|
942
1112
|
set locale(v) {
|
|
943
1113
|
if (v) this.setAttribute('locale', v);
|
|
944
1114
|
else this.removeAttribute('locale');
|
|
@@ -1281,9 +1451,24 @@ var GlassKitElements = (function (exports) {
|
|
|
1281
1451
|
const VARIANTS$3 = ['primary', 'secondary', 'tertiary'];
|
|
1282
1452
|
const SIZES$1 = ['sm', 'md', 'lg', 'auto'];
|
|
1283
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
|
+
|
|
1284
1459
|
class GlkButton extends GlkElement {
|
|
1285
1460
|
static get observedAttributes() {
|
|
1286
|
-
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();
|
|
1287
1472
|
}
|
|
1288
1473
|
|
|
1289
1474
|
render() {
|
|
@@ -1294,6 +1479,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1294
1479
|
if (this.getBoolAttr('disabled')) {
|
|
1295
1480
|
this._btn.disabled = true;
|
|
1296
1481
|
}
|
|
1482
|
+
for (const attr of FORWARDED_ARIA) this._forward(attr);
|
|
1297
1483
|
|
|
1298
1484
|
this._btn.appendChild(document.createElement('slot'));
|
|
1299
1485
|
this._wrapper.appendChild(this._btn);
|
|
@@ -1307,12 +1493,50 @@ var GlassKitElements = (function (exports) {
|
|
|
1307
1493
|
return;
|
|
1308
1494
|
}
|
|
1309
1495
|
this.emit('glk-click');
|
|
1496
|
+
this._activateForm(e);
|
|
1310
1497
|
};
|
|
1311
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);
|
|
1312
1501
|
}
|
|
1313
1502
|
|
|
1314
1503
|
teardownEvents() {
|
|
1315
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
|
+
});
|
|
1316
1540
|
}
|
|
1317
1541
|
|
|
1318
1542
|
onAttributeChanged(name) {
|
|
@@ -1328,9 +1552,17 @@ var GlassKitElements = (function (exports) {
|
|
|
1328
1552
|
case 'type':
|
|
1329
1553
|
this._btn.setAttribute('type', this.getAttribute('type') || 'button');
|
|
1330
1554
|
break;
|
|
1555
|
+
default:
|
|
1556
|
+
if (FORWARDED_ARIA.includes(name)) this._forward(name);
|
|
1331
1557
|
}
|
|
1332
1558
|
}
|
|
1333
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
|
+
|
|
1334
1566
|
_computeClasses() {
|
|
1335
1567
|
const classes = ['glass-btn'];
|
|
1336
1568
|
const variant = this.getAttribute('variant');
|
|
@@ -1352,6 +1584,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1352
1584
|
|
|
1353
1585
|
get disabled() { return this.getBoolAttr('disabled'); }
|
|
1354
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; }
|
|
1355
1592
|
}
|
|
1356
1593
|
|
|
1357
1594
|
customElements.define('glk-button', GlkButton);
|
|
@@ -1370,12 +1607,15 @@ var GlassKitElements = (function (exports) {
|
|
|
1370
1607
|
render() {
|
|
1371
1608
|
const group = this.createElement('div', ['glass-input-group']);
|
|
1372
1609
|
|
|
1373
|
-
// Label
|
|
1374
|
-
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' });
|
|
1375
1614
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
1376
1615
|
|
|
1377
1616
|
// Input
|
|
1378
1617
|
this._input = this.createElement('input', this._computeInputClasses(), {
|
|
1618
|
+
id: 'field',
|
|
1379
1619
|
type: this.getAttribute('type') || 'text'
|
|
1380
1620
|
});
|
|
1381
1621
|
|
|
@@ -1392,8 +1632,8 @@ var GlassKitElements = (function (exports) {
|
|
|
1392
1632
|
if (this.getBoolAttr('required')) this._input.required = true;
|
|
1393
1633
|
for (const attr of FORWARDED) this._forward(attr);
|
|
1394
1634
|
|
|
1395
|
-
// Hint
|
|
1396
|
-
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' });
|
|
1397
1637
|
this._hintEl.textContent = this.getAttribute('hint') || '';
|
|
1398
1638
|
|
|
1399
1639
|
group.appendChild(this._labelEl);
|
|
@@ -1403,6 +1643,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1403
1643
|
this._group = group;
|
|
1404
1644
|
this._wrapper.appendChild(group);
|
|
1405
1645
|
|
|
1646
|
+
this._applyDescription();
|
|
1406
1647
|
this._syncFormValue();
|
|
1407
1648
|
}
|
|
1408
1649
|
|
|
@@ -1440,12 +1681,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1440
1681
|
case 'error':
|
|
1441
1682
|
this._input.className = this._computeInputClasses().join(' ');
|
|
1442
1683
|
this._hintEl.className = this._computeHintClasses().join(' ');
|
|
1684
|
+
this._applyDescription();
|
|
1443
1685
|
break;
|
|
1444
1686
|
case 'hint':
|
|
1445
1687
|
this._hintEl.textContent = this.getAttribute('hint') || '';
|
|
1446
1688
|
if (this.getAttribute('hint') && !this._hintEl.parentNode) {
|
|
1447
1689
|
this._group.appendChild(this._hintEl);
|
|
1448
1690
|
}
|
|
1691
|
+
this._applyDescription();
|
|
1449
1692
|
break;
|
|
1450
1693
|
case 'disabled':
|
|
1451
1694
|
this._input.disabled = this.getBoolAttr('disabled');
|
|
@@ -1465,6 +1708,19 @@ var GlassKitElements = (function (exports) {
|
|
|
1465
1708
|
}
|
|
1466
1709
|
}
|
|
1467
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
|
+
|
|
1468
1724
|
_forward(attr) {
|
|
1469
1725
|
const value = this.getAttribute(attr);
|
|
1470
1726
|
if (value === null) this._input.removeAttribute(attr);
|
|
@@ -1483,6 +1739,8 @@ var GlassKitElements = (function (exports) {
|
|
|
1483
1739
|
return classes;
|
|
1484
1740
|
}
|
|
1485
1741
|
|
|
1742
|
+
get _validityField() { return this._input; }
|
|
1743
|
+
|
|
1486
1744
|
_syncFormValue() {
|
|
1487
1745
|
this.setFormValue(this._input.value);
|
|
1488
1746
|
}
|
|
@@ -1515,10 +1773,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1515
1773
|
render() {
|
|
1516
1774
|
const group = this.createElement('div', ['glass-input-group']);
|
|
1517
1775
|
|
|
1518
|
-
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' });
|
|
1519
1778
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
1520
1779
|
|
|
1521
|
-
this._textarea = this.createElement('textarea', ['glass-textarea']);
|
|
1780
|
+
this._textarea = this.createElement('textarea', ['glass-textarea'], { id: 'field' });
|
|
1522
1781
|
const placeholder = this.getAttribute('placeholder');
|
|
1523
1782
|
if (placeholder) this._textarea.setAttribute('placeholder', placeholder);
|
|
1524
1783
|
|
|
@@ -1576,9 +1835,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1576
1835
|
this._textarea.value = this.getAttribute('value') || '';
|
|
1577
1836
|
this._syncFormValue();
|
|
1578
1837
|
break;
|
|
1838
|
+
case 'required':
|
|
1839
|
+
this._textarea.required = this.getBoolAttr('required');
|
|
1840
|
+
break;
|
|
1579
1841
|
}
|
|
1580
1842
|
}
|
|
1581
1843
|
|
|
1844
|
+
get _validityField() { return this._textarea; }
|
|
1845
|
+
|
|
1582
1846
|
_syncFormValue() {
|
|
1583
1847
|
this.setFormValue(this._textarea.value);
|
|
1584
1848
|
}
|
|
@@ -1610,10 +1874,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1610
1874
|
render() {
|
|
1611
1875
|
const group = this.createElement('div', ['glass-input-group']);
|
|
1612
1876
|
|
|
1613
|
-
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' });
|
|
1614
1879
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
1615
1880
|
|
|
1616
|
-
this._select = this.createElement('select', ['glass-select']);
|
|
1881
|
+
this._select = this.createElement('select', ['glass-select'], { id: 'field' });
|
|
1617
1882
|
|
|
1618
1883
|
const name = this.getAttribute('name');
|
|
1619
1884
|
if (name) this._select.setAttribute('name', name);
|
|
@@ -1701,9 +1966,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1701
1966
|
this._applyValue(this.getAttribute('value'));
|
|
1702
1967
|
this._syncFormValue();
|
|
1703
1968
|
break;
|
|
1969
|
+
case 'required':
|
|
1970
|
+
this._select.required = this.getBoolAttr('required');
|
|
1971
|
+
break;
|
|
1704
1972
|
}
|
|
1705
1973
|
}
|
|
1706
1974
|
|
|
1975
|
+
get _validityField() { return this._select; }
|
|
1976
|
+
|
|
1707
1977
|
_syncFormValue() {
|
|
1708
1978
|
this.setFormValue(this._select.value);
|
|
1709
1979
|
}
|
|
@@ -1729,7 +1999,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1729
1999
|
|
|
1730
2000
|
class GlkSearch extends GlkFormElement {
|
|
1731
2001
|
static get observedAttributes() {
|
|
1732
|
-
return ['placeholder', 'name', 'value', 'disabled'];
|
|
2002
|
+
return ['placeholder', 'name', 'value', 'disabled', 'label'];
|
|
1733
2003
|
}
|
|
1734
2004
|
|
|
1735
2005
|
render() {
|
|
@@ -1745,6 +2015,10 @@ var GlassKitElements = (function (exports) {
|
|
|
1745
2015
|
const placeholder = this.getAttribute('placeholder');
|
|
1746
2016
|
if (placeholder) this._input.setAttribute('placeholder', placeholder);
|
|
1747
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
|
+
|
|
1748
2022
|
const name = this.getAttribute('name');
|
|
1749
2023
|
if (name) this._input.setAttribute('name', name);
|
|
1750
2024
|
|
|
@@ -1789,9 +2063,18 @@ var GlassKitElements = (function (exports) {
|
|
|
1789
2063
|
case 'disabled':
|
|
1790
2064
|
this._input.disabled = this.getBoolAttr('disabled');
|
|
1791
2065
|
break;
|
|
2066
|
+
case 'label':
|
|
2067
|
+
this._applyLabel();
|
|
2068
|
+
break;
|
|
1792
2069
|
}
|
|
1793
2070
|
}
|
|
1794
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
|
+
|
|
1795
2078
|
_syncFormValue() {
|
|
1796
2079
|
this.setFormValue(this._input.value);
|
|
1797
2080
|
}
|
|
@@ -1812,14 +2095,21 @@ var GlassKitElements = (function (exports) {
|
|
|
1812
2095
|
|
|
1813
2096
|
class GlkToggle extends GlkFormElement {
|
|
1814
2097
|
static get observedAttributes() {
|
|
1815
|
-
return ['checked', 'disabled', 'label', 'name', 'value'];
|
|
2098
|
+
return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
|
|
1816
2099
|
}
|
|
1817
2100
|
|
|
2101
|
+
static get hostStyles() { return checkControlSheet; }
|
|
2102
|
+
|
|
1818
2103
|
render() {
|
|
1819
2104
|
const label = this.createElement('label', ['glass-toggle']);
|
|
1820
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.
|
|
1821
2110
|
this._input = this.createElement('input', ['glass-toggle__input'], {
|
|
1822
|
-
type: 'checkbox'
|
|
2111
|
+
type: 'checkbox',
|
|
2112
|
+
role: 'switch'
|
|
1823
2113
|
});
|
|
1824
2114
|
|
|
1825
2115
|
const name = this.getAttribute('name');
|
|
@@ -1838,14 +2128,12 @@ var GlassKitElements = (function (exports) {
|
|
|
1838
2128
|
|
|
1839
2129
|
if (this.getBoolAttr('checked')) this._input.checked = true;
|
|
1840
2130
|
if (this.getBoolAttr('disabled')) this._input.disabled = true;
|
|
2131
|
+
if (this.getBoolAttr('required')) this._input.required = true;
|
|
1841
2132
|
|
|
1842
2133
|
this._defaultChecked = this.getBoolAttr('checked');
|
|
1843
2134
|
this._wrapper.appendChild(label);
|
|
1844
2135
|
|
|
1845
2136
|
this._syncFormValue();
|
|
1846
|
-
this.setAttribute('role', 'switch');
|
|
1847
|
-
this.setAttribute('aria-checked', String(this._input.checked));
|
|
1848
|
-
if (this.getBoolAttr('disabled')) this.setAttribute('aria-disabled', 'true');
|
|
1849
2137
|
}
|
|
1850
2138
|
|
|
1851
2139
|
setupEvents() {
|
|
@@ -1853,16 +2141,17 @@ var GlassKitElements = (function (exports) {
|
|
|
1853
2141
|
this._syncing = true;
|
|
1854
2142
|
this.setBoolAttr('checked', this._input.checked);
|
|
1855
2143
|
this._syncing = false;
|
|
1856
|
-
this.setAttribute('aria-checked', String(this._input.checked));
|
|
1857
2144
|
this._syncFormValue();
|
|
1858
2145
|
this.emit('glk-change', { checked: this._input.checked });
|
|
1859
2146
|
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
1860
2147
|
};
|
|
1861
2148
|
this._input.addEventListener('change', this._onChange);
|
|
2149
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._input);
|
|
1862
2150
|
}
|
|
1863
2151
|
|
|
1864
2152
|
teardownEvents() {
|
|
1865
2153
|
this._input?.removeEventListener('change', this._onChange);
|
|
2154
|
+
this._unforwardClicks?.();
|
|
1866
2155
|
}
|
|
1867
2156
|
|
|
1868
2157
|
onAttributeChanged(name) {
|
|
@@ -1871,12 +2160,10 @@ var GlassKitElements = (function (exports) {
|
|
|
1871
2160
|
switch (name) {
|
|
1872
2161
|
case 'checked':
|
|
1873
2162
|
this._input.checked = this.getBoolAttr('checked');
|
|
1874
|
-
this.setAttribute('aria-checked', String(this._input.checked));
|
|
1875
2163
|
this._syncFormValue();
|
|
1876
2164
|
break;
|
|
1877
2165
|
case 'disabled':
|
|
1878
2166
|
this._input.disabled = this.getBoolAttr('disabled');
|
|
1879
|
-
this.setAttribute('aria-disabled', String(this.getBoolAttr('disabled')));
|
|
1880
2167
|
break;
|
|
1881
2168
|
case 'label':
|
|
1882
2169
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
@@ -1884,9 +2171,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1884
2171
|
case 'name':
|
|
1885
2172
|
this._input.setAttribute('name', this.getAttribute('name') || '');
|
|
1886
2173
|
break;
|
|
2174
|
+
case 'required':
|
|
2175
|
+
this._input.required = this.getBoolAttr('required');
|
|
2176
|
+
break;
|
|
1887
2177
|
}
|
|
1888
2178
|
}
|
|
1889
2179
|
|
|
2180
|
+
get _validityField() { return this._input; }
|
|
2181
|
+
|
|
1890
2182
|
_syncFormValue() {
|
|
1891
2183
|
const val = this.getAttribute('value') || 'on';
|
|
1892
2184
|
this.setFormValue(this._input.checked ? val : null);
|
|
@@ -1895,7 +2187,6 @@ var GlassKitElements = (function (exports) {
|
|
|
1895
2187
|
resetValue() {
|
|
1896
2188
|
this._input.checked = this._defaultChecked;
|
|
1897
2189
|
this.setBoolAttr('checked', this._defaultChecked);
|
|
1898
|
-
this.setAttribute('aria-checked', String(this._defaultChecked));
|
|
1899
2190
|
this._syncFormValue();
|
|
1900
2191
|
}
|
|
1901
2192
|
|
|
@@ -1910,7 +2201,6 @@ var GlassKitElements = (function (exports) {
|
|
|
1910
2201
|
set checked(v) {
|
|
1911
2202
|
if (this._input) this._input.checked = v;
|
|
1912
2203
|
this.setBoolAttr('checked', v);
|
|
1913
|
-
this.setAttribute('aria-checked', String(v));
|
|
1914
2204
|
this._syncFormValue();
|
|
1915
2205
|
}
|
|
1916
2206
|
|
|
@@ -1933,9 +2223,11 @@ var GlassKitElements = (function (exports) {
|
|
|
1933
2223
|
|
|
1934
2224
|
class GlkCheckbox extends GlkFormElement {
|
|
1935
2225
|
static get observedAttributes() {
|
|
1936
|
-
return ['checked', 'disabled', 'label', 'name', 'value'];
|
|
2226
|
+
return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
|
|
1937
2227
|
}
|
|
1938
2228
|
|
|
2229
|
+
static get hostStyles() { return checkControlSheet; }
|
|
2230
|
+
|
|
1939
2231
|
render() {
|
|
1940
2232
|
const label = this.createElement('label', ['glass-checkbox']);
|
|
1941
2233
|
|
|
@@ -1958,6 +2250,7 @@ var GlassKitElements = (function (exports) {
|
|
|
1958
2250
|
|
|
1959
2251
|
if (this.getBoolAttr('checked')) this._input.checked = true;
|
|
1960
2252
|
if (this.getBoolAttr('disabled')) this._input.disabled = true;
|
|
2253
|
+
if (this.getBoolAttr('required')) this._input.required = true;
|
|
1961
2254
|
|
|
1962
2255
|
this._defaultChecked = this.getBoolAttr('checked');
|
|
1963
2256
|
this._wrapper.appendChild(label);
|
|
@@ -1974,10 +2267,12 @@ var GlassKitElements = (function (exports) {
|
|
|
1974
2267
|
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
1975
2268
|
};
|
|
1976
2269
|
this._input.addEventListener('change', this._onChange);
|
|
2270
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._input);
|
|
1977
2271
|
}
|
|
1978
2272
|
|
|
1979
2273
|
teardownEvents() {
|
|
1980
2274
|
this._input?.removeEventListener('change', this._onChange);
|
|
2275
|
+
this._unforwardClicks?.();
|
|
1981
2276
|
}
|
|
1982
2277
|
|
|
1983
2278
|
onAttributeChanged(name) {
|
|
@@ -1997,9 +2292,14 @@ var GlassKitElements = (function (exports) {
|
|
|
1997
2292
|
case 'name':
|
|
1998
2293
|
this._input.setAttribute('name', this.getAttribute('name') || '');
|
|
1999
2294
|
break;
|
|
2295
|
+
case 'required':
|
|
2296
|
+
this._input.required = this.getBoolAttr('required');
|
|
2297
|
+
break;
|
|
2000
2298
|
}
|
|
2001
2299
|
}
|
|
2002
2300
|
|
|
2301
|
+
get _validityField() { return this._input; }
|
|
2302
|
+
|
|
2003
2303
|
_syncFormValue() {
|
|
2004
2304
|
const val = this.getAttribute('value') || 'on';
|
|
2005
2305
|
this.setFormValue(this._input.checked ? val : null);
|
|
@@ -2059,9 +2359,11 @@ var GlassKitElements = (function (exports) {
|
|
|
2059
2359
|
|
|
2060
2360
|
class GlkRadio extends GlkFormElement {
|
|
2061
2361
|
static get observedAttributes() {
|
|
2062
|
-
return ['checked', 'disabled', 'label', 'name', 'value'];
|
|
2362
|
+
return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
|
|
2063
2363
|
}
|
|
2064
2364
|
|
|
2365
|
+
static get hostStyles() { return checkControlSheet; }
|
|
2366
|
+
|
|
2065
2367
|
render() {
|
|
2066
2368
|
const label = this.createElement('label', ['glass-radio']);
|
|
2067
2369
|
|
|
@@ -2116,11 +2418,13 @@ var GlassKitElements = (function (exports) {
|
|
|
2116
2418
|
|
|
2117
2419
|
this._input.addEventListener('change', this._onChange);
|
|
2118
2420
|
this._input.addEventListener('keydown', this._onKeyDown);
|
|
2421
|
+
this._unforwardClicks = forwardHostClicks(this, () => this._input);
|
|
2119
2422
|
}
|
|
2120
2423
|
|
|
2121
2424
|
teardownEvents() {
|
|
2122
2425
|
this._input?.removeEventListener('change', this._onChange);
|
|
2123
2426
|
this._input?.removeEventListener('keydown', this._onKeyDown);
|
|
2427
|
+
this._unforwardClicks?.();
|
|
2124
2428
|
}
|
|
2125
2429
|
|
|
2126
2430
|
/** Shared by user change and arrow-key selection, so both look identical. */
|
|
@@ -2155,6 +2459,26 @@ var GlassKitElements = (function (exports) {
|
|
|
2155
2459
|
}
|
|
2156
2460
|
}
|
|
2157
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
|
+
|
|
2158
2482
|
onAttributeChanged(name) {
|
|
2159
2483
|
if (this._syncing) return;
|
|
2160
2484
|
if (!this._input) return;
|
|
@@ -2228,7 +2552,8 @@ var GlassKitElements = (function (exports) {
|
|
|
2228
2552
|
|
|
2229
2553
|
const header = this.createElement('div', ['glass-range-header']);
|
|
2230
2554
|
|
|
2231
|
-
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' });
|
|
2232
2557
|
this._labelEl.textContent = this.getAttribute('label') || '';
|
|
2233
2558
|
|
|
2234
2559
|
this._valueEl = this.createElement('span', ['glass-range-value']);
|
|
@@ -2237,6 +2562,7 @@ var GlassKitElements = (function (exports) {
|
|
|
2237
2562
|
header.appendChild(this._valueEl);
|
|
2238
2563
|
|
|
2239
2564
|
this._input = this.createElement('input', ['glass-range'], {
|
|
2565
|
+
id: 'field',
|
|
2240
2566
|
type: 'range',
|
|
2241
2567
|
min: this.getAttribute('min') || '0',
|
|
2242
2568
|
max: this.getAttribute('max') || '100',
|
|
@@ -2366,6 +2692,10 @@ var GlassKitElements = (function (exports) {
|
|
|
2366
2692
|
class GlkSegmented extends GlkFormElement {
|
|
2367
2693
|
static get observedAttributes() { return ['options', 'value', 'full', 'overflow', 'label']; }
|
|
2368
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
|
+
|
|
2369
2699
|
render() {
|
|
2370
2700
|
this._group = this.createElement('div', ['glass-segmented'], { role: 'group', part: 'group' });
|
|
2371
2701
|
this._wrapper.appendChild(this._group);
|
|
@@ -2490,7 +2820,7 @@ var GlassKitElements = (function (exports) {
|
|
|
2490
2820
|
// today), value (YYYY-MM-DD), today (YYYY-MM-DD), min, max
|
|
2491
2821
|
// (YYYY-MM-DD; days outside cannot be picked), marks (JSON
|
|
2492
2822
|
// {date: tone | [tone, …]}, up to three dots), locale (default
|
|
2493
|
-
// the
|
|
2823
|
+
// the page language, else the browser's), week-start (0 = Sunday … 6 = Saturday;
|
|
2494
2824
|
// default from the locale, Monday where the browser cannot say),
|
|
2495
2825
|
// label (aria-label of the day group), prev-label / next-label
|
|
2496
2826
|
// (names of the nav buttons, English by default)
|
|
@@ -2528,6 +2858,9 @@ var GlassKitElements = (function (exports) {
|
|
|
2528
2858
|
return ['month', 'value', 'today', 'min', 'max', 'marks', 'locale', 'week-start', 'label', 'prev-label', 'next-label'];
|
|
2529
2859
|
}
|
|
2530
2860
|
|
|
2861
|
+
// Delegated focus would land on the month arrow, not on the chosen day.
|
|
2862
|
+
static get delegatesFocus() { return false; }
|
|
2863
|
+
|
|
2531
2864
|
render() {
|
|
2532
2865
|
this._root = this.createElement('div', ['glass-calendar'], { part: 'calendar' });
|
|
2533
2866
|
const head = this.createElement('div', ['glass-calendar__head'], { part: 'head' });
|
|
@@ -2548,7 +2881,7 @@ var GlassKitElements = (function (exports) {
|
|
|
2548
2881
|
get _todayIso() { return this.getAttribute('today') || isoDate(new Date()); }
|
|
2549
2882
|
|
|
2550
2883
|
_build() {
|
|
2551
|
-
const locale = resolveLocale(this.getAttribute('locale'));
|
|
2884
|
+
const locale = resolveLocale(this.getAttribute('locale'), this);
|
|
2552
2885
|
const f = formatters(locale);
|
|
2553
2886
|
const month = this.month;
|
|
2554
2887
|
const first = parseIso(month);
|
|
@@ -2725,7 +3058,7 @@ var GlassKitElements = (function (exports) {
|
|
|
2725
3058
|
get marks() { return parseJsonObject(this.getAttribute('marks')); }
|
|
2726
3059
|
set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
|
|
2727
3060
|
|
|
2728
|
-
get locale() { return resolveLocale(this.getAttribute('locale')); }
|
|
3061
|
+
get locale() { return resolveLocale(this.getAttribute('locale'), this); }
|
|
2729
3062
|
set locale(v) {
|
|
2730
3063
|
if (v) this.setAttribute('locale', v);
|
|
2731
3064
|
else this.removeAttribute('locale');
|
|
@@ -2986,6 +3319,29 @@ var GlassKitElements = (function (exports) {
|
|
|
2986
3319
|
|
|
2987
3320
|
customElements.define('glk-progress', GlkProgress);
|
|
2988
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
|
+
|
|
2989
3345
|
class GlkModal extends GlkElement {
|
|
2990
3346
|
static get observedAttributes() {
|
|
2991
3347
|
return ['open', 'title'];
|
|
@@ -2994,13 +3350,13 @@ var GlassKitElements = (function (exports) {
|
|
|
2994
3350
|
static get observesLightDom() { return true; }
|
|
2995
3351
|
|
|
2996
3352
|
render() {
|
|
2997
|
-
this._overlay = this.createElement('
|
|
3353
|
+
this._overlay = this.createElement('dialog', ['glass-modal-overlay'], { part: 'overlay' });
|
|
2998
3354
|
|
|
2999
3355
|
const modal = this.createElement('div', ['glass-modal'], { part: 'modal' });
|
|
3000
3356
|
|
|
3001
|
-
// Header
|
|
3357
|
+
// Header — the title names the dialog
|
|
3002
3358
|
const header = this.createElement('div', ['glass-modal__header'], { part: 'header' });
|
|
3003
|
-
this._titleEl = this.createElement('h2', ['glass-modal__title']);
|
|
3359
|
+
this._titleEl = this.createElement('h2', ['glass-modal__title'], { id: 'title' });
|
|
3004
3360
|
this.takeTitle();
|
|
3005
3361
|
this._applyTitle();
|
|
3006
3362
|
header.appendChild(this._titleEl);
|
|
@@ -3021,10 +3377,8 @@ var GlassKitElements = (function (exports) {
|
|
|
3021
3377
|
|
|
3022
3378
|
this._overlay.appendChild(modal);
|
|
3023
3379
|
this._wrapper.appendChild(this._overlay);
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
this._overlay.classList.add('is-active');
|
|
3027
|
-
}
|
|
3380
|
+
// `open` is applied in setupEvents, which also runs when a moved element
|
|
3381
|
+
// comes back.
|
|
3028
3382
|
}
|
|
3029
3383
|
|
|
3030
3384
|
projectLightDom() {
|
|
@@ -3049,33 +3403,49 @@ var GlassKitElements = (function (exports) {
|
|
|
3049
3403
|
setupEvents() {
|
|
3050
3404
|
// Close on overlay click (outside modal)
|
|
3051
3405
|
this._onOverlayClick = (e) => {
|
|
3052
|
-
if (e.target === this._overlay)
|
|
3053
|
-
this.removeAttribute('open');
|
|
3054
|
-
this.emit('glk-close');
|
|
3055
|
-
}
|
|
3406
|
+
if (e.target === this._overlay) this._dismiss();
|
|
3056
3407
|
};
|
|
3057
3408
|
this._overlay.addEventListener('click', this._onOverlayClick);
|
|
3058
3409
|
|
|
3059
|
-
//
|
|
3060
|
-
this.
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
this.emit('glk-close');
|
|
3064
|
-
}
|
|
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();
|
|
3065
3414
|
};
|
|
3066
|
-
|
|
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();
|
|
3067
3427
|
}
|
|
3068
3428
|
|
|
3069
3429
|
teardownEvents() {
|
|
3070
3430
|
this._overlay?.removeEventListener('click', this._onOverlayClick);
|
|
3071
|
-
|
|
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();
|
|
3072
3440
|
}
|
|
3073
3441
|
|
|
3074
3442
|
onAttributeChanged(name, _old, value) {
|
|
3075
3443
|
if (!this._overlay) return;
|
|
3076
3444
|
switch (name) {
|
|
3077
3445
|
case 'open':
|
|
3078
|
-
|
|
3446
|
+
if (!this.isConnected) return; // setupEvents applies it on connect
|
|
3447
|
+
if (this.open) this._show();
|
|
3448
|
+
else this._hide();
|
|
3079
3449
|
break;
|
|
3080
3450
|
case 'title':
|
|
3081
3451
|
if (this.takeTitle(value)) this._applyTitle();
|
|
@@ -3083,11 +3453,52 @@ var GlassKitElements = (function (exports) {
|
|
|
3083
3453
|
}
|
|
3084
3454
|
}
|
|
3085
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
|
+
|
|
3086
3494
|
show() { this.setAttribute('open', ''); }
|
|
3087
3495
|
close() { this.removeAttribute('open'); }
|
|
3088
3496
|
|
|
3089
3497
|
_applyTitle() {
|
|
3090
|
-
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');
|
|
3091
3502
|
}
|
|
3092
3503
|
|
|
3093
3504
|
// `title` is the heading, never a tooltip — see GlkElement.takeTitle().
|
|
@@ -3379,9 +3790,9 @@ var GlassKitElements = (function (exports) {
|
|
|
3379
3790
|
render() {
|
|
3380
3791
|
this._anchor = this.createElement('div', ['glass-popover-anchor']);
|
|
3381
3792
|
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
this._anchor.appendChild(
|
|
3793
|
+
this._triggerSlot = document.createElement('slot');
|
|
3794
|
+
this._triggerSlot.setAttribute('name', 'trigger');
|
|
3795
|
+
this._anchor.appendChild(this._triggerSlot);
|
|
3385
3796
|
|
|
3386
3797
|
this._popover = this.createElement('div', ['glass-popover']);
|
|
3387
3798
|
this._applyPlacement();
|
|
@@ -3405,7 +3816,23 @@ var GlassKitElements = (function (exports) {
|
|
|
3405
3816
|
}
|
|
3406
3817
|
}
|
|
3407
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
|
+
|
|
3408
3831
|
setupEvents() {
|
|
3832
|
+
this._onSlotChange = () => this._applyExpanded();
|
|
3833
|
+
this._triggerSlot.addEventListener('slotchange', this._onSlotChange);
|
|
3834
|
+
this._applyExpanded();
|
|
3835
|
+
|
|
3409
3836
|
// Toggle when the slotted trigger is clicked.
|
|
3410
3837
|
this._onTriggerClick = (e) => {
|
|
3411
3838
|
const path = e.composedPath();
|
|
@@ -3437,6 +3864,7 @@ var GlassKitElements = (function (exports) {
|
|
|
3437
3864
|
}
|
|
3438
3865
|
|
|
3439
3866
|
teardownEvents() {
|
|
3867
|
+
this._triggerSlot?.removeEventListener('slotchange', this._onSlotChange);
|
|
3440
3868
|
this.removeEventListener('click', this._onTriggerClick);
|
|
3441
3869
|
document.removeEventListener('click', this._onDocClick);
|
|
3442
3870
|
document.removeEventListener('keydown', this._onKeydown);
|
|
@@ -3448,6 +3876,7 @@ var GlassKitElements = (function (exports) {
|
|
|
3448
3876
|
case 'open': {
|
|
3449
3877
|
const isOpen = this.getBoolAttr('open');
|
|
3450
3878
|
this._popover.classList.toggle('is-open', isOpen);
|
|
3879
|
+
this._applyExpanded();
|
|
3451
3880
|
this.emit(isOpen ? 'glk-open' : 'glk-close');
|
|
3452
3881
|
break;
|
|
3453
3882
|
}
|
|
@@ -3640,17 +4069,19 @@ var GlassKitElements = (function (exports) {
|
|
|
3640
4069
|
|
|
3641
4070
|
render() {
|
|
3642
4071
|
this._item = this.createElement('div', ['glass-accordion__item']);
|
|
3643
|
-
if (this.getBoolAttr('open')) this._item.classList.add('is-open');
|
|
3644
4072
|
|
|
3645
|
-
// Trigger button
|
|
3646
|
-
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
|
+
});
|
|
3647
4078
|
this.takeTitle();
|
|
3648
4079
|
this._triggerText = document.createTextNode(this._title || '');
|
|
3649
4080
|
this._trigger.appendChild(this._triggerText);
|
|
3650
4081
|
this._trigger.insertAdjacentHTML('beforeend', CHEVRON_SVG);
|
|
3651
4082
|
|
|
3652
4083
|
// Content
|
|
3653
|
-
this._content = this.createElement('div', ['glass-accordion__content']);
|
|
4084
|
+
this._content = this.createElement('div', ['glass-accordion__content'], { id: 'content' });
|
|
3654
4085
|
const body = this.createElement('div', ['glass-accordion__body']);
|
|
3655
4086
|
body.appendChild(document.createElement('slot'));
|
|
3656
4087
|
this._content.appendChild(body);
|
|
@@ -3659,6 +4090,19 @@ var GlassKitElements = (function (exports) {
|
|
|
3659
4090
|
this._item.appendChild(this._content);
|
|
3660
4091
|
|
|
3661
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;
|
|
3662
4106
|
}
|
|
3663
4107
|
|
|
3664
4108
|
setupEvents() {
|
|
@@ -3677,7 +4121,7 @@ var GlassKitElements = (function (exports) {
|
|
|
3677
4121
|
if (!this._item) return;
|
|
3678
4122
|
switch (name) {
|
|
3679
4123
|
case 'open':
|
|
3680
|
-
this.
|
|
4124
|
+
this._applyOpen();
|
|
3681
4125
|
break;
|
|
3682
4126
|
case 'title':
|
|
3683
4127
|
if (this.takeTitle(value)) this._applyTitle();
|