@jungherz-de/glasskit-elements 1.15.2 → 1.16.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/README.md +8 -5
- package/dist/components/glk-calendar.js +261 -0
- package/dist/components/glk-date-strip.js +180 -0
- package/dist/components/glk-image-picker.js +175 -0
- package/dist/components/shared/dates-CNWaJf09.js +76 -0
- package/dist/glasskit-elements.esm.js +680 -3
- package/dist/glasskit-elements.js +682 -2
- package/dist/glasskit-elements.min.js +1 -1
- package/package.json +3 -3
- package/src/components/forms/glk-calendar.js +259 -0
- package/src/components/forms/glk-image-picker.js +173 -0
- package/src/components/navigation/glk-date-strip.js +178 -0
- package/src/dates.js +74 -0
- package/src/index.js +3 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GlassKit v1.
|
|
1
|
+
// GlassKit v1.16.0 – Constructable Stylesheet
|
|
2
2
|
// Auto-generated by build-styles-js.mjs – do not edit manually.
|
|
3
3
|
|
|
4
4
|
// The [data-theme] blocks that declare --gl-* …
|
|
@@ -6,7 +6,7 @@ const tokensCss = ":root,[data-theme=dark]{color-scheme:dark;--gl-color-primary:
|
|
|
6
6
|
|
|
7
7
|
// … and everything else, in two pieces around where they were.
|
|
8
8
|
const componentsHead = "[class*=gl-],[class*=glass-],[class*=glass-]::after,[class*=glass-]::before{box-sizing:border-box}";
|
|
9
|
-
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 ::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: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-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-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.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{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);line-height:1.4}.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--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__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{margin-top: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/*# sourceMappingURL=glasskit.min.css.map */";
|
|
9
|
+
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: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-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-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}.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{font-size:var(--gl-font-size-sm);font-weight:var(--gl-font-weight-medium);color:var(--gl-color-text);line-height:1.4}.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--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__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{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/*# sourceMappingURL=glasskit.min.css.map */";
|
|
10
10
|
|
|
11
11
|
const componentsCss = componentsHead + componentsTail;
|
|
12
12
|
const css = componentsHead + tokensCss + componentsTail;
|
|
@@ -666,6 +666,256 @@ class GlkSteps extends GlkElement {
|
|
|
666
666
|
|
|
667
667
|
customElements.define('glk-steps', GlkSteps);
|
|
668
668
|
|
|
669
|
+
// Date helpers shared by <glk-date-strip> and <glk-calendar>. Everything
|
|
670
|
+
// works on local calendar days — a date is "YYYY-MM-DD" in the element API
|
|
671
|
+
// and a local Date inside — so a day never shifts across midnight the way a
|
|
672
|
+
// UTC timestamp would. Names come from Intl, keyed by the element's locale
|
|
673
|
+
// attribute or the browser language.
|
|
674
|
+
|
|
675
|
+
const pad = n => String(n).padStart(2, '0');
|
|
676
|
+
|
|
677
|
+
/** Local Date → "YYYY-MM-DD". */
|
|
678
|
+
const isoDate = d => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
679
|
+
|
|
680
|
+
/** "YYYY-MM-DD" or "YYYY-MM" → local Date, or null when unreadable. */
|
|
681
|
+
function parseIso(text) {
|
|
682
|
+
const m = /^(\d{4})-(\d{2})(?:-(\d{2}))?$/.exec(String(text ?? '').trim());
|
|
683
|
+
if (!m) return null;
|
|
684
|
+
const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3] ?? 1));
|
|
685
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/** Days after a date; the Date constructor rolls over month and year ends. */
|
|
689
|
+
const addDays = (d, n) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
|
|
690
|
+
|
|
691
|
+
/** A JSON object attribute → object; anything else → {}. */
|
|
692
|
+
function parseJsonObject(text) {
|
|
693
|
+
try {
|
|
694
|
+
const v = JSON.parse(text || '{}');
|
|
695
|
+
return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
|
|
696
|
+
} catch {
|
|
697
|
+
return {};
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
function resolveLocale(attr) {
|
|
702
|
+
return attr || (typeof navigator !== 'undefined' && navigator.language) || 'en';
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// Intl formatters are cheap to keep and not to make; one set per locale.
|
|
706
|
+
const cache = new Map();
|
|
707
|
+
function formatters(locale) {
|
|
708
|
+
let f = cache.get(locale);
|
|
709
|
+
if (!f) {
|
|
710
|
+
try {
|
|
711
|
+
f = {
|
|
712
|
+
weekday: new Intl.DateTimeFormat(locale, { weekday: 'short' }),
|
|
713
|
+
day: new Intl.DateTimeFormat(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }),
|
|
714
|
+
month: new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' })
|
|
715
|
+
};
|
|
716
|
+
} catch {
|
|
717
|
+
return formatters('en'); // an unknown locale tag throws a RangeError
|
|
718
|
+
}
|
|
719
|
+
cache.set(locale, f);
|
|
720
|
+
}
|
|
721
|
+
return f;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/** Short weekday without the trailing dot some locales add ("Mo." → "Mo"). */
|
|
725
|
+
const weekdayShort = (f, d) => f.weekday.format(d).replace(/\.$/, '');
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* First day of the week for a locale, 0 = Sunday … 6 = Saturday. Read from
|
|
729
|
+
* Intl.Locale where the browser has it (getWeekInfo(), or the older weekInfo
|
|
730
|
+
* accessor); Monday where it cannot say.
|
|
731
|
+
*/
|
|
732
|
+
function firstWeekday(locale) {
|
|
733
|
+
try {
|
|
734
|
+
const loc = new Intl.Locale(locale);
|
|
735
|
+
const info = typeof loc.getWeekInfo === 'function' ? loc.getWeekInfo() : loc.weekInfo;
|
|
736
|
+
if (info && info.firstDay >= 1 && info.firstDay <= 7) return info.firstDay % 7;
|
|
737
|
+
} catch { /* no Intl.Locale, or an unknown tag */ }
|
|
738
|
+
return 1;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/** A tone is a short lowercase token that becomes a __mark--<tone> modifier. */
|
|
742
|
+
const isTone = v => typeof v === 'string' && /^[a-z][a-z0-9-]*$/.test(v);
|
|
743
|
+
|
|
744
|
+
// A row of day chips that scrolls sideways — a booking horizon, the days
|
|
745
|
+
// around today. Came back from EhrenPfoten in 1.16.0.
|
|
746
|
+
//
|
|
747
|
+
// Attributes: start (YYYY-MM-DD, default today), days (count, default 7),
|
|
748
|
+
// value (YYYY-MM-DD), today (YYYY-MM-DD, default the browser's
|
|
749
|
+
// day), marks (JSON {date: tone | {tone, disabled}}), locale
|
|
750
|
+
// (default the browser language), label (aria-label of the group)
|
|
751
|
+
// Properties: value, marks (object or JSON text), locale, label
|
|
752
|
+
// Event: glk-change { value } — only on a change made by the user
|
|
753
|
+
// Part: strip
|
|
754
|
+
//
|
|
755
|
+
// The chips are buttons in a role="group" with aria-pressed on the chosen
|
|
756
|
+
// one, like <glk-segmented>; each chip is named with its full date, so a
|
|
757
|
+
// screen reader hears "Monday, 22 September 2026" rather than "Mo 22". One
|
|
758
|
+
// tab stop: arrow keys move between chips, Home/End jump to the ends, Enter
|
|
759
|
+
// or Space presses. The chosen chip is scrolled to the middle of the strip
|
|
760
|
+
// after the first layout and on every value change — the strip alone
|
|
761
|
+
// scrolls, never the page. A value change only re-sets state; the chips are
|
|
762
|
+
// rebuilt for start, days, today, marks and locale.
|
|
763
|
+
|
|
764
|
+
const KEYS = { ArrowLeft: -1, ArrowRight: 1, Home: -Infinity, End: Infinity };
|
|
765
|
+
|
|
766
|
+
function readMark(entry) {
|
|
767
|
+
if (isTone(entry)) return { tone: entry, disabled: false };
|
|
768
|
+
if (entry && typeof entry === 'object') return { tone: isTone(entry.tone) ? entry.tone : '', disabled: Boolean(entry.disabled) };
|
|
769
|
+
return { tone: '', disabled: false };
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
class GlkDateStrip extends GlkElement {
|
|
773
|
+
static get observedAttributes() { return ['start', 'days', 'value', 'today', 'marks', 'locale', 'label']; }
|
|
774
|
+
|
|
775
|
+
render() {
|
|
776
|
+
this._strip = this.createElement('div', ['glass-date-strip'], { role: 'group', part: 'strip' });
|
|
777
|
+
this._wrapper.appendChild(this._strip);
|
|
778
|
+
this._build();
|
|
779
|
+
this._applyLabel();
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
_build() {
|
|
783
|
+
const f = formatters(resolveLocale(this.getAttribute('locale')));
|
|
784
|
+
const marks = parseJsonObject(this.getAttribute('marks'));
|
|
785
|
+
const start = parseIso(this.getAttribute('start')) ?? new Date();
|
|
786
|
+
const today = this.getAttribute('today') || isoDate(new Date());
|
|
787
|
+
const count = Math.max(1, Math.floor(Number(this.getAttribute('days'))) || 7);
|
|
788
|
+
this._strip.replaceChildren();
|
|
789
|
+
for (let i = 0; i < count; i += 1) {
|
|
790
|
+
const date = addDays(start, i);
|
|
791
|
+
const iso = isoDate(date);
|
|
792
|
+
const mark = readMark(marks[iso]);
|
|
793
|
+
const chip = this.createElement('button', ['glass-date-strip__day'], { type: 'button', 'data-value': iso, 'aria-label': f.day.format(date) });
|
|
794
|
+
if (iso === today) chip.classList.add('glass-date-strip__day--today');
|
|
795
|
+
if (mark.disabled) chip.disabled = true;
|
|
796
|
+
const wd = this.createElement('span', ['glass-date-strip__wd']);
|
|
797
|
+
wd.textContent = weekdayShort(f, date);
|
|
798
|
+
const num = this.createElement('span', ['glass-date-strip__num']);
|
|
799
|
+
num.textContent = String(date.getDate());
|
|
800
|
+
const dot = this.createElement('span', ['glass-date-strip__mark']);
|
|
801
|
+
if (mark.tone) dot.classList.add(`glass-date-strip__mark--${mark.tone}`);
|
|
802
|
+
chip.append(wd, num, dot);
|
|
803
|
+
this._strip.appendChild(chip);
|
|
804
|
+
}
|
|
805
|
+
this._syncValue();
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
_chips() { return [...this._strip.querySelectorAll('button[data-value]')]; }
|
|
809
|
+
|
|
810
|
+
_syncValue() {
|
|
811
|
+
const value = this.value;
|
|
812
|
+
let chosen = null;
|
|
813
|
+
for (const chip of this._chips()) {
|
|
814
|
+
const pressed = chip.dataset.value === value;
|
|
815
|
+
chip.setAttribute('aria-pressed', String(pressed));
|
|
816
|
+
if (pressed) chosen = chip;
|
|
817
|
+
}
|
|
818
|
+
const chips = this._chips();
|
|
819
|
+
this._setTabStop(chosen ?? chips.find(chip => !chip.disabled) ?? chips[0]);
|
|
820
|
+
this._reveal(this._revealedAt ? 'smooth' : 'instant');
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
_setTabStop(target) {
|
|
824
|
+
for (const chip of this._chips()) chip.tabIndex = chip === target ? 0 : -1;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Scroll the chosen chip to the middle of the strip. Computed from client
|
|
828
|
+
// rects and applied to the strip's own scrollLeft, so the page never moves —
|
|
829
|
+
// scrollIntoView would scroll every ancestor. Before the first layout the
|
|
830
|
+
// strip has no width; the ResizeObserver in setupEvents centres then, and
|
|
831
|
+
// again whenever the strip's width changes — a parent that upgrades later
|
|
832
|
+
// and adds its padding, a window resize, a strip that starts out hidden. A
|
|
833
|
+
// value change glides unless the user asked for reduced motion; a size
|
|
834
|
+
// change snaps, so a settling layout never animates.
|
|
835
|
+
_reveal(behavior = 'instant') {
|
|
836
|
+
const chip = this._strip.querySelector('[aria-pressed="true"]');
|
|
837
|
+
const width = this._strip.clientWidth;
|
|
838
|
+
if (!chip || !width) return;
|
|
839
|
+
const strip = this._strip.getBoundingClientRect();
|
|
840
|
+
const box = chip.getBoundingClientRect();
|
|
841
|
+
const left = this._strip.scrollLeft + (box.left - strip.left) - (strip.width - box.width) / 2;
|
|
842
|
+
const smooth = behavior === 'smooth' && !matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
843
|
+
this._strip.scrollTo({ left: Math.max(0, left), behavior: smooth ? 'smooth' : 'instant' });
|
|
844
|
+
this._revealedAt = width;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
_applyLabel() {
|
|
848
|
+
const label = this.getAttribute('label');
|
|
849
|
+
if (label) this._strip.setAttribute('aria-label', label);
|
|
850
|
+
else this._strip.removeAttribute('aria-label');
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
setupEvents() {
|
|
854
|
+
this._onClick = (event) => {
|
|
855
|
+
const chip = event.target.closest('button[data-value]');
|
|
856
|
+
if (!chip || chip.disabled || chip.getAttribute('aria-disabled') === 'true') return;
|
|
857
|
+
this._setTabStop(chip);
|
|
858
|
+
const { value } = chip.dataset;
|
|
859
|
+
if (value === this.value) return;
|
|
860
|
+
this.value = value;
|
|
861
|
+
this.emit('glk-change', { value });
|
|
862
|
+
};
|
|
863
|
+
this._onKeydown = (event) => {
|
|
864
|
+
const step = KEYS[event.key];
|
|
865
|
+
if (step === undefined) return;
|
|
866
|
+
const chips = this._chips().filter(chip => !chip.disabled);
|
|
867
|
+
const from = chips.indexOf(event.target.closest('button[data-value]'));
|
|
868
|
+
if (from < 0) return;
|
|
869
|
+
const to = Number.isFinite(step) ? Math.min(chips.length - 1, Math.max(0, from + step)) : (step < 0 ? 0 : chips.length - 1);
|
|
870
|
+
event.preventDefault();
|
|
871
|
+
this._setTabStop(chips[to]);
|
|
872
|
+
chips[to].focus();
|
|
873
|
+
};
|
|
874
|
+
this._onResize = () => { if (this._strip.clientWidth !== this._revealedAt) this._reveal('instant'); };
|
|
875
|
+
this._strip.addEventListener('click', this._onClick);
|
|
876
|
+
this._strip.addEventListener('keydown', this._onKeydown);
|
|
877
|
+
this._resizeObserver = new ResizeObserver(this._onResize);
|
|
878
|
+
this._resizeObserver.observe(this._strip);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
teardownEvents() {
|
|
882
|
+
this._strip?.removeEventListener('click', this._onClick);
|
|
883
|
+
this._strip?.removeEventListener('keydown', this._onKeydown);
|
|
884
|
+
this._resizeObserver?.disconnect();
|
|
885
|
+
this._resizeObserver = null;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
onAttributeChanged(name) {
|
|
889
|
+
if (!this._strip) return;
|
|
890
|
+
if (name === 'value') this._syncValue();
|
|
891
|
+
else if (name === 'label') this._applyLabel();
|
|
892
|
+
else this._build();
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
get value() { return this.getAttribute('value') ?? ''; }
|
|
896
|
+
set value(v) {
|
|
897
|
+
if (v == null || v === '') this.removeAttribute('value');
|
|
898
|
+
else this.setAttribute('value', String(v));
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
get marks() { return parseJsonObject(this.getAttribute('marks')); }
|
|
902
|
+
set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
|
|
903
|
+
|
|
904
|
+
get locale() { return resolveLocale(this.getAttribute('locale')); }
|
|
905
|
+
set locale(v) {
|
|
906
|
+
if (v) this.setAttribute('locale', v);
|
|
907
|
+
else this.removeAttribute('locale');
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
get label() { return this.getAttribute('label') || ''; }
|
|
911
|
+
set label(v) {
|
|
912
|
+
if (v) this.setAttribute('label', v);
|
|
913
|
+
else this.removeAttribute('label');
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
customElements.define('glk-date-strip', GlkDateStrip);
|
|
918
|
+
|
|
669
919
|
// <glk-card fill> stretches the visible card to the height of its grid or flex
|
|
670
920
|
// cell. The host must become a grid for this: it is stretched by the outer
|
|
671
921
|
// layout but keeps height:auto, so a percentage height on the inner card has
|
|
@@ -2131,6 +2381,433 @@ class GlkSegmented extends GlkFormElement {
|
|
|
2131
2381
|
|
|
2132
2382
|
customElements.define('glk-segmented', GlkSegmented);
|
|
2133
2383
|
|
|
2384
|
+
// One month with a day to pick. Came back from EhrenPfoten in 1.16.0.
|
|
2385
|
+
//
|
|
2386
|
+
// Attributes: month (YYYY-MM; without it the month of the value, else of
|
|
2387
|
+
// today), value (YYYY-MM-DD), today (YYYY-MM-DD), min, max
|
|
2388
|
+
// (YYYY-MM-DD; days outside cannot be picked), marks (JSON
|
|
2389
|
+
// {date: tone | [tone, …]}, up to three dots), locale (default
|
|
2390
|
+
// the browser language), week-start (0 = Sunday … 6 = Saturday;
|
|
2391
|
+
// default from the locale, Monday where the browser cannot say),
|
|
2392
|
+
// label (aria-label of the day group), prev-label / next-label
|
|
2393
|
+
// (names of the nav buttons, English by default)
|
|
2394
|
+
// Properties: month, value, marks, locale, label
|
|
2395
|
+
// Form: associated — a surrounding <form> receives name=value, reset
|
|
2396
|
+
// restores the initial value, like <glk-segmented>
|
|
2397
|
+
// Events: glk-change { value } — on a pick by the user
|
|
2398
|
+
// glk-month { month } — when the user moves to another month
|
|
2399
|
+
// Parts: calendar, head, title, grid
|
|
2400
|
+
//
|
|
2401
|
+
// The days are buttons in a role="group" with aria-pressed on the chosen
|
|
2402
|
+
// one, each named with its full date; the weekday row is decorative. One tab
|
|
2403
|
+
// stop (roving tabindex): arrows move by a day or a week, Home/End to the
|
|
2404
|
+
// ends of the week, PageUp/PageDown by a month; moving past the month's edge
|
|
2405
|
+
// shows that month and emits glk-month. Arrows only move focus — Enter or
|
|
2406
|
+
// Space picks — so a calendar that opens a sheet on every pick stays quiet
|
|
2407
|
+
// while the user looks around. Days outside min/max carry aria-disabled
|
|
2408
|
+
// rather than disabled: they stay in the arrow path and are announced, but
|
|
2409
|
+
// neither click nor Enter picks them. A value set to another month flips the
|
|
2410
|
+
// calendar to that month.
|
|
2411
|
+
|
|
2412
|
+
const CHEVRON_LEFT = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg>';
|
|
2413
|
+
const CHEVRON_RIGHT = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg>';
|
|
2414
|
+
const STEPS = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -7, ArrowDown: 7 };
|
|
2415
|
+
const CELLS = 42;
|
|
2416
|
+
const MONTH = /^\d{4}-\d{2}$/;
|
|
2417
|
+
|
|
2418
|
+
function tonesOf(entry) {
|
|
2419
|
+
const list = Array.isArray(entry) ? entry : [entry];
|
|
2420
|
+
return list.filter(isTone).slice(0, 3);
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
class GlkCalendar extends GlkFormElement {
|
|
2424
|
+
static get observedAttributes() {
|
|
2425
|
+
return ['month', 'value', 'today', 'min', 'max', 'marks', 'locale', 'week-start', 'label', 'prev-label', 'next-label'];
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
render() {
|
|
2429
|
+
this._root = this.createElement('div', ['glass-calendar'], { part: 'calendar' });
|
|
2430
|
+
const head = this.createElement('div', ['glass-calendar__head'], { part: 'head' });
|
|
2431
|
+
this._prev = this.createElement('button', ['glass-calendar__nav'], { type: 'button' });
|
|
2432
|
+
this._prev.innerHTML = CHEVRON_LEFT;
|
|
2433
|
+
this._title = this.createElement('div', ['glass-calendar__title'], { part: 'title', 'aria-live': 'polite' });
|
|
2434
|
+
this._next = this.createElement('button', ['glass-calendar__nav'], { type: 'button' });
|
|
2435
|
+
this._next.innerHTML = CHEVRON_RIGHT;
|
|
2436
|
+
head.append(this._prev, this._title, this._next);
|
|
2437
|
+
this._grid = this.createElement('div', ['glass-calendar__grid'], { role: 'group', part: 'grid' });
|
|
2438
|
+
this._root.append(head, this._grid);
|
|
2439
|
+
this._wrapper.appendChild(this._root);
|
|
2440
|
+
this._initialValue = this.value;
|
|
2441
|
+
this._applyLabels();
|
|
2442
|
+
this._build();
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
get _todayIso() { return this.getAttribute('today') || isoDate(new Date()); }
|
|
2446
|
+
|
|
2447
|
+
_build() {
|
|
2448
|
+
const locale = resolveLocale(this.getAttribute('locale'));
|
|
2449
|
+
const f = formatters(locale);
|
|
2450
|
+
const month = this.month;
|
|
2451
|
+
const first = parseIso(month);
|
|
2452
|
+
const weekStartAttr = this.hasAttribute('week-start') ? Number(this.getAttribute('week-start')) : NaN;
|
|
2453
|
+
this._weekStart = Number.isInteger(weekStartAttr) && weekStartAttr >= 0 && weekStartAttr <= 6 ? weekStartAttr : firstWeekday(locale);
|
|
2454
|
+
const marks = parseJsonObject(this.getAttribute('marks'));
|
|
2455
|
+
const today = this._todayIso;
|
|
2456
|
+
const min = this.getAttribute('min') || '';
|
|
2457
|
+
const max = this.getAttribute('max') || '';
|
|
2458
|
+
this._shown = month;
|
|
2459
|
+
this._title.textContent = f.month.format(first);
|
|
2460
|
+
this._grid.replaceChildren();
|
|
2461
|
+
const offset = (first.getDay() - this._weekStart + 7) % 7; // cells before the 1st
|
|
2462
|
+
for (let i = 0; i < 7; i += 1) {
|
|
2463
|
+
const wd = this.createElement('span', ['glass-calendar__wd'], { 'aria-hidden': 'true' });
|
|
2464
|
+
wd.textContent = weekdayShort(f, addDays(first, i - offset));
|
|
2465
|
+
this._grid.appendChild(wd);
|
|
2466
|
+
}
|
|
2467
|
+
for (let i = 0; i < CELLS; i += 1) {
|
|
2468
|
+
const date = addDays(first, i - offset);
|
|
2469
|
+
const iso = isoDate(date);
|
|
2470
|
+
const day = this.createElement('button', ['glass-calendar__day'], { type: 'button', 'data-value': iso, 'aria-label': f.day.format(date) });
|
|
2471
|
+
if (date.getMonth() !== first.getMonth()) day.classList.add('glass-calendar__day--other');
|
|
2472
|
+
if (iso === today) day.classList.add('glass-calendar__day--today');
|
|
2473
|
+
if ((min && iso < min) || (max && iso > max)) day.setAttribute('aria-disabled', 'true');
|
|
2474
|
+
const num = this.createElement('span');
|
|
2475
|
+
num.textContent = String(date.getDate());
|
|
2476
|
+
const dots = this.createElement('span', ['glass-calendar__marks']);
|
|
2477
|
+
for (const tone of tonesOf(marks[iso])) {
|
|
2478
|
+
dots.appendChild(this.createElement('span', ['glass-calendar__mark', `glass-calendar__mark--${tone}`]));
|
|
2479
|
+
}
|
|
2480
|
+
day.append(num, dots);
|
|
2481
|
+
this._grid.appendChild(day);
|
|
2482
|
+
}
|
|
2483
|
+
this._syncValue();
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
_days() { return [...this._grid.querySelectorAll('button[data-value]')]; }
|
|
2487
|
+
_dayFor(iso) { return this._grid.querySelector(`button[data-value="${iso}"]`); }
|
|
2488
|
+
|
|
2489
|
+
_syncValue() {
|
|
2490
|
+
const value = this.value;
|
|
2491
|
+
let pressed = null;
|
|
2492
|
+
for (const day of this._days()) {
|
|
2493
|
+
const on = day.dataset.value === value;
|
|
2494
|
+
day.setAttribute('aria-pressed', String(on));
|
|
2495
|
+
if (on) pressed = day;
|
|
2496
|
+
}
|
|
2497
|
+
const today = this._todayIso;
|
|
2498
|
+
const fallback = today.startsWith(this._shown) ? this._dayFor(today) : this._dayFor(`${this._shown}-01`);
|
|
2499
|
+
this._setTabStop(pressed ?? fallback ?? this._days()[0]);
|
|
2500
|
+
this.setFormValue(value);
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
_setTabStop(target) {
|
|
2504
|
+
for (const day of this._days()) day.tabIndex = day === target ? 0 : -1;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
_applyLabels() {
|
|
2508
|
+
const label = this.getAttribute('label');
|
|
2509
|
+
if (label) this._grid.setAttribute('aria-label', label);
|
|
2510
|
+
else this._grid.removeAttribute('aria-label');
|
|
2511
|
+
this._prev.setAttribute('aria-label', this.getAttribute('prev-label') || 'Previous month');
|
|
2512
|
+
this._next.setAttribute('aria-label', this.getAttribute('next-label') || 'Next month');
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
// Show another month because the user asked for it — nav buttons or a key
|
|
2516
|
+
// that crossed the month's edge. Setting the attribute rebuilds the grid.
|
|
2517
|
+
_show(month) {
|
|
2518
|
+
this.month = month;
|
|
2519
|
+
this.emit('glk-month', { month });
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
_shift(delta) {
|
|
2523
|
+
const first = parseIso(this.month);
|
|
2524
|
+
const next = new Date(first.getFullYear(), first.getMonth() + delta, 1);
|
|
2525
|
+
this._show(isoDate(next).slice(0, 7));
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
_focusDay(date) {
|
|
2529
|
+
const iso = isoDate(date);
|
|
2530
|
+
if (!iso.startsWith(this._shown)) this._show(iso.slice(0, 7));
|
|
2531
|
+
const day = this._dayFor(iso);
|
|
2532
|
+
if (!day) return;
|
|
2533
|
+
this._setTabStop(day);
|
|
2534
|
+
day.focus();
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
_pick(value) {
|
|
2538
|
+
if (value === this.value) return;
|
|
2539
|
+
this.value = value;
|
|
2540
|
+
this.emit('glk-change', { value });
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
setupEvents() {
|
|
2544
|
+
this._onPrev = () => this._shift(-1);
|
|
2545
|
+
this._onNext = () => this._shift(1);
|
|
2546
|
+
this._onClick = (event) => {
|
|
2547
|
+
const day = event.target.closest('button[data-value]');
|
|
2548
|
+
if (!day) return;
|
|
2549
|
+
this._setTabStop(day);
|
|
2550
|
+
if (day.getAttribute('aria-disabled') === 'true') return;
|
|
2551
|
+
this._pick(day.dataset.value);
|
|
2552
|
+
};
|
|
2553
|
+
this._onKeydown = (event) => {
|
|
2554
|
+
const from = event.target.closest('button[data-value]');
|
|
2555
|
+
if (!from) return;
|
|
2556
|
+
const date = parseIso(from.dataset.value);
|
|
2557
|
+
const weekday = (date.getDay() - this._weekStart + 7) % 7;
|
|
2558
|
+
let target;
|
|
2559
|
+
if (event.key in STEPS) target = addDays(date, STEPS[event.key]);
|
|
2560
|
+
else if (event.key === 'Home') target = addDays(date, -weekday);
|
|
2561
|
+
else if (event.key === 'End') target = addDays(date, 6 - weekday);
|
|
2562
|
+
else if (event.key === 'PageUp' || event.key === 'PageDown') {
|
|
2563
|
+
const months = event.key === 'PageUp' ? -1 : 1;
|
|
2564
|
+
const last = new Date(date.getFullYear(), date.getMonth() + months + 1, 0).getDate();
|
|
2565
|
+
target = new Date(date.getFullYear(), date.getMonth() + months, Math.min(date.getDate(), last));
|
|
2566
|
+
} else return;
|
|
2567
|
+
event.preventDefault();
|
|
2568
|
+
this._focusDay(target);
|
|
2569
|
+
};
|
|
2570
|
+
this._prev.addEventListener('click', this._onPrev);
|
|
2571
|
+
this._next.addEventListener('click', this._onNext);
|
|
2572
|
+
this._grid.addEventListener('click', this._onClick);
|
|
2573
|
+
this._grid.addEventListener('keydown', this._onKeydown);
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
teardownEvents() {
|
|
2577
|
+
this._prev?.removeEventListener('click', this._onPrev);
|
|
2578
|
+
this._next?.removeEventListener('click', this._onNext);
|
|
2579
|
+
this._grid?.removeEventListener('click', this._onClick);
|
|
2580
|
+
this._grid?.removeEventListener('keydown', this._onKeydown);
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
onAttributeChanged(name) {
|
|
2584
|
+
if (!this._grid) return;
|
|
2585
|
+
switch (name) {
|
|
2586
|
+
case 'value': {
|
|
2587
|
+
const value = this.value;
|
|
2588
|
+
if (value && !value.startsWith(this._shown)) this.month = value.slice(0, 7); // rebuilds via 'month'
|
|
2589
|
+
else this._syncValue();
|
|
2590
|
+
break;
|
|
2591
|
+
}
|
|
2592
|
+
case 'label':
|
|
2593
|
+
case 'prev-label':
|
|
2594
|
+
case 'next-label':
|
|
2595
|
+
this._applyLabels();
|
|
2596
|
+
break;
|
|
2597
|
+
default:
|
|
2598
|
+
this._build();
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
resetValue() { this.value = this._initialValue; }
|
|
2603
|
+
restoreValue(state) { if (typeof state === 'string') this.value = state; }
|
|
2604
|
+
|
|
2605
|
+
get month() {
|
|
2606
|
+
const attr = this.getAttribute('month');
|
|
2607
|
+
if (attr && MONTH.test(attr) && parseIso(attr)) return attr;
|
|
2608
|
+
const value = this.value;
|
|
2609
|
+
return (value && parseIso(value) ? value : this._todayIso).slice(0, 7);
|
|
2610
|
+
}
|
|
2611
|
+
set month(v) {
|
|
2612
|
+
if (v && MONTH.test(String(v))) this.setAttribute('month', String(v));
|
|
2613
|
+
else this.removeAttribute('month');
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
get value() { return this.getAttribute('value') ?? ''; }
|
|
2617
|
+
set value(v) {
|
|
2618
|
+
if (v == null || v === '') this.removeAttribute('value');
|
|
2619
|
+
else this.setAttribute('value', String(v));
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
get marks() { return parseJsonObject(this.getAttribute('marks')); }
|
|
2623
|
+
set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
|
|
2624
|
+
|
|
2625
|
+
get locale() { return resolveLocale(this.getAttribute('locale')); }
|
|
2626
|
+
set locale(v) {
|
|
2627
|
+
if (v) this.setAttribute('locale', v);
|
|
2628
|
+
else this.removeAttribute('locale');
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
get label() { return this.getAttribute('label') || ''; }
|
|
2632
|
+
set label(v) {
|
|
2633
|
+
if (v) this.setAttribute('label', v);
|
|
2634
|
+
else this.removeAttribute('label');
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
customElements.define('glk-calendar', GlkCalendar);
|
|
2639
|
+
|
|
2640
|
+
// One image with a preview, resized on the client before it goes anywhere.
|
|
2641
|
+
// Came back from EhrenPfoten in 1.16.0, where it was the photo picker.
|
|
2642
|
+
//
|
|
2643
|
+
// Attributes: src (starting image: URL or data URL), label (visible; names
|
|
2644
|
+
// the group), hint (small muted line; none by default), round
|
|
2645
|
+
// (circular preview, for avatars), max (longest edge after
|
|
2646
|
+
// resizing, default 1024), type (output MIME, default
|
|
2647
|
+
// image/jpeg; image/webp where the browser encodes it, PNG
|
|
2648
|
+
// otherwise), quality (0–1, default 0.82), accept (file dialog
|
|
2649
|
+
// filter, default image/*), choose-label, change-label,
|
|
2650
|
+
// remove-label (button texts, English by default)
|
|
2651
|
+
// Property: src — the current image as a data URL or the given URL; set
|
|
2652
|
+
// it to swap the preview. Not reflected to the attribute, so a
|
|
2653
|
+
// data URL of megabytes never lands in the DOM.
|
|
2654
|
+
// Events: glk-change { dataUrl, width, height, size } — after a pick;
|
|
2655
|
+
// on remove with an empty dataUrl and zeros
|
|
2656
|
+
// glk-error { message, name } — when the file cannot be decoded
|
|
2657
|
+
// (Chrome cannot read HEIC; a corrupt file)
|
|
2658
|
+
// Parts: picker, preview, meta, label, hint, actions
|
|
2659
|
+
//
|
|
2660
|
+
// Decoding goes through createImageBitmap with imageOrientation 'from-image',
|
|
2661
|
+
// which applies the EXIF rotation of a phone photo without a library, then
|
|
2662
|
+
// onto a canvas no larger than max. The file input is hidden and opened from
|
|
2663
|
+
// a real button — a <label> around a hidden input cannot be reached by
|
|
2664
|
+
// keyboard — and cleared after every pick, so the same file can be chosen
|
|
2665
|
+
// again. Not form-associated: the form value would be either the original
|
|
2666
|
+
// file, which is not what gets uploaded, or a data URL of megabytes. Listen
|
|
2667
|
+
// to glk-change and upload, or copy the data URL into a hidden field.
|
|
2668
|
+
|
|
2669
|
+
const PLACEHOLDER = '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="9" cy="10" r="2"/><path d="M21 15l-5-4-8 8"/></svg>';
|
|
2670
|
+
|
|
2671
|
+
function dataUrlBytes(url) {
|
|
2672
|
+
const b64 = url.slice(url.indexOf(',') + 1);
|
|
2673
|
+
const padding = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0;
|
|
2674
|
+
return Math.floor((b64.length * 3) / 4) - padding;
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
class GlkImagePicker extends GlkElement {
|
|
2678
|
+
static get observedAttributes() {
|
|
2679
|
+
return ['src', 'label', 'hint', 'round', 'max', 'type', 'quality', 'accept', 'choose-label', 'change-label', 'remove-label'];
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
constructor() {
|
|
2683
|
+
super();
|
|
2684
|
+
this._src = '';
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
render() {
|
|
2688
|
+
this._src = this.getAttribute('src') || '';
|
|
2689
|
+
this._root = this.createElement('div', ['glass-image-picker'], { part: 'picker', role: 'group' });
|
|
2690
|
+
this._preview = this.createElement('div', ['glass-image-picker__preview'], { part: 'preview' });
|
|
2691
|
+
const meta = this.createElement('div', ['glass-image-picker__meta'], { part: 'meta' });
|
|
2692
|
+
this._label = this.createElement('span', ['glass-image-picker__label'], { part: 'label', id: 'label' });
|
|
2693
|
+
this._hint = this.createElement('span', ['glass-image-picker__hint'], { part: 'hint', id: 'hint' });
|
|
2694
|
+
const actions = this.createElement('div', ['glass-image-picker__actions'], { part: 'actions' });
|
|
2695
|
+
this._choose = this.createElement('button', ['glass-btn', 'glass-btn--secondary', 'glass-btn--sm', 'glass-btn--auto'], { type: 'button' });
|
|
2696
|
+
this._remove = this.createElement('button', ['glass-btn', 'glass-btn--tertiary', 'glass-btn--sm', 'glass-btn--auto'], { type: 'button' });
|
|
2697
|
+
this._input = this.createElement('input', [], { type: 'file', tabindex: '-1' });
|
|
2698
|
+
this._input.hidden = true;
|
|
2699
|
+
actions.append(this._choose, this._remove, this._input);
|
|
2700
|
+
meta.append(this._label, this._hint, actions);
|
|
2701
|
+
this._root.append(this._preview, meta);
|
|
2702
|
+
this._wrapper.appendChild(this._root);
|
|
2703
|
+
this._update();
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
get _max() { return Math.max(1, Math.floor(Number(this.getAttribute('max'))) || 1024); }
|
|
2707
|
+
get _type() { return this.getAttribute('type') || 'image/jpeg'; }
|
|
2708
|
+
get _quality() {
|
|
2709
|
+
const q = Number(this.getAttribute('quality'));
|
|
2710
|
+
return this.hasAttribute('quality') && q >= 0 && q <= 1 ? q : 0.82;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
_update() {
|
|
2714
|
+
if (!this._root) return;
|
|
2715
|
+
const label = this.getAttribute('label') || '';
|
|
2716
|
+
const hint = this.getAttribute('hint') || '';
|
|
2717
|
+
this._preview.classList.toggle('glass-image-picker__preview--round', this.getBoolAttr('round'));
|
|
2718
|
+
if (!this._src) {
|
|
2719
|
+
this._img = null;
|
|
2720
|
+
this._preview.innerHTML = PLACEHOLDER;
|
|
2721
|
+
} else if (!this._img || this._img.getAttribute('src') !== this._src) {
|
|
2722
|
+
this._img = this.createElement('img', [], { alt: '', src: this._src });
|
|
2723
|
+
this._preview.replaceChildren(this._img);
|
|
2724
|
+
}
|
|
2725
|
+
this._label.textContent = label;
|
|
2726
|
+
this._label.hidden = !label;
|
|
2727
|
+
this._hint.textContent = hint;
|
|
2728
|
+
this._hint.hidden = !hint;
|
|
2729
|
+
if (label) this._root.setAttribute('aria-labelledby', 'label');
|
|
2730
|
+
else this._root.removeAttribute('aria-labelledby');
|
|
2731
|
+
if (hint) this._root.setAttribute('aria-describedby', 'hint');
|
|
2732
|
+
else this._root.removeAttribute('aria-describedby');
|
|
2733
|
+
this._choose.textContent = this._src
|
|
2734
|
+
? (this.getAttribute('change-label') || 'Change')
|
|
2735
|
+
: (this.getAttribute('choose-label') || 'Choose');
|
|
2736
|
+
this._remove.textContent = this.getAttribute('remove-label') || 'Remove';
|
|
2737
|
+
this._remove.hidden = !this._src;
|
|
2738
|
+
this._input.accept = this.getAttribute('accept') || 'image/*';
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
async _pick(file) {
|
|
2742
|
+
if (!file) return;
|
|
2743
|
+
try {
|
|
2744
|
+
const bitmap = await createImageBitmap(file, { imageOrientation: 'from-image' });
|
|
2745
|
+
const scale = Math.min(1, this._max / Math.max(bitmap.width, bitmap.height));
|
|
2746
|
+
const canvas = document.createElement('canvas');
|
|
2747
|
+
canvas.width = Math.max(1, Math.round(bitmap.width * scale));
|
|
2748
|
+
canvas.height = Math.max(1, Math.round(bitmap.height * scale));
|
|
2749
|
+
const ctx = canvas.getContext('2d');
|
|
2750
|
+
if (this._type === 'image/jpeg') {
|
|
2751
|
+
// JPEG has no alpha; without this a transparent PNG comes out on black.
|
|
2752
|
+
ctx.fillStyle = '#fff';
|
|
2753
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
2754
|
+
}
|
|
2755
|
+
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
|
|
2756
|
+
bitmap.close();
|
|
2757
|
+
const dataUrl = canvas.toDataURL(this._type, this._quality);
|
|
2758
|
+
this.src = dataUrl;
|
|
2759
|
+
this.emit('glk-change', { dataUrl, width: canvas.width, height: canvas.height, size: dataUrlBytes(dataUrl) });
|
|
2760
|
+
} catch (error) {
|
|
2761
|
+
this.emit('glk-error', { message: error?.message || String(error), name: file.name });
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
setupEvents() {
|
|
2766
|
+
this._onChoose = () => this._input.click();
|
|
2767
|
+
this._onChange = (event) => {
|
|
2768
|
+
const file = event.target.files?.[0];
|
|
2769
|
+
event.target.value = '';
|
|
2770
|
+
this._pick(file);
|
|
2771
|
+
};
|
|
2772
|
+
this._onRemove = () => {
|
|
2773
|
+
this.src = '';
|
|
2774
|
+
this._choose.focus(); // the remove button just went away under the focus
|
|
2775
|
+
this.emit('glk-change', { dataUrl: '', width: 0, height: 0, size: 0 });
|
|
2776
|
+
};
|
|
2777
|
+
this._choose.addEventListener('click', this._onChoose);
|
|
2778
|
+
this._input.addEventListener('change', this._onChange);
|
|
2779
|
+
this._remove.addEventListener('click', this._onRemove);
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
teardownEvents() {
|
|
2783
|
+
this._choose?.removeEventListener('click', this._onChoose);
|
|
2784
|
+
this._input?.removeEventListener('change', this._onChange);
|
|
2785
|
+
this._remove?.removeEventListener('click', this._onRemove);
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
onAttributeChanged(name, _old, value) {
|
|
2789
|
+
if (name === 'src') this._src = value || '';
|
|
2790
|
+
this._update();
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
get src() { return this._src; }
|
|
2794
|
+
set src(v) {
|
|
2795
|
+
this._src = v || '';
|
|
2796
|
+
this._update();
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2799
|
+
get label() { return this.getAttribute('label') || ''; }
|
|
2800
|
+
set label(v) {
|
|
2801
|
+
if (v) this.setAttribute('label', v);
|
|
2802
|
+
else this.removeAttribute('label');
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
get round() { return this.getBoolAttr('round'); }
|
|
2806
|
+
set round(v) { this.setBoolAttr('round', v); }
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
customElements.define('glk-image-picker', GlkImagePicker);
|
|
2810
|
+
|
|
2134
2811
|
const VARIANTS$2 = ['success', 'error'];
|
|
2135
2812
|
const SIZES = ['sm', 'lg'];
|
|
2136
2813
|
|
|
@@ -2982,4 +3659,4 @@ class GlkListItem extends GlkElement {
|
|
|
2982
3659
|
|
|
2983
3660
|
customElements.define('glk-list-item', GlkListItem);
|
|
2984
3661
|
|
|
2985
|
-
export { GlkAccordion, GlkAccordionItem, GlkAvatar, GlkBadge, GlkButton, GlkCard, GlkCheckbox, GlkDivider, GlkElement, GlkEmpty, GlkFormElement, GlkInput, GlkList, GlkListItem, GlkModal, GlkNav, GlkPill, GlkPopover, GlkProgress, GlkRadio, GlkRange, GlkSearch, GlkSegmented, GlkSelect, GlkSheet, GlkStatus, GlkSteps, GlkTabAccessory, GlkTabBar, GlkTabDock, GlkTabItem, GlkTextarea, GlkTitle, GlkToast, GlkToggle };
|
|
3662
|
+
export { GlkAccordion, GlkAccordionItem, GlkAvatar, GlkBadge, GlkButton, GlkCalendar, GlkCard, GlkCheckbox, GlkDateStrip, GlkDivider, GlkElement, GlkEmpty, GlkFormElement, GlkImagePicker, GlkInput, GlkList, GlkListItem, GlkModal, GlkNav, GlkPill, GlkPopover, GlkProgress, GlkRadio, GlkRange, GlkSearch, GlkSegmented, GlkSelect, GlkSheet, GlkStatus, GlkSteps, GlkTabAccessory, GlkTabBar, GlkTabDock, GlkTabItem, GlkTextarea, GlkTitle, GlkToast, GlkToggle };
|