/*!
 * Booterial: the bridge (m3-bootstrap.css)
 *
 * Maps Material 3 design tokens onto Bootstrap 5.3 and restyles its
 * components to M3 specs, with a few M3-only components added.
 *
 * This file holds NO color values. Every color, radius, font and shadow
 * comes from --md-* custom properties defined by a generated theme file
 * (css/m3-theme.css), so a client theme never needs this file touched.
 *
 * Load order: bootstrap.css → m3-bootstrap.css → m3-theme.css
 */

/* ==========================================================================
   1. Fixed M3 tokens (not themable)
   ========================================================================== */

:root {
  --md-sys-state-hover-state-layer-opacity: 8%;
  --md-sys-state-focus-state-layer-opacity: 10%;
  --md-sys-state-pressed-state-layer-opacity: 10%;
  --md-sys-state-dragged-state-layer-opacity: 16%;
  --md-sys-state-disabled-container-opacity: 12%;
  --md-sys-state-disabled-content-opacity: 38%;

  /* Spring fallbacks. The generated theme replaces these with true
     spring curves (linear()); these only apply if a theme lacks them. */
  --md-sys-motion-spring-fast-spatial: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --md-sys-motion-spring-fast-spatial-duration: 300ms;
  --md-sys-motion-spring-default-spatial: cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-spring-default-spatial-duration: 450ms;
  --md-sys-motion-spring-slow-spatial: cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-spring-slow-spatial-duration: 650ms;
  --md-sys-motion-spring-fast-effects: linear;
  --md-sys-motion-spring-fast-effects-duration: 150ms;
  --md-sys-motion-spring-default-effects: cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-spring-default-effects-duration: 230ms;
  --md-sys-motion-spring-slow-effects: cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-spring-slow-effects-duration: 330ms;
  --md-sys-motion-spring-fast-spatial-damping: 0.6;
  --md-sys-motion-spring-fast-spatial-stiffness: 800;
  --md-sys-motion-spring-default-spatial-damping: 0.8;
  --md-sys-motion-spring-default-spatial-stiffness: 380;
  --md-sys-motion-spring-slow-spatial-damping: 0.8;
  --md-sys-motion-spring-slow-spatial-stiffness: 200;

  /* Multiply every duration (the motion lab's slow-mo toggle sets this). */
  --md-motion-scale: 1;

  --md-focus-ring: 3px solid var(--md-sys-color-secondary);
  --md-focus-offset: 2px;

  --md-disabled-container: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-disabled-container-opacity), transparent);
  --md-disabled-content: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-disabled-content-opacity), transparent);
  /* Expressive buttons use a lighter disabled container and a variant-toned label. */
  --md-btn-disabled-container: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
  --md-btn-disabled-content: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 38%, transparent);
}

/* "duration easing" pairs for transition shorthands, e.g.
   transition: transform var(--md-motion-fast-spatial); */
* {
  --md-motion-fast-spatial: calc(var(--md-sys-motion-spring-fast-spatial-duration) * var(--md-motion-scale)) var(--md-sys-motion-spring-fast-spatial);
  --md-motion-default-spatial: calc(var(--md-sys-motion-spring-default-spatial-duration) * var(--md-motion-scale)) var(--md-sys-motion-spring-default-spatial);
  --md-motion-slow-spatial: calc(var(--md-sys-motion-spring-slow-spatial-duration) * var(--md-motion-scale)) var(--md-sys-motion-spring-slow-spatial);
  --md-motion-fast-effects: calc(var(--md-sys-motion-spring-fast-effects-duration) * var(--md-motion-scale)) var(--md-sys-motion-spring-fast-effects);
  --md-motion-default-effects: calc(var(--md-sys-motion-spring-default-effects-duration) * var(--md-motion-scale)) var(--md-sys-motion-spring-default-effects);
  --md-motion-slow-effects: calc(var(--md-sys-motion-spring-slow-effects-duration) * var(--md-motion-scale)) var(--md-sys-motion-spring-slow-effects);
}

/* ==========================================================================
   2. Bootstrap root variables → M3 roles
   Listed for light AND dark so this wins over Bootstrap's own
   [data-bs-theme=dark] block; values resolve per scheme automatically.
   ========================================================================== */

:root,
[data-bs-theme=light],
[data-bs-theme=dark] {
  --bs-primary: var(--md-sys-color-primary);
  --bs-secondary: var(--md-sys-color-secondary);
  --bs-success: var(--md-sys-color-success);
  --bs-info: var(--md-sys-color-info);
  --bs-warning: var(--md-sys-color-warning);
  --bs-danger: var(--md-sys-color-error);
  --bs-light: var(--md-sys-color-surface-container-highest);
  --bs-dark: var(--md-sys-color-inverse-surface);

  --bs-primary-rgb: var(--md-sys-color-primary-rgb);
  --bs-secondary-rgb: var(--md-sys-color-secondary-rgb);
  --bs-success-rgb: var(--md-sys-color-success-rgb);
  --bs-info-rgb: var(--md-sys-color-info-rgb);
  --bs-warning-rgb: var(--md-sys-color-warning-rgb);
  --bs-danger-rgb: var(--md-sys-color-error-rgb);
  --bs-light-rgb: var(--md-sys-color-surface-container-highest-rgb);
  --bs-dark-rgb: var(--md-sys-color-inverse-surface-rgb);

  --bs-primary-text-emphasis: var(--md-sys-color-on-primary-container);
  --bs-secondary-text-emphasis: var(--md-sys-color-on-secondary-container);
  --bs-success-text-emphasis: var(--md-sys-color-on-success-container);
  --bs-info-text-emphasis: var(--md-sys-color-on-info-container);
  --bs-warning-text-emphasis: var(--md-sys-color-on-warning-container);
  --bs-danger-text-emphasis: var(--md-sys-color-on-error-container);
  --bs-light-text-emphasis: var(--md-sys-color-on-surface);
  --bs-dark-text-emphasis: var(--md-sys-color-on-surface);

  --bs-primary-bg-subtle: var(--md-sys-color-primary-container);
  --bs-secondary-bg-subtle: var(--md-sys-color-secondary-container);
  --bs-success-bg-subtle: var(--md-sys-color-success-container);
  --bs-info-bg-subtle: var(--md-sys-color-info-container);
  --bs-warning-bg-subtle: var(--md-sys-color-warning-container);
  --bs-danger-bg-subtle: var(--md-sys-color-error-container);
  --bs-light-bg-subtle: var(--md-sys-color-surface-container-low);
  --bs-dark-bg-subtle: var(--md-sys-color-surface-container-highest);

  --bs-primary-border-subtle: color-mix(in srgb, var(--md-sys-color-primary) 30%, var(--md-sys-color-primary-container));
  --bs-secondary-border-subtle: color-mix(in srgb, var(--md-sys-color-secondary) 30%, var(--md-sys-color-secondary-container));
  --bs-success-border-subtle: color-mix(in srgb, var(--md-sys-color-success) 30%, var(--md-sys-color-success-container));
  --bs-info-border-subtle: color-mix(in srgb, var(--md-sys-color-info) 30%, var(--md-sys-color-info-container));
  --bs-warning-border-subtle: color-mix(in srgb, var(--md-sys-color-warning) 30%, var(--md-sys-color-warning-container));
  --bs-danger-border-subtle: color-mix(in srgb, var(--md-sys-color-error) 30%, var(--md-sys-color-error-container));
  --bs-light-border-subtle: var(--md-sys-color-outline-variant);
  --bs-dark-border-subtle: var(--md-sys-color-outline);

  --bs-body-font-family: var(--md-ref-typeface-plain);
  --bs-body-font-size: var(--md-sys-typescale-body-large-size);
  --bs-body-font-weight: var(--md-sys-typescale-body-large-weight);
  --bs-body-line-height: 1.5;
  --bs-body-color: var(--md-sys-color-on-surface);
  --bs-body-color-rgb: var(--md-sys-color-on-surface-rgb);
  --bs-body-bg: var(--md-app-bg);
  --bs-body-bg-rgb: var(--md-app-bg-rgb);

  --bs-emphasis-color: var(--md-sys-color-on-surface);
  --bs-emphasis-color-rgb: var(--md-sys-color-on-surface-rgb);
  --bs-secondary-color: var(--md-sys-color-on-surface-variant);
  --bs-secondary-color-rgb: var(--md-sys-color-on-surface-variant-rgb);
  --bs-secondary-bg: var(--md-sys-color-surface-container-high);
  --bs-secondary-bg-rgb: var(--md-sys-color-surface-container-high-rgb);
  --bs-tertiary-color: var(--md-sys-color-on-surface-variant);
  --bs-tertiary-color-rgb: var(--md-sys-color-on-surface-variant-rgb);
  --bs-tertiary-bg: var(--md-sys-color-surface-container);
  --bs-tertiary-bg-rgb: var(--md-sys-color-surface-container-rgb);

  --bs-heading-color: var(--md-sys-color-on-surface);
  --bs-link-color: var(--md-sys-color-primary);
  --bs-link-color-rgb: var(--md-sys-color-primary-rgb);
  --bs-link-hover-color: var(--md-sys-color-on-primary-container);
  --bs-link-hover-color-rgb: var(--md-sys-color-on-primary-container-rgb);
  --bs-code-color: var(--md-sys-color-tertiary);
  --bs-highlight-color: var(--md-sys-color-on-tertiary-container);
  --bs-highlight-bg: var(--md-sys-color-tertiary-container);

  --bs-border-color: var(--md-sys-color-outline-variant);
  --bs-border-color-translucent: var(--md-sys-color-outline-variant);

  --bs-border-radius-sm: var(--md-sys-shape-corner-extra-small);
  --bs-border-radius: var(--md-sys-shape-corner-small);
  --bs-border-radius-lg: var(--md-sys-shape-corner-large);
  --bs-border-radius-xl: var(--md-sys-shape-corner-extra-large);
  --bs-border-radius-xxl: var(--md-sys-shape-corner-extra-extra-large);
  --bs-border-radius-2xl: var(--md-sys-shape-corner-extra-extra-large);
  --bs-border-radius-pill: var(--md-sys-shape-corner-full);

  --bs-box-shadow-sm: var(--md-sys-elevation-level1);
  --bs-box-shadow: var(--md-sys-elevation-level2);
  --bs-box-shadow-lg: var(--md-sys-elevation-level3);
  --bs-box-shadow-inset: none;

  --bs-focus-ring-width: 3px;
  --bs-focus-ring-opacity: 1;
  --bs-focus-ring-color: var(--md-sys-color-secondary);

  --bs-form-valid-color: var(--md-sys-color-success);
  --bs-form-valid-border-color: var(--md-sys-color-success);
  --bs-form-invalid-color: var(--md-sys-color-error);
  --bs-form-invalid-border-color: var(--md-sys-color-error);
}

/* ==========================================================================
   3. Base & typography
   ========================================================================== */

body {
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Scrollbars. M3 has no scrollbar spec, so this follows Google's own web
   apps: no visible track, a thin full-round thumb in a muted neutral that
   widens and darkens under the pointer. Colors come from the theme, so it
   follows light/dark and client palettes. Inverse surfaces (toasts,
   snackbars) set --md-scrollbar-thumb to a light thumb.
   Chromium/Safari get the pill via ::-webkit-scrollbar (a transparent border
   insets the thumb); Firefox gets the standard scrollbar-color/-width. */
:root {
  --md-scrollbar-thumb: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 40%, transparent);
  --md-scrollbar-thumb-hover: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 65%, transparent);
  --md-scrollbar-thumb-active: var(--md-sys-color-on-surface-variant);
}
.toast, .snackbar {
  --md-scrollbar-thumb: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 40%, transparent);
  --md-scrollbar-thumb-hover: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 65%, transparent);
  --md-scrollbar-thumb-active: var(--md-sys-color-inverse-on-surface);
}
@supports selector(::-webkit-scrollbar) {
  ::-webkit-scrollbar { width: 12px; height: 12px; background: transparent; }
  ::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
  ::-webkit-scrollbar-thumb {
    min-width: 40px;
    min-height: 40px;
    border: 3px solid transparent;
    border-radius: 999px;
    background-color: var(--md-scrollbar-thumb);
    background-clip: padding-box;
  }
  ::-webkit-scrollbar-thumb:hover { border-width: 2px; background-color: var(--md-scrollbar-thumb-hover); }
  ::-webkit-scrollbar-thumb:active { border-width: 2px; background-color: var(--md-scrollbar-thumb-active); }
  ::-webkit-scrollbar-button { display: none; }
}
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-color: var(--md-scrollbar-thumb) transparent; }
  :where(.dropdown-menu, .toast, .offcanvas-body, .modal-body, .demo-scroll) { scrollbar-width: thin; }
}

h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6 {
  font-family: var(--md-ref-typeface-brand);
}

h1, .h1 { font-size: var(--md-sys-typescale-display-small-size); line-height: var(--md-sys-typescale-display-small-line-height); font-weight: var(--md-sys-typescale-display-small-weight); letter-spacing: var(--md-sys-typescale-display-small-tracking); }
h2, .h2 { font-size: var(--md-sys-typescale-headline-large-size); line-height: var(--md-sys-typescale-headline-large-line-height); font-weight: var(--md-sys-typescale-headline-large-weight); letter-spacing: var(--md-sys-typescale-headline-large-tracking); }
h3, .h3 { font-size: var(--md-sys-typescale-headline-medium-size); line-height: var(--md-sys-typescale-headline-medium-line-height); font-weight: var(--md-sys-typescale-headline-medium-weight); letter-spacing: var(--md-sys-typescale-headline-medium-tracking); }
h4, .h4 { font-size: var(--md-sys-typescale-headline-small-size); line-height: var(--md-sys-typescale-headline-small-line-height); font-weight: var(--md-sys-typescale-headline-small-weight); letter-spacing: var(--md-sys-typescale-headline-small-tracking); }
h5, .h5 { font-size: var(--md-sys-typescale-title-large-size); line-height: var(--md-sys-typescale-title-large-line-height); font-weight: var(--md-sys-typescale-title-large-weight); letter-spacing: var(--md-sys-typescale-title-large-tracking); }
h6, .h6 { font-family: var(--md-sys-typescale-title-medium-font); font-size: var(--md-sys-typescale-title-medium-size); line-height: var(--md-sys-typescale-title-medium-line-height); font-weight: var(--md-sys-typescale-title-medium-weight); letter-spacing: var(--md-sys-typescale-title-medium-tracking); }

.display-1 { font-size: calc(var(--md-sys-typescale-display-large-size) * 1.25); line-height: 1.1; font-weight: var(--md-sys-typescale-display-large-weight); letter-spacing: var(--md-sys-typescale-display-large-tracking); }
.display-2 { font-size: var(--md-sys-typescale-display-large-size); line-height: var(--md-sys-typescale-display-large-line-height); font-weight: var(--md-sys-typescale-display-large-weight); letter-spacing: var(--md-sys-typescale-display-large-tracking); }
.display-3 { font-size: var(--md-sys-typescale-display-medium-size); line-height: var(--md-sys-typescale-display-medium-line-height); font-weight: var(--md-sys-typescale-display-medium-weight); }
.display-4 { font-size: var(--md-sys-typescale-display-small-size); line-height: var(--md-sys-typescale-display-small-line-height); font-weight: var(--md-sys-typescale-display-small-weight); }
.display-5 { font-size: var(--md-sys-typescale-headline-large-size); line-height: var(--md-sys-typescale-headline-large-line-height); font-weight: var(--md-sys-typescale-headline-large-weight); }
.display-6 { font-size: var(--md-sys-typescale-headline-medium-size); line-height: var(--md-sys-typescale-headline-medium-line-height); font-weight: var(--md-sys-typescale-headline-medium-weight); }

.lead { font-size: var(--md-sys-typescale-title-large-size); line-height: var(--md-sys-typescale-title-large-line-height); font-weight: 400; }
small, .small { font-size: var(--md-sys-typescale-body-small-size); letter-spacing: var(--md-sys-typescale-body-small-tracking); }

/* Type-scale utilities: .md-display-large … .md-label-small */
.md-display-large   { font-family: var(--md-sys-typescale-display-large-font); --md-type-emph: var(--md-sys-typescale-display-large-emphasized-weight);   font-size: var(--md-sys-typescale-display-large-size);   line-height: var(--md-sys-typescale-display-large-line-height);   font-weight: var(--md-sys-typescale-display-large-weight);   letter-spacing: var(--md-sys-typescale-display-large-tracking); }
.md-display-medium  { font-family: var(--md-sys-typescale-display-medium-font); --md-type-emph: var(--md-sys-typescale-display-medium-emphasized-weight);  font-size: var(--md-sys-typescale-display-medium-size);  line-height: var(--md-sys-typescale-display-medium-line-height);  font-weight: var(--md-sys-typescale-display-medium-weight);  letter-spacing: var(--md-sys-typescale-display-medium-tracking); }
.md-display-small   { font-family: var(--md-sys-typescale-display-small-font); --md-type-emph: var(--md-sys-typescale-display-small-emphasized-weight);   font-size: var(--md-sys-typescale-display-small-size);   line-height: var(--md-sys-typescale-display-small-line-height);   font-weight: var(--md-sys-typescale-display-small-weight);   letter-spacing: var(--md-sys-typescale-display-small-tracking); }
.md-headline-large  { font-family: var(--md-sys-typescale-headline-large-font); --md-type-emph: var(--md-sys-typescale-headline-large-emphasized-weight);  font-size: var(--md-sys-typescale-headline-large-size);  line-height: var(--md-sys-typescale-headline-large-line-height);  font-weight: var(--md-sys-typescale-headline-large-weight);  letter-spacing: var(--md-sys-typescale-headline-large-tracking); }
.md-headline-medium { font-family: var(--md-sys-typescale-headline-medium-font); --md-type-emph: var(--md-sys-typescale-headline-medium-emphasized-weight); font-size: var(--md-sys-typescale-headline-medium-size); line-height: var(--md-sys-typescale-headline-medium-line-height); font-weight: var(--md-sys-typescale-headline-medium-weight); letter-spacing: var(--md-sys-typescale-headline-medium-tracking); }
.md-headline-small  { font-family: var(--md-sys-typescale-headline-small-font); --md-type-emph: var(--md-sys-typescale-headline-small-emphasized-weight);  font-size: var(--md-sys-typescale-headline-small-size);  line-height: var(--md-sys-typescale-headline-small-line-height);  font-weight: var(--md-sys-typescale-headline-small-weight);  letter-spacing: var(--md-sys-typescale-headline-small-tracking); }
.md-title-large     { font-family: var(--md-sys-typescale-title-large-font); --md-type-emph: var(--md-sys-typescale-title-large-emphasized-weight);     font-size: var(--md-sys-typescale-title-large-size);     line-height: var(--md-sys-typescale-title-large-line-height);     font-weight: var(--md-sys-typescale-title-large-weight);     letter-spacing: var(--md-sys-typescale-title-large-tracking); }
.md-title-medium    { font-family: var(--md-sys-typescale-title-medium-font); --md-type-emph: var(--md-sys-typescale-title-medium-emphasized-weight);    font-size: var(--md-sys-typescale-title-medium-size);    line-height: var(--md-sys-typescale-title-medium-line-height);    font-weight: var(--md-sys-typescale-title-medium-weight);    letter-spacing: var(--md-sys-typescale-title-medium-tracking); }
.md-title-small     { font-family: var(--md-sys-typescale-title-small-font); --md-type-emph: var(--md-sys-typescale-title-small-emphasized-weight);     font-size: var(--md-sys-typescale-title-small-size);     line-height: var(--md-sys-typescale-title-small-line-height);     font-weight: var(--md-sys-typescale-title-small-weight);     letter-spacing: var(--md-sys-typescale-title-small-tracking); }
.md-body-large      { font-family: var(--md-sys-typescale-body-large-font); --md-type-emph: var(--md-sys-typescale-body-large-emphasized-weight);      font-size: var(--md-sys-typescale-body-large-size);      line-height: var(--md-sys-typescale-body-large-line-height);      font-weight: var(--md-sys-typescale-body-large-weight);      letter-spacing: var(--md-sys-typescale-body-large-tracking); }
.md-body-medium     { font-family: var(--md-sys-typescale-body-medium-font); --md-type-emph: var(--md-sys-typescale-body-medium-emphasized-weight);     font-size: var(--md-sys-typescale-body-medium-size);     line-height: var(--md-sys-typescale-body-medium-line-height);     font-weight: var(--md-sys-typescale-body-medium-weight);     letter-spacing: var(--md-sys-typescale-body-medium-tracking); }
.md-body-small      { font-family: var(--md-sys-typescale-body-small-font); --md-type-emph: var(--md-sys-typescale-body-small-emphasized-weight);      font-size: var(--md-sys-typescale-body-small-size);      line-height: var(--md-sys-typescale-body-small-line-height);      font-weight: var(--md-sys-typescale-body-small-weight);      letter-spacing: var(--md-sys-typescale-body-small-tracking); }
.md-label-large     { font-family: var(--md-sys-typescale-label-large-font); --md-type-emph: var(--md-sys-typescale-label-large-emphasized-weight);     font-size: var(--md-sys-typescale-label-large-size);     line-height: var(--md-sys-typescale-label-large-line-height);     font-weight: var(--md-sys-typescale-label-large-weight);     letter-spacing: var(--md-sys-typescale-label-large-tracking); }
.md-label-medium    { font-family: var(--md-sys-typescale-label-medium-font); --md-type-emph: var(--md-sys-typescale-label-medium-emphasized-weight);    font-size: var(--md-sys-typescale-label-medium-size);    line-height: var(--md-sys-typescale-label-medium-line-height);    font-weight: var(--md-sys-typescale-label-medium-weight);    letter-spacing: var(--md-sys-typescale-label-medium-tracking); }
.md-label-small     { font-family: var(--md-sys-typescale-label-small-font); --md-type-emph: var(--md-sys-typescale-label-small-emphasized-weight);     font-size: var(--md-sys-typescale-label-small-size);     line-height: var(--md-sys-typescale-label-small-line-height);     font-weight: var(--md-sys-typescale-label-small-weight);     letter-spacing: var(--md-sys-typescale-label-small-tracking); }

/* Expressive emphasized type: add .md-emphasized to any .md-<role> class */
.md-emphasized { font-weight: var(--md-type-emph, 700); }

::selection {
  background-color: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
}

/* ==========================================================================
   4. Surface, color & elevation utilities
   ========================================================================== */

.bg-surface                   { background-color: var(--md-sys-color-surface) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-dim               { background-color: var(--md-sys-color-surface-dim) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-bright            { background-color: var(--md-sys-color-surface-bright) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-container-lowest  { background-color: var(--md-sys-color-surface-container-lowest) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-container-low     { background-color: var(--md-sys-color-surface-container-low) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-container         { background-color: var(--md-sys-color-surface-container) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-container-high    { background-color: var(--md-sys-color-surface-container-high) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-container-highest { background-color: var(--md-sys-color-surface-container-highest) !important; color: var(--md-sys-color-on-surface) !important; }
.bg-surface-variant           { background-color: var(--md-sys-color-surface-variant) !important; color: var(--md-sys-color-on-surface-variant) !important; }
.bg-inverse-surface           { background-color: var(--md-sys-color-inverse-surface) !important; color: var(--md-sys-color-inverse-on-surface) !important; }

.bg-primary-container   { background-color: var(--md-sys-color-primary-container) !important; color: var(--md-sys-color-on-primary-container) !important; }
.bg-secondary-container { background-color: var(--md-sys-color-secondary-container) !important; color: var(--md-sys-color-on-secondary-container) !important; }
.bg-tertiary-container  { background-color: var(--md-sys-color-tertiary-container) !important; color: var(--md-sys-color-on-tertiary-container) !important; }
.bg-error-container     { background-color: var(--md-sys-color-error-container) !important; color: var(--md-sys-color-on-error-container) !important; }
.bg-tertiary            { background-color: var(--md-sys-color-tertiary) !important; color: var(--md-sys-color-on-tertiary) !important; }

.text-tertiary           { color: var(--md-sys-color-tertiary) !important; }
.text-on-surface         { color: var(--md-sys-color-on-surface) !important; }
.text-on-surface-variant { color: var(--md-sys-color-on-surface-variant) !important; }
.text-outline            { color: var(--md-sys-color-outline) !important; }

/* Bootstrap's .text-bg-* hard-code #fff / #000 text; use the on-colors. */
.text-bg-primary   { color: var(--md-sys-color-on-primary) !important; }
.text-bg-secondary { color: var(--md-sys-color-on-secondary) !important; }
.text-bg-success   { color: var(--md-sys-color-on-success) !important; }
.text-bg-info      { color: var(--md-sys-color-on-info) !important; }
.text-bg-warning   { color: var(--md-sys-color-on-warning) !important; }
.text-bg-danger    { color: var(--md-sys-color-on-error) !important; }
.text-bg-light     { color: var(--md-sys-color-on-surface) !important; }
.text-bg-dark      { color: var(--md-sys-color-inverse-on-surface) !important; }

.elevation-0 { box-shadow: var(--md-sys-elevation-level0) !important; }
.elevation-1 { box-shadow: var(--md-sys-elevation-level1) !important; }
.elevation-2 { box-shadow: var(--md-sys-elevation-level2) !important; }
.elevation-3 { box-shadow: var(--md-sys-elevation-level3) !important; }
.elevation-4 { box-shadow: var(--md-sys-elevation-level4) !important; }
.elevation-5 { box-shadow: var(--md-sys-elevation-level5) !important; }

.rounded-m3-xs   { border-radius: var(--md-sys-shape-corner-extra-small) !important; }
.rounded-m3-sm   { border-radius: var(--md-sys-shape-corner-small) !important; }
.rounded-m3-md   { border-radius: var(--md-sys-shape-corner-medium) !important; }
.rounded-m3-lg   { border-radius: var(--md-sys-shape-corner-large) !important; }
.rounded-m3-xl   { border-radius: var(--md-sys-shape-corner-extra-large) !important; }
.rounded-m3-full { border-radius: var(--md-sys-shape-corner-full) !important; }

/* ==========================================================================
   5. Buttons
   Each variant sets two inputs (--md-btn-container / --md-btn-content);
   the shared rules turn them into Bootstrap's --bs-btn-* with M3 state
   layers (hover 8%, pressed 10%) mixed in.
   ========================================================================== */

/* Five Expressive sizes (Compose Button*Tokens). Default .btn is S (40px).
   Bootstrap's .btn-sm maps to XS and .btn-lg to M.

          height pad  icon gap  label           pressed   square  outline
     XS   32     16   20   8    label-large     small 8   12      1
     S    40     24   20   8    label-large     small 8   12      1
     M    56     24   24   8    title-medium    medium 12 16      1
     L    96     48   32   12   headline-small  large 16  28      2
     XL   136    64   40   16   headline-large  large 16  28      3

   Every size-dependent value is a variable, so .btn-square, toggles,
   icon buttons and groups all scale with the size class. */
.btn {
  --md-btn-height: 40px;
  --md-btn-icon: 20px;
  --md-btn-gap: 8px;
  --md-btn-outline-w: 1px;
  --md-btn-pressed-shape: var(--md-sys-shape-corner-small);
  --md-btn-square-shape: var(--md-sys-shape-corner-medium);
  --bs-btn-padding-x: 24px;
  --bs-btn-padding-y: 0;
  --bs-btn-font-family: var(--md-sys-typescale-label-large-font);
  --bs-btn-font-size: var(--md-sys-typescale-label-large-size);
  --bs-btn-font-weight: var(--md-sys-typescale-label-large-weight);
  --bs-btn-line-height: var(--md-sys-typescale-label-large-line-height);
  --bs-btn-border-width: var(--md-btn-outline-w);
  /* "full" is clamped to half the height so the corner can animate:
     a 9999px radius can't visibly tween down to 8px. */
  --bs-btn-border-radius: min(var(--md-comp-button-shape), calc(var(--md-btn-height) / 2));
  --bs-btn-box-shadow: none;
  --bs-btn-disabled-opacity: 1;
  min-height: var(--md-btn-height);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--md-btn-gap);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  transition: background-color var(--md-motion-fast-effects),
              box-shadow var(--md-motion-default-effects),
              border-color var(--md-motion-fast-effects),
              color var(--md-motion-fast-effects),
              border-radius var(--md-motion-fast-spatial),
              padding var(--md-motion-fast-spatial);
}
.btn-size-xs, .btn-sm, .btn-group-sm > .btn {
  --md-btn-height: 32px;
  --bs-btn-padding-x: 16px;
}
.btn-size-s { --md-btn-height: 40px; }
.btn-size-m, .btn-lg, .btn-group-lg > .btn {
  --md-btn-height: 56px;
  --md-btn-icon: 24px;
  --md-btn-pressed-shape: var(--md-sys-shape-corner-medium);
  --md-btn-square-shape: var(--md-sys-shape-corner-large);
  --bs-btn-padding-x: 24px;
  --bs-btn-font-family: var(--md-sys-typescale-title-medium-font);
  --bs-btn-font-size: var(--md-sys-typescale-title-medium-size);
  --bs-btn-font-weight: var(--md-sys-typescale-title-medium-weight);
  --bs-btn-line-height: var(--md-sys-typescale-title-medium-line-height);
  letter-spacing: var(--md-sys-typescale-title-medium-tracking);
}
.btn-size-l {
  --md-btn-height: 96px;
  --md-btn-icon: 32px;
  --md-btn-gap: 12px;
  --md-btn-outline-w: 2px;
  --md-btn-pressed-shape: var(--md-sys-shape-corner-large);
  --md-btn-square-shape: var(--md-sys-shape-corner-extra-large);
  --bs-btn-padding-x: 48px;
  --bs-btn-font-family: var(--md-sys-typescale-headline-small-font);
  --bs-btn-font-size: var(--md-sys-typescale-headline-small-size);
  --bs-btn-font-weight: var(--md-sys-typescale-headline-small-weight);
  --bs-btn-line-height: var(--md-sys-typescale-headline-small-line-height);
  letter-spacing: var(--md-sys-typescale-headline-small-tracking);
}
.btn-size-xl {
  --md-btn-height: 136px;
  --md-btn-icon: 40px;
  --md-btn-gap: 16px;
  --md-btn-outline-w: 3px;
  --md-btn-pressed-shape: var(--md-sys-shape-corner-large);
  --md-btn-square-shape: var(--md-sys-shape-corner-extra-large);
  --bs-btn-padding-x: 64px;
  --bs-btn-font-family: var(--md-sys-typescale-headline-large-font);
  --bs-btn-font-size: var(--md-sys-typescale-headline-large-size);
  --bs-btn-font-weight: var(--md-sys-typescale-headline-large-weight);
  --bs-btn-line-height: var(--md-sys-typescale-headline-large-line-height);
  letter-spacing: var(--md-sys-typescale-headline-large-tracking);
}
/* Square shape: XS/S 12 · M 16 · L/XL 28 */
.btn-square { --md-comp-button-shape: var(--md-btn-square-shape); }

/* M3 Expressive shape morph: corners tighten while pressed, spring back on
   release. (FABs and segmented buttons don't morph.) */
.btn:active:not(:disabled):not(.disabled):not(.btn-link):not(.btn-text):not(.btn-fab):not(.btn-group > .btn) {
  --bs-btn-border-radius: min(var(--md-btn-pressed-shape), calc(var(--md-btn-height) / 2));
}

.btn:focus-visible,
.btn-check:focus-visible + .btn {
  outline: var(--md-focus-ring);
  outline-offset: var(--md-focus-offset);
  box-shadow: none;
}

/* Filled */
.btn-primary   { --md-btn-container: var(--md-sys-color-primary);   --md-btn-content: var(--md-sys-color-on-primary); }
.btn-secondary { --md-btn-container: var(--md-sys-color-secondary); --md-btn-content: var(--md-sys-color-on-secondary); }
.btn-tertiary  { --md-btn-container: var(--md-sys-color-tertiary);  --md-btn-content: var(--md-sys-color-on-tertiary); }
.btn-success   { --md-btn-container: var(--md-sys-color-success);   --md-btn-content: var(--md-sys-color-on-success); }
.btn-info      { --md-btn-container: var(--md-sys-color-info);      --md-btn-content: var(--md-sys-color-on-info); }
.btn-warning   { --md-btn-container: var(--md-sys-color-warning);   --md-btn-content: var(--md-sys-color-on-warning); }
.btn-danger    { --md-btn-container: var(--md-sys-color-error);     --md-btn-content: var(--md-sys-color-on-error); }
.btn-light     { --md-btn-container: var(--md-sys-color-surface-container-highest); --md-btn-content: var(--md-sys-color-on-surface); }
.btn-dark      { --md-btn-container: var(--md-sys-color-inverse-surface); --md-btn-content: var(--md-sys-color-inverse-on-surface); }
/* M3 filled tonal */
.btn-tonal     { --md-btn-container: var(--md-sys-color-secondary-container); --md-btn-content: var(--md-sys-color-on-secondary-container); }
/* M3 elevated */
.btn-elevated  { --md-btn-container: var(--md-sys-color-surface-container-low); --md-btn-content: var(--md-sys-color-primary); }

.btn-primary, .btn-secondary, .btn-tertiary, .btn-success, .btn-info,
.btn-warning, .btn-danger, .btn-light, .btn-dark, .btn-tonal, .btn-elevated {
  --bs-btn-color: var(--md-btn-content);
  --bs-btn-bg: var(--md-btn-container);
  --bs-btn-border-color: var(--md-btn-container);
  --bs-btn-hover-color: var(--md-btn-content);
  --bs-btn-hover-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-hover-state-layer-opacity), var(--md-btn-container));
  --bs-btn-hover-border-color: var(--bs-btn-hover-bg);
  --bs-btn-active-color: var(--md-btn-content);
  --bs-btn-active-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-pressed-state-layer-opacity), var(--md-btn-container));
  --bs-btn-active-border-color: var(--bs-btn-active-bg);
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: var(--md-btn-disabled-content);
  --bs-btn-disabled-bg: var(--md-btn-disabled-container);
  --bs-btn-disabled-border-color: transparent;
}
.btn-primary:hover, .btn-secondary:hover, .btn-tertiary:hover, .btn-success:hover,
.btn-info:hover, .btn-warning:hover, .btn-danger:hover {
  box-shadow: var(--md-sys-elevation-level1);
}
.btn-elevated { box-shadow: var(--md-sys-elevation-level1); }
.btn-elevated:hover { box-shadow: var(--md-sys-elevation-level2); }
.btn-elevated:disabled, .btn-elevated.disabled { box-shadow: none; }

/* Outlined. Expressive made the M3 outlined button neutral: on-surface-variant
   label, outline-variant border. .btn-outline-primary / -secondary follow
   the spec; the status variants keep their color since M3 has no equivalent. */
.btn-outline-primary,
.btn-outline-secondary,
.btn-outlined          { --md-btn-content: var(--md-sys-color-on-surface-variant); }
.btn-outline-tertiary  { --md-btn-content: var(--md-sys-color-tertiary); }
.btn-outline-success   { --md-btn-content: var(--md-sys-color-success); --md-btn-outline: var(--md-sys-color-success); }
.btn-outline-info      { --md-btn-content: var(--md-sys-color-info);    --md-btn-outline: var(--md-sys-color-info); }
.btn-outline-warning   { --md-btn-content: var(--md-sys-color-warning); --md-btn-outline: var(--md-sys-color-warning); }
.btn-outline-danger    { --md-btn-content: var(--md-sys-color-error);   --md-btn-outline: var(--md-sys-color-error); }
.btn-outline-light,
.btn-outline-dark      { --md-btn-content: var(--md-sys-color-on-surface); }

.btn[class*="btn-outline-"], .btn-outlined {
  --bs-btn-color: var(--md-btn-content);
  --bs-btn-bg: transparent;
  --bs-btn-border-color: var(--md-btn-outline, var(--md-sys-color-outline-variant));
  --bs-btn-hover-color: var(--md-btn-content);
  --bs-btn-hover-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-btn-hover-border-color: var(--md-btn-outline, var(--md-sys-color-outline-variant));
  --bs-btn-active-color: var(--md-btn-content);
  --bs-btn-active-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-pressed-state-layer-opacity), transparent);
  --bs-btn-active-border-color: var(--md-btn-outline, var(--md-sys-color-outline-variant));
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: var(--md-btn-disabled-content);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: color-mix(in srgb, var(--md-sys-color-outline-variant) 10%, transparent);
}
/* Standalone outlined toggle (.btn-check + .btn-outline-*): Expressive
   selected outlined = inverse-surface. */
.btn-check:checked + .btn[class*="btn-outline-"],
.btn-check:checked + .btn-outlined {
  --md-btn-content: var(--md-sys-color-inverse-on-surface);
  background-color: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  border-color: var(--md-sys-color-inverse-surface);
}

/* Segmented buttons (.btn-group of .btn-check + outlined): M3 outlined
   segmented button: `outline` border, on-surface label, selected
   secondary-container with an 18px check icon. */
.btn-group > .btn[class*="btn-outline-"],
.btn-group > .btn-outlined {
  --md-btn-content: var(--md-sys-color-on-surface);
  --md-btn-outline: var(--md-sys-color-outline);
}
.btn-group > .btn-check:checked + .btn[class*="btn-outline-"],
.btn-group > .btn-check:checked + .btn-outlined {
  --md-btn-content: var(--md-sys-color-on-secondary-container);
  background-color: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border-color: var(--md-sys-color-outline);
}
.btn-group > .btn-check + .btn::before {
  content: "";
  width: 0;
  height: 18px;
  margin-right: -8px; /* cancels the flex gap while hidden */
  background-color: currentColor;
  -webkit-mask: var(--md-check-mask) center / 18px 18px no-repeat;
  mask: var(--md-check-mask) center / 18px 18px no-repeat;
  transition: width var(--md-motion-fast-spatial), margin var(--md-motion-fast-spatial);
}
.btn-group > .btn-check:checked + .btn::before { width: 18px; margin-right: 0; }
:root {
  --md-check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.55 18 3.85 12.3l1.43-1.43 4.27 4.28 9.17-9.18 1.43 1.43z'/%3E%3C/svg%3E");
}

/* Text (.btn-link) */
.btn-link, .btn-text {
  --md-btn-content: var(--md-sys-color-primary);
  --bs-btn-padding-x: 12px;
  --bs-btn-color: var(--md-btn-content);
  --bs-btn-bg: transparent;
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--md-btn-content);
  --bs-btn-hover-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--md-btn-content);
  --bs-btn-active-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-pressed-state-layer-opacity), transparent);
  --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-color: var(--md-btn-disabled-content);
  --bs-btn-disabled-border-color: transparent;
  text-decoration: none;
}
.btn-link:hover, .btn-link:focus-visible { text-decoration: none; }

/* Icon-side padding (Compose ButtonWithIconContentPadding /
   TextButtonWithIconContentPadding). A default (S) button with a leading icon
   uses 16px on that side; a text button uses 12px start / 16px end. An icon
   that is the button's first element counts as leading. For a trailing icon
   add .btn-icon-end. (XS already uses 16px; larger sizes keep their own.) */
.btn:not(.btn-icon):not(.btn-fab):not(.btn-link):not(.btn-text):not(.btn-sm):not(.btn-size-xs):not(.btn-lg):not(.btn-size-m):not(.btn-size-l):not(.btn-size-xl):not(.btn-icon-end):has(> :is(.material-symbols-rounded, .material-symbols-outlined):first-child) {
  padding-left: 16px;
}
.btn.btn-icon-end:not(.btn-link):not(.btn-text):not(.btn-sm):not(.btn-size-xs):not(.btn-lg):not(.btn-size-m):not(.btn-size-l):not(.btn-size-xl) { padding-right: 16px; }
:is(.btn-link, .btn-text):not(.btn-icon-end):has(> :is(.material-symbols-rounded, .material-symbols-outlined):first-child) { padding-left: 12px; padding-right: 16px; }
:is(.btn-link, .btn-text).btn-icon-end { padding-left: 16px; padding-right: 12px; }

/* Icon buttons: any variant above, five sizes × three widths
   (Compose *IconButtonTokens). width = icon + 2 × side space:

          icon  narrow / default / wide side   → widths
     XS   20    4 / 6 / 10                     28 / 32 / 40
     S    24    4 / 8 / 14                     32 / 40 / 52
     M    24    12 / 16 / 24                   48 / 56 / 72
     L    32    16 / 32 / 48                   64 / 96 / 128
     XL   40    32 / 48 / 72                   104 / 136 / 184 */
.btn-icon {
  --md-ib-icon: 24px;
  --md-ib-narrow: 4px;
  --md-ib-default: 8px;
  --md-ib-wide: 14px;
  --md-ib-space: var(--md-ib-default);
  --bs-btn-padding-x: 0;
  width: calc(var(--md-ib-icon) + 2 * var(--md-ib-space));
  height: var(--md-btn-height);
  flex: none;
}
.btn-icon:not(.btn-square) { --md-comp-button-shape: var(--md-sys-shape-corner-full); }
.btn-icon.btn-size-xs, .btn-icon.btn-sm { --md-ib-icon: 20px; --md-ib-narrow: 4px;  --md-ib-default: 6px;  --md-ib-wide: 10px; }
.btn-icon.btn-size-m,  .btn-icon.btn-lg { --md-ib-icon: 24px; --md-ib-narrow: 12px; --md-ib-default: 16px; --md-ib-wide: 24px; }
.btn-icon.btn-size-l  { --md-ib-icon: 32px; --md-ib-narrow: 16px; --md-ib-default: 32px; --md-ib-wide: 48px; }
.btn-icon.btn-size-xl { --md-ib-icon: 40px; --md-ib-narrow: 32px; --md-ib-default: 48px; --md-ib-wide: 72px; }
.btn-icon-narrow { --md-ib-space: var(--md-ib-narrow); }
.btn-icon-wide   { --md-ib-space: var(--md-ib-wide); }
.btn-icon > :is(.material-symbols-rounded, .material-symbols-outlined),
.btn-icon > .badge-anchor > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: var(--md-ib-icon); }
/* :where() keeps this at single-class weight, so context rules such as
   .app-bar-actions .btn-icon or .snackbar .btn-icon can recolor it. */
.btn-icon:not(:where([class*="btn-outline-"], .btn-primary, .btn-secondary, .btn-tertiary, .btn-tonal, .btn-success, .btn-info, .btn-warning, .btn-danger, .btn-light, .btn-dark, .btn-elevated)) {
  --md-btn-content: var(--md-sys-color-on-surface-variant);
  --bs-btn-color: var(--md-btn-content);
  --bs-btn-bg: transparent;
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--md-btn-content);
  --bs-btn-hover-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--md-btn-content);
  --bs-btn-active-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-pressed-state-layer-opacity), transparent);
  --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-color: var(--md-btn-disabled-content);
  --bs-btn-disabled-border-color: transparent;
}

/* Toggle buttons (Expressive). Add .btn-toggle to a filled (.btn-primary),
   tonal, elevated, outlined or standard icon button. Selected via
   .btn-check:checked + .btn, .active or aria-pressed="true".
     filled   unselected surface-container / on-surface-variant → primary / on-primary
     tonal    secondary-container → secondary / on-secondary
     elevated surface-container-low / primary → primary / on-primary
     outlined transparent / on-surface-variant → inverse-surface
     icon     on-surface-variant → primary, with a filled icon
   Selected corners morph from round to the size's square shape. */
.btn-toggle.btn-primary { --md-btn-container: var(--md-sys-color-surface-container); --md-btn-content: var(--md-sys-color-on-surface-variant); }
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]) {
  --md-comp-button-shape: var(--md-btn-square-shape);
  background-color: var(--md-btn-container, transparent);
  color: var(--md-btn-content);
  border-color: var(--md-btn-container, transparent);
}
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]):is(.btn-primary, .btn-elevated) {
  --md-btn-container: var(--md-sys-color-primary);
  --md-btn-content: var(--md-sys-color-on-primary);
}
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]).btn-tonal {
  --md-btn-container: var(--md-sys-color-secondary);
  --md-btn-content: var(--md-sys-color-on-secondary);
}
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]):is([class*="btn-outline-"], .btn-outlined) {
  --md-btn-container: var(--md-sys-color-inverse-surface);
  --md-btn-content: var(--md-sys-color-inverse-on-surface);
}
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]).btn-icon:not([class*="btn-outline-"]):not(.btn-primary):not(.btn-tonal):not(.btn-elevated):not(.btn-outlined) {
  --md-btn-content: var(--md-sys-color-primary);
  --bs-btn-color: var(--md-btn-content);
}
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]) > :is(.material-symbols-rounded, .material-symbols-outlined) {
  font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}
:is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]):hover {
  background-color: var(--bs-btn-hover-bg);
}

/* FAB (M3-only). .btn-fab defaults to primary-container.
   Sizes (Compose Fab*Tokens): -sm 40 / r12 · default 56 / r16 ·
   -md 80 / r20 · -lg 96 / r28. Add -extended for a labelled FAB. */
.btn-fab {
  --md-btn-container: var(--md-sys-color-primary-container);
  --md-btn-content: var(--md-sys-color-on-primary-container);
  --md-fab-shape: var(--md-sys-shape-corner-large);
  --md-btn-icon: 24px;
  --bs-btn-padding-x: 0;
  --bs-btn-border-radius: var(--md-fab-shape);
  --bs-btn-color: var(--md-btn-content);
  --bs-btn-bg: var(--md-btn-container);
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--md-btn-content);
  --bs-btn-hover-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-hover-state-layer-opacity), var(--md-btn-container));
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--md-btn-content);
  --bs-btn-active-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-pressed-state-layer-opacity), var(--md-btn-container));
  --bs-btn-active-border-color: transparent;
  --md-btn-height: 56px;
  width: var(--md-btn-height);
  height: var(--md-btn-height);
  box-shadow: var(--md-sys-elevation-level3);
}
.btn-fab:hover { box-shadow: var(--md-sys-elevation-level4); }
.btn-fab-secondary { --md-btn-container: var(--md-sys-color-secondary-container); --md-btn-content: var(--md-sys-color-on-secondary-container); }
.btn-fab-tertiary  { --md-btn-container: var(--md-sys-color-tertiary-container);  --md-btn-content: var(--md-sys-color-on-tertiary-container); }
.btn-fab-surface   { --md-btn-container: var(--md-sys-color-surface-container-high); --md-btn-content: var(--md-sys-color-primary); }
.btn-fab-primary   { --md-btn-container: var(--md-sys-color-primary); --md-btn-content: var(--md-sys-color-on-primary); }
.btn-fab.btn-fab-sm { --md-btn-height: 40px; --md-fab-shape: var(--md-sys-shape-corner-medium); }
.btn-fab.btn-fab-md { --md-btn-height: 80px; --md-fab-shape: var(--md-sys-shape-corner-large-increased); --md-btn-icon: 28px; }
.btn-fab.btn-fab-lg { --md-btn-height: 96px; --md-fab-shape: var(--md-sys-shape-corner-extra-large); --md-btn-icon: 32px; }
/* Extended FAB: S 56 (pad 16, gap 8) · M 80 (pad 26, gap 16) · L 96 (pad 28, gap 20) */
.btn-fab.btn-fab-extended {
  --bs-btn-padding-x: 16px;
  --md-btn-gap: 8px;
  --bs-btn-font-family: var(--md-sys-typescale-title-medium-font);
  --bs-btn-font-size: var(--md-sys-typescale-title-medium-size);
  --bs-btn-font-weight: var(--md-sys-typescale-title-medium-weight);
  --bs-btn-line-height: var(--md-sys-typescale-title-medium-line-height);
  width: auto;
}
.btn-fab.btn-fab-extended.btn-fab-md {
  --bs-btn-padding-x: 26px;
  --md-btn-gap: 16px;
  --bs-btn-font-family: var(--md-sys-typescale-title-large-font);
  --bs-btn-font-size: var(--md-sys-typescale-title-large-size);
  --bs-btn-font-weight: var(--md-sys-typescale-title-large-weight);
  --bs-btn-line-height: var(--md-sys-typescale-title-large-line-height);
}
.btn-fab.btn-fab-extended.btn-fab-lg {
  --bs-btn-padding-x: 28px;
  --md-btn-gap: 20px;
  --bs-btn-font-family: var(--md-sys-typescale-headline-small-font);
  --bs-btn-font-size: var(--md-sys-typescale-headline-small-size);
  --bs-btn-font-weight: var(--md-sys-typescale-headline-small-weight);
  --bs-btn-line-height: var(--md-sys-typescale-headline-small-line-height);
}
/* Collapse to icon-only (Compose ExtendedFloatingActionButton, expanded =
   false): add .btn-fab-collapsed. Width springs between the full label and
   the square FAB on fast-spatial while the label fades on fast-effects; the
   label stays in the DOM as the accessible name. m3-components.js can drive
   it from scrolling: data-m3-fab-collapse (collapses scrolling down, expands
   scrolling up, as Compose's samples do). Width animation needs
   interpolate-size (Chrome 129+); other browsers switch instantly. */
.btn-fab.btn-fab-extended {
  interpolate-size: allow-keywords;
  justify-content: flex-start;
  overflow: hidden;
  white-space: nowrap;
  transition: background-color var(--md-motion-fast-effects),
              box-shadow var(--md-motion-default-effects),
              color var(--md-motion-fast-effects),
              border-radius var(--md-motion-fast-spatial),
              padding var(--md-motion-fast-spatial),
              width var(--md-motion-fast-spatial);
}
.btn-fab-extended > :is(.material-symbols-rounded, .material-symbols-outlined) { flex: none; color: var(--md-btn-content); }
.btn-fab.btn-fab-extended.btn-fab-collapsed {
  --bs-btn-padding-x: calc((var(--md-btn-height) - var(--md-btn-icon)) / 2);
  --bs-btn-color: transparent;
  --bs-btn-hover-color: transparent;
  --bs-btn-active-color: transparent;
  width: var(--md-btn-height);
}

/* Segmented buttons (Bootstrap .btn-group of toggles) */
.btn-group > .btn { --bs-btn-border-radius: var(--md-comp-button-shape); }

/* Standard button group (Expressive): 12px apart; the pressed button grows
   ~15% and its neighbors give way, on the fast-spatial spring.
   <div class="btn-group-standard"> … .btn … </div> */
.btn-group-standard { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.btn-group-standard > .btn:active:not(:disabled) { padding-inline: calc(var(--bs-btn-padding-x) * 1.3); }
.btn-group-standard > .btn:active:not(:disabled) + .btn,
.btn-group-standard > .btn:active:not(:disabled) + .btn-check + .btn,
.btn-group-standard > .btn:has(+ .btn:active:not(:disabled)),
.btn-group-standard > .btn:has(+ .btn-check + .btn:active:not(:disabled)) {
  padding-inline: calc(var(--bs-btn-padding-x) * 0.85);
}

/* Connected button group (Expressive; replaces segmented buttons):
   2px gaps, outer corners round, inner corners 8 → 4 pressed → fully
   round when selected. Usually holds .btn-toggle buttons.
   <div class="btn-group-connected" role="group"> … </div> */
.btn-group-connected { display: inline-flex; align-items: center; gap: 2px; }
.btn-group-connected > .btn {
  --md-cg-inner: var(--md-sys-shape-corner-small);
  --md-cg-outer: calc(var(--md-btn-height) / 2);
  border-radius: var(--md-cg-inner);
}
.btn-group-connected > .btn:first-of-type { border-start-start-radius: var(--md-cg-outer); border-end-start-radius: var(--md-cg-outer); }
.btn-group-connected > .btn:last-of-type  { border-start-end-radius: var(--md-cg-outer); border-end-end-radius: var(--md-cg-outer); }
.btn-group-connected > .btn:active:not(:disabled) { --md-cg-inner: var(--md-sys-shape-corner-extra-small); }
.btn-group-connected > :is(.btn-check:checked + .btn, .btn.active, .btn[aria-pressed="true"]) { --md-cg-inner: calc(var(--md-btn-height) / 2); }
.btn-group-connected.w-100 > .btn { flex: 1 1 0; }

/* Split button (Expressive): a leading action and a trailing menu button,
   2px apart. Inner corners 4 → 12 on hover/press; the trailing button goes
   fully round and its chevron flips while its menu is open.
   <div class="split-button">
     <button class="btn btn-primary">Save</button>
     <button class="btn btn-primary" data-bs-toggle="dropdown" aria-expanded="false" aria-label="More options">
       <span class="material-symbols-rounded">keyboard_arrow_down</span></button>
     <ul class="dropdown-menu dropdown-menu-end">…</ul>
   </div> */
.split-button { position: relative; display: inline-flex; align-items: center; gap: 2px; vertical-align: middle; }
.split-button > .btn {
  --md-sb-inner: var(--md-sys-shape-corner-extra-small);
  --md-sb-outer: calc(var(--md-btn-height) / 2);
}
.split-button > .btn:first-child {
  padding-inline: 16px 12px;
  border-radius: var(--md-sb-outer) var(--md-sb-inner) var(--md-sb-inner) var(--md-sb-outer);
}
.split-button > .btn + .btn {
  padding-inline: 13px;
  border-radius: var(--md-sb-inner) var(--md-sb-outer) var(--md-sb-outer) var(--md-sb-inner);
}
.split-button > .btn:is(:hover, :active, :focus-visible):not(:disabled) { --md-sb-inner: var(--md-sys-shape-corner-medium); }
.split-button > .btn + .btn:is([aria-expanded="true"], .show) { --md-sb-inner: var(--md-sb-outer); }
.split-button > .btn + .btn > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: 22px; transition: rotate var(--md-motion-fast-spatial); }
.split-button > .btn + .btn:is([aria-expanded="true"], .show) > :is(.material-symbols-rounded, .material-symbols-outlined) { rotate: 180deg; }

/* ==========================================================================
   6. Cards (default = outlined; add .card-elevated or .card-filled)
   ========================================================================== */

.card {
  --bs-card-spacer-x: 16px;
  --bs-card-spacer-y: 16px;
  --bs-card-title-spacer-y: 8px;
  --bs-card-border-color: var(--md-sys-color-outline-variant);
  --bs-card-border-radius: var(--md-comp-card-shape);
  --bs-card-inner-border-radius: max(0px, calc(var(--md-comp-card-shape) - 1px));
  --bs-card-cap-padding-x: 16px;
  --bs-card-cap-padding-y: 12px;
  --bs-card-cap-bg: var(--md-sys-color-surface-container);
  --bs-card-cap-color: var(--md-sys-color-on-surface);
  --bs-card-color: var(--md-sys-color-on-surface);
  --bs-card-title-color: var(--md-sys-color-on-surface);
  --bs-card-subtitle-color: var(--md-sys-color-on-surface-variant);
  --bs-card-bg: var(--md-sys-color-surface);
  overflow: hidden;
}
.card-elevated {
  --bs-card-bg: var(--md-sys-color-surface-container-low);
  --bs-card-border-color: transparent;
  box-shadow: var(--md-sys-elevation-level1);
}
.card-filled {
  --bs-card-bg: var(--md-sys-color-surface-container-highest);
  --bs-card-border-color: transparent;
}
a.card, .card-action { transition: box-shadow var(--md-motion-default-effects), background-color var(--md-motion-default-effects); text-decoration: none; }
a.card:hover, .card-action:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--bs-card-bg)); }
a.card.card-elevated:hover, .card-action.card-elevated:hover { box-shadow: var(--md-sys-elevation-level2); }
/* Interactive filled and outlined cards lift to level 1 on hover (Compose
   FilledCard / OutlinedCard HoverContainerElevation). */
a.card:not(.card-elevated):hover, .card-action:not(.card-elevated):hover { box-shadow: var(--md-sys-elevation-level1); }

.card-title { font-family: var(--md-sys-typescale-title-large-font); font-size: var(--md-sys-typescale-title-large-size); line-height: var(--md-sys-typescale-title-large-line-height); font-weight: var(--md-sys-typescale-title-large-weight); }
.card-subtitle { font-size: var(--md-sys-typescale-body-medium-size); font-weight: 400; }
.card-text { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-medium-size); line-height: var(--md-sys-typescale-body-medium-line-height); letter-spacing: var(--md-sys-typescale-body-medium-tracking); }

/* ==========================================================================
   7. Forms (outlined text fields)
   ========================================================================== */

.form-label {
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-small-size);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  margin-bottom: 4px;
}
.form-text {
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-small-size);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  padding-inline: 16px;
}
/* Character counter (js: data-m3-counter): the supporting text line holds
   the helper text on the left and the count on the right; over a soft
   limit the count goes to the error color (the field does too) */
.form-text.has-counter { display: flex; align-items: baseline; gap: 16px; }
.form-counter { flex: none; margin-left: auto; font-variant-numeric: tabular-nums; transition: color var(--md-motion-fast-effects); }
.form-counter.is-over { color: var(--md-sys-color-error); }
.form-text.is-over { color: var(--md-sys-color-error); }
/* data-autosize: the textarea grows with its text, up to a cap, then scrolls */
textarea[data-autosize] { field-sizing: content; min-height: calc(3lh + 30px); max-height: 320px; resize: none; }
.form-floating > textarea[data-autosize].form-control { height: auto; min-height: 112px; }

.form-control,
.form-select {
  min-height: 56px;
  padding: 15px 16px;
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
  color: var(--md-sys-color-on-surface);
  background-color: transparent;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-comp-field-shape);
  transition: border-color var(--md-motion-default-effects),
              box-shadow var(--md-motion-default-effects);
}
textarea.form-control { min-height: 112px; }
.form-control:hover:not(:disabled):not(:focus),
.form-select:hover:not(:disabled):not(:focus) {
  border-color: var(--md-sys-color-on-surface);
}
.form-control:focus,
.form-select:focus {
  color: var(--md-sys-color-on-surface);
  background-color: transparent;
  border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
  outline: 0;
}
.form-control::placeholder { color: var(--md-sys-color-on-surface-variant); opacity: 1; }
.form-control:disabled,
.form-select:disabled {
  color: var(--md-disabled-content);
  background-color: transparent;
  border-color: var(--md-disabled-container);
}
.form-control[readonly] { background-color: var(--md-sys-color-surface-container-low); }
.form-control-sm, .form-select-sm { min-height: 40px; padding: 7px 12px; font-size: var(--md-sys-typescale-body-medium-size); border-radius: var(--md-comp-field-shape); }
.form-control-lg, .form-select-lg { min-height: 64px; padding: 19px 16px; font-size: var(--md-sys-typescale-title-medium-size); border-radius: var(--md-comp-field-shape); }
.form-control-color { min-height: 56px; width: 4rem; padding: 8px; }

.form-select,
[data-bs-theme] .form-select {
  --bs-form-select-bg-img: var(--md-icon-select);
  padding-right: 48px;
  background-position: right 12px center;
  background-size: 24px 24px;
}
.form-select option { background-color: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface); }

/* Floating labels sit on the outline, M3-style */
.form-floating > .form-control,
.form-floating > .form-select { height: 56px; min-height: 56px; padding: 16px; }
.form-floating > textarea.form-control { height: auto; min-height: 112px; }
/* The label floats on Compose's labelTransitionSpec (fast-spatial, so it
   overshoots a little). Only the transform animates: the box keeps the same
   padding and size in both states, so the motion stays sub-pixel smooth
   (animating padding/margin snapped the text a pixel at a time as the
   spring settled). The text starts at 16px; floated it sits at x 15, on the
   outline, at 75%. The 4px side borders are transparent at rest and become
   the label background's side margins when floated (see the fallback). */
.form-floating > label {
  padding: 16px 12px;
  border-style: solid;
  border-width: 0 4px;
  border-color: transparent;
  color: var(--md-sys-color-on-surface-variant);
  transform-origin: 0 0;
  transition: transform var(--md-motion-fast-spatial), color var(--md-motion-fast-effects);
}
.form-floating > .form-control:focus,
.form-floating > .form-control:not(:placeholder-shown),
.form-floating > .form-select { padding-top: 16px; padding-bottom: 16px; }
.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label,
.form-floating > .form-control-plaintext ~ label,
.form-floating > .form-select ~ label {
  transform: translate(3px, -20px) scale(.75);
  color: var(--md-sys-color-on-surface-variant);
  /* Without m3-components.js the label's own background "notches" the
     outline: the text plus its two 4px borders. It must match whatever the
     field sits on; cards and sheets set --md-field-container. */
  background: linear-gradient(var(--md-field-container, var(--bs-body-bg)) 0 0) content-box;
  border-color: var(--md-field-container, var(--bs-body-bg));
}
.form-floating > .form-control:focus ~ label { color: var(--md-sys-color-primary); }
.form-floating > textarea ~ label::after { display: none; }
.card { --md-field-container: var(--bs-card-bg); }
.modal-content { --md-field-container: var(--bs-modal-bg); }
.offcanvas { --md-field-container: var(--bs-offcanvas-bg); }

/* True outline notch (with js/m3-components.js). The script measures the
   floated label and sets --md-notch-full on the field; the field's top
   border is then masked out where the label sits, so the label needs no
   background and works over any surface. The gap opens and closes on the
   label's own spring (same duration and curve), so the outline never
   crosses the label mid-flight. Without the script the label-background fallback above
   applies. */
@property --md-notch-w { syntax: '<length>'; inherits: false; initial-value: 0px; }
.form-floating.md-js-notch > label,
.form-floating.md-js-notch > .form-control:focus ~ label,
.form-floating.md-js-notch > .form-control:not(:placeholder-shown) ~ label,
.form-floating.md-js-notch > .form-select ~ label { background: none; border-color: transparent; }
.form-floating.md-js-notch > :is(.form-control, .form-select) {
  --md-notch-w: 0px;
  -webkit-mask: linear-gradient(#000 0 0), linear-gradient(#000 0 0) 12px 0 / max(0px, var(--md-notch-w) - 1px) 2px no-repeat;
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0), linear-gradient(#000 0 0) 12px 0 / max(0px, var(--md-notch-w) - 1px) 2px no-repeat;
  mask-composite: exclude;
  /* The spring bounces the width slightly below zero on close; a negative
     size would void the mask, so it's clamped (and trimmed 1px so the
     settling tail can't leave a sub-pixel break in the outline). */
  transition: border-color var(--md-motion-default-effects),
              box-shadow var(--md-motion-default-effects),
              --md-notch-w var(--md-motion-fast-spatial);
}
.form-floating.md-js-notch > .form-control:is(:focus, :not(:placeholder-shown)),
.form-floating.md-js-notch > .form-select { --md-notch-w: var(--md-notch-full, 0px); }

/* Validation: border + supporting text color, no Bootstrap status icons */
.form-control.is-valid, .was-validated .form-control:valid,
.form-select.is-valid, .was-validated .form-select:valid {
  border-color: var(--md-sys-color-success);
  background-image: none;
  padding-right: 16px;
}
.form-control.is-valid:focus, .was-validated .form-control:valid:focus,
.form-select.is-valid:focus, .was-validated .form-select:valid:focus {
  border-color: var(--md-sys-color-success);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-success);
}
.form-control.is-invalid, .was-validated .form-control:invalid,
.form-select.is-invalid, .was-validated .form-select:invalid {
  border-color: var(--md-sys-color-error);
  background-image: none;
  padding-right: 16px;
}
.form-control.is-invalid:focus, .was-validated .form-control:invalid:focus,
.form-select.is-invalid:focus, .was-validated .form-select:invalid:focus {
  border-color: var(--md-sys-color-error);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-error);
}
/* Bootstrap adds a status icon to validated selects with a 4-class selector;
   !important is the least-bad way to keep just the M3 chevron. */
.form-select.is-valid, .form-select.is-invalid,
.was-validated .form-select:valid, .was-validated .form-select:invalid {
  padding-right: 48px !important;
  background-image: var(--bs-form-select-bg-img) !important;
  background-position: right 12px center !important;
  background-size: 24px 24px !important;
}
.valid-feedback, .invalid-feedback {
  font-size: var(--md-sys-typescale-body-small-size);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  padding-inline: 16px;
}
.form-check-input.is-invalid, .was-validated .form-check-input:invalid { border-color: var(--md-sys-color-error); }
.form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { color: var(--md-sys-color-error); }

/* Filled text field (Compose FilledTextFieldTokens): surface-container-highest
   container, extra-small top corners, a 1px on-surface-variant indicator line
   that becomes 2px primary on focus. Add .form-control-filled /
   .form-select-filled; for a floating label add .form-floating-filled to the
   .form-floating wrapper. */
.form-control-filled,
.form-select-filled {
  --md-field-indicator: var(--md-sys-color-on-surface-variant);
  --md-field-indicator-w: 1px;
  background-color: var(--md-sys-color-surface-container-highest);
  border: 0;
  border-radius: var(--md-sys-shape-corner-extra-small) var(--md-sys-shape-corner-extra-small) 0 0;
  box-shadow: inset 0 calc(-1 * var(--md-field-indicator-w)) 0 var(--md-field-indicator);
  transition: box-shadow var(--md-motion-fast-effects), background-color var(--md-motion-fast-effects);
}
.form-control-filled:hover:not(:disabled):not(:focus),
.form-select-filled:hover:not(:disabled):not(:focus) {
  --md-field-indicator: var(--md-sys-color-on-surface);
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-highest));
}
.form-control-filled:focus,
.form-select-filled:focus {
  --md-field-indicator: var(--md-sys-color-primary);
  --md-field-indicator-w: 2px;
  background-color: var(--md-sys-color-surface-container-highest);
  box-shadow: inset 0 calc(-1 * var(--md-field-indicator-w)) 0 var(--md-field-indicator);
}
.form-control-filled:disabled,
.form-select-filled:disabled {
  --md-field-indicator: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 4%, transparent);
}
.form-control-filled.is-invalid, .was-validated .form-control-filled:invalid,
.form-select-filled.is-invalid, .was-validated .form-select-filled:invalid {
  --md-field-indicator: var(--md-sys-color-error);
  box-shadow: inset 0 calc(-1 * var(--md-field-indicator-w)) 0 var(--md-field-indicator);
}
.form-control-filled.is-invalid:hover:not(:focus), .was-validated .form-control-filled:invalid:hover:not(:focus),
.form-select-filled.is-invalid:hover:not(:focus), .was-validated .form-select-filled:invalid:hover:not(:focus) {
  --md-field-indicator: var(--md-sys-color-on-error-container);
}
.form-control-filled.is-invalid:focus, .was-validated .form-control-filled:invalid:focus,
.form-select-filled.is-invalid:focus, .was-validated .form-select-filled:invalid:focus {
  --md-field-indicator: var(--md-sys-color-error);
  --md-field-indicator-w: 2px;
  box-shadow: inset 0 calc(-1 * var(--md-field-indicator-w)) 0 var(--md-field-indicator);
}
.form-control-filled.is-valid, .was-validated .form-control-filled:valid,
.form-select-filled.is-valid, .was-validated .form-select-filled:valid {
  --md-field-indicator: var(--md-sys-color-success);
  box-shadow: inset 0 calc(-1 * var(--md-field-indicator-w)) 0 var(--md-field-indicator);
}
/* Floating label inside the filled container: rests centered, floats to 8px
   from the top in body-small; the input text drops to make room. */
.form-floating-filled > label { background: none; }
.form-floating-filled > .form-control:focus ~ label,
.form-floating-filled > .form-control:not(:placeholder-shown) ~ label,
.form-floating-filled > .form-control-plaintext ~ label,
.form-floating-filled > .form-select ~ label {
  transform: translate(4px, -4px) scale(.75);
  background: none;
  border-color: transparent;
}
.form-floating-filled > .form-control:focus,
.form-floating-filled > .form-control:not(:placeholder-shown),
.form-floating-filled > .form-select { padding-top: 24px; padding-bottom: 8px; }
.form-floating-filled > .form-control.is-invalid ~ label,
.was-validated .form-floating-filled > .form-control:invalid ~ label { color: var(--md-sys-color-error); }

/* Outlined field error hover: outline and label go on-error-container
   (Compose OutlinedTextField ErrorHover* tokens). */
.form-control.is-invalid:hover:not(:focus):not(:disabled):not(.form-control-filled),
.was-validated .form-control:invalid:hover:not(:focus):not(:disabled):not(.form-control-filled),
.form-select.is-invalid:hover:not(:focus):not(:disabled):not(.form-select-filled),
.was-validated .form-select:invalid:hover:not(:focus):not(:disabled):not(.form-select-filled) {
  border-color: var(--md-sys-color-on-error-container);
}
.form-floating > .form-control.is-invalid ~ label,
.was-validated .form-floating > .form-control:invalid ~ label { color: var(--md-sys-color-error); }
.form-floating > .form-control.is-invalid:hover:not(:focus) ~ label,
.was-validated .form-floating > .form-control:invalid:hover:not(:focus) ~ label { color: var(--md-sys-color-on-error-container); }

/* Input groups */
.input-group-text {
  color: var(--md-sys-color-on-surface-variant);
  background-color: var(--md-sys-color-surface-container-highest);
  border-color: var(--md-sys-color-outline);
  border-radius: var(--md-comp-field-shape);
  padding-inline: 16px;
}
.input-group > .btn { min-height: 56px; }

/* Checkbox / radio */
.form-check { min-height: 24px; padding-left: 2em; }
.form-check .form-check-input { margin-left: -2em; }
.form-check-input {
  --bs-form-check-bg: transparent;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  border: 2px solid var(--md-sys-color-on-surface-variant);
  /* The mark grows from 0 on a spatial spring, so it "pops" in. */
  background-size: 0 0;
  transition: box-shadow var(--md-motion-fast-effects),
              background-color var(--md-motion-fast-effects),
              border-color var(--md-motion-fast-effects),
              background-size var(--md-motion-fast-spatial);
}
.form-check-input:checked,
.form-check-input[type=checkbox]:indeterminate { background-size: 100% 100%; }
/* Checkbox: the mark draws on left → right (a wipe) instead of popping. */
.form-check-input[type=checkbox]:not(.form-switch > *) {
  background-position: left center;
  background-size: 0% 100%;
  transition: box-shadow var(--md-motion-fast-effects),
              background-color var(--md-motion-fast-effects),
              border-color var(--md-motion-fast-effects),
              background-size var(--md-motion-default-effects);
}
.form-check-input[type=checkbox]:not(.form-switch > *):is(:checked, :indeterminate) { background-size: 100% 100%; }
.form-check-input[type=checkbox] { border-radius: 2px; }
.form-check-input[type=radio] { width: 20px; height: 20px; margin-top: 2px; }
.form-check-input:hover:not(:disabled) { box-shadow: 0 0 0 11px color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.form-check-input:checked:hover:not(:disabled) { box-shadow: 0 0 0 11px color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.form-check-input:focus { border-color: var(--md-sys-color-on-surface-variant); box-shadow: none; }
.form-check-input:focus-visible { outline: var(--md-focus-ring); outline-offset: var(--md-focus-offset); }
.form-check-input:checked { background-color: var(--md-sys-color-primary); border-color: var(--md-sys-color-primary); }
.form-check-input:checked[type=checkbox] { --bs-form-check-bg-image: var(--md-icon-check); }
.form-check-input[type=checkbox]:indeterminate {
  background-color: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
  --bs-form-check-bg-image: var(--md-icon-indeterminate);
}
/* Radio dot (Compose RadioButton): a 12px dot whose radius animates on the
   fast-spatial spring. Drawn as a gradient with a registered radius so it
   renders at sub-pixel precision (a resized background image snaps to whole
   pixels and visibly wobbles). */
@property --md-radio-r { syntax: '<length>'; inherits: false; initial-value: 0px; }
.form-check-input[type=radio] {
  --md-radio-r: 0px;
  --md-radio-dot: var(--md-sys-color-primary);
  --bs-form-check-bg-image: radial-gradient(circle at 50% 50%, var(--md-radio-dot) calc(var(--md-radio-r) - .5px), transparent var(--md-radio-r));
  background-size: 100% 100%;
  background-position: 0 0;
  transition: box-shadow var(--md-motion-fast-effects),
              border-color var(--md-motion-default-effects),
              --md-radio-r var(--md-motion-fast-spatial);
}
.form-check-input:checked[type=radio] {
  --md-radio-r: 6px;
  --bs-form-check-bg-image: radial-gradient(circle at 50% 50%, var(--md-radio-dot) calc(var(--md-radio-r) - .5px), transparent var(--md-radio-r));
  background-color: transparent;
  background-size: 100% 100%;
  border-color: var(--md-sys-color-primary);
}
/* Unselected hover/press darkens the outline to on-surface (Compose tokens) */
.form-check-input:not(:checked):not(:indeterminate):not(:disabled):not(.form-switch > *):not(.is-invalid):not(.was-validated :invalid):is(:hover, :active) {
  border-color: var(--md-sys-color-on-surface);
}

/* Disabled: per-part colors instead of fading the whole control.
   Checkbox checked → on-surface 38% container with a `surface` mark. */
.form-check-input:disabled { opacity: 1; border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent); }
.form-check-input[type=checkbox]:disabled:checked,
.form-check-input[type=checkbox]:disabled:indeterminate {
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  border-color: transparent;
}
.form-check-input[type=checkbox]:disabled:checked { --bs-form-check-bg-image: var(--md-icon-check-disabled); }
.form-check-input[type=checkbox]:disabled:indeterminate { --bs-form-check-bg-image: var(--md-icon-indeterminate-disabled); }
.form-check-input[type=radio]:disabled:checked { --md-radio-dot: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent); }
.form-check-input:disabled ~ .form-check-label, .form-check-input[disabled] ~ .form-check-label { opacity: .38; }

/* Error: outline goes `error`; a checked checkbox fills `error` with an
   on-error mark (radio dot turns error). */
.form-check-input.is-invalid:checked, .was-validated .form-check-input:invalid:checked,
.form-check-input[type=checkbox].is-invalid:indeterminate {
  background-color: var(--md-sys-color-error);
  border-color: var(--md-sys-color-error);
}
.form-check-input[type=checkbox].is-invalid:checked, .was-validated .form-check-input[type=checkbox]:invalid:checked { --bs-form-check-bg-image: var(--md-icon-check-error); }
.form-check-input[type=checkbox].is-invalid:indeterminate { --bs-form-check-bg-image: var(--md-icon-indeterminate-error); }
.form-check-input[type=radio].is-invalid:checked, .was-validated .form-check-input[type=radio]:invalid:checked {
  background-color: transparent;
  --md-radio-dot: var(--md-sys-color-error);
}
.form-check-input.is-invalid:hover:not(:disabled), .was-validated .form-check-input:invalid:hover:not(:disabled) {
  box-shadow: 0 0 0 11px color-mix(in srgb, var(--md-sys-color-error) var(--md-sys-state-hover-state-layer-opacity), transparent);
}

/* Switch: M3 52×32 track. The handle is a radial-gradient whose position,
   radius and color are registered custom properties, so they animate on
   springs: it slides with overshoot, grows 16→24px when selected and
   28px while pressed. No extra markup; it's still a native checkbox. */
@property --md-switch-x { syntax: '<length>'; inherits: false; initial-value: 14px; }
@property --md-switch-r { syntax: '<length>'; inherits: false; initial-value: 8px; }
@property --md-switch-handle { syntax: '<color>'; inherits: false; initial-value: transparent; }

.form-switch { padding-left: 64px; min-height: 32px; }
.form-switch .form-check-input {
  --md-switch-x: 14px;
  --md-switch-r: 8px;
  --md-switch-handle: var(--md-sys-color-outline);
  width: 52px;
  height: 32px;
  margin-left: -64px;
  margin-top: -4px;
  border: 2px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-surface-container-highest);
  background-size: 100% 100%;
  background-position: 0 0;
  transition: --md-switch-x var(--md-motion-fast-spatial),
              --md-switch-r var(--md-motion-fast-spatial),
              --md-switch-handle var(--md-motion-fast-effects),
              background-color var(--md-motion-fast-effects),
              border-color var(--md-motion-fast-effects);
}
/* background-image is restated at Bootstrap's dark-mode specificity so its
   SVG knob never wins; the custom properties carry all the state. */
.form-switch .form-check-input,
.form-switch .form-check-input:focus,
.form-switch .form-check-input:checked,
[data-bs-theme] .form-switch .form-check-input:not(:checked):not(:focus) {
  background-image: radial-gradient(circle at var(--md-js-switch-x, var(--md-switch-x)) 50%,
                    var(--md-switch-handle) calc(var(--md-js-switch-r, var(--md-switch-r)) - .5px),
                    transparent var(--md-js-switch-r, var(--md-switch-r)));
  background-position: 0 0;
}
/* With m3-springs.js loaded, position and size are integrated in JS (so an
   interrupted toggle keeps its momentum); only colors stay on CSS transitions. */
.form-switch .form-check-input.md-js-spring {
  transition: --md-switch-handle var(--md-motion-fast-effects),
              background-color var(--md-motion-fast-effects),
              border-color var(--md-motion-fast-effects);
}
.form-switch .form-check-input:focus { border-color: var(--md-sys-color-outline); }
.form-switch .form-check-input:hover:not(:disabled) { --md-switch-handle: var(--md-sys-color-on-surface-variant); box-shadow: none; }
.form-switch .form-check-input:active:not(:disabled) { --md-switch-r: 14px; --md-switch-handle: var(--md-sys-color-on-surface-variant); }
.form-switch .form-check-input:checked {
  --md-switch-x: 34px;
  --md-switch-r: 12px;
  --md-switch-handle: var(--md-sys-color-on-primary);
  background-color: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
}
.form-switch .form-check-input:checked:hover:not(:disabled) { --md-switch-handle: var(--md-sys-color-primary-container); }
.form-switch .form-check-input:checked:active:not(:disabled) { --md-switch-r: 14px; --md-switch-handle: var(--md-sys-color-primary-container); }
/* Disabled (Compose tokens): track at 12%, unselected handle on-surface 38%,
   selected handle solid `surface`. */
.form-switch .form-check-input:disabled {
  --md-switch-handle: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  background-color: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 12%, transparent);
  border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
}
.form-switch .form-check-input:checked:disabled {
  --md-switch-handle: var(--md-sys-color-surface);
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  border-color: transparent;
}
.form-switch .form-check-input:hover:not(:disabled) { border-color: var(--md-sys-color-outline); }
.form-switch .form-check-input:checked:hover:not(:disabled) { border-color: var(--md-sys-color-primary); }

/* State layer: a 40px circle around the handle on hover / focus / press.
   It overflows the 32px track, so the wrapper draws it (an input can't
   paint outside its own box) and follows the handle via :has(). */
.form-switch { position: relative; }
.form-switch::before {
  content: "";
  position: absolute;
  z-index: 2;
  top: -8px;
  left: -4px;               /* handle center 16px − 20px */
  width: 40px;
  height: 40px;
  border-radius: 50%;
  pointer-events: none;
  background-color: transparent;
  transition: left var(--md-motion-fast-spatial), right var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects);
}
.form-switch:has(> .form-check-input:checked)::before { left: 16px; }  /* 36 − 20 */
.form-switch:has(> .form-check-input:not(:disabled):hover)::before {
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
}
.form-switch:has(> .form-check-input:not(:disabled):is(:focus-visible, :active))::before {
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity), transparent);
}
.form-switch:has(> .form-check-input:checked:not(:disabled):hover)::before {
  background-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-hover-state-layer-opacity), transparent);
}
.form-switch:has(> .form-check-input:checked:not(:disabled):is(:focus-visible, :active))::before {
  background-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-pressed-state-layer-opacity), transparent);
}
.form-check-reverse.form-switch::before { left: auto; right: 16px; }
.form-check-reverse.form-switch:has(> .form-check-input:checked)::before { left: auto; right: -4px; }
.form-check-reverse.form-switch { padding-left: 0; padding-right: 64px; }
.form-check-reverse.form-switch .form-check-input { margin-left: 0; margin-right: -64px; }

/* Slider (M3 Expressive, Compose SliderTokens): 16px track, 4×44px bar
   handle that narrows to 2px while pressed or focused, a 6px gap each side
   of the handle, and a 4px stop dot 8px (the corner radius) from the end.
   The narrowing is instant and keeps the 4px layout box, as in Compose
   (ThumbContent draws a narrower bar inside a fixed box): resizing the
   native thumb would move it along the track, which made it jitter.

   A native range can't tell CSS where its handle is, and Chrome has no
   "filled part" pseudo-element. The optional js/m3-components.js sets
   --md-range-p (0–1) and adds .md-js-range, which turns on the full
   design. Without it, Firefox still fills via ::-moz-range-progress;
   Chrome shows the track and handle only. */
.form-range {
  --md-range-p: 0;
  --md-range-active: var(--md-sys-color-primary);
  --md-range-inactive: var(--md-sys-color-secondary-container);
  --md-range-handle: var(--md-sys-color-primary);
  --md-range-stop: var(--md-sys-color-primary);
  height: 44px;
  padding: 0;
}
.form-range:disabled {
  --md-range-active: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  --md-range-inactive: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  --md-range-handle: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  --md-range-stop: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
}
.form-range.md-js-range {
  /* Handle center along the track (the 4px handle travels inside it) */
  --md-range-x: calc(2px + (100% - 4px) * var(--md-range-p));
  --md-range-fill:
    radial-gradient(circle at calc(100% - 8px) 50%, var(--md-range-stop-now, var(--md-range-stop)) 2px, transparent 2.5px),
    linear-gradient(to right,
      var(--md-range-active) 0 calc(var(--md-range-x) - 8px),
      transparent 0 calc(var(--md-range-x) + 8px),
      var(--md-range-inactive) 0);
}

/* The script hides the stop dot while it sits inside the handle's gap */
.form-range.md-range-stop-hidden { --md-range-stop-now: transparent; }

.form-range::-webkit-slider-runnable-track {
  height: 16px;
  border-radius: 8px;
  background: var(--md-range-inactive);
}
.form-range.md-js-range::-webkit-slider-runnable-track { background: var(--md-range-fill); }
.form-range::-webkit-slider-thumb,
.form-range:active::-webkit-slider-thumb,
.form-range:disabled::-webkit-slider-thumb {
  box-sizing: border-box;
  width: 4px;
  height: 44px;
  margin-top: -14px;
  border: 0 solid transparent;
  border-radius: 2px;
  background: var(--md-range-handle) padding-box;
  box-shadow: none;
  transition: none;
}
.form-range:is(:active, :focus-visible)::-webkit-slider-thumb { border-inline-width: 1px; }
.form-range:focus::-webkit-slider-thumb { box-shadow: none; }

.form-range::-moz-range-track {
  height: 16px;
  border-radius: 8px;
  background: var(--md-range-inactive);
}
.form-range::-moz-range-progress {
  height: 16px;
  border-radius: 8px 2px 2px 8px;
  background: var(--md-range-active);
}
.form-range.md-js-range::-moz-range-track { background: var(--md-range-fill); }
.form-range.md-js-range::-moz-range-progress { background: transparent; }
.form-range::-moz-range-thumb,
.form-range:active::-moz-range-thumb,
.form-range:disabled::-moz-range-thumb {
  box-sizing: border-box;
  width: 4px;
  height: 44px;
  border: 0 solid transparent;
  border-radius: 2px;
  background: var(--md-range-handle) padding-box;
  box-shadow: none;
  transition: none;
}
.form-range:is(:active, :focus-visible)::-moz-range-thumb { border-inline-width: 1px; }

/* ---- Slider component (Compose Slider / RangeSlider / VerticalSlider) ----
   Wrap native ranges in .slider. js/m3-components.js draws the track from
   real geometry; the inputs stay underneath for keyboard, forms and screen
   readers. Without the script it falls back to the plain .form-range above.
     <div class="slider"><input type="range" class="form-range" aria-label="Volume"></div>
   Options on .slider:
     .slider-s / -m / -l / -xl   Expressive sizes (track 24 / 40 / 56 / 96px)
     .slider-vertical            bottom-to-top; give it a height (default 240px)
     .slider-labeled             value indicator above the handle while
                                 dragging or keyboard-focused
                                 (data-m3-suffix="%" appends text)
     .slider-ticks               a dot per step (needs step on the input)
   Two inputs make a range slider. Optional icons inside the track:
     <span class="material-symbols-rounded slider-icon">volume_up</span>
       inset icon (M and up): rides the start of the active track, hops to
       the inactive side when the active part gets too short
     <span class="material-symbols-rounded slider-icon-start">…</span> and
     <span class="material-symbols-rounded slider-icon-end">…</span>
       fixed at the track's ends (Compose SliderWithTrackIconsSample)
   Track heights, corners and handle sizes for S–XL follow the Expressive
   slider spec; the 8px / 12px icon inset is my reading of it. */
.slider {
  --md-slider-track: 16px;
  --md-slider-handle: 44px;
  --md-slider-corner: 8px;
  --md-slider-icon: 24px;
  --md-slider-icon-pad: 8px;
  --md-slider-active: var(--md-sys-color-primary);
  --md-slider-inactive: var(--md-sys-color-secondary-container);
  --md-slider-handle-color: var(--md-sys-color-primary);
  --md-slider-on-active: var(--md-sys-color-secondary-container);  /* ticks/stops on the active track */
  --md-slider-on-inactive: var(--md-sys-color-primary);            /* ticks/stops on the inactive track */
  --md-slider-icon-on-active: var(--md-sys-color-on-primary);
  --md-slider-icon-on-inactive: var(--md-sys-color-on-secondary-container);
  position: relative;
  touch-action: none;
}
.slider-s  { --md-slider-track: 24px; }
.slider-m  { --md-slider-track: 40px; --md-slider-handle: 52px; --md-slider-corner: 12px; }
.slider-l  { --md-slider-track: 56px; --md-slider-handle: 68px; --md-slider-corner: 16px; }
.slider-xl { --md-slider-track: 96px; --md-slider-handle: 108px; --md-slider-corner: 28px; --md-slider-icon: 32px; --md-slider-icon-pad: 12px; }
.slider:has(.form-range:disabled) {
  --md-slider-active: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  --md-slider-inactive: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  --md-slider-handle-color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  --md-slider-on-active: var(--md-sys-color-inverse-on-surface);
  --md-slider-on-inactive: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  --md-slider-icon-on-active: var(--md-sys-color-inverse-on-surface);
  --md-slider-icon-on-inactive: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
}
/* No script yet: icons hidden, stacked range inputs laid out one per row */
.slider:not(.md-js-slider) > :is(.slider-icon, .slider-icon-start, .slider-icon-end) { display: none; }

.md-js-slider { height: var(--md-slider-handle); cursor: pointer; }
.md-js-slider.slider-vertical { width: var(--md-slider-handle); height: 240px; }
.md-js-slider:has(.form-range:disabled) { cursor: default; }
/* The native inputs cover the slider invisibly: they keep focus, keyboard
   and form behaviour, while the script handles pointer input. */
.md-js-slider > .form-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.md-js-slider.slider-vertical > .form-range { writing-mode: vertical-lr; direction: rtl; }
.slider-track {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% - var(--md-slider-track) / 2);
  height: var(--md-slider-track);
}
.slider-vertical .slider-track {
  top: 0;
  bottom: 0;
  left: calc(50% - var(--md-slider-track) / 2);
  right: auto;
  width: var(--md-slider-track);
  height: auto;
}
.slider-seg, .slider-dot, .slider-handle, .slider-track > :is(.slider-icon, .slider-icon-start, .slider-icon-end) { position: absolute; }
.slider-seg { top: 0; height: 100%; }
.slider-vertical .slider-seg { top: auto; left: 0; width: 100%; height: auto; }
.slider-seg-active { background-color: var(--md-slider-active); }
.slider-seg-inactive { background-color: var(--md-slider-inactive); }
.slider-dot {
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  top: 50%;
  border-radius: 50%;
  background-color: var(--md-slider-on-inactive);
}
.slider-vertical .slider-dot { top: auto; left: 50%; margin: 0 0 -2px -2px; }
.slider-dot.on-active { background-color: var(--md-slider-on-active); }
.slider-handle {
  top: calc(50% - var(--md-slider-handle) / 2);
  width: 4px;
  height: var(--md-slider-handle);
  margin-left: -2px;
}
.slider-vertical .slider-handle {
  top: auto;
  left: calc(50% - var(--md-slider-handle) / 2);
  width: var(--md-slider-handle);
  height: 4px;
  margin: 0 0 -2px;
}
/* The bar inside the handle box narrows to 2px instantly when pressed or
   keyboard-focused (Compose ThumbContent), without moving the box. */
.slider-handle::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 2px;
  background-color: var(--md-slider-handle-color);
}
.slider-handle.md-pressed::before, .slider-handle.md-focused::before { inset: 0 1px; }
.slider-vertical .slider-handle.md-pressed::before, .slider-vertical .slider-handle.md-focused::before { inset: 1px 0; }
.slider-handle.md-focused::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 4px;
  outline: var(--md-focus-ring);
  outline-offset: var(--md-focus-offset);
}
.slider-handle.md-pressed::after { display: none; }
.slider-track > :is(.slider-icon, .slider-icon-start, .slider-icon-end) {
  top: calc(50% - var(--md-slider-icon) / 2);
  width: var(--md-slider-icon);
  height: var(--md-slider-icon);
  font-size: var(--md-slider-icon);
  line-height: 1;
  color: var(--md-slider-icon-on-inactive);
  pointer-events: none;
  transition: color var(--md-motion-fast-effects), opacity var(--md-motion-fast-effects);
}
.slider-vertical .slider-track > :is(.slider-icon, .slider-icon-start, .slider-icon-end) { top: auto; left: calc(50% - var(--md-slider-icon) / 2); }
.slider-track > .on-active { color: var(--md-slider-icon-on-active); }
.slider-track > .md-hidden { opacity: 0; }

/* Value indicator (SliderTokens.ValueIndicator*): inverse-surface pill in
   label-large, 12px above the handle (left of it on a vertical slider). */
.slider-value {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 12px);
  min-width: 48px;
  height: 44px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 22px;
  background-color: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  font-weight: var(--md-sys-typescale-label-large-weight);
  white-space: nowrap;
  pointer-events: none;
  translate: -50% 0;
  transform-origin: 50% 100%;
  scale: .6;
  opacity: 0;
  transition: scale var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
.slider-vertical .slider-value { left: auto; right: calc(100% + 12px); bottom: auto; top: 50%; translate: 0 -50%; transform-origin: 100% 50%; }
.slider-handle:is(.md-pressed, .md-focused) > .slider-value { scale: 1; opacity: 1; }
.form-range:focus::-moz-range-thumb { box-shadow: none; }

/* ==========================================================================
   8. Chips (M3-only): assist / filter / input
   <button class="chip">Label</button>
   <input type="checkbox" class="btn-check" id="x"><label class="chip" for="x">Filter</label>
   ========================================================================== */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 16px;
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  line-height: 1;
  color: var(--md-sys-color-on-surface-variant);
  background-color: transparent;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-comp-chip-shape);
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  transition: background-color var(--md-motion-default-effects);
}
.chip:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) var(--md-sys-state-hover-state-layer-opacity), transparent); color: var(--md-sys-color-on-surface-variant); }
.chip:focus-visible, .btn-check:focus-visible + .chip { outline: var(--md-focus-ring); outline-offset: var(--md-focus-offset); }
.chip.active, .btn-check:checked + .chip {
  color: var(--md-sys-color-on-secondary-container);
  background-color: var(--md-sys-color-secondary-container);
  border-color: transparent;
}
.chip.active:hover, .btn-check:checked + .chip:hover {
  background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-secondary-container));
}
.chip:disabled, .btn-check:disabled + .chip { color: var(--md-disabled-content); border-color: var(--md-disabled-container); pointer-events: none; }
.chip .material-symbols-rounded, .chip svg { font-size: 18px; width: 18px; height: 18px; }
.chip-elevated { border-color: transparent; background-color: var(--md-sys-color-surface-container-low); box-shadow: var(--md-sys-elevation-level1); }
/* Leading icons are primary (Assist/Suggestion/Filter chip tokens); selected
   chips use the label color; input chips stay on-surface-variant. */
.chip > :is(.material-symbols-rounded, .material-symbols-outlined):first-child { color: var(--md-sys-color-primary); }
:is(.chip.active, .btn-check:checked + .chip) > :is(.material-symbols-rounded, .material-symbols-outlined):first-child,
.chip:disabled > :is(.material-symbols-rounded, .material-symbols-outlined),
.btn-check:disabled + .chip > :is(.material-symbols-rounded, .material-symbols-outlined) { color: inherit; }
.chip-input > :is(.material-symbols-rounded, .material-symbols-outlined):first-child { color: var(--md-sys-color-on-surface-variant); }

/* ==========================================================================
   9. Navigation
   ========================================================================== */

.navbar {
  --bs-navbar-color: var(--md-sys-color-on-surface-variant);
  --bs-navbar-hover-color: var(--md-sys-color-on-surface);
  --bs-navbar-active-color: var(--md-sys-color-on-surface);
  --bs-navbar-disabled-color: var(--md-disabled-content);
  --bs-navbar-brand-color: var(--md-sys-color-on-surface);
  --bs-navbar-brand-hover-color: var(--md-sys-color-on-surface);
  --bs-navbar-brand-font-size: var(--md-sys-typescale-title-large-size);
  --bs-navbar-toggler-border-color: transparent;
  --bs-navbar-toggler-border-radius: var(--md-sys-shape-corner-full);
  --bs-navbar-toggler-focus-width: 3px;
  min-height: 64px;
}
.navbar-brand { font-family: var(--md-sys-typescale-title-large-font); font-weight: var(--md-sys-typescale-title-large-weight); }
.navbar-toggler-icon,
[data-bs-theme] .navbar-toggler-icon { --bs-navbar-toggler-icon-bg: var(--md-icon-menu); }
.navbar-toggler:focus { box-shadow: none; outline: var(--md-focus-ring); }

.nav-link {
  --bs-nav-link-color: var(--md-sys-color-on-surface-variant);
  --bs-nav-link-hover-color: var(--md-sys-color-on-surface);
  --bs-nav-link-disabled-color: var(--md-disabled-content);
  --bs-nav-link-font-size: var(--md-sys-typescale-label-large-size);
  --bs-nav-link-font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
}
.nav-link:focus-visible { box-shadow: none; outline: var(--md-focus-ring); outline-offset: -3px; }

/* Pills = M3 navigation-style active indicator */
.nav-pills {
  --bs-nav-pills-border-radius: var(--md-sys-shape-corner-full);
  --bs-nav-pills-link-active-color: var(--md-sys-color-on-secondary-container);
  --bs-nav-pills-link-active-bg: var(--md-sys-color-secondary-container);
  gap: 4px;
}
.nav-pills .nav-link:not(.active):hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }

/* Tabs = M3 primary tabs (underline indicator) */
.nav-tabs {
  --bs-nav-tabs-border-width: 1px;
  --bs-nav-tabs-border-color: var(--md-sys-color-surface-variant);
  --bs-nav-tabs-border-radius: 0;
  --bs-nav-tabs-link-hover-border-color: transparent;
  --bs-nav-tabs-link-active-color: var(--md-sys-color-primary);
  --bs-nav-tabs-link-active-bg: transparent;
  --bs-nav-tabs-link-active-border-color: transparent;
}
.nav-tabs .nav-link { border: 0; padding: 14px 16px; position: relative; }
.nav-tabs .nav-link:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.nav-tabs .nav-link.active::after {
  content: "";
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 0;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background-color: var(--md-sys-color-primary);
}

.breadcrumb {
  --bs-breadcrumb-divider-color: var(--md-sys-color-on-surface-variant);
  --bs-breadcrumb-item-active-color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-medium-size);
  /* One line that scrolls sideways when the trail is too long, starting at
     the first (home) item. m3-components.js adds edge fades and arrow
     buttons; .breadcrumb-wrap restores Bootstrap's wrapping. Ported from the
     Hunt Safety Zone breadcrumbs (2026-10-04). */
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  white-space: nowrap;
  padding-block: 4px;  /* room for focus rings inside the scroller */
}
.breadcrumb::-webkit-scrollbar { display: none; }
.breadcrumb > .breadcrumb-item { flex-shrink: 0; }
.breadcrumb.breadcrumb-wrap { flex-wrap: wrap; overflow-x: visible; white-space: normal; }

/* With the script: the trail sits in .breadcrumb-scroll, which fades the
   cut-off side(s) and shows a round arrow there. The arrows step one link at
   a time, so a long title can never carry a middle page past unseen. */
@property --md-crumbs-fade-start { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --md-crumbs-fade-end { syntax: "<length>"; inherits: true; initial-value: 0px; }
.breadcrumb-scroll {
  --md-crumbs-fade: 48px;
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
  transition: --md-crumbs-fade-start var(--md-motion-fast-effects), --md-crumbs-fade-end var(--md-motion-fast-effects);
}
.breadcrumb-scroll.can-prev { --md-crumbs-fade-start: var(--md-crumbs-fade); }
.breadcrumb-scroll.can-next { --md-crumbs-fade-end: var(--md-crumbs-fade); }
.breadcrumb-scroll > .breadcrumb {
  flex: 1 1 auto;
  min-width: 0;
  mask-image: linear-gradient(to right, transparent 0, #000 var(--md-crumbs-fade-start), #000 calc(100% - var(--md-crumbs-fade-end)), transparent 100%);
}
.breadcrumb-scroll-btn.btn-icon {
  /* A real M3 icon button (press shape-morph, ripple, state layers) on a
     raised surface; it scales in from 0.8 on fast-spatial as it appears. */
  --bs-btn-bg: var(--md-sys-color-surface-container-highest);
  --bs-btn-hover-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-highest));
  --bs-btn-active-bg: color-mix(in srgb, var(--md-btn-content) var(--md-sys-state-pressed-state-layer-opacity), var(--md-sys-color-surface-container-highest));
  position: absolute;
  top: 50%;
  z-index: 1;
  box-shadow: var(--md-sys-elevation-level1);
  translate: 0 -50%;
  scale: .8;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--md-motion-fast-effects), scale var(--md-motion-fast-spatial),
              visibility 0s linear var(--md-sys-motion-spring-fast-effects-duration),
              border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects);
}
.breadcrumb-scroll-prev { left: 0; }
.breadcrumb-scroll-next { right: 0; }
.breadcrumb-scroll.can-prev .breadcrumb-scroll-prev,
.breadcrumb-scroll.can-next .breadcrumb-scroll-next {
  scale: 1;
  opacity: 1;
  visibility: visible;
  transition: opacity var(--md-motion-fast-effects), scale var(--md-motion-fast-spatial), visibility 0s,
              border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects);
}

.pagination {
  --bs-pagination-padding-x: 0;
  --bs-pagination-padding-y: 0;
  --bs-pagination-font-size: var(--md-sys-typescale-label-large-size);
  --bs-pagination-color: var(--md-sys-color-on-surface-variant);
  --bs-pagination-bg: transparent;
  --bs-pagination-border-width: 0;
  --bs-pagination-border-color: transparent;
  --bs-pagination-border-radius: var(--md-sys-shape-corner-full);
  --bs-pagination-hover-color: var(--md-sys-color-on-surface);
  --bs-pagination-hover-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-pagination-hover-border-color: transparent;
  --bs-pagination-focus-color: var(--md-sys-color-on-surface);
  --bs-pagination-focus-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity), transparent);
  --bs-pagination-focus-box-shadow: none;
  --bs-pagination-active-color: var(--md-sys-color-on-secondary-container);
  --bs-pagination-active-bg: var(--md-sys-color-secondary-container);
  --bs-pagination-active-border-color: transparent;
  --bs-pagination-disabled-color: var(--md-disabled-content);
  --bs-pagination-disabled-bg: transparent;
  --bs-pagination-disabled-border-color: transparent;
  flex-wrap: wrap;  /* long page lists wrap instead of widening the page */
  gap: 4px;
}
.page-link { min-width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center; padding: 0 12px; border-radius: var(--bs-pagination-border-radius) !important; }
.page-link:focus-visible { outline: var(--md-focus-ring); outline-offset: var(--md-focus-offset); }
/* Sizes: our fixed 40px links would otherwise ignore Bootstrap's -sm / -lg */
.pagination-sm .page-link { min-width: 32px; height: 32px; padding: 0 8px; font-size: var(--md-sys-typescale-label-medium-size); }
.pagination-lg .page-link { min-width: 48px; height: 48px; padding: 0 16px; font-size: var(--md-sys-typescale-title-medium-size); }
.page-link > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: 20px; }
.page-item-ellipsis .page-link { pointer-events: none; }

/* ==========================================================================
   9b. Navigation bar & navigation rail (M3 Expressive; Compose NavigationBar /
       NavigationRail tokens)

   <nav class="nav-bar" aria-label="Main">
     <a class="nav-bar-item active" href="#" aria-current="page">
       <span class="nav-indicator"><span class="material-symbols-rounded">home</span></span>
       <span class="nav-label">Home</span>
     </a> …
   </nav>
   Variants: .nav-bar-tall (80px) · .nav-bar-horizontal (icon + label side by side)

   <nav class="nav-rail" aria-label="Main">
     <div class="nav-rail-header">
       <button class="btn btn-icon" data-m3-rail-toggle aria-label="Expand navigation"
               aria-expanded="false"><span class="material-symbols-rounded">menu</span></button>
       <button class="btn btn-fab btn-fab-tertiary">…</button>
     </div>
     <a class="nav-rail-item active" …>same inner markup as the bar</a> …
   </nav>
   Variants: .nav-rail-narrow (80px) · .nav-rail-expanded (220px, labels beside icons).
   js/m3-components.js wires [data-m3-rail-toggle]; otherwise toggle the class yourself.
   An item is active with .active or aria-current="page". Put a .badge or
   .badge-dot inside .nav-indicator for counts.
   ========================================================================== */

.nav-bar, .nav-rail {
  --md-nav-indicator: var(--md-sys-color-secondary-container);
  --md-nav-active-icon: var(--md-sys-color-on-secondary-container);
  --md-nav-active-label: var(--md-sys-color-secondary);
  --md-nav-inactive: var(--md-sys-color-on-surface-variant);
  --md-nav-state: var(--md-sys-color-on-secondary-container);
}

/* The 56×32 indicator around the icon. ::before = active pill (grows from
   the center on the fast spring), ::after = hover/focus/press state layer. */
.nav-indicator {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 56px;
  height: 32px;
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-nav-inactive);
  transition: color var(--md-motion-fast-effects);
}
.nav-indicator::before,
.nav-indicator::after,
.nav-bar-horizontal .nav-bar-item::before,
.nav-bar-horizontal .nav-bar-item::after,
.nav-rail-expanded .nav-rail-item::before,
.nav-rail-expanded .nav-rail-item::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
}
.nav-indicator::before,
.nav-bar-horizontal .nav-bar-item::before,
.nav-rail-expanded .nav-rail-item::before {
  background-color: var(--md-nav-indicator);
  opacity: 0;
  transform: scaleX(.32);
  transition: transform var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
.nav-indicator::after,
.nav-bar-horizontal .nav-bar-item::after,
.nav-rail-expanded .nav-rail-item::after {
  background-color: transparent;
  transition: background-color var(--md-motion-fast-effects);
}
.nav-indicator > :is(.material-symbols-rounded, .material-symbols-outlined) {
  font-size: 24px;
  transition: font-variation-settings var(--md-motion-fast-effects);
}
/* M3 badge specs: a count badge's bottom-leading corner sits 14dp below and
   12dp in from the icon's top-trailing corner; a dot's 6dp and 6dp. The icon
   is 24px, centered in the 32px-tall indicator (top 4px, right edge 50% + 12px). */
.nav-indicator > .badge { position: absolute; top: 2px; left: 50%; }
.nav-indicator > .badge-dot { position: absolute; top: 4px; left: calc(50% + 6px); }

.nav-label {
  font-family: var(--md-sys-typescale-label-medium-font);
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line-height);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  color: var(--md-nav-inactive);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  transition: color var(--md-motion-fast-effects);
}

.nav-bar-item, .nav-rail-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  color: var(--md-nav-inactive);
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: 0;
  -webkit-tap-highlight-color: transparent;
}
.nav-bar-item:focus-visible, .nav-rail-item:focus-visible { outline: none; }
.nav-bar-item:focus-visible .nav-indicator,
.nav-rail-item:focus-visible .nav-indicator { outline: var(--md-focus-ring); outline-offset: var(--md-focus-offset); }

/* State layers */
:is(.nav-bar-item, .nav-rail-item):hover .nav-indicator::after,
.nav-bar-horizontal .nav-bar-item:hover::after,
.nav-rail-expanded .nav-rail-item:hover::after {
  background-color: color-mix(in srgb, var(--md-nav-state) var(--md-sys-state-hover-state-layer-opacity), transparent);
}
:is(.nav-bar-item, .nav-rail-item):is(:focus-visible, :active) .nav-indicator::after,
.nav-bar-horizontal .nav-bar-item:is(:focus-visible, :active)::after,
.nav-rail-expanded .nav-rail-item:is(:focus-visible, :active)::after {
  background-color: color-mix(in srgb, var(--md-nav-state) var(--md-sys-state-pressed-state-layer-opacity), transparent);
}

/* Active */
:is(.nav-bar-item, .nav-rail-item):is(.active, [aria-current="page"]) .nav-indicator::before,
.nav-bar-horizontal .nav-bar-item:is(.active, [aria-current="page"])::before,
.nav-rail-expanded .nav-rail-item:is(.active, [aria-current="page"])::before {
  opacity: 1;
  transform: none;
}
:is(.nav-bar-item, .nav-rail-item):is(.active, [aria-current="page"]) .nav-indicator { color: var(--md-nav-active-icon); }
:is(.nav-bar-item, .nav-rail-item):is(.active, [aria-current="page"]) .nav-indicator > :is(.material-symbols-rounded, .material-symbols-outlined) {
  font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}
:is(.nav-bar-item, .nav-rail-item):is(.active, [aria-current="page"]) .nav-label { color: var(--md-nav-active-label); }

/* ---- Navigation bar: 64px (80px tall), surface-container ---- */
.nav-bar {
  display: flex;
  align-items: stretch;
  height: 64px;
  background-color: var(--md-sys-color-surface-container);
}
.nav-bar-tall { height: 80px; }
.nav-bar-item { flex: 1 1 0; padding-block: 6px; }
/* Horizontal items: the 40px pill wraps icon + label (16px sides) */
.nav-bar-horizontal { justify-content: space-around; align-items: center; }
.nav-bar-horizontal .nav-bar-item {
  flex: 0 1 auto;
  flex-direction: row;
  gap: 4px;
  isolation: isolate;
  height: 40px;
  padding: 0 16px;
  border-radius: var(--md-sys-shape-corner-full);
}
.nav-bar-horizontal .nav-indicator { width: auto; height: auto; }
.nav-bar-horizontal .nav-indicator::before,
.nav-bar-horizontal .nav-indicator::after { display: none; }

/* ---- Navigation rail: 96px collapsed (80 narrow), surface ---- */
/* Icons and header stay in a fixed column (centered at --md-rail-w / 2) in
   both states, so expanding/collapsing never shifts them sideways while the
   width animates; m3-components.js glides labels and rows to their new spots. */
.nav-rail {
  --md-rail-w: 96px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  flex: none;
  width: var(--md-rail-w);
  padding-top: 44px;
  padding-bottom: 16px;
  background-color: var(--md-sys-color-surface);
  overflow: hidden;
  transition: width var(--md-motion-default-spatial);
}
.nav-rail:has(> .nav-rail-header) { padding-top: 12px; }
.nav-rail-narrow { --md-rail-w: 80px; }
.nav-rail-header { display: flex; flex-direction: column; align-items: center; gap: 4px; width: var(--md-rail-w); margin-bottom: 32px; flex: none; }
.nav-rail-item { width: var(--md-rail-w); flex: none; padding-block: 6px; }

/* Expanded: 220px, items become full-width 56px pills with the label inside.
   Icon center stays at --md-rail-w / 2: 12px rail inset + (w/2 − 24) padding + 12px half-icon. */
.nav-rail-expanded { width: 220px; padding-inline: 12px; }
.nav-rail-expanded .nav-rail-header { margin-left: -12px; }
.nav-rail-expanded .nav-rail-item {
  align-self: stretch;
  width: auto;
  flex-direction: row;
  justify-content: flex-start;
  gap: 8px;
  isolation: isolate;
  height: 56px;
  padding: 0 16px 0 calc(var(--md-rail-w) / 2 - 24px);
  border-radius: var(--md-sys-shape-corner-full);
}
/* While toggling (m3-components.js adds .md-rail-animating), the active
   pill grows from the icon instead of popping in. */
.nav-rail-animating.nav-rail-expanded .nav-rail-item:is(.active, [aria-current="page"])::before { animation: md-rail-pill var(--md-motion-default-spatial) both; transform-origin: calc(var(--md-rail-w) / 2) 50%; }
.nav-rail-animating:not(.nav-rail-expanded) .nav-rail-item:is(.active, [aria-current="page"]) .nav-indicator::before { animation: md-rail-pill var(--md-motion-default-spatial) both; }
@keyframes md-rail-pill { from { transform: scaleX(.3); opacity: 0; } }
.nav-rail-expanded .nav-indicator { width: auto; height: auto; position: static; }
/* Expanded: badges move from the icon to the end of the row */
.nav-rail-expanded .nav-indicator > :is(.badge, .badge-dot) { top: 50%; left: auto; right: 16px; transform: translateY(-50%); }
.nav-rail-expanded .nav-indicator::before,
.nav-rail-expanded .nav-indicator::after { display: none; }
.nav-rail-expanded .nav-label {
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
}

/* ==========================================================================
   10. Menus, dialogs, sheets, overlays
   ========================================================================== */

.dropdown-menu {
  --bs-dropdown-min-width: 112px;
  --bs-dropdown-padding-y: 8px;
  --bs-dropdown-font-size: var(--md-sys-typescale-label-large-size);
  --bs-dropdown-color: var(--md-sys-color-on-surface);
  --bs-dropdown-bg: var(--md-sys-color-surface-container);
  --bs-dropdown-border-color: transparent;
  --bs-dropdown-border-width: 0;
  --bs-dropdown-border-radius: var(--md-comp-menu-shape);
  --bs-dropdown-inner-border-radius: var(--md-comp-menu-shape);
  --bs-dropdown-box-shadow: var(--md-sys-elevation-level2);
  --bs-dropdown-divider-bg: var(--md-sys-color-outline-variant);
  --bs-dropdown-link-color: var(--md-sys-color-on-surface);
  --bs-dropdown-link-hover-color: var(--md-sys-color-on-surface);
  --bs-dropdown-link-hover-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-dropdown-link-active-color: var(--md-sys-color-on-secondary-container);
  --bs-dropdown-link-active-bg: var(--md-sys-color-secondary-container);
  --bs-dropdown-link-disabled-color: var(--md-disabled-content);
  --bs-dropdown-item-padding-x: 12px;
  --bs-dropdown-item-padding-y: 14px;
  --bs-dropdown-header-color: var(--md-sys-color-on-surface-variant);
  box-shadow: var(--bs-dropdown-box-shadow);
  overflow: hidden;
}
.dropdown-item { line-height: var(--md-sys-typescale-label-large-line-height); letter-spacing: var(--md-sys-typescale-label-large-tracking); display: flex; align-items: center; gap: 12px; }

/* Menu open (Compose DropdownMenu): scale 0.8 → 1 on fast-spatial + fade on
   fast-effects, growing out of the anchor side. Entry is pure CSS
   (@starting-style); m3-components.js plays the reverse on close. */
.dropdown-menu.show {
  transition: scale var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
  transform-origin: top left;
}
@starting-style {
  .dropdown-menu.show { scale: .8; opacity: 0; }
}
.dropdown-menu[data-popper-placement="bottom-end"], .dropdown-menu-end.show:not([data-popper-placement]) { transform-origin: top right; }
.dropdown-menu[data-popper-placement="top-start"] { transform-origin: bottom left; }
.dropdown-menu[data-popper-placement="top-end"] { transform-origin: bottom right; }
.dropdown-menu[data-popper-placement^="right"] { transform-origin: top left; }
.dropdown-menu[data-popper-placement^="left"] { transform-origin: top right; }
.dropdown-item:focus-visible { outline: none; background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity), transparent); }

.modal {
  --bs-modal-padding: 24px;
  --bs-modal-margin: 24px;
  --bs-modal-color: var(--md-sys-color-on-surface-variant);
  --bs-modal-bg: var(--md-sys-color-surface-container-high);
  --bs-modal-border-color: transparent;
  --bs-modal-border-width: 0;
  --bs-modal-border-radius: var(--md-comp-dialog-shape);
  --bs-modal-inner-border-radius: var(--md-comp-dialog-shape);
  --bs-modal-box-shadow: var(--md-sys-elevation-level3);
  --bs-modal-header-padding: 24px 24px 16px;
  --bs-modal-header-border-width: 0;
  --bs-modal-footer-border-width: 0;
  --bs-modal-footer-gap: 8px;
  --bs-modal-title-line-height: var(--md-sys-typescale-headline-small-line-height);
}
.modal-content { box-shadow: var(--bs-modal-box-shadow); }
.modal-title { font-family: var(--md-sys-typescale-headline-small-font); font-size: var(--md-sys-typescale-headline-small-size); font-weight: var(--md-sys-typescale-headline-small-weight); color: var(--md-sys-color-on-surface); }
.modal-body { padding-top: 0; font-size: var(--md-sys-typescale-body-medium-size); line-height: var(--md-sys-typescale-body-medium-line-height); letter-spacing: var(--md-sys-typescale-body-medium-tracking); }
.modal-footer { padding: 0 24px 24px; }
.modal-backdrop { --bs-backdrop-bg: var(--md-sys-color-scrim); --bs-backdrop-opacity: .32; }

/* Compose AlertDialog: always centered, and sized to its content between
   280 and 560px (DialogMinWidth / DialogMaxWidth). .modal-sm/-lg/-xl and
   .modal-dialog-wide take their full width instead (forms, wide content). */
.modal { --bs-modal-width: 560px; }
/* Centering is zero-specificity (:where) so Bootstrap's full-screen classes
   still win; widths skip every .modal-fullscreen* variant, which take
   Bootstrap's own sizes. */
:where(.modal-dialog) {
  display: flex;
  align-items: center;
  min-height: calc(100% - var(--bs-modal-margin) * 2);
}
.modal-dialog:not([class*="modal-fullscreen"]) {
  width: fit-content;
  min-width: min(280px, calc(100% - var(--bs-modal-margin) * 2));
  /* below 576px Bootstrap uses fixed side margins; auto keeps a narrow
     dialog centered while max-width keeps the 24px gutters */
  max-width: min(var(--bs-modal-width), calc(100% - var(--bs-modal-margin) * 2));
  margin-inline: auto;
}
.modal-dialog:is(.modal-sm, .modal-lg, .modal-xl, .modal-dialog-wide):not([class*="modal-fullscreen"]) { width: calc(100% - var(--bs-modal-margin) * 2); }
@media (min-width: 576px) { .modal-dialog:is(.modal-sm, .modal-lg, .modal-xl, .modal-dialog-wide):not([class*="modal-fullscreen"]) { width: 100%; } }
.modal-dialog > .modal-content { width: 100%; }

/* Hero icon: secondary, 24px, centered with the headline below it */
.modal-header:has(> .modal-icon) { flex-direction: column; align-items: center; text-align: center; }
.modal-icon { margin-bottom: 16px; font-size: 24px; color: var(--md-sys-color-secondary); }

/* Scrolling content: dividers mark where the content scrolls under */
.modal-dialog-scrollable .modal-body {
  padding-top: 16px;
  padding-bottom: 16px;
  border-block: 1px solid var(--md-sys-color-outline-variant);
}
.modal-dialog-scrollable .modal-footer { padding-top: 24px; }

/* Full-screen dialog (M3 full-screen dialog): surface, no corners or shadow,
   and a 56px top bar: close icon, title-large headline, text-button action.
   Any header that starts with an icon button gets the bar layout. */
.modal-header:has(> .btn-icon:first-child) { gap: 12px; min-height: 56px; padding: 4px 12px 4px 4px; }
.modal-header:has(> .btn-icon:first-child) > .modal-title {
  flex: 1;
  min-width: 0;
  font-family: var(--md-sys-typescale-title-large-font);
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  font-weight: var(--md-sys-typescale-title-large-weight);
}
.modal-fullscreen .modal-content { --bs-modal-bg: var(--md-sys-color-surface); box-shadow: none; }
@media (max-width: 575.98px)  { .modal-fullscreen-sm-down .modal-content  { --bs-modal-bg: var(--md-sys-color-surface); box-shadow: none; } }
@media (max-width: 767.98px)  { .modal-fullscreen-md-down .modal-content  { --bs-modal-bg: var(--md-sys-color-surface); box-shadow: none; } }
@media (max-width: 991.98px)  { .modal-fullscreen-lg-down .modal-content  { --bs-modal-bg: var(--md-sys-color-surface); box-shadow: none; } }
@media (max-width: 1199.98px) { .modal-fullscreen-xl-down .modal-content  { --bs-modal-bg: var(--md-sys-color-surface); box-shadow: none; } }
@media (max-width: 1399.98px) { .modal-fullscreen-xxl-down .modal-content { --bs-modal-bg: var(--md-sys-color-surface); box-shadow: none; } }

.offcanvas, .offcanvas-lg, .offcanvas-md, .offcanvas-sm, .offcanvas-xl, .offcanvas-xxl {
  --bs-offcanvas-color: var(--md-sys-color-on-surface);
  --bs-offcanvas-bg: var(--md-sys-color-surface-container-low);
  --bs-offcanvas-border-color: var(--md-sys-color-outline-variant);
  --bs-offcanvas-box-shadow: var(--md-sys-elevation-level1);
  --bs-offcanvas-padding-x: 24px;
  --bs-offcanvas-padding-y: 16px;
}
.offcanvas-title { font-family: var(--md-sys-typescale-title-large-font); font-size: var(--md-sys-typescale-title-large-size); font-weight: var(--md-sys-typescale-title-large-weight); }

.btn-close,
[data-bs-theme] .btn-close {
  --bs-btn-close-bg: var(--md-icon-close);
  --bs-btn-close-opacity: 1;
  --bs-btn-close-hover-opacity: 1;
  --bs-btn-close-focus-shadow: none;
  --bs-btn-close-filter: none;
  filter: none;
  width: 24px;
  height: 24px;
  padding: 8px;
  box-sizing: content-box;
  border-radius: var(--md-sys-shape-corner-full);
  background-size: 24px;
}
.btn-close:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.btn-close:focus-visible { outline: var(--md-focus-ring); outline-offset: 0; }
.btn-close.btn-close-white { filter: invert(1) grayscale(100%) brightness(200%); }

.tooltip {
  --bs-tooltip-color: var(--md-sys-color-inverse-on-surface);
  --bs-tooltip-bg: var(--md-sys-color-inverse-surface);
  --bs-tooltip-border-radius: var(--md-sys-shape-corner-extra-small);
  --bs-tooltip-font-size: var(--md-sys-typescale-body-small-size);
  --bs-tooltip-padding-x: 8px;
  --bs-tooltip-padding-y: 4px;
  --bs-tooltip-opacity: 1;
  /* M3 tooltips have no caret by default (Compose caretShape = null) */
  --bs-tooltip-arrow-width: 0px;
  --bs-tooltip-arrow-height: 0px;
  --bs-tooltip-max-width: 200px;
}
.tooltip .tooltip-arrow, .popover .popover-arrow { display: none; }
/* Opt-in caret: data-bs-custom-class="tooltip-caret" on the trigger.
   Size is Compose TooltipDefaults.caretSize, 16 × 8. */
.tooltip.tooltip-caret { --bs-tooltip-arrow-width: 16px; --bs-tooltip-arrow-height: 8px; }
.tooltip.tooltip-caret .tooltip-arrow, .popover.tooltip-caret .popover-arrow { display: block; }
.tooltip-inner { min-width: 40px; min-height: 24px; }
/* Popover = M3 rich tooltip (RichTooltipTokens): surface-container, medium
   corners, level-2 shadow, title and text both on-surface-variant. The
   shadow is a drop-shadow filter so an opt-in caret casts it too. */
.popover {
  --bs-popover-bg: var(--md-sys-color-surface-container);
  --bs-popover-border-color: transparent;
  --bs-popover-border-width: 0px;
  --bs-popover-border-radius: var(--md-sys-shape-corner-medium);
  --bs-popover-inner-border-radius: var(--md-sys-shape-corner-medium);
  --bs-popover-box-shadow: none;
  --bs-popover-max-width: 320px;
  --bs-popover-font-size: var(--md-sys-typescale-body-medium-size);
  --bs-popover-header-bg: transparent;
  --bs-popover-header-color: var(--md-sys-color-on-surface-variant);
  --bs-popover-header-font-size: var(--md-sys-typescale-title-small-size);
  --bs-popover-body-color: var(--md-sys-color-on-surface-variant);
  --bs-popover-body-padding-x: 16px;
  --bs-popover-body-padding-y: 12px;
  --bs-popover-header-padding-x: 16px;
  --bs-popover-header-padding-y: 12px;
  --bs-popover-arrow-width: 16px;
  --bs-popover-arrow-height: 8px;
  min-width: 40px;
  filter: drop-shadow(0 1px 2px rgba(var(--md-sys-color-shadow-rgb), .3)) drop-shadow(0 2px 4px rgba(var(--md-sys-color-shadow-rgb), .15));
}
.popover-header { border-bottom: 0; padding-bottom: 0; font-family: var(--md-sys-typescale-title-small-font); font-weight: var(--md-sys-typescale-title-small-weight); line-height: var(--md-sys-typescale-title-small-line-height); }
.popover-body { line-height: var(--md-sys-typescale-body-medium-line-height); padding-bottom: 16px; }
/* Compose: 24dp from the title's baseline to the text's first baseline */
.popover-header + .popover-body { padding-top: 4px; }
/* Optional action row: <div class="popover-actions"><button class="btn btn-text">…</button></div> */
.popover-actions { display: flex; gap: 8px; margin: 12px -12px -8px; }
/* Show/hide (Compose TooltipBox): scale 0.8 → 1 on fast-spatial, fade on
   fast-effects, growing from the anchor side. m3-components.js positions
   tips with top/left so this scale doesn't also scale Popper's offset. */
.tooltip.fade, .popover.fade { scale: .8; transition: opacity var(--md-motion-fast-effects), scale var(--md-motion-fast-spatial); }
.tooltip.fade.show, .popover.fade.show { scale: 1; }
:is(.tooltip, .popover)[data-popper-placement^="top"] { transform-origin: 50% 100%; }
:is(.tooltip, .popover)[data-popper-placement^="bottom"] { transform-origin: 50% 0; }
:is(.tooltip, .popover)[data-popper-placement^="left"] { transform-origin: 100% 50%; }
:is(.tooltip, .popover)[data-popper-placement^="right"] { transform-origin: 0 50%; }

/* Toast = M3 snackbar */
.toast {
  --bs-toast-padding-x: 16px;
  --bs-toast-padding-y: 14px;
  --bs-toast-color: var(--md-sys-color-inverse-on-surface);
  --bs-toast-bg: var(--md-sys-color-inverse-surface);
  --bs-toast-border-width: 0;
  --bs-toast-border-color: transparent;
  --bs-toast-border-radius: var(--md-sys-shape-corner-extra-small);
  --bs-toast-box-shadow: var(--md-sys-elevation-level3);
  --bs-toast-header-color: var(--md-sys-color-inverse-on-surface);
  --bs-toast-header-bg: var(--md-sys-color-inverse-surface);
  --bs-toast-header-border-color: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 20%, transparent);
  --bs-toast-font-size: var(--md-sys-typescale-body-medium-size);
}
.toast .btn-close, [data-bs-theme] .toast .btn-close { --bs-btn-close-bg: var(--md-icon-close-inverse); }
.toast .btn-link, .toast .btn-text { --md-btn-content: var(--md-sys-color-inverse-primary); }

/* Snackbar (SnackbarTokens + Compose SnackbarHost). Built by
   M3Components.snackbar() in js/m3-components.js, which queues them one at
   a time; the outgoing one fades and shrinks while the next scales in from
   0.8 (fast-spatial) and fades in (fast-effects). 48px single line, 68px
   two lines, inverse-surface, extra-small corners, level 3. */
.snackbar-host {
  position: fixed;
  z-index: 1090;
  left: 50%;
  bottom: 12px;
  width: min(600px, 100% - 24px);
  translate: -50% 0;
  display: grid;
  justify-items: center;
  pointer-events: none;
}
/* From 600px up, snackbars sit at the bottom leading corner (left in LTR),
   sized to their message, as in Google's web apps; centered on phones.
   align: 'center' (.snackbar-host-center) keeps them centered everywhere. */
@media (min-width: 600px) {
  .snackbar-host:not(.snackbar-host-center) {
    left: auto;
    inset-inline-start: 24px;
    bottom: 24px;
    width: min(672px, 100% - 48px);
    translate: none;
    justify-items: start;
  }
  .snackbar-host:not(.snackbar-host-center) > .snackbar {
    width: fit-content;
    min-width: min(344px, 100%);
    max-width: 100%;
    transform-origin: 0 100%;
  }
  [dir="rtl"] .snackbar-host:not(.snackbar-host-center) > .snackbar { transform-origin: 100% 100%; }
}
.snackbar {
  grid-area: 1 / 1;
  align-self: end;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 4px;
  width: 100%;
  min-height: 48px;
  padding: 0 4px 0 16px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background-color: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  box-shadow: var(--md-sys-elevation-level3);
  pointer-events: auto;
  transition: scale var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
@starting-style { .snackbar { scale: .8; opacity: 0; } }
.snackbar.md-leaving { scale: .8; opacity: 0; pointer-events: none; }
.snackbar-text {
  flex: 1 1 0;
  min-width: 0;
  padding: 14px 8px 14px 0;
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
  font-weight: var(--md-sys-typescale-body-medium-weight);
  letter-spacing: var(--md-sys-typescale-body-medium-tracking);
}
.snackbar:has(.snackbar-text:only-child) { padding-right: 16px; }
.snackbar-actions { display: flex; align-items: center; margin-left: auto; }
.snackbar .btn-text { --md-btn-content: var(--md-sys-color-inverse-primary); }
.snackbar .btn-icon { --md-btn-content: var(--md-sys-color-inverse-on-surface); }
/* Long action label: the action drops to its own line, right-aligned */
.snackbar-stacked { padding-bottom: 4px; }
.snackbar-stacked > .snackbar-text { flex-basis: 100%; padding-bottom: 6px; }

/* Transfer panel: one Bootstrap toast listing uploads/downloads, Drive-style.
   Not an M3 component (M3 snackbars never stack). Unlike a snackbar it is a
   lasting, multi-row surface, so it follows the theme like a dialog or menu
   (surface-container-high, level 3, large corners), as Google Drive's upload
   panel does. Built by M3Components.transfer() in m3-components.js:
   the panel scales in like a snackbar, each new row springs open on
   fast-spatial, and each row shows a circular progress indicator that turns
   into a check (or an error) when it finishes. */
.toast-transfers-host { z-index: 1090; }
.toast.toast-transfers {
  --bs-toast-bg: var(--md-sys-color-surface-container-high);
  --bs-toast-color: var(--md-sys-color-on-surface);
  --bs-toast-border-radius: var(--md-sys-shape-corner-large);
  --md-scrollbar-thumb: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 40%, transparent);
  --md-scrollbar-thumb-hover: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 65%, transparent);
  --md-scrollbar-thumb-active: var(--md-sys-color-on-surface-variant);
  width: 360px;
  max-width: calc(100vw - 24px);
  overflow: hidden;
  transform-origin: 100% 100%;
  transition: scale var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
@starting-style { .toast.toast-transfers.show { scale: .8; opacity: 0; } }
.toast.toast-transfers.md-leaving { scale: .8; opacity: 0; pointer-events: none; }
.toast-transfers-header {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 56px;
  padding: 4px 4px 4px 16px;
}
.toast-transfers-title {
  flex: 1;
  min-width: 0;
  margin: 0;
  color: inherit;
  font-family: var(--md-sys-typescale-title-small-font);
  font-size: var(--md-sys-typescale-title-small-size);
  line-height: var(--md-sys-typescale-title-small-line-height);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
.toast-transfers .btn-icon { --md-btn-content: var(--md-sys-color-on-surface-variant); }
.toast-transfers-collapse > .material-symbols-rounded { transition: rotate var(--md-motion-fast-spatial); }
.toast-transfers.md-collapsed .toast-transfers-collapse > .material-symbols-rounded { rotate: 180deg; }
.toast-transfers-body { overflow: hidden; }
.toast-transfers-list { max-height: 264px; margin: 0; padding: 0 0 8px; overflow-y: auto; list-style: none; }
.transfer-row { overflow: hidden; }
.transfer-row-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 0 12px 0 16px;
}
.transfer-row-inner > .material-symbols-rounded { flex: none; font-size: 20px; color: var(--md-sys-color-on-surface-variant); }
.transfer-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
}
.transfer-status { position: relative; flex: none; display: grid; place-items: center; width: 32px; height: 32px; }
.transfer-status > * { grid-area: 1 / 1; transition: opacity var(--md-motion-fast-effects), scale var(--md-motion-fast-spatial); }
.transfer-status > .material-symbols-rounded { font-size: 24px; opacity: 0; scale: .4; font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }
.transfer-done { color: var(--md-sys-color-primary); }
.transfer-failed { color: var(--md-sys-color-error); }
.transfer-row.is-done .transfer-status > .progress-circular,
.transfer-row.is-failed .transfer-status > .progress-circular { opacity: 0; scale: .6; }
.transfer-row.is-done .transfer-done,
.transfer-row.is-failed .transfer-failed { opacity: 1; scale: 1; }

/* ==========================================================================
   11. Content components
   ========================================================================== */

.alert {
  --bs-alert-padding-x: 16px;
  --bs-alert-padding-y: 14px;
  --bs-alert-border-radius: var(--md-sys-shape-corner-medium);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
  letter-spacing: var(--md-sys-typescale-body-medium-tracking);
}
.alert-heading { font-family: var(--md-sys-typescale-title-medium-font); font-size: var(--md-sys-typescale-title-medium-size); font-weight: var(--md-sys-typescale-title-medium-weight); color: inherit; }
.alert-dismissible .btn-close { padding: 12px; }

/* Small M3 badge: a 6px error dot with no label */
.badge-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  min-height: 6px;
  padding: 0;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-error);
}
/* Bootstrap word badges ("New", "Active"): label-medium in a 20px pill so
   they stay readable. M3's own badge (counts on icons) is smaller, see
   .badge-count below. */
.badge {
  --bs-badge-padding-x: 8px;
  --bs-badge-padding-y: 2px;
  --bs-badge-font-size: var(--md-sys-typescale-label-medium-size);
  --bs-badge-font-weight: var(--md-sys-typescale-label-medium-weight);
  --bs-badge-color: var(--md-sys-color-on-error);
  --bs-badge-border-radius: var(--md-sys-shape-corner-full);
  min-height: 20px;
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  line-height: var(--md-sys-typescale-label-medium-line-height);
}
/* M3 large badge (BadgeTokens): 16px tall, label-small, error. Used
   automatically inside nav indicators; add .badge-count elsewhere. */
.badge-count,
.nav-indicator > .badge {
  --bs-badge-padding-x: 4px;
  --bs-badge-padding-y: 2px;
  --bs-badge-font-size: var(--md-sys-typescale-label-small-size);
  --bs-badge-font-weight: var(--md-sys-typescale-label-small-weight);
  min-width: 16px;
  min-height: 16px;
  line-height: 12px;
  letter-spacing: var(--md-sys-typescale-label-small-tracking);
  /* BadgeTokens.Color (Bootstrap's .text-bg-* still override) */
  background-color: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
}

/* Badge on an icon (Compose BadgedBox). Wrap the icon and its badge:
   <span class="badge-anchor">
     <span class="material-symbols-rounded">mail</span>
     <span class="badge badge-count">3</span>        (or <span class="badge-dot"></span>)
   </span>
   A count badge starts 12px in from the icon's end edge and overlaps it by
   14px vertically; a dot sits 6px in, overlapping 6px. Works inside icon
   buttons, list items and anywhere else; nav bar/rail items do this
   themselves. */
.badge-anchor { position: relative; display: inline-flex; vertical-align: middle; }
.badge-anchor > .badge { position: absolute; top: -2px; inset-inline-start: calc(100% - 12px); }
.badge-anchor > .badge-dot { position: absolute; top: 0; inset-inline-start: calc(100% - 6px); }

.list-group {
  --bs-list-group-color: var(--md-sys-color-on-surface);
  --bs-list-group-bg: var(--md-sys-color-surface);
  --bs-list-group-border-color: var(--md-sys-color-outline-variant);
  --bs-list-group-border-radius: var(--md-sys-shape-corner-medium);
  /* M3 list items: 56px one-line (16 + 24 + 16), 16px sides */
  --bs-list-group-item-padding-x: 16px;
  --bs-list-group-item-padding-y: 16px;
  --bs-list-group-action-color: var(--md-sys-color-on-surface);
  --bs-list-group-action-hover-color: var(--md-sys-color-on-surface);
  --bs-list-group-action-hover-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface));
  --bs-list-group-action-active-color: var(--md-sys-color-on-surface);
  --bs-list-group-action-active-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity), var(--md-sys-color-surface));
  --bs-list-group-disabled-color: var(--md-disabled-content);
  --bs-list-group-disabled-bg: var(--md-sys-color-surface);
  --bs-list-group-active-color: var(--md-sys-color-on-secondary-container);
  --bs-list-group-active-bg: var(--md-sys-color-secondary-container);
  --bs-list-group-active-border-color: var(--md-sys-color-secondary-container);
}
.list-group-item { min-height: 56px; font-size: var(--md-sys-typescale-body-large-size); line-height: var(--md-sys-typescale-body-large-line-height); }
.list-group-item small, .list-group-item .small { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-medium-size); line-height: var(--md-sys-typescale-body-medium-line-height); }
.list-group-item.active small, .list-group-item.active .small { color: inherit; }
/* Two- and three-line items: 72px / 88px (top/bottom 8px / 12px) */
.list-group-item-two-line { min-height: 72px; padding-block: 12px; }
.list-group-item-three-line { min-height: 88px; padding-block: 12px; }
.list-group-item-primary   { --bs-list-group-color: var(--md-sys-color-on-primary-container);   --bs-list-group-bg: var(--md-sys-color-primary-container); }
.list-group-item-secondary { --bs-list-group-color: var(--md-sys-color-on-secondary-container); --bs-list-group-bg: var(--md-sys-color-secondary-container); }
.list-group-item-success   { --bs-list-group-color: var(--md-sys-color-on-success-container);   --bs-list-group-bg: var(--md-sys-color-success-container); }
.list-group-item-info      { --bs-list-group-color: var(--md-sys-color-on-info-container);      --bs-list-group-bg: var(--md-sys-color-info-container); }
.list-group-item-warning   { --bs-list-group-color: var(--md-sys-color-on-warning-container);   --bs-list-group-bg: var(--md-sys-color-warning-container); }
.list-group-item-danger    { --bs-list-group-color: var(--md-sys-color-on-error-container);     --bs-list-group-bg: var(--md-sys-color-error-container); }

.accordion {
  --bs-accordion-color: var(--md-sys-color-on-surface);
  --bs-accordion-bg: var(--md-sys-color-surface);
  --bs-accordion-border-color: var(--md-sys-color-outline-variant);
  --bs-accordion-border-radius: var(--md-sys-shape-corner-medium);
  --bs-accordion-inner-border-radius: max(0px, calc(var(--md-sys-shape-corner-medium) - 1px));
  --bs-accordion-btn-padding-x: 16px;
  --bs-accordion-btn-padding-y: 16px;
  --bs-accordion-btn-color: var(--md-sys-color-on-surface);
  --bs-accordion-btn-bg: var(--md-sys-color-surface);
  --bs-accordion-btn-focus-box-shadow: inset 0 0 0 3px var(--md-sys-color-secondary);
  --bs-accordion-body-padding-x: 16px;
  --bs-accordion-body-padding-y: 16px;
  --bs-accordion-active-color: var(--md-sys-color-on-surface);
  --bs-accordion-active-bg: var(--md-sys-color-surface-container);
}
.accordion-button { font-family: var(--md-sys-typescale-title-medium-font); font-size: var(--md-sys-typescale-title-medium-size); font-weight: var(--md-sys-typescale-title-medium-weight); }
.accordion-button:not(.collapsed) { box-shadow: none; }
.accordion-button:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--bs-accordion-btn-bg)); }
.accordion-button:not(.collapsed):hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--bs-accordion-active-bg)); }
.accordion-button::after,
[data-bs-theme] .accordion-button::after {
  --bs-accordion-btn-icon: var(--md-icon-expand);
  --bs-accordion-btn-active-icon: var(--md-icon-expand-active);
  --bs-accordion-btn-icon-width: 24px;
}
/* M3 has no accordion, so this borrows the motion scheme: the panel opens and
   closes on default-effects (critically damped, so it never grows past its
   full height and nothing below it moves) and the chevron turns on the
   bouncy fast-spatial. Bootstrap reads the transition duration to know when
   to finish, so the spring durations work with its collapse plugin. */
.accordion { --bs-accordion-btn-icon-transition: transform var(--md-motion-fast-spatial); }
.accordion-collapse.collapsing { transition: height var(--md-motion-default-effects); }
.accordion-body { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-medium-size); line-height: var(--md-sys-typescale-body-medium-line-height); }

.progress, .progress-stacked {
  --bs-progress-height: 4px;
  --bs-progress-bg: var(--md-sys-color-secondary-container);
  --bs-progress-border-radius: var(--md-sys-shape-corner-full);
  --bs-progress-bar-color: var(--md-sys-color-on-primary);
  --bs-progress-bar-bg: var(--md-sys-color-primary);
  --bs-progress-box-shadow: none;
  --bs-progress-font-size: var(--md-sys-typescale-label-small-size);
}
.progress-bar { border-radius: var(--md-sys-shape-corner-full); }
.progress-bar { transition: width var(--md-motion-default-effects); }

/* M3 flat linear progress (LinearProgressIndicatorTokens): the track starts
   4px after the indicator and ends in a stop dot. The bar draws its own track
   (::after, clipped by the container); the container draws the dot.
   Stacked progress bars keep Bootstrap's continuous track. */
.progress:not(.progress-stacked .progress) {
  position: relative;
  background-color: transparent;
}
.progress:not(.progress-stacked .progress) > .progress-bar:last-child {
  position: relative;
  overflow: visible;
}
.progress:not(.progress-stacked .progress) > .progress-bar:last-child::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(100% + 4px);
  width: 100vw;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--bs-progress-bg);
}
.progress:not(.progress-stacked .progress)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: min(4px, var(--bs-progress-height));
  height: min(4px, var(--bs-progress-height));
  translate: 0 -50%;
  border-radius: 50%;
  background-color: var(--bs-progress-bar-bg);
}

/* --------------------------------------------------------------------------
   Wavy progress (M3 Expressive)
   Geometry and timing follow Jetpack Compose's WavyProgressIndicator
   (androidx material3), the reference implementation:
     linear   10px tall, 4px stroke, 3px amplitude, 40px wavelength
              (20px indeterminate), 4px track gap, 4px stop indicator
     circular 48px, 4px stroke, 1.6px amplitude, ~15px wavelength, 4px gap
   The wave travels one wavelength per second and flattens when progress
   is ≤10% or ≥95%, as in Compose.

     <div class="progress-wavy" role="progressbar" style="--md-progress-value: 60%"
          aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>
     <div class="progress-circular" role="progressbar" style="--md-progress-value: 60%" …></div>
   Add .progress-indeterminate for the looping versions.
   -------------------------------------------------------------------------- */

@property --md-progress-value { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
@property --md-ind-h1 { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
@property --md-ind-t1 { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
@property --md-ind-h2 { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
@property --md-ind-t2 { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
@property --md-wave-rot { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@property --md-circ-spin { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
@property --md-circ-step { syntax: '<angle>'; inherits: true; initial-value: 0deg; }

:root {
  --md-wave-mask-40: url("data:image/svg+xml,%3Csvg xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27 width%3D%271600%27 height%3D%2710%27 viewBox%3D%270 0 1600 10%27%3E%3Cpath d%3D%27M-40 5Q-30 11 -20 5Q-10 -1 0 5Q10 11 20 5Q30 -1 40 5Q50 11 60 5Q70 -1 80 5Q90 11 100 5Q110 -1 120 5Q130 11 140 5Q150 -1 160 5Q170 11 180 5Q190 -1 200 5Q210 11 220 5Q230 -1 240 5Q250 11 260 5Q270 -1 280 5Q290 11 300 5Q310 -1 320 5Q330 11 340 5Q350 -1 360 5Q370 11 380 5Q390 -1 400 5Q410 11 420 5Q430 -1 440 5Q450 11 460 5Q470 -1 480 5Q490 11 500 5Q510 -1 520 5Q530 11 540 5Q550 -1 560 5Q570 11 580 5Q590 -1 600 5Q610 11 620 5Q630 -1 640 5Q650 11 660 5Q670 -1 680 5Q690 11 700 5Q710 -1 720 5Q730 11 740 5Q750 -1 760 5Q770 11 780 5Q790 -1 800 5Q810 11 820 5Q830 -1 840 5Q850 11 860 5Q870 -1 880 5Q890 11 900 5Q910 -1 920 5Q930 11 940 5Q950 -1 960 5Q970 11 980 5Q990 -1 1000 5Q1010 11 1020 5Q1030 -1 1040 5Q1050 11 1060 5Q1070 -1 1080 5Q1090 11 1100 5Q1110 -1 1120 5Q1130 11 1140 5Q1150 -1 1160 5Q1170 11 1180 5Q1190 -1 1200 5Q1210 11 1220 5Q1230 -1 1240 5Q1250 11 1260 5Q1270 -1 1280 5Q1290 11 1300 5Q1310 -1 1320 5Q1330 11 1340 5Q1350 -1 1360 5Q1370 11 1380 5Q1390 -1 1400 5Q1410 11 1420 5Q1430 -1 1440 5Q1450 11 1460 5Q1470 -1 1480 5Q1490 11 1500 5Q1510 -1 1520 5Q1530 11 1540 5Q1550 -1 1560 5Q1570 11 1580 5Q1590 -1 1600 5Q1610 11 1620 5Q1630 -1 1640 5%27 fill%3D%27none%27 stroke%3D%27%23000%27 stroke-width%3D%274%27%2F%3E%3C%2Fsvg%3E");
  --md-wave-mask-20: url("data:image/svg+xml,%3Csvg xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27 width%3D%271600%27 height%3D%2710%27 viewBox%3D%270 0 1600 10%27%3E%3Cpath d%3D%27M-20 5Q-15 11 -10 5Q-5 -1 0 5Q5 11 10 5Q15 -1 20 5Q25 11 30 5Q35 -1 40 5Q45 11 50 5Q55 -1 60 5Q65 11 70 5Q75 -1 80 5Q85 11 90 5Q95 -1 100 5Q105 11 110 5Q115 -1 120 5Q125 11 130 5Q135 -1 140 5Q145 11 150 5Q155 -1 160 5Q165 11 170 5Q175 -1 180 5Q185 11 190 5Q195 -1 200 5Q205 11 210 5Q215 -1 220 5Q225 11 230 5Q235 -1 240 5Q245 11 250 5Q255 -1 260 5Q265 11 270 5Q275 -1 280 5Q285 11 290 5Q295 -1 300 5Q305 11 310 5Q315 -1 320 5Q325 11 330 5Q335 -1 340 5Q345 11 350 5Q355 -1 360 5Q365 11 370 5Q375 -1 380 5Q385 11 390 5Q395 -1 400 5Q405 11 410 5Q415 -1 420 5Q425 11 430 5Q435 -1 440 5Q445 11 450 5Q455 -1 460 5Q465 11 470 5Q475 -1 480 5Q485 11 490 5Q495 -1 500 5Q505 11 510 5Q515 -1 520 5Q525 11 530 5Q535 -1 540 5Q545 11 550 5Q555 -1 560 5Q565 11 570 5Q575 -1 580 5Q585 11 590 5Q595 -1 600 5Q605 11 610 5Q615 -1 620 5Q625 11 630 5Q635 -1 640 5Q645 11 650 5Q655 -1 660 5Q665 11 670 5Q675 -1 680 5Q685 11 690 5Q695 -1 700 5Q705 11 710 5Q715 -1 720 5Q725 11 730 5Q735 -1 740 5Q745 11 750 5Q755 -1 760 5Q765 11 770 5Q775 -1 780 5Q785 11 790 5Q795 -1 800 5Q805 11 810 5Q815 -1 820 5Q825 11 830 5Q835 -1 840 5Q845 11 850 5Q855 -1 860 5Q865 11 870 5Q875 -1 880 5Q885 11 890 5Q895 -1 900 5Q905 11 910 5Q915 -1 920 5Q925 11 930 5Q935 -1 940 5Q945 11 950 5Q955 -1 960 5Q965 11 970 5Q975 -1 980 5Q985 11 990 5Q995 -1 1000 5Q1005 11 1010 5Q1015 -1 1020 5Q1025 11 1030 5Q1035 -1 1040 5Q1045 11 1050 5Q1055 -1 1060 5Q1065 11 1070 5Q1075 -1 1080 5Q1085 11 1090 5Q1095 -1 1100 5Q1105 11 1110 5Q1115 -1 1120 5Q1125 11 1130 5Q1135 -1 1140 5Q1145 11 1150 5Q1155 -1 1160 5Q1165 11 1170 5Q1175 -1 1180 5Q1185 11 1190 5Q1195 -1 1200 5Q1205 11 1210 5Q1215 -1 1220 5Q1225 11 1230 5Q1235 -1 1240 5Q1245 11 1250 5Q1255 -1 1260 5Q1265 11 1270 5Q1275 -1 1280 5Q1285 11 1290 5Q1295 -1 1300 5Q1305 11 1310 5Q1315 -1 1320 5Q1325 11 1330 5Q1335 -1 1340 5Q1345 11 1350 5Q1355 -1 1360 5Q1365 11 1370 5Q1375 -1 1380 5Q1385 11 1390 5Q1395 -1 1400 5Q1405 11 1410 5Q1415 -1 1420 5Q1425 11 1430 5Q1435 -1 1440 5Q1445 11 1450 5Q1455 -1 1460 5Q1465 11 1470 5Q1475 -1 1480 5Q1485 11 1490 5Q1495 -1 1500 5Q1505 11 1510 5Q1515 -1 1520 5Q1525 11 1530 5Q1535 -1 1540 5Q1545 11 1550 5Q1555 -1 1560 5Q1565 11 1570 5Q1575 -1 1580 5Q1585 11 1590 5Q1595 -1 1600 5Q1605 11 1610 5Q1615 -1 1620 5%27 fill%3D%27none%27 stroke%3D%27%23000%27 stroke-width%3D%274%27%2F%3E%3C%2Fsvg%3E");
  --md-wave-ring-32: url("data:image/svg+xml,%3Csvg xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27 viewBox%3D%270 0 32 32%27%3E%3Cpath d%3D%27M16.00 2.00L16.37 2.02L16.73 2.10L17.08 2.22L17.43 2.38L17.77 2.58L18.09 2.82L18.39 3.09L18.68 3.39L18.95 3.70L19.21 4.02L19.45 4.35L19.68 4.68L19.90 5.00L20.11 5.30L20.31 5.59L20.52 5.85L20.72 6.09L20.94 6.31L21.16 6.49L21.40 6.65L21.65 6.77L21.92 6.88L22.22 6.96L22.53 7.02L22.86 7.06L23.21 7.09L23.58 7.12L23.97 7.15L24.36 7.19L24.77 7.23L25.18 7.29L25.58 7.37L25.98 7.48L26.37 7.60L26.74 7.76L27.08 7.95L27.39 8.17L27.68 8.42L27.92 8.70L28.12 9.00L28.29 9.33L28.40 9.68L28.48 10.05L28.51 10.43L28.50 10.82L28.45 11.22L28.37 11.62L28.26 12.02L28.13 12.41L27.98 12.79L27.81 13.16L27.65 13.52L27.48 13.87L27.32 14.21L27.17 14.53L27.04 14.84L26.94 15.14L26.86 15.43L26.82 15.72L26.80 16.00L26.82 16.28L26.86 16.57L26.94 16.86L27.04 17.16L27.17 17.47L27.32 17.79L27.48 18.13L27.65 18.48L27.81 18.84L27.98 19.21L28.13 19.59L28.26 19.98L28.37 20.38L28.45 20.78L28.50 21.18L28.51 21.57L28.48 21.95L28.40 22.32L28.29 22.67L28.12 23.00L27.92 23.30L27.68 23.58L27.39 23.83L27.08 24.05L26.74 24.24L26.37 24.40L25.98 24.52L25.58 24.63L25.18 24.71L24.77 24.77L24.36 24.81L23.97 24.85L23.58 24.88L23.21 24.91L22.86 24.94L22.53 24.98L22.22 25.04L21.92 25.12L21.65 25.23L21.40 25.35L21.16 25.51L20.94 25.69L20.72 25.91L20.52 26.15L20.31 26.41L20.11 26.70L19.90 27.00L19.68 27.32L19.45 27.65L19.21 27.98L18.95 28.30L18.68 28.61L18.39 28.91L18.09 29.18L17.77 29.42L17.43 29.62L17.08 29.78L16.73 29.90L16.37 29.98L16.00 30.00L15.63 29.98L15.27 29.90L14.92 29.78L14.57 29.62L14.23 29.42L13.91 29.18L13.61 28.91L13.32 28.61L13.05 28.30L12.79 27.98L12.55 27.65L12.32 27.32L12.10 27.00L11.89 26.70L11.69 26.41L11.48 26.15L11.28 25.91L11.06 25.69L10.84 25.51L10.60 25.35L10.35 25.23L10.08 25.12L9.78 25.04L9.47 24.98L9.14 24.94L8.79 24.91L8.42 24.88L8.03 24.85L7.64 24.81L7.23 24.77L6.82 24.71L6.42 24.63L6.02 24.52L5.63 24.40L5.26 24.24L4.92 24.05L4.61 23.83L4.32 23.58L4.08 23.30L3.88 23.00L3.71 22.67L3.60 22.32L3.52 21.95L3.49 21.57L3.50 21.18L3.55 20.78L3.63 20.38L3.74 19.98L3.87 19.59L4.02 19.21L4.19 18.84L4.35 18.48L4.52 18.13L4.68 17.79L4.83 17.47L4.96 17.16L5.06 16.86L5.14 16.57L5.18 16.28L5.20 16.00L5.18 15.72L5.14 15.43L5.06 15.14L4.96 14.84L4.83 14.53L4.68 14.21L4.52 13.87L4.35 13.52L4.19 13.16L4.02 12.79L3.87 12.41L3.74 12.02L3.63 11.62L3.55 11.22L3.50 10.82L3.49 10.43L3.52 10.05L3.60 9.68L3.71 9.33L3.88 9.00L4.08 8.70L4.32 8.42L4.61 8.17L4.92 7.95L5.26 7.76L5.63 7.60L6.02 7.48L6.42 7.37L6.82 7.29L7.23 7.23L7.64 7.19L8.03 7.15L8.42 7.12L8.79 7.09L9.14 7.06L9.47 7.02L9.78 6.96L10.08 6.88L10.35 6.77L10.60 6.65L10.84 6.49L11.06 6.31L11.28 6.09L11.48 5.85L11.69 5.59L11.89 5.30L12.10 5.00L12.32 4.68L12.55 4.35L12.79 4.02L13.05 3.70L13.32 3.39L13.61 3.09L13.91 2.82L14.23 2.58L14.57 2.38L14.92 2.22L15.27 2.10L15.63 2.02Z%27 fill%3D%27none%27 stroke%3D%27%23000%27 stroke-width%3D%274%27 stroke-linejoin%3D%27round%27%2F%3E%3C%2Fsvg%3E");
  --md-wave-ring-48: url("data:image/svg+xml,%3Csvg xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27 viewBox%3D%270 0 48 48%27%3E%3Cpath d%3D%27M24.00 2.00L24.57 2.05L25.14 2.20L25.70 2.45L26.23 2.78L26.74 3.17L27.23 3.60L27.69 4.07L28.14 4.53L28.57 4.98L28.99 5.39L29.41 5.75L29.83 6.05L30.28 6.27L30.74 6.43L31.24 6.52L31.77 6.55L32.34 6.53L32.93 6.47L33.56 6.40L34.20 6.33L34.85 6.29L35.51 6.28L36.14 6.33L36.75 6.45L37.32 6.64L37.83 6.92L38.28 7.27L38.67 7.71L38.98 8.21L39.22 8.78L39.40 9.38L39.53 10.02L39.61 10.67L39.66 11.32L39.70 11.95L39.74 12.56L39.81 13.13L39.91 13.67L40.07 14.15L40.28 14.60L40.56 15.01L40.91 15.39L41.31 15.74L41.78 16.09L42.28 16.43L42.81 16.78L43.35 17.15L43.87 17.54L44.36 17.97L44.80 18.43L45.16 18.92L45.44 19.44L45.63 19.99L45.71 20.56L45.69 21.14L45.58 21.73L45.37 22.32L45.10 22.89L44.77 23.46L44.40 24.00L44.02 24.52L43.65 25.03L43.30 25.52L43.00 26.00L42.76 26.47L42.59 26.94L42.49 27.43L42.47 27.93L42.51 28.44L42.61 28.99L42.76 29.56L42.93 30.15L43.11 30.77L43.28 31.40L43.41 32.04L43.50 32.68L43.51 33.31L43.45 33.91L43.30 34.48L43.05 35.00L42.72 35.47L42.30 35.89L41.81 36.24L41.26 36.54L40.67 36.79L40.05 37.00L39.42 37.17L38.79 37.32L38.19 37.47L37.62 37.62L37.10 37.81L36.63 38.03L36.21 38.30L35.84 38.63L35.52 39.01L35.23 39.46L34.97 39.96L34.72 40.50L34.46 41.08L34.20 41.67L33.91 42.26L33.59 42.82L33.23 43.35L32.82 43.82L32.37 44.21L31.88 44.52L31.34 44.73L30.77 44.85L30.18 44.87L29.57 44.80L28.96 44.65L28.34 44.44L27.74 44.18L27.15 43.90L26.58 43.62L26.03 43.35L25.51 43.12L24.99 42.95L24.49 42.84L24.00 42.80L23.51 42.84L23.01 42.95L22.49 43.12L21.97 43.35L21.42 43.62L20.85 43.90L20.26 44.18L19.66 44.44L19.04 44.65L18.43 44.80L17.82 44.87L17.23 44.85L16.66 44.73L16.12 44.52L15.63 44.21L15.18 43.82L14.77 43.35L14.41 42.82L14.09 42.26L13.80 41.67L13.54 41.08L13.28 40.50L13.03 39.96L12.77 39.46L12.48 39.01L12.16 38.63L11.79 38.30L11.37 38.03L10.90 37.81L10.38 37.62L9.81 37.47L9.21 37.32L8.58 37.17L7.95 37.00L7.33 36.79L6.74 36.54L6.19 36.24L5.70 35.89L5.28 35.47L4.95 35.00L4.70 34.48L4.55 33.91L4.49 33.31L4.50 32.68L4.59 32.04L4.72 31.40L4.89 30.77L5.07 30.15L5.24 29.56L5.39 28.99L5.49 28.44L5.53 27.93L5.51 27.43L5.41 26.94L5.24 26.47L5.00 26.00L4.70 25.52L4.35 25.03L3.98 24.52L3.60 24.00L3.23 23.46L2.90 22.89L2.63 22.32L2.42 21.73L2.31 21.14L2.29 20.56L2.37 19.99L2.56 19.44L2.84 18.92L3.20 18.43L3.64 17.97L4.13 17.54L4.65 17.15L5.19 16.78L5.72 16.43L6.22 16.09L6.69 15.74L7.09 15.39L7.44 15.01L7.72 14.60L7.93 14.15L8.09 13.67L8.19 13.13L8.26 12.56L8.30 11.95L8.34 11.32L8.39 10.67L8.47 10.02L8.60 9.38L8.78 8.78L9.02 8.21L9.33 7.71L9.72 7.27L10.17 6.92L10.68 6.64L11.25 6.45L11.86 6.33L12.49 6.28L13.15 6.29L13.80 6.33L14.44 6.40L15.07 6.47L15.66 6.53L16.23 6.55L16.76 6.52L17.26 6.43L17.72 6.27L18.17 6.05L18.59 5.75L19.01 5.39L19.43 4.98L19.86 4.53L20.31 4.07L20.77 3.60L21.26 3.17L21.77 2.78L22.30 2.45L22.86 2.20L23.43 2.05Z%27 fill%3D%27none%27 stroke%3D%27%23000%27 stroke-width%3D%274%27 stroke-linejoin%3D%27round%27%2F%3E%3C%2Fsvg%3E");
  --md-wave-ring-72: url("data:image/svg+xml,%3Csvg xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27 viewBox%3D%270 0 72 72%27%3E%3Cpath d%3D%27M36.00 2.00L36.63 2.06L37.26 2.24L37.88 2.52L38.48 2.89L39.06 3.33L39.63 3.80L40.17 4.29L40.71 4.75L41.24 5.17L41.77 5.53L42.30 5.80L42.85 5.97L43.43 6.05L44.03 6.04L44.66 5.95L45.31 5.80L46.00 5.62L46.70 5.42L47.42 5.24L48.13 5.09L48.83 5.02L49.51 5.03L50.15 5.15L50.75 5.37L51.30 5.70L51.79 6.13L52.22 6.65L52.60 7.25L52.94 7.89L53.24 8.57L53.52 9.24L53.80 9.89L54.09 10.50L54.42 11.05L54.78 11.52L55.20 11.92L55.69 12.24L56.23 12.49L56.84 12.68L57.49 12.84L58.19 12.96L58.91 13.09L59.63 13.23L60.34 13.42L61.00 13.66L61.61 13.96L62.14 14.34L62.58 14.80L62.93 15.34L63.18 15.94L63.35 16.60L63.43 17.30L63.45 18.03L63.43 18.76L63.40 19.49L63.37 20.20L63.37 20.87L63.42 21.51L63.54 22.10L63.75 22.64L64.04 23.13L64.43 23.60L64.89 24.03L65.42 24.46L65.99 24.87L66.58 25.30L67.17 25.74L67.73 26.21L68.22 26.72L68.63 27.26L68.95 27.83L69.15 28.43L69.23 29.07L69.20 29.72L69.06 30.38L68.83 31.05L68.53 31.72L68.20 32.37L67.85 33.01L67.51 33.64L67.22 34.25L66.99 34.84L66.85 35.42L66.80 36.00L66.85 36.58L66.99 37.16L67.22 37.75L67.51 38.36L67.85 38.99L68.20 39.63L68.53 40.28L68.83 40.95L69.06 41.62L69.20 42.28L69.23 42.93L69.15 43.57L68.95 44.17L68.63 44.74L68.22 45.28L67.73 45.79L67.17 46.26L66.58 46.70L65.99 47.13L65.42 47.54L64.89 47.97L64.43 48.40L64.04 48.87L63.75 49.36L63.54 49.90L63.42 50.49L63.37 51.13L63.37 51.80L63.40 52.51L63.43 53.24L63.45 53.97L63.43 54.70L63.35 55.40L63.18 56.06L62.93 56.66L62.58 57.20L62.14 57.66L61.61 58.04L61.00 58.34L60.34 58.58L59.63 58.77L58.91 58.91L58.19 59.04L57.49 59.16L56.84 59.32L56.23 59.51L55.69 59.76L55.20 60.08L54.78 60.48L54.42 60.95L54.09 61.50L53.80 62.11L53.52 62.76L53.24 63.43L52.94 64.11L52.60 64.75L52.22 65.35L51.79 65.87L51.30 66.30L50.75 66.63L50.15 66.85L49.51 66.97L48.83 66.98L48.13 66.91L47.42 66.76L46.70 66.58L46.00 66.38L45.31 66.20L44.66 66.05L44.03 65.96L43.43 65.95L42.85 66.03L42.30 66.20L41.77 66.47L41.24 66.83L40.71 67.25L40.17 67.71L39.63 68.20L39.06 68.67L38.48 69.11L37.88 69.48L37.26 69.76L36.63 69.94L36.00 70.00L35.37 69.94L34.74 69.76L34.12 69.48L33.52 69.11L32.94 68.67L32.37 68.20L31.83 67.71L31.29 67.25L30.76 66.83L30.23 66.47L29.70 66.20L29.15 66.03L28.57 65.95L27.97 65.96L27.34 66.05L26.69 66.20L26.00 66.38L25.30 66.58L24.58 66.76L23.87 66.91L23.17 66.98L22.49 66.97L21.85 66.85L21.25 66.63L20.70 66.30L20.21 65.87L19.78 65.35L19.40 64.75L19.06 64.11L18.76 63.43L18.48 62.76L18.20 62.11L17.91 61.50L17.58 60.95L17.22 60.48L16.80 60.08L16.31 59.76L15.77 59.51L15.16 59.32L14.51 59.16L13.81 59.04L13.09 58.91L12.37 58.77L11.66 58.58L11.00 58.34L10.39 58.04L9.86 57.66L9.42 57.20L9.07 56.66L8.82 56.06L8.65 55.40L8.57 54.70L8.55 53.97L8.57 53.24L8.60 52.51L8.63 51.80L8.63 51.13L8.58 50.49L8.46 49.90L8.25 49.36L7.96 48.87L7.57 48.40L7.11 47.97L6.58 47.54L6.01 47.13L5.42 46.70L4.83 46.26L4.27 45.79L3.78 45.28L3.37 44.74L3.05 44.17L2.85 43.57L2.77 42.93L2.80 42.28L2.94 41.62L3.17 40.95L3.47 40.28L3.80 39.63L4.15 38.99L4.49 38.36L4.78 37.75L5.01 37.16L5.15 36.58L5.20 36.00L5.15 35.42L5.01 34.84L4.78 34.25L4.49 33.64L4.15 33.01L3.80 32.37L3.47 31.72L3.17 31.05L2.94 30.38L2.80 29.72L2.77 29.07L2.85 28.43L3.05 27.83L3.37 27.26L3.78 26.72L4.27 26.21L4.83 25.74L5.42 25.30L6.01 24.87L6.58 24.46L7.11 24.03L7.57 23.60L7.96 23.13L8.25 22.64L8.46 22.10L8.58 21.51L8.63 20.87L8.63 20.20L8.60 19.49L8.57 18.76L8.55 18.03L8.57 17.30L8.65 16.60L8.82 15.94L9.07 15.34L9.42 14.80L9.86 14.34L10.39 13.96L11.00 13.66L11.66 13.42L12.37 13.23L13.09 13.09L13.81 12.96L14.51 12.84L15.16 12.68L15.77 12.49L16.31 12.24L16.80 11.92L17.22 11.52L17.58 11.05L17.91 10.50L18.20 9.89L18.48 9.24L18.76 8.57L19.06 7.89L19.40 7.25L19.78 6.65L20.21 6.13L20.70 5.70L21.25 5.37L21.85 5.15L22.49 5.03L23.17 5.02L23.87 5.09L24.58 5.24L25.30 5.42L26.00 5.62L26.69 5.80L27.34 5.95L27.97 6.04L28.57 6.05L29.15 5.97L29.70 5.80L30.23 5.53L30.76 5.17L31.29 4.75L31.83 4.29L32.37 3.80L32.94 3.33L33.52 2.89L34.12 2.52L34.74 2.24L35.37 2.06Z%27 fill%3D%27none%27 stroke%3D%27%23000%27 stroke-width%3D%274%27 stroke-linejoin%3D%27round%27%2F%3E%3C%2Fsvg%3E");
}

.progress-wavy,
.progress-circular {
  --md-progress-indicator: var(--md-sys-color-primary);
  --md-progress-track: var(--md-sys-color-secondary-container);
  /* m3-springs.js (optional) drives --md-progress-js; otherwise the CSS transition runs. */
  --md-progress-now: var(--md-progress-js, var(--md-progress-value));
  transition: --md-progress-value var(--md-motion-default-spatial);
}
.progress-wavy.md-js-spring,
.progress-circular.md-js-spring { transition: none; }

/* ---- Linear, determinate ---- */
.progress-wavy {
  /* Wave band height: 0 at ≤10% / ≥95%, ramping to the full 10px over 5%.
     Percentages here resolve against the 10px height wherever it's used. */
  --md-wave-h: clamp(0px, min(var(--md-progress-now) - 10%, 95% - var(--md-progress-now)) * 20, 10px);
  position: relative;
  height: 10px;
  overflow: hidden;
  /* Flat indicator, shown whenever the wave isn't at full height */
  background: linear-gradient(var(--md-progress-indicator) 0 0) no-repeat 0 50% /
              var(--md-progress-now) clamp(0px, (10px - var(--md-wave-h)) * 1000, 4px);
}
.progress-wavy::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(50% - var(--md-wave-h) / 2);
  height: var(--md-wave-h);
  width: var(--md-progress-now);
  background-color: var(--md-progress-indicator);
  -webkit-mask: var(--md-wave-mask-40) repeat-x -40px 50% / 1600px 10px;
  mask: var(--md-wave-mask-40) repeat-x -40px 50% / 1600px 10px;
  animation: md-wave-40 calc(1s * var(--md-motion-scale)) linear infinite;
}
/* Track after a 4px gap, ending in the 4px stop indicator */
.progress-wavy::after {
  content: "";
  position: absolute;
  top: 3px;
  right: 0;
  left: calc(var(--md-progress-now) + 4px);
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to left, var(--md-progress-indicator) 4px, var(--md-progress-track) 4px);
}
@keyframes md-wave-40 {
  from { -webkit-mask-position: -40px 50%; mask-position: -40px 50%; }
  to   { -webkit-mask-position: 0 50%;     mask-position: 0 50%; }
}

/* ---- Linear, indeterminate: two segments chase each other (1750ms) ---- */
.progress-wavy.progress-indeterminate {
  --md-ind-ease: cubic-bezier(0.3, 0, 0.8, 0.15); /* M3 emphasized-accelerate */
  background: linear-gradient(to right,
      var(--md-progress-track) 0 calc(var(--md-ind-t2) - 4px), transparent 0 calc(var(--md-ind-h2) + 4px),
      var(--md-progress-track) 0 calc(var(--md-ind-t1) - 4px), transparent 0 calc(var(--md-ind-h1) + 4px),
      var(--md-progress-track) 0) no-repeat 0 50% / 100% 4px;
  animation: md-ind-h1 calc(1.75s * var(--md-motion-scale)) linear infinite,
             md-ind-t1 calc(1.75s * var(--md-motion-scale)) linear infinite,
             md-ind-h2 calc(1.75s * var(--md-motion-scale)) linear infinite,
             md-ind-t2 calc(1.75s * var(--md-motion-scale)) linear infinite;
}
.progress-wavy.progress-indeterminate::before,
.progress-wavy.progress-indeterminate::after {
  inset: 0;
  top: 0;
  left: 0;
  width: auto;
  height: auto;
  border-radius: 0;
  background: var(--md-progress-indicator);
  -webkit-mask: var(--md-wave-mask-20) repeat-x -20px 50% / 1600px 10px,
                linear-gradient(to right, transparent var(--md-seg-t), #000 0 var(--md-seg-h), transparent 0);
  -webkit-mask-composite: source-in;
  mask: var(--md-wave-mask-20) repeat-x -20px 50% / 1600px 10px,
        linear-gradient(to right, transparent var(--md-seg-t), #000 0 var(--md-seg-h), transparent 0);
  mask-composite: intersect;
  animation: md-wave-20 calc(1s * var(--md-motion-scale)) linear infinite;
}
.progress-wavy.progress-indeterminate::before { --md-seg-t: var(--md-ind-t1); --md-seg-h: var(--md-ind-h1); }
.progress-wavy.progress-indeterminate::after  { --md-seg-t: var(--md-ind-t2); --md-seg-h: var(--md-ind-h2); }
@keyframes md-wave-20 {
  from { -webkit-mask-position: -20px 50%, 0 0; mask-position: -20px 50%, 0 0; }
  to   { -webkit-mask-position: 0 50%, 0 0;     mask-position: 0 50%, 0 0; }
}
/* Compose: line 1 head 0–1000ms, tail 250–1250ms; line 2 head 650–1500ms,
   tail 900–1750ms. Finished/idle segments park off-track so their gaps don't show. */
@keyframes md-ind-h1 {
  0%     { --md-ind-h1: 0%; animation-timing-function: var(--md-ind-ease); }
  57.14% { --md-ind-h1: 100%; }
  71.43% { --md-ind-h1: 100%; animation-timing-function: steps(1, end); }
  71.5%, 100% { --md-ind-h1: 110%; }
}
@keyframes md-ind-t1 {
  0%, 14.29% { --md-ind-t1: 0%; animation-timing-function: var(--md-ind-ease); }
  71.43% { --md-ind-t1: 100%; animation-timing-function: steps(1, end); }
  71.5%, 100% { --md-ind-t1: 110%; }
}
@keyframes md-ind-h2 {
  0%, 37.09% { --md-ind-h2: -10%; animation-timing-function: steps(1, end); }
  37.14% { --md-ind-h2: 0%; animation-timing-function: var(--md-ind-ease); }
  85.71%, 100% { --md-ind-h2: 100%; }
}
@keyframes md-ind-t2 {
  0%, 51.37% { --md-ind-t2: -10%; animation-timing-function: steps(1, end); }
  51.43% { --md-ind-t2: 0%; animation-timing-function: var(--md-ind-ease); }
  100% { --md-ind-t2: 100%; }
}

/* ---- Circular ---- */
.progress-circular {
  --md-progress-size: 48px;
  --md-wave-ring: var(--md-wave-ring-48);
  --md-wave-period: 40deg;   /* 360° / 9 waves */
  --md-progress-gap: 3.12%;  /* 4px of the ring's circumference */
  position: relative;
  display: inline-block;
  flex: none;
  width: var(--md-progress-size);
  height: var(--md-progress-size);
}
.progress-circular-sm { --md-progress-size: 32px; --md-wave-ring: var(--md-wave-ring-32); --md-wave-period: 60deg; --md-progress-gap: 5.13%; }

/* With js/m3-components.js the wave is redrawn as SVG each frame (round
   caps, eased amplitude); the mask-drawn version above is hidden. */
.progress-wavy.md-js-wave { background: none; }
.progress-wavy.md-js-wave::before, .progress-wavy.md-js-wave::after,
.progress-circular.md-js-wave::before, .progress-circular.md-js-wave::after { display: none; }
.md-wave-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.md-wave-ind, .md-wave-trk { fill: none; stroke-width: 4px; stroke-linecap: round; stroke-linejoin: round; }
.md-wave-ind { stroke: var(--md-progress-indicator); }
.md-wave-trk { stroke: var(--md-progress-track); }
.md-wave-dot { fill: var(--md-progress-indicator); }

/* Ripples (with js/m3-components.js). While ripples are on, the pressed
   tint drops to the hover level; the ripple supplies the pressed 10%, as
   in Compose. */
html.md-ripples-on { --md-sys-state-pressed-state-layer-opacity: var(--md-sys-state-hover-state-layer-opacity); }
.md-ripple-host {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.md-ripple {
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  background-color: currentColor;
  opacity: 0;
  pointer-events: none;
}
.progress-circular-lg { --md-progress-size: 72px; --md-wave-ring: var(--md-wave-ring-72); --md-wave-period: 25.714deg; --md-progress-gap: 1.96%; }

/* Flat track ring, on the wave's center line, clipped after the indicator */
.progress-circular::before {
  content: "";
  position: absolute;
  inset: 1.6px;
  border: 4px solid var(--md-progress-track);
  border-radius: 50%;
  -webkit-mask: conic-gradient(transparent calc(var(--md-progress-now) + var(--md-progress-gap)), #000 0 calc(100% - var(--md-progress-gap)), transparent 0);
  mask: conic-gradient(transparent calc(var(--md-progress-now) + var(--md-progress-gap)), #000 0 calc(100% - var(--md-progress-gap)), transparent 0);
}
/* Wavy indicator. The ring image rotates (wave travel) while the conic
   window counter-rotates, so the arc stays put and the wave moves. */
.progress-circular::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--md-progress-indicator);
  rotate: var(--md-wave-rot);
  -webkit-mask: var(--md-wave-ring) center / 100% 100% no-repeat,
                conic-gradient(from calc(var(--md-wave-rot) * -1), #000 var(--md-progress-now), transparent 0);
  -webkit-mask-composite: source-in;
  mask: var(--md-wave-ring) center / 100% 100% no-repeat,
        conic-gradient(from calc(var(--md-wave-rot) * -1), #000 var(--md-progress-now), transparent 0);
  mask-composite: intersect;
  animation: md-wave-ring calc(1s * var(--md-motion-scale)) linear infinite;
}
@keyframes md-wave-ring {
  from { --md-wave-rot: 0deg; }
  to   { --md-wave-rot: var(--md-wave-period); }
}

/* Indeterminate, 6000ms loop: the arc grows 10%→87%→10% while the whole
   indicator spins 1080° plus a 90° kick every 1.5s. Timing is Compose's, but
   the easing is measured from M3's own spec video ("Indeterminate progress
   indicators move along a fixed track"): standard easing on both the growth
   and the shrink, and each kick on standard easing over 500ms. Compose's code
   grows linearly and kicks with emphasized-decelerate in 300ms, which snaps
   ~60% of the kick into the first frame. */
.progress-circular.progress-indeterminate {
  animation: md-circ-arc calc(6s * var(--md-motion-scale)) linear infinite,
             md-circ-spin calc(6s * var(--md-motion-scale)) linear infinite,
             md-circ-step calc(6s * var(--md-motion-scale)) linear infinite;
}
.progress-circular.progress-indeterminate::before,
.progress-circular.progress-indeterminate::after {
  transform: rotate(calc(var(--md-circ-spin) + var(--md-circ-step)));
}
@keyframes md-circ-arc {
  0%   { --md-progress-value: 10%; animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }
  50%  { --md-progress-value: 87%; animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }
  100% { --md-progress-value: 10%; }
}
@keyframes md-circ-spin { from { --md-circ-spin: 0deg; } to { --md-circ-spin: 1080deg; } }
@keyframes md-circ-step {
  0%  { --md-circ-step: 0deg;   animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }
  8.333%, 25% { --md-circ-step: 90deg;  animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }
  33.333%, 50% { --md-circ-step: 180deg; animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }
  58.333%, 75% { --md-circ-step: 270deg; animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }
  83.333%, 100% { --md-circ-step: 360deg; }
}

.spinner-border, .spinner-grow { color: var(--md-sys-color-primary); }

.table {
  --bs-table-color: var(--md-sys-color-on-surface);
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--md-sys-color-outline-variant);
  --bs-table-striped-color: var(--md-sys-color-on-surface);
  --bs-table-striped-bg: color-mix(in srgb, var(--md-sys-color-on-surface) 4%, transparent);
  --bs-table-hover-color: var(--md-sys-color-on-surface);
  --bs-table-hover-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-table-active-color: var(--md-sys-color-on-secondary-container);
  --bs-table-active-bg: var(--md-sys-color-secondary-container);
  font-size: var(--md-sys-typescale-body-medium-size);
}
.table > :not(caption) > * > * { padding: 12px 16px; }
/* Our padding above would otherwise override Bootstrap's .table-sm */
.table-sm > :not(caption) > * > * { padding: 6px 12px; }
.table > thead th { font-family: var(--md-sys-typescale-title-small-font); font-weight: var(--md-sys-typescale-title-small-weight); color: var(--md-sys-color-on-surface-variant); }
.table > caption { color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-small-size); }
.table td > .form-check-input, .table th > .form-check-input { margin: 0; vertical-align: middle; }
/* Sortable column: a text button in the header cell; aria-sort on the th
   ("ascending" / "descending") turns and shows the arrow. */
.table-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: -4px -8px;
  padding: 4px 8px;
  border: 0;
  border-radius: var(--md-sys-shape-corner-full);
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.table-sort:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.table-sort:focus-visible { outline: var(--md-focus-ring); outline-offset: 0; }
.table-sort > .material-symbols-rounded { font-size: 18px; opacity: 0; transition: opacity var(--md-motion-fast-effects), rotate var(--md-motion-fast-spatial); }
.table-sort:hover > .material-symbols-rounded { opacity: .5; }
th[aria-sort="ascending"] .table-sort > .material-symbols-rounded,
th[aria-sort="descending"] .table-sort > .material-symbols-rounded { opacity: 1; }
th[aria-sort="descending"] .table-sort > .material-symbols-rounded { rotate: 180deg; }
th[aria-sort="ascending"], th[aria-sort="descending"] { color: var(--md-sys-color-on-surface) !important; }
/* Toolbar above and footer below a table in a card */
.table-toolbar, .table-footer { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 16px; }
.table-toolbar-title { flex: 1; margin: 0; font-family: var(--md-sys-typescale-title-large-font); font-size: var(--md-sys-typescale-title-large-size); line-height: var(--md-sys-typescale-title-large-line-height); font-weight: var(--md-sys-typescale-title-large-weight); }
.table-toolbar.is-selecting { background-color: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.table-footer { justify-content: flex-end; gap: 16px; color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-body-small-size); }
.table-footer .form-select { width: auto; }
.table-primary   { --bs-table-color: var(--md-sys-color-on-primary-container);   --bs-table-bg: var(--md-sys-color-primary-container);   --bs-table-border-color: var(--bs-primary-border-subtle); }
.table-secondary { --bs-table-color: var(--md-sys-color-on-secondary-container); --bs-table-bg: var(--md-sys-color-secondary-container); --bs-table-border-color: var(--bs-secondary-border-subtle); }
.table-success   { --bs-table-color: var(--md-sys-color-on-success-container);   --bs-table-bg: var(--md-sys-color-success-container);   --bs-table-border-color: var(--bs-success-border-subtle); }
.table-info      { --bs-table-color: var(--md-sys-color-on-info-container);      --bs-table-bg: var(--md-sys-color-info-container);      --bs-table-border-color: var(--bs-info-border-subtle); }
.table-warning   { --bs-table-color: var(--md-sys-color-on-warning-container);   --bs-table-bg: var(--md-sys-color-warning-container);   --bs-table-border-color: var(--bs-warning-border-subtle); }
.table-danger    { --bs-table-color: var(--md-sys-color-on-error-container);     --bs-table-bg: var(--md-sys-color-error-container);     --bs-table-border-color: var(--bs-danger-border-subtle); }
.table-light     { --bs-table-color: var(--md-sys-color-on-surface);             --bs-table-bg: var(--md-sys-color-surface-container);   --bs-table-border-color: var(--md-sys-color-outline-variant); }
.table-dark      { --bs-table-color: var(--md-sys-color-inverse-on-surface);     --bs-table-bg: var(--md-sys-color-inverse-surface);     --bs-table-border-color: var(--md-sys-color-outline); }
.table-primary, .table-secondary, .table-success, .table-info, .table-warning,
.table-danger, .table-light, .table-dark {
  --bs-table-striped-bg: color-mix(in srgb, var(--bs-table-color) 6%, var(--bs-table-bg));
  --bs-table-striped-color: var(--bs-table-color);
  --bs-table-hover-bg: color-mix(in srgb, var(--bs-table-color) var(--md-sys-state-hover-state-layer-opacity), var(--bs-table-bg));
  --bs-table-hover-color: var(--bs-table-color);
  --bs-table-active-bg: color-mix(in srgb, var(--bs-table-color) 12%, var(--bs-table-bg));
  --bs-table-active-color: var(--bs-table-color);
}

hr { color: var(--md-sys-color-outline-variant); opacity: 1; }

/* ==========================================================================
   11b. M3 Expressive surfaces: bottom sheet, search, toolbars, app bars,
        menu groups, segmented lists (Compose *Tokens)
   ========================================================================== */

/* ---- Bottom sheet: Bootstrap .offcanvas-bottom (SheetBottomTokens) ----
   surface-container-low, 28px top corners, 32×4 drag handle, level 1,
   max 640px wide, height follows content. */
.offcanvas-bottom {
  --bs-offcanvas-height: auto;
  --bs-offcanvas-bg: var(--md-sys-color-surface-container-low);
  --bs-offcanvas-transition: transform var(--md-motion-default-spatial);
  max-height: calc(100% - 56px);
  max-width: 640px;
  margin-inline: auto;
  border: 0 !important;
  border-radius: var(--md-sys-shape-corner-extra-large) var(--md-sys-shape-corner-extra-large) 0 0;
  box-shadow: var(--md-sys-elevation-level1);
}
.offcanvas-bottom::before {
  content: "";
  flex: none;
  align-self: center;
  width: 32px;
  height: 4px;
  margin: 22px 0 6px;
  border-radius: 2px;
  background-color: var(--md-sys-color-on-surface-variant);
}
.offcanvas-bottom.sheet-no-handle::before { display: none; }
/* Lists inside sheets and dialogs take the container's color */
.offcanvas .list-group, .modal-content .list-group {
  --bs-list-group-bg: transparent;
  --bs-list-group-action-hover-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-list-group-action-active-bg: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity), transparent);
}
.offcanvas-backdrop { --bs-backdrop-bg: var(--md-sys-color-scrim); --bs-backdrop-opacity: .32; }
/* ---- Side sheet (SheetSideTokens + the M3 side sheet spec) ----
   Modal: Bootstrap .offcanvas-end (or -start) with a scrim. surface-container-low,
   level 1, large corners on the inner edge, max 400 wide.
   <div class="offcanvas offcanvas-end" …>
     <div class="offcanvas-header">
       <button class="btn btn-icon" aria-label="Back">…arrow_back…</button>   (optional)
       <h2 class="offcanvas-title">Title</h2>
       <button class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
     </div>
     <div class="offcanvas-body">…</div>
     <div class="offcanvas-footer border-top"> buttons </div>   (optional; border-top = divider)
   </div>
   .offcanvas-detached floats it 16px from the edges with all corners rounded.
   Standard (non-modal, beside the content): .side-sheet; see below. */
.offcanvas { --bs-offcanvas-transition: transform var(--md-motion-default-spatial); }
.offcanvas-end, .offcanvas-start {
  --bs-offcanvas-width: min(400px, 100%);
  --bs-offcanvas-bg: var(--md-sys-color-surface-container-low);
  border: 0 !important;
  box-shadow: var(--md-sys-elevation-level1);
}
.offcanvas-end   { border-radius: var(--md-sys-shape-corner-large) 0 0 var(--md-sys-shape-corner-large); }
.offcanvas-start { border-radius: 0 var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0; }
.offcanvas-detached.offcanvas-end, .offcanvas-detached.offcanvas-start {
  --bs-offcanvas-width: min(400px, calc(100% - 32px));
  top: 16px;
  bottom: 16px;
  border-radius: var(--md-sys-shape-corner-large);
}
.offcanvas-detached.offcanvas-end { right: 16px; transform: translateX(calc(100% + 16px)); }
.offcanvas-detached.offcanvas-start { left: 16px; transform: translateX(calc(-100% - 16px)); }
.offcanvas-detached:is(.showing, .show:not(.hiding)) { transform: none; }

/* Header, body and actions (shared by modal and standard side sheets) */
:is(.offcanvas-end, .offcanvas-start, .side-sheet) .offcanvas-header {
  gap: 12px;
  min-height: 72px;
  padding: 12px 12px 12px 24px;
}
:is(.offcanvas-end, .offcanvas-start, .side-sheet) .offcanvas-header:has(> .btn-icon:first-child) { padding-left: 16px; }
:is(.offcanvas-end, .offcanvas-start, .side-sheet) .offcanvas-header > .btn-close { margin: 0 0 0 auto; }
:is(.offcanvas-end, .offcanvas-start, .side-sheet) .offcanvas-title {
  flex: 1;
  min-width: 0;
  color: var(--md-sys-color-on-surface-variant);
  line-height: var(--md-sys-typescale-title-large-line-height);
}
:is(.offcanvas-end, .offcanvas-start, .side-sheet) .offcanvas-body {
  padding: 0 24px 24px;
  color: var(--md-sys-color-on-surface-variant);
}
.offcanvas-footer {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  min-height: 72px;
  padding: 16px 24px 24px;
  margin-top: auto;
}
.offcanvas-footer.border-top { border-color: var(--md-sys-color-outline) !important; }

/* Standard side sheet: in the page beside the content, on surface, no
   shadow or corners. Put it in a flex row; wrap it in Bootstrap's
   .collapse.collapse-horizontal to open and close it. Width moves on
   default-effects (no overshoot), so the content beside it never wobbles.
   On the start side, add .side-sheet-start (and use .border-end).
   <div class="d-flex">
     <main class="flex-grow-1">…</main>
     <div class="collapse collapse-horizontal show" id="filters">
       <aside class="side-sheet border-start"> header / body / footer </aside>
     </div>
   </div>
   .border-start (or .border-end on the start side) is the optional divider. */
.side-sheet {
  display: flex;
  flex-direction: column;
  width: 400px;
  max-width: 100%;
  height: 100%;
  background-color: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
}
.side-sheet.border-start, .side-sheet.border-end { border-color: var(--md-sys-color-outline) !important; }
.side-sheet > .offcanvas-header { display: flex; align-items: center; }
.side-sheet > .offcanvas-body { flex: 1 1 auto; overflow-y: auto; }
.collapse-horizontal.collapsing:has(> .side-sheet) { transition: width var(--md-motion-default-effects); }
/* The sheet keeps its full width while the wrapper's width animates, so its
   content never reflows. It rides the content-side edge, so it slides out
   past the window edge. A start-side sheet is pinned to its right edge with
   direction: rtl, which (unlike flex-end) keeps the overflow in
   scrollWidth, which Bootstrap measures to open. */
.collapse-horizontal > .side-sheet { height: 100%; max-width: none; direction: ltr; }
.collapse-horizontal:has(> .side-sheet-start) { direction: rtl; }
/* In a flex row the wrapper must not shrink below the sheet, or the sheet is clipped */
.collapse-horizontal:has(> .side-sheet) { flex: none; }

/* ---- Search (SearchBarTokens / SearchViewTokens) ----
   <div class="search">
     <form class="search-bar" role="search">
       <span class="material-symbols-rounded">search</span>
       <input class="search-bar-input" type="search" placeholder="Search" aria-label="Search">
       <button class="btn btn-icon" type="button" aria-label="Voice search">…mic…</button>
     </form>
     <div class="search-results"> <a class="search-result" href="#">…</a> … </div>   (optional)
   </div>
   With results present, focusing the bar opens them below it in one
   rounded container (the M3 docked search view), no JS needed. */
.search { position: relative; max-width: 720px; }
.search-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 56px;
  padding: 0 4px 0 16px;
  border-radius: 28px; /* = height / 2; a real value so the corners can animate */
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  transition: border-radius var(--md-motion-fast-effects), background-color var(--md-motion-fast-effects);
}
.search-bar:hover:not(:focus-within) { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-high)); }
.search-bar > :is(.material-symbols-rounded, .material-symbols-outlined):first-child { flex: none; margin-right: 12px; color: var(--md-sys-color-on-surface); }
.search-bar .btn-icon { --md-btn-content: var(--md-sys-color-on-surface-variant); }
.search-bar-avatar { flex: none; width: 30px; height: 30px; margin-inline: 5px; border-radius: 50%; object-fit: cover; }
.search-bar-input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
}
.search-bar-input::placeholder { color: var(--md-sys-color-on-surface-variant); opacity: 1; }
.search-bar-input::-webkit-search-cancel-button { display: none; }
.search-bar:has(.search-bar-input:focus-visible) { outline: var(--md-focus-ring); outline-offset: var(--md-focus-offset); }

/* Docked search view: results grow open below the bar */
.search-results {
  position: absolute;
  z-index: 1000;
  inset: 100% 0 auto;
  display: grid;
  grid-template-rows: 0fr;
  max-height: min(60vh, 480px);
  overflow: auto;
  border-radius: 0 0 var(--md-sys-shape-corner-extra-large) var(--md-sys-shape-corner-extra-large);
  background-color: var(--md-sys-color-surface-container-high);
  box-shadow: var(--md-sys-elevation-level3);
  visibility: hidden;
  opacity: 0;
  /* Closing: rows, fade and the bar corners all finish together, quickly */
  transition: grid-template-rows var(--md-motion-fast-effects), opacity var(--md-motion-fast-effects),
              visibility 0s linear calc(var(--md-sys-motion-spring-fast-effects-duration) * var(--md-motion-scale));
}
.search-results > * { min-height: 0; overflow: hidden; }
.search-results-list { padding-block: 8px; border-top: 1px solid var(--md-sys-color-outline); }
.search:has(.search-results):focus-within .search-bar {
  border-radius: var(--md-sys-shape-corner-extra-large) var(--md-sys-shape-corner-extra-large) 0 0;
  outline: 0;
  transition: border-radius var(--md-motion-default-spatial), background-color var(--md-motion-fast-effects);
}
.search:has(.search-results):focus-within .search-results {
  grid-template-rows: 1fr;
  visibility: visible;
  opacity: 1;
  transition: grid-template-rows var(--md-motion-default-spatial), opacity var(--md-motion-fast-effects), visibility 0s;
}
/* Script-filled results: an empty list (cleared by your code) keeps the view
   closed and the bar round until there is something to show. */
.search:has(.search-results-list:empty):focus-within .search-bar { border-radius: 28px; }
.search:has(.search-results-list:empty):focus-within .search-results {
  grid-template-rows: 0fr;
  visibility: hidden;
  opacity: 0;
}
.search-results-heading {
  margin: 0;
  padding: 8px 16px 4px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-title-small-font);
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
.search-results-empty { padding: 16px; color: var(--md-sys-color-on-surface-variant); }
.search-result mark { padding: 0; background: none; color: inherit; font-weight: 600; }
.search-result {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 56px;
  padding: 8px 16px;
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
  font-size: var(--md-sys-typescale-body-large-size);
}
.search-result > :is(.material-symbols-rounded, .material-symbols-outlined) { color: var(--md-sys-color-on-surface-variant); }
.search-result:hover, .search-result:focus-visible {
  outline: 0;
  color: var(--md-sys-color-on-surface);
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
}

/* ---- Toolbars (DockedToolbarTokens / FloatingToolbarTokens) ----
   .toolbar-docked: full-width 64px bar, surface-container; items spread
     edge to edge (.toolbar-docked-fixed: centered, 32px apart).
   .toolbar-floating: 64px pill, 8px padding, 4px between items.
   .toolbar-vibrant: primary-container with on-primary-container content.
   .toolbar-vertical: floating toolbar stacked vertically. */
/* Compose FlexibleBottomAppBar: items spread edge to edge (SpaceBetween)
   inside 16px end padding, never closer than 4px. .toolbar-docked-fixed is
   FlexibleFixedHorizontalArrangement: centered with 32px between items. */
.toolbar-docked {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  height: 64px;
  padding-inline: 16px;
  background-color: var(--md-sys-color-surface-container);
}
.toolbar-docked-fixed { justify-content: center; gap: 32px; }
.toolbar-floating {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 64px;
  padding-inline: 8px;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-surface-container);
  box-shadow: var(--md-sys-elevation-level3);
}
.toolbar-vertical { flex-direction: column; height: auto; width: 64px; padding: 8px 0; }
.toolbar-vibrant { background-color: var(--md-sys-color-primary-container); }
.toolbar-vibrant .btn-icon:not(.btn-primary):not(.btn-tonal):not(.btn-elevated):not([class*="btn-outline-"]) {
  --md-btn-content: var(--md-sys-color-on-primary-container);
  --bs-btn-color: var(--md-btn-content);
  --bs-btn-hover-color: var(--md-btn-content);
  --bs-btn-active-color: var(--md-btn-content);
}
.toolbar-vibrant :is(.btn-check:checked + .btn-toggle, .btn-toggle.active, .btn-toggle[aria-pressed="true"]).btn-icon {
  --md-btn-container: var(--md-sys-color-surface-container);
  --md-btn-content: var(--md-sys-color-on-surface);
  --bs-btn-color: var(--md-btn-content);
}
.toolbar-floating > .btn-fab { box-shadow: none; }

/* Docked toolbar that hides on scroll (Compose FlexibleBottomAppBar with
   BottomAppBarDefaults.exitAlwaysScrollBehavior), with js/m3-components.js:
   <div class="toolbar-docked sticky-bottom" data-m3-toolbar="exit-always">
   It slides down 1:1 as the content scrolls down and back up as it scrolls
   up; when scrolling stops halfway it snaps shown or hidden on fast-spatial.
   The offset is clamped (as Compose clamps heightOffset), so the spring's
   bounce never lifts the bar off its edge. Keyboard focus inside shows it. */
@property --md-tb-hide { syntax: "<length>"; inherits: true; initial-value: 0px; }
/* As in Compose the bar loses height from the top rather than moving: the
   container is clipped from its top edge while the items ride down with it.
   overflow: clip keeps the moved items out of the scroll area's height. */
.toolbar-docked[data-m3-toolbar="exit-always"] { overflow: clip; clip-path: inset(clamp(0px, var(--md-tb-hide), 100%) 0 0 0); }
.toolbar-docked[data-m3-toolbar="exit-always"] > * { translate: 0 max(0px, var(--md-tb-hide)); }
.toolbar-docked[data-m3-toolbar="exit-always"].md-tb-settling { transition: --md-tb-hide var(--md-motion-fast-spatial); }

/* ---- Expanding floating toolbars (Compose HorizontalFloatingToolbar /
   VerticalFloatingToolbar with expanded, + the M3 spec video) ----
   Toolbar beside a FAB that toggles it:
     <div class="toolbar-fab">                       (+ -start, -vertical)
       <div class="toolbar-floating" id="tb" role="toolbar" aria-label="Actions"> …icon buttons… </div>
       <button class="btn btn-fab toolbar-fab-toggle" aria-expanded="false" aria-controls="tb" aria-label="Show actions">
         <span class="material-symbols-rounded toolbar-toggle-icon">edit</span>
         <span class="material-symbols-rounded toolbar-toggle-icon-close">close</span></button>
     </div>
   Toolbar that opens out both sides of a middle toggle:
     <div class="toolbar-floating toolbar-expandable">
       <div class="toolbar-group"> … </div>
       <button class="btn btn-icon toolbar-expand-toggle" aria-expanded="false" aria-label="More">…same two icons…</button>
       <div class="toolbar-group"> … </div>
     </div>
   m3-components.js measures the toolbar (--md-toolbar-size) and toggles
   .open. The bar's size springs on fast-spatial (it overshoots, so the bar
   stretches past its length and settles); its content rides the moving edge,
   so the icons slide out of the FAB, starting bunched up and spreading to
   their spacing, fading in nearest-first. The toggle icon turns and
   cross-fades. Without the script the toolbar simply stays closed. */
.toolbar-fab { position: relative; display: inline-flex; vertical-align: middle; }
/* Closing uses default-effects (critically damped, no overshoot) plus a
   fade: a bouncy close would undershoot past zero, clamp, then rebound and
   peek back out of the FAB. Opening keeps the fast-spatial bounce. */
.toolbar-fab > .toolbar-floating,
.toolbar-expandable > .toolbar-group {
  --md-tb-dur: calc(var(--md-sys-motion-spring-default-effects-duration) * var(--md-motion-scale));
  overflow: hidden;
  visibility: hidden;
  opacity: 0;
  transition: width var(--md-motion-default-effects), height var(--md-motion-default-effects),
              padding var(--md-motion-default-effects), opacity var(--md-motion-default-effects),
              box-shadow var(--md-motion-default-effects), visibility 0s linear var(--md-tb-dur);
}
.toolbar-fab.open > .toolbar-floating,
.toolbar-expandable.open > .toolbar-group {
  visibility: visible;
  opacity: 1;
  transition: width var(--md-motion-fast-spatial), height var(--md-motion-fast-spatial),
              padding var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects),
              box-shadow var(--md-motion-default-effects), visibility 0s;
}
.toolbar-fab > .toolbar-floating > *,
.toolbar-expandable > .toolbar-group > * { flex: none; }

/* Toolbar beside the FAB: out of flow, so the FAB never moves */
.toolbar-fab > .toolbar-floating {
  position: absolute;
  z-index: 1;
  top: 50%;
  right: calc(100% + 8px);
  translate: 0 -50%;
  width: 0;
  padding-inline: 0;
  box-shadow: var(--md-sys-elevation-level1);
}
.toolbar-fab.open > .toolbar-floating { width: var(--md-toolbar-size, max-content); padding-inline: 8px; box-shadow: var(--md-sys-elevation-level3); }
.toolbar-fab-start > .toolbar-floating { right: auto; left: calc(100% + 8px); justify-content: flex-end; }
.toolbar-fab-vertical > .toolbar-floating {
  top: auto;
  right: auto;
  bottom: calc(100% + 8px);
  left: 50%;
  translate: -50% 0;
  width: 64px;
  height: 0;
  padding: 0;
}
.toolbar-fab-vertical.open > .toolbar-floating { width: 64px; height: var(--md-toolbar-size, max-content); padding: 8px 0; }

/* Middle toggle: leading and trailing groups grow outward */
.toolbar-expandable { gap: 0; }
.toolbar-expandable > .toolbar-group { display: flex; align-items: center; gap: 4px; width: 0; }
.toolbar-expandable > .toolbar-group:first-child { padding-right: 0; }
.toolbar-expandable > .toolbar-group:last-child { justify-content: flex-end; }
.toolbar-expandable.open > .toolbar-group { width: var(--md-toolbar-size, max-content); }
.toolbar-expandable.open > .toolbar-group:first-child { padding-right: 4px; }
.toolbar-expandable.open > .toolbar-group:last-child { padding-left: 4px; }

/* Items: bunched toward the toggle and transparent while closed; they spread
   out on fast-spatial (overshooting their spacing) and fade in nearest-first. */
.toolbar-fab > .toolbar-floating > *,
.toolbar-expandable > .toolbar-group > * {
  --md-tb-step: 8px;
  opacity: 0;
  translate: calc(var(--md-tb-k, 1) * var(--md-tb-step)) 0;
  /* translate/opacity are the reveal; the rest keep the button's own
     state transitions (press shape morph, colors) */
  transition: translate var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects),
              background-color var(--md-motion-fast-effects), color var(--md-motion-fast-effects),
              border-radius var(--md-motion-fast-spatial), padding var(--md-motion-fast-spatial);
}
/* --md-tb-k: how far an item sits from the toggle (1 = nearest) */
.toolbar-fab:not(.toolbar-fab-start) > .toolbar-floating > :nth-last-child(1),
.toolbar-fab-start > .toolbar-floating > :nth-child(1),
.toolbar-expandable > .toolbar-group:first-child > :nth-last-child(1),
.toolbar-expandable > .toolbar-group:last-child > :nth-child(1) { --md-tb-k: 1; --md-tb-delay: 0ms; }
.toolbar-fab:not(.toolbar-fab-start) > .toolbar-floating > :nth-last-child(2),
.toolbar-fab-start > .toolbar-floating > :nth-child(2),
.toolbar-expandable > .toolbar-group:first-child > :nth-last-child(2),
.toolbar-expandable > .toolbar-group:last-child > :nth-child(2) { --md-tb-k: 2; --md-tb-delay: 25ms; }
.toolbar-fab:not(.toolbar-fab-start) > .toolbar-floating > :nth-last-child(3),
.toolbar-fab-start > .toolbar-floating > :nth-child(3),
.toolbar-expandable > .toolbar-group:first-child > :nth-last-child(3),
.toolbar-expandable > .toolbar-group:last-child > :nth-child(3) { --md-tb-k: 3; --md-tb-delay: 50ms; }
.toolbar-fab:not(.toolbar-fab-start) > .toolbar-floating > :nth-last-child(4),
.toolbar-fab-start > .toolbar-floating > :nth-child(4),
.toolbar-expandable > .toolbar-group:first-child > :nth-last-child(4),
.toolbar-expandable > .toolbar-group:last-child > :nth-child(4) { --md-tb-k: 4; --md-tb-delay: 75ms; }
.toolbar-fab:not(.toolbar-fab-start) > .toolbar-floating > :nth-last-child(n+5),
.toolbar-fab-start > .toolbar-floating > :nth-child(n+5),
.toolbar-expandable > .toolbar-group:first-child > :nth-last-child(n+5),
.toolbar-expandable > .toolbar-group:last-child > :nth-child(n+5) { --md-tb-k: 5; --md-tb-delay: 100ms; }
/* Direction toward the toggle: right for end FABs and the leading group,
   left for start FABs and the trailing group, down for vertical. */
.toolbar-fab-start > .toolbar-floating > *,
.toolbar-expandable > .toolbar-group:last-child > * { --md-tb-step: -8px; }
.toolbar-fab-vertical > .toolbar-floating > * { translate: 0 calc(var(--md-tb-k, 1) * 8px); }
.toolbar-fab.open > .toolbar-floating > *,
.toolbar-expandable.open > .toolbar-group > * {
  opacity: 1;
  translate: 0 0;
  /* stagger only the reveal, never the press morph */
  transition-delay: var(--md-tb-delay, 0ms), var(--md-tb-delay, 0ms), 0ms, 0ms, 0ms, 0ms;
}

/* Toggle icon: turns 90° and cross-fades (edit → close). Composited at rest
   so it never snaps a pixel when the turn ends. */
:is(.toolbar-fab-toggle, .toolbar-expand-toggle) { position: relative; }
:is(.toolbar-fab-toggle, .toolbar-expand-toggle) > :is(.toolbar-toggle-icon, .toolbar-toggle-icon-close) {
  position: absolute;
  inset: 0;
  width: 1em;
  height: 1em;
  margin: auto;
  transition: opacity var(--md-motion-fast-effects), rotate var(--md-motion-fast-spatial);
  will-change: rotate, opacity;
}
:is(.toolbar-fab-toggle, .toolbar-expand-toggle) > .toolbar-toggle-icon-close { opacity: 0; rotate: -90deg; }
:is(.toolbar-fab, .toolbar-expandable).open :is(.toolbar-fab-toggle, .toolbar-expand-toggle) > .toolbar-toggle-icon { opacity: 0; rotate: 90deg; }
:is(.toolbar-fab, .toolbar-expandable).open :is(.toolbar-fab-toggle, .toolbar-expand-toggle) > .toolbar-toggle-icon-close { opacity: 1; rotate: 0deg; }

/* ---- App bars (AppBar*Tokens, Expressive flexible sizes) ----
   <header class="app-bar app-bar-medium">
     <div class="app-bar-row">
       <button class="btn btn-icon" aria-label="Back">…arrow_back…</button>
       <span class="app-bar-title">Title</span>   (small bar only)
       <div class="app-bar-actions"> …icon buttons… </div>
     </div>
     <div class="app-bar-headline"><h1 class="app-bar-title">Title</h1><p class="app-bar-subtitle">Subtitle</p></div>
   </header>
   small 64 (title-large) · medium flexible 112 / 136 with subtitle
   (headline-medium) · large flexible 120 / 152 with subtitle (display-small).
   .app-bar-scrolled switches to surface-container (m3-components.js adds it
   on scroll for [data-m3-app-bar]). */
.app-bar {
  --md-app-bar-title: title-large;
  display: flex;
  flex-direction: column;
  background-color: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
  transition: background-color var(--md-motion-default-effects);
}
.app-bar-scrolled { background-color: var(--md-sys-color-surface-container); }
.app-bar-row { display: flex; align-items: center; gap: 4px; height: 64px; padding-inline: 4px; }
.app-bar-row > .app-bar-title { flex: 1; min-width: 0; padding-inline: 12px 4px; }
.app-bar-row > .btn-icon:first-child { --md-btn-content: var(--md-sys-color-on-surface); }
.app-bar-actions { display: flex; align-items: center; margin-left: auto; }
.app-bar-actions .btn-icon { --md-btn-content: var(--md-sys-color-on-surface-variant); }
.app-bar-title {
  margin: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-title-large-font);
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  font-weight: var(--md-sys-typescale-title-large-weight);
}
.app-bar-subtitle {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-label-medium-font);
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line-height);
  font-weight: var(--md-sys-typescale-label-medium-weight);
}
.app-bar-headline { display: flex; flex-direction: column; justify-content: flex-end; padding: 0 16px 12px; }
.app-bar-medium .app-bar-headline { min-height: 48px; }
.app-bar-medium:has(.app-bar-subtitle) .app-bar-headline { min-height: 72px; }
.app-bar-large .app-bar-headline { min-height: 56px; }
.app-bar-large:has(.app-bar-subtitle) .app-bar-headline { min-height: 88px; }
.app-bar-medium .app-bar-headline .app-bar-title {
  white-space: normal;
  font-family: var(--md-sys-typescale-headline-medium-font);
  font-size: var(--md-sys-typescale-headline-medium-size);
  line-height: var(--md-sys-typescale-headline-medium-line-height);
  font-weight: var(--md-sys-typescale-headline-medium-weight);
}
.app-bar-medium .app-bar-subtitle {
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  font-weight: var(--md-sys-typescale-label-large-weight);
}
.app-bar-large .app-bar-headline .app-bar-title {
  white-space: normal;
  font-family: var(--md-sys-typescale-display-small-font);
  font-size: var(--md-sys-typescale-display-small-size);
  line-height: var(--md-sys-typescale-display-small-line-height);
  font-weight: var(--md-sys-typescale-display-small-weight);
}
.app-bar-large .app-bar-subtitle {
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
/* Collapse on scroll (Compose exitUntilCollapsed): data-m3-app-bar="collapse"
   on a medium/large bar, plus a small .app-bar-title in its top row.
   m3-components.js measures the headline into --md-app-bar-range; the bar
   then sticks at minus that height while its top row sticks at 0, so the
   headline slides up beneath the row. The script's collapsed fraction fades
   the headline out, fades the small title in (TopTitleAlphaEasing) and
   blends the container to surface-container. Without the script the bar is
   static and the small title stays hidden. */
.app-bar-medium > .app-bar-row > .app-bar-title,
.app-bar-large > .app-bar-row > .app-bar-title { opacity: var(--md-app-bar-title-alpha, 0); }
.app-bar.md-js-app-bar {
  position: sticky;
  top: calc(-1 * var(--md-app-bar-range, 0px));
  z-index: 2;
  background-color: color-mix(in srgb, var(--md-sys-color-surface-container) var(--md-app-bar-scrolled, 0%), var(--md-sys-color-surface));
  transition: none;
}
.md-js-app-bar > .app-bar-row { position: sticky; top: 0; z-index: 1; background-color: inherit; }
.md-js-app-bar > .app-bar-headline { opacity: calc(1 - var(--md-app-bar-f, 0)); }

/* ---- Expressive menus (SegmentedMenuTokens / StandardMenuTokens) ----
   <div class="dropdown-menu menu-expressive">
     <div class="menu-group"> <a class="dropdown-item">…</a> … </div>
     <div class="menu-group"> … </div>
   </div>
   Groups sit 2px apart on surface-container-low (16px outer corners, 4px
   between groups). Items have 4px corners, 12px at the group's ends and
   when selected; selected = tertiary-container. Add .menu-vibrant for
   the tertiary-container menu. */
.dropdown-menu.menu-expressive {
  --md-menu-bg: var(--md-sys-color-surface-container-low);
  --md-menu-text: var(--md-sys-color-on-surface);
  --md-menu-icon: var(--md-sys-color-on-surface-variant);
  --md-menu-selected-bg: var(--md-sys-color-tertiary-container);
  --md-menu-selected-text: var(--md-sys-color-on-tertiary-container);
  --bs-dropdown-padding-y: 0;
  --bs-dropdown-bg: transparent;
  --bs-dropdown-box-shadow: none;
  --bs-dropdown-item-padding-y: 10px;
  --bs-dropdown-item-padding-x: 16px;
  --bs-dropdown-font-size: var(--md-sys-typescale-body-large-size);
  --bs-dropdown-link-color: var(--md-menu-text);
  --bs-dropdown-link-hover-color: var(--md-menu-text);
  --bs-dropdown-link-hover-bg: color-mix(in srgb, var(--md-menu-text) var(--md-sys-state-hover-state-layer-opacity), transparent);
  --bs-dropdown-link-active-color: var(--md-menu-selected-text);
  --bs-dropdown-link-active-bg: var(--md-menu-selected-bg);
  overflow: visible;
}
.dropdown-menu.menu-expressive.show { display: flex; flex-direction: column; gap: 2px; }
.menu-vibrant {
  --md-menu-bg: var(--md-sys-color-tertiary-container);
  --md-menu-text: var(--md-sys-color-on-tertiary-container);
  --md-menu-icon: var(--md-sys-color-on-tertiary-container);
  --md-menu-selected-bg: var(--md-sys-color-tertiary);
  --md-menu-selected-text: var(--md-sys-color-on-tertiary);
}
/* Group corners (SegmentedMenuTokens): 16px at the menu's outer ends, 8px
   between groups. When you move into a submenu, the menu you came from
   tightens to 8px all round ("inactive"), so the active menu stands out. */
.menu-group {
  --md-group-outer: var(--md-sys-shape-corner-large);
  --md-group-inner: var(--md-sys-shape-corner-small);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px;
  border-radius: var(--md-group-inner);
  background-color: var(--md-menu-bg);
  box-shadow: var(--md-sys-elevation-level2);
  transition: border-radius var(--md-motion-fast-spatial);
}
.menu-group:first-child { border-top-left-radius: var(--md-group-outer); border-top-right-radius: var(--md-group-outer); }
.menu-group:last-child { border-bottom-left-radius: var(--md-group-outer); border-bottom-right-radius: var(--md-group-outer); }
.menu-expressive.md-menu-inactive > .menu-group { --md-group-outer: var(--md-sys-shape-corner-small); }
.menu-group > .dropdown-item,
.menu-group > .dropdown-submenu > .dropdown-item {
  min-height: 44px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  font-size: var(--md-sys-typescale-body-large-size);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
  transition: border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects);
}
.menu-group > .dropdown-item:first-child,
.menu-group > .dropdown-submenu:first-child > .dropdown-item { border-top-left-radius: var(--md-sys-shape-corner-medium); border-top-right-radius: var(--md-sys-shape-corner-medium); }
.menu-group > .dropdown-item:last-child,
.menu-group > .dropdown-submenu:last-child > .dropdown-item { border-bottom-left-radius: var(--md-sys-shape-corner-medium); border-bottom-right-radius: var(--md-sys-shape-corner-medium); }
.menu-group > .dropdown-item.active,
.menu-group > .dropdown-submenu > .dropdown-item.active { border-radius: var(--md-sys-shape-corner-medium); }
.menu-group .dropdown-item > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: 20px; color: var(--md-menu-icon); }
.menu-group .dropdown-item.active > :is(.material-symbols-rounded, .material-symbols-outlined) { color: inherit; font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }
.menu-group > .dropdown-header { padding: 8px 16px 4px; color: var(--md-menu-icon); }

/* --------------------------------------------------------------------------
   Cascading submenus (any depth). Wrap the item and its menu:
     <div class="dropdown-submenu">            (an <li> in <ul> menus)
       <a class="dropdown-item" href="#">Create</a>
       <div class="dropdown-menu"> …items, or more .dropdown-submenu… </div>
     </div>
   Works in standard and .menu-expressive menus (inside a .menu-group).
   The submenu opens beside its item, top-aligned, and flips left/up when
   it would leave the screen. js/m3-components.js adds hover-intent,
   click/tap, arrow keys, Escape, flipping and the active-menu shape morph;
   without it, submenus still open on hover and keyboard focus.
   -------------------------------------------------------------------------- */
.dropdown-submenu { position: relative; list-style: none; }
.dropdown-menu:has(.dropdown-submenu) { overflow: visible; }
.dropdown-submenu > .dropdown-menu {
  --md-sub-gap: 2px;
  position: absolute;
  top: 0;
  left: calc(100% + var(--md-sub-gap));
  right: auto;
  margin: 0;
  transform-origin: top left;
}
.menu-group > .dropdown-submenu > .dropdown-menu { --md-sub-gap: 8px; top: -4px; }
.dropdown-submenu > .dropdown-menu.md-sub-left { left: auto; right: calc(100% + var(--md-sub-gap)); transform-origin: top right; }
.dropdown-submenu > .dropdown-menu.md-sub-up { top: auto; bottom: 0; transform-origin: bottom left; }
.dropdown-submenu > .dropdown-menu.md-sub-left.md-sub-up { transform-origin: bottom right; }
/* Trailing ▸ on the parent item (drawn, so no icon markup is needed) */
.dropdown-submenu > .dropdown-item::after {
  content: "";
  flex: none;
  width: 20px;
  height: 20px;
  margin-left: auto;
  margin-right: -4px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 17l5-5-5-5z'/%3E%3C/svg%3E") center / 20px 20px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 17l5-5-5-5z'/%3E%3C/svg%3E") center / 20px 20px no-repeat;
  opacity: .8;
}
/* Parent item stays highlighted while its submenu is open ("active") */
.dropdown-submenu > .dropdown-item.md-submenu-open {
  background-color: color-mix(in srgb, var(--md-menu-text, var(--md-sys-color-on-surface)) var(--md-sys-state-focus-state-layer-opacity), transparent);
  color: var(--md-menu-text, var(--md-sys-color-on-surface));
}
.dropdown-submenu > .dropdown-item.md-submenu-open.active { background-color: var(--md-menu-selected-bg, var(--bs-dropdown-link-active-bg)); color: var(--md-menu-selected-text, var(--bs-dropdown-link-active-color)); }
/* No-JS fallback: open on hover / keyboard focus */
html:not(.md-submenus-js) .dropdown-submenu:is(:hover, :focus-within) > .dropdown-menu { display: block; }
html:not(.md-submenus-js) .dropdown-submenu:is(:hover, :focus-within) > .dropdown-menu.menu-expressive { display: flex; flex-direction: column; gap: 2px; }

/* ---- Segmented lists (ListTokens, Expressive) ----
   Add .list-group-segmented to a .list-group: items 2px apart, 4px corners
   (16px at the list's ends) that morph to 12px on hover and 16px when
   pressed, focused or selected; selected = secondary-container.
   Note: Compose's item color is `surface`; on a surface page that makes the
   items invisible, so this uses surface-container-low unless overridden via
   --md-list-item-bg. */
.list-group-segmented {
  --md-list-item-bg: var(--md-sys-color-surface-container-low);
  gap: 2px;
  border-radius: 0;
}
.list-group-segmented > .list-group-item {
  border: 0;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background-color: var(--md-list-item-bg);
  padding-block: 10px;
  transition: border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects);
}
.list-group-segmented > .list-group-item:first-child { border-top-left-radius: var(--md-sys-shape-corner-large); border-top-right-radius: var(--md-sys-shape-corner-large); }
.list-group-segmented > .list-group-item:last-child { border-bottom-left-radius: var(--md-sys-shape-corner-large); border-bottom-right-radius: var(--md-sys-shape-corner-large); }
.list-group-segmented > .list-group-item-action:hover { border-radius: var(--md-sys-shape-corner-medium); background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-list-item-bg)); }
.list-group-segmented > .list-group-item:is(:active, :focus-visible, .active) { border-radius: var(--md-sys-shape-corner-large); }
.list-group-segmented > .list-group-item.active { background-color: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.list-group-segmented > .list-group-item + .list-group-item { border-top-width: 0; }

/* ==========================================================================
   11c. More Expressive components: switch icons, chips, secondary tabs,
        navigation drawer, FAB menu (Compose tokens)
   ========================================================================== */

/* ---- Switch with handle icons (SwitchTokens): add .form-switch-icons to the
   .form-switch wrapper. The handle is 24px even when off, and carries a 16px
   check (on, on-primary-container) or close (off, surface-container-highest)
   icon that rides along with it. */
.form-switch-icons .form-check-input { --md-switch-r: 12px; --md-switch-icon: var(--md-icon-switch-close); }
.form-switch-icons .form-check-input:checked { --md-switch-icon: var(--md-icon-switch-check); }
.form-switch-icons .form-check-input:disabled { --md-switch-icon: var(--md-icon-switch-close-disabled); }
.form-switch-icons .form-check-input:checked:disabled { --md-switch-icon: var(--md-icon-switch-check-disabled); }
.form-switch-icons .form-check-input,
.form-switch-icons .form-check-input:focus,
.form-switch-icons .form-check-input:checked,
[data-bs-theme] .form-switch-icons .form-check-input:not(:checked):not(:focus) {
  background-image: var(--md-switch-icon),
                    radial-gradient(circle at var(--md-js-switch-x, var(--md-switch-x)) 50%,
                      var(--md-switch-handle) calc(var(--md-js-switch-r, var(--md-switch-r)) - .5px),
                      transparent var(--md-js-switch-r, var(--md-switch-r)));
  background-size: 16px 16px, 100% 100%;
  background-position: calc(var(--md-js-switch-x, var(--md-switch-x)) - 8px) 50%, 0 0;
  background-repeat: no-repeat;
}

/* ---- Shape-morphing chips (ChipsTokens): add .chip-morph to a chip.
   12px corners → fully round when selected → 8px while pressed. */
.chip { transition: background-color var(--md-motion-default-effects), border-radius var(--md-motion-fast-spatial); }
.chip-morph { border-radius: var(--md-sys-shape-corner-medium); }
.chip-morph.active, .btn-check:checked + .chip-morph { border-radius: 16px; }
.chip-morph:active { border-radius: var(--md-sys-shape-corner-small); }

/* ---- Input chips (InputChipTokens): avatar and remove button.
   <span class="chip chip-input"><img class="chip-avatar" src alt> Ana
     <button class="chip-remove" aria-label="Remove Ana">…close…</button></span> */
.chip-input { cursor: default; gap: 8px; }
.chip:has(> .chip-avatar) { padding-left: 4px; }
.chip:has(> .chip-remove) { padding-right: 8px; }
.chip-avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; flex: none; }
.chip-remove {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--md-sys-color-on-surface-variant);
  cursor: pointer;
}
.chip-remove > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: 18px; }
.chip-remove:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.chip-remove:focus-visible { outline: var(--md-focus-ring); outline-offset: 1px; }
.chip-input.active .chip-remove, .btn-check:checked + .chip-input .chip-remove { color: var(--md-sys-color-on-secondary-container); }

/* ---- Secondary tabs (SecondaryNavigationTabTokens): add .nav-tabs-secondary
   to .nav-tabs. on-surface active label, 2px primary indicator spanning the
   whole tab, surface-variant divider. */
.nav-tabs-secondary { --bs-nav-tabs-link-active-color: var(--md-sys-color-on-surface); }
.nav-tabs-secondary .nav-link { font-family: var(--md-sys-typescale-title-small-font); font-weight: var(--md-sys-typescale-title-small-weight); }
.nav-tabs-secondary .nav-link.active::after { left: 0; right: 0; height: 2px; border-radius: 0; }

/* Sliding tab indicator (with js/m3-components.js). The script writes the
   active tab's position to --md-tab-x / --md-tab-w / --md-tab-bottom on the
   .nav-tabs; one indicator on the row then slides there on the
   default-spatial spring. Primary tabs: 3px, rounded top, content width.
   Secondary: 2px, full tab width. */
.nav-tabs.md-js-tabs { position: relative; }
.nav-tabs.md-js-tabs .nav-link.active::after { display: none; }
.nav-tabs.md-js-tabs::after {
  content: "";
  position: absolute;
  top: var(--md-tab-bottom, 100%);
  left: 0;
  width: var(--md-tab-w, 0px);
  height: 3px;
  translate: var(--md-tab-x, 0px) -100%;
  border-radius: 3px 3px 0 0;
  background-color: var(--md-sys-color-primary);
  pointer-events: none;
  transition: translate var(--md-motion-default-spatial), width var(--md-motion-default-spatial), top var(--md-motion-default-spatial);
}
.nav-tabs-secondary.md-js-tabs::after { height: 2px; border-radius: 0; }
.nav-tabs.md-js-tabs.md-tabs-instant::after { transition: none; }

/* ---- Navigation drawer (NavigationDrawerTokens)
   <nav class="nav-drawer">
     <h2 class="nav-drawer-headline">Mail</h2>
     <a class="nav-drawer-item active" href="#" aria-current="page">
       <span class="material-symbols-rounded">inbox</span>Inbox<span class="nav-drawer-badge">24</span></a>
     <hr class="nav-drawer-divider"> …
   </nav>
   Standard: in the page, on surface. Modal: put it in an
   .offcanvas.offcanvas-start.nav-drawer-modal (surface-container-low,
   large end corners, 360px). */
.nav-drawer {
  display: flex;
  flex-direction: column;
  width: 360px;
  max-width: 100%;
  padding: 12px;
  background-color: var(--md-sys-color-surface);
}
.nav-drawer-modal { --bs-offcanvas-width: min(360px, calc(100vw - 56px)); --bs-offcanvas-bg: var(--md-sys-color-surface-container-low); border-right: 0 !important; }
.nav-drawer-modal .nav-drawer { width: 100%; background: none; }
.nav-drawer-headline {
  margin: 0;
  padding: 18px 16px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-title-small-font);
  font-size: var(--md-sys-typescale-title-small-size);
  line-height: var(--md-sys-typescale-title-small-line-height);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
.nav-drawer-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 0 24px 0 16px;
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-sys-color-on-surface-variant);
  text-decoration: none;
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  transition: background-color var(--md-motion-fast-effects), color var(--md-motion-fast-effects);
}
.nav-drawer-item > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: 24px; transition: font-variation-settings var(--md-motion-fast-effects); }
.nav-drawer-item:hover { color: var(--md-sys-color-on-surface); background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.nav-drawer-item:active { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity), transparent); }
.nav-drawer-item:focus-visible { outline: var(--md-focus-ring); outline-offset: -3px; }
.nav-drawer-item:is(.active, [aria-current="page"]) { background-color: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.nav-drawer-item:is(.active, [aria-current="page"]):hover { background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-secondary-container)); }
.nav-drawer-item:is(.active, [aria-current="page"]) > :is(.material-symbols-rounded, .material-symbols-outlined) { font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }
.nav-drawer-badge { margin-left: auto; color: inherit; }
.nav-drawer-divider { margin: 8px 16px; }

/* Sliding active indicator (with js/m3-components.js), as in the M3
   Expressive demos: one secondary-container pill that glides to the newly
   active item on the fast-spatial spring (it overshoots ~10%) instead of
   each item filling in place. The script writes the active item's box to
   --md-drawer-x/-y/-w/-h on the .nav-drawer. */
.nav-drawer.md-js-drawer { position: relative; }
.nav-drawer.md-js-drawer::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: var(--md-drawer-w, 0px);
  height: var(--md-drawer-h, 56px);
  translate: var(--md-drawer-x, 0px) var(--md-drawer-y, 0px);
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-secondary-container);
  opacity: var(--md-drawer-on, 0);
  pointer-events: none;
  will-change: translate;
  transition: translate var(--md-motion-fast-spatial), width var(--md-motion-fast-spatial), height var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
.nav-drawer.md-js-drawer.md-drawer-instant::before { transition: none; }
/* The active item shows no hover layer of its own: it would appear in place
   the instant you click, and the pill would then slide in under it, so you'd
   briefly see two pills. Inactive items keep their hover. */
.nav-drawer.md-js-drawer .nav-drawer-item:is(.active, [aria-current="page"]),
.nav-drawer.md-js-drawer .nav-drawer-item:is(.active, [aria-current="page"]):hover { background-color: transparent; }

/* ---- Date picker, docked (M3 docked date picker spec + Compose DatePicker,
   DatePickerModalTokens). Built by js/m3-pickers.js from
   <input type="text" class="form-control" data-m3-datepicker> in a .form-floating.
   360 x 460, surface-container-high, large corners: a header with month and
   year menus, weekdays, six 48px rows of 40px day circles, Cancel / OK. */
.datepicker-field { position: relative; }
.datepicker-field > .form-control { padding-right: 52px; }
.datepicker-toggle.btn-icon { position: absolute; z-index: 3; top: 8px; right: 4px; }
.datepicker {
  position: absolute;
  z-index: 1060;
  top: calc(100% + 4px);
  left: 0;
  display: flex;
  flex-direction: column;
  width: 360px;
  max-width: calc(100vw - 16px);
  padding: 20px 12px 12px;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-sys-elevation-level3);
  transform-origin: top left;
  transition: scale var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
@starting-style { .datepicker { scale: .8; opacity: 0; } }
.datepicker.datepicker-above { top: auto; bottom: calc(100% + 4px); transform-origin: bottom left; }
.datepicker.md-closing { scale: .8; opacity: 0; pointer-events: none;
  transition: scale 200ms cubic-bezier(0.3, 0, 0.8, 0.15), opacity 200ms cubic-bezier(0.3, 0, 0.8, 0.15); }

/* Header: [< Aug v >]  [< 2025 v >] */
.datepicker-header { display: flex; align-items: center; justify-content: space-between; height: 24px; margin-bottom: 30px; }
.datepicker-nav { display: flex; align-items: center; }
.datepicker-header .btn-icon { --md-btn-height: 40px; margin: -8px 0; }
.datepicker-header .btn-icon > .material-symbols-rounded { font-size: 24px; }
.datepicker-menu-btn.btn-text {
  --md-btn-content: var(--md-sys-color-on-surface-variant);
  --md-btn-height: 40px;
  gap: 4px;
  margin: -8px 0;
  padding: 0 4px 0 8px;
}
.datepicker-menu-btn > .material-symbols-rounded { font-size: 18px; transition: rotate var(--md-motion-fast-spatial); }
.datepicker-menu-btn[aria-expanded="true"] > .material-symbols-rounded { rotate: 180deg; }

/* Weekdays + days */
.datepicker-body { position: relative; }
.datepicker-weekdays, .datepicker-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.datepicker-weekdays { height: 24px; margin-bottom: 16px; }
.datepicker-weekdays > span {
  display: grid;
  place-items: center;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
}
.datepicker-months { position: relative; height: 290px; overflow: hidden; }  /* six rows, M3 total height 460 */
.datepicker-grid { position: absolute; inset: 0; grid-template-rows: repeat(6, 1fr); }
.datepicker-day {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: transparent;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: 1;
  cursor: pointer;
  overflow: hidden;
  transition: background-color var(--md-motion-default-effects), color var(--md-motion-default-effects);
}
.datepicker-day:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.datepicker-day:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.datepicker-day.is-outside { color: var(--md-sys-color-on-surface-variant); opacity: .6; }
.datepicker-day.is-today { color: var(--md-sys-color-primary); box-shadow: inset 0 0 0 1px var(--md-sys-color-primary); }
.datepicker-day[aria-selected="true"] { background-color: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); opacity: 1; box-shadow: none; }
.datepicker-day[aria-selected="true"]:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-primary) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-primary)); }
.datepicker-day:disabled { color: var(--md-sys-color-on-surface); opacity: .38; cursor: default; background-color: transparent; }

/* Month / year list: grows down over the calendar (Compose: expandVertically
   + fade from 0.6 on default-effects; shrinks and fades out on close) */
.datepicker-list {
  position: absolute;
  z-index: 2;
  inset: 0;
  margin: 0 -12px;
  padding: 8px 0;
  overflow-y: auto;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  background-color: var(--md-sys-color-surface-container-high);
  clip-path: inset(0 0 0 0);
  transition: clip-path var(--md-motion-default-effects), opacity var(--md-motion-default-effects);
}
@starting-style { .datepicker-list { clip-path: inset(0 0 100% 0); opacity: .6; } }
.datepicker-list.md-closing { clip-path: inset(0 0 100% 0); opacity: 0; pointer-events: none;
  transition: clip-path var(--md-motion-default-effects), opacity var(--md-motion-fast-effects); }
.datepicker-list-item {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  border: 0;
  background: none;
  color: var(--md-sys-color-on-surface);
  text-align: left;
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  cursor: pointer;
}
.datepicker-list-item > .material-symbols-rounded { width: 24px; font-size: 24px; visibility: hidden; }
.datepicker-list-item[aria-selected="true"] { background-color: var(--md-sys-color-surface-variant); }
.datepicker-list-item[aria-selected="true"] > .material-symbols-rounded { visibility: visible; }
.datepicker-list-item:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.datepicker-list-item:focus-visible { outline: var(--md-focus-ring); outline-offset: -3px; }

.datepicker-actions { display: flex; justify-content: flex-end; gap: 8px; height: 36px; margin-top: 8px; }
.datepicker-actions .btn { --md-btn-height: 36px; }

/* ---- Date picker, modal + date range (Compose DatePicker in a
   DatePickerDialog, DateRangePicker; DatePickerModalTokens). Bootstrap modals
   built by js/m3-pickers.js. */
.modal-dialog.dp-modal-dialog { width: 360px; max-width: calc(100% - var(--bs-modal-margin) * 2); }
/* the range picker goes full screen on phones (Bootstrap's -sm-down breakpoint) */
@media (max-width: 575.98px) { .modal-dialog.dp-modal-dialog.modal-fullscreen-sm-down { width: 100vw; max-width: none; } }
.dp-modal .modal-content { overflow: hidden; }
.dp-head { padding: 16px 12px 12px 24px; color: var(--md-sys-color-on-surface-variant); }
.dp-title {
  margin: 0 0 32px;  /* header = 120px: 16 + 20 title + 32 + 40 headline + 12 */
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  font-weight: var(--md-sys-typescale-label-large-weight);
}
.dp-headline-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dp-headline {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-headline-large-font);
  font-size: var(--md-sys-typescale-headline-large-size);
  line-height: var(--md-sys-typescale-headline-large-line-height);
  font-weight: var(--md-sys-typescale-headline-large-weight);
}
.dp-divider { margin: 0; border: 0; border-top: 1px solid var(--md-sys-color-outline-variant); opacity: 1; }
.dp-stage { position: relative; overflow: hidden; }
.dp-nav { display: flex; align-items: center; justify-content: space-between; height: 56px; padding: 0 12px 0 16px; }
.dp-year-btn.btn-text { --md-btn-content: var(--md-sys-color-on-surface-variant); gap: 4px; padding: 0 8px 0 8px; }
.dp-year-btn > .material-symbols-rounded { font-size: 18px; transition: rotate var(--md-motion-fast-spatial); }
.dp-year-btn[aria-expanded="true"] > .material-symbols-rounded { rotate: 180deg; }
.dp-calendar { position: relative; padding: 0 12px; }
.dp-calendar .datepicker-weekdays { margin-bottom: 0; height: 48px; }
.dp-calendar .datepicker-months { height: 288px; }
.dp-years {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 36px;
  row-gap: 16px;
  align-content: start;
  padding: 16px 12px;
  overflow-y: auto;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  background-color: var(--md-sys-color-surface-container-high);
  clip-path: inset(0 0 0 0);
  transition: clip-path var(--md-motion-default-effects), opacity var(--md-motion-default-effects);
}
@starting-style { .dp-years { clip-path: inset(0 0 100% 0); opacity: .6; } }
.dp-years.md-closing { clip-path: inset(0 0 100% 0); opacity: 0; pointer-events: none; transition: clip-path var(--md-motion-default-effects), opacity var(--md-motion-fast-effects); }
.dp-year {
  justify-self: center;
  width: 72px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--md-sys-shape-corner-full);
  background: none;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  cursor: pointer;
  overflow: hidden;
  transition: background-color var(--md-motion-default-effects), color var(--md-motion-default-effects);
}
.dp-year:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) var(--md-sys-state-hover-state-layer-opacity), transparent); }
.dp-year.is-current { color: var(--md-sys-color-primary); box-shadow: inset 0 0 0 1px var(--md-sys-color-primary); }
.dp-year[aria-selected="true"] { background-color: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); box-shadow: none; }
.dp-year:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.dp-year:disabled { opacity: .38; cursor: default; }
.dp-input { padding: 16px 24px 8px; }
.dp-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 0 6px 8px; }  /* Compose DialogButtonsPadding */

/* Range (DateRangePicker): full screen on phones, 568px dialog elsewhere */
.dp-range .modal-content { display: flex; flex-direction: column; }
@media (min-width: 576px) { .dp-range .modal-content { height: min(568px, calc(100vh - var(--bs-modal-margin) * 2)); } }
.dp-range-bar { display: flex; flex: none; align-items: center; justify-content: space-between; height: 56px; padding: 0 12px 0 4px; }
.dp-range .dp-head { padding: 0 12px 12px 64px; }
.dp-range .dp-title { margin-bottom: 16px; }
/* As a rounded dialog (576px and up) the bar needs room from the 28px
   corners; full screen on phones it sits flush like an app bar. */
@media (min-width: 576px) {
  .dp-range-bar { height: 64px; padding: 12px 16px 0 12px; }
  .dp-range .dp-head { padding-left: 72px; }
}
.dp-range .dp-headline {
  font-family: var(--md-sys-typescale-title-large-font);
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  font-weight: var(--md-sys-typescale-title-large-weight);
}
.dp-range .datepicker-weekdays { flex: none; height: 48px; margin: 0; padding: 0 12px; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.dp-range-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 12px 16px; overscroll-behavior: contain; }
.dp-range-month-title {
  margin: 0;
  padding: 20px 12px 8px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-title-small-font);
  font-size: var(--md-sys-typescale-title-small-size);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
.dp-range-grid { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: 48px; }
.dp-cell { position: relative; display: grid; place-items: center; }
/* the in-range strip: 40px tall, from the middle of the start day to the
   middle of the end day, square at the ends of each week row */
.dp-cell::before { content: ""; position: absolute; top: 4px; bottom: 4px; left: 0; right: 0; background-color: var(--md-sys-color-secondary-container); opacity: 0; transition: opacity var(--md-motion-default-effects); }
.dp-cell.in-range::before { opacity: 1; }
.dp-cell.range-start::before { left: 50%; }
.dp-cell.range-end::before { right: 50%; }
.dp-cell.in-range > .datepicker-day:not([aria-selected="true"]) { color: var(--md-sys-color-on-secondary-container); }
.dp-cell > .datepicker-day { z-index: 1; }
.dp-range .dp-input { display: grid; gap: 16px; }
.dp-range-stage, .dp-range-pane { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.dp-range-pane[hidden], .dp-pane-input[hidden], .dp-pane-calendar[hidden] { display: none; }

/* ---- Time picker (Compose TimePicker / TimeInput, vibrant style, in a
   VibrantTimePickerDialog; TimePickerTokens). A Bootstrap modal built by
   js/m3-pickers.js from <input type="text" class="form-control" data-m3-timepicker>.
   Surface-container, extra-large corners, 12px padding: 100x120 hour and
   minute fields (surface-container-lowest, large corners, display-large; the
   active one primary with a 2px primary outline), a 56x120 AM/PM toggle,
   the 256px dial, then keyboard / Cancel / OK. */
@property --tp-a { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
@property --tp-r { syntax: '<length>'; inherits: true; initial-value: 101px; }
.modal-dialog.dp-modal-dialog.tp-dialog { width: fit-content; }
.tp-modal .modal-content { --bs-modal-bg: var(--md-sys-color-surface-container); padding: 12px; }
.tp {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas: "time period" "error error" "dial dial";
  justify-content: center;
  --tp-pill: 28px;
}
.tp [hidden] { display: none !important; }
.tp-time { grid-area: time; display: flex; }
.tp-field {
  display: grid;
  place-items: center;
  width: 100px;
  height: 120px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-lowest);
  box-shadow: inset 0 0 0 2px transparent;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-display-large-font);
  font-size: var(--md-sys-typescale-display-large-size);
  line-height: var(--md-sys-typescale-display-large-line-height);
  font-weight: var(--md-sys-typescale-display-large-weight);
  letter-spacing: var(--md-sys-typescale-display-large-tracking);
  text-align: center;
  font-variant-numeric: tabular-nums;
  transition: color var(--md-motion-fast-effects), box-shadow var(--md-motion-fast-effects), background-color var(--md-motion-fast-effects);
}
.tp-24h .tp-field { width: 132px; }
/* TimeInput and TimeScroll keep 100px fields and an 8px gap before AM/PM */
.tp-typing .tp-field, .tp-scroll .tp-field { width: 100px; }
.tp-typing .tp-period, .tp-scroll .tp-period { margin-left: 8px; }
button.tp-field { cursor: pointer; }
button.tp-field:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-lowest)); }
button.tp-field:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.tp-field[aria-checked="true"], .tp-field-input:focus {
  color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 2px var(--md-sys-color-primary);
}
.tp-field-input { outline: none; caret-color: var(--md-sys-color-primary); }
.tp-field-input.is-invalid {
  background-color: var(--md-sys-color-error-container);
  box-shadow: inset 0 0 0 2px var(--md-sys-color-error);
  color: var(--md-sys-color-on-error-container);
  caret-color: var(--md-sys-color-error);
}
.tp-sep {
  display: grid;
  place-items: center;
  width: 16px;
  translate: 0 -4px;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-display-large-font);
  font-size: var(--md-sys-typescale-display-large-size);
  user-select: none;
}
/* AM / PM: two toggle buttons 8px apart, pills that square to 12px corners
   when checked (Compose ToggleItem: CircleShape -> RoundedCornerShape(12)) */
.tp-period { grid-area: period; display: flex; flex-direction: column; gap: 8px; width: 56px; height: 120px; margin-left: 16px; }
.tp-period-btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 0 4px;
  border: 0;
  border-radius: var(--tp-pill);
  background-color: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  font-weight: var(--md-sys-typescale-title-medium-weight);
  cursor: pointer;
  transition: border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects), color var(--md-motion-fast-effects);
}
.tp-period-btn:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-lowest)); }
.tp-period-btn:active { border-radius: 12px; }
.tp-period-btn:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.tp-period-btn[aria-checked="true"] {
  border-radius: 12px;
  background-color: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  font-weight: 700;
}
.tp-error {
  grid-area: error;
  margin: 8px 0 0;
  color: var(--md-sys-color-error);
  font-family: var(--md-sys-typescale-body-small-font);
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line-height);
}
/* The dial collapses away when typing (rows 1fr -> 0fr) */
.tp-dial-wrap {
  grid-area: dial;
  display: grid;
  grid-template-rows: 1fr;
  justify-items: center;
  margin-top: 12px;
  transition: grid-template-rows var(--md-motion-default-spatial), margin-top var(--md-motion-default-spatial), opacity var(--md-motion-fast-effects);
}
.tp-typing .tp-dial-wrap { grid-template-rows: 0fr; margin-top: 0; opacity: 0; }
.tp-dial-inner { min-height: 0; overflow: hidden; }
.tp-dial {
  position: relative;
  width: 256px;
  height: 256px;
  border-radius: 50%;
  background-color: var(--md-sys-color-surface-container-lowest);
  touch-action: none;
  user-select: none;
  cursor: pointer;
  transition: --tp-a var(--md-motion-default-spatial), --tp-r var(--md-motion-default-spatial);
}
.tp-dial.is-dragging { transition: none; }
.tp-dial:focus-visible { outline: var(--md-focus-ring); outline-offset: -3px; }
.tp-face { position: absolute; inset: 0; pointer-events: none; transition: opacity var(--md-motion-default-effects); }
.tp-face.is-off { opacity: 0; }
.tp-num {
  position: absolute;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: 1;
}
/* the hand: 8px center dot, 2px track, 48px handle at --tp-a / --tp-r */
.tp-hand { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle, var(--md-sys-color-primary) 4px, transparent 4.5px); }
.tp-hand::before {
  content: "";
  position: absolute;
  left: calc(50% - 1px);
  bottom: 50%;
  width: 2px;
  height: calc(var(--tp-r) - 24px);
  background-color: var(--md-sys-color-primary);
  transform-origin: 50% 100%;
  rotate: var(--tp-a);
}
.tp-hand::after {
  content: "";
  position: absolute;
  left: calc(50% - 24px);
  top: calc(50% - 24px);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background-color: var(--md-sys-color-primary);
  translate: calc(sin(var(--tp-a)) * var(--tp-r)) calc(cos(var(--tp-a)) * var(--tp-r) * -1);
}
.tp-face-on { clip-path: circle(24px at calc(50% + sin(var(--tp-a)) * var(--tp-r)) calc(50% - cos(var(--tp-a)) * var(--tp-r))); }
.tp-face-on .tp-num { color: var(--md-sys-color-on-primary); }
/* Scroll wheels (Compose ScrollField): 66.7px rows in the 100x120 field */
.tp-wheel {
  width: 100px;
  height: 120px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-lowest);
  cursor: grab;
  user-select: none;
}
.tp-wheel::-webkit-scrollbar { display: none; }
.tp-wheel.is-grabbing { scroll-snap-type: none; cursor: grabbing; }
.tp-wheel:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.tp-wheel-list { padding: calc((120px - 200px / 3) / 2) 0; }
.tp-wheel-item {
  display: grid;
  place-items: center;
  height: calc(200px / 3);
  scroll-snap-align: center;
  color: var(--md-sys-color-outline);
  font-family: var(--md-sys-typescale-display-medium-font);
  font-size: var(--md-sys-typescale-display-medium-size);
  line-height: var(--md-sys-typescale-display-medium-line-height);
  font-weight: var(--md-sys-typescale-display-medium-weight);
  font-variant-numeric: tabular-nums;
  transition: font-size var(--md-motion-fast-spatial), font-weight var(--md-motion-fast-spatial), color var(--md-motion-fast-spatial);
}
.tp-wheel-item.is-selected {
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-display-large-font);
  font-size: var(--md-sys-typescale-display-large-size);
  font-weight: var(--md-sys-typescale-display-large-emphasized-weight);
}
.tp-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.tp-actions-gap { flex: 1 1 auto; }

/* Short landscape screens: Compose's horizontal layout, the dial beside
   the time with a 216x40 AM/PM toggle under it */
@media (orientation: landscape) and (max-height: 500px) {
  .tp-modal .modal-content:has(> .tp:not(.tp-typing):not(.tp-scroll)) { padding: 12px 24px; }
  .tp:not(.tp-typing):not(.tp-scroll) { grid-template-areas: ". dial" "time dial" "period dial" "error dial"; grid-template-rows: 1fr auto auto 1fr; column-gap: 52px; }
  .tp:not(.tp-typing):not(.tp-scroll) + .tp-actions { margin-top: 24px; }
  .tp:not(.tp-typing):not(.tp-scroll) .tp-period { flex-direction: row; gap: 16px; width: 216px; height: 40px; margin: 16px 0 0; --tp-pill: 20px; }
  .tp:not(.tp-typing):not(.tp-scroll) .tp-dial-wrap { margin-top: 0; }
  .tp-24h .tp-field { width: 100px; }
}

/* ---- Color picker. Not an M3 component; built by js/m3-pickers.js from
   <input type="text" class="form-control" data-m3-colorpicker> out of M3
   parts: a docked surface like the date picker's (surface-container-high,
   large corners, level 3, menu motion), a saturation/brightness area, the
   Expressive slider for hue (16px track, 4px handle, 6px gaps), outlined
   fields, and swatches that morph from circles to 12px squares when chosen. */
/* see-through colors sit on a checkerboard */
.cp-toggle, .colorpicker { --cp-checker: repeating-conic-gradient(#cfcfcf 0 25%, #fff 0 50%) 0 0 / 8px 8px; }
.cp-toggle .cp-dot {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: linear-gradient(var(--cp-dot, transparent), var(--cp-dot, transparent)), var(--cp-checker);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 24%, transparent);
}
.cp-toggle .cp-dot.is-empty {
  background: linear-gradient(135deg, transparent calc(50% - 1px), var(--md-sys-color-outline) 0 calc(50% + 1px), transparent 0);
  box-shadow: inset 0 0 0 2px var(--md-sys-color-outline);
}
.cp-origin { position: fixed; top: 0; left: 0; width: 0; height: 0; pointer-events: none; }
.colorpicker {
  position: fixed;
  z-index: 1060;
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 360px;
  max-width: calc(100vw - 16px);
  padding: 16px;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-sys-elevation-level3);
  transform-origin: top left;
  transition: scale var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects);
}
@starting-style { .colorpicker { scale: .8; opacity: 0; } }
.colorpicker.colorpicker-above { transform-origin: bottom left; }
.colorpicker.md-closing { scale: .8; opacity: 0; pointer-events: none;
  transition: scale 200ms cubic-bezier(0.3, 0, 0.8, 0.15), opacity 200ms cubic-bezier(0.3, 0, 0.8, 0.15); }
.colorpicker-palette { width: auto; padding: 12px; }

/* 40px swatches 8px apart (48px apart center to center, the touch target),
   wrapping onto as many rows as the palette needs */
.cp-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.colorpicker-palette .cp-swatches { max-width: calc(var(--cp-cols, 6) * 48px - 8px); }
.cp-swatch {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 20px;
  background: linear-gradient(var(--cp-swatch), var(--cp-swatch)), var(--cp-checker);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 16%, transparent);
  color: var(--cp-on);
  cursor: pointer;
  transition: border-radius var(--md-motion-fast-spatial);
}
.cp-swatch::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background-color: currentColor; opacity: 0; transition: opacity var(--md-motion-fast-effects); }
.cp-swatch:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }
.cp-swatch:active { border-radius: 8px; }
.cp-swatch:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.cp-swatch > .material-symbols-rounded { font-size: 20px; scale: 0; transition: scale var(--md-motion-fast-spatial); }
.cp-swatch[aria-checked="true"] { border-radius: 12px; }
.cp-swatch[aria-checked="true"] > .material-symbols-rounded { scale: 1; }

.cp-area {
  position: relative;
  height: 192px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, rgb(255 255 255 / 0)), var(--cp-hue, red);
  touch-action: none;
  cursor: crosshair;
}
.cp-area:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.cp-area-handle {
  position: absolute;
  left: calc(var(--cp-s, 1) * 100%);
  top: calc((1 - var(--cp-v, 1)) * 100%);
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border-radius: 50%;
  background-color: var(--cp-color);
  box-shadow: 0 0 0 3px #fff, 0 0 0 4px rgb(0 0 0 / .24), var(--md-sys-elevation-level1);
  pointer-events: none;
  transition: scale var(--md-motion-fast-spatial);
}
.cp-area.is-dragging .cp-area-handle { scale: 1.2; }

.cp-hue-row { display: flex; align-items: center; gap: 8px; }
.cp-sliders { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.cp-slider { position: relative; height: 44px; touch-action: none; cursor: pointer; outline: none; }
/* the track, with a 16px window cut around the handle (4px + 6px each side) */
.cp-slider::before {
  --x: calc(2px + var(--cp-f, 0) * (100% - 4px));
  content: "";
  position: absolute;
  inset: 14px 0;
  border-radius: 8px;
  background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
  -webkit-mask: linear-gradient(to right, #000 calc(var(--x) - 8px), transparent 0 calc(var(--x) + 8px), #000 0);
  mask: linear-gradient(to right, #000 calc(var(--x) - 8px), transparent 0 calc(var(--x) + 8px), #000 0);
}
.cp-alpha::before { background: linear-gradient(to right, transparent, var(--cp-color)), var(--cp-checker); }
.cp-slider-handle {
  position: absolute;
  top: 0;
  left: calc(2px + var(--cp-f, 0) * (100% - 4px));
  width: 4px;
  height: 44px;
  margin-left: -2px;
  border-radius: 2px;
  background-color: var(--md-sys-color-primary);
  transition: width var(--md-motion-fast-spatial), margin var(--md-motion-fast-spatial);
}
/* Expressive slider handle narrows to 2px while held */
.cp-slider.is-dragging .cp-slider-handle { width: 2px; margin-left: -1px; }
.cp-slider:focus-visible .cp-slider-handle { outline: var(--md-focus-ring); outline-offset: 2px; }

.cp-modes { margin-bottom: -4px; }
.cp-fields { display: grid; grid-template-columns: 1fr repeat(3, 64px); gap: 8px; }
/* with alpha: hex on its own row, then the three channels and A */
.cp-fields.has-alpha { grid-template-columns: repeat(4, 1fr); }
.cp-fields.has-alpha .cp-hex-field { grid-column: 1 / -1; }
.cp-fields .form-control { padding-inline: 12px; font-variant-numeric: tabular-nums; }
.cp-fields .form-floating > label { padding-inline: 12px; }
.cp-hex { text-transform: uppercase; }
/* Below 600px the same panel sits in a dialog with Cancel / OK */
.cp-modal .colorpicker { position: static; width: auto; max-width: none; padding: 24px 24px 16px; background: none; box-shadow: none; scale: none; opacity: 1; transition: none; }
.cp-modal .colorpicker-palette .cp-swatches { max-width: none; justify-content: center; }
.cp-modal .cp-fields:not(.has-alpha) { grid-template-columns: repeat(3, 1fr); }
.cp-modal .cp-hex-field { grid-column: 1 / -1; }

/* ---- Imagery. M3 has no imagery component: images sit in shaped
   containers (cards, carousel items, headers) and text on them gets a
   scrim. These pieces collect that guidance.
   <div class="media ratio ratio-16x9">
     <img class="media-img" src="…" alt="…">
     <div class="media-text"><h3 class="md-title-large">Title</h3></div>
   </div> */
.media {
  position: relative;
  display: block;
  overflow: hidden;
  isolation: isolate;
  border-radius: inherit;
  background-color: var(--md-sys-color-surface-container-highest);
}
.media > .media-img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* in a card the card's shape does the clipping */
.card:has(> .media) { overflow: hidden; }
.card > .media { border-radius: 0; }

/* Text on an image. The scrim is black at 60% under the text (white text
   then clears 4.5:1 even over a pure white image) and fades out over the
   96px above it on an eased curve, so there's no visible edge or banding. */
.media-text {
  --md-scrim: rgb(0 0 0 / .6);
  --md-scrim-fade: 96px;
  position: absolute;
  inset: auto 0 0 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: calc(var(--md-scrim-fade) + 0px) 16px 16px;
  color: #fff;
  background: linear-gradient(to top,
    var(--md-scrim) calc(100% - var(--md-scrim-fade)),
    color-mix(in srgb, var(--md-scrim) 87%, transparent) calc(100% - var(--md-scrim-fade) * .86),
    color-mix(in srgb, var(--md-scrim) 69%, transparent) calc(100% - var(--md-scrim-fade) * .71),
    color-mix(in srgb, var(--md-scrim) 50%, transparent) calc(100% - var(--md-scrim-fade) * .57),
    color-mix(in srgb, var(--md-scrim) 31%, transparent) calc(100% - var(--md-scrim-fade) * .43),
    color-mix(in srgb, var(--md-scrim) 15%, transparent) calc(100% - var(--md-scrim-fade) * .29),
    color-mix(in srgb, var(--md-scrim) 4%, transparent) calc(100% - var(--md-scrim-fade) * .14),
    transparent 100%);
}
.media-text > * { margin: 0; }
.media-text :is(h1, h2, h3, h4, h5, h6, .card-title) { color: inherit; }
.media-text a:not(.btn) { color: inherit; }
.media-text-top {
  inset: 0 0 auto 0;
  padding: 16px 16px calc(var(--md-scrim-fade) + 0px);
  background: linear-gradient(to bottom,
    var(--md-scrim) calc(100% - var(--md-scrim-fade)),
    color-mix(in srgb, var(--md-scrim) 87%, transparent) calc(100% - var(--md-scrim-fade) * .86),
    color-mix(in srgb, var(--md-scrim) 69%, transparent) calc(100% - var(--md-scrim-fade) * .71),
    color-mix(in srgb, var(--md-scrim) 50%, transparent) calc(100% - var(--md-scrim-fade) * .57),
    color-mix(in srgb, var(--md-scrim) 31%, transparent) calc(100% - var(--md-scrim-fade) * .43),
    color-mix(in srgb, var(--md-scrim) 15%, transparent) calc(100% - var(--md-scrim-fade) * .29),
    color-mix(in srgb, var(--md-scrim) 4%, transparent) calc(100% - var(--md-scrim-fade) * .14),
    transparent 100%);
}
/* Bootstrap's .ratio stretches every child; the text keeps its own size */
.media.ratio > .media-text { top: auto; height: auto; }
.media.ratio > .media-text-top { top: 0; bottom: auto; }
.media.ratio > .media-text-fill { inset: 0; height: auto; }
/* the whole image dimmed, for centered text */
.media-text-fill { inset: 0; justify-content: center; align-items: center; padding: 16px; text-align: center; background: var(--md-scrim); }
/* a scrim in a dark tone of the image's own color instead of black */
.media-text-tinted { --md-scrim: oklch(from var(--md-image-color) .3 min(c, .1) h); }
/* Bootstrap's overlay gets the same treatment, bottom-aligned */
.card-img-overlay {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  color: #fff;
  background: linear-gradient(to top, rgb(0 0 0 / .6) 40%, rgb(0 0 0 / .27) 60%, transparent 85%);
}
.card-img-overlay .card-title, .card-img-overlay .card-text { color: inherit; }

/* Header images: tall, Expressive extra-large corners (drop them for full
   bleed with .rounded-0). .media-parallax lets the image drift slower than
   the page as it scrolls past: CSS scroll-driven animation, no JS; browsers
   without it, and reduced motion, show it still. */
.media-hero { height: clamp(240px, 45vh, 440px); border-radius: var(--md-sys-shape-corner-extra-large); }
.media-hero > .media-text { padding-inline: 24px; padding-bottom: 24px; }
@supports (animation-timeline: view()) {
  .media-parallax > .media-img {
    --md-parallax: 48px;
    height: calc(100% + var(--md-parallax) * 2);
    animation: md-parallax linear both;
    animation-timeline: view();
  }
  @keyframes md-parallax {
    from { translate: 0 calc(var(--md-parallax) * -2); }
    to { translate: 0 0; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .media-parallax > .media-img { height: 100%; animation: none; translate: none; }
}

/* Color from an image (M3 content-based color, the Spotify album page
   idea). --md-image-color comes from data-m3-image-color (js) or is set by
   hand; it fades in from neutral. Mixing it at most 35% into the theme's
   surfaces keeps on-surface text above 4.5:1 for any image, light or dark. */
@property --md-image-color { syntax: '<color>'; inherits: true; initial-value: #808080; }
[data-m3-image-color] { transition: --md-image-color var(--md-motion-slow-effects); }
.image-tint { background-color: color-mix(in oklch, var(--md-image-color) 16%, var(--md-sys-color-surface-container)); }
.image-gradient {
  background-color: var(--md-sys-color-surface);
  background-image: linear-gradient(to bottom, color-mix(in oklch, var(--md-image-color) 35%, var(--md-sys-color-surface)), transparent 480px);
}

/* ---- Carousel (Compose Carousel; M3 carousel spec). js/m3-components.js
   lays the items out on Compose's keylines and masks them; without it the
   carousel is a plain snapping row of the same items.
   <div class="m3-carousel" data-m3-carousel="multi-browse" aria-label="Photos">
     <div class="m3-carousel-item"><img src="…" alt="…"></div> …
   </div>
   Items are extra-large-cornered windows onto their image; the image stays
   centered as the window narrows, which is the carousel's parallax. */
@property --m3-carousel-shape { syntax: '<length>'; inherits: true; initial-value: 28px; }
.m3-carousel {
  --m3-carousel-shape: var(--md-sys-shape-corner-extra-large);
  --m3-carousel-height: 221px;
  position: relative;
  height: var(--m3-carousel-height);
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.m3-carousel::-webkit-scrollbar { display: none; }
.m3-carousel-item {
  position: relative;
  flex: 0 0 186px;
  height: 100%;
  overflow: hidden;
  border-radius: var(--m3-carousel-shape);
  background-color: var(--md-sys-color-surface-container-highest);
  scroll-snap-align: start;
}
.m3-carousel-item > img { display: block; width: 100%; height: 100%; object-fit: cover; user-select: none; -webkit-user-drag: none; }
/* Item text (M3: optional and brief), as in M3's carousel: the text block
   follows the left edge of the visible window and shows, as one block,
   only once the window is wide enough for all of it (--m3-carousel-fade,
   set by the script from the text's measured width). It keeps the item's
   full width, so nothing is ever ellipsized. The scrim fades with it, and
   is 55% under the text (white text still clears 4.5:1 on a white photo),
   easing out over 120px above. */
.m3-carousel-item > .media-text {
  --md-scrim: rgb(0 0 0 / .55);
  --md-scrim-fade: 120px;
  left: var(--m3-carousel-inset, 0px);
  right: auto;
  width: 100%;
  gap: 0;
  opacity: var(--m3-carousel-fade, 1);
}

/* With the script */
.m3-carousel.is-ready { display: block; overflow: visible; scroll-snap-type: none; }
.m3-carousel-scroller {
  height: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  outline: none;
  cursor: grab;
  /* a drag moves the strip; it never selects the captions */
  -webkit-user-select: none;
  user-select: none;
}
.m3-carousel-scroller::-webkit-scrollbar { display: none; }
.m3-carousel-scroller.m3-carousel-snap { scroll-snap-type: x mandatory; }
.m3-carousel-scroller.is-dragging { scroll-snap-type: none; cursor: grabbing; }
.m3-carousel-scroller.is-settling { scroll-snap-type: none; }
/* data-fling="free": a touch fling can pass several items before snapping */
.m3-carousel-free .m3-carousel-snap-point { scroll-snap-stop: normal; }
.m3-carousel-scroller:focus-visible { outline: var(--md-focus-ring); outline-offset: 4px; border-radius: var(--m3-carousel-shape); }
.m3-carousel-track { position: relative; height: 100%; }
.m3-carousel-stage { position: sticky; left: 0; height: 100%; }
.m3-carousel-snap-point { position: absolute; top: 0; width: 1px; height: 1px; scroll-snap-align: start; scroll-snap-stop: always; }
.m3-carousel.is-ready .m3-carousel-item {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 0;
  scroll-snap-align: none;
}
.m3-carousel.is-ready .m3-carousel-item > img { border-radius: 0; }
.m3-carousel.is-ready .m3-carousel-item { outline: none; transition: --m3-carousel-shape var(--md-motion-fast-spatial); }
.m3-carousel-item.is-faded > .media-text { visibility: hidden; }
.m3-carousel-item.is-offscreen { opacity: 0; pointer-events: none; }
/* Interactive items (holding a link or button): hover layer, ripple, and
   the corners tighten a little while pressed (M3: "changes the shape
   slightly"). The focus ring is drawn inside the visible window. */
.m3-carousel-item.is-interactive { cursor: pointer; }
.m3-carousel-item.is-interactive::after,
.m3-carousel-item:focus-visible::before {
  content: "";
  position: absolute;
  inset: 0 var(--m3-carousel-inset, 0px);
  z-index: 2;
  border-radius: var(--m3-carousel-shape);
  pointer-events: none;
}
.m3-carousel-item.is-interactive::after { background-color: var(--md-sys-color-on-surface); opacity: 0; transition: opacity var(--md-motion-fast-effects); }
.m3-carousel-item.is-interactive:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }
.m3-carousel-scroller:not(.is-dragging) .m3-carousel-item.is-interactive:active { --m3-carousel-shape: calc(var(--md-sys-shape-corner-extra-large) - 8px); }
.m3-carousel-item:focus-visible::before { box-shadow: inset 0 0 0 3px var(--md-sys-color-secondary); }
.m3-carousel-item .media-text .btn { pointer-events: auto; }
/* Controls you place beside it go above or below it (M3), e.g.
   <div class="m3-carousel-controls"> with prev / next / play buttons */
.m3-carousel-controls { display: flex; justify-content: flex-end; align-items: center; gap: 4px; margin-top: 8px; }

/* ---- Location picker (js: data-m3-location). M3 text fields, the Expressive
   menu for suggestions and a Google map on a large-cornered surface. The
   address and map sit beside the fields on large screens, above them
   otherwise (.location-picker-stacked keeps them above). Tinted map colors come from the theme (js). */
.location-picker { --location-map-height: 334px; position: relative; container-type: inline-size; display: grid; gap: 16px; }
.location-picker:focus-within { z-index: 5; }
.location-picker-main { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.location-picker-search { position: relative; }
.location-picker-map {
  position: relative;
  height: var(--location-map-height);
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-high);
}
.location-picker-canvas { position: absolute; inset: 0; }
.location-picker-note {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  padding: 24px;
  text-align: center;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
}
.location-picker-note > .material-symbols-rounded { font-size: 32px; }
.location-picker.is-unavailable .location-picker-note { display: flex; }
.location-picker.is-unavailable .location-picker-canvas { display: none; }
.location-picker-fields { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 12px; align-content: start; min-width: 0; }
.location-picker-field { grid-column: span var(--location-span, 12); min-width: 0; }
.location-picker-field > .form-floating > label { max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
@media (min-width: 992px) {
  .location-picker:not(.is-compact):not(.location-picker-stacked) { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
}
@container (max-width: 359.98px) {
  .location-picker-field { grid-column: span 12; }
}
.location-picker-menu.dropdown-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  bottom: auto;
  left: 0;
  z-index: 1000;
  min-width: 0;
  margin: 0;
  padding: 2px;
  overflow-y: auto;
  overscroll-behavior: contain;
  transform-origin: 50% 0;
  scrollbar-width: thin;
}
.location-picker.is-up .location-picker-menu.dropdown-menu { top: auto; bottom: calc(100% + 4px); transform-origin: 50% 100%; }
.location-picker-option { align-items: center; cursor: pointer; user-select: none; }
.location-picker-option.is-focused { background-color: var(--bs-dropdown-link-hover-bg); }
.location-picker-option-text { display: flex; flex-direction: column; min-width: 0; white-space: normal; }
.location-picker-option-text > small {
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-small-font);
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line-height);
}
.location-picker-option-text > small:empty { display: none; }
.location-picker-menu-note, .location-picker-attribution {
  padding: 8px 16px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-small-font);
  font-size: var(--md-sys-typescale-body-small-size);
}
.location-picker-attribution { padding-block: 4px; text-align: end; }

/* ---- Multi-select (js: data-m3-multi-select on a <select multiple>). Not
   an M3 component; built from M3 parts: an outlined (or filled) text field
   whose floating label rises onto the outline, input chips for what's
   chosen, and an Expressive menu (segmented groups, chosen items in
   tertiary-container with a check). Chips pop in on fast-spatial and the
   rest glide; a removed chip shrinks away before the gap closes. */
.multi-select { position: relative; --md-ms-pad: 12px; }
.multi-select-native { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; overflow: hidden; clip-path: inset(50%); }
.multi-select-field {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: 11px 44px 11px var(--md-ms-pad);
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-comp-field-shape);
  background-color: transparent;
  cursor: text;
  transition: border-color var(--md-motion-default-effects), box-shadow var(--md-motion-default-effects);
}
.multi-select.is-picker .multi-select-field { cursor: pointer; }
.multi-select-field:hover { border-color: var(--md-sys-color-on-surface); }
.multi-select.is-focused .multi-select-field { border-color: var(--md-sys-color-primary); box-shadow: inset 0 0 0 1px var(--md-sys-color-primary); }
.multi-select-chips { position: relative; display: flex; flex: 1 1 auto; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.multi-select-input {
  flex: 1 0 64px;
  min-width: 64px;
  height: 32px;
  padding: 0 4px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
}
.multi-select.is-picker .multi-select-input { caret-color: transparent; cursor: pointer; }
.multi-select-input::placeholder { color: var(--md-sys-color-on-surface-variant); opacity: 1; }
/* M3: the placeholder only shows once the label has moved up */
.multi-select:not(.is-focused) .multi-select-input::placeholder { color: transparent; }
.multi-select-arrow {
  position: absolute;
  top: 50%;
  right: 12px;
  margin-top: -12px;
  color: var(--md-sys-color-on-surface-variant);
  pointer-events: none;
  transition: rotate var(--md-motion-fast-spatial);
}
.multi-select.is-open .multi-select-arrow { rotate: 180deg; }
.multi-select-label {
  position: absolute;
  top: 15px;
  left: calc(var(--md-ms-pad) - 4px);
  max-width: calc(100% - 56px);
  overflow: hidden;
  padding: 0 4px;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  transform-origin: 0 0;
  pointer-events: none;
  transition: transform var(--md-motion-fast-spatial), color var(--md-motion-fast-effects);
}
/* floated onto the outline; its own background notches it (as the text
   field's fallback does: set --md-field-container on what it sits on) */
.multi-select:is(.is-focused, .has-value) .multi-select-label {
  transform: translateY(-24px) scale(.75);
  background-color: var(--md-field-container, var(--bs-body-bg));
}
.multi-select.is-focused .multi-select-label { color: var(--md-sys-color-primary); }
/* filled */
.multi-select-filled .multi-select-field {
  padding-top: 20px;
  padding-bottom: 4px;
  border: 0;
  border-radius: var(--md-comp-field-shape) var(--md-comp-field-shape) 0 0;
  background-color: var(--md-sys-color-surface-container-highest);
  box-shadow: inset 0 -1px 0 var(--md-sys-color-on-surface-variant);
}
.multi-select-filled.has-value .multi-select-field { padding-top: 26px; padding-bottom: 6px; }
.multi-select-filled .multi-select-field:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-highest)); box-shadow: inset 0 -1px 0 var(--md-sys-color-on-surface); }
.multi-select-filled.is-focused .multi-select-field { box-shadow: inset 0 -2px 0 var(--md-sys-color-primary); }
.multi-select-filled .multi-select-label { top: 16px; }
.multi-select-filled:is(.is-focused, .has-value) .multi-select-label { transform: translateY(-9px) scale(.75); background: none; }
/* error and disabled */
.multi-select.is-invalid .multi-select-field { border-color: var(--md-sys-color-error); }
.multi-select.is-invalid.is-focused .multi-select-field { box-shadow: inset 0 0 0 1px var(--md-sys-color-error); }
.multi-select-filled.is-invalid .multi-select-field { box-shadow: inset 0 -2px 0 var(--md-sys-color-error); }
.multi-select.is-invalid .multi-select-label { color: var(--md-sys-color-error); }
.multi-select.is-disabled { opacity: .38; pointer-events: none; }
/* chips: a tonal fill as well as the input chip's outline, so they stand out
   from the field (the outline-variant edge alone is faint, in dark themes
   especially); in the filled field, the surface color against its fill */
.multi-select-chip { max-width: 100%; border-color: var(--md-sys-color-outline-variant); background-color: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface); }
.multi-select-chip:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-high)); color: var(--md-sys-color-on-surface); }
.multi-select-filled .multi-select-chip { border-color: transparent; background-color: var(--md-sys-color-surface); }
.multi-select-filled .multi-select-chip:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface)); }
.multi-select-chip-text { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.multi-select.is-reorder .multi-select-chip { cursor: grab; }
.multi-select-chip.is-dragging { z-index: 2; box-shadow: var(--md-sys-elevation-level2); background-color: var(--md-sys-color-surface-container-high); cursor: grabbing; }
.multi-select.is-sorting { user-select: none; cursor: grabbing; }
/* the menu */
.multi-select-menu.dropdown-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  bottom: auto;
  left: 0;
  z-index: 1000;
  min-width: 0;
  margin: 0;
  padding: 2px;
  overflow-y: auto;
  overscroll-behavior: contain;
  transform-origin: 50% 0;
  scrollbar-width: thin;
}
.multi-select.is-up .multi-select-menu.dropdown-menu { top: auto; bottom: calc(100% + 4px); transform-origin: 50% 100%; }
.multi-select-option { gap: 0; cursor: pointer; user-select: none; }
.multi-select-option.is-focused { background-color: var(--bs-dropdown-link-hover-bg); }
.multi-select-option.active.is-focused { background-color: color-mix(in srgb, var(--md-menu-selected-text) var(--md-sys-state-hover-state-layer-opacity), var(--md-menu-selected-bg)); }
.multi-select-option.disabled { opacity: .38; pointer-events: none; }
.multi-select-check {
  width: 0;
  overflow: hidden;
  flex: none;
  opacity: 0;
  scale: .4;
  transition: width var(--md-motion-fast-spatial), margin var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects), scale var(--md-motion-fast-spatial);
}
.multi-select-option.active .multi-select-check { width: 20px; margin-right: 12px; opacity: 1; scale: 1; }
.multi-select-option > .chip-avatar { margin-right: 12px; }
.multi-select-option-text { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.multi-select-match { font-weight: 700; }
.multi-select-create > .material-symbols-rounded { margin-right: 12px; color: var(--md-sys-color-primary); }
.multi-select-note {
  padding: 10px 16px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
}

/* ---- Dual list (js: data-m3-dual-list on a <select multiple>). Not an M3
   component; built from M3 parts: two panes on surface-container-low (large
   corners) with a title-medium heading and a count, a pill search field,
   and list items (48px, body large) that turn secondary-container when
   picked, with a check that grows in and corners that morph from medium to
   full (Expressive shape change). Between them, tonal icon buttons. Under
   520px wide the panes stack and the arrows turn to point down and up. */
.dual-list {
  --dual-list-height: 360px;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  container-type: inline-size;
}
.dual-list-select { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; overflow: hidden; clip-path: inset(50%); }
.dual-list-pane {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  height: var(--dual-list-height);
  padding: 4px 8px 8px;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-low);
}
.dual-list-head { display: flex; flex: none; align-items: center; gap: 8px; min-height: 40px; padding: 0 4px 0 8px; }
.dual-list-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.dual-list-count {
  min-width: 28px;
  padding: 2px 8px;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
  text-align: center;
  font-family: var(--md-sys-typescale-label-medium-font);
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line-height);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  font-variant-numeric: tabular-nums;
}
.dual-list-search {
  display: none;
  flex: none;
  align-items: center;
  gap: 8px;
  height: 40px;
  margin: 0 0 4px;
  padding: 0 16px 0 12px;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface-variant);
  cursor: text;
}
.dual-list.has-search .dual-list-search { display: flex; }
.dual-list-search > .material-symbols-rounded { font-size: 20px; }
.dual-list-search > input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
}
.dual-list-search > input::placeholder { color: var(--md-sys-color-on-surface-variant); opacity: 1; }
.dual-list-search:focus-within { outline: var(--md-focus-ring); outline-offset: 0; }
.dual-list-box {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  outline: none;
  scrollbar-width: thin;
}
.dual-list-item {
  position: relative;
  display: flex;
  flex: none;
  align-items: center;
  min-height: 48px;
  padding: 0 16px 0 12px;
  border-radius: var(--md-sys-shape-corner-medium);
  background-color: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  cursor: pointer;
  user-select: none;
  transition: border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects), color var(--md-motion-fast-effects);
}
.dual-list-item[hidden] { display: none; }
.dual-list-item::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-color: currentColor;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--md-motion-fast-effects);
}
.dual-list-item:hover::before { opacity: var(--md-sys-state-hover-state-layer-opacity); }
.dual-list-item:active::before { opacity: var(--md-sys-state-pressed-state-layer-opacity); }
.dual-list-check {
  width: 0;
  overflow: hidden;
  flex: none;
  font-size: 20px;
  opacity: 0;
  scale: .4;
  transition: width var(--md-motion-fast-spatial), margin var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects), scale var(--md-motion-fast-spatial);
}
.dual-list-text { min-width: 0; padding-left: 4px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.dual-list-item.is-picked {
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
.dual-list-item.is-picked .dual-list-check { width: 20px; margin-right: 8px; opacity: 1; scale: 1; }
.dual-list-item[aria-disabled="true"] { opacity: .38; cursor: default; }
.dual-list-item[aria-disabled="true"]::before { content: none; }
.dual-list-box:focus-visible .dual-list-item.is-active { outline: var(--md-focus-ring); outline-offset: -3px; }
.dual-list-group {
  flex: none;
  padding: 12px 12px 4px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-title-small-font);
  font-size: var(--md-sys-typescale-title-small-size);
  line-height: var(--md-sys-typescale-title-small-line-height);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
.dual-list-group[hidden] { display: none; }
.dual-list-empty { display: none; margin: 0; }
.dual-list-pane.is-empty .dual-list-empty {
  display: block;
  position: absolute;
  left: 16px;
  right: 16px;
  top: 55%;
  text-align: center;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  pointer-events: none;
}
.dual-list-actions { display: flex; flex-direction: column; gap: 8px; }
/* data-reorder: a drag handle on Selected items, the lifted item while it's
   dragged, and move up / down buttons under a divider */
.dual-list-box { position: relative; }
.dual-list-handle { display: none; flex: none; margin: 0 -8px 0 auto; padding: 12px 8px; color: var(--md-sys-color-on-surface-variant); cursor: grab; touch-action: none; }
.dual-list.is-reorder .dual-list-pane[data-side="selected"] .dual-list-handle { display: block; }
.dual-list.is-reorder .dual-list-pane[data-side="selected"] .dual-list-text { flex: 1 1 auto; }
.dual-list-item.is-dragging { z-index: 2; box-shadow: var(--md-sys-elevation-level3); background-color: var(--md-sys-color-surface-container-high); cursor: grabbing; }
.dual-list-box.is-sorting { cursor: grabbing; user-select: none; }
.dual-list-box.is-sorting .dual-list-item:not(.is-dragging)::before { opacity: 0; }
.dual-list-divider { width: 24px; height: 1px; margin: 4px auto; background-color: var(--md-sys-color-outline-variant); }
.dual-list-actions > .btn > .material-symbols-rounded { transition: rotate var(--md-motion-default-spatial); }
/* an item on its way across (js): lifted, over both lists */
.dual-list-flying { position: absolute; z-index: 3; margin: 0; pointer-events: none; box-shadow: var(--md-sys-elevation-level3); will-change: transform; }
.dual-list.is-invalid .dual-list-pane[data-side="selected"] { outline: 2px solid var(--md-sys-color-error); outline-offset: -2px; }
.dual-list.is-invalid .dual-list-pane[data-side="selected"] .dual-list-title { color: var(--md-sys-color-error); }
.dual-list.is-disabled { opacity: .38; pointer-events: none; }
@container (max-width: 519.98px) {
  .dual-list-pane { height: calc(var(--dual-list-height) * .75); }
}
@media (max-width: 575.98px) {
  .dual-list { grid-template-columns: minmax(0, 1fr); }
  .dual-list-actions { flex-direction: row; justify-content: center; }
  .dual-list-actions > .btn:not(.dual-list-order) > .material-symbols-rounded { rotate: 90deg; }
  .dual-list-divider { width: 1px; height: 24px; margin: auto 4px; }
}

/* ---- Media viewer (js: data-m3-viewer / M3Components.viewer; also the
   file upload's previews). A Fancybox-style lightbox in M3 parts, full
   screen on black (the media convention): a top bar with close, the title
   (title medium) and "2 of 5" (body medium, white at 72%, 10:1), zoom and
   download; icon buttons with a white state layer; 56px round arrows
   beside the item; the caption (body large, white at 88%) and the gallery
   as an M3 carousel strip under it. White focus rings: the theme's
   secondary ring doesn't show on black. */
.m3-viewer {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  outline: none;
  background: transparent;
  color: #fff;
  touch-action: none;
  overscroll-behavior: contain;
}
.m3-viewer::backdrop { background: transparent; }
.m3-viewer-scrim { position: absolute; inset: 0; background: #000; }
.m3-viewer-stage { position: absolute; inset: 0; }
.m3-viewer-media { position: absolute; transform-origin: 50% 50%; }
.m3-viewer-media > :is(img, video, iframe) { display: block; width: 100%; height: 100%; border: 0; }
.m3-viewer-media > img { user-select: none; -webkit-user-drag: none; }
.m3-viewer-media.is-image { cursor: zoom-in; }
.m3-viewer.is-zoomed .m3-viewer-media.is-image { cursor: grab; }
.m3-viewer-media:is(.is-video, .is-youtube, .is-vimeo) { background: #000; }
.m3-viewer-media:is(.is-iframe, .is-pdf) > iframe { background: #fff; border-radius: var(--md-sys-shape-corner-medium); }
.m3-viewer-html {
  box-sizing: border-box;
  height: 100%;
  overflow: auto;
  padding: 24px;
  border-radius: var(--md-sys-shape-corner-extra-large);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  touch-action: pan-y;
  cursor: auto;
}
.m3-viewer-html > :last-child { margin-bottom: 0; }
.m3-viewer.is-opening :is(.m3-viewer-scrim, .m3-viewer-chrome, .m3-viewer-media) { opacity: 0; }
.m3-viewer-spinner {
  --md-progress-indicator: #fff;
  --md-progress-track: rgb(255 255 255 / .24);
  position: absolute;
  inset: 0;
  margin: auto;
  display: none;
}
.m3-viewer.is-loading .m3-viewer-spinner { display: inline-block; }
.m3-viewer-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  height: 64px;
  padding: 0 8px;
}
.m3-viewer-heading { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.m3-viewer-title {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.m3-viewer-title:empty { display: none; }
.m3-viewer-count {
  color: rgb(255 255 255 / .72);
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
}
.m3-viewer-count:empty { display: none; }
.m3-viewer-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: #fff;
  cursor: pointer;
}
.m3-viewer-btn[hidden], .m3-viewer:not(.can-zoom) .m3-viewer-zoom { display: none; }
.m3-viewer-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: #fff;
  opacity: 0;
  transition: opacity var(--md-motion-fast-effects);
}
.m3-viewer-btn:hover { color: #fff; }
.m3-viewer-btn:hover::before { opacity: .08; }
.m3-viewer-btn:active::before { opacity: .1; }
.m3-viewer-btn:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.m3-viewer-btn > .material-symbols-rounded { position: relative; }
.m3-viewer-nav {
  position: absolute;
  top: calc(50% - 28px);
  width: 56px;
  height: 56px;
  background: rgb(255 255 255 / .12);
}
.m3-viewer-prev { left: 16px; }
.m3-viewer-next { right: 16px; }
.m3-viewer-nav:disabled { opacity: .38; cursor: default; }
.m3-viewer-nav:disabled::before { content: none; }
.m3-viewer.is-single .m3-viewer-nav { display: none; }
.m3-viewer-foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 0 16px 16px;
  pointer-events: none;
}
.m3-viewer-foot > * { pointer-events: auto; }
.m3-viewer-caption {
  max-width: 72ch;
  max-height: 4.5lh;
  margin: 0;
  overflow: auto;
  text-align: center;
  color: rgb(255 255 255 / .88);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
}
.m3-viewer-caption:empty { display: none; }
.m3-viewer-strip-slot { width: 100%; max-width: 960px; }
/* slideshow: a round filled play button (primary / on-primary, Spotify's
   green-button idea in the theme's color) and a thin playback bar, white on
   a 24% track, that fills over each item's time */
.m3-viewer-play {
  width: 40px;
  height: 40px;
  margin: 0 4px;
  background-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}
.m3-viewer-play:hover { color: var(--md-sys-color-on-primary); }
.m3-viewer-play::before { background: var(--md-sys-color-on-primary); }
.m3-viewer-play > .material-symbols-rounded { font-variation-settings: "FILL" 1; }
.m3-viewer.is-single .m3-viewer-play { display: none; }
.m3-viewer-progress {
  width: 100%;
  max-width: 480px;
  height: 4px;
  overflow: hidden;
  border-radius: 2px;
  background: rgb(255 255 255 / .24);
  opacity: 0;
  transition: opacity var(--md-motion-default-effects);
}
.m3-viewer-progress > span { display: block; height: 100%; background: #fff; border-radius: inherit; transform-origin: left; scale: 0 1; }
.m3-viewer.is-playing .m3-viewer-progress { opacity: 1; }
.m3-viewer.is-single .m3-viewer-progress { display: none; }
.m3-viewer.is-waiting .m3-viewer-progress > span { scale: 0 1; }
.m3-viewer-blocked { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; text-align: center; }
.m3-viewer-blocked > p { max-width: 36ch; margin: 0; }
.m3-viewer-strip-slot:empty { display: none; }
/* the strip: an M3 carousel of the gallery; the item showing is at full
   brightness, the rest dimmed */
.m3-viewer-strip { --m3-carousel-height: 72px; --m3-carousel-shape: var(--md-sys-shape-corner-medium); }
.m3-viewer-strip-item { background-color: #2b2930; filter: brightness(.5); transition: filter var(--md-motion-fast-effects), --m3-carousel-shape var(--md-motion-fast-spatial); }
.m3-viewer-strip-item:hover { filter: brightness(.8); }
.m3-viewer-strip-item.is-viewing { filter: none; }
.m3-viewer-strip-item > .material-symbols-rounded { position: absolute; inset: 0; display: grid; place-items: center; color: #fff; font-size: 28px; }
.m3-viewer-strip-btn { position: absolute; inset: 0; padding: 0; border: 0; background: transparent; cursor: pointer; }
.m3-viewer-strip .m3-carousel-item:focus-visible::before { box-shadow: inset 0 0 0 3px #fff; }
@media (max-width: 599.98px) {
  .m3-viewer-nav { top: auto; bottom: 16px; }
  .m3-viewer.has-strip .m3-viewer-nav { display: none; }
  .m3-viewer-strip { --m3-carousel-height: 56px; }
}

/* ---- File upload: the M3 skin for Dropzone (js/m3-components.js builds it
   from <div class="file-upload" data-m3-file-upload><input type="file" …></div>;
   Dropzone's own stylesheet isn't needed). Not an M3 component; M3 parts:
   a drop zone (surface-container-low, large corners, a dashed
   outline-variant edge that turns primary while files hover over it),
   Expressive segmented list rows for the files (Dropzone's preview
   template), and the linear progress indicator. The real input stays in
   the form, just unseen. */
.file-upload { position: relative; display: flex; flex-direction: column; gap: 8px; }
.file-upload.is-ready > input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  clip-path: inset(50%);
}
.file-upload-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 168px;
  padding: 24px;
  border: 2px dashed var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface-variant);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--md-motion-fast-effects), background-color var(--md-motion-fast-effects), border-radius var(--md-motion-fast-spatial);
}
.file-upload-zone > .material-symbols-rounded {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  margin-bottom: 8px;
  border-radius: var(--md-sys-shape-corner-large);
  background-color: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-size: 28px;
  transition: translate var(--md-motion-fast-spatial), border-radius var(--md-motion-fast-spatial), background-color var(--md-motion-fast-effects), color var(--md-motion-fast-effects);
}
.file-upload-title {
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.file-upload-browse { color: var(--md-sys-color-primary); text-decoration: underline; text-underline-offset: 3px; }
.file-upload-hint {
  font-family: var(--md-sys-typescale-body-small-font);
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line-height);
}
.file-upload-zone:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-surface-container-low)); }
.file-upload-zone:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
/* files over the zone: solid primary edge, the icon lifts and goes round */
.file-upload.dz-drag-hover .file-upload-zone {
  border-style: solid;
  border-color: var(--md-sys-color-primary);
  border-radius: var(--md-sys-shape-corner-extra-large);
  background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, var(--md-sys-color-surface-container-low));
}
.file-upload.dz-drag-hover .file-upload-zone > .material-symbols-rounded {
  translate: 0 -6px;
  border-radius: 28px;
  background-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}
.file-upload.is-invalid .file-upload-zone { border-color: var(--md-sys-color-error); }
.file-upload:has(> input:disabled) .file-upload-zone { opacity: .38; cursor: default; pointer-events: none; }
/* every allowed file is in: the zone steps back (one-file uploads stay open, a new file replaces the old) */
.file-upload.dz-max-files-reached:has(> input[multiple]) .file-upload-zone { opacity: .38; pointer-events: none; }
.file-upload-button { align-self: flex-start; }

/* the files: segmented list rows (2px apart, 4px corners, 16px at the ends) */
.file-upload-list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.file-upload-list:empty { display: none; }
.file-upload-item {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 64px;
  padding: 8px 8px 8px 16px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background-color: var(--md-sys-color-surface-container-low);
  overflow: hidden;
  transition: opacity var(--md-motion-fast-effects), translate var(--md-motion-fast-spatial);
}
/* entry: js drops new files in, in turn (flipFiles) */
.file-upload-item.dz-processing:not(.dz-complete) .file-upload-remove { color: var(--md-sys-color-on-surface-variant); }
.file-upload-item:first-child { border-top-left-radius: var(--md-sys-shape-corner-large); border-top-right-radius: var(--md-sys-shape-corner-large); }
.file-upload-item:last-child { border-bottom-left-radius: var(--md-sys-shape-corner-large); border-bottom-right-radius: var(--md-sys-shape-corner-large); }
.file-upload-item.is-leaving { opacity: 0; translate: 0 -8px; pointer-events: none; }
.file-upload-ghost { z-index: 0; transition: none; }  /* a removed file fading out (js) */
.file-upload-thumb {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-small);
  background-color: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
.file-upload-thumb > img { display: none; width: 100%; height: 100%; object-fit: cover; }
.file-upload-thumb > .material-symbols-rounded { font-size: 24px; }
/* Dropzone swaps dz-file-preview for dz-image-preview once a thumbnail exists */
.file-upload-item.dz-image-preview .file-upload-thumb > img { display: block; }
.file-upload-item.dz-image-preview .file-upload-thumb > .material-symbols-rounded { display: none; }
.file-upload-text { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; gap: 2px; }
.file-upload-name {
  overflow: hidden;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font);
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.file-upload-meta {
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-medium-font);
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
  font-variant-numeric: tabular-nums;
}
.file-upload-size strong { font-weight: inherit; }
/* Preview (js): images and PDFs open from anywhere on their row or tile
   (mouse/touch); for the keyboard, a button. The whole file gets an M3
   state layer (hover 8%, pressed and keyboard focus 10%) and a pointer
   cursor; the image itself is kept clear of the layer. In a row the button
   is the thumbnail itself, unmarked (a ring on focus). On a tile it's a
   40px filled primary button with a level-2 shadow that fades and rises
   into the middle of the image on hover or focus, Spotify-style, so the
   photo itself is never covered. */
.file-upload-thumb { position: relative; }
.file-upload-open {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.file-upload-open > .material-symbols-rounded { display: none; }
.file-upload-open:focus-visible { outline: var(--md-focus-ring); outline-offset: 2px; }
.file-upload-item.is-previewable:not(.dz-error) { cursor: pointer; }
.file-upload-item.is-previewable::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  background-color: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--md-motion-fast-effects);
}
.file-upload-item.is-previewable:not(.dz-error):hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }
.file-upload-item.is-previewable:not(.dz-error):is(:active, :has(.file-upload-open:focus-visible))::after { opacity: var(--md-sys-state-pressed-state-layer-opacity); }
.file-upload-item.is-previewable:has(.file-upload-remove:active, .file-upload-retry:active)::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }
.file-tile .file-upload-remove, .file-tile .file-upload-retry { z-index: 2; }
/* the image stays clear of the state layer */
.file-upload-item.is-previewable .file-upload-thumb { z-index: 2; }
.file-tile .file-upload-open {
  inset: 0;
  width: 40px;
  height: 40px;
  margin: auto;
  border-radius: 50%;
  background-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
  box-shadow: var(--md-sys-elevation-level2);
  opacity: 0;
  translate: 0 8px;
  transition: opacity var(--md-motion-fast-effects), translate var(--md-motion-default-spatial);
}
.file-tile .file-upload-open::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-color: var(--md-sys-color-on-primary);
  opacity: 0;
  transition: opacity var(--md-motion-fast-effects);
}
.file-tile .file-upload-open:hover::before { opacity: var(--md-sys-state-hover-state-layer-opacity); }
.file-tile .file-upload-open > .material-symbols-rounded { position: relative; display: block; font-size: 24px; }
.file-tile.is-previewable:not(.dz-error):hover .file-upload-open,
.file-tile .file-upload-open:focus-visible { opacity: 1; translate: 0 0; }
.dz-error .file-upload-open,
.file-tile.dz-processing:not(.dz-complete) .file-upload-open { display: none; }

/* Long names: cut in the middle so the end shows ("Quarterly-repo…final-v3.pdf") */
.file-upload-name { display: flex; min-width: 0; }
.fu-name-start { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: pre; }
.fu-name-end { flex: none; white-space: pre; }

/* Color from the thumbnail (data-image-color="false" on .file-upload turns
   it off): the image's vivid color fades into the surface behind the file,
   30% of the mix, with its lightness held to the theme's side (a white
   photo can't lift a dark surface, a black one can't sink a light one), so
   on-surface-variant text stays above 4.5:1 for any image */
@property --fu-tint { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
.file-upload-item.has-image-color:not(.dz-error) {
  --fu-tint: 30%;
  --fu-tint-color: oklch(from var(--md-image-color) max(l, .6) c h);
  background-image: linear-gradient(to right,
    color-mix(in oklch, var(--fu-tint-color) var(--fu-tint), var(--md-sys-color-surface-container-low)),
    color-mix(in oklch, var(--fu-tint-color) calc(var(--fu-tint) / 3), var(--md-sys-color-surface-container-low)) 70%);
  transition: opacity var(--md-motion-fast-effects), translate var(--md-motion-fast-spatial), --fu-tint var(--md-motion-slow-effects);
}
/* an emphasized name over the muted size line */
.file-upload-item .file-upload-name { font-weight: var(--md-sys-typescale-body-large-emphasized-weight); }
[data-bs-theme=dark] .file-upload-item.has-image-color { --fu-tint-color: oklch(from var(--md-image-color) min(l, .55) c h); }
@starting-style { .file-upload-item.has-image-color { --fu-tint: 0%; } }

/* ---- Tiles: data-m3-file-upload="grid". Square cards (medium corners,
   surface-container-low): the image cropped to fill, or a type icon with
   the extension; name and size below; remove in the corner (always shown,
   for touch); circular progress over the image while uploading, retry over
   it when that failed. The zone spans the grid until there are files, then
   becomes an "Add" tile after the last one. */
.file-upload-tiles { position: relative; display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); grid-auto-rows: 1fr; gap: 8px; }
.file-upload-tiles > .file-upload-zone { grid-column: 1 / -1; order: 1; }
.file-tile-add { display: none; }
.file-upload-tiles:has(> .file-tile) > .file-upload-zone {
  grid-column: auto;
  min-height: 0;
  padding: 12px;
  border-radius: var(--md-sys-shape-corner-medium);
}
.file-upload-tiles:has(> .file-tile) > .file-upload-zone > :is(.file-upload-title, .file-upload-hint) { display: none; }
.file-upload-tiles:has(> .file-tile) > .file-upload-zone > .file-tile-add {
  display: block;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-label-large-font);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
}
.file-upload-tiles:has(> .file-tile) > .file-upload-zone > .material-symbols-rounded { margin-bottom: 4px; }
.file-upload-tiles > .file-tile {
  position: relative;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  min-height: 0;
  padding: 8px;
  border-radius: var(--md-sys-shape-corner-large);
}
/* the image inset in the card, Spotify style: 16px card - 8px padding = 8px corners */
.file-tile .file-upload-thumb { position: relative; width: 100%; height: auto; aspect-ratio: 1; border-radius: var(--md-sys-shape-corner-small); }
.file-tile .file-upload-thumb > img { position: absolute; inset: 0; }
.file-tile .file-upload-thumb > .material-symbols-rounded { font-size: 40px; }
.file-tile-ext {
  position: absolute;
  bottom: 10px;
  left: 0;
  right: 0;
  text-align: center;
  font-family: var(--md-sys-typescale-label-medium-font);
  font-size: var(--md-sys-typescale-label-medium-size);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: .04em;
}
.file-tile.dz-image-preview .file-tile-ext, .file-tile.dz-error .file-tile-ext { display: none; }
.file-tile .file-upload-text { padding: 10px 4px 2px; gap: 2px; }
.file-upload-tiles > .file-tile.has-image-color:not(.dz-error) {
  background-image: linear-gradient(to bottom,
    color-mix(in oklch, var(--fu-tint-color) var(--fu-tint), var(--md-sys-color-surface-container-low)) 50%,
    color-mix(in oklch, var(--fu-tint-color) calc(var(--fu-tint) / 2), var(--md-sys-color-surface-container-low)));
}
.file-tile .file-upload-name {
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  font-weight: var(--md-sys-typescale-title-medium-emphasized-weight);
  letter-spacing: var(--md-sys-typescale-title-medium-tracking);
}
.file-tile .file-upload-meta {
  font-family: var(--md-sys-typescale-body-small-font);
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line-height);
}
.file-tile .file-upload-remove {
  --md-btn-height: 32px;
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  min-height: 32px;
  height: 32px;
  background-color: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 88%, transparent);
  color: var(--md-sys-color-on-surface);
}
.file-tile .file-upload-remove > .material-symbols-rounded { font-size: 18px; }
/* uploading: dimmed image, circular progress in the middle */
.file-tile.dz-processing:not(.dz-complete) .file-upload-thumb::after { content: ""; position: absolute; inset: 0; background: rgb(0 0 0 / .32); }
.file-tile .file-upload-progress {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: auto;
  /* a surface disc under the ring so it reads on any photo */
  border-radius: 50%;
  background-color: var(--md-sys-color-surface-container-highest);
  box-shadow: 0 0 0 6px var(--md-sys-color-surface-container-highest);
}
.file-tile.dz-processing:not(.dz-complete) .file-upload-progress { display: block; }
.file-tile .file-upload-retry {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: auto;
  background-color: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
}
.file-tile.is-failed .file-upload-retry { display: inline-flex; }
.file-upload-tiles > .file-tile.dz-error .file-upload-error { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.file-upload-error { display: none; }
.file-upload-progress { display: none; }
.file-upload-item.dz-processing:not(.dz-complete) .file-upload-progress { display: flex; }
/* in a row the bar lies along the bottom edge, taking no room, so rows
   don't change height as uploads start and finish; it fades out when done */
.file-upload-list .file-upload-item { position: relative; }
.file-upload-list .file-upload-item .file-upload-progress {
  display: flex;
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 4px;
  opacity: 0;
  transition: opacity var(--md-motion-fast-effects);
}
.file-upload-list .file-upload-item.dz-processing:not(.dz-complete) .file-upload-progress { opacity: 1; }
.file-upload-retry { display: none; }
.file-upload-item.is-failed .file-upload-retry { display: inline-flex; }
/* turned away (type, size, count) or failed to upload */
.file-upload-item.dz-error .file-upload-size,
.file-upload-item.dz-error .file-upload-status { display: none; }
.file-upload-item.dz-error .file-upload-error { display: inline; }
.file-upload-item.dz-error .file-upload-thumb { background-color: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); }
.file-upload-item.dz-error .file-upload-thumb > img { display: none; }
.file-upload-item.dz-error .file-upload-thumb > .material-symbols-rounded { display: block; font-size: 0; }
.file-upload-item.dz-error .file-upload-thumb > .material-symbols-rounded::before { content: "error"; font-size: 24px; }
.file-upload-item.dz-error .file-upload-meta { color: var(--md-sys-color-error); }
.file-upload-item.is-rejected .file-upload-name { color: var(--md-sys-color-on-surface-variant); }
.file-upload-item.dz-success .file-upload-meta::before {
  content: "check_circle";
  margin-right: 4px;
  font-family: "Material Symbols Rounded";
  font-size: 16px;
  vertical-align: -3px;
  color: var(--md-sys-color-primary);
  line-height: 0;  /* the icon mustn't make the line taller (rows would grow 1px when done) */
}

/* ---- FAB menu (FabMenuBaselineTokens + Compose FloatingActionButtonMenu)
   <div class="fab-menu">
     <div class="fab-menu-items" id="fm" role="menu">
       <button class="fab-menu-item" role="menuitem"><span class="material-symbols-rounded">mail</span>Email</button> …
     </div>
     <button class="btn btn-fab fab-menu-toggle" aria-expanded="false" aria-controls="fm" aria-label="Open menu">
       <span class="material-symbols-rounded fab-menu-icon">add</span>
       <span class="material-symbols-rounded fab-menu-icon-close">close</span></button>
   </div>
   Open with .open on .fab-menu (js/m3-components.js toggles it from the
   button, closes on Escape / outside click). The FAB morphs into a 56px
   round close button (primary-container → primary); items reveal from the
   FAB's side one after another, nearest first. */
@property --md-fab-item-p { syntax: '<number>'; inherits: false; initial-value: 0; }
.fab-menu { position: relative; display: inline-flex; flex-direction: column; align-items: flex-end; }
.fab-menu-start { align-items: flex-start; }
/* Items float above the FAB (8px gap) so the closed menu takes no space */
.fab-menu-items {
  position: absolute;
  z-index: 1030;
  right: 0;
  bottom: calc(100% + 8px);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  pointer-events: none;
  /* Closed items wait translated off to the FAB's side; clipping keeps them
     from widening the page (a horizontal scrollbar on phones). While open
     (and until the close animation ends) a 32px margin leaves room for the
     level-3 shadow and the spring's overshoot; closed, nothing can poke out. */
  overflow: clip;
  overflow-clip-margin: 0px;
}
/* .md-closing is held by m3-components.js until the close animation ends
   (overflow-clip-margin can't be transitioned). */
.fab-menu:is(.open, .md-closing) .fab-menu-items { overflow-clip-margin: 32px; }
.fab-menu-start .fab-menu-items { right: auto; left: 0; align-items: flex-start; }
.fab-menu.open .fab-menu-items { pointer-events: auto; }
.fab-menu-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 56px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--md-sys-shape-corner-full);
  background-color: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  box-shadow: var(--md-sys-elevation-level3);
  font-family: var(--md-sys-typescale-title-medium-font);
  font-size: var(--md-sys-typescale-title-medium-size);
  font-weight: var(--md-sys-typescale-title-medium-weight);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  opacity: 0;
  /* Reveal (matches the M3 spec video): the item slides out of the FAB while
     its pill is unmasked on the same spring value, so the icon and label
     ride the moving outer edge and the far end of the label stays cut off
     until the pill is full width. --md-fab-item-p springs 0 → 1. */
  --md-fab-item-p: 0;
  --md-fab-item-hide: calc((1 - var(--md-fab-item-p)) * 100%);
  translate: var(--md-fab-item-hide) 0;
  clip-path: inset(0 var(--md-fab-item-hide) 0 0 round 28px);
  transition: --md-fab-item-p var(--md-motion-fast-spatial), opacity var(--md-motion-fast-effects), background-color var(--md-motion-fast-effects);
}
.fab-menu-start .fab-menu-item { translate: calc(-1 * var(--md-fab-item-hide)) 0; clip-path: inset(0 0 0 var(--md-fab-item-hide) round 28px); }
/* Compose's horizontalAlignment = CenterHorizontally: items center over the
   FAB and grow out from their middle. */
.fab-menu-center { align-items: center; }
.fab-menu-center .fab-menu-items { right: auto; left: 50%; translate: -50% 0; align-items: center; }
.fab-menu-center .fab-menu-item { translate: none; clip-path: inset(0 calc(var(--md-fab-item-hide) / 2) 0 calc(var(--md-fab-item-hide) / 2) round 28px); }
/* Not in Compose (its menu always opens upward): -down opens below the FAB,
   for a FAB that sits near the top of the page. Nearest item still first. */
.fab-menu-down .fab-menu-items { bottom: auto; top: calc(100% + 8px); flex-direction: column-reverse; }
.fab-menu-item > :is(.material-symbols-rounded, .material-symbols-outlined) { font-size: 24px; }
.fab-menu-item:hover { background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-primary-container)); color: var(--md-sys-color-on-primary-container); }
.fab-menu-item:focus-visible { outline: var(--md-focus-ring); outline-offset: var(--md-focus-offset); }
.fab-menu.open .fab-menu-item { opacity: 1; --md-fab-item-p: 1; }
/* Stagger: nearest the FAB first */
.fab-menu.open .fab-menu-item:nth-last-child(2) { transition-delay: 30ms; }
.fab-menu.open .fab-menu-item:nth-last-child(3) { transition-delay: 60ms; }
.fab-menu.open .fab-menu-item:nth-last-child(4) { transition-delay: 90ms; }
.fab-menu.open .fab-menu-item:nth-last-child(5) { transition-delay: 120ms; }
.fab-menu.open .fab-menu-item:nth-last-child(n+6) { transition-delay: 150ms; }
/* Closing reverses it: farthest item leaves first */
.fab-menu:not(.open) .fab-menu-item:nth-child(2) { transition-delay: 30ms; }
.fab-menu:not(.open) .fab-menu-item:nth-child(3) { transition-delay: 60ms; }
.fab-menu:not(.open) .fab-menu-item:nth-child(4) { transition-delay: 90ms; }
.fab-menu:not(.open) .fab-menu-item:nth-child(5) { transition-delay: 120ms; }
.fab-menu:not(.open) .fab-menu-item:nth-child(n+6) { transition-delay: 150ms; }

.fab-menu-toggle {
  transition: background-color var(--md-motion-fast-effects), color var(--md-motion-fast-effects),
              width var(--md-motion-fast-spatial), height var(--md-motion-fast-spatial),
              border-radius var(--md-motion-fast-spatial), box-shadow var(--md-motion-default-effects);
}
.fab-menu.open .fab-menu-toggle {
  --md-btn-height: 56px;
  --md-fab-shape: 28px;
  --md-btn-container: var(--md-sys-color-primary);
  --md-btn-content: var(--md-sys-color-on-primary);
}
/* The icons keep their closed font-size and shrink to 20px with `scale`:
   springing font-size re-lays out and re-hints the glyph every frame, which
   made it jitter. Both sit in the same centered 1em box, so they rotate about
   their true center. */
.fab-menu-toggle { position: relative; --md-fab-icon-open: calc(20 / 24); }
.fab-menu-toggle.btn-fab-md { --md-fab-icon-open: calc(20 / 28); }
.fab-menu-toggle.btn-fab-lg { --md-fab-icon-open: calc(20 / 32); }
.fab-menu-toggle > :is(.fab-menu-icon, .fab-menu-icon-close) {
  position: absolute;
  inset: 0;
  width: 1em;
  height: 1em;
  margin: auto;
  transition: opacity var(--md-motion-fast-effects), rotate var(--md-motion-fast-spatial), scale var(--md-motion-fast-spatial);
  /* Stay composited at rest too. A FAB centered in its container can land
     on a half pixel; mid-animation the glyph draws there, but once the
     transform ends the browser snaps it to the pixel grid, a 1px jump.
     Keeping the layer means it draws the same way moving or still. */
  will-change: rotate, scale, opacity;
}
.fab-menu.open .fab-menu-toggle > :is(.fab-menu-icon, .fab-menu-icon-close) { scale: var(--md-fab-icon-open); }
.fab-menu-toggle > .fab-menu-icon-close { opacity: 0; rotate: -90deg; }
.fab-menu.open .fab-menu-toggle > .fab-menu-icon { opacity: 0; rotate: 90deg; }
.fab-menu.open .fab-menu-toggle > .fab-menu-icon-close { opacity: 1; rotate: 0deg; }

/* --------------------------------------------------------------------------
   Loading indicator (M3 Expressive), following Compose's LoadingIndicator:
   48px container, 38px active shape. Indeterminate: every 650ms the shape
   turns 90° on a damping 0.6 / stiffness 200 spring (overshooting to ~98°
   and settling back) while the whole indicator spins 360° every 4.666s.
   At the turn's fastest moment (~82ms in) the shape snaps to the next of
   7 Material shapes (soft burst, 9-sided cookie, pentagon, pill, sunny,
   4-sided cookie, oval) in a 100ms morph, then holds it for the rest of
   the step. Compose morphs on the spring itself; the snap matches how the
   spec videos read. The shapes were generated from the androidx
   graphics-shapes definitions, and like Compose's Morph each step matches
   the corners of one shape to the nearest corners of the next, so corners
   travel along the outline into their partners. Sampled into 160-point
   polygons for clip-path; no runtime JS. Regenerate with tools/li-css.js.
   (Easing curves are inlined per keyframe: browsers ignore var() there.)

     <div class="loading-indicator" role="progressbar" aria-label="Loading"></div>
     <div class="loading-indicator loading-indicator-contained" ...></div>
     <div class="loading-indicator loading-indicator-determinate"
          style="--md-loading-progress: .4" role="progressbar" aria-valuenow="40" ...></div>
   Determinate morphs circle → soft burst and turns −180° as progress goes 0 → 1.
   -------------------------------------------------------------------------- */
.loading-indicator {
  --md-li-size: 48px;
  --md-li-color: var(--md-sys-color-primary);
  --md-li-container: transparent;
  position: relative;
  display: inline-block;
  flex: none;
  width: var(--md-li-size);
  height: var(--md-li-size);
  border-radius: 50%;
  background-color: var(--md-li-container);
  animation: md-li-spin calc(4.666s * var(--md-motion-scale)) linear infinite;
}
.loading-indicator::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--md-li-color);
  clip-path: polygon(26.96% 36.05%,28.30% 35.39%,29.24% 34.22%,29.61% 32.77%,29.51% 31.27%,29.39% 29.77%,29.28% 28.26%,29.16% 26.76%,29.22% 25.26%,29.89% 23.92%,31.05% 22.98%,32.50% 22.62%,33.97% 22.90%,35.37% 23.46%,36.77% 24.03%,38.16% 24.60%,39.56% 25.17%,41.03% 25.42%,42.48% 25.03%,43.63% 24.08%,44.43% 22.80%,45.22% 21.52%,46.01% 20.24%,46.80% 18.95%,47.73% 17.77%,49.06% 17.08%,50.55% 17.01%,51.94% 17.56%,52.96% 18.65%,53.76% 19.93%,54.56% 21.21%,55.35% 22.49%,56.15% 23.77%,57.19% 24.85%,58.59% 25.38%,60.08% 25.28%,61.48% 24.73%,62.88% 24.15%,64.27% 23.58%,65.66% 23.00%,67.11% 22.60%,68.59% 22.81%,69.84% 23.63%,70.64% 24.90%,70.82% 26.38%,70.72% 27.89%,70.61% 29.39%,70.50% 30.89%,70.39% 32.40%,70.60% 33.88%,71.42% 35.13%,72.69% 35.93%,74.14% 36.30%,75.61% 36.66%,77.08% 37.01%,78.54% 37.37%,79.95% 37.88%,81.02% 38.93%,81.55% 40.33%,81.45% 41.82%,80.73% 43.13%,79.76% 44.28%,78.79% 45.44%,77.81% 46.59%,76.84% 47.74%,76.15% 49.07%,76.07% 50.56%,76.63% 51.95%,77.59% 53.11%,78.56% 54.26%,79.54% 55.41%,80.52% 56.55%,81.35% 57.80%,81.60% 59.28%,81.21% 60.72%,80.25% 61.87%,78.90% 62.51%,77.43% 62.87%,75.97% 63.23%,74.51% 63.59%,73.04% 63.95%,71.70% 64.61%,70.76% 65.78%,70.39% 67.23%,70.49% 68.73%,70.61% 70.23%,70.72% 71.74%,70.84% 73.24%,70.78% 74.74%,70.11% 76.08%,68.95% 77.02%,67.50% 77.38%,66.03% 77.10%,64.63% 76.54%,63.23% 75.97%,61.84% 75.40%,60.44% 74.83%,58.97% 74.58%,57.52% 74.97%,56.37% 75.92%,55.57% 77.20%,54.78% 78.48%,53.99% 79.76%,53.20% 81.05%,52.27% 82.23%,50.94% 82.92%,49.45% 82.99%,48.06% 82.44%,47.04% 81.35%,46.24% 80.07%,45.44% 78.79%,44.65% 77.51%,43.85% 76.23%,42.81% 75.15%,41.41% 74.62%,39.92% 74.72%,38.52% 75.27%,37.12% 75.85%,35.73% 76.42%,34.34% 77.00%,32.89% 77.40%,31.41% 77.19%,30.16% 76.37%,29.36% 75.10%,29.18% 73.62%,29.28% 72.11%,29.39% 70.61%,29.50% 69.11%,29.61% 67.60%,29.40% 66.12%,28.58% 64.87%,27.31% 64.07%,25.86% 63.70%,24.39% 63.34%,22.92% 62.99%,21.46% 62.63%,20.05% 62.12%,18.98% 61.07%,18.45% 59.67%,18.55% 58.18%,19.27% 56.87%,20.24% 55.72%,21.21% 54.56%,22.19% 53.41%,23.16% 52.26%,23.85% 50.93%,23.93% 49.44%,23.37% 48.05%,22.41% 46.89%,21.44% 45.74%,20.46% 44.59%,19.48% 43.45%,18.65% 42.20%,18.40% 40.72%,18.79% 39.28%,19.75% 38.13%,21.10% 37.49%,22.57% 37.13%,24.03% 36.77%,25.49% 36.41%);
  animation: md-li-snap calc(4.55s * var(--md-motion-scale)) infinite,
             md-li-turn calc(2.6s * var(--md-motion-scale)) infinite;
}
.loading-indicator-contained {
  --md-li-container: var(--md-sys-color-primary-container);
  --md-li-color: var(--md-sys-color-on-primary-container);
}
.loading-indicator-sm { --md-li-size: 32px; }
.loading-indicator-lg { --md-li-size: 72px; }

.loading-indicator-determinate { animation: none; }
.loading-indicator-determinate::before {
  /* A paused animation scrubbed by the progress value */
  animation: md-li-determinate 1s linear paused both;
  /* --md-li-p is the smoothed value from m3-components.js (Compose's
     ProgressAnimationSpec spring); without the script it steps directly.
     A transitioned custom property can't drive animation-delay (it is
     "animation-tainted" and computes to 0), hence the script. */
  animation-delay: calc(var(--md-li-p, var(--md-loading-progress, 0)) * -1s);
}

@keyframes md-li-spin { to { rotate: 360deg; } }
@keyframes md-li-turn {
  0%   { rotate: 0deg;   animation-timing-function: linear(0, 0.017, 0.0625, 0.1294, 0.211, 0.3016, 0.3964, 0.4914, 0.5836, 0.6704, 0.7502, 0.8218, 0.8844, 0.938, 0.9826, 1.0187, 1.0467, 1.0674, 1.0817, 1.0904, 1.0943, 1.0944, 1.0913, 1.0859, 1.0788, 1.0706, 1.0618, 1.0527, 1.0438, 1.0353, 1.0274, 1.0202, 1.0138, 1.0083, 1.0037, 0.9999, 0.9968, 0.9945, 0.9929, 0.9918, 0.9912, 0.991, 0.9912, 0.9916, 0.9922, 0.9929, 0.9937, 0.9946, 1); }
  25%  { rotate: 90deg;  animation-timing-function: linear(0, 0.017, 0.0625, 0.1294, 0.211, 0.3016, 0.3964, 0.4914, 0.5836, 0.6704, 0.7502, 0.8218, 0.8844, 0.938, 0.9826, 1.0187, 1.0467, 1.0674, 1.0817, 1.0904, 1.0943, 1.0944, 1.0913, 1.0859, 1.0788, 1.0706, 1.0618, 1.0527, 1.0438, 1.0353, 1.0274, 1.0202, 1.0138, 1.0083, 1.0037, 0.9999, 0.9968, 0.9945, 0.9929, 0.9918, 0.9912, 0.991, 0.9912, 0.9916, 0.9922, 0.9929, 0.9937, 0.9946, 1); }
  50%  { rotate: 180deg; animation-timing-function: linear(0, 0.017, 0.0625, 0.1294, 0.211, 0.3016, 0.3964, 0.4914, 0.5836, 0.6704, 0.7502, 0.8218, 0.8844, 0.938, 0.9826, 1.0187, 1.0467, 1.0674, 1.0817, 1.0904, 1.0943, 1.0944, 1.0913, 1.0859, 1.0788, 1.0706, 1.0618, 1.0527, 1.0438, 1.0353, 1.0274, 1.0202, 1.0138, 1.0083, 1.0037, 0.9999, 0.9968, 0.9945, 0.9929, 0.9918, 0.9912, 0.991, 0.9912, 0.9916, 0.9922, 0.9929, 0.9937, 0.9946, 1); }
  75%  { rotate: 270deg; animation-timing-function: linear(0, 0.017, 0.0625, 0.1294, 0.211, 0.3016, 0.3964, 0.4914, 0.5836, 0.6704, 0.7502, 0.8218, 0.8844, 0.938, 0.9826, 1.0187, 1.0467, 1.0674, 1.0817, 1.0904, 1.0943, 1.0944, 1.0913, 1.0859, 1.0788, 1.0706, 1.0618, 1.0527, 1.0438, 1.0353, 1.0274, 1.0202, 1.0138, 1.0083, 1.0037, 0.9999, 0.9968, 0.9945, 0.9929, 0.9918, 0.9912, 0.991, 0.9912, 0.9916, 0.9922, 0.9929, 0.9937, 0.9946, 1); }
  100% { rotate: 360deg; }
}
@keyframes md-li-determinate {
  from { clip-path: polygon(89.58% 50.00%,89.55% 51.55%,89.46% 53.11%,89.31% 54.65%,89.10% 56.19%,88.82% 57.72%,88.49% 59.24%,88.10% 60.74%,87.65% 62.23%,87.14% 63.70%,86.57% 65.15%,85.95% 66.57%,85.27% 67.97%,84.54% 69.34%,83.75% 70.68%,82.91% 71.99%,82.02% 73.27%,81.09% 74.51%,80.10% 75.71%,79.07% 76.87%,77.99% 77.99%,76.87% 79.07%,75.71% 80.10%,74.51% 81.09%,73.27% 82.02%,71.99% 82.91%,70.68% 83.75%,69.34% 84.54%,67.97% 85.27%,66.57% 85.95%,65.15% 86.57%,63.70% 87.14%,62.23% 87.65%,60.74% 88.10%,59.24% 88.49%,57.72% 88.82%,56.19% 89.10%,54.65% 89.31%,53.11% 89.46%,51.55% 89.55%,50.00% 89.58%,48.45% 89.55%,46.89% 89.46%,45.35% 89.31%,43.81% 89.10%,42.28% 88.82%,40.76% 88.49%,39.26% 88.10%,37.77% 87.65%,36.30% 87.14%,34.85% 86.57%,33.43% 85.95%,32.03% 85.27%,30.66% 84.54%,29.32% 83.75%,28.01% 82.91%,26.73% 82.02%,25.49% 81.09%,24.29% 80.10%,23.13% 79.07%,22.01% 77.99%,20.93% 76.87%,19.90% 75.71%,18.91% 74.51%,17.98% 73.27%,17.09% 71.99%,16.25% 70.68%,15.46% 69.34%,14.73% 67.97%,14.05% 66.57%,13.43% 65.15%,12.86% 63.70%,12.35% 62.23%,11.90% 60.74%,11.51% 59.24%,11.18% 57.72%,10.90% 56.19%,10.69% 54.65%,10.54% 53.11%,10.45% 51.55%,10.42% 50.00%,10.45% 48.45%,10.54% 46.89%,10.69% 45.35%,10.90% 43.81%,11.18% 42.28%,11.51% 40.76%,11.90% 39.26%,12.35% 37.77%,12.86% 36.30%,13.43% 34.85%,14.05% 33.43%,14.73% 32.03%,15.46% 30.66%,16.25% 29.32%,17.09% 28.01%,17.98% 26.73%,18.91% 25.49%,19.90% 24.29%,20.93% 23.13%,22.01% 22.01%,23.13% 20.93%,24.29% 19.90%,25.49% 18.91%,26.73% 17.98%,28.01% 17.09%,29.32% 16.25%,30.66% 15.46%,32.03% 14.73%,33.43% 14.05%,34.85% 13.43%,36.30% 12.86%,37.77% 12.35%,39.26% 11.90%,40.76% 11.51%,42.28% 11.18%,43.81% 10.90%,45.35% 10.69%,46.89% 10.54%,48.45% 10.45%,50.00% 10.42%,51.55% 10.45%,53.11% 10.54%,54.65% 10.69%,56.19% 10.90%,57.72% 11.18%,59.24% 11.51%,60.74% 11.90%,62.23% 12.35%,63.70% 12.86%,65.15% 13.43%,66.57% 14.05%,67.97% 14.73%,69.34% 15.46%,70.68% 16.25%,71.99% 17.09%,73.27% 17.98%,74.51% 18.91%,75.71% 19.90%,76.87% 20.93%,77.99% 22.01%,79.07% 23.13%,80.10% 24.29%,81.09% 25.49%,82.02% 26.73%,82.91% 28.01%,83.75% 29.32%,84.54% 30.66%,85.27% 32.03%,85.95% 33.43%,86.57% 34.85%,87.14% 36.30%,87.65% 37.77%,88.10% 39.26%,88.49% 40.76%,88.82% 42.28%,89.10% 43.81%,89.31% 45.35%,89.46% 46.89%,89.55% 48.45%); rotate: 0deg; }
  to   { clip-path: polygon(81.17% 49.97%,81.55% 51.73%,82.59% 53.19%,83.77% 54.57%,84.94% 55.94%,86.11% 57.32%,87.24% 58.72%,87.83% 60.41%,87.66% 62.20%,86.76% 63.75%,85.29% 64.77%,83.55% 65.25%,81.79% 65.68%,80.04% 66.11%,78.29% 66.55%,76.58% 67.12%,75.24% 68.30%,74.51% 69.94%,74.49% 71.74%,74.63% 73.54%,74.77% 75.34%,74.91% 77.14%,75.00% 78.95%,74.49% 80.66%,73.30% 82.00%,71.66% 82.73%,69.87% 82.69%,68.18% 82.05%,66.50% 81.37%,64.83% 80.69%,63.16% 80.01%,61.44% 79.47%,59.66% 79.64%,58.11% 80.54%,57.04% 81.99%,56.09% 83.52%,55.14% 85.06%,54.20% 86.60%,53.21% 88.11%,51.79% 89.20%,50.04% 89.58%,48.28% 89.21%,46.86% 88.12%,45.86% 86.62%,44.91% 85.08%,43.96% 83.55%,43.00% 82.01%,41.94% 80.57%,40.39% 79.66%,38.61% 79.48%,36.89% 80.01%,35.22% 80.70%,33.55% 81.39%,31.88% 82.08%,30.20% 82.72%,28.41% 82.76%,26.76% 82.04%,25.57% 80.71%,25.05% 79.00%,25.13% 77.19%,25.26% 75.39%,25.39% 73.59%,25.52% 71.79%,25.51% 69.99%,24.80% 68.35%,23.46% 67.15%,21.75% 66.58%,20.00% 66.15%,18.24% 65.73%,16.49% 65.30%,14.75% 64.83%,13.27% 63.81%,12.37% 62.27%,12.18% 60.48%,12.77% 58.79%,13.90% 57.38%,15.06% 56.00%,16.23% 54.62%,17.39% 53.24%,18.44% 51.78%,18.83% 50.03%,18.45% 48.27%,17.41% 46.81%,16.23% 45.43%,15.06% 44.06%,13.89% 42.68%,12.76% 41.28%,12.17% 39.59%,12.34% 37.80%,13.24% 36.25%,14.71% 35.23%,16.45% 34.75%,18.21% 34.32%,19.96% 33.89%,21.71% 33.45%,23.42% 32.88%,24.76% 31.70%,25.49% 30.06%,25.51% 28.26%,25.37% 26.46%,25.23% 24.66%,25.09% 22.86%,25.00% 21.05%,25.51% 19.34%,26.70% 18.00%,28.34% 17.27%,30.13% 17.31%,31.82% 17.95%,33.50% 18.63%,35.17% 19.31%,36.84% 19.99%,38.56% 20.53%,40.34% 20.36%,41.89% 19.46%,42.96% 18.01%,43.91% 16.48%,44.86% 14.94%,45.80% 13.40%,46.79% 11.89%,48.21% 10.80%,49.96% 10.42%,51.72% 10.79%,53.14% 11.88%,54.14% 13.38%,55.09% 14.92%,56.04% 16.45%,57.00% 17.99%,58.06% 19.43%,59.61% 20.34%,61.39% 20.52%,63.11% 19.99%,64.78% 19.30%,66.45% 18.61%,68.12% 17.92%,69.80% 17.28%,71.59% 17.24%,73.24% 17.96%,74.43% 19.29%,74.95% 21.00%,74.87% 22.81%,74.74% 24.61%,74.61% 26.41%,74.48% 28.21%,74.49% 30.01%,75.20% 31.65%,76.54% 32.85%,78.25% 33.42%,80.00% 33.85%,81.76% 34.27%,83.51% 34.70%,85.25% 35.17%,86.73% 36.19%,87.63% 37.73%,87.82% 39.52%,87.23% 41.21%,86.10% 42.62%,84.94% 44.00%,83.77% 45.38%,82.61% 46.76%,81.56% 48.22%); rotate: -180deg; }
}
@keyframes md-li-snap {
  0% { clip-path: polygon(26.96% 36.05%,28.30% 35.39%,29.24% 34.22%,29.61% 32.77%,29.51% 31.27%,29.39% 29.77%,29.28% 28.26%,29.16% 26.76%,29.22% 25.26%,29.89% 23.92%,31.05% 22.98%,32.50% 22.62%,33.97% 22.90%,35.37% 23.46%,36.77% 24.03%,38.16% 24.60%,39.56% 25.17%,41.03% 25.42%,42.48% 25.03%,43.63% 24.08%,44.43% 22.80%,45.22% 21.52%,46.01% 20.24%,46.80% 18.95%,47.73% 17.77%,49.06% 17.08%,50.55% 17.01%,51.94% 17.56%,52.96% 18.65%,53.76% 19.93%,54.56% 21.21%,55.35% 22.49%,56.15% 23.77%,57.19% 24.85%,58.59% 25.38%,60.08% 25.28%,61.48% 24.73%,62.88% 24.15%,64.27% 23.58%,65.66% 23.00%,67.11% 22.60%,68.59% 22.81%,69.84% 23.63%,70.64% 24.90%,70.82% 26.38%,70.72% 27.89%,70.61% 29.39%,70.50% 30.89%,70.39% 32.40%,70.60% 33.88%,71.42% 35.13%,72.69% 35.93%,74.14% 36.30%,75.61% 36.66%,77.08% 37.01%,78.54% 37.37%,79.95% 37.88%,81.02% 38.93%,81.55% 40.33%,81.45% 41.82%,80.73% 43.13%,79.76% 44.28%,78.79% 45.44%,77.81% 46.59%,76.84% 47.74%,76.15% 49.07%,76.07% 50.56%,76.63% 51.95%,77.59% 53.11%,78.56% 54.26%,79.54% 55.41%,80.52% 56.55%,81.35% 57.80%,81.60% 59.28%,81.21% 60.72%,80.25% 61.87%,78.90% 62.51%,77.43% 62.87%,75.97% 63.23%,74.51% 63.59%,73.04% 63.95%,71.70% 64.61%,70.76% 65.78%,70.39% 67.23%,70.49% 68.73%,70.61% 70.23%,70.72% 71.74%,70.84% 73.24%,70.78% 74.74%,70.11% 76.08%,68.95% 77.02%,67.50% 77.38%,66.03% 77.10%,64.63% 76.54%,63.23% 75.97%,61.84% 75.40%,60.44% 74.83%,58.97% 74.58%,57.52% 74.97%,56.37% 75.92%,55.57% 77.20%,54.78% 78.48%,53.99% 79.76%,53.20% 81.05%,52.27% 82.23%,50.94% 82.92%,49.45% 82.99%,48.06% 82.44%,47.04% 81.35%,46.24% 80.07%,45.44% 78.79%,44.65% 77.51%,43.85% 76.23%,42.81% 75.15%,41.41% 74.62%,39.92% 74.72%,38.52% 75.27%,37.12% 75.85%,35.73% 76.42%,34.34% 77.00%,32.89% 77.40%,31.41% 77.19%,30.16% 76.37%,29.36% 75.10%,29.18% 73.62%,29.28% 72.11%,29.39% 70.61%,29.50% 69.11%,29.61% 67.60%,29.40% 66.12%,28.58% 64.87%,27.31% 64.07%,25.86% 63.70%,24.39% 63.34%,22.92% 62.99%,21.46% 62.63%,20.05% 62.12%,18.98% 61.07%,18.45% 59.67%,18.55% 58.18%,19.27% 56.87%,20.24% 55.72%,21.21% 54.56%,22.19% 53.41%,23.16% 52.26%,23.85% 50.93%,23.93% 49.44%,23.37% 48.05%,22.41% 46.89%,21.44% 45.74%,20.46% 44.59%,19.48% 43.45%,18.65% 42.20%,18.40% 40.72%,18.79% 39.28%,19.75% 38.13%,21.10% 37.49%,22.57% 37.13%,24.03% 36.77%,25.49% 36.41%); }
  0.69231% { clip-path: polygon(26.96% 36.05%,28.30% 35.39%,29.24% 34.22%,29.61% 32.77%,29.51% 31.27%,29.39% 29.77%,29.28% 28.26%,29.16% 26.76%,29.22% 25.26%,29.89% 23.92%,31.05% 22.98%,32.50% 22.62%,33.97% 22.90%,35.37% 23.46%,36.77% 24.03%,38.16% 24.60%,39.56% 25.17%,41.03% 25.42%,42.48% 25.03%,43.63% 24.08%,44.43% 22.80%,45.22% 21.52%,46.01% 20.24%,46.80% 18.95%,47.73% 17.77%,49.06% 17.08%,50.55% 17.01%,51.94% 17.56%,52.96% 18.65%,53.76% 19.93%,54.56% 21.21%,55.35% 22.49%,56.15% 23.77%,57.19% 24.85%,58.59% 25.38%,60.08% 25.28%,61.48% 24.73%,62.88% 24.15%,64.27% 23.58%,65.66% 23.00%,67.11% 22.60%,68.59% 22.81%,69.84% 23.63%,70.64% 24.90%,70.82% 26.38%,70.72% 27.89%,70.61% 29.39%,70.50% 30.89%,70.39% 32.40%,70.60% 33.88%,71.42% 35.13%,72.69% 35.93%,74.14% 36.30%,75.61% 36.66%,77.08% 37.01%,78.54% 37.37%,79.95% 37.88%,81.02% 38.93%,81.55% 40.33%,81.45% 41.82%,80.73% 43.13%,79.76% 44.28%,78.79% 45.44%,77.81% 46.59%,76.84% 47.74%,76.15% 49.07%,76.07% 50.56%,76.63% 51.95%,77.59% 53.11%,78.56% 54.26%,79.54% 55.41%,80.52% 56.55%,81.35% 57.80%,81.60% 59.28%,81.21% 60.72%,80.25% 61.87%,78.90% 62.51%,77.43% 62.87%,75.97% 63.23%,74.51% 63.59%,73.04% 63.95%,71.70% 64.61%,70.76% 65.78%,70.39% 67.23%,70.49% 68.73%,70.61% 70.23%,70.72% 71.74%,70.84% 73.24%,70.78% 74.74%,70.11% 76.08%,68.95% 77.02%,67.50% 77.38%,66.03% 77.10%,64.63% 76.54%,63.23% 75.97%,61.84% 75.40%,60.44% 74.83%,58.97% 74.58%,57.52% 74.97%,56.37% 75.92%,55.57% 77.20%,54.78% 78.48%,53.99% 79.76%,53.20% 81.05%,52.27% 82.23%,50.94% 82.92%,49.45% 82.99%,48.06% 82.44%,47.04% 81.35%,46.24% 80.07%,45.44% 78.79%,44.65% 77.51%,43.85% 76.23%,42.81% 75.15%,41.41% 74.62%,39.92% 74.72%,38.52% 75.27%,37.12% 75.85%,35.73% 76.42%,34.34% 77.00%,32.89% 77.40%,31.41% 77.19%,30.16% 76.37%,29.36% 75.10%,29.18% 73.62%,29.28% 72.11%,29.39% 70.61%,29.50% 69.11%,29.61% 67.60%,29.40% 66.12%,28.58% 64.87%,27.31% 64.07%,25.86% 63.70%,24.39% 63.34%,22.92% 62.99%,21.46% 62.63%,20.05% 62.12%,18.98% 61.07%,18.45% 59.67%,18.55% 58.18%,19.27% 56.87%,20.24% 55.72%,21.21% 54.56%,22.19% 53.41%,23.16% 52.26%,23.85% 50.93%,23.93% 49.44%,23.37% 48.05%,22.41% 46.89%,21.44% 45.74%,20.46% 44.59%,19.48% 43.45%,18.65% 42.20%,18.40% 40.72%,18.79% 39.28%,19.75% 38.13%,21.10% 37.49%,22.57% 37.13%,24.03% 36.77%,25.49% 36.41%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  2.89011% { clip-path: polygon(22.21% 37.36%,23.13% 36.23%,23.88% 34.98%,24.45% 33.63%,24.83% 32.22%,25.08% 30.78%,25.50% 29.38%,26.12% 28.05%,26.92% 26.82%,27.88% 25.72%,28.98% 24.76%,30.21% 23.97%,31.53% 23.36%,32.93% 22.94%,34.37% 22.72%,35.83% 22.70%,37.28% 22.62%,38.71% 22.34%,40.09% 21.87%,41.40% 21.20%,42.59% 20.36%,43.71% 19.42%,44.94% 18.62%,46.26% 18.00%,47.66% 17.57%,49.10% 17.34%,50.57% 17.32%,52.01% 17.50%,53.42% 17.88%,54.76% 18.46%,56.01% 19.21%,57.14% 20.13%,58.30% 21.01%,59.58% 21.72%,60.94% 22.25%,62.37% 22.57%,63.82% 22.70%,65.29% 22.70%,66.74% 22.87%,68.15% 23.24%,69.50% 23.82%,70.75% 24.57%,71.89% 25.49%,72.88% 26.56%,73.71% 27.76%,74.37% 29.06%,74.84% 30.44%,75.11% 31.87%,75.44% 33.29%,75.96% 34.66%,76.67% 35.93%,77.55% 37.10%,78.58% 38.13%,79.71% 39.07%,80.71% 40.14%,81.55% 41.33%,82.21% 42.64%,82.69% 44.02%,82.96% 45.45%,83.04% 46.91%,82.91% 48.36%,82.57% 49.78%,82.04% 51.14%,81.33% 52.42%,80.67% 53.71%,80.19% 55.09%,79.92% 56.53%,79.84% 57.99%,79.97% 59.44%,80.23% 60.89%,80.31% 62.35%,80.18% 63.80%,79.85% 65.23%,79.33% 66.59%,78.62% 67.87%,77.74% 69.03%,76.71% 70.06%,75.54% 70.93%,74.26% 71.63%,72.89% 72.15%,71.55% 72.72%,70.30% 73.47%,69.17% 74.39%,68.17% 75.46%,67.33% 76.66%,66.60% 77.93%,65.73% 79.10%,64.70% 80.14%,63.53% 81.02%,62.25% 81.73%,61.24% 82.13%,60.78% 82.28%,60.31% 82.40%,59.83% 82.51%,59.35% 82.59%,58.87% 82.65%,58.38% 82.68%,57.90% 82.70%,57.41% 82.69%,56.92% 82.65%,56.44% 82.60%,55.96% 82.52%,55.48% 82.42%,55.01% 82.30%,54.55% 82.15%,54.09% 81.98%,53.63% 81.81%,53.17% 81.65%,52.71% 81.51%,52.23% 81.39%,51.76% 81.30%,51.27% 81.23%,50.79% 81.18%,50.30% 81.16%,49.45% 81.17%,48.00% 81.35%,46.59% 81.73%,45.21% 82.23%,43.79% 82.56%,42.33% 82.69%,40.87% 82.62%,39.43% 82.34%,38.05% 81.86%,36.76% 81.19%,35.56% 80.36%,34.50% 79.36%,33.59% 78.22%,32.84% 76.97%,32.05% 75.74%,31.09% 74.64%,29.99% 73.68%,28.76% 72.89%,27.44% 72.27%,26.06% 71.77%,24.75% 71.11%,23.55% 70.28%,22.49% 69.28%,21.57% 68.14%,20.82% 66.89%,20.25% 65.55%,19.87% 64.14%,19.70% 62.69%,19.74% 61.23%,19.97% 59.79%,20.15% 58.34%,20.12% 56.88%,19.89% 55.44%,19.46% 54.04%,18.84% 52.72%,18.11% 51.45%,17.53% 50.11%,17.15% 48.70%,16.97% 47.25%,17.00% 45.78%,17.23% 44.34%,17.66% 42.95%,18.28% 41.63%,19.08% 40.41%,20.04% 39.31%,21.15% 38.36%); }
  2.89022% { clip-path: polygon(43.01% 20.00%,44.04% 19.18%,45.16% 18.50%,46.36% 17.96%,47.62% 17.58%,48.92% 17.36%,50.23% 17.31%,51.54% 17.42%,52.83% 17.69%,54.07% 18.13%,55.24% 18.72%,56.33% 19.45%,57.34% 20.30%,58.40% 21.08%,59.55% 21.71%,60.77% 22.19%,62.05% 22.52%,63.35% 22.68%,64.67% 22.68%,65.98% 22.75%,67.28% 22.98%,68.53% 23.38%,69.72% 23.93%,70.84% 24.63%,71.85% 25.46%,72.76% 26.42%,73.54% 27.48%,74.17% 28.63%,74.66% 29.85%,74.99% 31.12%,75.21% 32.42%,75.56% 33.68%,76.07% 34.89%,76.73% 36.03%,77.53% 37.08%,78.45% 38.01%,79.46% 38.85%,80.40% 39.78%,81.21% 40.81%,81.89% 41.94%,82.41% 43.14%,82.78% 44.41%,82.99% 45.70%,83.04% 47.02%,82.91% 48.33%,82.63% 49.61%,82.18% 50.85%,81.58% 52.01%,80.93% 53.16%,80.42% 54.37%,80.06% 55.64%,79.87% 56.94%,79.85% 58.25%,79.99% 59.56%,80.22% 60.85%,80.31% 62.16%,80.23% 63.48%,79.99% 64.77%,79.58% 66.02%,79.02% 67.21%,78.31% 68.32%,77.47% 69.33%,76.51% 70.23%,75.44% 70.99%,74.29% 71.62%,73.06% 72.10%,71.84% 72.58%,70.69% 73.21%,69.63% 73.99%,68.67% 74.89%,67.83% 75.90%,67.13% 77.02%,66.46% 78.15%,65.65% 79.18%,64.72% 80.11%,63.68% 80.92%,62.55% 81.58%,61.34% 82.10%,60.08% 82.46%,58.78% 82.66%,57.46% 82.69%,56.15% 82.56%,54.87% 82.26%,53.64% 81.81%,52.38% 81.43%,51.08% 81.21%,49.77% 81.15%,48.46% 81.27%,47.17% 81.54%,45.93% 81.98%,44.68% 82.38%,43.39% 82.62%,42.08% 82.70%,40.76% 82.60%,39.47% 82.35%,38.23% 81.93%,37.04% 81.36%,35.94% 80.65%,34.94% 79.80%,34.05% 78.83%,33.29% 77.76%,32.64% 76.61%,31.89% 75.53%,31.01% 74.56%,30.01% 73.70%,28.92% 72.97%,27.74% 72.39%,26.50% 71.95%,25.30% 71.42%,24.17% 70.74%,23.14% 69.92%,22.22% 68.98%,21.42% 67.94%,20.77% 66.80%,20.26% 65.58%,19.91% 64.32%,19.72% 63.02%,19.70% 61.70%,19.85% 60.39%,20.08% 59.10%,20.16% 57.79%,20.08% 56.48%,19.83% 55.18%,19.42% 53.94%,18.86% 52.75%,18.19% 51.61%,17.65% 50.42%,17.25% 49.16%,17.03% 47.87%,16.96% 46.55%,17.06% 45.24%,17.33% 43.96%,17.76% 42.71%,18.33% 41.53%,19.06% 40.44%,19.92% 39.44%,20.89% 38.56%,21.89% 37.70%,22.77% 36.72%,23.52% 35.64%,24.12% 34.48%,24.58% 33.24%,24.88% 31.96%,25.11% 30.67%,25.49% 29.41%,26.03% 28.21%,26.72% 27.09%,27.55% 26.07%,28.49% 25.16%,29.55% 24.37%,30.69% 23.72%,31.91% 23.22%,33.18% 22.89%,34.48% 22.71%,35.79% 22.70%,37.11% 22.64%,38.40% 22.42%,39.66% 22.04%,40.86% 21.50%,41.99% 20.82%); }
  14.97802% { clip-path: polygon(43.01% 20.00%,44.04% 19.18%,45.16% 18.50%,46.36% 17.96%,47.62% 17.58%,48.92% 17.36%,50.23% 17.31%,51.54% 17.42%,52.83% 17.69%,54.07% 18.13%,55.24% 18.72%,56.33% 19.45%,57.34% 20.30%,58.40% 21.08%,59.55% 21.71%,60.77% 22.19%,62.05% 22.52%,63.35% 22.68%,64.67% 22.68%,65.98% 22.75%,67.28% 22.98%,68.53% 23.38%,69.72% 23.93%,70.84% 24.63%,71.85% 25.46%,72.76% 26.42%,73.54% 27.48%,74.17% 28.63%,74.66% 29.85%,74.99% 31.12%,75.21% 32.42%,75.56% 33.68%,76.07% 34.89%,76.73% 36.03%,77.53% 37.08%,78.45% 38.01%,79.46% 38.85%,80.40% 39.78%,81.21% 40.81%,81.89% 41.94%,82.41% 43.14%,82.78% 44.41%,82.99% 45.70%,83.04% 47.02%,82.91% 48.33%,82.63% 49.61%,82.18% 50.85%,81.58% 52.01%,80.93% 53.16%,80.42% 54.37%,80.06% 55.64%,79.87% 56.94%,79.85% 58.25%,79.99% 59.56%,80.22% 60.85%,80.31% 62.16%,80.23% 63.48%,79.99% 64.77%,79.58% 66.02%,79.02% 67.21%,78.31% 68.32%,77.47% 69.33%,76.51% 70.23%,75.44% 70.99%,74.29% 71.62%,73.06% 72.10%,71.84% 72.58%,70.69% 73.21%,69.63% 73.99%,68.67% 74.89%,67.83% 75.90%,67.13% 77.02%,66.46% 78.15%,65.65% 79.18%,64.72% 80.11%,63.68% 80.92%,62.55% 81.58%,61.34% 82.10%,60.08% 82.46%,58.78% 82.66%,57.46% 82.69%,56.15% 82.56%,54.87% 82.26%,53.64% 81.81%,52.38% 81.43%,51.08% 81.21%,49.77% 81.15%,48.46% 81.27%,47.17% 81.54%,45.93% 81.98%,44.68% 82.38%,43.39% 82.62%,42.08% 82.70%,40.76% 82.60%,39.47% 82.35%,38.23% 81.93%,37.04% 81.36%,35.94% 80.65%,34.94% 79.80%,34.05% 78.83%,33.29% 77.76%,32.64% 76.61%,31.89% 75.53%,31.01% 74.56%,30.01% 73.70%,28.92% 72.97%,27.74% 72.39%,26.50% 71.95%,25.30% 71.42%,24.17% 70.74%,23.14% 69.92%,22.22% 68.98%,21.42% 67.94%,20.77% 66.80%,20.26% 65.58%,19.91% 64.32%,19.72% 63.02%,19.70% 61.70%,19.85% 60.39%,20.08% 59.10%,20.16% 57.79%,20.08% 56.48%,19.83% 55.18%,19.42% 53.94%,18.86% 52.75%,18.19% 51.61%,17.65% 50.42%,17.25% 49.16%,17.03% 47.87%,16.96% 46.55%,17.06% 45.24%,17.33% 43.96%,17.76% 42.71%,18.33% 41.53%,19.06% 40.44%,19.92% 39.44%,20.89% 38.56%,21.89% 37.70%,22.77% 36.72%,23.52% 35.64%,24.12% 34.48%,24.58% 33.24%,24.88% 31.96%,25.11% 30.67%,25.49% 29.41%,26.03% 28.21%,26.72% 27.09%,27.55% 26.07%,28.49% 25.16%,29.55% 24.37%,30.69% 23.72%,31.91% 23.22%,33.18% 22.89%,34.48% 22.71%,35.79% 22.70%,37.11% 22.64%,38.40% 22.42%,39.66% 22.04%,40.86% 21.50%,41.99% 20.82%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  17.17582% { clip-path: polygon(43.71% 20.82%,44.69% 20.23%,45.73% 19.75%,46.81% 19.37%,47.92% 19.11%,49.06% 18.96%,50.20% 18.92%,51.34% 19.00%,52.47% 19.19%,53.57% 19.49%,54.64% 19.91%,55.66% 20.43%,56.62% 21.05%,57.56% 21.71%,58.50% 22.37%,59.43% 23.03%,60.37% 23.69%,61.30% 24.35%,62.24% 25.01%,63.17% 25.67%,64.11% 26.33%,65.04% 26.99%,65.98% 27.65%,66.92% 28.31%,67.85% 28.97%,68.79% 29.63%,69.72% 30.29%,70.66% 30.95%,71.59% 31.61%,72.53% 32.27%,73.47% 32.93%,74.40% 33.59%,75.34% 34.25%,76.27% 34.91%,77.21% 35.57%,78.14% 36.23%,79.06% 36.91%,79.91% 37.68%,80.67% 38.54%,81.34% 39.47%,81.90% 40.46%,82.35% 41.51%,82.69% 42.59%,82.92% 43.69%,83.03% 44.81%,83.02% 45.93%,82.90% 47.05%,82.66% 48.15%,82.32% 49.22%,81.96% 50.29%,81.61% 51.35%,81.25% 52.42%,80.90% 53.48%,80.54% 54.55%,80.18% 55.62%,79.83% 56.68%,79.47% 57.75%,79.12% 58.81%,78.76% 59.88%,78.40% 60.95%,78.05% 62.01%,77.69% 63.08%,77.34% 64.14%,76.98% 65.21%,76.63% 66.28%,76.27% 67.34%,75.91% 68.41%,75.56% 69.47%,75.20% 70.54%,74.85% 71.61%,74.49% 72.67%,74.13% 73.74%,73.69% 74.77%,73.15% 75.76%,72.52% 76.68%,71.79% 77.54%,70.99% 78.32%,70.04% 79.06%,68.02% 80.19%,65.81% 80.87%,63.50% 81.08%,61.18% 81.08%,58.87% 81.08%,56.55% 81.08%,54.23% 81.08%,51.91% 81.08%,49.59% 81.08%,47.27% 81.08%,44.96% 81.08%,42.64% 81.08%,40.32% 81.08%,38.00% 81.08%,35.68% 81.06%,33.40% 80.68%,31.24% 79.84%,29.58% 78.78%,28.72% 78.06%,27.94% 77.25%,27.25% 76.37%,26.65% 75.42%,26.14% 74.41%,25.74% 73.36%,25.39% 72.30%,25.03% 71.23%,24.67% 70.17%,24.32% 69.10%,23.96% 68.03%,23.61% 66.97%,23.25% 65.90%,22.89% 64.84%,22.54% 63.77%,22.18% 62.70%,21.83% 61.64%,21.47% 60.57%,21.11% 59.51%,20.76% 58.44%,20.40% 57.37%,20.05% 56.31%,19.69% 55.24%,19.33% 54.18%,18.98% 53.11%,18.62% 52.04%,18.27% 50.98%,17.91% 49.91%,17.55% 48.85%,17.24% 47.77%,17.05% 46.66%,16.96% 45.54%,17.00% 44.42%,17.15% 43.30%,17.41% 42.21%,17.79% 41.14%,18.29% 40.11%,18.89% 39.13%,19.59% 38.23%,20.38% 37.40%,21.25% 36.66%,22.19% 36.00%,23.12% 35.34%,24.06% 34.68%,24.99% 34.02%,25.93% 33.36%,26.86% 32.70%,27.80% 32.04%,28.74% 31.38%,29.67% 30.72%,30.61% 30.06%,31.54% 29.40%,32.48% 28.74%,33.41% 28.08%,34.35% 27.41%,35.28% 26.75%,36.22% 26.09%,37.16% 25.43%,38.09% 24.77%,39.03% 24.11%,39.96% 23.45%,40.90% 22.79%,41.83% 22.13%,42.77% 21.47%); }
  17.17593% { clip-path: polygon(43.44% 21.00%,44.52% 20.33%,45.66% 19.78%,46.85% 19.36%,48.09% 19.08%,49.34% 18.94%,50.61% 18.93%,51.87% 19.07%,53.10% 19.35%,54.30% 19.76%,55.44% 20.30%,56.52% 20.97%,57.55% 21.70%,58.59% 22.43%,59.62% 23.16%,60.65% 23.89%,61.69% 24.62%,62.72% 25.35%,63.76% 26.08%,64.79% 26.81%,65.83% 27.54%,66.86% 28.27%,67.89% 29.00%,68.93% 29.73%,69.96% 30.46%,71.00% 31.19%,72.03% 31.92%,73.07% 32.65%,74.10% 33.38%,75.14% 34.11%,76.17% 34.84%,77.20% 35.57%,78.24% 36.30%,79.24% 37.07%,80.16% 37.94%,80.96% 38.92%,81.64% 39.98%,82.20% 41.12%,82.62% 42.31%,82.90% 43.55%,83.03% 44.81%,83.01% 46.07%,82.85% 47.33%,82.54% 48.55%,82.14% 49.76%,81.74% 50.96%,81.34% 52.16%,80.94% 53.36%,80.54% 54.56%,80.14% 55.76%,79.74% 56.96%,79.33% 58.16%,78.93% 59.36%,78.53% 60.56%,78.13% 61.76%,77.73% 62.96%,77.33% 64.17%,76.93% 65.37%,76.53% 66.57%,76.13% 67.77%,75.73% 68.97%,75.33% 70.17%,74.92% 71.37%,74.52% 72.57%,74.12% 73.77%,73.61% 74.93%,72.98% 76.03%,72.23% 77.05%,71.37% 77.97%,70.41% 78.80%,69.36% 79.50%,68.24% 80.09%,67.06% 80.55%,65.83% 80.86%,64.58% 81.04%,63.32% 81.08%,62.05% 81.08%,60.78% 81.08%,59.52% 81.08%,58.25% 81.08%,56.99% 81.08%,55.72% 81.08%,54.45% 81.08%,53.19% 81.08%,51.92% 81.08%,50.66% 81.08%,49.39% 81.08%,48.12% 81.08%,46.86% 81.08%,45.59% 81.08%,44.33% 81.08%,43.06% 81.08%,41.79% 81.08%,40.53% 81.08%,39.26% 81.08%,38.00% 81.08%,36.73% 81.08%,35.47% 81.05%,34.21% 80.87%,32.99% 80.56%,31.80% 80.11%,30.68% 79.53%,29.63% 78.82%,28.67% 78.00%,27.80% 77.08%,27.04% 76.07%,26.41% 74.97%,25.90% 73.81%,25.49% 72.62%,25.09% 71.42%,24.69% 70.21%,24.29% 69.01%,23.89% 67.81%,23.49% 66.61%,23.09% 65.41%,22.68% 64.21%,22.28% 63.01%,21.88% 61.81%,21.48% 60.61%,21.08% 59.41%,20.68% 58.21%,20.28% 57.01%,19.88% 55.80%,19.48% 54.60%,19.08% 53.40%,18.68% 52.20%,18.27% 51.00%,17.87% 49.80%,17.47% 48.60%,17.16% 47.37%,16.99% 46.12%,16.97% 44.85%,17.10% 43.60%,17.37% 42.36%,17.78% 41.16%,18.33% 40.02%,19.01% 38.96%,19.81% 37.98%,20.72% 37.10%,21.72% 36.32%,22.76% 35.59%,23.79% 34.86%,24.83% 34.13%,25.86% 33.40%,26.89% 32.67%,27.93% 31.95%,28.96% 31.22%,30.00% 30.49%,31.03% 29.76%,32.07% 29.03%,33.10% 28.30%,34.14% 27.57%,35.17% 26.84%,36.20% 26.11%,37.24% 25.38%,38.27% 24.65%,39.31% 23.92%,40.34% 23.19%,41.38% 22.46%,42.41% 21.73%); }
  29.26374% { clip-path: polygon(43.44% 21.00%,44.52% 20.33%,45.66% 19.78%,46.85% 19.36%,48.09% 19.08%,49.34% 18.94%,50.61% 18.93%,51.87% 19.07%,53.10% 19.35%,54.30% 19.76%,55.44% 20.30%,56.52% 20.97%,57.55% 21.70%,58.59% 22.43%,59.62% 23.16%,60.65% 23.89%,61.69% 24.62%,62.72% 25.35%,63.76% 26.08%,64.79% 26.81%,65.83% 27.54%,66.86% 28.27%,67.89% 29.00%,68.93% 29.73%,69.96% 30.46%,71.00% 31.19%,72.03% 31.92%,73.07% 32.65%,74.10% 33.38%,75.14% 34.11%,76.17% 34.84%,77.20% 35.57%,78.24% 36.30%,79.24% 37.07%,80.16% 37.94%,80.96% 38.92%,81.64% 39.98%,82.20% 41.12%,82.62% 42.31%,82.90% 43.55%,83.03% 44.81%,83.01% 46.07%,82.85% 47.33%,82.54% 48.55%,82.14% 49.76%,81.74% 50.96%,81.34% 52.16%,80.94% 53.36%,80.54% 54.56%,80.14% 55.76%,79.74% 56.96%,79.33% 58.16%,78.93% 59.36%,78.53% 60.56%,78.13% 61.76%,77.73% 62.96%,77.33% 64.17%,76.93% 65.37%,76.53% 66.57%,76.13% 67.77%,75.73% 68.97%,75.33% 70.17%,74.92% 71.37%,74.52% 72.57%,74.12% 73.77%,73.61% 74.93%,72.98% 76.03%,72.23% 77.05%,71.37% 77.97%,70.41% 78.80%,69.36% 79.50%,68.24% 80.09%,67.06% 80.55%,65.83% 80.86%,64.58% 81.04%,63.32% 81.08%,62.05% 81.08%,60.78% 81.08%,59.52% 81.08%,58.25% 81.08%,56.99% 81.08%,55.72% 81.08%,54.45% 81.08%,53.19% 81.08%,51.92% 81.08%,50.66% 81.08%,49.39% 81.08%,48.12% 81.08%,46.86% 81.08%,45.59% 81.08%,44.33% 81.08%,43.06% 81.08%,41.79% 81.08%,40.53% 81.08%,39.26% 81.08%,38.00% 81.08%,36.73% 81.08%,35.47% 81.05%,34.21% 80.87%,32.99% 80.56%,31.80% 80.11%,30.68% 79.53%,29.63% 78.82%,28.67% 78.00%,27.80% 77.08%,27.04% 76.07%,26.41% 74.97%,25.90% 73.81%,25.49% 72.62%,25.09% 71.42%,24.69% 70.21%,24.29% 69.01%,23.89% 67.81%,23.49% 66.61%,23.09% 65.41%,22.68% 64.21%,22.28% 63.01%,21.88% 61.81%,21.48% 60.61%,21.08% 59.41%,20.68% 58.21%,20.28% 57.01%,19.88% 55.80%,19.48% 54.60%,19.08% 53.40%,18.68% 52.20%,18.27% 51.00%,17.87% 49.80%,17.47% 48.60%,17.16% 47.37%,16.99% 46.12%,16.97% 44.85%,17.10% 43.60%,17.37% 42.36%,17.78% 41.16%,18.33% 40.02%,19.01% 38.96%,19.81% 37.98%,20.72% 37.10%,21.72% 36.32%,22.76% 35.59%,23.79% 34.86%,24.83% 34.13%,25.86% 33.40%,26.89% 32.67%,27.93% 31.95%,28.96% 31.22%,30.00% 30.49%,31.03% 29.76%,32.07% 29.03%,33.10% 28.30%,34.14% 27.57%,35.17% 26.84%,36.20% 26.11%,37.24% 25.38%,38.27% 24.65%,39.31% 23.92%,40.34% 23.19%,41.38% 22.46%,42.41% 21.73%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  31.46154% { clip-path: polygon(38.42% 22.09%,39.33% 21.49%,40.27% 20.92%,41.23% 20.38%,42.20% 19.89%,43.20% 19.43%,44.49% 18.89%,46.12% 18.32%,47.78% 17.85%,49.47% 17.47%,51.18% 17.20%,52.90% 17.03%,54.62% 16.96%,56.34% 17.12%,58.06% 17.31%,59.77% 17.56%,61.46% 17.92%,63.12% 18.37%,64.76% 18.94%,66.35% 19.60%,67.90% 20.36%,69.41% 21.21%,70.85% 22.16%,72.24% 23.19%,73.56% 24.30%,74.81% 25.50%,75.98% 26.76%,77.08% 28.10%,78.09% 29.50%,79.01% 30.96%,79.84% 32.48%,80.57% 34.04%,81.21% 35.65%,81.75% 37.29%,82.18% 38.96%,82.52% 40.66%,82.74% 42.37%,82.92% 44.09%,83.03% 45.73%,82.96% 47.20%,82.82% 48.67%,82.60% 50.13%,82.31% 51.57%,81.94% 53.00%,81.50% 54.41%,81.00% 55.80%,80.42% 57.15%,79.77% 58.48%,79.06% 59.77%,78.28% 61.02%,77.44% 62.24%,76.54% 63.41%,75.58% 64.53%,74.56% 65.60%,73.52% 66.64%,72.48% 67.68%,71.43% 68.73%,70.39% 69.77%,69.35% 70.81%,68.31% 71.86%,67.26% 72.90%,66.22% 73.94%,65.17% 74.98%,64.08% 75.97%,62.94% 76.91%,61.75% 77.79%,60.52% 78.60%,59.25% 79.35%,57.95% 80.04%,56.61% 80.66%,55.56% 81.09%,54.59% 81.44%,53.62% 81.76%,52.63% 82.05%,51.63% 82.29%,50.63% 82.51%,49.61% 82.69%,48.60% 82.83%,47.58% 82.93%,46.55% 83.00%,45.52% 83.04%,44.50% 82.96%,43.48% 82.86%,42.46% 82.75%,41.44% 82.63%,40.42% 82.48%,39.41% 82.28%,38.41% 82.05%,37.42% 81.79%,36.44% 81.48%,35.47% 81.15%,34.51% 80.77%,33.57% 80.36%,32.64% 79.92%,31.73% 79.45%,30.84% 78.94%,29.97% 78.39%,29.11% 77.82%,28.28% 77.22%,27.47% 76.58%,26.69% 75.92%,25.93% 75.23%,25.19% 74.50%,24.46% 73.74%,23.76% 72.94%,23.09% 72.12%,22.45% 71.27%,21.85% 70.40%,21.28% 69.51%,20.74% 68.60%,20.23% 67.67%,19.77% 66.72%,19.34% 65.75%,18.94% 64.77%,18.58% 63.77%,18.26% 62.76%,17.98% 61.74%,17.74% 60.70%,17.54% 59.66%,17.38% 58.62%,17.25% 57.56%,17.14% 56.51%,17.03% 55.46%,16.96% 54.40%,17.00% 53.34%,17.08% 52.29%,17.19% 51.23%,17.35% 50.18%,17.54% 49.14%,17.77% 48.11%,18.03% 47.08%,18.34% 46.07%,18.68% 45.06%,19.06% 44.07%,19.48% 43.08%,19.94% 42.08%,20.45% 41.11%,20.99% 40.16%,21.56% 39.22%,22.17% 38.31%,22.81% 37.42%,23.49% 36.56%,24.20% 35.72%,24.94% 34.92%,25.70% 34.13%,26.48% 33.36%,27.25% 32.58%,28.03% 31.81%,28.80% 31.03%,29.58% 30.26%,30.35% 29.48%,31.13% 28.71%,31.90% 27.93%,32.68% 27.16%,33.45% 26.38%,34.23% 25.61%,35.01% 24.84%,35.83% 24.11%,36.66% 23.40%,37.53% 22.73%); }
  31.46165% { clip-path: polygon(57.67% 17.26%,58.93% 17.42%,60.19% 17.64%,61.44% 17.91%,62.67% 18.24%,63.89% 18.62%,65.09% 19.07%,66.26% 19.56%,67.42% 20.11%,68.54% 20.71%,69.64% 21.36%,70.71% 22.06%,71.75% 22.80%,72.75% 23.60%,73.71% 24.44%,74.63% 25.32%,75.51% 26.24%,76.36% 27.20%,77.15% 28.20%,77.90% 29.23%,78.61% 30.30%,79.26% 31.39%,79.86% 32.52%,80.41% 33.67%,80.91% 34.85%,81.35% 36.04%,81.74% 37.26%,82.07% 38.49%,82.35% 39.74%,82.57% 41.00%,82.73% 42.26%,82.86% 43.53%,82.99% 44.80%,83.02% 46.08%,82.95% 47.35%,82.83% 48.62%,82.64% 49.88%,82.40% 51.14%,82.11% 52.38%,81.76% 53.61%,81.36% 54.82%,80.91% 56.01%,80.40% 57.19%,79.85% 58.33%,79.24% 59.46%,78.58% 60.55%,77.88% 61.62%,77.13% 62.65%,76.34% 63.65%,75.50% 64.62%,74.62% 65.54%,73.72% 66.44%,72.82% 67.35%,71.91% 68.25%,71.01% 69.15%,70.11% 70.06%,69.20% 70.96%,68.30% 71.86%,67.40% 72.76%,66.50% 73.67%,65.59% 74.57%,64.67% 75.45%,63.71% 76.29%,62.71% 77.09%,61.68% 77.84%,60.61% 78.54%,59.52% 79.20%,58.40% 79.81%,57.25% 80.37%,56.08% 80.88%,54.89% 81.34%,53.68% 81.74%,52.45% 82.09%,51.21% 82.39%,49.95% 82.63%,48.69% 82.82%,47.42% 82.95%,46.15% 83.02%,44.87% 83.00%,43.60% 82.87%,42.33% 82.74%,41.07% 82.58%,39.81% 82.36%,38.56% 82.09%,37.33% 81.76%,36.11% 81.38%,34.91% 80.93%,33.74% 80.44%,32.58% 79.89%,31.46% 79.29%,30.36% 78.64%,29.29% 77.94%,28.25% 77.20%,27.25% 76.40%,26.29% 75.56%,25.37% 74.68%,24.49% 73.76%,23.64% 72.80%,22.85% 71.80%,22.10% 70.77%,21.39% 69.70%,20.74% 68.61%,20.14% 67.48%,19.59% 66.33%,19.09% 65.15%,18.65% 63.96%,18.26% 62.74%,17.93% 61.51%,17.65% 60.26%,17.43% 59.00%,17.27% 57.74%,17.14% 56.47%,17.01% 55.20%,16.98% 53.92%,17.05% 52.65%,17.17% 51.38%,17.36% 50.12%,17.60% 48.86%,17.89% 47.62%,18.24% 46.39%,18.64% 45.18%,19.09% 43.99%,19.60% 42.81%,20.15% 41.67%,20.76% 40.54%,21.42% 39.45%,22.12% 38.38%,22.87% 37.35%,23.66% 36.35%,24.50% 35.38%,25.38% 34.46%,26.28% 33.56%,27.18% 32.65%,28.09% 31.75%,28.99% 30.85%,29.89% 29.94%,30.80% 29.04%,31.70% 28.14%,32.60% 27.24%,33.50% 26.33%,34.41% 25.43%,35.33% 24.55%,36.29% 23.71%,37.29% 22.91%,38.32% 22.16%,39.39% 21.46%,40.48% 20.80%,41.60% 20.19%,42.75% 19.63%,43.92% 19.12%,45.11% 18.66%,46.32% 18.26%,47.55% 17.91%,48.79% 17.61%,50.05% 17.37%,51.31% 17.18%,52.58% 17.05%,53.85% 16.98%,55.13% 17.00%,56.40% 17.13%); }
  43.54945% { clip-path: polygon(57.67% 17.26%,58.93% 17.42%,60.19% 17.64%,61.44% 17.91%,62.67% 18.24%,63.89% 18.62%,65.09% 19.07%,66.26% 19.56%,67.42% 20.11%,68.54% 20.71%,69.64% 21.36%,70.71% 22.06%,71.75% 22.80%,72.75% 23.60%,73.71% 24.44%,74.63% 25.32%,75.51% 26.24%,76.36% 27.20%,77.15% 28.20%,77.90% 29.23%,78.61% 30.30%,79.26% 31.39%,79.86% 32.52%,80.41% 33.67%,80.91% 34.85%,81.35% 36.04%,81.74% 37.26%,82.07% 38.49%,82.35% 39.74%,82.57% 41.00%,82.73% 42.26%,82.86% 43.53%,82.99% 44.80%,83.02% 46.08%,82.95% 47.35%,82.83% 48.62%,82.64% 49.88%,82.40% 51.14%,82.11% 52.38%,81.76% 53.61%,81.36% 54.82%,80.91% 56.01%,80.40% 57.19%,79.85% 58.33%,79.24% 59.46%,78.58% 60.55%,77.88% 61.62%,77.13% 62.65%,76.34% 63.65%,75.50% 64.62%,74.62% 65.54%,73.72% 66.44%,72.82% 67.35%,71.91% 68.25%,71.01% 69.15%,70.11% 70.06%,69.20% 70.96%,68.30% 71.86%,67.40% 72.76%,66.50% 73.67%,65.59% 74.57%,64.67% 75.45%,63.71% 76.29%,62.71% 77.09%,61.68% 77.84%,60.61% 78.54%,59.52% 79.20%,58.40% 79.81%,57.25% 80.37%,56.08% 80.88%,54.89% 81.34%,53.68% 81.74%,52.45% 82.09%,51.21% 82.39%,49.95% 82.63%,48.69% 82.82%,47.42% 82.95%,46.15% 83.02%,44.87% 83.00%,43.60% 82.87%,42.33% 82.74%,41.07% 82.58%,39.81% 82.36%,38.56% 82.09%,37.33% 81.76%,36.11% 81.38%,34.91% 80.93%,33.74% 80.44%,32.58% 79.89%,31.46% 79.29%,30.36% 78.64%,29.29% 77.94%,28.25% 77.20%,27.25% 76.40%,26.29% 75.56%,25.37% 74.68%,24.49% 73.76%,23.64% 72.80%,22.85% 71.80%,22.10% 70.77%,21.39% 69.70%,20.74% 68.61%,20.14% 67.48%,19.59% 66.33%,19.09% 65.15%,18.65% 63.96%,18.26% 62.74%,17.93% 61.51%,17.65% 60.26%,17.43% 59.00%,17.27% 57.74%,17.14% 56.47%,17.01% 55.20%,16.98% 53.92%,17.05% 52.65%,17.17% 51.38%,17.36% 50.12%,17.60% 48.86%,17.89% 47.62%,18.24% 46.39%,18.64% 45.18%,19.09% 43.99%,19.60% 42.81%,20.15% 41.67%,20.76% 40.54%,21.42% 39.45%,22.12% 38.38%,22.87% 37.35%,23.66% 36.35%,24.50% 35.38%,25.38% 34.46%,26.28% 33.56%,27.18% 32.65%,28.09% 31.75%,28.99% 30.85%,29.89% 29.94%,30.80% 29.04%,31.70% 28.14%,32.60% 27.24%,33.50% 26.33%,34.41% 25.43%,35.33% 24.55%,36.29% 23.71%,37.29% 22.91%,38.32% 22.16%,39.39% 21.46%,40.48% 20.80%,41.60% 20.19%,42.75% 19.63%,43.92% 19.12%,45.11% 18.66%,46.32% 18.26%,47.55% 17.91%,48.79% 17.61%,50.05% 17.37%,51.31% 17.18%,52.58% 17.05%,53.85% 16.98%,55.13% 17.00%,56.40% 17.13%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  45.74725% { clip-path: polygon(53.23% 18.08%,54.38% 19.06%,55.54% 20.05%,56.69% 21.03%,57.84% 22.01%,59.00% 23.00%,60.22% 23.89%,61.63% 24.41%,63.14% 24.57%,64.65% 24.70%,66.16% 24.82%,67.67% 24.94%,69.18% 25.06%,70.69% 25.21%,72.11% 25.72%,73.33% 26.61%,74.24% 27.81%,74.77% 29.23%,74.94% 30.73%,75.06% 32.24%,75.18% 33.75%,75.30% 35.26%,75.42% 36.77%,75.57% 38.28%,76.07% 39.71%,76.95% 40.94%,77.93% 42.09%,78.92% 43.24%,79.90% 44.40%,80.88% 45.55%,81.86% 46.71%,82.64% 48.00%,83.01% 49.46%,82.69% 51.87%,81.02% 54.29%,79.10% 56.54%,77.18% 58.79%,75.67% 61.30%,75.34% 64.24%,75.10% 67.19%,74.87% 70.14%,73.80% 72.86%,72.95% 73.74%,72.36% 74.15%,71.72% 74.47%,71.04% 74.71%,70.33% 74.85%,69.61% 74.91%,68.90% 74.97%,68.18% 75.02%,67.46% 75.08%,66.74% 75.14%,66.03% 75.20%,65.31% 75.25%,64.59% 75.31%,63.87% 75.37%,63.16% 75.42%,62.44% 75.48%,61.72% 75.57%,61.03% 75.75%,60.37% 76.03%,59.75% 76.40%,59.18% 76.85%,58.64% 77.31%,58.09% 77.78%,57.54% 78.25%,56.99% 78.71%,56.44% 79.18%,55.90% 79.65%,55.35% 80.12%,54.80% 80.58%,54.25% 81.05%,53.70% 81.52%,53.15% 81.98%,52.55% 82.37%,51.90% 82.68%,51.21% 82.90%,50.50% 83.02%,49.55% 83.02%,48.08% 82.67%,46.77% 81.92%,45.62% 80.94%,44.46% 79.95%,43.31% 78.97%,42.16% 77.99%,41.00% 77.00%,39.78% 76.11%,38.37% 75.59%,36.86% 75.43%,35.35% 75.30%,33.84% 75.18%,32.33% 75.06%,30.82% 74.94%,29.31% 74.79%,27.89% 74.28%,26.67% 73.39%,25.76% 72.19%,25.23% 70.77%,25.06% 69.27%,24.94% 67.76%,24.82% 66.25%,24.70% 64.74%,24.58% 63.23%,24.43% 61.72%,23.93% 60.29%,23.05% 59.06%,22.07% 57.91%,21.08% 56.76%,20.10% 55.60%,19.12% 54.45%,18.14% 53.29%,17.36% 52.00%,16.99% 50.54%,16.98% 49.54%,17.09% 48.83%,17.30% 48.14%,17.61% 47.49%,18.00% 46.88%,18.46% 46.33%,18.92% 45.78%,19.39% 45.23%,19.86% 44.68%,20.32% 44.14%,20.79% 43.59%,21.26% 43.04%,21.73% 42.49%,22.19% 41.94%,22.66% 41.40%,23.13% 40.85%,23.58% 40.29%,23.95% 39.67%,24.23% 39.01%,24.42% 38.32%,24.52% 37.60%,24.57% 36.88%,24.63% 36.17%,24.69% 35.45%,24.74% 34.73%,24.80% 34.01%,24.86% 33.30%,24.92% 32.58%,24.97% 31.86%,25.03% 31.14%,25.09% 30.43%,25.15% 29.71%,25.28% 29.00%,25.51% 28.32%,25.83% 27.68%,26.24% 27.08%,27.01% 26.30%,29.69% 25.15%,32.64% 24.91%,35.59% 24.68%,38.53% 24.37%,41.08% 22.93%,43.33% 21.01%,45.59% 19.09%,47.98% 17.37%,50.45% 16.98%,51.92% 17.33%); }
  45.74736% { clip-path: polygon(81.80% 46.63%,82.52% 47.72%,82.94% 48.96%,83.03% 50.27%,82.80% 51.56%,82.26% 52.75%,81.45% 53.78%,80.60% 54.78%,79.75% 55.78%,78.90% 56.78%,78.04% 57.78%,77.19% 58.78%,76.37% 59.80%,75.78% 60.97%,75.50% 62.25%,75.39% 63.56%,75.29% 64.86%,75.18% 66.17%,75.08% 67.48%,74.97% 68.79%,74.87% 70.10%,74.60% 71.38%,74.02% 72.56%,73.17% 73.55%,72.09% 74.30%,70.87% 74.75%,69.56% 74.91%,68.26% 75.02%,66.95% 75.12%,65.64% 75.23%,64.33% 75.33%,63.02% 75.43%,61.72% 75.57%,60.47% 75.98%,59.37% 76.69%,58.37% 77.54%,57.37% 78.39%,56.37% 79.24%,55.37% 80.09%,54.37% 80.95%,53.37% 81.80%,52.28% 82.52%,51.04% 82.94%,49.73% 83.03%,48.44% 82.80%,47.25% 82.26%,46.22% 81.45%,45.22% 80.60%,44.22% 79.75%,43.22% 78.90%,42.22% 78.04%,41.22% 77.19%,40.20% 76.37%,39.03% 75.78%,37.75% 75.50%,36.44% 75.39%,35.14% 75.29%,33.83% 75.18%,32.52% 75.08%,31.21% 74.97%,29.90% 74.87%,28.62% 74.60%,27.44% 74.02%,26.45% 73.17%,25.70% 72.09%,25.25% 70.87%,25.09% 69.56%,24.98% 68.26%,24.88% 66.95%,24.77% 65.64%,24.67% 64.33%,24.57% 63.02%,24.43% 61.72%,24.02% 60.47%,23.31% 59.37%,22.46% 58.37%,21.61% 57.37%,20.76% 56.37%,19.91% 55.37%,19.05% 54.37%,18.20% 53.37%,17.48% 52.28%,17.06% 51.04%,16.97% 49.73%,17.20% 48.44%,17.74% 47.25%,18.55% 46.22%,19.40% 45.22%,20.25% 44.22%,21.10% 43.22%,21.96% 42.22%,22.81% 41.22%,23.63% 40.20%,24.22% 39.03%,24.50% 37.75%,24.61% 36.44%,24.71% 35.14%,24.82% 33.83%,24.92% 32.52%,25.03% 31.21%,25.13% 29.90%,25.40% 28.62%,25.98% 27.44%,26.83% 26.45%,27.91% 25.70%,29.13% 25.25%,30.44% 25.09%,31.74% 24.98%,33.05% 24.88%,34.36% 24.77%,35.67% 24.67%,36.98% 24.57%,38.28% 24.43%,39.53% 24.02%,40.63% 23.31%,41.63% 22.46%,42.63% 21.61%,43.63% 20.76%,44.63% 19.91%,45.63% 19.05%,46.63% 18.20%,47.72% 17.48%,48.96% 17.06%,50.27% 16.97%,51.56% 17.20%,52.75% 17.74%,53.78% 18.55%,54.78% 19.40%,55.78% 20.25%,56.78% 21.10%,57.78% 21.96%,58.78% 22.81%,59.80% 23.63%,60.97% 24.22%,62.25% 24.50%,63.56% 24.61%,64.86% 24.71%,66.17% 24.82%,67.48% 24.92%,68.79% 25.03%,70.10% 25.13%,71.38% 25.40%,72.56% 25.98%,73.55% 26.83%,74.30% 27.91%,74.75% 29.13%,74.91% 30.44%,75.02% 31.74%,75.12% 33.05%,75.23% 34.36%,75.33% 35.67%,75.43% 36.98%,75.57% 38.28%,75.98% 39.53%,76.69% 40.63%,77.54% 41.63%,78.39% 42.63%,79.24% 43.63%,80.09% 44.63%,80.95% 45.63%); }
  57.83516% { clip-path: polygon(81.80% 46.63%,82.52% 47.72%,82.94% 48.96%,83.03% 50.27%,82.80% 51.56%,82.26% 52.75%,81.45% 53.78%,80.60% 54.78%,79.75% 55.78%,78.90% 56.78%,78.04% 57.78%,77.19% 58.78%,76.37% 59.80%,75.78% 60.97%,75.50% 62.25%,75.39% 63.56%,75.29% 64.86%,75.18% 66.17%,75.08% 67.48%,74.97% 68.79%,74.87% 70.10%,74.60% 71.38%,74.02% 72.56%,73.17% 73.55%,72.09% 74.30%,70.87% 74.75%,69.56% 74.91%,68.26% 75.02%,66.95% 75.12%,65.64% 75.23%,64.33% 75.33%,63.02% 75.43%,61.72% 75.57%,60.47% 75.98%,59.37% 76.69%,58.37% 77.54%,57.37% 78.39%,56.37% 79.24%,55.37% 80.09%,54.37% 80.95%,53.37% 81.80%,52.28% 82.52%,51.04% 82.94%,49.73% 83.03%,48.44% 82.80%,47.25% 82.26%,46.22% 81.45%,45.22% 80.60%,44.22% 79.75%,43.22% 78.90%,42.22% 78.04%,41.22% 77.19%,40.20% 76.37%,39.03% 75.78%,37.75% 75.50%,36.44% 75.39%,35.14% 75.29%,33.83% 75.18%,32.52% 75.08%,31.21% 74.97%,29.90% 74.87%,28.62% 74.60%,27.44% 74.02%,26.45% 73.17%,25.70% 72.09%,25.25% 70.87%,25.09% 69.56%,24.98% 68.26%,24.88% 66.95%,24.77% 65.64%,24.67% 64.33%,24.57% 63.02%,24.43% 61.72%,24.02% 60.47%,23.31% 59.37%,22.46% 58.37%,21.61% 57.37%,20.76% 56.37%,19.91% 55.37%,19.05% 54.37%,18.20% 53.37%,17.48% 52.28%,17.06% 51.04%,16.97% 49.73%,17.20% 48.44%,17.74% 47.25%,18.55% 46.22%,19.40% 45.22%,20.25% 44.22%,21.10% 43.22%,21.96% 42.22%,22.81% 41.22%,23.63% 40.20%,24.22% 39.03%,24.50% 37.75%,24.61% 36.44%,24.71% 35.14%,24.82% 33.83%,24.92% 32.52%,25.03% 31.21%,25.13% 29.90%,25.40% 28.62%,25.98% 27.44%,26.83% 26.45%,27.91% 25.70%,29.13% 25.25%,30.44% 25.09%,31.74% 24.98%,33.05% 24.88%,34.36% 24.77%,35.67% 24.67%,36.98% 24.57%,38.28% 24.43%,39.53% 24.02%,40.63% 23.31%,41.63% 22.46%,42.63% 21.61%,43.63% 20.76%,44.63% 19.91%,45.63% 19.05%,46.63% 18.20%,47.72% 17.48%,48.96% 17.06%,50.27% 16.97%,51.56% 17.20%,52.75% 17.74%,53.78% 18.55%,54.78% 19.40%,55.78% 20.25%,56.78% 21.10%,57.78% 21.96%,58.78% 22.81%,59.80% 23.63%,60.97% 24.22%,62.25% 24.50%,63.56% 24.61%,64.86% 24.71%,66.17% 24.82%,67.48% 24.92%,68.79% 25.03%,70.10% 25.13%,71.38% 25.40%,72.56% 25.98%,73.55% 26.83%,74.30% 27.91%,74.75% 29.13%,74.91% 30.44%,75.02% 31.74%,75.12% 33.05%,75.23% 34.36%,75.33% 35.67%,75.43% 36.98%,75.57% 38.28%,75.98% 39.53%,76.69% 40.63%,77.54% 41.63%,78.39% 42.63%,79.24% 43.63%,80.09% 44.63%,80.95% 45.63%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  60.03297% { clip-path: polygon(80.63% 56.95%,81.02% 57.87%,81.42% 58.78%,81.81% 59.71%,82.15% 60.64%,82.44% 61.60%,82.68% 62.57%,82.86% 63.55%,82.97% 64.54%,83.03% 65.54%,83.03% 66.54%,82.97% 67.54%,82.84% 68.53%,82.66% 69.51%,82.42% 70.48%,82.12% 71.43%,81.76% 72.37%,81.35% 73.28%,80.89% 74.16%,80.37% 75.02%,79.81% 75.85%,79.20% 76.64%,78.55% 77.40%,77.56% 78.40%,75.21% 80.25%,72.57% 81.67%,69.72% 82.60%,66.75% 83.01%,63.76% 82.87%,60.84% 82.20%,58.05% 81.09%,55.28% 79.92%,52.38% 79.18%,49.80% 79.00%,48.80% 79.04%,47.81% 79.15%,46.82% 79.33%,45.85% 79.57%,44.90% 79.87%,43.97% 80.23%,43.05% 80.63%,42.13% 81.02%,41.22% 81.42%,40.29% 81.81%,39.36% 82.15%,38.40% 82.44%,37.43% 82.68%,36.45% 82.86%,35.46% 82.97%,34.46% 83.03%,33.46% 83.03%,32.46% 82.97%,31.47% 82.84%,30.49% 82.66%,29.52% 82.42%,28.57% 82.12%,27.63% 81.76%,26.72% 81.35%,25.84% 80.89%,24.98% 80.37%,24.15% 79.81%,23.36% 79.20%,22.60% 78.55%,21.60% 77.56%,19.75% 75.21%,18.33% 72.57%,17.40% 69.72%,16.99% 66.75%,17.13% 63.76%,17.80% 60.84%,18.91% 58.05%,20.08% 55.28%,20.82% 52.38%,21.00% 49.80%,20.96% 48.80%,20.85% 47.81%,20.67% 46.82%,20.43% 45.85%,20.13% 44.90%,19.77% 43.97%,19.37% 43.05%,18.98% 42.13%,18.58% 41.22%,18.19% 40.29%,17.85% 39.36%,17.56% 38.40%,17.32% 37.43%,17.14% 36.45%,17.03% 35.46%,16.97% 34.46%,16.97% 33.46%,17.03% 32.46%,17.16% 31.47%,17.34% 30.49%,17.58% 29.52%,17.88% 28.57%,18.24% 27.63%,18.65% 26.72%,19.11% 25.84%,19.63% 24.98%,20.19% 24.15%,20.80% 23.36%,21.45% 22.60%,22.44% 21.60%,24.79% 19.75%,27.43% 18.33%,30.28% 17.40%,33.25% 16.99%,36.24% 17.13%,39.16% 17.80%,41.95% 18.91%,44.72% 20.08%,47.62% 20.82%,50.20% 21.00%,51.20% 20.96%,52.19% 20.85%,53.18% 20.67%,54.15% 20.43%,55.10% 20.13%,56.03% 19.77%,56.95% 19.37%,57.87% 18.98%,58.78% 18.58%,59.71% 18.19%,60.64% 17.85%,61.60% 17.56%,62.57% 17.32%,63.55% 17.14%,64.54% 17.03%,65.54% 16.97%,66.54% 16.97%,67.54% 17.03%,68.53% 17.16%,69.51% 17.34%,70.48% 17.58%,71.43% 17.88%,72.37% 18.24%,73.28% 18.65%,74.16% 19.11%,75.02% 19.63%,75.85% 20.19%,76.64% 20.80%,77.40% 21.45%,78.40% 22.44%,80.25% 24.79%,81.67% 27.43%,82.60% 30.28%,83.01% 33.25%,82.87% 36.24%,82.20% 39.16%,81.09% 41.95%,79.92% 44.72%,79.18% 47.62%,79.00% 50.20%,79.04% 51.20%,79.15% 52.19%,79.33% 53.18%,79.57% 54.15%,79.87% 55.10%,80.23% 56.03%); }
  60.03308% { clip-path: polygon(81.58% 59.15%,82.12% 60.55%,82.54% 61.99%,82.84% 63.46%,83.00% 64.95%,83.03% 66.45%,82.93% 67.94%,82.68% 69.42%,82.30% 70.87%,81.79% 72.29%,81.17% 73.65%,80.42% 74.95%,79.57% 76.18%,78.61% 77.33%,77.56% 78.40%,76.42% 79.38%,75.20% 80.25%,73.91% 81.02%,72.57% 81.67%,71.16% 82.20%,69.72% 82.60%,68.24% 82.87%,66.75% 83.01%,65.25% 83.01%,63.76% 82.87%,62.28% 82.59%,60.84% 82.20%,59.43% 81.68%,58.05% 81.09%,56.68% 80.50%,55.29% 79.93%,53.86% 79.48%,52.39% 79.18%,50.90% 79.02%,49.40% 79.01%,47.91% 79.14%,46.43% 79.42%,44.99% 79.84%,43.60% 80.39%,42.22% 80.99%,40.85% 81.58%,39.45% 82.12%,38.01% 82.54%,36.54% 82.84%,35.05% 83.00%,33.55% 83.03%,32.06% 82.93%,30.58% 82.68%,29.13% 82.30%,27.71% 81.79%,26.35% 81.17%,25.05% 80.42%,23.82% 79.57%,22.67% 78.61%,21.60% 77.56%,20.62% 76.42%,19.75% 75.20%,18.98% 73.91%,18.33% 72.57%,17.80% 71.16%,17.40% 69.72%,17.13% 68.24%,16.99% 66.75%,16.99% 65.25%,17.13% 63.76%,17.41% 62.28%,17.80% 60.84%,18.32% 59.43%,18.91% 58.05%,19.50% 56.68%,20.07% 55.29%,20.52% 53.86%,20.82% 52.39%,20.98% 50.90%,20.99% 49.40%,20.86% 47.91%,20.58% 46.43%,20.16% 44.99%,19.61% 43.60%,19.01% 42.22%,18.42% 40.85%,17.88% 39.45%,17.46% 38.01%,17.16% 36.54%,17.00% 35.05%,16.97% 33.55%,17.07% 32.06%,17.32% 30.58%,17.70% 29.13%,18.21% 27.71%,18.83% 26.35%,19.58% 25.05%,20.43% 23.82%,21.39% 22.67%,22.44% 21.60%,23.58% 20.62%,24.80% 19.75%,26.09% 18.98%,27.43% 18.33%,28.84% 17.80%,30.28% 17.40%,31.76% 17.13%,33.25% 16.99%,34.75% 16.99%,36.24% 17.13%,37.72% 17.41%,39.16% 17.80%,40.57% 18.32%,41.95% 18.91%,43.32% 19.50%,44.71% 20.07%,46.14% 20.52%,47.61% 20.82%,49.10% 20.98%,50.60% 20.99%,52.09% 20.86%,53.57% 20.58%,55.01% 20.16%,56.40% 19.61%,57.78% 19.01%,59.15% 18.42%,60.55% 17.88%,61.99% 17.46%,63.46% 17.16%,64.95% 17.00%,66.45% 16.97%,67.94% 17.07%,69.42% 17.32%,70.87% 17.70%,72.29% 18.21%,73.65% 18.83%,74.95% 19.58%,76.18% 20.43%,77.33% 21.39%,78.40% 22.44%,79.38% 23.58%,80.25% 24.80%,81.02% 26.09%,81.67% 27.43%,82.20% 28.84%,82.60% 30.28%,82.87% 31.76%,83.01% 33.25%,83.01% 34.75%,82.87% 36.24%,82.59% 37.72%,82.20% 39.16%,81.68% 40.57%,81.09% 41.95%,80.50% 43.32%,79.93% 44.71%,79.48% 46.14%,79.18% 47.61%,79.02% 49.10%,79.01% 50.60%,79.14% 52.09%,79.42% 53.57%,79.84% 55.01%,80.39% 56.40%,80.99% 57.78%); }
  72.12088% { clip-path: polygon(81.58% 59.15%,82.12% 60.55%,82.54% 61.99%,82.84% 63.46%,83.00% 64.95%,83.03% 66.45%,82.93% 67.94%,82.68% 69.42%,82.30% 70.87%,81.79% 72.29%,81.17% 73.65%,80.42% 74.95%,79.57% 76.18%,78.61% 77.33%,77.56% 78.40%,76.42% 79.38%,75.20% 80.25%,73.91% 81.02%,72.57% 81.67%,71.16% 82.20%,69.72% 82.60%,68.24% 82.87%,66.75% 83.01%,65.25% 83.01%,63.76% 82.87%,62.28% 82.59%,60.84% 82.20%,59.43% 81.68%,58.05% 81.09%,56.68% 80.50%,55.29% 79.93%,53.86% 79.48%,52.39% 79.18%,50.90% 79.02%,49.40% 79.01%,47.91% 79.14%,46.43% 79.42%,44.99% 79.84%,43.60% 80.39%,42.22% 80.99%,40.85% 81.58%,39.45% 82.12%,38.01% 82.54%,36.54% 82.84%,35.05% 83.00%,33.55% 83.03%,32.06% 82.93%,30.58% 82.68%,29.13% 82.30%,27.71% 81.79%,26.35% 81.17%,25.05% 80.42%,23.82% 79.57%,22.67% 78.61%,21.60% 77.56%,20.62% 76.42%,19.75% 75.20%,18.98% 73.91%,18.33% 72.57%,17.80% 71.16%,17.40% 69.72%,17.13% 68.24%,16.99% 66.75%,16.99% 65.25%,17.13% 63.76%,17.41% 62.28%,17.80% 60.84%,18.32% 59.43%,18.91% 58.05%,19.50% 56.68%,20.07% 55.29%,20.52% 53.86%,20.82% 52.39%,20.98% 50.90%,20.99% 49.40%,20.86% 47.91%,20.58% 46.43%,20.16% 44.99%,19.61% 43.60%,19.01% 42.22%,18.42% 40.85%,17.88% 39.45%,17.46% 38.01%,17.16% 36.54%,17.00% 35.05%,16.97% 33.55%,17.07% 32.06%,17.32% 30.58%,17.70% 29.13%,18.21% 27.71%,18.83% 26.35%,19.58% 25.05%,20.43% 23.82%,21.39% 22.67%,22.44% 21.60%,23.58% 20.62%,24.80% 19.75%,26.09% 18.98%,27.43% 18.33%,28.84% 17.80%,30.28% 17.40%,31.76% 17.13%,33.25% 16.99%,34.75% 16.99%,36.24% 17.13%,37.72% 17.41%,39.16% 17.80%,40.57% 18.32%,41.95% 18.91%,43.32% 19.50%,44.71% 20.07%,46.14% 20.52%,47.61% 20.82%,49.10% 20.98%,50.60% 20.99%,52.09% 20.86%,53.57% 20.58%,55.01% 20.16%,56.40% 19.61%,57.78% 19.01%,59.15% 18.42%,60.55% 17.88%,61.99% 17.46%,63.46% 17.16%,64.95% 17.00%,66.45% 16.97%,67.94% 17.07%,69.42% 17.32%,70.87% 17.70%,72.29% 18.21%,73.65% 18.83%,74.95% 19.58%,76.18% 20.43%,77.33% 21.39%,78.40% 22.44%,79.38% 23.58%,80.25% 24.80%,81.02% 26.09%,81.67% 27.43%,82.20% 28.84%,82.60% 30.28%,82.87% 31.76%,83.01% 33.25%,83.01% 34.75%,82.87% 36.24%,82.59% 37.72%,82.20% 39.16%,81.68% 40.57%,81.09% 41.95%,80.50% 43.32%,79.93% 44.71%,79.48% 46.14%,79.18% 47.61%,79.02% 49.10%,79.01% 50.60%,79.14% 52.09%,79.42% 53.57%,79.84% 55.01%,80.39% 56.40%,80.99% 57.78%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  74.31868% { clip-path: polygon(78.17% 53.88%,77.56% 55.01%,76.92% 56.12%,76.26% 57.22%,75.57% 58.30%,74.85% 59.36%,74.12% 60.41%,73.35% 61.44%,72.57% 62.46%,71.77% 63.46%,70.94% 64.44%,70.09% 65.40%,69.23% 66.35%,68.34% 67.28%,67.44% 68.18%,66.51% 69.07%,65.57% 69.94%,64.61% 70.79%,63.63% 71.62%,62.63% 72.43%,61.62% 73.22%,60.59% 73.98%,59.55% 74.73%,58.48% 75.45%,57.40% 76.14%,56.31% 76.81%,55.20% 77.45%,54.08% 78.07%,52.94% 78.66%,51.78% 79.21%,50.61% 79.74%,49.43% 80.24%,48.23% 80.70%,47.02% 81.13%,45.80% 81.52%,44.57% 81.87%,43.32% 82.18%,42.07% 82.45%,40.81% 82.67%,39.53% 82.84%,38.26% 82.96%,36.98% 83.03%,35.69% 83.04%,34.41% 82.98%,33.14% 82.87%,31.87% 82.68%,30.61% 82.42%,29.37% 82.08%,28.16% 81.66%,26.98% 81.17%,25.84% 80.59%,24.74% 79.92%,23.70% 79.18%,22.71% 78.35%,21.80% 77.45%,20.96% 76.48%,20.20% 75.45%,19.52% 74.36%,18.93% 73.22%,18.42% 72.05%,17.99% 70.84%,17.64% 69.60%,17.36% 68.35%,17.16% 67.09%,17.03% 65.81%,16.97% 64.53%,16.96% 63.25%,17.02% 61.96%,17.13% 60.69%,17.30% 59.41%,17.51% 58.15%,17.77% 56.89%,18.07% 55.65%,18.42% 54.41%,18.80% 53.19%,19.22% 51.98%,19.68% 50.78%,20.17% 49.59%,20.69% 48.42%,21.24% 47.26%,21.83% 46.12%,22.44% 44.99%,23.08% 43.88%,23.74% 42.78%,24.43% 41.70%,25.15% 40.64%,25.88% 39.59%,26.65% 38.56%,27.43% 37.54%,28.23% 36.54%,29.06% 35.56%,29.91% 34.60%,30.77% 33.65%,31.66% 32.72%,32.56% 31.82%,33.49% 30.93%,34.43% 30.06%,35.39% 29.21%,36.37% 28.38%,37.37% 27.57%,38.38% 26.78%,39.41% 26.02%,40.45% 25.27%,41.52% 24.55%,42.60% 23.86%,43.69% 23.19%,44.80% 22.55%,45.92% 21.93%,47.06% 21.34%,48.22% 20.79%,49.39% 20.26%,50.57% 19.76%,51.77% 19.30%,52.98% 18.87%,54.20% 18.48%,55.43% 18.13%,56.68% 17.82%,57.93% 17.55%,59.19% 17.33%,60.47% 17.16%,61.74% 17.04%,63.02% 16.97%,64.31% 16.96%,65.59% 17.02%,66.86% 17.13%,68.13% 17.32%,69.39% 17.58%,70.63% 17.92%,71.84% 18.34%,73.02% 18.83%,74.16% 19.41%,75.26% 20.08%,76.30% 20.82%,77.29% 21.65%,78.20% 22.55%,79.04% 23.52%,79.80% 24.55%,80.48% 25.64%,81.07% 26.78%,81.58% 27.95%,82.01% 29.16%,82.36% 30.40%,82.64% 31.65%,82.84% 32.91%,82.97% 34.19%,83.03% 35.47%,83.04% 36.75%,82.98% 38.04%,82.87% 39.31%,82.70% 40.59%,82.49% 41.85%,82.23% 43.11%,81.93% 44.35%,81.58% 45.59%,81.20% 46.81%,80.78% 48.02%,80.32% 49.22%,79.83% 50.41%,79.31% 51.58%,78.76% 52.74%); }
  74.31879% { clip-path: polygon(68.90% 17.47%,70.14% 17.78%,71.36% 18.16%,72.56% 18.63%,73.72% 19.18%,74.84% 19.81%,75.90% 20.52%,76.91% 21.32%,77.85% 22.19%,78.72% 23.13%,79.51% 24.14%,80.22% 25.21%,80.85% 26.33%,81.39% 27.49%,81.85% 28.68%,82.23% 29.91%,82.54% 31.15%,82.77% 32.42%,82.92% 33.69%,83.02% 34.97%,83.04% 36.25%,83.01% 37.53%,82.92% 38.81%,82.77% 40.09%,82.58% 41.35%,82.34% 42.61%,82.05% 43.86%,81.72% 45.10%,81.35% 46.33%,80.95% 47.55%,80.51% 48.75%,80.03% 49.94%,79.52% 51.12%,78.98% 52.28%,78.40% 53.43%,77.80% 54.56%,77.18% 55.68%,76.52% 56.79%,75.84% 57.87%,75.14% 58.94%,74.41% 60.00%,73.66% 61.04%,72.88% 62.06%,72.09% 63.07%,71.27% 64.06%,70.43% 65.03%,69.57% 65.98%,68.69% 66.91%,67.79% 67.83%,66.88% 68.73%,65.94% 69.60%,64.99% 70.46%,64.02% 71.30%,63.03% 72.12%,62.02% 72.91%,61.00% 73.69%,59.96% 74.44%,58.90% 75.17%,57.83% 75.87%,56.74% 76.55%,55.64% 77.20%,54.52% 77.83%,53.39% 78.43%,52.24% 79.00%,51.07% 79.54%,49.90% 80.05%,48.71% 80.52%,47.50% 80.96%,46.28% 81.37%,45.06% 81.74%,43.81% 82.06%,42.56% 82.35%,41.30% 82.59%,40.04% 82.78%,38.76% 82.92%,37.48% 83.01%,36.20% 83.04%,34.92% 83.01%,33.64% 82.92%,32.37% 82.76%,31.10% 82.53%,29.86% 82.22%,28.64% 81.84%,27.44% 81.37%,26.28% 80.82%,25.16% 80.19%,24.10% 79.48%,23.09% 78.68%,22.15% 77.81%,21.28% 76.87%,20.49% 75.86%,19.78% 74.79%,19.15% 73.67%,18.61% 72.51%,18.15% 71.32%,17.77% 70.09%,17.46% 68.85%,17.23% 67.58%,17.08% 66.31%,16.98% 65.03%,16.96% 63.75%,16.99% 62.47%,17.08% 61.19%,17.23% 59.91%,17.42% 58.65%,17.66% 57.39%,17.95% 56.14%,18.28% 54.90%,18.65% 53.67%,19.05% 52.45%,19.49% 51.25%,19.97% 50.06%,20.48% 48.88%,21.02% 47.72%,21.60% 46.57%,22.20% 45.44%,22.82% 44.32%,23.48% 43.21%,24.16% 42.13%,24.86% 41.06%,25.59% 40.00%,26.34% 38.96%,27.12% 37.94%,27.91% 36.93%,28.73% 35.94%,29.57% 34.97%,30.43% 34.02%,31.31% 33.09%,32.21% 32.17%,33.12% 31.27%,34.06% 30.40%,35.01% 29.54%,35.98% 28.70%,36.97% 27.88%,37.98% 27.09%,39.00% 26.31%,40.04% 25.56%,41.10% 24.83%,42.17% 24.13%,43.26% 23.45%,44.36% 22.80%,45.48% 22.17%,46.61% 21.57%,47.76% 21.00%,48.93% 20.46%,50.10% 19.95%,51.29% 19.48%,52.50% 19.04%,53.72% 18.63%,54.94% 18.26%,56.19% 17.94%,57.44% 17.65%,58.70% 17.41%,59.96% 17.22%,61.24% 17.08%,62.52% 16.99%,63.80% 16.96%,65.08% 16.99%,66.36% 17.08%,67.63% 17.24%); }
  86.40659% { clip-path: polygon(68.90% 17.47%,70.14% 17.78%,71.36% 18.16%,72.56% 18.63%,73.72% 19.18%,74.84% 19.81%,75.90% 20.52%,76.91% 21.32%,77.85% 22.19%,78.72% 23.13%,79.51% 24.14%,80.22% 25.21%,80.85% 26.33%,81.39% 27.49%,81.85% 28.68%,82.23% 29.91%,82.54% 31.15%,82.77% 32.42%,82.92% 33.69%,83.02% 34.97%,83.04% 36.25%,83.01% 37.53%,82.92% 38.81%,82.77% 40.09%,82.58% 41.35%,82.34% 42.61%,82.05% 43.86%,81.72% 45.10%,81.35% 46.33%,80.95% 47.55%,80.51% 48.75%,80.03% 49.94%,79.52% 51.12%,78.98% 52.28%,78.40% 53.43%,77.80% 54.56%,77.18% 55.68%,76.52% 56.79%,75.84% 57.87%,75.14% 58.94%,74.41% 60.00%,73.66% 61.04%,72.88% 62.06%,72.09% 63.07%,71.27% 64.06%,70.43% 65.03%,69.57% 65.98%,68.69% 66.91%,67.79% 67.83%,66.88% 68.73%,65.94% 69.60%,64.99% 70.46%,64.02% 71.30%,63.03% 72.12%,62.02% 72.91%,61.00% 73.69%,59.96% 74.44%,58.90% 75.17%,57.83% 75.87%,56.74% 76.55%,55.64% 77.20%,54.52% 77.83%,53.39% 78.43%,52.24% 79.00%,51.07% 79.54%,49.90% 80.05%,48.71% 80.52%,47.50% 80.96%,46.28% 81.37%,45.06% 81.74%,43.81% 82.06%,42.56% 82.35%,41.30% 82.59%,40.04% 82.78%,38.76% 82.92%,37.48% 83.01%,36.20% 83.04%,34.92% 83.01%,33.64% 82.92%,32.37% 82.76%,31.10% 82.53%,29.86% 82.22%,28.64% 81.84%,27.44% 81.37%,26.28% 80.82%,25.16% 80.19%,24.10% 79.48%,23.09% 78.68%,22.15% 77.81%,21.28% 76.87%,20.49% 75.86%,19.78% 74.79%,19.15% 73.67%,18.61% 72.51%,18.15% 71.32%,17.77% 70.09%,17.46% 68.85%,17.23% 67.58%,17.08% 66.31%,16.98% 65.03%,16.96% 63.75%,16.99% 62.47%,17.08% 61.19%,17.23% 59.91%,17.42% 58.65%,17.66% 57.39%,17.95% 56.14%,18.28% 54.90%,18.65% 53.67%,19.05% 52.45%,19.49% 51.25%,19.97% 50.06%,20.48% 48.88%,21.02% 47.72%,21.60% 46.57%,22.20% 45.44%,22.82% 44.32%,23.48% 43.21%,24.16% 42.13%,24.86% 41.06%,25.59% 40.00%,26.34% 38.96%,27.12% 37.94%,27.91% 36.93%,28.73% 35.94%,29.57% 34.97%,30.43% 34.02%,31.31% 33.09%,32.21% 32.17%,33.12% 31.27%,34.06% 30.40%,35.01% 29.54%,35.98% 28.70%,36.97% 27.88%,37.98% 27.09%,39.00% 26.31%,40.04% 25.56%,41.10% 24.83%,42.17% 24.13%,43.26% 23.45%,44.36% 22.80%,45.48% 22.17%,46.61% 21.57%,47.76% 21.00%,48.93% 20.46%,50.10% 19.95%,51.29% 19.48%,52.50% 19.04%,53.72% 18.63%,54.94% 18.26%,56.19% 17.94%,57.44% 17.65%,58.70% 17.41%,59.96% 17.22%,61.24% 17.08%,62.52% 16.99%,63.80% 16.96%,65.08% 16.99%,66.36% 17.08%,67.63% 17.24%); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  88.60440% { clip-path: polygon(59.40% 25.41%,60.68% 25.05%,61.92% 24.55%,63.15% 24.04%,64.39% 23.53%,65.62% 23.02%,66.89% 22.62%,68.22% 22.70%,69.42% 23.27%,70.32% 24.24%,70.79% 25.48%,70.79% 26.81%,70.70% 28.15%,70.60% 29.48%,70.50% 30.81%,70.41% 32.14%,70.48% 33.47%,71.03% 34.68%,72.00% 35.59%,73.23% 36.08%,74.53% 36.39%,75.83% 36.71%,77.13% 37.02%,78.43% 37.34%,79.70% 37.74%,80.74% 38.56%,81.40% 39.72%,81.44% 41.85%,80.27% 43.68%,78.85% 45.36%,77.43% 47.04%,76.21% 48.85%,76.18% 51.01%,77.36% 52.84%,78.78% 54.52%,80.21% 56.19%,81.42% 58.00%,81.44% 60.16%,80.18% 61.92%,78.14% 62.69%,76.01% 63.22%,73.87% 63.75%,71.83% 64.51%,70.56% 66.26%,70.47% 68.44%,70.64% 70.63%,70.80% 72.83%,70.70% 75.00%,69.43% 76.72%,68.45% 77.22%,67.37% 77.39%,66.29% 77.20%,65.27% 76.80%,64.25% 76.38%,63.23% 75.97%,62.21% 75.55%,61.20% 75.14%,60.17% 74.73%,59.09% 74.57%,58.01% 74.76%,57.04% 75.27%,56.28% 76.05%,55.70% 76.98%,55.12% 77.92%,54.55% 78.86%,53.97% 79.79%,53.39% 80.73%,52.80% 81.66%,52.02% 82.42%,51.03% 82.89%,49.93% 83.04%,48.63% 82.75%,47.54% 82.00%,46.77% 80.92%,46.06% 79.78%,45.36% 78.65%,44.65% 77.51%,43.95% 76.38%,43.09% 75.36%,41.92% 74.74%,40.60% 74.59%,39.32% 74.95%,38.08% 75.45%,36.85% 75.96%,35.61% 76.47%,34.38% 76.98%,33.11% 77.38%,31.78% 77.30%,30.58% 76.73%,29.68% 75.76%,29.21% 74.52%,29.21% 73.19%,29.30% 71.85%,29.40% 70.52%,29.50% 69.19%,29.59% 67.86%,29.52% 66.53%,28.97% 65.32%,28.00% 64.41%,26.77% 63.92%,25.47% 63.61%,24.17% 63.29%,22.87% 62.98%,21.57% 62.66%,20.30% 62.26%,19.26% 61.44%,18.60% 60.28%,18.56% 58.15%,19.73% 56.32%,21.15% 54.64%,22.57% 52.96%,23.79% 51.15%,23.82% 48.99%,22.64% 47.16%,21.22% 45.48%,19.79% 43.81%,18.58% 42.00%,18.56% 39.84%,19.82% 38.08%,21.86% 37.31%,23.99% 36.78%,26.13% 36.25%,28.17% 35.49%,29.44% 33.74%,29.53% 31.56%,29.36% 29.37%,29.20% 27.17%,29.30% 25.00%,30.57% 23.28%,31.55% 22.78%,32.63% 22.61%,33.71% 22.80%,34.73% 23.20%,35.75% 23.62%,36.77% 24.03%,37.79% 24.45%,38.80% 24.86%,39.83% 25.27%,40.91% 25.43%,41.99% 25.24%,42.96% 24.73%,43.72% 23.95%,44.30% 23.02%,44.88% 22.08%,45.45% 21.14%,46.03% 20.21%,46.61% 19.27%,47.20% 18.34%,47.98% 17.58%,48.97% 17.11%,50.07% 16.96%,51.37% 17.25%,52.46% 18.00%,53.23% 19.08%,53.94% 20.22%,54.64% 21.35%,55.35% 22.49%,56.05% 23.62%,56.91% 24.64%,58.08% 25.26%); }
  88.60451% { clip-path: polygon(26.96% 36.05%,28.30% 35.39%,29.24% 34.22%,29.61% 32.77%,29.51% 31.27%,29.39% 29.77%,29.28% 28.26%,29.16% 26.76%,29.22% 25.26%,29.89% 23.92%,31.05% 22.98%,32.50% 22.62%,33.97% 22.90%,35.37% 23.46%,36.77% 24.03%,38.16% 24.60%,39.56% 25.17%,41.03% 25.42%,42.48% 25.03%,43.63% 24.08%,44.43% 22.80%,45.22% 21.52%,46.01% 20.24%,46.80% 18.95%,47.73% 17.77%,49.06% 17.08%,50.55% 17.01%,51.94% 17.56%,52.96% 18.65%,53.76% 19.93%,54.56% 21.21%,55.35% 22.49%,56.15% 23.77%,57.19% 24.85%,58.59% 25.38%,60.08% 25.28%,61.48% 24.73%,62.88% 24.15%,64.27% 23.58%,65.66% 23.00%,67.11% 22.60%,68.59% 22.81%,69.84% 23.63%,70.64% 24.90%,70.82% 26.38%,70.72% 27.89%,70.61% 29.39%,70.50% 30.89%,70.39% 32.40%,70.60% 33.88%,71.42% 35.13%,72.69% 35.93%,74.14% 36.30%,75.61% 36.66%,77.08% 37.01%,78.54% 37.37%,79.95% 37.88%,81.02% 38.93%,81.55% 40.33%,81.45% 41.82%,80.73% 43.13%,79.76% 44.28%,78.79% 45.44%,77.81% 46.59%,76.84% 47.74%,76.15% 49.07%,76.07% 50.56%,76.63% 51.95%,77.59% 53.11%,78.56% 54.26%,79.54% 55.41%,80.52% 56.55%,81.35% 57.80%,81.60% 59.28%,81.21% 60.72%,80.25% 61.87%,78.90% 62.51%,77.43% 62.87%,75.97% 63.23%,74.51% 63.59%,73.04% 63.95%,71.70% 64.61%,70.76% 65.78%,70.39% 67.23%,70.49% 68.73%,70.61% 70.23%,70.72% 71.74%,70.84% 73.24%,70.78% 74.74%,70.11% 76.08%,68.95% 77.02%,67.50% 77.38%,66.03% 77.10%,64.63% 76.54%,63.23% 75.97%,61.84% 75.40%,60.44% 74.83%,58.97% 74.58%,57.52% 74.97%,56.37% 75.92%,55.57% 77.20%,54.78% 78.48%,53.99% 79.76%,53.20% 81.05%,52.27% 82.23%,50.94% 82.92%,49.45% 82.99%,48.06% 82.44%,47.04% 81.35%,46.24% 80.07%,45.44% 78.79%,44.65% 77.51%,43.85% 76.23%,42.81% 75.15%,41.41% 74.62%,39.92% 74.72%,38.52% 75.27%,37.12% 75.85%,35.73% 76.42%,34.34% 77.00%,32.89% 77.40%,31.41% 77.19%,30.16% 76.37%,29.36% 75.10%,29.18% 73.62%,29.28% 72.11%,29.39% 70.61%,29.50% 69.11%,29.61% 67.60%,29.40% 66.12%,28.58% 64.87%,27.31% 64.07%,25.86% 63.70%,24.39% 63.34%,22.92% 62.99%,21.46% 62.63%,20.05% 62.12%,18.98% 61.07%,18.45% 59.67%,18.55% 58.18%,19.27% 56.87%,20.24% 55.72%,21.21% 54.56%,22.19% 53.41%,23.16% 52.26%,23.85% 50.93%,23.93% 49.44%,23.37% 48.05%,22.41% 46.89%,21.44% 45.74%,20.46% 44.59%,19.48% 43.45%,18.65% 42.20%,18.40% 40.72%,18.79% 39.28%,19.75% 38.13%,21.10% 37.49%,22.57% 37.13%,24.03% 36.77%,25.49% 36.41%); }
  100% { clip-path: polygon(26.96% 36.05%,28.30% 35.39%,29.24% 34.22%,29.61% 32.77%,29.51% 31.27%,29.39% 29.77%,29.28% 28.26%,29.16% 26.76%,29.22% 25.26%,29.89% 23.92%,31.05% 22.98%,32.50% 22.62%,33.97% 22.90%,35.37% 23.46%,36.77% 24.03%,38.16% 24.60%,39.56% 25.17%,41.03% 25.42%,42.48% 25.03%,43.63% 24.08%,44.43% 22.80%,45.22% 21.52%,46.01% 20.24%,46.80% 18.95%,47.73% 17.77%,49.06% 17.08%,50.55% 17.01%,51.94% 17.56%,52.96% 18.65%,53.76% 19.93%,54.56% 21.21%,55.35% 22.49%,56.15% 23.77%,57.19% 24.85%,58.59% 25.38%,60.08% 25.28%,61.48% 24.73%,62.88% 24.15%,64.27% 23.58%,65.66% 23.00%,67.11% 22.60%,68.59% 22.81%,69.84% 23.63%,70.64% 24.90%,70.82% 26.38%,70.72% 27.89%,70.61% 29.39%,70.50% 30.89%,70.39% 32.40%,70.60% 33.88%,71.42% 35.13%,72.69% 35.93%,74.14% 36.30%,75.61% 36.66%,77.08% 37.01%,78.54% 37.37%,79.95% 37.88%,81.02% 38.93%,81.55% 40.33%,81.45% 41.82%,80.73% 43.13%,79.76% 44.28%,78.79% 45.44%,77.81% 46.59%,76.84% 47.74%,76.15% 49.07%,76.07% 50.56%,76.63% 51.95%,77.59% 53.11%,78.56% 54.26%,79.54% 55.41%,80.52% 56.55%,81.35% 57.80%,81.60% 59.28%,81.21% 60.72%,80.25% 61.87%,78.90% 62.51%,77.43% 62.87%,75.97% 63.23%,74.51% 63.59%,73.04% 63.95%,71.70% 64.61%,70.76% 65.78%,70.39% 67.23%,70.49% 68.73%,70.61% 70.23%,70.72% 71.74%,70.84% 73.24%,70.78% 74.74%,70.11% 76.08%,68.95% 77.02%,67.50% 77.38%,66.03% 77.10%,64.63% 76.54%,63.23% 75.97%,61.84% 75.40%,60.44% 74.83%,58.97% 74.58%,57.52% 74.97%,56.37% 75.92%,55.57% 77.20%,54.78% 78.48%,53.99% 79.76%,53.20% 81.05%,52.27% 82.23%,50.94% 82.92%,49.45% 82.99%,48.06% 82.44%,47.04% 81.35%,46.24% 80.07%,45.44% 78.79%,44.65% 77.51%,43.85% 76.23%,42.81% 75.15%,41.41% 74.62%,39.92% 74.72%,38.52% 75.27%,37.12% 75.85%,35.73% 76.42%,34.34% 77.00%,32.89% 77.40%,31.41% 77.19%,30.16% 76.37%,29.36% 75.10%,29.18% 73.62%,29.28% 72.11%,29.39% 70.61%,29.50% 69.11%,29.61% 67.60%,29.40% 66.12%,28.58% 64.87%,27.31% 64.07%,25.86% 63.70%,24.39% 63.34%,22.92% 62.99%,21.46% 62.63%,20.05% 62.12%,18.98% 61.07%,18.45% 59.67%,18.55% 58.18%,19.27% 56.87%,20.24% 55.72%,21.21% 54.56%,22.19% 53.41%,23.16% 52.26%,23.85% 50.93%,23.93% 49.44%,23.37% 48.05%,22.41% 46.89%,21.44% 45.74%,20.46% 44.59%,19.48% 43.45%,18.65% 42.20%,18.40% 40.72%,18.79% 39.28%,19.75% 38.13%,21.10% 37.49%,22.57% 37.13%,24.03% 36.77%,25.49% 36.41%); }
}

/* ==========================================================================
   12. Material Symbols helper (if the icon font is loaded)
   ========================================================================== */

.material-symbols-rounded,
.material-symbols-outlined {
  font-size: 24px;
  line-height: 1;
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
  user-select: none;
}
.btn .material-symbols-rounded, .btn .material-symbols-outlined { font-size: var(--md-btn-icon); }
.btn-icon > .material-symbols-rounded, .btn-icon > .material-symbols-outlined { font-size: var(--md-ib-icon); }
.icon-filled { font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }

@media (prefers-reduced-motion: reduce) {
  * { --md-motion-scale: 0; }
  /* Indeterminate indicators still need to show activity, just calmer. */
  .progress-indeterminate, .loading-indicator { --md-motion-scale: 2; }
}
