/* GENERATO da scripts/build.mjs, non modificare. Fonte: OXQ Matrix (Figma yyzkJAhmSCImr1HojYeMq7), export 2026-10-15. */
@layer theme, base, components, utilities;

@layer theme {

/* Tokens · Color: Light */
:root,
[data-theme="light"] {
  color-scheme: light;
  --oxq-neutral-line-border: #d5d5d5;
  --oxq-neutral-line-border-strong: #c7c7c7;
  --oxq-neutral-line-control: #747474;
  --oxq-neutral-line-hairline: #0000000d;
  --oxq-neutral-line-popover: #00000029;
  --oxq-system-scrim-soft: #00000029;
  --oxq-system-scrim-strong: #00000052;
  --oxq-system-state-hover: #0000000d;
  --oxq-system-state-pressed: #00000029;
  --oxq-neutral-surface-canvas: #f8f8f8;
  --oxq-neutral-surface-muted: #d5d5d5;
  --oxq-neutral-surface-raised: #ffffff;
  --oxq-neutral-surface-sunken: #f1f1f1;
  --oxq-neutral-text-ink: #1a1a1a;
  --oxq-neutral-text-ink-hover: #101010;
  --oxq-neutral-text-muted: #919191;
  --oxq-neutral-text-on-ink: #ffffff;
  --oxq-neutral-text-secondary: #5e5e5e;
  --oxq-neutral-icon-ink: #1a1a1a;
  --oxq-neutral-icon-secondary: #5e5e5e;
  --oxq-neutral-icon-muted: #919191;
  --oxq-neutral-icon-on-ink: #ffffff;
  --oxq-brand-surface-solid: #ff224c;
  --oxq-brand-text-on-solid: #ffffff;
  --oxq-danger-surface-canvas: #ffedee;
  --oxq-danger-surface-sunken: #ffdbdc;
  --oxq-danger-surface-solid: #e31a42;
  --oxq-danger-surface-solid-hover: #bd0733;
  --oxq-danger-surface-solid-pressed: #8e0425;
  --oxq-danger-line-border: #feb4b7;
  --oxq-danger-line-border-strong: #e31a42;
  --oxq-danger-text-ink: #8e0425;
  --oxq-danger-text-ink-hover: #620c1c;
  --oxq-danger-text-on-ink: #ffffff;
  --oxq-danger-icon-ink: #8e0425;
  --oxq-danger-icon-on-ink: #ffffff;
  --oxq-warning-surface-canvas: #fdfadc;
  --oxq-warning-surface-sunken: #fcf3a6;
  --oxq-warning-surface-solid: #ffe715;
  --oxq-warning-surface-solid-hover: #e5c600;
  --oxq-warning-surface-solid-pressed: #cfa70f;
  --oxq-warning-line-border: #e5c600;
  --oxq-warning-line-border-strong: #9e6900;
  --oxq-warning-text-ink: #bb8800;
  --oxq-warning-text-ink-hover: #4d2601;
  --oxq-warning-text-on-ink: #101010;
  --oxq-warning-icon-ink: #bb8800;
  --oxq-warning-icon-on-ink: #101010;
  --oxq-success-surface-canvas: #e1f6e8;
  --oxq-success-surface-sunken: #c5ecd1;
  --oxq-success-surface-solid: #198638;
  --oxq-success-surface-solid-hover: #136d2e;
  --oxq-success-surface-solid-pressed: #0b5021;
  --oxq-success-line-border: #7cda9d;
  --oxq-success-line-border-strong: #198638;
  --oxq-success-text-ink: #0b5021;
  --oxq-success-text-ink-hover: #053916;
  --oxq-success-text-on-ink: #ffffff;
  --oxq-success-icon-ink: #0b5021;
  --oxq-success-icon-on-ink: #ffffff;
  --oxq-info-surface-canvas: #e6f3ff;
  --oxq-info-surface-sunken: #cce6fe;
  --oxq-info-surface-solid: #0075d4;
  --oxq-info-surface-solid-hover: #005cb8;
  --oxq-info-surface-solid-pressed: #004195;
  --oxq-info-line-border: #98ccfd;
  --oxq-info-line-border-strong: #0075d4;
  --oxq-info-text-ink: #004195;
  --oxq-info-text-ink-hover: #052d6b;
  --oxq-info-text-on-ink: #ffffff;
  --oxq-info-icon-ink: #004195;
  --oxq-info-icon-on-ink: #ffffff;
  --oxq-discovery-surface-canvas: #f9eefc;
  --oxq-discovery-surface-sunken: #f3dcf8;
  --oxq-discovery-surface-solid: #b836d2;
  --oxq-discovery-surface-solid-hover: #9829ab;
  --oxq-discovery-surface-solid-pressed: #721d7e;
  --oxq-discovery-line-border: #e8b6f4;
  --oxq-discovery-line-border-strong: #b836d2;
  --oxq-discovery-text-ink: #721d7e;
  --oxq-discovery-text-ink-hover: #4f1856;
  --oxq-discovery-text-on-ink: #ffffff;
  --oxq-discovery-icon-ink: #721d7e;
  --oxq-discovery-icon-on-ink: #ffffff;
  --oxq-danger-surface-raised: #fff6f7;
  --oxq-danger-surface-muted: #ffc7c9;
  --oxq-danger-text-secondary: #bd0733;
  --oxq-danger-text-muted: #f55e6b;
  --oxq-danger-icon-secondary: #bd0733;
  --oxq-danger-icon-muted: #f55e6b;
  --oxq-danger-line-control: #e31a42;
  --oxq-danger-line-hairline: #0000000d;
  --oxq-danger-line-popover: #00000029;
  --oxq-success-surface-raised: #f0fbf4;
  --oxq-success-surface-muted: #a6e3b9;
  --oxq-success-text-secondary: #136d2e;
  --oxq-success-text-muted: #00a84e;
  --oxq-success-icon-secondary: #136d2e;
  --oxq-success-icon-muted: #00a84e;
  --oxq-success-line-control: #198638;
  --oxq-success-line-hairline: #0000000d;
  --oxq-success-line-popover: #00000029;
  --oxq-warning-surface-raised: #ffffff;
  --oxq-warning-surface-muted: #f1d600;
  --oxq-warning-text-secondary: #875102;
  --oxq-warning-text-muted: #cfa70f;
  --oxq-warning-icon-secondary: #875102;
  --oxq-warning-icon-muted: #cfa70f;
  --oxq-warning-line-control: #9e6900;
  --oxq-warning-line-hairline: #0000000d;
  --oxq-warning-line-popover: #00000029;
  --oxq-info-surface-raised: #f3f9ff;
  --oxq-info-surface-muted: #b4dafe;
  --oxq-info-text-secondary: #005cb8;
  --oxq-info-text-muted: #1a98ff;
  --oxq-info-icon-secondary: #005cb8;
  --oxq-info-icon-muted: #1a98ff;
  --oxq-info-line-control: #0075d4;
  --oxq-info-line-hairline: #0000000d;
  --oxq-info-line-popover: #00000029;
  --oxq-discovery-surface-raised: #fcf6fd;
  --oxq-discovery-surface-muted: #edc9f6;
  --oxq-discovery-text-secondary: #9829ab;
  --oxq-discovery-text-muted: #db55f8;
  --oxq-discovery-icon-secondary: #9829ab;
  --oxq-discovery-icon-muted: #db55f8;
  --oxq-discovery-line-control: #b836d2;
  --oxq-discovery-line-hairline: #0000000d;
  --oxq-discovery-line-popover: #00000029;
  --oxq-system-focus-ring: #005cb8;
  --oxq-neutral-surface-solid: #101010;
  --oxq-neutral-surface-solid-hover: #303030;
  --oxq-neutral-surface-solid-pressed: #5e5e5e;
  --oxq-neutral-surface-control: #e3e3e3;
  --oxq-danger-surface-control: #ffdbdc;
  --oxq-warning-surface-control: #fcf3a6;
  --oxq-success-surface-control: #c5ecd1;
  --oxq-info-surface-control: #cce6fe;
  --oxq-discovery-surface-control: #f3dcf8;
  --oxq-neutral-surface-control-disabled: #f1f1f1;
  --oxq-danger-surface-control-disabled: #ffedee;
  --oxq-warning-surface-control-disabled: #fdfadc;
  --oxq-success-surface-control-disabled: #e1f6e8;
  --oxq-info-surface-control-disabled: #e6f3ff;
  --oxq-discovery-surface-control-disabled: #f9eefc;
  --oxq-system-shadow-contact: #00000014;
  --oxq-system-shadow-diffusion-1: #0000000d;
  --oxq-system-shadow-diffusion-2: #00000014;
  --oxq-system-shadow-diffusion-3: #0000001f;
  --oxq-system-shadow-diffusion-4: #00000029;
  --oxq-brand-text-ink: #000b13;
  --oxq-brand-shape-ink-x-back: #00000099;
  --oxq-brand-surface-solid-x-back: #ff224c99;
  --oxq-highlight-surface-canvas: #eff0ff;
  --oxq-highlight-surface-sunken: #dfe1ff;
  --oxq-highlight-surface-solid: #6a53f4;
  --oxq-highlight-surface-solid-hover: #5c44d5;
  --oxq-highlight-surface-solid-pressed: #45329e;
  --oxq-highlight-line-border: #bfc2ff;
  --oxq-highlight-line-border-strong: #6a53f4;
  --oxq-highlight-text-ink: #45329e;
  --oxq-highlight-text-ink-hover: #30246b;
  --oxq-highlight-text-on-ink: #ffffff;
  --oxq-highlight-icon-ink: #45329e;
  --oxq-highlight-icon-on-ink: #ffffff;
  --oxq-highlight-surface-raised: #f7f8ff;
  --oxq-highlight-surface-muted: #cfd2ff;
  --oxq-highlight-text-secondary: #5c44d5;
  --oxq-highlight-text-muted: #8782ff;
  --oxq-highlight-icon-secondary: #5c44d5;
  --oxq-highlight-icon-muted: #8782ff;
  --oxq-highlight-line-control: #6a53f4;
  --oxq-highlight-line-hairline: #0000000d;
  --oxq-highlight-line-popover: #00000029;
  --oxq-highlight-surface-control: #dfe1ff;
  --oxq-highlight-surface-control-disabled: #eff0ff;
  --oxq-brand-text-reverse: #ffffff;
  --oxq-brand-shape-reverse-x-back: #ffffff99;
  --oxq-brand-shape-ink: #00000014;
  --oxq-brand-shape-reverse: #ffffff29;
  --oxq-neutral-surface-skeleton: #e3e3e3;
  --oxq-brand-surface-solid-hover: #e31a42;
  --oxq-brand-surface-solid-pressed: #bd0733;
  --oxq-brand-icon-on-solid: #ffffff;
  --oxq-neutral-line-control-hover: #747474;
  --oxq-neutral-shape-ink: #00000014;
  --oxq-neutral-shape-on-ink: #ffffff29;
  --oxq-success-surface-indicator: #00a84e;
  --oxq-neutral-surface-indicator: #c7c7c7;
  --oxq-accent-yellow-surface-soft: #fcf3a6;
  --oxq-accent-yellow-text-ink: #9e6900;
  --oxq-accent-yellow-icon-ink: #9e6900;
  --oxq-accent-green-surface-soft: #c5ecd1;
  --oxq-accent-green-text-ink: #0b5021;
  --oxq-accent-green-icon-ink: #0b5021;
  --oxq-accent-blue-surface-soft: #cce6fe;
  --oxq-accent-blue-text-ink: #004195;
  --oxq-accent-blue-icon-ink: #004195;
  --oxq-accent-violet-surface-soft: #dfe1ff;
  --oxq-accent-violet-text-ink: #45329e;
  --oxq-accent-violet-icon-ink: #45329e;
  --oxq-accent-magenta-surface-soft: #f3dcf8;
  --oxq-accent-magenta-text-ink: #721d7e;
  --oxq-accent-magenta-icon-ink: #721d7e;
  --oxq-neutral-surface-thumb: #ffffff;
  --oxq-accent-yellow-surface-solid: #ffe715;
  --oxq-accent-green-surface-solid: #4bd181;
  --oxq-accent-blue-surface-solid: #1a98ff;
  --oxq-accent-violet-surface-solid: #6a53f4;
  --oxq-accent-magenta-surface-solid: #e269ff;
  --oxq-neutral-surface-subtle: #f1f1f1;
  --oxq-accent-blue-surface-subtle: #e6f3ff;
  --oxq-accent-green-surface-subtle: #e1f6e8;
  --oxq-accent-violet-surface-subtle: #eff0ff;
  --oxq-accent-magenta-surface-subtle: #f9eefc;
  --oxq-accent-yellow-surface-subtle: #fdfadc;
  --oxq-neutral-line-on-ink: #ffffff;
  --oxq-brand-surface-soft: #ffdbdc;
  --oxq-warning-surface-indicator: #bb8800;
  --oxq-danger-line-on-ink: #ffffff;
  --oxq-warning-line-on-ink: #101010;
  --oxq-success-line-on-ink: #ffffff;
  --oxq-info-line-on-ink: #ffffff;
  --oxq-discovery-line-on-ink: #ffffff;
  --oxq-highlight-line-on-ink: #ffffff;
  --oxq-neutral-text-on-ink-secondary: #acacac;
  --oxq-brand-text-red: #ff224c;
  --oxq-success-text-vivid: #198638;
  --oxq-danger-text-vivid: #bd0733;
  --oxq-warning-text-vivid: #bb8800;
  --oxq-success-text-vivid-small: #198638;
  --oxq-danger-text-vivid-small: #bd0733;
  --oxq-warning-text-vivid-small: #9e6900;
  --oxq-info-text-vivid: #0075d4;
  --oxq-info-text-vivid-small: #0075d4;
  --oxq-highlight-text-vivid: #6a53f4;
  --oxq-highlight-text-vivid-small: #6a53f4;
  --oxq-discovery-text-vivid: #b836d2;
  --oxq-discovery-text-vivid-small: #b836d2;
  --oxq-accent-yellow-text-vivid: #bb8800;
  --oxq-accent-yellow-text-vivid-small: #9e6900;
  --oxq-accent-green-text-vivid: #198638;
  --oxq-accent-green-text-vivid-small: #198638;
  --oxq-accent-blue-text-vivid: #0075d4;
  --oxq-accent-blue-text-vivid-small: #0075d4;
  --oxq-accent-violet-text-vivid: #6a53f4;
  --oxq-accent-violet-text-vivid-small: #6a53f4;
  --oxq-accent-magenta-text-vivid: #b836d2;
  --oxq-accent-magenta-text-vivid-small: #b836d2;
  --oxq-neutral-surface-track-on-media: #00000052;
  --oxq-neutral-surface-deep: #f1f1f1;
  --oxq-brand-text-on-solid-secondary: #ffdbdc;
  --oxq-warning-surface-indicator-vivid: #e5c600;
  --oxq-success-surface-indicator-vivid: #09c66a;
  --oxq-info-surface-indicator-vivid: #1a98ff;
  --oxq-discovery-surface-indicator-vivid: #db55f8;
  --oxq-highlight-surface-indicator-vivid: #8782ff;
  --oxq-brand-icon-chevron: #1a1a1a;
  --oxq-accent-yellow-line-border: #f1d600;
  --oxq-accent-green-line-border: #4bd181;
  --oxq-accent-blue-line-border: #1a98ff;
  --oxq-accent-violet-line-border: #6a53f4;
  --oxq-accent-magenta-line-border: #e269ff;
  --oxq-elevation-1: 0 1px 2px 0 var(--oxq-system-shadow-contact), 0 2px 6px 0 var(--oxq-system-shadow-diffusion-1);
  --oxq-elevation-2: 0 2px 4px 0 var(--oxq-system-shadow-contact), 0 4px 12px 0 var(--oxq-system-shadow-diffusion-2);
  --oxq-elevation-3: 0 2px 4px 0 var(--oxq-system-shadow-contact), 0 8px 24px 0 var(--oxq-system-shadow-diffusion-3);
  --oxq-elevation-4: 0 4px 8px 0 var(--oxq-system-shadow-contact), 0 16px 48px 0 var(--oxq-system-shadow-diffusion-4);
}

/* Tokens · Color: Dark, forzato */
[data-theme="dark"] {
  color-scheme: dark;
  --oxq-neutral-line-border: #5e5e5e;
  --oxq-neutral-line-border-strong: #747474;
  --oxq-neutral-line-hairline: #ffffff29;
  --oxq-neutral-line-popover: #ffffff29;
  --oxq-system-scrim-soft: #ffffff29;
  --oxq-system-scrim-strong: #ffffff52;
  --oxq-system-state-hover: #ffffff0d;
  --oxq-system-state-pressed: #ffffff29;
  --oxq-neutral-surface-canvas: #1a1a1a;
  --oxq-neutral-surface-muted: #454545;
  --oxq-neutral-surface-raised: #262626;
  --oxq-neutral-surface-sunken: #101010;
  --oxq-neutral-text-ink: #f1f1f1;
  --oxq-neutral-text-ink-hover: #f8f8f8;
  --oxq-neutral-text-muted: #5e5e5e;
  --oxq-neutral-text-on-ink: #101010;
  --oxq-neutral-text-secondary: #acacac;
  --oxq-neutral-icon-ink: #f1f1f1;
  --oxq-neutral-icon-secondary: #acacac;
  --oxq-neutral-icon-muted: #5e5e5e;
  --oxq-neutral-icon-on-ink: #101010;
  --oxq-danger-surface-canvas: #340e12;
  --oxq-danger-surface-sunken: #101010;
  --oxq-danger-surface-solid: #f55e6b;
  --oxq-danger-surface-solid-hover: #fe8a91;
  --oxq-danger-surface-solid-pressed: #feb4b7;
  --oxq-danger-line-border: #bd0733;
  --oxq-danger-line-border-strong: #f55e6b;
  --oxq-danger-text-ink: #feb4b7;
  --oxq-danger-text-ink-hover: #ffdbdc;
  --oxq-danger-text-on-ink: #101010;
  --oxq-danger-icon-ink: #feb4b7;
  --oxq-danger-icon-on-ink: #101010;
  --oxq-warning-surface-canvas: #301300;
  --oxq-warning-surface-sunken: #101010;
  --oxq-warning-line-border: #6a3902;
  --oxq-warning-line-border-strong: #cfa70f;
  --oxq-warning-text-ink: #e5c600;
  --oxq-warning-text-ink-hover: #ffe715;
  --oxq-warning-text-on-ink: #301300;
  --oxq-warning-icon-ink: #e5c600;
  --oxq-warning-icon-on-ink: #301300;
  --oxq-success-surface-canvas: #02210a;
  --oxq-success-surface-sunken: #101010;
  --oxq-success-surface-solid: #00a84e;
  --oxq-success-surface-solid-hover: #09c66a;
  --oxq-success-surface-solid-pressed: #7cda9d;
  --oxq-success-line-border: #136d2e;
  --oxq-success-line-border-strong: #00a84e;
  --oxq-success-text-ink: #7cda9d;
  --oxq-success-text-ink-hover: #c5ecd1;
  --oxq-success-text-on-ink: #101010;
  --oxq-success-icon-ink: #7cda9d;
  --oxq-success-icon-on-ink: #101010;
  --oxq-info-surface-canvas: #0a1b38;
  --oxq-info-surface-sunken: #101010;
  --oxq-info-surface-solid: #1a98ff;
  --oxq-info-surface-solid-hover: #5fb1fe;
  --oxq-info-surface-solid-pressed: #98ccfd;
  --oxq-info-line-border: #005cb8;
  --oxq-info-line-border-strong: #1a98ff;
  --oxq-info-text-ink: #98ccfd;
  --oxq-info-text-ink-hover: #cce6fe;
  --oxq-info-text-on-ink: #101010;
  --oxq-info-icon-ink: #98ccfd;
  --oxq-info-icon-on-ink: #101010;
  --oxq-discovery-surface-canvas: #2a112e;
  --oxq-discovery-surface-sunken: #101010;
  --oxq-discovery-surface-solid: #db55f8;
  --oxq-discovery-surface-solid-hover: #e489fc;
  --oxq-discovery-surface-solid-pressed: #e8b6f4;
  --oxq-discovery-line-border: #9829ab;
  --oxq-discovery-line-border-strong: #db55f8;
  --oxq-discovery-text-ink: #e8b6f4;
  --oxq-discovery-text-ink-hover: #f3dcf8;
  --oxq-discovery-text-on-ink: #101010;
  --oxq-discovery-icon-ink: #e8b6f4;
  --oxq-discovery-icon-on-ink: #101010;
  --oxq-danger-surface-raised: #4c0e17;
  --oxq-danger-surface-muted: #8e0425;
  --oxq-danger-text-secondary: #fe8a91;
  --oxq-danger-text-muted: #bd0733;
  --oxq-danger-icon-secondary: #fe8a91;
  --oxq-danger-icon-muted: #bd0733;
  --oxq-danger-line-hairline: #ffffff29;
  --oxq-danger-line-popover: #ffffff29;
  --oxq-success-surface-raised: #042d11;
  --oxq-success-surface-muted: #0b5021;
  --oxq-success-text-secondary: #09c66a;
  --oxq-success-text-muted: #136d2e;
  --oxq-success-icon-secondary: #09c66a;
  --oxq-success-icon-muted: #136d2e;
  --oxq-success-line-hairline: #ffffff29;
  --oxq-success-line-popover: #ffffff29;
  --oxq-warning-surface-raised: #3f1d01;
  --oxq-warning-surface-muted: #5b2f02;
  --oxq-warning-text-secondary: #cfa70f;
  --oxq-warning-text-muted: #9e6900;
  --oxq-warning-icon-secondary: #cfa70f;
  --oxq-warning-icon-muted: #9e6900;
  --oxq-warning-line-control: #cfa70f;
  --oxq-warning-line-hairline: #ffffff29;
  --oxq-warning-line-popover: #ffffff29;
  --oxq-info-surface-raised: #092452;
  --oxq-info-surface-muted: #004195;
  --oxq-info-text-secondary: #5fb1fe;
  --oxq-info-text-muted: #005cb8;
  --oxq-info-icon-secondary: #5fb1fe;
  --oxq-info-icon-muted: #005cb8;
  --oxq-info-line-hairline: #ffffff29;
  --oxq-info-line-popover: #ffffff29;
  --oxq-discovery-surface-raised: #3d1542;
  --oxq-discovery-surface-muted: #721d7e;
  --oxq-discovery-text-secondary: #e489fc;
  --oxq-discovery-text-muted: #9829ab;
  --oxq-discovery-icon-secondary: #e489fc;
  --oxq-discovery-icon-muted: #9829ab;
  --oxq-discovery-line-hairline: #ffffff29;
  --oxq-discovery-line-popover: #ffffff29;
  --oxq-system-focus-ring: #5fb1fe;
  --oxq-neutral-surface-solid: #ffffff;
  --oxq-neutral-surface-solid-hover: #d5d5d5;
  --oxq-neutral-surface-solid-pressed: #acacac;
  --oxq-neutral-surface-control: #3a3a3a;
  --oxq-danger-surface-control: #780920;
  --oxq-warning-surface-control: #4d2601;
  --oxq-success-surface-control: #07441c;
  --oxq-info-surface-control: #003783;
  --oxq-discovery-surface-control: #601b6a;
  --oxq-neutral-surface-control-disabled: #303030;
  --oxq-danger-surface-control-disabled: #620c1c;
  --oxq-warning-surface-control-disabled: #ffe71533;
  --oxq-success-surface-control-disabled: #053916;
  --oxq-info-surface-control-disabled: #052d6b;
  --oxq-discovery-surface-control-disabled: #4f1856;
  --oxq-system-shadow-contact: #00000052;
  --oxq-system-shadow-diffusion-1: #00000029;
  --oxq-system-shadow-diffusion-2: #0000003d;
  --oxq-system-shadow-diffusion-3: #00000052;
  --oxq-system-shadow-diffusion-4: #00000066;
  --oxq-highlight-surface-canvas: #1a1738;
  --oxq-highlight-surface-sunken: #101010;
  --oxq-highlight-surface-solid: #8782ff;
  --oxq-highlight-surface-solid-hover: #a1a4ff;
  --oxq-highlight-surface-solid-pressed: #bfc2ff;
  --oxq-highlight-line-border: #5c44d5;
  --oxq-highlight-line-border-strong: #8782ff;
  --oxq-highlight-text-ink: #bfc2ff;
  --oxq-highlight-text-ink-hover: #dfe1ff;
  --oxq-highlight-text-on-ink: #101010;
  --oxq-highlight-icon-ink: #bfc2ff;
  --oxq-highlight-icon-on-ink: #101010;
  --oxq-highlight-surface-raised: #251d52;
  --oxq-highlight-surface-muted: #45329e;
  --oxq-highlight-text-secondary: #a1a4ff;
  --oxq-highlight-text-muted: #5c44d5;
  --oxq-highlight-icon-secondary: #a1a4ff;
  --oxq-highlight-icon-muted: #5c44d5;
  --oxq-highlight-line-hairline: #ffffff29;
  --oxq-highlight-line-popover: #ffffff29;
  --oxq-highlight-surface-control: #3a2b83;
  --oxq-highlight-surface-control-disabled: #30246b;
  --oxq-neutral-surface-skeleton: #3a3a3a;
  --oxq-neutral-line-control-hover: #acacac;
  --oxq-neutral-shape-ink: #ffffff29;
  --oxq-neutral-shape-on-ink: #00000014;
  --oxq-neutral-surface-indicator: #5e5e5e;
  --oxq-accent-yellow-surface-soft: #4d2601;
  --oxq-accent-yellow-text-ink: #e5c600;
  --oxq-accent-yellow-icon-ink: #e5c600;
  --oxq-accent-green-surface-soft: #07441c;
  --oxq-accent-green-text-ink: #7cda9d;
  --oxq-accent-green-icon-ink: #7cda9d;
  --oxq-accent-blue-surface-soft: #003783;
  --oxq-accent-blue-text-ink: #98ccfd;
  --oxq-accent-blue-icon-ink: #98ccfd;
  --oxq-accent-violet-surface-soft: #3a2b83;
  --oxq-accent-violet-text-ink: #bfc2ff;
  --oxq-accent-violet-icon-ink: #bfc2ff;
  --oxq-accent-magenta-surface-soft: #601b6a;
  --oxq-accent-magenta-text-ink: #e8b6f4;
  --oxq-accent-magenta-icon-ink: #e8b6f4;
  --oxq-neutral-surface-thumb: #acacac;
  --oxq-neutral-surface-subtle: #3a3a3a;
  --oxq-accent-blue-surface-subtle: #052d6b;
  --oxq-accent-green-surface-subtle: #053916;
  --oxq-accent-violet-surface-subtle: #30246b;
  --oxq-accent-magenta-surface-subtle: #4f1856;
  --oxq-accent-yellow-surface-subtle: #3f1d01;
  --oxq-neutral-line-on-ink: #101010;
  --oxq-brand-surface-soft: #4c0e17;
  --oxq-warning-surface-indicator: #ffe715;
  --oxq-danger-line-on-ink: #101010;
  --oxq-warning-line-on-ink: #301300;
  --oxq-success-line-on-ink: #101010;
  --oxq-info-line-on-ink: #101010;
  --oxq-discovery-line-on-ink: #101010;
  --oxq-highlight-line-on-ink: #101010;
  --oxq-neutral-text-on-ink-secondary: #5e5e5e;
  --oxq-success-text-vivid: #09c66a;
  --oxq-danger-text-vivid: #f55e6b;
  --oxq-warning-text-vivid: #e5c600;
  --oxq-success-text-vivid-small: #09c66a;
  --oxq-danger-text-vivid-small: #f55e6b;
  --oxq-warning-text-vivid-small: #e5c600;
  --oxq-info-text-vivid: #1a98ff;
  --oxq-info-text-vivid-small: #1a98ff;
  --oxq-highlight-text-vivid: #8782ff;
  --oxq-highlight-text-vivid-small: #8782ff;
  --oxq-discovery-text-vivid: #db55f8;
  --oxq-discovery-text-vivid-small: #db55f8;
  --oxq-accent-yellow-text-vivid: #e5c600;
  --oxq-accent-yellow-text-vivid-small: #e5c600;
  --oxq-accent-green-text-vivid: #09c66a;
  --oxq-accent-green-text-vivid-small: #09c66a;
  --oxq-accent-blue-text-vivid: #1a98ff;
  --oxq-accent-blue-text-vivid-small: #1a98ff;
  --oxq-accent-violet-text-vivid: #8782ff;
  --oxq-accent-violet-text-vivid-small: #8782ff;
  --oxq-accent-magenta-text-vivid: #db55f8;
  --oxq-accent-magenta-text-vivid-small: #db55f8;
  --oxq-neutral-surface-track-on-media: #ffffff52;
  --oxq-neutral-surface-deep: #101010;
  --oxq-warning-surface-indicator-vivid: #ffe715;
  --oxq-brand-icon-chevron: #ff224c;
  --oxq-accent-yellow-line-border: #ffe715;
  --oxq-elevation-1: 0 1px 2px 0 var(--oxq-system-shadow-contact), 0 2px 6px 0 var(--oxq-system-shadow-diffusion-1);
  --oxq-elevation-2: 0 2px 4px 0 var(--oxq-system-shadow-contact), 0 4px 12px 0 var(--oxq-system-shadow-diffusion-2);
  --oxq-elevation-3: 0 2px 4px 0 var(--oxq-system-shadow-contact), 0 8px 24px 0 var(--oxq-system-shadow-diffusion-3);
  --oxq-elevation-4: 0 4px 8px 0 var(--oxq-system-shadow-contact), 0 16px 48px 0 var(--oxq-system-shadow-diffusion-4);
}

/* Tokens · Color: Dark, da sistema */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --oxq-neutral-line-border: #5e5e5e;
    --oxq-neutral-line-border-strong: #747474;
    --oxq-neutral-line-hairline: #ffffff29;
    --oxq-neutral-line-popover: #ffffff29;
    --oxq-system-scrim-soft: #ffffff29;
    --oxq-system-scrim-strong: #ffffff52;
    --oxq-system-state-hover: #ffffff0d;
    --oxq-system-state-pressed: #ffffff29;
    --oxq-neutral-surface-canvas: #1a1a1a;
    --oxq-neutral-surface-muted: #454545;
    --oxq-neutral-surface-raised: #262626;
    --oxq-neutral-surface-sunken: #101010;
    --oxq-neutral-text-ink: #f1f1f1;
    --oxq-neutral-text-ink-hover: #f8f8f8;
    --oxq-neutral-text-muted: #5e5e5e;
    --oxq-neutral-text-on-ink: #101010;
    --oxq-neutral-text-secondary: #acacac;
    --oxq-neutral-icon-ink: #f1f1f1;
    --oxq-neutral-icon-secondary: #acacac;
    --oxq-neutral-icon-muted: #5e5e5e;
    --oxq-neutral-icon-on-ink: #101010;
    --oxq-danger-surface-canvas: #340e12;
    --oxq-danger-surface-sunken: #101010;
    --oxq-danger-surface-solid: #f55e6b;
    --oxq-danger-surface-solid-hover: #fe8a91;
    --oxq-danger-surface-solid-pressed: #feb4b7;
    --oxq-danger-line-border: #bd0733;
    --oxq-danger-line-border-strong: #f55e6b;
    --oxq-danger-text-ink: #feb4b7;
    --oxq-danger-text-ink-hover: #ffdbdc;
    --oxq-danger-text-on-ink: #101010;
    --oxq-danger-icon-ink: #feb4b7;
    --oxq-danger-icon-on-ink: #101010;
    --oxq-warning-surface-canvas: #301300;
    --oxq-warning-surface-sunken: #101010;
    --oxq-warning-line-border: #6a3902;
    --oxq-warning-line-border-strong: #cfa70f;
    --oxq-warning-text-ink: #e5c600;
    --oxq-warning-text-ink-hover: #ffe715;
    --oxq-warning-text-on-ink: #301300;
    --oxq-warning-icon-ink: #e5c600;
    --oxq-warning-icon-on-ink: #301300;
    --oxq-success-surface-canvas: #02210a;
    --oxq-success-surface-sunken: #101010;
    --oxq-success-surface-solid: #00a84e;
    --oxq-success-surface-solid-hover: #09c66a;
    --oxq-success-surface-solid-pressed: #7cda9d;
    --oxq-success-line-border: #136d2e;
    --oxq-success-line-border-strong: #00a84e;
    --oxq-success-text-ink: #7cda9d;
    --oxq-success-text-ink-hover: #c5ecd1;
    --oxq-success-text-on-ink: #101010;
    --oxq-success-icon-ink: #7cda9d;
    --oxq-success-icon-on-ink: #101010;
    --oxq-info-surface-canvas: #0a1b38;
    --oxq-info-surface-sunken: #101010;
    --oxq-info-surface-solid: #1a98ff;
    --oxq-info-surface-solid-hover: #5fb1fe;
    --oxq-info-surface-solid-pressed: #98ccfd;
    --oxq-info-line-border: #005cb8;
    --oxq-info-line-border-strong: #1a98ff;
    --oxq-info-text-ink: #98ccfd;
    --oxq-info-text-ink-hover: #cce6fe;
    --oxq-info-text-on-ink: #101010;
    --oxq-info-icon-ink: #98ccfd;
    --oxq-info-icon-on-ink: #101010;
    --oxq-discovery-surface-canvas: #2a112e;
    --oxq-discovery-surface-sunken: #101010;
    --oxq-discovery-surface-solid: #db55f8;
    --oxq-discovery-surface-solid-hover: #e489fc;
    --oxq-discovery-surface-solid-pressed: #e8b6f4;
    --oxq-discovery-line-border: #9829ab;
    --oxq-discovery-line-border-strong: #db55f8;
    --oxq-discovery-text-ink: #e8b6f4;
    --oxq-discovery-text-ink-hover: #f3dcf8;
    --oxq-discovery-text-on-ink: #101010;
    --oxq-discovery-icon-ink: #e8b6f4;
    --oxq-discovery-icon-on-ink: #101010;
    --oxq-danger-surface-raised: #4c0e17;
    --oxq-danger-surface-muted: #8e0425;
    --oxq-danger-text-secondary: #fe8a91;
    --oxq-danger-text-muted: #bd0733;
    --oxq-danger-icon-secondary: #fe8a91;
    --oxq-danger-icon-muted: #bd0733;
    --oxq-danger-line-hairline: #ffffff29;
    --oxq-danger-line-popover: #ffffff29;
    --oxq-success-surface-raised: #042d11;
    --oxq-success-surface-muted: #0b5021;
    --oxq-success-text-secondary: #09c66a;
    --oxq-success-text-muted: #136d2e;
    --oxq-success-icon-secondary: #09c66a;
    --oxq-success-icon-muted: #136d2e;
    --oxq-success-line-hairline: #ffffff29;
    --oxq-success-line-popover: #ffffff29;
    --oxq-warning-surface-raised: #3f1d01;
    --oxq-warning-surface-muted: #5b2f02;
    --oxq-warning-text-secondary: #cfa70f;
    --oxq-warning-text-muted: #9e6900;
    --oxq-warning-icon-secondary: #cfa70f;
    --oxq-warning-icon-muted: #9e6900;
    --oxq-warning-line-control: #cfa70f;
    --oxq-warning-line-hairline: #ffffff29;
    --oxq-warning-line-popover: #ffffff29;
    --oxq-info-surface-raised: #092452;
    --oxq-info-surface-muted: #004195;
    --oxq-info-text-secondary: #5fb1fe;
    --oxq-info-text-muted: #005cb8;
    --oxq-info-icon-secondary: #5fb1fe;
    --oxq-info-icon-muted: #005cb8;
    --oxq-info-line-hairline: #ffffff29;
    --oxq-info-line-popover: #ffffff29;
    --oxq-discovery-surface-raised: #3d1542;
    --oxq-discovery-surface-muted: #721d7e;
    --oxq-discovery-text-secondary: #e489fc;
    --oxq-discovery-text-muted: #9829ab;
    --oxq-discovery-icon-secondary: #e489fc;
    --oxq-discovery-icon-muted: #9829ab;
    --oxq-discovery-line-hairline: #ffffff29;
    --oxq-discovery-line-popover: #ffffff29;
    --oxq-system-focus-ring: #5fb1fe;
    --oxq-neutral-surface-solid: #ffffff;
    --oxq-neutral-surface-solid-hover: #d5d5d5;
    --oxq-neutral-surface-solid-pressed: #acacac;
    --oxq-neutral-surface-control: #3a3a3a;
    --oxq-danger-surface-control: #780920;
    --oxq-warning-surface-control: #4d2601;
    --oxq-success-surface-control: #07441c;
    --oxq-info-surface-control: #003783;
    --oxq-discovery-surface-control: #601b6a;
    --oxq-neutral-surface-control-disabled: #303030;
    --oxq-danger-surface-control-disabled: #620c1c;
    --oxq-warning-surface-control-disabled: #ffe71533;
    --oxq-success-surface-control-disabled: #053916;
    --oxq-info-surface-control-disabled: #052d6b;
    --oxq-discovery-surface-control-disabled: #4f1856;
    --oxq-system-shadow-contact: #00000052;
    --oxq-system-shadow-diffusion-1: #00000029;
    --oxq-system-shadow-diffusion-2: #0000003d;
    --oxq-system-shadow-diffusion-3: #00000052;
    --oxq-system-shadow-diffusion-4: #00000066;
    --oxq-highlight-surface-canvas: #1a1738;
    --oxq-highlight-surface-sunken: #101010;
    --oxq-highlight-surface-solid: #8782ff;
    --oxq-highlight-surface-solid-hover: #a1a4ff;
    --oxq-highlight-surface-solid-pressed: #bfc2ff;
    --oxq-highlight-line-border: #5c44d5;
    --oxq-highlight-line-border-strong: #8782ff;
    --oxq-highlight-text-ink: #bfc2ff;
    --oxq-highlight-text-ink-hover: #dfe1ff;
    --oxq-highlight-text-on-ink: #101010;
    --oxq-highlight-icon-ink: #bfc2ff;
    --oxq-highlight-icon-on-ink: #101010;
    --oxq-highlight-surface-raised: #251d52;
    --oxq-highlight-surface-muted: #45329e;
    --oxq-highlight-text-secondary: #a1a4ff;
    --oxq-highlight-text-muted: #5c44d5;
    --oxq-highlight-icon-secondary: #a1a4ff;
    --oxq-highlight-icon-muted: #5c44d5;
    --oxq-highlight-line-hairline: #ffffff29;
    --oxq-highlight-line-popover: #ffffff29;
    --oxq-highlight-surface-control: #3a2b83;
    --oxq-highlight-surface-control-disabled: #30246b;
    --oxq-neutral-surface-skeleton: #3a3a3a;
    --oxq-neutral-line-control-hover: #acacac;
    --oxq-neutral-shape-ink: #ffffff29;
    --oxq-neutral-shape-on-ink: #00000014;
    --oxq-neutral-surface-indicator: #5e5e5e;
    --oxq-accent-yellow-surface-soft: #4d2601;
    --oxq-accent-yellow-text-ink: #e5c600;
    --oxq-accent-yellow-icon-ink: #e5c600;
    --oxq-accent-green-surface-soft: #07441c;
    --oxq-accent-green-text-ink: #7cda9d;
    --oxq-accent-green-icon-ink: #7cda9d;
    --oxq-accent-blue-surface-soft: #003783;
    --oxq-accent-blue-text-ink: #98ccfd;
    --oxq-accent-blue-icon-ink: #98ccfd;
    --oxq-accent-violet-surface-soft: #3a2b83;
    --oxq-accent-violet-text-ink: #bfc2ff;
    --oxq-accent-violet-icon-ink: #bfc2ff;
    --oxq-accent-magenta-surface-soft: #601b6a;
    --oxq-accent-magenta-text-ink: #e8b6f4;
    --oxq-accent-magenta-icon-ink: #e8b6f4;
    --oxq-neutral-surface-thumb: #acacac;
    --oxq-neutral-surface-subtle: #3a3a3a;
    --oxq-accent-blue-surface-subtle: #052d6b;
    --oxq-accent-green-surface-subtle: #053916;
    --oxq-accent-violet-surface-subtle: #30246b;
    --oxq-accent-magenta-surface-subtle: #4f1856;
    --oxq-accent-yellow-surface-subtle: #3f1d01;
    --oxq-neutral-line-on-ink: #101010;
    --oxq-brand-surface-soft: #4c0e17;
    --oxq-warning-surface-indicator: #ffe715;
    --oxq-danger-line-on-ink: #101010;
    --oxq-warning-line-on-ink: #301300;
    --oxq-success-line-on-ink: #101010;
    --oxq-info-line-on-ink: #101010;
    --oxq-discovery-line-on-ink: #101010;
    --oxq-highlight-line-on-ink: #101010;
    --oxq-neutral-text-on-ink-secondary: #5e5e5e;
    --oxq-success-text-vivid: #09c66a;
    --oxq-danger-text-vivid: #f55e6b;
    --oxq-warning-text-vivid: #e5c600;
    --oxq-success-text-vivid-small: #09c66a;
    --oxq-danger-text-vivid-small: #f55e6b;
    --oxq-warning-text-vivid-small: #e5c600;
    --oxq-info-text-vivid: #1a98ff;
    --oxq-info-text-vivid-small: #1a98ff;
    --oxq-highlight-text-vivid: #8782ff;
    --oxq-highlight-text-vivid-small: #8782ff;
    --oxq-discovery-text-vivid: #db55f8;
    --oxq-discovery-text-vivid-small: #db55f8;
    --oxq-accent-yellow-text-vivid: #e5c600;
    --oxq-accent-yellow-text-vivid-small: #e5c600;
    --oxq-accent-green-text-vivid: #09c66a;
    --oxq-accent-green-text-vivid-small: #09c66a;
    --oxq-accent-blue-text-vivid: #1a98ff;
    --oxq-accent-blue-text-vivid-small: #1a98ff;
    --oxq-accent-violet-text-vivid: #8782ff;
    --oxq-accent-violet-text-vivid-small: #8782ff;
    --oxq-accent-magenta-text-vivid: #db55f8;
    --oxq-accent-magenta-text-vivid-small: #db55f8;
    --oxq-neutral-surface-track-on-media: #ffffff52;
    --oxq-neutral-surface-deep: #101010;
    --oxq-warning-surface-indicator-vivid: #ffe715;
    --oxq-brand-icon-chevron: #ff224c;
    --oxq-accent-yellow-line-border: #ffe715;
    --oxq-elevation-1: 0 1px 2px 0 var(--oxq-system-shadow-contact), 0 2px 6px 0 var(--oxq-system-shadow-diffusion-1);
    --oxq-elevation-2: 0 2px 4px 0 var(--oxq-system-shadow-contact), 0 4px 12px 0 var(--oxq-system-shadow-diffusion-2);
    --oxq-elevation-3: 0 2px 4px 0 var(--oxq-system-shadow-contact), 0 8px 24px 0 var(--oxq-system-shadow-diffusion-3);
    --oxq-elevation-4: 0 4px 8px 0 var(--oxq-system-shadow-contact), 0 16px 48px 0 var(--oxq-system-shadow-diffusion-4);
  }
}

/* Tone: famiglia di colore dell'elemento con data-tone */
:root,
[data-theme],
[data-tone="neutral"] {
  --oxq-tone-surface-canvas: var(--oxq-neutral-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-neutral-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-neutral-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-neutral-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-neutral-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-neutral-line-border);
  --oxq-tone-line-border-strong: var(--oxq-neutral-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-neutral-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-neutral-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-neutral-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-neutral-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-neutral-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-neutral-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-neutral-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-neutral-text-secondary);
  --oxq-tone-text-muted: var(--oxq-neutral-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-neutral-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-neutral-icon-muted);
  --oxq-tone-line-control: var(--oxq-neutral-line-control);
  --oxq-tone-line-hairline: var(--oxq-neutral-line-hairline);
  --oxq-tone-line-popover: var(--oxq-neutral-line-popover);
  --oxq-tone-surface-control: var(--oxq-neutral-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-neutral-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-neutral-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-neutral-text-secondary);
  --oxq-tone-text-vivid-small: var(--oxq-neutral-text-secondary);
}

[data-tone="danger"] {
  --oxq-tone-surface-canvas: var(--oxq-danger-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-danger-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-danger-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-danger-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-danger-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-danger-line-border);
  --oxq-tone-line-border-strong: var(--oxq-danger-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-danger-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-danger-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-danger-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-danger-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-danger-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-danger-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-danger-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-danger-text-secondary);
  --oxq-tone-text-muted: var(--oxq-danger-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-danger-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-danger-icon-muted);
  --oxq-tone-line-control: var(--oxq-danger-line-control);
  --oxq-tone-line-hairline: var(--oxq-danger-line-hairline);
  --oxq-tone-line-popover: var(--oxq-danger-line-popover);
  --oxq-tone-surface-control: var(--oxq-danger-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-danger-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-danger-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-danger-text-vivid);
  --oxq-tone-text-vivid-small: var(--oxq-danger-text-vivid-small);
}

[data-tone="warning"] {
  --oxq-tone-surface-canvas: var(--oxq-warning-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-warning-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-warning-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-warning-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-warning-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-warning-line-border);
  --oxq-tone-line-border-strong: var(--oxq-warning-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-warning-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-warning-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-warning-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-warning-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-warning-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-warning-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-warning-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-warning-text-secondary);
  --oxq-tone-text-muted: var(--oxq-warning-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-warning-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-warning-icon-muted);
  --oxq-tone-line-control: var(--oxq-warning-line-control);
  --oxq-tone-line-hairline: var(--oxq-warning-line-hairline);
  --oxq-tone-line-popover: var(--oxq-warning-line-popover);
  --oxq-tone-surface-control: var(--oxq-warning-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-warning-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-warning-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-warning-text-vivid);
  --oxq-tone-text-vivid-small: var(--oxq-warning-text-vivid-small);
}

[data-tone="success"] {
  --oxq-tone-surface-canvas: var(--oxq-success-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-success-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-success-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-success-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-success-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-success-line-border);
  --oxq-tone-line-border-strong: var(--oxq-success-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-success-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-success-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-success-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-success-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-success-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-success-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-success-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-success-text-secondary);
  --oxq-tone-text-muted: var(--oxq-success-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-success-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-success-icon-muted);
  --oxq-tone-line-control: var(--oxq-success-line-control);
  --oxq-tone-line-hairline: var(--oxq-success-line-hairline);
  --oxq-tone-line-popover: var(--oxq-success-line-popover);
  --oxq-tone-surface-control: var(--oxq-success-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-success-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-success-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-success-text-vivid);
  --oxq-tone-text-vivid-small: var(--oxq-success-text-vivid-small);
}

[data-tone="info"] {
  --oxq-tone-surface-canvas: var(--oxq-info-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-info-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-info-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-info-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-info-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-info-line-border);
  --oxq-tone-line-border-strong: var(--oxq-info-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-info-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-info-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-info-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-info-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-info-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-info-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-info-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-info-text-secondary);
  --oxq-tone-text-muted: var(--oxq-info-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-info-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-info-icon-muted);
  --oxq-tone-line-control: var(--oxq-info-line-control);
  --oxq-tone-line-hairline: var(--oxq-info-line-hairline);
  --oxq-tone-line-popover: var(--oxq-info-line-popover);
  --oxq-tone-surface-control: var(--oxq-info-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-info-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-info-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-info-text-vivid);
  --oxq-tone-text-vivid-small: var(--oxq-info-text-vivid-small);
}

[data-tone="discovery"] {
  --oxq-tone-surface-canvas: var(--oxq-discovery-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-discovery-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-discovery-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-discovery-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-discovery-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-discovery-line-border);
  --oxq-tone-line-border-strong: var(--oxq-discovery-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-discovery-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-discovery-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-discovery-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-discovery-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-discovery-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-discovery-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-discovery-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-discovery-text-secondary);
  --oxq-tone-text-muted: var(--oxq-discovery-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-discovery-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-discovery-icon-muted);
  --oxq-tone-line-control: var(--oxq-discovery-line-control);
  --oxq-tone-line-hairline: var(--oxq-discovery-line-hairline);
  --oxq-tone-line-popover: var(--oxq-discovery-line-popover);
  --oxq-tone-surface-control: var(--oxq-discovery-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-discovery-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-discovery-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-discovery-text-vivid);
  --oxq-tone-text-vivid-small: var(--oxq-discovery-text-vivid-small);
}

[data-tone="highlight"] {
  --oxq-tone-surface-canvas: var(--oxq-highlight-surface-canvas);
  --oxq-tone-surface-sunken: var(--oxq-highlight-surface-sunken);
  --oxq-tone-surface-solid: var(--oxq-highlight-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-highlight-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-highlight-surface-solid-pressed);
  --oxq-tone-line-border: var(--oxq-highlight-line-border);
  --oxq-tone-line-border-strong: var(--oxq-highlight-line-border-strong);
  --oxq-tone-text-ink: var(--oxq-highlight-text-ink);
  --oxq-tone-text-ink-hover: var(--oxq-highlight-text-ink-hover);
  --oxq-tone-text-on-ink: var(--oxq-highlight-text-on-ink);
  --oxq-tone-icon-ink: var(--oxq-highlight-icon-ink);
  --oxq-tone-icon-on-ink: var(--oxq-highlight-icon-on-ink);
  --oxq-tone-surface-raised: var(--oxq-highlight-surface-raised);
  --oxq-tone-surface-muted: var(--oxq-highlight-surface-muted);
  --oxq-tone-text-secondary: var(--oxq-highlight-text-secondary);
  --oxq-tone-text-muted: var(--oxq-highlight-text-muted);
  --oxq-tone-icon-secondary: var(--oxq-highlight-icon-secondary);
  --oxq-tone-icon-muted: var(--oxq-highlight-icon-muted);
  --oxq-tone-line-control: var(--oxq-highlight-line-control);
  --oxq-tone-line-hairline: var(--oxq-highlight-line-hairline);
  --oxq-tone-line-popover: var(--oxq-highlight-line-popover);
  --oxq-tone-surface-control: var(--oxq-highlight-surface-control);
  --oxq-tone-surface-control-disabled: var(--oxq-highlight-surface-control-disabled);
  --oxq-tone-line-on-ink: var(--oxq-highlight-line-on-ink);
  --oxq-tone-text-vivid: var(--oxq-highlight-text-vivid);
  --oxq-tone-text-vivid-small: var(--oxq-highlight-text-vivid-small);
}

[data-tone="brand"] {
  --oxq-tone-text-secondary: var(--oxq-danger-text-secondary);
  --oxq-tone-text-ink-hover: var(--oxq-danger-text-ink-hover);
  --oxq-tone-surface-solid: var(--oxq-brand-surface-solid);
  --oxq-tone-surface-solid-hover: var(--oxq-brand-surface-solid-hover);
  --oxq-tone-surface-solid-pressed: var(--oxq-brand-surface-solid-pressed);
  --oxq-tone-text-on-ink: var(--oxq-brand-text-on-solid);
  --oxq-tone-icon-on-ink: var(--oxq-brand-icon-on-solid);
  --oxq-tone-surface-control-disabled: var(--oxq-danger-surface-control-disabled);
  --oxq-tone-text-muted: var(--oxq-danger-text-muted);
  --oxq-tone-icon-muted: var(--oxq-danger-icon-muted);
}

/* Tokens · Dimension, Tokens · Typography, Tokens · Motion: Desktop / Default */
:root {
  --oxq-radius-overlay: 1.5rem;
  --oxq-radius-container: 1.25rem;
  --oxq-radius-surface: 1rem;
  --oxq-radius-control: 0.75rem;
  --oxq-radius-item: 0.5rem;
  --oxq-radius-selection: 0.25rem;
  --oxq-radius-pill: 9999px;
  --oxq-size-avatar-xs: 1.5rem;
  --oxq-size-avatar-sm: 2rem;
  --oxq-size-avatar-md: 2.5rem;
  --oxq-size-avatar-lg: 4rem;
  --oxq-size-control-sm: 2rem;
  --oxq-size-control-md: 2.5rem;
  --oxq-size-control-lg: 3rem;
  --oxq-size-control-tap-min: 2.75rem;
  --oxq-size-icon-sm: 1rem;
  --oxq-size-layout-header: 4rem;
  --oxq-size-layout-content-max: 75rem;
  --oxq-size-layout-prose-max: 45rem;
  --oxq-size-icon-md: 1.25rem;
  --oxq-size-icon-lg: 1.5rem;
  --oxq-space-gap-2xs: 0.25rem;
  --oxq-space-gap-xs: 0.5rem;
  --oxq-space-gap-sm: 0.75rem;
  --oxq-space-gap-md: 1rem;
  --oxq-space-gap-lg: 1.5rem;
  --oxq-space-gap-xl: 2rem;
  --oxq-space-gap-2xl: 3rem;
  --oxq-space-inset-item-x: 0.75rem;
  --oxq-space-layout-gutter: 1.5rem;
  --oxq-space-layout-margin: 1.5rem;
  --oxq-space-layout-section: 4rem;
  --oxq-space-layout-page: 6rem;
  --oxq-space-inset-item-y: 0.5rem;
  --oxq-space-inset-control-x: 1rem;
  --oxq-space-inset-control-y: 0.75rem;
  --oxq-space-inset-container: 1.5rem;
  --oxq-space-inset-overlay: 2rem;
  --oxq-radius-none: 0;
  --oxq-size-layout-narrow-max: 30rem;
  --oxq-size-dot-sm: 0.375rem;
  --oxq-size-dot-md: 0.5rem;
  --oxq-size-dot-lg: 0.625rem;
  --oxq-size-presence-sm: 0.75rem;
  --oxq-size-presence-md: 1rem;
  --oxq-size-presence-lg: 1.25rem;
  --oxq-size-switch-width-sm: 2.25rem;
  --oxq-size-switch-width-md: 2.75rem;
  --oxq-size-switch-width-lg: 3.25rem;
  --oxq-size-switch-height-sm: 1.25rem;
  --oxq-size-switch-height-md: 1.5rem;
  --oxq-size-switch-height-lg: 1.75rem;
  --oxq-space-inset-track: 0.125rem;
  --oxq-size-progress-sm: 0.25rem;
  --oxq-size-progress-md: 0.5rem;
  --oxq-size-progress-lg: 0.75rem;
  --oxq-size-meter-sm: 0.25rem;
  --oxq-size-meter-md: 0.5rem;
  --oxq-size-meter-lg: 0.75rem;
  --oxq-size-textarea-sm: 4rem;
  --oxq-size-textarea-md: 6rem;
  --oxq-size-textarea-lg: 8rem;
  --oxq-size-chip-sm: 1.5rem;
  --oxq-size-chip-md: 2rem;
  --oxq-size-kbd-sm: 1.25rem;
  --oxq-size-kbd-md: 1.5rem;
  --oxq-size-kbd-lg: 1.75rem;
  --oxq-size-tooltip-max: 15rem;
  --oxq-size-swatch-sm: 0.5rem;
  --oxq-size-swatch-md: 0.625rem;
  --oxq-size-swatch-lg: 0.75rem;
  --oxq-size-thumb-width-sm: 2.25rem;
  --oxq-size-thumb-height-sm: 3rem;
  --oxq-size-thumb-width-md: 3rem;
  --oxq-size-thumb-height-md: 4rem;
  --oxq-size-thumb-width-lg: 6rem;
  --oxq-size-thumb-height-lg: 8rem;
  --oxq-size-sparkline-width-sm: 6rem;
  --oxq-size-sparkline-height-sm: 1.5rem;
  --oxq-size-sparkline-width-md: 8rem;
  --oxq-size-sparkline-height-md: 2rem;
  --oxq-size-sparkline-width-lg: 8rem;
  --oxq-size-sparkline-height-lg: 3rem;
  --oxq-size-fab-sm: 3.5rem;
  --oxq-size-fab-md: 5rem;
  --oxq-size-fab-lg: 6rem;
  --oxq-size-fab-icon-sm: 1.5rem;
  --oxq-size-fab-icon-md: 1.75rem;
  --oxq-size-fab-icon-lg: 2.25rem;
  --oxq-size-menu: 15rem;
  --oxq-size-modal-sm: 25rem;
  --oxq-size-modal-md: 35rem;
  --oxq-size-modal-lg: 45rem;
  --oxq-size-command-palette: 35rem;
  --oxq-size-toast: 25rem;
  --oxq-size-sheet-sm: 25rem;
  --oxq-size-sheet-md: 30rem;
  --oxq-size-sheet-lg: 45rem;
  --oxq-size-presence-xs: 0.625rem;
  --oxq-size-side-nav-expanded: 15rem;
  --oxq-size-side-nav-collapsed: 4rem;
  --oxq-size-description-label: 8rem;
  --oxq-space-inset-thumb-sm: 0.25rem;
  --oxq-space-inset-thumb-md: 0.25rem;
  --oxq-space-inset-thumb-lg: 0.75rem;
  --oxq-size-thumb-check-sm: 1rem;
  --oxq-size-thumb-check-md: 1rem;
  --oxq-size-thumb-check-lg: 1.5rem;
  --oxq-size-tag-sm: 1.5rem;
  --oxq-size-tag-md: 2rem;
  --oxq-space-layout-section-wide: 7rem;
  --oxq-space-gap-3xl: 4rem;
  --oxq-space-inset-container-wide: 5rem;
  --oxq-size-tag-lg: 2rem;
  --oxq-size-badge-xl: 2rem;
  --oxq-size-client-logo-sm: 1.5rem;
  --oxq-size-client-logo-md: 2rem;
  --oxq-size-client-logo-lg: 2.5rem;
  --oxq-size-page-indicator-width: 1.75rem;
  --oxq-size-page-indicator-height: 0.25rem;
  --oxq-size-link-label-sm: 1rem;
  --oxq-size-link-label-md: 1.25rem;
  --oxq-size-link-label-lg: 1.25rem;
  --oxq-size-skeleton-text: 1rem;
  --oxq-size-bulk-action-bar-sm: 3rem;
  --oxq-size-bulk-action-bar-md: 3.5rem;
  --oxq-radius-swatch: 0.125rem;
  --oxq-size-link-body-sm: 1.25rem;
  --oxq-size-link-body-md: 1.5rem;
  --oxq-size-link-body-lg: 1.75rem;
  --oxq-family-brand: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-family-plain: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-family-code: "Geist Mono", ui-monospace, monospace;
  --oxq-weight-light: 300;
  --oxq-weight-medium: 500;
  --oxq-weight-strong: 700;
  --oxq-weight-code-regular: 400;
  --oxq-display-lg-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-display-lg-font-weight: 900;
  --oxq-display-lg-font-size: 3.5rem;
  --oxq-display-lg-line-height: 4rem;
  --oxq-display-lg-letter-spacing: 0;
  --oxq-display-md-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-display-md-font-weight: 900;
  --oxq-display-md-font-size: 3rem;
  --oxq-display-md-line-height: 3.5rem;
  --oxq-display-md-letter-spacing: 0;
  --oxq-display-sm-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-display-sm-font-weight: 900;
  --oxq-display-sm-font-size: 2.5rem;
  --oxq-display-sm-line-height: 3rem;
  --oxq-display-sm-letter-spacing: 0;
  --oxq-heading-lg-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-heading-lg-font-weight: 800;
  --oxq-heading-lg-font-size: 1.75rem;
  --oxq-heading-lg-line-height: 2.25rem;
  --oxq-heading-lg-letter-spacing: 0;
  --oxq-heading-md-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-heading-md-font-weight: 800;
  --oxq-heading-md-font-size: 1.5rem;
  --oxq-heading-md-line-height: 2rem;
  --oxq-heading-md-letter-spacing: 0;
  --oxq-heading-sm-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-heading-sm-font-weight: 800;
  --oxq-heading-sm-font-size: 1.25rem;
  --oxq-heading-sm-line-height: 1.75rem;
  --oxq-heading-sm-letter-spacing: 0;
  --oxq-title-lg-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-title-lg-font-weight: 700;
  --oxq-title-lg-font-size: 1.125rem;
  --oxq-title-lg-line-height: 1.5rem;
  --oxq-title-lg-letter-spacing: 0;
  --oxq-title-md-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-title-md-font-weight: 700;
  --oxq-title-md-font-size: 1rem;
  --oxq-title-md-line-height: 1.5rem;
  --oxq-title-md-letter-spacing: 0;
  --oxq-title-sm-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-title-sm-font-weight: 700;
  --oxq-title-sm-font-size: 0.875rem;
  --oxq-title-sm-line-height: 1.25rem;
  --oxq-title-sm-letter-spacing: 0;
  --oxq-body-lg-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-body-lg-font-weight: 300;
  --oxq-body-lg-font-size: 1.125rem;
  --oxq-body-lg-line-height: 1.75rem;
  --oxq-body-lg-letter-spacing: 0;
  --oxq-body-md-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-body-md-font-weight: 300;
  --oxq-body-md-font-size: 1rem;
  --oxq-body-md-line-height: 1.5rem;
  --oxq-body-md-letter-spacing: 0;
  --oxq-body-sm-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-body-sm-font-weight: 300;
  --oxq-body-sm-font-size: 0.875rem;
  --oxq-body-sm-line-height: 1.25rem;
  --oxq-body-sm-letter-spacing: 0;
  --oxq-body-xs-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-body-xs-font-weight: 300;
  --oxq-body-xs-font-size: 0.75rem;
  --oxq-body-xs-line-height: 1rem;
  --oxq-body-xs-letter-spacing: 0;
  --oxq-label-lg-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-label-lg-font-weight: 500;
  --oxq-label-lg-font-size: 1rem;
  --oxq-label-lg-line-height: 1.25rem;
  --oxq-label-lg-letter-spacing: 0;
  --oxq-label-md-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-label-md-font-weight: 500;
  --oxq-label-md-font-size: 0.875rem;
  --oxq-label-md-line-height: 1.25rem;
  --oxq-label-md-letter-spacing: 0;
  --oxq-label-sm-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-label-sm-font-weight: 500;
  --oxq-label-sm-font-size: 0.75rem;
  --oxq-label-sm-line-height: 1rem;
  --oxq-label-sm-letter-spacing: 0;
  --oxq-code-lg-font-family: "Geist Mono", ui-monospace, monospace;
  --oxq-code-lg-font-weight: 400;
  --oxq-code-lg-font-size: 1rem;
  --oxq-code-lg-line-height: 1.5rem;
  --oxq-code-lg-letter-spacing: 0;
  --oxq-code-md-font-family: "Geist Mono", ui-monospace, monospace;
  --oxq-code-md-font-weight: 400;
  --oxq-code-md-font-size: 0.875rem;
  --oxq-code-md-line-height: 1.25rem;
  --oxq-code-md-letter-spacing: 0;
  --oxq-code-sm-font-family: "Geist Mono", ui-monospace, monospace;
  --oxq-code-sm-font-weight: 400;
  --oxq-code-sm-font-size: 0.75rem;
  --oxq-code-sm-line-height: 1rem;
  --oxq-code-sm-letter-spacing: 0;
  --oxq-body-lg-font-weight-strong: 500;
  --oxq-body-md-font-weight-strong: 500;
  --oxq-body-sm-font-weight-strong: 500;
  --oxq-body-xs-font-weight-strong: 500;
  --oxq-label-lg-font-weight-strong: 700;
  --oxq-label-md-font-weight-strong: 700;
  --oxq-label-sm-font-weight-strong: 700;
  --oxq-weight-light-italic: 300;
  --oxq-weight-medium-italic: 500;
  --oxq-body-lg-font-weight-italic: 300;
  --oxq-body-md-font-weight-italic: 300;
  --oxq-body-sm-font-weight-italic: 300;
  --oxq-body-xs-font-weight-italic: 300;
  --oxq-label-lg-font-weight-italic: 500;
  --oxq-label-md-font-weight-italic: 500;
  --oxq-label-sm-font-weight-italic: 500;
  --oxq-weight-brand-black: 900;
  --oxq-weight-brand-heavy: 800;
  --oxq-overline-sm-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-overline-sm-font-weight: 500;
  --oxq-overline-sm-font-size: 0.75rem;
  --oxq-overline-sm-line-height: 1rem;
  --oxq-overline-sm-letter-spacing: 0.045rem;
  --oxq-overline-md-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-overline-md-font-weight: 500;
  --oxq-overline-md-font-size: 0.875rem;
  --oxq-overline-md-line-height: 1.25rem;
  --oxq-overline-md-letter-spacing: 0.0525rem;
  --oxq-overline-lg-font-family: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --oxq-overline-lg-font-weight: 500;
  --oxq-overline-lg-font-size: 1rem;
  --oxq-overline-lg-line-height: 1.25rem;
  --oxq-overline-lg-letter-spacing: 0.06rem;
  --oxq-display-xl-font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
  --oxq-display-xl-font-weight: 900;
  --oxq-display-xl-font-size: 4rem;
  --oxq-display-xl-line-height: 4.5rem;
  --oxq-display-xl-letter-spacing: 0;
  --oxq-font-display-lg: var(--oxq-display-lg-font-weight) var(--oxq-display-lg-font-size)/var(--oxq-display-lg-line-height) var(--oxq-display-lg-font-family);
  --oxq-font-display-md: var(--oxq-display-md-font-weight) var(--oxq-display-md-font-size)/var(--oxq-display-md-line-height) var(--oxq-display-md-font-family);
  --oxq-font-display-sm: var(--oxq-display-sm-font-weight) var(--oxq-display-sm-font-size)/var(--oxq-display-sm-line-height) var(--oxq-display-sm-font-family);
  --oxq-font-heading-lg: var(--oxq-heading-lg-font-weight) var(--oxq-heading-lg-font-size)/var(--oxq-heading-lg-line-height) var(--oxq-heading-lg-font-family);
  --oxq-font-heading-md: var(--oxq-heading-md-font-weight) var(--oxq-heading-md-font-size)/var(--oxq-heading-md-line-height) var(--oxq-heading-md-font-family);
  --oxq-font-heading-sm: var(--oxq-heading-sm-font-weight) var(--oxq-heading-sm-font-size)/var(--oxq-heading-sm-line-height) var(--oxq-heading-sm-font-family);
  --oxq-font-title-lg: var(--oxq-title-lg-font-weight) var(--oxq-title-lg-font-size)/var(--oxq-title-lg-line-height) var(--oxq-title-lg-font-family);
  --oxq-font-title-md: var(--oxq-title-md-font-weight) var(--oxq-title-md-font-size)/var(--oxq-title-md-line-height) var(--oxq-title-md-font-family);
  --oxq-font-title-sm: var(--oxq-title-sm-font-weight) var(--oxq-title-sm-font-size)/var(--oxq-title-sm-line-height) var(--oxq-title-sm-font-family);
  --oxq-font-body-lg: var(--oxq-body-lg-font-weight) var(--oxq-body-lg-font-size)/var(--oxq-body-lg-line-height) var(--oxq-body-lg-font-family);
  --oxq-font-body-md: var(--oxq-body-md-font-weight) var(--oxq-body-md-font-size)/var(--oxq-body-md-line-height) var(--oxq-body-md-font-family);
  --oxq-font-body-sm: var(--oxq-body-sm-font-weight) var(--oxq-body-sm-font-size)/var(--oxq-body-sm-line-height) var(--oxq-body-sm-font-family);
  --oxq-font-body-xs: var(--oxq-body-xs-font-weight) var(--oxq-body-xs-font-size)/var(--oxq-body-xs-line-height) var(--oxq-body-xs-font-family);
  --oxq-font-label-lg: var(--oxq-label-lg-font-weight) var(--oxq-label-lg-font-size)/var(--oxq-label-lg-line-height) var(--oxq-label-lg-font-family);
  --oxq-font-label-md: var(--oxq-label-md-font-weight) var(--oxq-label-md-font-size)/var(--oxq-label-md-line-height) var(--oxq-label-md-font-family);
  --oxq-font-label-sm: var(--oxq-label-sm-font-weight) var(--oxq-label-sm-font-size)/var(--oxq-label-sm-line-height) var(--oxq-label-sm-font-family);
  --oxq-font-code-lg: var(--oxq-code-lg-font-weight) var(--oxq-code-lg-font-size)/var(--oxq-code-lg-line-height) var(--oxq-code-lg-font-family);
  --oxq-font-code-md: var(--oxq-code-md-font-weight) var(--oxq-code-md-font-size)/var(--oxq-code-md-line-height) var(--oxq-code-md-font-family);
  --oxq-font-code-sm: var(--oxq-code-sm-font-weight) var(--oxq-code-sm-font-size)/var(--oxq-code-sm-line-height) var(--oxq-code-sm-font-family);
  --oxq-font-overline-sm: var(--oxq-overline-sm-font-weight) var(--oxq-overline-sm-font-size)/var(--oxq-overline-sm-line-height) var(--oxq-overline-sm-font-family);
  --oxq-font-overline-md: var(--oxq-overline-md-font-weight) var(--oxq-overline-md-font-size)/var(--oxq-overline-md-line-height) var(--oxq-overline-md-font-family);
  --oxq-font-overline-lg: var(--oxq-overline-lg-font-weight) var(--oxq-overline-lg-font-size)/var(--oxq-overline-lg-line-height) var(--oxq-overline-lg-font-family);
  --oxq-font-display-xl: var(--oxq-display-xl-font-weight) var(--oxq-display-xl-font-size)/var(--oxq-display-xl-line-height) var(--oxq-display-xl-font-family);
  --oxq-duration-state: 150ms;
  --oxq-duration-open: 200ms;
  --oxq-duration-surface: 300ms;
  --oxq-duration-shimmer: 1500ms;
  --oxq-duration-blink: 500ms;
  --oxq-easing-transition: cubic-bezier(0, 0, 0.58, 1);
  --oxq-easing-loop: linear;
  --oxq-easing-blink: step-end;
}

/* Sotto viewport/lg: Dimension Mobile, Typography Tablet */
@media (width < 64rem) {
  :root {
    --oxq-size-avatar-lg: 3.5rem;
    --oxq-size-control-sm: 2.5rem;
    --oxq-size-control-md: 2.75rem;
    --oxq-size-layout-header: 3.5rem;
    --oxq-space-gap-2xl: 2.5rem;
    --oxq-space-layout-gutter: 1rem;
    --oxq-space-layout-section: 3rem;
    --oxq-space-layout-page: 3rem;
    --oxq-space-inset-container: 1rem;
    --oxq-space-inset-overlay: 1.5rem;
    --oxq-space-layout-section-wide: 4rem;
    --oxq-space-gap-3xl: 3rem;
    --oxq-space-inset-container-wide: 1.5rem;
    --oxq-size-bulk-action-bar-sm: 3.5rem;
    --oxq-size-bulk-action-bar-md: 3.75rem;
    --oxq-size-link-body-lg: 1.5rem;
    --oxq-display-lg-font-size: 2.75rem;
    --oxq-display-lg-line-height: 3.25rem;
    --oxq-display-md-font-size: 2.5rem;
    --oxq-display-md-line-height: 3rem;
    --oxq-display-sm-font-size: 2rem;
    --oxq-display-sm-line-height: 2.5rem;
    --oxq-display-xl-font-size: 3rem;
    --oxq-display-xl-line-height: 3.5rem;
  }
}

/* Sotto viewport/md: Typography Mobile */
@media (width < 48rem) {
  :root {
    --oxq-display-lg-font-size: 2.25rem;
    --oxq-display-lg-line-height: 2.75rem;
    --oxq-display-md-font-size: 1.75rem;
    --oxq-display-md-line-height: 2.25rem;
    --oxq-display-sm-font-size: 1.5rem;
    --oxq-display-sm-line-height: 2rem;
    --oxq-heading-lg-font-size: 1.5rem;
    --oxq-heading-lg-line-height: 2rem;
    --oxq-heading-md-font-size: 1.25rem;
    --oxq-heading-md-line-height: 1.75rem;
    --oxq-heading-sm-font-size: 1.125rem;
    --oxq-heading-sm-line-height: 1.5rem;
    --oxq-body-lg-font-size: 1rem;
    --oxq-body-lg-line-height: 1.5rem;
    --oxq-display-xl-font-size: 2.25rem;
    --oxq-display-xl-line-height: 2.75rem;
  }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  :root {
    --oxq-duration-open: 0ms;
    --oxq-duration-surface: 0ms;
    --oxq-duration-shimmer: 0ms;
  }
}

/* Pending: valori non ancora nel DS Figma (figma/pending.json) */
:root {
  --oxq-stroke-control: 1px;
  --oxq-stroke-focus: 2px;
  --oxq-offset-focus: 2px;
  --oxq-duration-spin: 1000ms;
  --oxq-stroke-underline: 1px;
  --oxq-stroke-underline-hover: 2px;
  --oxq-offset-underline: 2px;
  --oxq-stroke-divider: 1px;
  --oxq-size-skeleton-shine: 3rem;
  --oxq-blur-skeleton-shine: 12px;
  --oxq-opacity-skeleton-shine: 0.8;
  --oxq-stroke-keyline: 2px;
  --oxq-size-icon-xl: 2rem;
  --oxq-space-overlap-xs: 0.125rem;
  --oxq-space-overlap-sm: 0.25rem;
  --oxq-space-overlap-md: 0.375rem;
  --oxq-space-overlap-lg: 0.625rem;
  --oxq-size-tooltip-tail-width: 0.875rem;
  --oxq-size-tooltip-tail-height: 0.625rem;
  --oxq-stroke-selected: 2px;
  --oxq-size-icon-xs: 0.75rem;
  --oxq-opacity-thumbnail-veil: 0.4;
  --oxq-opacity-thumbnail-disabled: 0.4;
  --oxq-stroke-sparkline: 1.5px;
  --oxq-size-sparkline-dash: 0.1875rem;
  --oxq-offset-focus-floating: 4px;
  --oxq-stroke-indicator: 2px;
  --oxq-size-caret-width: 0.0625rem;
  --oxq-size-streaming-cursor-width: 0.125rem;
  --oxq-size-splitter-grab: 0.5625rem;
  --oxq-stroke-splitter-active: 2px;
  --oxq-size-logo-height: 3rem;
  --oxq-size-logo-min: 1rem;
  --oxq-size-logo-min-wide: 1.5rem;
  --oxq-size-logo-nav: 0.898125rem;
  --oxq-size-logo-side-nav: 1rem;
  --oxq-size-logo-nav-submark: 1.25rem;
  --oxq-size-kpi-item-content: 10.5rem;
  --oxq-size-distribution-bar-row-label: 7.5rem;
  --oxq-space-gap-segment: 0.125rem;
  --oxq-size-segment-min: 0.25rem;
  --oxq-size-divider-controls: 1.25rem;
  --oxq-size-filter-chip-listbox: 20rem;
  --oxq-size-filter-bar-search: 20rem;
  --oxq-size-separator-sm: 0.75rem;
  --oxq-size-separator-md: 1rem;
  --oxq-size-empty-state-sm: 22.5rem;
  --oxq-space-inset-toolbar-y: 0.25rem;
  --oxq-size-property-item-inline: 17.5rem;
  --oxq-space-inset-task-item-y: 0.75rem;
  --oxq-space-gap-task-item-text: 0.125rem;
  --oxq-size-handle-resize: 1rem;
  --oxq-size-handle-bar: 0.25rem;
  --oxq-space-inset-list-item-y-sm: 0.5rem;
  --oxq-space-inset-list-item-x-sm: 1rem;
  --oxq-space-inset-list-item-y-md: 1rem;
  --oxq-space-inset-list-item-x-md: 1.5rem;
  --oxq-space-gap-item-text: 0.125rem;
  --oxq-space-inset-cell-y: 0.25rem;
  --oxq-space-gap-cell-suffix: 0.25rem;
  --oxq-space-gap-table-row: 0.5rem;
  --oxq-stroke-emphasis: 2px;
  --oxq-stroke-indent-guide: 2px;
  --oxq-size-editable-cell-handle: 0.375rem;
  --oxq-size-period-picker-shortcuts: 12.5rem;
  --oxq-size-period-picker-month: 3.5rem;
  --oxq-scale-thumbnail-table-sm: 0.46;
  --oxq-scale-thumbnail-table-md: 0.62;
  --oxq-size-icon-2xs: 0.625rem;
}
}
/* Base del DS: dopo il preflight di Tailwind, prima dei componenti. */
@layer base {
  html,
  [data-theme] {
    background-color: var(--oxq-neutral-surface-canvas);
    color: var(--oxq-neutral-text-ink);
  }

  html {
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  /* Anello system/focus/ring da 2 px a 2 px dal bordo, solo da tastiera, mai tolto (Button › Regole d’uso). */
  :focus-visible {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);
  }

  /* Le regole del preflight di Tailwind da cui dipendono i componenti, solo dentro i componenti:
     così oxq.css funziona senza Tailwind e non tocca il resto della pagina. Con Tailwind coincidono
     col preflight. Le verifica tests/standalone.browser.test.ts.
     Si fermano dove comincia il contenuto dell'app, che tiene i suoi stili: i figli dello slot della card,
     del modal e dello sheet. Un componente OXQ messo nello slot è a sua volta un
     inizio di scope, e la base la riceve lo stesso. Il limite si scrive due volte perché anche lo slot è un
     inizio di scope (ha una classe oxq-): :scope per lui, il discendente per il componente che lo contiene. */
  @scope ([class*='oxq-']) to (:scope:where(.oxq-card-content, .oxq-modal-content, .oxq-sheet-content) > *, :where(.oxq-card-content, .oxq-modal-content, .oxq-sheet-content) > *) {
    :where(:scope, *),
    :where(:scope, *)::before,
    :where(:scope, *)::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      border: 0 solid;
    }

    :where(:scope, *):where(svg, img) {
      display: block;
      vertical-align: middle;
    }

    :where(:scope, *):where(img) {
      max-width: 100%;
    }

    :where(:scope, *):where(hr) {
      color: inherit;
    }

    :where(:scope, *):where(table) {
      text-indent: 0;
      border-color: inherit;
      border-collapse: collapse;
    }

    :where(:scope, *):where(button, input, select, textarea) {
      font: inherit;
      letter-spacing: inherit;
      color: inherit;
      opacity: 1;
    }

    /* hidden vince sul display dei componenti, come nel preflight: l'option placeholder del dropdown resta nascosta
       anche nel menu disegnato. */
    :where(:scope, *)[hidden]:where(:not([hidden='until-found'])) {
      display: none !important;
    }

    /* Il preflight dà ai kbd il font mono, con specificità (0,0,1): lo shortcut prende il font della pagina,
       ogni tasto il suo. */
    kbd:where(:scope, *) {
      font: inherit;
    }

    :where(:scope, *):where(button) {
      appearance: button;
    }
  }

  /* Tailwind v4 ha tolto il cursor pointer dai button: lo ridà la base, non ogni componente. */
  button:not(:disabled),
  [role='button']:not([aria-disabled='true']) {
    cursor: pointer;
  }
}
/* Icon (Foundations › Icons): Lucide 20 × 20, tratto 1.5 px che non scala con la taglia,
   colore da currentColor. Dentro un controllo la taglia la decide il controllo (--_icon-size). */
@layer components {
  .oxq-icon,
  .oxq-spinner {
    flex-shrink: 0;
    inline-size: var(--_icon-size, var(--oxq-size-icon-md));
    block-size: var(--_icon-size, var(--oxq-size-icon-md));

    & * {
      vector-effect: non-scaling-stroke;
    }
  }

  .oxq-icon:where([data-size='sm']),
  .oxq-spinner:where([data-size='sm']) {
    --_icon-size: var(--oxq-size-icon-sm);
  }

  .oxq-icon:where([data-size='lg']),
  .oxq-spinner:where([data-size='lg']) {
    --_icon-size: var(--oxq-size-icon-lg);
  }
}
/* Logo (Foundations › Brand Identity › logo e tagline): il marchio OXEQUA come SVG inline, dall'export di Figma
   (oxq_ui/logo.json). Prop Figma → attributi: data-type, data-color; style sceglie l'artwork (solid o outline).
   I riempimenti hanno un ruolo, data-fill: mark (la chevron rossa del primary), ink (il resto) e back (la chevron
   dietro la X, al 60 %). color li colora e si sceglie in base al fondo, non al tema: i token brand sono uguali nei
   due modi.
   - fondi chiari: full-color (chevron rossa, resto nero) o ink (tutto nero)
   - fondi scuri e rosso: full-color-reverse (chevron rossa, resto bianco) o reverse (tutto bianco)
   - brand (tutto rosso) solo per submark e submark-x, mai sul rosso
   Alto quanto l'artwork di Figma; si cambia con una classe (h-8), fino al minimo del DS: 24 px primary,
   pictogram-tagline e tagline, 16 px gli altri. */
@layer components {
  .oxq-logo {
    --_ink: var(--oxq-brand-text-ink);
    --_mark: var(--_ink);
    --_back: var(--oxq-brand-shape-ink-x-back);

    display: inline-block;
    flex-shrink: 0;
    inline-size: auto;
    block-size: var(--oxq-size-logo-height);
    min-block-size: var(--oxq-size-logo-min);
    vertical-align: middle;

    & [data-fill='ink'] {
      fill: var(--_ink);
    }

    & [data-fill='mark'] {
      fill: var(--_mark);
    }

    & [data-fill='back'] {
      fill: var(--_back);
    }
  }

  .oxq-logo:where([data-type='primary'], [data-type='pictogram-tagline'], [data-type='tagline']) {
    min-block-size: var(--oxq-size-logo-min-wide);
  }

  .oxq-logo:where([data-color='full-color']) {
    --_mark: var(--oxq-brand-surface-solid);
  }

  .oxq-logo:where([data-color='full-color-reverse'], [data-color='reverse']) {
    --_ink: var(--oxq-brand-text-reverse);
    --_back: var(--oxq-brand-shape-reverse-x-back);
  }

  .oxq-logo:where([data-color='full-color-reverse']) {
    --_mark: var(--oxq-brand-surface-solid);
  }

  .oxq-logo:where([data-color='brand']) {
    --_ink: var(--oxq-brand-surface-solid);
    --_back: var(--oxq-brand-surface-solid-x-back);
  }
}
/* Spinner (Atoms › Spinner): attesa di durata indefinita, ruota di continuo con easing/loop.
   Taglie e tratto come le icone (icon.css); il colore lo decide chi lo contiene. */
@layer components {
  .oxq-spinner {
    animation: oxq-spin var(--oxq-duration-spin) var(--oxq-easing-loop) infinite;
  }
}

@keyframes oxq-spin {
  to {
    rotate: 1turn;
  }
}
/* Button e icon-button (Atoms › Button).
   Prop Figma → attributi: data-variant, data-tone (sempre presente), data-size.
   Gli state li decide il browser: :hover, :active, :focus-visible (base.css), :disabled / aria-disabled, aria-busy.
   Ogni variant sceglie i ruoli da --oxq-tone-* (tokens.css): tone × variant non si moltiplica.
   Tutto a specificità (0,1,0) con :where(), così le utility del progetto (w-full) vincono. */

/* Overlay system/state/* di hover e pressed: registrato per poterlo animare. */
@property --_overlay {
  syntax: '<color>';
  inherits: false;
  initial-value: transparent;
}

@layer components {
  .oxq-button {
    --_height: var(--oxq-size-control-sm);
    --_icon-size: var(--oxq-size-icon-sm);
    --_bg: transparent;
    --_border: transparent;
    --_shadow: none;
    --_fg: var(--oxq-tone-text-ink);
    --_fg-icon: var(--oxq-tone-icon-ink);

    position: relative;
    box-sizing: border-box;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--oxq-space-gap-2xs);
    block-size: var(--_height);
    /* Il bordo sta dentro altezza e padding, come lo stroke inside di Figma. */
    padding-inline: calc(var(--oxq-space-inset-control-x) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-control);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    box-shadow: var(--_shadow);
    color: var(--_fg);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
    white-space: nowrap;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, border-color, box-shadow, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > :is(.oxq-icon, .oxq-spinner) {
      color: var(--_fg-icon);
    }

    /* Area sensibile di almeno size/control/tap-min anche quando il bottone è più basso. */
    &::after {
      content: '';
      position: absolute;
      inset: 50% auto auto 50%;
      translate: -50% -50%;
      inline-size: max(100%, var(--oxq-size-control-tap-min));
      block-size: max(100%, var(--oxq-size-control-tap-min));
    }
  }

  /* Size: sm è il default del DS. */
  .oxq-button:where([data-size='md']) {
    --_height: var(--oxq-size-control-md);
    --_icon-size: var(--oxq-size-icon-md);
  }

  .oxq-button:where([data-size='lg']) {
    --_height: var(--oxq-size-control-lg);
    --_icon-size: var(--oxq-size-icon-lg);
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  /* Icon-button: quadrato, stessa altezza del button. */
  .oxq-button:where(.oxq-icon-button) {
    inline-size: var(--_height);
    padding-inline: 0;
  }

  /* Variant, dal più forte al più leggero. */
  .oxq-button:where([data-variant='primary']) {
    --_bg: var(--oxq-tone-surface-solid);
    --_fg: var(--oxq-tone-text-on-ink);
    --_fg-icon: var(--oxq-tone-icon-on-ink);
  }

  .oxq-button:where([data-variant='secondary']) {
    --_bg: var(--oxq-tone-surface-raised);
    --_border: var(--oxq-tone-line-control);
  }

  .oxq-button:where([data-variant='soft']) {
    --_bg: var(--oxq-tone-surface-control);
  }

  .oxq-button:where([data-variant='elevated']) {
    --_bg: var(--oxq-tone-surface-raised);
    --_shadow: var(--oxq-elevation-1);
  }

  /* Ghost ed elevated usano secondary; neutral e warning restano su ink. */
  .oxq-button:where([data-variant='ghost'], [data-variant='elevated']):where(
      :not([data-tone='neutral'], [data-tone='warning'])
    ) {
    --_fg: var(--oxq-tone-text-secondary);
    --_fg-icon: var(--oxq-tone-icon-secondary);
  }

  /* Hover e pressed: primary cambia fondo, le altre aggiungono l'overlay system/state/*. */
  @media (hover: hover) {
    .oxq-button:where(:not([data-variant='primary']):hover:not(:disabled, [aria-disabled='true'])) {
      --_overlay: var(--oxq-system-state-hover);
    }

    .oxq-button:where([data-variant='primary']:hover:not(:disabled, [aria-disabled='true'])) {
      --_bg: var(--oxq-tone-surface-solid-hover);
    }

    .oxq-button:where([data-variant='elevated']:hover:not(:disabled, [aria-disabled='true'])) {
      --_shadow: var(--oxq-elevation-2);
    }
  }

  .oxq-button:where(:not([data-variant='primary']):active:not(:disabled, [aria-disabled='true'])) {
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-button:where([data-variant='primary']:active:not(:disabled, [aria-disabled='true'])) {
    --_bg: var(--oxq-tone-surface-solid-pressed);
  }

  .oxq-button:where([data-variant='elevated']:active:not(:disabled, [aria-disabled='true'])) {
    --_shadow: var(--oxq-elevation-1);
  }

  /* Disabled: fondo control-disabled, testo e icona muted. Loading resta come rest (aria-disabled ma
     aria-busy), e così una richiesta htmx con hx-disabled-elt, sul bottone o sul form del submit. */
  .oxq-button:where(:disabled, [aria-disabled='true']):where(
      :not([aria-busy='true'], .htmx-request, .htmx-request [type='submit'])
    ) {
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: transparent;
    --_shadow: none;
    --_fg: var(--oxq-tone-text-muted);
    --_fg-icon: var(--oxq-tone-icon-muted);
    cursor: not-allowed;
    transition: none;
  }

  .oxq-button:where([data-variant='secondary']):where(:disabled, [aria-disabled='true']):where(
      :not([aria-busy='true'], .htmx-request, .htmx-request [type='submit'])
    ) {
    --_bg: var(--oxq-tone-surface-raised);
    --_border: var(--oxq-tone-line-border);
  }

  .oxq-button:where([data-variant='ghost']):where(:disabled, [aria-disabled='true']) {
    --_bg: transparent;
  }

  .oxq-button:where([aria-busy='true'], .htmx-request, .htmx-request [type='submit']) {
    cursor: wait;
  }

  /* Richiesta htmx in corso (solo Django): .htmx-request sul bottone che la fa, o sul form del submit.
     Lo spinner nascosto (data-oxq-htmx) prende il posto di icon-start, il resto resta come rest. */
  .oxq-button > :where(.oxq-spinner[data-oxq-htmx]) {
    display: none;
  }

  .oxq-button:where(.htmx-request, .htmx-request [type='submit']) {
    & > :where(.oxq-spinner[data-oxq-htmx]) {
      display: revert;
    }

    & > :where(.oxq-icon:has(+ .oxq-spinner[data-oxq-htmx])) {
      display: none;
    }
  }
}
/* Link (Atoms › Link): porta a un'altra pagina.
   Prop Figma → attributi: data-tone (neutral | brand, sempre presente), data-variant (underline | ghost),
   data-text (label | body), data-size.
   - tone: neutral di default, in neutral/text/ink; brand è uno stile opzionale, nel rosso del link
   - variant: underline è sempre sottolineato, come nel testo; ghost non lo è a riposo, solo in hover: per nav e footer
   - text: label accanto a button e chip; body nei paragrafi e nel footer
   Dentro un paragrafo il link è un <a> senza classe: tiene lo stile del paragrafo e prende colore e sottolineatura
   del link neutral. */
@layer components {
  .oxq-link,
  :where(p, li, dd, td, blockquote, figcaption) a:where([href]:not([class])) {
    --_fg: var(--oxq-neutral-text-ink);
    --_fg-hover: var(--oxq-neutral-text-ink-hover);

    border-radius: var(--oxq-radius-selection);
    color: var(--_fg);
    text-decoration-line: underline;
    text-decoration-thickness: var(--oxq-stroke-underline);
    text-underline-offset: var(--oxq-offset-underline);
    text-decoration-skip-ink: auto;
    transition-property: color, text-decoration-thickness;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    @media (hover: hover) {
      &:where(:hover) {
        color: var(--_fg-hover);
        text-decoration-line: underline;
        text-decoration-thickness: var(--oxq-stroke-underline-hover);
      }
    }
  }

  .oxq-link {
    --_fg: var(--oxq-tone-text-ink);
    --_fg-hover: var(--oxq-tone-text-ink-hover);
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  /* brand: il tone brand mappa text/secondary e text/ink-hover sul rosso dei testi (danger). */
  .oxq-link:where([data-tone='brand']) {
    --_fg: var(--oxq-tone-text-secondary);
  }

  .oxq-link:where([data-variant='ghost']) {
    text-decoration-line: none;
  }

  /* Size: lo stesso testo dei label, così il link sta accanto a button e chip; con text body quello del paragrafo. */
  .oxq-link:where([data-size='md']) {
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-link:where([data-size='lg']) {
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  .oxq-link:where([data-text='body']) {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-link:where([data-text='body'][data-size='md']) {
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-link:where([data-text='body'][data-size='lg']) {
    font: var(--oxq-font-body-lg);
    letter-spacing: var(--oxq-body-lg-letter-spacing);
  }
}
/* Divider (Atoms › Divider): separa gruppi di contenuto e basta, non è interattivo.
   Prop Figma → attributi: aria-orientation (horizontal | vertical), data-line (border | hairline).
   Il colore segue il tone del contenitore (--oxq-tone-line-*): ogni famiglia ha il suo divisore.
   Lo spazio intorno è il gap del contesto, mai un margine del divider. */
@layer components {
  .oxq-divider {
    flex-shrink: 0;
    align-self: stretch;
    block-size: var(--oxq-stroke-divider);
    margin: 0;
    border: 0;
    background-color: var(--oxq-tone-line-border);
  }

  .oxq-divider:where([data-line='hairline']) {
    background-color: var(--oxq-tone-line-hairline);
  }

  /* Vertical solo fra elementi in fila: alto quanto il più alto. */
  .oxq-divider:where([aria-orientation='vertical']) {
    inline-size: var(--oxq-stroke-divider);
    block-size: auto;
  }
}
/* Splitter (Atoms › Divider › splitter): la maniglia fra due pannelli ridimensionabili. Il divider separa e basta;
   lo splitter si trascina, o si sposta con le frecce, e cambia la misura del primo pannello.
   Prop Figma → attributi: data-orientation (vertical | horizontal) e aria-orientation. hover, pressed e focus li
   decide il browser.
   - .oxq-split: il contenitore, una griglia col primo pannello, lo splitter e il secondo. La misura del primo è
     --oxq-split, una percentuale; la aggiornano oxq.js o il v-model di Vue. Senza, metà e metà.
   - .oxq-splitter: role="separator", 9 px da afferrare con la linea al centro, cursore ew-resize o ns-resize. */
@layer components {
  .oxq-split {
    display: grid;
    grid-template-columns: minmax(0, var(--oxq-split, 50%)) auto minmax(0, 1fr);
    min-block-size: 0;
  }

  .oxq-split:where([data-orientation='horizontal']) {
    grid-template-rows: minmax(0, var(--oxq-split, 50%)) auto minmax(0, 1fr);
    grid-template-columns: none;
  }

  /* vertical: la linea è verticale, fra pannelli affiancati. */
  .oxq-splitter {
    --_line: var(--oxq-neutral-line-border);
    --_stroke: var(--oxq-stroke-divider);

    position: relative;
    flex-shrink: 0;
    inline-size: var(--oxq-size-splitter-grab);
    block-size: 100%;
    cursor: ew-resize;
    touch-action: none;
    user-select: none;

    &::before {
      content: '';
      position: absolute;
      inset-block: 0;
      inset-inline-start: 50%;
      inline-size: var(--_stroke);
      translate: -50% 0;
      background-color: var(--_line);
      transition: background-color var(--oxq-duration-state) var(--oxq-easing-transition);
    }
  }

  .oxq-splitter:where([data-orientation='horizontal']) {
    inline-size: 100%;
    block-size: var(--oxq-size-splitter-grab);
    cursor: ns-resize;

    &::before {
      inset: 50% 0 auto;
      inline-size: auto;
      block-size: var(--_stroke);
      translate: 0 -50%;
    }
  }

  @media (hover: hover) {
    .oxq-splitter:where(:hover) {
      --_line: var(--oxq-neutral-line-control);
    }
  }

  .oxq-splitter:where(:active) {
    --_line: var(--oxq-neutral-line-control);
    --_stroke: var(--oxq-stroke-splitter-active);
  }

  /* Focus: niente anello attorno, la linea stessa diventa system/focus/ring. */
  .oxq-splitter:focus-visible {
    --_line: var(--oxq-system-focus-ring);
    --_stroke: var(--oxq-stroke-splitter-active);

    outline: none;
  }
}
/* Skeleton (Atoms › Skeleton): segnaposto del contenuto mentre carica. È decorativo (aria-hidden):
   chi carica mette aria-busy="true" sul contenitore.
   Prop Figma → attributo: data-shape. Le misure si cambiano con le utility (size-avatar-lg, w-2/3).
   Il riflesso attraversa in duration/shimmer con easing/loop; in reduced motion la durata è 0 e resta fermo. */
@layer components {
  .oxq-skeleton {
    /* Il rettangolo sfocato di Figma come gradiente: rampe larghe il doppio del blur, pieno al centro. */
    --_blur: var(--oxq-blur-skeleton-shine);
    --_shine-size: calc(var(--oxq-size-skeleton-shine) + 2 * var(--_blur));
    --_shine: color-mix(
      in srgb,
      var(--oxq-neutral-surface-raised) calc(var(--oxq-opacity-skeleton-shine) * 100%),
      transparent
    );

    display: block;
    flex-shrink: 0;
    /* text: largo quanto la colonna, alto una riga di testo. */
    inline-size: 100%;
    block-size: var(--oxq-size-skeleton-text);
    border-radius: var(--oxq-radius-selection);
    background-color: var(--oxq-neutral-surface-skeleton);
    background-image: linear-gradient(
      to right,
      transparent,
      var(--_shine) calc(2 * var(--_blur)),
      var(--_shine) calc(100% - 2 * var(--_blur)),
      transparent
    );
    background-repeat: no-repeat;
    background-size: var(--_shine-size) 100%;
    background-position: calc(-1 * var(--_shine-size)) 0;
    animation: oxq-shimmer var(--oxq-duration-shimmer) var(--oxq-easing-loop) infinite;
  }

  .oxq-skeleton:where([data-shape='square']) {
    inline-size: var(--oxq-size-icon-md);
    block-size: var(--oxq-size-icon-md);
  }

  .oxq-skeleton:where([data-shape='circle']) {
    inline-size: var(--oxq-size-avatar-md);
    block-size: var(--oxq-size-avatar-md);
    border-radius: var(--oxq-radius-pill);
  }

  /* block: la larghezza la dà la colonna, l'altezza il rapporto (Foundations › Aspect ratio, 16 / 9). */
  .oxq-skeleton:where([data-shape='block']) {
    block-size: auto;
    aspect-ratio: 16 / 9;
    border-radius: var(--oxq-radius-container);
  }
}

@keyframes oxq-shimmer {
  to {
    background-position: calc(100% + var(--_shine-size)) 0;
  }
}
/* Badge (Atoms › Badge). Non è un controllo: niente hover, focus o disabled.
   Il colore non basta: la label, il numero o il glifo dicono lo stato anche senza colore.
   - badge: stato o categoria in 1-2 parole. Prop Figma → data-variant, data-tone, data-size.
   - counter-badge: un numero; zero non si mostra, oltre 99 è 99+ (lo decidono gli adattatori).
   - dot-badge: una novità senza numero, in alto a destra dell'icona.
   - presence-badge: lo stato di una persona, in basso a destra dell'avatar (data-status).
   Badge e counter sono alti come un'icona (size/icon/*), così si allineano alle icone della riga. */
@layer components {
  .oxq-badge,
  .oxq-counter-badge {
    --_height: var(--oxq-size-icon-sm);
    --_pad: var(--oxq-space-gap-2xs);
    --_bg: transparent;
    --_border: transparent;
    --_fg: var(--oxq-tone-text-ink);
    --_fg-icon: var(--oxq-tone-icon-ink);
    --_icon-size: var(--oxq-size-icon-sm);

    box-sizing: border-box;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--oxq-space-gap-2xs);
    block-size: var(--_height);
    /* Il bordo sta dentro altezza e padding, come lo stroke inside di Figma. */
    padding-inline: calc(var(--_pad) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;

    & > .oxq-icon {
      color: var(--_fg-icon);
    }
  }

  .oxq-counter-badge {
    min-inline-size: var(--_height);
  }

  /* Size: sm è il default. Il counter tiene il padding space/gap/2xs a tutte le size. */
  .oxq-badge:where([data-size='md']),
  .oxq-counter-badge:where([data-size='md']) {
    --_height: var(--oxq-size-icon-md);
  }

  .oxq-badge:where([data-size='lg']),
  .oxq-counter-badge:where([data-size='lg']) {
    --_height: var(--oxq-size-icon-lg);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-badge:where([data-size='md'], [data-size='lg']) {
    --_pad: var(--oxq-space-gap-xs);
  }

  /* Variant: badge solid, soft, outline, ghost; counter solid e soft. brand esiste solo solid. */
  .oxq-badge:where([data-variant='solid']),
  .oxq-counter-badge:where([data-variant='solid']) {
    --_bg: var(--oxq-tone-surface-solid);
    --_fg: var(--oxq-tone-text-on-ink);
    --_fg-icon: var(--oxq-tone-icon-on-ink);
  }

  /* soft: il badge sul canvas del tone col testo secondary, il counter sul muted. */
  .oxq-badge:where([data-variant='soft']) {
    --_bg: var(--oxq-tone-surface-canvas);
    --_fg: var(--oxq-tone-text-secondary);
    --_fg-icon: var(--oxq-tone-icon-secondary);
  }

  .oxq-counter-badge:where([data-variant='soft']) {
    --_bg: var(--oxq-tone-surface-muted);
  }

  /* Solo l'outline ha lo stroke in Figma, incluso nel layout: il bordo si aggiunge al padding, 2 px più largo. */
  .oxq-badge:where([data-variant='outline']) {
    --_border: var(--oxq-tone-line-border-strong);

    padding-inline: var(--_pad);
  }

  /* Ghost usa secondary; neutral e warning restano su ink. */
  .oxq-badge:where([data-variant='ghost']):where(:not([data-tone='neutral'], [data-tone='warning'])) {
    --_fg: var(--oxq-tone-text-secondary);
    --_fg-icon: var(--oxq-tone-icon-secondary);
  }

  /* Dot: il pieno del tone; success, warning e neutral-secondary hanno un pieno per gli indicatori piccoli. */
  .oxq-dot-badge {
    display: inline-block;
    flex-shrink: 0;
    inline-size: var(--oxq-size-dot-sm);
    block-size: var(--oxq-size-dot-sm);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-tone-surface-solid);
  }

  .oxq-dot-badge:where([data-size='md']) {
    inline-size: var(--oxq-size-dot-md);
    block-size: var(--oxq-size-dot-md);
  }

  .oxq-dot-badge:where([data-size='lg']) {
    inline-size: var(--oxq-size-dot-lg);
    block-size: var(--oxq-size-dot-lg);
  }

  .oxq-dot-badge:where([data-tone='success']) {
    background-color: var(--oxq-success-surface-indicator);
  }

  .oxq-dot-badge:where([data-tone='warning']) {
    background-color: var(--oxq-warning-surface-indicator);
  }

  .oxq-dot-badge:where([data-tone='neutral-secondary']) {
    background-color: var(--oxq-neutral-surface-indicator);
  }

  /* Presence: un cerchio (--_bg) e un glifo disegnato per il cerchio (--_glyph, colore --_fg).
     Il glifo è una maschera in viewBox 16: il tratto resta 1/8 del diametro a ogni size. */
  .oxq-presence-badge {
    --_bg: transparent;
    --_fg: transparent;
    --_glyph: none;

    position: relative;
    display: inline-block;
    flex-shrink: 0;
    inline-size: var(--oxq-size-presence-sm);
    block-size: var(--oxq-size-presence-sm);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);

    &::after {
      content: '';
      position: absolute;
      inset: 0;
      background-color: var(--_fg);
      mask: var(--_glyph) center / 100% no-repeat;
    }
  }

  .oxq-presence-badge:where([data-size='xs']) {
    inline-size: var(--oxq-size-presence-xs);
    block-size: var(--oxq-size-presence-xs);
  }

  .oxq-presence-badge:where([data-size='md']) {
    inline-size: var(--oxq-size-presence-md);
    block-size: var(--oxq-size-presence-md);
  }

  .oxq-presence-badge:where([data-size='lg']) {
    inline-size: var(--oxq-size-presence-lg);
    block-size: var(--oxq-size-presence-lg);
  }

  .oxq-presence-badge:where([data-status='available']) {
    --_bg: var(--oxq-success-surface-solid);
    --_fg: var(--oxq-success-icon-on-ink);
    --_glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.48 8.32 6.88 10.56 11.52 5.92' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  .oxq-presence-badge:where([data-status='away']) {
    --_bg: var(--oxq-warning-surface-solid);
    --_fg: var(--oxq-warning-icon-on-ink);
    --_glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 4.16V8.32L10.88 10.08' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  .oxq-presence-badge:where([data-status='busy']) {
    --_bg: var(--oxq-danger-surface-solid);
  }

  /* do-not-disturb e offline sono la X di OXQ al 76% del diametro, senza cerchio: rossa e grigia. */
  .oxq-presence-badge:where([data-status='do-not-disturb'], [data-status='offline']) {
    --_fg: var(--oxq-danger-surface-solid);
    --_glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M14.0746 4.82589L10.8551 8.04646L14.0746 11.266V14.0353H11.1679L8.01645 10.8838L7.95397 10.8198L4.69302 14.08H1.92578V11.1743L5.14534 7.95376L1.92578 4.73395V1.96494H4.83169L7.98292 5.11617L8.0454 5.17992L11.3074 1.91998H14.0746V4.82589Z'/%3E%3C/svg%3E");
  }

  .oxq-presence-badge:where([data-status='offline']) {
    --_fg: var(--oxq-neutral-icon-secondary);
  }

  /* blocked e unknown: cerchio raised con l'anello nel colore del glifo. */
  .oxq-presence-badge:where([data-status='blocked'], [data-status='unknown']) {
    --_bg: var(--oxq-neutral-surface-raised);
    --_fg: var(--oxq-neutral-icon-secondary);
  }

  .oxq-presence-badge:where([data-status='blocked']) {
    --_fg: var(--oxq-danger-icon-ink);
    --_glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2'%3E%3Ccircle cx='8' cy='8' r='7'/%3E%3Cpath d='M3.76 12.24 12.24 3.76' stroke-linecap='round'/%3E%3C/svg%3E");
  }

  .oxq-presence-badge:where([data-status='unknown']) {
    --_glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2'%3E%3Ccircle cx='8' cy='8' r='7'/%3E%3C/svg%3E");
  }

  /* outline: il filo raised di 2 px (stroke/keyline) che stacca il badge da quello che ha sotto, come sull'avatar. */
  .oxq-presence-badge:where([data-outline]) {
    box-shadow: 0 0 0 var(--oxq-stroke-keyline) var(--oxq-neutral-surface-raised);
  }

  /* do-not-disturb e offline sono la X, senza cerchio: il filo segue la X, 2 px (stroke/keyline) tutto intorno
     con gli angoli tondi. Il viewBox allarga quello del glifo di 2 px per lato, misurati nella size del badge. */
  .oxq-presence-badge:where([data-outline]):where([data-status='do-not-disturb'], [data-status='offline']) {
    --_keyline: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-2.6667 -2.6667 21.3333 21.3333'%3E%3Cpath d='M14.0746 4.82589L10.8551 8.04646L14.0746 11.266V14.0353H11.1679L8.01645 10.8838L7.95397 10.8198L4.69302 14.08H1.92578V11.1743L5.14534 7.95376L1.92578 4.73395V1.96494H4.83169L7.98292 5.11617L8.0454 5.17992L11.3074 1.91998H14.0746V4.82589Z' stroke='black' stroke-width='5.3333' stroke-linejoin='round'/%3E%3C/svg%3E");

    box-shadow: none;

    &::before {
      content: '';
      position: absolute;
      inset: calc(-1 * var(--oxq-stroke-keyline));
      background-color: var(--oxq-neutral-surface-raised);
      mask: var(--_keyline) center / 100% no-repeat;
    }
  }

  .oxq-presence-badge:where([data-outline]):where([data-status='do-not-disturb'], [data-status='offline']):where(
      [data-size='md']
    ) {
    --_keyline: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 20 20'%3E%3Cpath d='M14.0746 4.82589L10.8551 8.04646L14.0746 11.266V14.0353H11.1679L8.01645 10.8838L7.95397 10.8198L4.69302 14.08H1.92578V11.1743L5.14534 7.95376L1.92578 4.73395V1.96494H4.83169L7.98292 5.11617L8.0454 5.17992L11.3074 1.91998H14.0746V4.82589Z' stroke='black' stroke-width='4' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  .oxq-presence-badge:where([data-outline]):where([data-status='do-not-disturb'], [data-status='offline']):where(
      [data-size='lg']
    ) {
    --_keyline: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1.6 -1.6 19.2 19.2'%3E%3Cpath d='M14.0746 4.82589L10.8551 8.04646L14.0746 11.266V14.0353H11.1679L8.01645 10.8838L7.95397 10.8198L4.69302 14.08H1.92578V11.1743L5.14534 7.95376L1.92578 4.73395V1.96494H4.83169L7.98292 5.11617L8.0454 5.17992L11.3074 1.91998H14.0746V4.82589Z' stroke='black' stroke-width='3.2' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  .oxq-presence-badge:where([data-outline]):where([data-status='do-not-disturb'], [data-status='offline']):where(
      [data-size='xs']
    ) {
    --_keyline: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-3.2 -3.2 22.4 22.4'%3E%3Cpath d='M14.0746 4.82589L10.8551 8.04646L14.0746 11.266V14.0353H11.1679L8.01645 10.8838L7.95397 10.8198L4.69302 14.08H1.92578V11.1743L5.14534 7.95376L1.92578 4.73395V1.96494H4.83169L7.98292 5.11617L8.0454 5.17992L11.3074 1.91998H14.0746V4.82589Z' stroke='black' stroke-width='6.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}
/* Tag (Atoms › Tag): l'etichetta di una categoria (reparto, progetto, tipo di documento). Distingue e basta: per
   uno stato c'è il badge, per un filtro il chip. Non si clicca e non si chiude.
   Prop Figma → attributi: data-color (neutral | yellow | green | blue | violet | magenta), data-size. Neutral su
   surface/control, gli accent soft; l'angolo radius/selection lo distingue dal chip, che è a pillola.
   L'icona facoltativa sta prima della label. Fra tag vicini space/gap/xs, a capo se non entrano. */
@layer components {
  .oxq-tag {
    --_bg: var(--oxq-neutral-surface-control);
    --_fg: var(--oxq-neutral-text-ink);
    --_fg-icon: var(--oxq-neutral-icon-ink);
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    min-block-size: var(--oxq-size-tag-sm);
    padding-inline: var(--oxq-space-gap-xs);
    border-radius: var(--oxq-radius-selection);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;
    vertical-align: middle;

    & > .oxq-icon {
      color: var(--_fg-icon);
    }
  }

  .oxq-tag:where([data-size='md']) {
    min-block-size: var(--oxq-size-tag-md);
    padding-inline: var(--oxq-space-gap-sm);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-tag:where([data-color='yellow']) {
    --_bg: var(--oxq-accent-yellow-surface-soft);
    --_fg: var(--oxq-accent-yellow-text-ink);
    --_fg-icon: var(--oxq-accent-yellow-icon-ink);
  }

  .oxq-tag:where([data-color='green']) {
    --_bg: var(--oxq-accent-green-surface-soft);
    --_fg: var(--oxq-accent-green-text-ink);
    --_fg-icon: var(--oxq-accent-green-icon-ink);
  }

  .oxq-tag:where([data-color='blue']) {
    --_bg: var(--oxq-accent-blue-surface-soft);
    --_fg: var(--oxq-accent-blue-text-ink);
    --_fg-icon: var(--oxq-accent-blue-icon-ink);
  }

  .oxq-tag:where([data-color='violet']) {
    --_bg: var(--oxq-accent-violet-surface-soft);
    --_fg: var(--oxq-accent-violet-text-ink);
    --_fg-icon: var(--oxq-accent-violet-icon-ink);
  }

  .oxq-tag:where([data-color='magenta']) {
    --_bg: var(--oxq-accent-magenta-surface-soft);
    --_fg: var(--oxq-accent-magenta-text-ink);
    --_fg-icon: var(--oxq-accent-magenta-icon-ink);
  }
}
/* Avatar (Atoms › Avatar): una persona, un team o un gruppo.
   Il tipo viene dai dati: la foto se c'è, altrimenti le initials, e l'icona quando non si sa chi sia.
   Prop Figma → attributi: data-shape (o | square | ox | q), data-size, data-color, data-active.
   color: neutral e brand solid, gli accent soft (accent/*: colori senza significato, non i tone).
   Dentro .oxq-avatar-shape stanno fondo e contenuto; fuori, lo stato (presence-badge) e l'anello active,
   solo su o e square. */
@layer components {
  .oxq-avatar {
    /* Le shape del brand (Foundations › Shapes): ox e q ritagliano l'avatar nei gruppi. */
    --_ox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 192 192'%3E%3Cpath d='M191.912 45.8828L182.817 54.9795C188.705 67.4184 192 81.3242 192 96C192 111.063 188.529 125.316 182.346 138.003L191.912 147.569V191.294H146.017L137.373 182.65C124.845 188.643 110.815 192 96 192C80.7877 192 66.4025 188.461 53.6211 182.162L43.7812 192H0.0878906V146.121L9.18262 137.022C3.29451 124.583 0 110.676 0 96C0 80.9368 3.47018 66.6843 9.65332 53.9971L0.0878906 44.4307V0.709961H45.9707L54.6152 9.35449C67.1465 3.35835 81.181 0 96 0C111.211 0 125.595 3.53843 138.376 9.83594L148.219 0H191.912V45.8828Z'/%3E%3C/svg%3E");
    --_q: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 192 192'%3E%3Cpath d='M178.706 144.717L191.984 158.089V191.244H158.309L145.315 178.36C138.653 182.361 131.486 185.574 123.879 187.873C115.042 190.567 105.655 192 95.9842 192C86.3134 192 76.926 190.567 68.0899 187.873C37.7542 178.691 13.766 154.876 4.31565 124.65C1.49629 115.594 0 105.986 0 96.0157C0 86.5024 1.37029 77.3198 3.96914 68.6412C13.0887 37.8015 37.3447 13.4353 68.1372 4.12667C76.9418 1.43331 86.3134 0 96 0C105.671 0 114.995 1.43331 123.831 4.09516C154.608 13.4195 178.864 37.8015 188.031 68.6412C190.63 77.304 192 86.5024 192 96.0157C192 105.986 190.504 115.594 187.653 124.65C185.432 131.722 182.439 138.448 178.706 144.717Z'/%3E%3C/svg%3E");
    --_size: var(--oxq-size-avatar-xs);
    --_radius: var(--oxq-radius-pill);
    --_icon-size: var(--oxq-size-icon-sm);
    --_bg: var(--oxq-neutral-surface-solid);
    --_fg: var(--oxq-neutral-text-on-ink);
    --_fg-icon: var(--oxq-neutral-icon-on-ink);

    position: relative;
    isolation: isolate;
    display: inline-flex;
    flex-shrink: 0;
    inline-size: var(--_size);
    block-size: var(--_size);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-avatar-shape {
    position: relative;
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: var(--_radius);
    background-color: var(--_bg);
    color: var(--_fg);
    white-space: nowrap;

    & > .oxq-icon {
      color: var(--_fg-icon);
    }
  }

  .oxq-avatar-photo {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
  }

  /* Size: xs è il default del DS. Le initials in label/*, in lg title/large. */
  .oxq-avatar:where([data-size='sm']) {
    --_size: var(--oxq-size-avatar-sm);
    --_icon-size: var(--oxq-size-icon-md);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-avatar:where([data-size='md']) {
    --_size: var(--oxq-size-avatar-md);
    --_icon-size: var(--oxq-size-icon-lg);
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  .oxq-avatar:where([data-size='lg']) {
    --_size: var(--oxq-size-avatar-lg);
    --_icon-size: var(--oxq-size-icon-xl);
    font: var(--oxq-font-title-lg);
    letter-spacing: var(--oxq-title-lg-letter-spacing);
  }

  /* Shape: square per team, organizzazioni e spazi: radius/item in xs, radius/control dalle sm in su. */
  .oxq-avatar:where([data-shape='square']) {
    --_radius: var(--oxq-radius-control);
  }

  .oxq-avatar:where([data-shape='square'][data-size='xs']) {
    --_radius: var(--oxq-radius-item);
  }

  /* ox e q, solo nei gruppi: ox al 93% e q al 96%, per pesare come la o. */
  .oxq-avatar:where([data-shape='ox']) > .oxq-avatar-shape {
    border-radius: 0;
    mask: var(--_ox) center / 93% no-repeat;
  }

  .oxq-avatar:where([data-shape='q']) > .oxq-avatar-shape {
    border-radius: 0;
    mask: var(--_q) center / 96% no-repeat;
  }

  /* Color: neutral e brand solid, gli accent soft. Valgono anche per gli spicchi del pie. */
  :is(.oxq-avatar, .oxq-avatar-pie-segment):where([data-color='brand']) {
    --_bg: var(--oxq-brand-surface-solid);
    --_fg: var(--oxq-brand-text-on-solid);
    --_fg-icon: var(--oxq-brand-icon-on-solid);
  }

  :is(.oxq-avatar, .oxq-avatar-pie-segment):where([data-color='yellow']) {
    --_bg: var(--oxq-accent-yellow-surface-soft);
    --_fg: var(--oxq-accent-yellow-text-ink);
    --_fg-icon: var(--oxq-accent-yellow-icon-ink);
  }

  :is(.oxq-avatar, .oxq-avatar-pie-segment):where([data-color='green']) {
    --_bg: var(--oxq-accent-green-surface-soft);
    --_fg: var(--oxq-accent-green-text-ink);
    --_fg-icon: var(--oxq-accent-green-icon-ink);
  }

  :is(.oxq-avatar, .oxq-avatar-pie-segment):where([data-color='blue']) {
    --_bg: var(--oxq-accent-blue-surface-soft);
    --_fg: var(--oxq-accent-blue-text-ink);
    --_fg-icon: var(--oxq-accent-blue-icon-ink);
  }

  :is(.oxq-avatar, .oxq-avatar-pie-segment):where([data-color='violet']) {
    --_bg: var(--oxq-accent-violet-surface-soft);
    --_fg: var(--oxq-accent-violet-text-ink);
    --_fg-icon: var(--oxq-accent-violet-icon-ink);
  }

  :is(.oxq-avatar, .oxq-avatar-pie-segment):where([data-color='magenta']) {
    --_bg: var(--oxq-accent-magenta-surface-soft);
    --_fg: var(--oxq-accent-magenta-text-ink);
    --_fg-icon: var(--oxq-accent-magenta-icon-ink);
  }

  /* Active: chi parla o chi è selezionato, uno alla volta. 2 px a 2 px dal bordo, come il focus; sullo square
     l'outline segue il raggio e fuori arriva a quello di Figma: radius/control in xs, radius/surface dalle sm. */
  .oxq-avatar:where([data-active]) > .oxq-avatar-shape {
    outline: var(--oxq-stroke-focus) solid var(--oxq-brand-surface-solid);
    outline-offset: var(--oxq-offset-focus);
  }

  /* Stato: centro del badge sul bordo, a 45° in basso a destra, col filo raised di outline (badge.css). */
  .oxq-avatar > .oxq-presence-badge {
    position: absolute;
    inset-block-start: calc(50% + 50% * cos(45deg));
    inset-inline-start: calc(50% + 50% * cos(45deg));
    translate: -50% -50%;
  }

  /* Group: o, ox e q in fila, poi il contatore dei restanti. spread separati, stack sovrapposti
     con un filo raised che segue la forma. */
  .oxq-avatar-group {
    --_size: var(--oxq-size-avatar-xs);
    --_gap: var(--oxq-space-gap-2xs);
    --_overlap: var(--oxq-space-overlap-xs);

    display: inline-flex;
    align-items: center;
    gap: var(--_gap);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-avatar-group:where([data-size='sm']) {
    --_size: var(--oxq-size-avatar-sm);
    --_overlap: var(--oxq-space-overlap-sm);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-avatar-group:where([data-size='md']) {
    --_size: var(--oxq-size-avatar-md);
    --_gap: var(--oxq-space-gap-xs);
    --_overlap: var(--oxq-space-overlap-md);
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  .oxq-avatar-group:where([data-size='lg']) {
    --_size: var(--oxq-size-avatar-lg);
    --_gap: var(--oxq-space-gap-xs);
    --_overlap: var(--oxq-space-overlap-lg);
    font: var(--oxq-font-title-lg);
    letter-spacing: var(--oxq-title-lg-letter-spacing);
  }

  /* Stack: gap non accetta valori negativi, la sovrapposizione è un margine. */
  .oxq-avatar-group:where([data-layout='stack']) {
    --_gap: 0;

    & > * + * {
      margin-inline-start: calc(-1 * var(--_overlap));
    }
  }

  /* Contatore: l'unico tondo del gruppo. position: relative lo dipinge sopra l'avatar prima. */
  .oxq-avatar-overflow {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    inline-size: var(--_size);
    block-size: var(--_size);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-control);
    color: var(--oxq-neutral-text-ink);
    white-space: nowrap;
  }

  .oxq-avatar-group:where([data-layout='stack']) {
    & > .oxq-avatar::before {
      content: '';
      position: absolute;
      inset: calc(-1 * var(--oxq-stroke-keyline));
      z-index: -1;
      border-radius: var(--oxq-radius-pill);
      background-color: var(--oxq-neutral-surface-raised);
    }

    /* Su ox e q il filo è la shape dell'avatar allargata di stroke/keyline per lato. */
    & > .oxq-avatar:where([data-shape='ox'])::before {
      border-radius: 0;
      mask: var(--_ox) center / calc((100% - 2 * var(--oxq-stroke-keyline)) * 0.93 + 2 * var(--oxq-stroke-keyline))
        no-repeat;
    }

    & > .oxq-avatar:where([data-shape='q'])::before {
      border-radius: 0;
      mask: var(--_q) center / calc((100% - 2 * var(--oxq-stroke-keyline)) * 0.96 + 2 * var(--oxq-stroke-keyline))
        no-repeat;
    }

    & > .oxq-avatar-overflow {
      box-shadow: 0 0 0 var(--oxq-stroke-keyline) var(--oxq-neutral-surface-raised);
    }
  }

  /* Pie: due o tre persone in una O sola, ognuna con foto, initials o icona come l'avatar. Due metà, o una metà e
     due quarti, divisi da un filo raised; la metà va alla persona principale. Sempre o, senza stato né anello. */
  .oxq-avatar-pie {
    --_size: var(--oxq-size-avatar-xs);
    --_icon-size: var(--oxq-size-icon-2xs);
    --_split: linear-gradient(var(--oxq-neutral-surface-raised) 0 0);

    position: relative;
    display: inline-grid;
    flex-shrink: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    inline-size: var(--_size);
    block-size: var(--_size);
    overflow: hidden;
    border-radius: var(--oxq-radius-pill);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);

    /* Il filo sta sopra gli spicchi, a cavallo del confine come in Figma. */
    &::after {
      content: '';
      position: absolute;
      inset: 0;
      background: var(--_split) center / var(--oxq-stroke-keyline) 100% no-repeat;
    }
  }

  .oxq-avatar-pie:where([data-count='3']) {
    grid-template-rows: repeat(2, minmax(0, 1fr));

    &::after {
      background:
        var(--_split) center / var(--oxq-stroke-keyline) 100% no-repeat,
        var(--_split) right center / 50% var(--oxq-stroke-keyline) no-repeat;
    }

    & > :first-child {
      grid-row: span 2;
    }
  }

  .oxq-avatar-pie:where([data-size='sm']) {
    --_size: var(--oxq-size-avatar-sm);
    --_icon-size: var(--oxq-size-icon-xs);
  }

  .oxq-avatar-pie:where([data-size='md']) {
    --_size: var(--oxq-size-avatar-md);
    --_icon-size: var(--oxq-size-icon-sm);
  }

  .oxq-avatar-pie:where([data-size='lg']) {
    --_size: var(--oxq-size-avatar-lg);
    --_icon-size: var(--oxq-size-icon-md);

    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  /* Fuori da :where perderebbe con i colori qui sopra, che vengono prima. */
  :where(.oxq-avatar-pie-segment) {
    --_bg: var(--oxq-neutral-surface-solid);
    --_fg: var(--oxq-neutral-text-on-ink);
    --_fg-icon: var(--oxq-neutral-icon-on-ink);
  }

  .oxq-avatar-pie-segment {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background-color: var(--_bg);
    color: var(--_fg);
    white-space: nowrap;

    & > .oxq-icon {
      color: var(--_fg-icon);
    }
  }
}
/* Input field (Atoms › Input field): campo di testo a una riga, con la label sempre visibile sopra.
   Prop Figma → attributi: data-size, data-status (error | warning | success), data-appearance (on-subtle sopra un
   fondo subtle: il box raised invece di sunken; vale anche per il combobox). hover, focus, disabled e
   read-only li decide il browser: il box li legge dall'input con :has(), così vale anche per l'input
   che rende un widget di Django. Le stesse regole valgono per il <select> del dropdown e il trigger del combobox.
   Il campo segue il tone del contenitore (il DS ha un surface/sunken per ogni famiglia: «campo,
   pozzetto»); gli status usano la loro famiglia. */
@layer components {
  .oxq-input-field {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
  }

  .oxq-input-field-label {
    display: flex;
    align-items: baseline;
    gap: var(--oxq-space-gap-2xs);
    color: var(--oxq-tone-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  /* Con il counter (show-counter) la label sta a sinistra e il counter a destra: caratteri scritti su maxlength. */
  .oxq-input-field-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-input-field-counter {
    flex-shrink: 0;
    margin-inline-start: auto;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  /* L'asterisco dei campi obbligatori; il required dell'input lo dice agli screen reader. */
  .oxq-input-field-required {
    color: var(--oxq-danger-text-secondary);
  }

  .oxq-input-field-box {
    --_height: var(--oxq-size-control-sm);
    --_icon-size: var(--oxq-size-icon-sm);
    --_overlay: transparent;
    --_bg: var(--oxq-tone-surface-sunken);
    --_border: var(--oxq-tone-line-control);
    --_fg: var(--oxq-tone-text-ink);
    --_fg-secondary: var(--oxq-tone-text-secondary);
    --_icon: var(--oxq-tone-icon-secondary);

    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    block-size: var(--_height);
    /* Il bordo sta dentro l'altezza e si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding-inline: var(--oxq-space-inset-control-x);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-control);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    cursor: text;
    transition-property: border-color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > :is(.oxq-icon, .oxq-spinner) {
      color: var(--_icon);
    }

    /* L'input (o il select del dropdown) riempie il box: fondo, bordo e anello di focus sono del box. */
    & > :is(input, select, .oxq-combobox-trigger) {
      flex: 1;
      min-inline-size: 0;
      block-size: 100%;
      margin: 0;
      padding: 0;
      border: 0;
      background: none;
      color: inherit;
      font: inherit;
      letter-spacing: inherit;
      outline: none;

      &::placeholder {
        color: var(--_fg-secondary);
        opacity: 1;
      }
    }

    /* icon-end è un'azione sul valore (cancellare, mostrare la password): area sensibile di almeno
       size/control/tap-min, come il button. */
    & > button {
      position: relative;
      display: inline-flex;
      flex-shrink: 0;
      padding: 0;
      border: 0;
      background: none;
      color: var(--_icon);

      &::after {
        content: '';
        position: absolute;
        inset: 50% auto auto 50%;
        translate: -50% -50%;
        inline-size: max(100%, var(--oxq-size-control-tap-min));
        block-size: max(100%, var(--oxq-size-control-tap-min));
      }
    }
  }

  /* prefix e suffix: parti fisse, non si cancellano e non finiscono nel valore inviato. */
  .oxq-input-field-affix {
    flex-shrink: 0;
    color: var(--_fg-secondary);
    white-space: nowrap;
  }

  .oxq-input-field-helper {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    margin: 0;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  /* Size: sm è il default del DS, md quella dei form. In md il valore è a 16 px: sotto, Safari su iOS
     ingrandisce la pagina al focus. */
  .oxq-input-field:where([data-size='md']) {
    & .oxq-input-field-label {
      font: var(--oxq-font-label-md);
      letter-spacing: var(--oxq-label-md-letter-spacing);
    }

    & > .oxq-input-field-box {
      --_height: var(--oxq-size-control-md);
      --_icon-size: var(--oxq-size-icon-md);

      font: var(--oxq-font-body-md);
      letter-spacing: var(--oxq-body-md-letter-spacing);
    }
  }

  .oxq-input-field:where([data-size='lg']) {
    & .oxq-input-field-label {
      font: var(--oxq-font-label-lg);
      letter-spacing: var(--oxq-label-lg-letter-spacing);
    }

    & > .oxq-input-field-box {
      --_height: var(--oxq-size-control-lg);
      --_icon-size: var(--oxq-size-icon-md);

      font: var(--oxq-font-body-lg);
      letter-spacing: var(--oxq-body-lg-letter-spacing);
    }
  }

  .oxq-input-field:where([data-size='md'], [data-size='lg']) > .oxq-input-field-helper,
  .oxq-input-field:where([data-size='md'], [data-size='lg']) > .oxq-input-field-header > .oxq-input-field-counter {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* appearance on-subtle: sopra un fondo subtle (la riga di tabella in modifica) il box è raised, non sunken. */
  .oxq-input-field:where([data-appearance='on-subtle']) > .oxq-input-field-box {
    --_bg: var(--oxq-neutral-surface-raised);
  }

  /* Hover: l'overlay system/state/hover sul fondo e, senza status, il bordo line/control-hover. */
  @media (hover: hover) {
    .oxq-input-field-box:where(:hover):where(
        :not(:has(> :is(input, select, .oxq-combobox-trigger):disabled, > input[readonly]))
      ) {
      --_overlay: var(--oxq-system-state-hover);
    }

    .oxq-input-field:where(:not([data-status]))
      > .oxq-input-field-box:where(:hover):where(
        :not(:has(> :is(input, select, .oxq-combobox-trigger):disabled, > input[readonly]))
      ) {
      --_border: var(--oxq-neutral-line-control-hover);
    }
  }

  /* Focus: l'anello system/focus/ring a 2 px dal box, come nel button; il bordo resta quello dello status. */
  .oxq-input-field-box:where(:has(> :is(input, select, .oxq-combobox-trigger):focus-visible)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);
  }

  /* Status: bordo, icona e messaggio nell'helper, perché il colore da solo non basta. */
  .oxq-input-field:where([data-status='error']) {
    --_status-line: var(--oxq-danger-line-border-strong);
    --_status-fg: var(--oxq-danger-text-secondary);
    --_status-icon: var(--oxq-danger-icon-secondary);
  }

  .oxq-input-field:where([data-status='warning']) {
    --_status-line: var(--oxq-warning-line-border-strong);
    --_status-fg: var(--oxq-warning-text-secondary);
    --_status-icon: var(--oxq-warning-icon-secondary);
  }

  .oxq-input-field:where([data-status='success']) {
    --_status-line: var(--oxq-success-line-border-strong);
    --_status-fg: var(--oxq-success-text-secondary);
    --_status-icon: var(--oxq-success-icon-secondary);
  }

  .oxq-input-field:where([data-status]) {
    & > .oxq-input-field-box {
      --_border: var(--_status-line);
    }

    & > .oxq-input-field-helper,
    & > .oxq-input-field-header > .oxq-input-field-counter {
      color: var(--_status-fg);

      & > .oxq-icon {
        color: var(--_status-icon);
      }
    }
  }

  /* read-only: si legge e si copia ma non si cambia; riceve focus e si invia. */
  .oxq-input-field > .oxq-input-field-box:where(:has(> input[readonly])) {
    --_bg: transparent;
    --_border: var(--oxq-tone-line-border);
  }

  /* disabled: non riceve focus e il valore non si invia. Tutto in muted, senza transizioni. */
  .oxq-input-field > .oxq-input-field-box:where(:has(> :is(input, select, .oxq-combobox-trigger):disabled)) {
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: var(--oxq-tone-line-border);
    --_fg: var(--oxq-tone-text-muted);
    --_fg-secondary: var(--oxq-tone-text-muted);
    --_icon: var(--oxq-tone-icon-muted);

    cursor: not-allowed;
    transition: none;

    & > :is(input, select, .oxq-combobox-trigger) {
      cursor: not-allowed;
    }
  }

  .oxq-input-field:where(:has(> .oxq-input-field-box > :is(input, select, .oxq-combobox-trigger):disabled)) {
    & :is(.oxq-input-field-label, .oxq-input-field-helper, .oxq-input-field-counter),
    & .oxq-input-field-required {
      color: var(--oxq-tone-text-muted);
    }
  }

  /* Richiesta htmx in corso (solo Django): lo spinner nascosto prende il posto di icon-end. */
  .oxq-input-field-box > :where(.oxq-spinner[data-oxq-htmx]) {
    display: none;
  }

  .oxq-input-field-box:where(:has(> .htmx-request)) {
    & > :where(.oxq-spinner[data-oxq-htmx]) {
      display: revert;
    }

    & > :where(.oxq-spinner[data-oxq-htmx]) ~ * {
      display: none;
    }
  }
}
/* Textarea (Atoms › Textarea): campo di testo su più righe, con la label sempre visibile sopra.
   Prop Figma → attributi: data-size, data-status (error | warning | success), data-fixed (show-resize spento).
   Il box è la textarea stessa: hover, focus, disabled e read-only sono i suoi, anche quando la rende
   un widget di Django. Parte da size/textarea e cresce con il testo dove c'è field-sizing; altrove
   si allunga col grip nativo, solo in verticale.
   Il campo segue il tone del contenitore, come input-field; gli status usano la loro famiglia. */
@layer components {
  .oxq-textarea {
    --_min-height: var(--oxq-size-textarea-sm);

    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
    min-inline-size: 0;
  }

  /* Label a sinistra, counter (show-counter) a destra. */
  .oxq-textarea-header,
  .oxq-textarea-footer {
    display: flex;
    justify-content: space-between;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-textarea-header {
    align-items: baseline;
  }

  .oxq-textarea-label {
    display: flex;
    align-items: baseline;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
    color: var(--oxq-tone-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-textarea-required {
    color: var(--oxq-danger-text-secondary);
  }

  .oxq-textarea > textarea {
    --_overlay: transparent;
    --_bg: var(--oxq-tone-surface-sunken);
    --_border: var(--oxq-tone-line-control);
    --_fg: var(--oxq-tone-text-ink);

    display: block;
    min-inline-size: 0;
    min-block-size: var(--_min-height);
    /* Il bordo si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding: var(--oxq-space-inset-control-y) var(--oxq-space-inset-control-x);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-control);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    resize: vertical;
    field-sizing: content;
    transition-property: border-color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    &::placeholder {
      color: var(--oxq-tone-text-secondary);
      opacity: 1;
    }
  }

  /* show-resize spento: altezza fissa, niente grip e niente crescita. */
  .oxq-textarea:where([data-fixed]) > textarea {
    resize: none;
    field-sizing: fixed;
  }

  .oxq-textarea-footer {
    align-items: center;
  }

  .oxq-textarea-helper {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    flex: 1;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
    margin: 0;
  }

  .oxq-textarea-counter {
    flex-shrink: 0;
    margin-inline-start: auto;
    font-variant-numeric: tabular-nums;
  }

  .oxq-textarea :is(.oxq-textarea-helper, .oxq-textarea-counter) {
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  /* Size: sm è il default del DS, md quella dei form. In md il testo è a 16 px: sotto, Safari su iOS
     ingrandisce la pagina al focus. */
  .oxq-textarea:where([data-size='md']) {
    --_min-height: var(--oxq-size-textarea-md);

    & .oxq-textarea-label {
      font: var(--oxq-font-label-md);
      letter-spacing: var(--oxq-label-md-letter-spacing);
    }

    & > textarea {
      font: var(--oxq-font-body-md);
      letter-spacing: var(--oxq-body-md-letter-spacing);
    }
  }

  .oxq-textarea:where([data-size='lg']) {
    --_min-height: var(--oxq-size-textarea-lg);

    & .oxq-textarea-label {
      font: var(--oxq-font-label-lg);
      letter-spacing: var(--oxq-label-lg-letter-spacing);
    }

    & > textarea {
      font: var(--oxq-font-body-lg);
      letter-spacing: var(--oxq-body-lg-letter-spacing);
    }
  }

  .oxq-textarea:where([data-size='md'], [data-size='lg']) :is(.oxq-textarea-helper, .oxq-textarea-counter) {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* Hover: l'overlay system/state/hover sul fondo e, senza status, il bordo line/control-hover. */
  @media (hover: hover) {
    .oxq-textarea > textarea:where(:hover):where(:not(:disabled, [readonly])) {
      --_overlay: var(--oxq-system-state-hover);
    }

    .oxq-textarea:where(:not([data-status])) > textarea:where(:hover):where(:not(:disabled, [readonly])) {
      --_border: var(--oxq-neutral-line-control-hover);
    }
  }

  /* Status: bordo, icona e messaggio nell'helper, e il counter, perché il colore da solo non basta. */
  .oxq-textarea:where([data-status='error']) {
    --_status-line: var(--oxq-danger-line-border-strong);
    --_status-fg: var(--oxq-danger-text-secondary);
    --_status-icon: var(--oxq-danger-icon-secondary);
  }

  .oxq-textarea:where([data-status='warning']) {
    --_status-line: var(--oxq-warning-line-border-strong);
    --_status-fg: var(--oxq-warning-text-secondary);
    --_status-icon: var(--oxq-warning-icon-secondary);
  }

  .oxq-textarea:where([data-status='success']) {
    --_status-line: var(--oxq-success-line-border-strong);
    --_status-fg: var(--oxq-success-text-secondary);
    --_status-icon: var(--oxq-success-icon-secondary);
  }

  .oxq-textarea:where([data-status]) {
    & > textarea {
      --_border: var(--_status-line);
    }

    & :is(.oxq-textarea-helper, .oxq-textarea-counter) {
      color: var(--_status-fg);
    }

    & .oxq-textarea-helper > .oxq-icon {
      color: var(--_status-icon);
    }
  }

  /* read-only: si legge e si copia ma non si cambia; riceve focus e si invia. */
  .oxq-textarea > textarea:where([readonly]) {
    --_bg: transparent;
    --_border: var(--oxq-tone-line-border);
  }

  /* disabled: non riceve focus e il testo non si invia. Tutto in muted, senza transizioni. */
  .oxq-textarea > textarea:where(:disabled) {
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: var(--oxq-tone-line-border);
    --_fg: var(--oxq-tone-text-muted);

    cursor: not-allowed;
    transition: none;

    &::placeholder {
      color: var(--oxq-tone-text-muted);
    }
  }

  .oxq-textarea:where(:has(> textarea:disabled))
    :is(.oxq-textarea-label, .oxq-textarea-required, .oxq-textarea-helper, .oxq-textarea-counter) {
    color: var(--oxq-tone-text-muted);
  }
}
/* Chip (Atoms › Chip): valore breve scelto o inserito dall'utente. Per uno stato c'è il badge, per
   un'azione il button. Prop Figma → attributi: data-size, data-tone (sempre presente).
   Tre forme, secondo quello che fa:
   - tag: <span>, non interattivo
   - filtro (selected): <label> con un checkbox nascosto; selezionato è :checked, con il check al posto
     dell'icona. Funziona senza JS e si invia col form
   - rimovibile (show-close): <span> con un <button> di chiusura, solo per i valori inseriti
   key (show-key) è il nome del campo prima del valore (Stato Attivo), in text/secondary.
   hover, focus e disabled li decide il browser sul checkbox o sul button. */
@layer components {
  .oxq-chip {
    --_icon-size: var(--oxq-size-icon-sm);
    --_bg: var(--oxq-tone-surface-canvas);
    --_border: var(--oxq-tone-line-border);
    --_fg: var(--oxq-tone-text-ink);
    --_fg-icon: var(--oxq-tone-icon-secondary);
    --_fg-key: var(--oxq-tone-text-secondary);

    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    max-inline-size: 100%;
    min-block-size: var(--oxq-size-chip-sm);
    /* Il bordo sta dentro l'altezza e si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding-inline: var(--oxq-space-gap-xs);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, border-color, color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--_fg-icon);
    }
  }

  /* Una riga sola: se non sta, si accorcia. */
  .oxq-chip-label {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Il key non si accorcia: se manca spazio cede il valore. */
  .oxq-chip-key {
    flex-shrink: 0;
    color: var(--_fg-key);
    white-space: nowrap;
  }

  .oxq-chip:where([data-size='md']) {
    min-block-size: var(--oxq-size-chip-md);
    padding-inline: var(--oxq-space-gap-sm);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  /* neutral non è un canvas colorato: fondo raised e bordo dei controlli. */
  .oxq-chip:where([data-tone='neutral']) {
    --_bg: var(--oxq-neutral-surface-raised);
    --_border: var(--oxq-neutral-line-control);
  }

  /* Filtro: il checkbox resta nel flusso di focus e degli screen reader, ma non si vede. */
  .oxq-chip > input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    pointer-events: none;
  }

  .oxq-chip:where(:has(> input)) {
    cursor: pointer;

    /* Il check appare solo da selezionato. */
    & > .oxq-icon {
      display: none;
    }
  }

  /* Area sensibile di almeno size/control/tap-min, anche se il chip resta piccolo. */
  .oxq-chip:where(:has(> input))::after,
  .oxq-chip > button::after {
    content: '';
    position: absolute;
    inset: 50% auto auto 50%;
    translate: -50% -50%;
    inline-size: max(100%, var(--oxq-size-control-tap-min));
    block-size: max(100%, var(--oxq-size-control-tap-min));
  }

  /* Rimovibile: il close è un button, l'anello di focus è del chip. */
  .oxq-chip > button {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--_fg-icon);
    outline: none;
  }

  .oxq-chip:where(:has(> input:focus-visible, > button:focus-visible)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);
  }

  /* Selezionato: la surface/solid del tone, testo e icone on-ink, e il check. */
  .oxq-chip:where(:has(> input:checked)) {
    --_bg: var(--oxq-tone-surface-solid);
    --_border: var(--oxq-tone-surface-solid);
    --_fg: var(--oxq-tone-text-on-ink);
    --_fg-icon: var(--oxq-tone-icon-on-ink);
    --_fg-key: var(--oxq-tone-text-on-ink);

    & > .oxq-icon {
      display: revert;
    }
  }

  /* Hover: fondo surface/sunken e bordo line/border-strong del tone; in neutral muted e control-hover. */
  @media (hover: hover) {
    .oxq-chip:where(:has(> input:not(:checked, :disabled)):hover, :has(> button:not(:disabled):hover)) {
      --_bg: var(--oxq-tone-surface-sunken);
      --_border: var(--oxq-tone-line-border-strong);
    }

    .oxq-chip:where([data-tone='neutral']):where(
        :has(> input:not(:checked, :disabled)):hover,
        :has(> button:not(:disabled):hover)
      ) {
      --_bg: var(--oxq-neutral-surface-muted);
      --_border: var(--oxq-neutral-line-control-hover);
    }

    .oxq-chip:where(:has(> input:checked:not(:disabled)):hover) {
      --_bg: var(--oxq-tone-surface-solid-hover);
      --_border: var(--oxq-tone-surface-solid-hover);
    }
  }

  /* disabled: non si sceglie e non si toglie. Tutto in muted, senza transizioni. */
  .oxq-chip:where(:has(> input:disabled, > button:disabled)) {
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: var(--oxq-neutral-line-border);
    --_fg: var(--oxq-tone-text-muted);
    --_fg-icon: var(--oxq-tone-icon-muted);
    --_fg-key: var(--oxq-tone-text-muted);

    cursor: not-allowed;
    transition: none;

    & > button {
      cursor: not-allowed;
    }
  }

  /* Più chip in riga, a capo quando la riga finisce. */
  .oxq-chip-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }
}
/* Stat chip (Molecules › Stat chip): il riassunto di un gruppo di righe (stato, quantità, totale) che filtra la
   lista. Per un filtro senza numeri c'è il chip, per un contatore il badge.
   È un chip filtro (.oxq-chip) con un radio al posto del checkbox: fondo, bordo, hover, focus, selected e disabled
   sono quelli del chip, perché il DS li dà uguali. Un solo gruppo selected alla volta: lo fa il radio, senza JS,
   e si invia col form. In più: il dot del tone (data-hide-dot lo spegne), il count in strong text/ink-hover e il
   totale dopo un filo line/hairline (line/border-strong in hover, line/on-ink da selezionato). Più stat chip in riga
   stanno in .oxq-chip-group. */
@layer components {
  .oxq-stat-chip {
    --_dot: var(--oxq-tone-surface-solid);
    --_dot-size: var(--oxq-size-dot-sm);
    --_sep: var(--oxq-tone-line-hairline);
    --_sep-size: var(--oxq-size-separator-sm);

    /* Il dot, almeno 3:1 sul fondo. */
    &::before {
      content: '';
      flex-shrink: 0;
      inline-size: var(--_dot-size);
      block-size: var(--_dot-size);
      border-radius: var(--oxq-radius-pill);
      background-color: var(--_dot);
    }
  }

  .oxq-stat-chip:where([data-hide-dot])::before {
    display: none;
  }

  .oxq-stat-chip-count {
    flex-shrink: 0;
    color: var(--oxq-tone-text-ink-hover);
    font-weight: var(--oxq-label-sm-font-weight-strong);
    white-space: nowrap;
  }

  /* Il totale e, prima, il filo: space/gap/2xs per parte, oltre al gap del chip. */
  .oxq-stat-chip-total {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: calc(2 * var(--oxq-space-gap-2xs));
    color: var(--_fg-key);
    white-space: nowrap;

    &::before {
      content: '';
      inline-size: var(--oxq-stroke-divider);
      block-size: var(--_sep-size);
      margin-inline-start: var(--oxq-space-gap-2xs);
      background-color: var(--_sep);
    }
  }

  .oxq-stat-chip:where([data-size='md']) {
    --_dot-size: var(--oxq-size-dot-md);
    --_sep-size: var(--oxq-size-separator-md);

    & .oxq-stat-chip-count {
      font-weight: var(--oxq-label-md-font-weight-strong);
    }
  }

  /* In warning il pieno del tone è troppo chiaro sul canvas: il dot prende line/border-strong. */
  .oxq-stat-chip:where([data-tone='warning']) {
    --_dot: var(--oxq-warning-line-border-strong);
  }

  /* Hover: il filo prende il bordo marcato del tone; in neutral resta hairline, come in Figma. */
  @media (hover: hover) {
    .oxq-stat-chip:where(:not([data-tone='neutral'])):where(:has(> input:not(:checked, :disabled)):hover) {
      --_sep: var(--oxq-tone-line-border-strong);
    }
  }

  .oxq-stat-chip:where(:has(> input:checked)) {
    --_dot: var(--oxq-tone-text-on-ink);
    --_sep: var(--oxq-tone-line-on-ink);

    & .oxq-stat-chip-count {
      color: inherit;
    }
  }

  .oxq-stat-chip:where(:has(> input:disabled)) {
    --_dot: var(--oxq-tone-text-muted);
    --_sep: var(--oxq-tone-line-hairline);

    & .oxq-stat-chip-count {
      color: inherit;
    }
  }
}
/* Date picker (Molecules › Date picker): il calendario di un mese per scegliere una data o un intervallo. Sta in un
   popover sotto un input-field o da solo in un pannello. Per scrivere la data a mano c'è l'input-field type=date.
   Il giorno (date-picker-day) è una cella della griglia con un cerchio: data-selection single, range-start,
   range-middle o range-end. La band del range è brand/surface/soft a tutta cella e continua a capo della settimana;
   cerchio e focus restano neutral. Oggi (aria-current=date) ha un anello da 1 px, anche da disabled.
   La cella segue size/control/*: sm 32, md 40, e in Mobile sm sale a 40.
   Frecce, PagSu e PagGiù, Home e Fine, il cambio di mese e la scelta li fanno OxqDatePicker e, in Django, oxq.js. */
@layer components {
  .oxq-date-picker {
    --_cell: var(--oxq-size-control-sm);
    --_band: var(--oxq-brand-surface-soft);

    box-sizing: border-box;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
    /* Il bordo sta dentro il padding, come lo stroke inside di Figma che non entra nel layout. */
    padding: calc(var(--oxq-space-gap-sm) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-3);
    color: var(--oxq-neutral-text-ink);
  }

  /* display solo da aperto: chiuso il popover resta display: none, come lo vuole il browser. */
  .oxq-date-picker:where(:not([popover]), :popover-open) {
    display: inline-flex;
  }

  .oxq-date-picker:where([data-size='md']) {
    --_cell: var(--oxq-size-control-md);
  }

  /* Nel date field è un popover: compare in dissolvenza e sparisce allo stesso modo, come il menu. */
  .oxq-date-picker:where([popover]) {
    transition-behavior: allow-discrete;
    transition-property: opacity, display, overlay;
    transition-duration: var(--oxq-duration-open);
    transition-timing-function: var(--oxq-easing-transition);

    @starting-style {
      opacity: 0;
    }
  }

  .oxq-date-picker:where([popover]:not(:popover-open)) {
    opacity: 0;
  }

  /* Sotto il campo, allineato a sinistra, a space/gap/2xs; sopra se sotto non c'è spazio. L'ancora è il date field
     (anchor-name e position-anchor col suo id, nello style). Dove l'anchor positioning non c'è, il browser lo
     mette al centro. */
  @supports (position-area: block-end) {
    .oxq-date-picker:where([popover]) {
      inset: auto;
      margin: var(--oxq-space-gap-2xs) 0 0;
      position-area: block-end span-inline-end;
      position-try-fallbacks:
        flip-block,
        flip-inline,
        flip-block flip-inline;
    }
  }

  /* Le frecce ai lati, il titolo in mezzo. */
  .oxq-date-picker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-date-picker-title {
    font: var(--oxq-font-label-md);
    font-weight: var(--oxq-label-md-font-weight-strong);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-date-picker:where([data-size='md']) .oxq-date-picker-title {
    font: var(--oxq-font-label-lg);
    font-weight: var(--oxq-label-lg-font-weight-strong);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  /* Le celle si toccano: la band del range non ha spazi. */
  .oxq-date-picker-grid {
    border-collapse: collapse;
    border-spacing: 0;

    & th,
    & td {
      inline-size: var(--_cell);
      padding: 0;
      text-align: center;
    }

    /* Le iniziali dei giorni, e sotto lo stesso spazio che separa le altre parti. */
    & th {
      padding-block: var(--oxq-space-gap-2xs) calc(var(--oxq-space-gap-2xs) + var(--oxq-space-gap-xs));
      color: var(--oxq-neutral-text-secondary);
      font: var(--oxq-font-label-sm);
      letter-spacing: var(--oxq-label-sm-letter-spacing);
    }

    & td {
      block-size: var(--_cell);
      outline: none;
    }

    & td[data-date] {
      cursor: pointer;
    }
  }

  .oxq-date-picker-day {
    --_bg: transparent;
    --_fg: var(--oxq-neutral-text-ink);
    --_ring: transparent;

    box-sizing: border-box;
    display: grid;
    place-items: center;
    inline-size: var(--_cell);
    block-size: var(--_cell);
    border: var(--oxq-stroke-control) solid var(--_ring);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    transition-property: background-color, border-color, color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  .oxq-date-picker:where([data-size='md']) .oxq-date-picker-day {
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  /* La band: a tutta cella in mezzo, la metà verso l'interno all'inizio e alla fine. */
  .oxq-date-picker-grid td:where([data-selection='range-middle']) {
    background-color: var(--_band);
  }

  .oxq-date-picker-grid td:where([data-selection='range-start']) {
    background-image: linear-gradient(to right, transparent 50%, var(--_band) 50%);
  }

  .oxq-date-picker-grid td:where([data-selection='range-end']) {
    background-image: linear-gradient(to left, transparent 50%, var(--_band) 50%);
  }

  .oxq-date-picker-grid td:where([aria-current='date']) > .oxq-date-picker-day {
    --_ring: var(--oxq-neutral-line-border-strong);
  }

  /* Il cerchio pieno: la data scelta, l'inizio e la fine del range. */
  .oxq-date-picker-grid
    td:where([data-selection='single'], [data-selection='range-start'], [data-selection='range-end'])
    > .oxq-date-picker-day {
    --_bg: var(--oxq-neutral-surface-solid);
    --_fg: var(--oxq-neutral-text-on-ink);
    --_ring: transparent;
  }

  @media (hover: hover) {
    .oxq-date-picker-grid td:where([data-date]:not([aria-disabled='true'])):hover > .oxq-date-picker-day {
      --_bg: var(--oxq-system-state-hover);
    }

    .oxq-date-picker-grid
      td:where([data-selection='single'], [data-selection='range-start'], [data-selection='range-end']):where(
        :not([aria-disabled='true'])
      ):hover
      > .oxq-date-picker-day {
      --_bg: var(--oxq-neutral-surface-solid-hover);
    }
  }

  /* Anello di focus da 2 px dentro il cerchio. */
  .oxq-date-picker-grid td:focus-visible > .oxq-date-picker-day {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }

  /* Fuori da min e max: muted, senza hover, e non si sceglie. */
  .oxq-date-picker-grid td:where([aria-disabled='true']) {
    cursor: not-allowed;

    & > .oxq-date-picker-day {
      --_fg: var(--oxq-neutral-text-muted);

      transition: none;
    }
  }

  .oxq-date-picker-grid
    td:where([aria-disabled='true'][aria-current='date']):where(
      :not([data-selection='single'], [data-selection='range-start'], [data-selection='range-end'])
    )
    > .oxq-date-picker-day {
    --_ring: var(--oxq-neutral-line-border);
  }

  .oxq-date-picker-grid
    td:where([aria-disabled='true'][aria-selected='true']):where(:not([data-selection='range-middle']))
    > .oxq-date-picker-day {
    --_bg: var(--oxq-neutral-surface-control-disabled);
    --_fg: var(--oxq-neutral-text-muted);
  }

  /* Annulla e Applica, a destra. */
  .oxq-date-picker-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--oxq-space-gap-xs);
    padding-block-start: var(--oxq-space-gap-xs);
  }

  /* Date field: l'input field col calendario, e il date picker in popover. Per un range due campi in riga, con
     space/gap/md. Il campo resta in focus mentre il date picker è aperto. */
  .oxq-date-field {
    display: flex;
    gap: var(--oxq-space-gap-md);

    & > .oxq-input-field {
      flex: 1 1 0;
      min-inline-size: 0;
    }
  }

  .oxq-date-field:where(:has(> .oxq-date-picker:popover-open)) .oxq-input-field-box {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);
  }
}
/* Kbd (Atoms › Kbd) e Kbd shortcut (Molecules › Kbd shortcut): il tasto, e i tasti di una scorciatoia. Non si
   clicca: per un'azione c'è il button.
   Prop Figma → attributi: data-size, data-inverse (tone inverse), data-line (tone line), data-pressed (state pressed).
   - kbd: un <kbd> su surface/control, col bordo line/border-strong
   - kbd-shortcut: un <kbd> con da uno a tre kbd, premuti insieme, con la stessa size, tone e state
   - kbd-shortcut-row: descrizione, linea guida e kbd-shortcut, per elenchi e pannelli di scorciatoie
   Colori solo neutral: il tone di Figma è default, inverse o line, non una famiglia. inverse va solo su un fondo
   neutral/surface/solid, come dentro un button pieno; line è il tasto leggero, senza fondo, col bordo line/border
   e il testo text/secondary. */
@layer components {
  .oxq-kbd {
    --_size: var(--oxq-size-kbd-sm);
    --_bg: var(--oxq-neutral-surface-control);
    --_border: var(--oxq-neutral-line-border-strong);
    --_fg: var(--oxq-neutral-text-ink);

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    min-inline-size: var(--_size);
    /* Altezza fissa: in una riga flex più alta il tasto non si allunga. */
    block-size: var(--_size);
    /* Il bordo sta dentro le misure e si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding-inline: var(--oxq-space-gap-2xs);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-selection);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;
  }

  .oxq-kbd:where([data-size='md']) {
    --_size: var(--oxq-size-kbd-md);

    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-kbd:where([data-size='lg']) {
    --_size: var(--oxq-size-kbd-lg);

    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  .oxq-kbd:where([data-inverse]) {
    --_bg: transparent;
    --_border: var(--oxq-neutral-line-on-ink);
    --_fg: var(--oxq-neutral-text-on-ink);
  }

  .oxq-kbd:where([data-line]) {
    --_bg: transparent;
    --_border: var(--oxq-neutral-line-border);
    --_fg: var(--oxq-neutral-text-secondary);
  }

  /* Premuto, solo nelle guide interattive: il tasto si scurisce con system/state/pressed. */
  .oxq-kbd:where([data-pressed]) {
    background-image: linear-gradient(var(--oxq-system-state-pressed), var(--oxq-system-state-pressed));
  }

  /* line premuto: il testo torna ink, come in Figma. */
  .oxq-kbd:where([data-line][data-pressed]) {
    --_fg: var(--oxq-neutral-text-ink);
  }

  .oxq-kbd:where([data-inverse][data-pressed]) {
    --_bg: var(--oxq-neutral-surface-solid-pressed);

    background-image: none;
  }

  /* Il nome del tasto per chi usa un lettore di schermo, quando la faccia è un simbolo (⌘, ⇧). Ritagliato
     del tutto da clip-path; la misura minima serve solo perché alcuni lettori saltano gli elementi a misura zero. */
  .oxq-kbd-name {
    position: absolute;
    inline-size: 1em;
    block-size: 1em;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .oxq-kbd-shortcut {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
  }

  /* La linea guida va dalla descrizione ai tasti. */
  .oxq-kbd-shortcut-row {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-kbd-shortcut-row-label {
    display: flex;
    flex: 1;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-inline-size: 0;

    &::after {
      content: '';
      flex: 1;
      border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    }
  }

  .oxq-kbd-shortcut-row:where([data-size='md']) {
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }
}
/* Tooltip e hint-button (Atoms › Tooltip): un balloon con la coda che spiega un comando o un dato.
   Spiega e basta: niente link né pulsanti, per quelli c'è il popover. Prop Figma → attributi: data-placement
   sul balloon (top | bottom | left | right), data-size sull'hint-button.
   Il balloon sta dentro .oxq-tooltip-anchor insieme al trigger, che lo cita con aria-describedby. Compare su hover e
   su focus da tastiera; Esc lo chiude (data-dismissed, lo mettono il componente Vue o oxq.js) finché puntatore e
   focus non lasciano il trigger. Il placement lo sceglie chi lo usa: non si sposta da solo vicino ai bordi.
   Colori solo neutral, nessun tone: chiaro in light, scuro in dark.
   Nella side-nav collapsed la label della voce è un balloon right (side-nav.css). */
@layer components {
  .oxq-tooltip-anchor {
    position: relative;
    display: inline-flex;
    vertical-align: middle;
  }

  .oxq-tooltip,
  :where(.oxq-side-nav[data-collapsed]) .oxq-nav-item-label {
    --_stroke: var(--oxq-stroke-control);
    --_tail-w: var(--oxq-size-tooltip-tail-width);
    --_tail-h: var(--oxq-size-tooltip-tail-height);
    /* La punta della coda sta a space/gap/2xs dal trigger. */
    --_offset: calc(var(--oxq-space-gap-2xs) + var(--_tail-h) - var(--_stroke));

    position: absolute;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    inline-size: max-content;
    max-inline-size: var(--oxq-size-tooltip-max);
    /* Il bordo sta dentro il padding, come lo stroke del balloon in Figma. */
    padding: calc(var(--oxq-space-gap-xs) - var(--_stroke)) calc(var(--oxq-space-gap-sm) - var(--_stroke));
    border: var(--_stroke) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-item);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-3);
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
    text-align: start;
    white-space: normal;
    pointer-events: auto;
    visibility: hidden;
    opacity: 0;
    /* In uscita visibility aspetta la dissolvenza: il puntatore che va dal trigger al balloon lo ritrova. */
    transition:
      opacity var(--oxq-duration-open) var(--oxq-easing-transition),
      visibility 0s linear var(--oxq-duration-open);

    /* La coda: il bordo (::before) e sotto il fondo (::after), più piccolo dello spessore del bordo. Copre il
       bordo del balloon dove si attacca. */
    &::before,
    &::after {
      content: '';
      position: absolute;
    }

    &::before {
      background-color: var(--oxq-neutral-line-popover);
    }

    &::after {
      background-color: var(--oxq-neutral-surface-raised);
    }
  }

  .oxq-tooltip-anchor:where(:hover, :has(:focus-visible)):where(:not([data-dismissed])) > .oxq-tooltip,
  :where(.oxq-side-nav[data-collapsed])
    .oxq-nav-item:where(:hover, :focus-visible):where(:not([data-dismissed]))
    > .oxq-nav-item-label {
    visibility: visible;
    opacity: 1;
    transition-delay: 0s;
  }

  /* top, il default: balloon sopra, coda in basso al centro. */
  .oxq-tooltip:where([data-placement='top'], [data-placement='bottom']) {
    left: 50%;
    translate: -50% 0;

    &::before,
    &::after {
      left: 50%;
      translate: -50% 0;
    }

    &::before {
      inline-size: var(--_tail-w);
      block-size: var(--_tail-h);
    }

    &::after {
      inline-size: calc(var(--_tail-w) - 2.5 * var(--_stroke));
      block-size: calc(var(--_tail-h) - 1.5 * var(--_stroke));
    }
  }

  .oxq-tooltip:where([data-placement='top']) {
    bottom: calc(100% + var(--_offset));

    &::before,
    &::after {
      top: 100%;
      clip-path: polygon(0 0, 100% 0, 50% 100%);
    }
  }

  .oxq-tooltip:where([data-placement='bottom']) {
    top: calc(100% + var(--_offset));

    &::before,
    &::after {
      bottom: 100%;
      clip-path: polygon(50% 0, 100% 100%, 0 100%);
    }
  }

  .oxq-tooltip:where([data-placement='left'], [data-placement='right']),
  :where(.oxq-side-nav[data-collapsed]) .oxq-nav-item-label {
    top: 50%;
    translate: 0 -50%;

    &::before,
    &::after {
      top: 50%;
      translate: 0 -50%;
    }

    &::before {
      inline-size: var(--_tail-h);
      block-size: var(--_tail-w);
    }

    &::after {
      inline-size: calc(var(--_tail-h) - 1.5 * var(--_stroke));
      block-size: calc(var(--_tail-w) - 2.5 * var(--_stroke));
    }
  }

  .oxq-tooltip:where([data-placement='left']) {
    right: calc(100% + var(--_offset));

    &::before,
    &::after {
      left: 100%;
      clip-path: polygon(0 0, 100% 50%, 0 100%);
    }
  }

  .oxq-tooltip:where([data-placement='right']),
  :where(.oxq-side-nav[data-collapsed]) .oxq-nav-item-label {
    left: calc(100% + var(--_offset));

    &::before,
    &::after {
      right: 100%;
      clip-path: polygon(100% 0, 100% 100%, 0 50%);
    }
  }

  /* Nel testo corrente: il termine da spiegare, sottolineato a puntini. */
  .oxq-tooltip-term {
    text-decoration-line: underline;
    text-decoration-style: dotted;
    text-decoration-thickness: var(--oxq-stroke-underline);
    text-underline-offset: var(--oxq-offset-underline);
    cursor: help;
  }

  /* hint-button: il tasto «i» accanto a una label o a un valore. */
  .oxq-hint-button {
    --_icon-size: var(--oxq-size-icon-sm);

    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    inline-size: var(--_icon-size);
    block-size: var(--_icon-size);
    padding: 0;
    border: 0;
    border-radius: var(--oxq-radius-pill);
    background-color: transparent;
    color: var(--oxq-neutral-icon-secondary);
    cursor: help;
    transition-property: background-color, color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    /* Area sensibile di almeno size/control/tap-min. */
    &::after {
      content: '';
      position: absolute;
      inset: 50% auto auto 50%;
      translate: -50% -50%;
      inline-size: max(100%, var(--oxq-size-control-tap-min));
      block-size: max(100%, var(--oxq-size-control-tap-min));
    }
  }

  .oxq-hint-button:where([data-size='md']) {
    --_icon-size: var(--oxq-size-icon-md);
  }

  @media (hover: hover) {
    .oxq-hint-button:where(:hover) {
      background-color: var(--oxq-system-state-hover);
      color: var(--oxq-neutral-icon-ink);
    }
  }
}
/* Swatch (Atoms › Swatch): il campione di colore di una legenda o di un elenco di stato. Sempre accanto alla sua
   label, che ne dice il significato: da solo non si legge, e non è interattivo.
   Prop Figma → attributi: data-tone, data-variant (style in Figma: style è un attributo HTML), data-shape, data-size.
   - tone: neutral, info, success, warning e danger quando il colore è uno stato; gli accent (blue, green, yellow,
     violet, magenta) distinguono soltanto le serie. Il brand non è un tone dello swatch.
   - variant: solid è un valore presente, dashed non applicabile o stimato, hollow vuoto o non avviato. Il tratto
     li distingue anche senza colore. */
@layer components {
  .oxq-swatch {
    --_size: var(--oxq-size-swatch-sm);
    --_radius: var(--oxq-radius-swatch);
    --_solid: var(--oxq-tone-surface-solid);
    --_soft: var(--oxq-tone-surface-muted);
    --_line: var(--oxq-tone-line-border-strong);

    box-sizing: border-box;
    display: inline-block;
    flex-shrink: 0;
    inline-size: var(--_size);
    block-size: var(--_size);
    /* Il bordo sta dentro la misura, come lo stroke inside di Figma; in solid è trasparente sul fondo. */
    border: var(--oxq-stroke-control) solid transparent;
    border-radius: var(--_radius);
    background-color: var(--_solid);
  }

  .oxq-swatch:where([data-variant='dashed']) {
    border-style: dashed;
    border-color: var(--_line);
    background-color: var(--_soft);
  }

  .oxq-swatch:where([data-variant='hollow']) {
    border-color: var(--_line);
    background-color: transparent;
  }

  .oxq-swatch:where([data-size='md']) {
    --_size: var(--oxq-size-swatch-md);
    --_radius: var(--oxq-radius-selection);
  }

  .oxq-swatch:where([data-size='lg']) {
    --_size: var(--oxq-size-swatch-lg);
    --_radius: var(--oxq-radius-selection);
  }

  .oxq-swatch:where([data-shape='circle']) {
    --_radius: var(--oxq-radius-pill);
  }

  /* neutral ha un pieno per gli indicatori piccoli, più scuro di neutral/surface/solid. */
  .oxq-swatch:where([data-tone='neutral']) {
    --_solid: var(--oxq-neutral-surface-indicator);
  }

  /* Gli accent: il pieno è anche il bordo, il fondo di dashed è il soft. */
  .oxq-swatch:where([data-tone='blue']) {
    --_solid: var(--oxq-accent-blue-surface-solid);
    --_soft: var(--oxq-accent-blue-surface-soft);
    --_line: var(--oxq-accent-blue-surface-solid);
  }

  .oxq-swatch:where([data-tone='green']) {
    --_solid: var(--oxq-accent-green-surface-solid);
    --_soft: var(--oxq-accent-green-surface-soft);
    --_line: var(--oxq-accent-green-surface-solid);
  }

  .oxq-swatch:where([data-tone='yellow']) {
    --_solid: var(--oxq-accent-yellow-surface-solid);
    --_soft: var(--oxq-accent-yellow-surface-soft);
    --_line: var(--oxq-accent-yellow-surface-solid);
  }

  .oxq-swatch:where([data-tone='violet']) {
    --_solid: var(--oxq-accent-violet-surface-solid);
    --_soft: var(--oxq-accent-violet-surface-soft);
    --_line: var(--oxq-accent-violet-surface-solid);
  }

  .oxq-swatch:where([data-tone='magenta']) {
    --_solid: var(--oxq-accent-magenta-surface-solid);
    --_soft: var(--oxq-accent-magenta-surface-soft);
    --_line: var(--oxq-accent-magenta-surface-solid);
  }
}
/* Thumbnail (Atoms › Thumbnail): l'anteprima di un file o di un'immagine, in rapporto circa 3:4. Il nome del file,
   il peso e l'errore stanno nella riga accanto, a space/gap/md.
   Prop Figma → attributi: data-size, data-state (selected | uploading | error | disabled). content non è un
   attributo: con un'immagine c'è <img class="oxq-thumbnail-image">, altrimenti la label col tipo di file (PDF, XLS).
   Hover e focus solo sul thumbnail che è un link; il focus è quello di base.css.
   Solo neutral e danger: niente tone. */
@layer components {
  .oxq-thumbnail {
    --_w: var(--oxq-size-thumb-width-sm);
    --_h: var(--oxq-size-thumb-height-sm);
    --_stroke: var(--oxq-stroke-control);
    --_bg: var(--oxq-neutral-surface-sunken);
    --_border: var(--oxq-neutral-line-border);
    --_fg: var(--oxq-neutral-text-secondary);
    --_check: var(--oxq-size-thumb-check-sm);
    --_check-icon: var(--oxq-size-icon-xs);
    --_check-inset: var(--oxq-space-inset-thumb-sm);

    position: relative;
    box-sizing: border-box;
    display: inline-flex;
    flex-direction: column;
    flex-shrink: 0;
    align-items: center;
    justify-content: flex-end;
    inline-size: var(--_w);
    block-size: var(--_h);
    /* Il bordo sta dentro le misure e la label sta a space/gap/xs dal bordo, come in Figma. overflow ritaglia
       immagine e velo sul raggio interno. */
    padding: 0 0 var(--oxq-space-gap-xs);
    overflow: hidden;
    border: var(--_stroke) solid var(--_border);
    border-radius: var(--oxq-radius-item);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-code-sm);
    letter-spacing: var(--oxq-code-sm-letter-spacing);
    text-decoration: none;
    transition-property: border-color, box-shadow;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  .oxq-thumbnail:where([data-size='md']) {
    --_w: var(--oxq-size-thumb-width-md);
    --_h: var(--oxq-size-thumb-height-md);
    --_check: var(--oxq-size-thumb-check-md);
    --_check-inset: var(--oxq-space-inset-thumb-md);
  }

  .oxq-thumbnail:where([data-size='lg']) {
    --_w: var(--oxq-size-thumb-width-lg);
    --_h: var(--oxq-size-thumb-height-lg);
    --_check: var(--oxq-size-thumb-check-lg);
    --_check-icon: var(--oxq-size-icon-sm);
    --_check-inset: var(--oxq-space-inset-thumb-lg);
  }

  /* L'immagine riempie l'interno del bordo; neutral/surface/muted si vede finché carica. */
  .oxq-thumbnail-image {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    background-color: var(--oxq-neutral-surface-muted);
  }

  /* Prima degli stati: selected ed error tengono il loro bordo, l'ombra si aggiunge. */
  @media (hover: hover) {
    .oxq-thumbnail:where(:any-link:hover) {
      --_border: var(--oxq-neutral-line-control-hover);

      box-shadow: var(--oxq-elevation-1);
    }
  }

  /* Bordo più spesso e spunta: la selezione si legge anche senza colore. */
  .oxq-thumbnail:where([data-state='selected']) {
    --_stroke: var(--oxq-stroke-selected);
    --_border: var(--oxq-neutral-surface-solid);
  }

  .oxq-thumbnail-check {
    position: absolute;
    /* Dal bordo interno, come il check-slot di Figma dentro lo stroke. */
    inset-block-start: var(--_check-inset);
    inset-inline-end: var(--_check-inset);
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--_check);
    block-size: var(--_check);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-solid);
    color: var(--oxq-neutral-icon-on-ink);

    & > .oxq-icon {
      --_icon-size: var(--_check-icon);
    }
  }

  /* Contenuto velato e barra sempre al 60 %: dice che sta caricando, non quanto. Per l'avanzamento reale
     accanto va una progress bar. La label resta sotto il velo e sale per lasciare posto alla barra. */
  .oxq-thumbnail:where([data-state='uploading']) {
    padding-block-end: var(--oxq-space-gap-md);

    &::before,
    &::after {
      content: '';
      position: absolute;
    }

    &::before {
      inset: 0;
      background-color: color-mix(
        in srgb,
        var(--oxq-neutral-surface-raised) calc(var(--oxq-opacity-thumbnail-veil) * 100%),
        transparent
      );
    }

    &::after {
      inset-inline: calc(var(--oxq-space-gap-xs) - var(--_stroke));
      inset-block-end: calc(var(--oxq-space-gap-xs) - var(--_stroke));
      block-size: var(--oxq-size-progress-sm);
      border-radius: var(--oxq-radius-pill);
      background: linear-gradient(
        to right,
        var(--oxq-neutral-surface-solid) 60%,
        var(--oxq-neutral-surface-track-on-media) 0
      );
    }
  }

  .oxq-thumbnail:where([data-state='error']) {
    --_bg: var(--oxq-danger-surface-canvas);
    --_border: var(--oxq-danger-line-border-strong);
    --_fg: var(--oxq-danger-text-secondary);
  }

  .oxq-thumbnail:where([data-state='disabled']) {
    --_bg: var(--oxq-neutral-surface-control-disabled);
    --_fg: var(--oxq-neutral-text-muted);

    & > .oxq-thumbnail-image {
      opacity: var(--oxq-opacity-thumbnail-disabled);
    }
  }
}
/* Sparkline (Atoms › Sparkline): l'andamento in miniatura, senza assi né tooltip. È decorativo: sta accanto al
   numero, alla variazione o alla label che lo spiega, a space/gap/md.
   Prop Figma → attributi: data-type (bars | line | area), data-tone, data-size. show-limit e show-peak sono
   elementi: .oxq-sparkline-limit (il tetto tratteggiato, neutral) e data-peak o .oxq-sparkline-peak.
   I valori arrivano come --oxq-value, frazione del massimo da 0 a 1; il punto del picco ha anche --oxq-x.
   - bars: barre affiancate a space/inset/track, dal fondo, in surface/muted del tone; il picco è pieno
   - line e area: un SVG in coordinate normalizzate (x = indice, y = 1 - valore) stirato sulla misura, con il
     tratto che non scala. Il grafico sta a mezzo punto dai bordi, così il punto del picco non si taglia. */
@layer components {
  .oxq-sparkline {
    --_w: var(--oxq-size-sparkline-width-sm);
    --_h: var(--oxq-size-sparkline-height-sm);
    --_color: var(--oxq-tone-surface-solid);
    --_bar: var(--oxq-tone-surface-muted);
    --_area: var(--oxq-tone-surface-control);
    /* Senza punto del picco, il grafico arriva ai bordi: zero come lunghezza, per i calc. */
    --_pad: calc(0 * var(--oxq-size-dot-sm));

    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: flex-end;
    gap: var(--oxq-space-inset-track);
    inline-size: var(--_w);
    block-size: var(--_h);
    vertical-align: middle;
  }

  .oxq-sparkline:where([data-size='md']) {
    --_w: var(--oxq-size-sparkline-width-md);
    --_h: var(--oxq-size-sparkline-height-md);
  }

  .oxq-sparkline:where([data-size='lg']) {
    --_w: var(--oxq-size-sparkline-width-lg);
    --_h: var(--oxq-size-sparkline-height-lg);
  }

  /* neutral è una serie senza giudizio: il grigio delle icone, non il pieno nero. */
  .oxq-sparkline:where([data-tone='neutral']) {
    --_color: var(--oxq-neutral-icon-secondary);
  }

  .oxq-sparkline:where([data-type='line'], [data-type='area']) {
    --_pad: calc(var(--oxq-size-dot-sm) / 2);
  }

  .oxq-sparkline-bar {
    flex: 1;
    block-size: calc(var(--oxq-value) * 100%);
    background-color: var(--_bar);
  }

  .oxq-sparkline-bar:where([data-peak]) {
    background-color: var(--_color);
  }

  .oxq-sparkline-plot {
    position: absolute;
    inset-block-start: var(--_pad);
    inset-inline-start: 0;
    inline-size: 100%;
    block-size: calc(100% - 2 * var(--_pad));
    overflow: visible;

    & polyline {
      fill: none;
      stroke: var(--_color);
      stroke-width: var(--oxq-stroke-sparkline);
      stroke-linecap: round;
      stroke-linejoin: round;
      vector-effect: non-scaling-stroke;
    }

    & polygon {
      fill: var(--_area);
    }
  }

  /* Picco e tetto: --oxq-value sull'altezza del grafico, dentro --_pad. */
  .oxq-sparkline-peak,
  .oxq-sparkline-limit {
    position: absolute;
    inset-block-end: calc(var(--_pad) + var(--oxq-value) * (100% - 2 * var(--_pad)));
  }

  .oxq-sparkline-peak {
    inset-inline-start: calc(var(--oxq-x) * 100%);
    inline-size: var(--oxq-size-dot-sm);
    block-size: var(--oxq-size-dot-sm);
    translate: -50% 50%;
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_color);
  }

  /* Il tetto: un filo tratteggiato centrato sul valore, sempre neutral. */
  .oxq-sparkline-limit {
    inset-inline: 0;
    block-size: var(--oxq-stroke-divider);
    translate: 0 50%;
    background-image: repeating-linear-gradient(
      to right,
      var(--oxq-neutral-line-border-strong) 0 var(--oxq-size-sparkline-dash),
      transparent 0 calc(2 * var(--oxq-size-sparkline-dash))
    );
  }
}
/* FAB (Atoms › FAB): l'azione principale della schermata, fluttuante. Al massimo uno per schermata, in basso a
   destra a space/inset/container dai bordi (lo posiziona chi lo usa). Mai disabled né loading: se l'azione non è
   possibile, il FAB non si mostra.
   Prop Figma → attributi: data-variant (primary | soft | elevated), data-tone (neutral di default, brand solo
   primary, mai un accent), data-shape (rounded | circle), data-size, data-extended (type extended, con la label
   dopo l'icona).
   Hover e pressed come il button: primary cambia fondo, soft ed elevated aggiungono l'overlay system/state/*
   (--_overlay, registrato in button.css). */
@layer components {
  .oxq-fab {
    --_side: var(--oxq-size-fab-sm);
    --_icon-size: var(--oxq-size-fab-icon-sm);
    --_radius: var(--oxq-radius-surface);
    --_pad: var(--oxq-space-inset-control-x);
    --_bg: var(--oxq-tone-surface-solid);
    --_fg: var(--oxq-tone-text-on-ink);
    --_fg-icon: var(--oxq-tone-icon-on-ink);
    --_shadow: var(--oxq-elevation-3);

    box-sizing: border-box;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--oxq-space-gap-xs);
    inline-size: var(--_side);
    block-size: var(--_side);
    padding: 0;
    border: 0;
    border-radius: var(--_radius);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    box-shadow: var(--_shadow);
    color: var(--_fg);
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
    white-space: nowrap;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, box-shadow, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--_fg-icon);
    }

    /* L'ombra copre i 2 px dell'anello di base.css: qui sta a 4 px dal bordo. */
    &:focus-visible {
      outline-offset: var(--oxq-offset-focus-floating);
    }
  }

  .oxq-fab:where([data-size='md']) {
    --_side: var(--oxq-size-fab-md);
    --_icon-size: var(--oxq-size-fab-icon-md);
    --_radius: var(--oxq-radius-container);
    --_pad: var(--oxq-space-inset-container);

    gap: var(--oxq-space-gap-sm);
    font: var(--oxq-font-title-md);
    letter-spacing: var(--oxq-title-md-letter-spacing);
  }

  .oxq-fab:where([data-size='lg']) {
    --_side: var(--oxq-size-fab-lg);
    --_icon-size: var(--oxq-size-fab-icon-lg);
    --_radius: var(--oxq-radius-overlay);
    --_pad: var(--oxq-space-inset-overlay);

    gap: var(--oxq-space-gap-md);
    font: var(--oxq-font-title-lg);
    letter-spacing: var(--oxq-title-lg-letter-spacing);
  }

  .oxq-fab:where([data-shape='circle']) {
    --_radius: var(--oxq-radius-pill);
  }

  /* Extended: alto come il FAB, largo quanto icona e label. */
  .oxq-fab:where([data-extended]) {
    inline-size: auto;
    padding-inline: var(--_pad);
  }

  /* soft ed elevated: fondo chiaro, icona e label in ink. soft è tone/surface/control, neutral surface/subtle;
     elevated tone/surface/raised. Un menu di FAB dà il tone alle voci (fab-menu.css). */
  .oxq-fab:where([data-variant='soft']) {
    --_bg: var(--oxq-tone-surface-control);
  }

  .oxq-fab:where([data-variant='soft'][data-tone='neutral']) {
    --_bg: var(--oxq-neutral-surface-subtle);
  }

  .oxq-fab:where([data-variant='elevated']) {
    --_bg: var(--oxq-tone-surface-raised);
  }

  .oxq-fab:where([data-variant='soft'], [data-variant='elevated']) {
    --_fg: var(--oxq-tone-text-ink);
    --_fg-icon: var(--oxq-tone-icon-ink);
  }

  /* Hover: elevation/4. Primary ha i suoi solid-hover e solid-pressed; soft ed elevated l'overlay. */
  @media (hover: hover) {
    .oxq-fab:where(:hover) {
      --_shadow: var(--oxq-elevation-4);
      --_overlay: var(--oxq-system-state-hover);
    }

    .oxq-fab:where([data-variant='primary']:hover) {
      --_bg: var(--oxq-tone-surface-solid-hover);
      --_overlay: transparent;
    }
  }

  .oxq-fab:where(:active) {
    --_shadow: var(--oxq-elevation-3);
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-fab:where([data-variant='primary']:active) {
    --_bg: var(--oxq-tone-surface-solid-pressed);
    --_overlay: transparent;
  }
}
/* FAB menu (Molecules › FAB menu): un FAB che apre da 2 a 6 azioni correlate, in colonna sopra il toggle. Lo
   posiziona chi lo usa, come il FAB: in basso, a space/inset/container dai bordi.
   Prop Figma → attributi: data-align sul menu (end se il FAB sta a destra, start a sinistra), data-tone sul menu,
   aria-expanded sul toggle (open). Toggle e voci sono .oxq-fab (fab.css) senza data-tone: il tone è quello del menu,
   e con brand le voci restano neutral.
   - toggle: fab sm circle primary; chiuso mostra plus, aperto close
   - fab-menu-item: fab sm circle extended, elevated (default) o soft, mai solid: il pieno spetta al toggle. Ha
     elevation/2 e in hover elevation/3, un gradino sotto il FAB.
   Il toggle apre e chiude; Esc, un clic fuori o una voce scelta chiudono. All'apertura il focus va alla prima
   voce, Esc lo riporta al toggle. Lo fanno OxqFabMenu.vue e, fuori da Vue, oxq.js. */
@layer components {
  .oxq-fab-menu {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-fab-menu:where([data-align='start']) {
    align-items: flex-start;
  }

  .oxq-fab-menu-items {
    display: flex;
    flex-direction: column;
    align-items: inherit;
    gap: var(--oxq-space-gap-2xs);
    margin: 0;
    padding: 0;
    list-style: none;
    transition-property: opacity, translate;
    transition-duration: var(--oxq-duration-open);
    transition-timing-function: var(--oxq-easing-transition);

    /* All'apertura le voci salgono e compaiono; dove @starting-style non c'è, compaiono e basta. */
    @starting-style {
      opacity: 0;
      translate: 0 var(--oxq-space-gap-xs);
    }
  }

  .oxq-fab-menu-item {
    --_shadow: var(--oxq-elevation-2);
  }

  .oxq-fab-menu:where([data-tone='brand']) .oxq-fab-menu-item {
    --_bg: var(--oxq-neutral-surface-raised);
    --_fg: var(--oxq-neutral-text-ink);
    --_fg-icon: var(--oxq-neutral-icon-ink);
  }

  .oxq-fab-menu:where([data-tone='neutral'], [data-tone='brand']) .oxq-fab-menu-item:where([data-variant='soft']) {
    --_bg: var(--oxq-neutral-surface-subtle);
  }

  @media (hover: hover) {
    .oxq-fab-menu-item:where(:hover) {
      --_shadow: var(--oxq-elevation-3);
    }
  }

  .oxq-fab-menu-item:where(:active) {
    --_shadow: var(--oxq-elevation-2);
  }

  .oxq-fab-menu-toggle:where([aria-expanded='true']) > .oxq-icon:first-child,
  .oxq-fab-menu-toggle:where(:not([aria-expanded='true'])) > .oxq-icon:last-child {
    display: none;
  }
}
/* Tabs (Atoms › Tabs): la tab list sceglie fra sezioni diverse, sempre con un tab selected. Se cambia solo la
   vista dello stesso contenuto c'è il segmented control; per un valore da salvare, il segmented button.
   Prop Figma → attributi: data-variant e data-size sulla tab list (uguali per tutti i tab), aria-selected sul
   tab (selected), disabled. Hover, pressed e focus li decide il browser; il focus sta dentro il tab.
   I moduli dell'app-header sono link con l'aspetto dei tab solid: aria-current="page" sul modulo corrente.
   - line: sotto il titolo della page, con la linea della lista su tutta la larghezza; il selected ha l'indicatore
   - soft: sottosezioni, il selected su neutral/surface/control
   - solid: moduli di una barra, il selected su neutral/surface/solid
   Troppi tab scorrono in orizzontale, mai su due righe. Colori solo neutral. */
@layer components {
  .oxq-tab-list {
    --_tab-py: var(--oxq-space-gap-2xs);
    --_tab-px: var(--oxq-space-gap-sm);
    --_tab-font: var(--oxq-font-label-md);
    --_tab-ls: var(--oxq-label-md-letter-spacing);
    --_count-font: var(--oxq-font-label-sm);
    --_count-ls: var(--oxq-label-sm-letter-spacing);
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    overflow-x: auto;
  }

  .oxq-tab-list:where([data-size='md']) {
    --_tab-py: var(--oxq-space-gap-xs);
    --_tab-px: var(--oxq-space-inset-control-x);
  }

  .oxq-tab-list:where([data-size='lg']) {
    --_tab-py: var(--oxq-space-gap-sm);
    --_tab-px: var(--oxq-space-inset-control-x);
    --_tab-font: var(--oxq-font-label-lg);
    --_tab-ls: var(--oxq-label-lg-letter-spacing);
    --_count-font: var(--oxq-font-label-md);
    --_count-ls: var(--oxq-label-md-letter-spacing);
    --_icon-size: var(--oxq-size-icon-md);
  }

  .oxq-tab-list:where([data-variant='line']) {
    border-block-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-border);
  }

  .oxq-tab-list:where([data-variant='soft'], [data-variant='solid']) {
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-tab {
    --_bg: transparent;
    --_fg: var(--oxq-neutral-text-secondary);
    --_count-fg: var(--oxq-neutral-text-ink);

    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--oxq-space-gap-2xs);
    padding: var(--_tab-py) var(--_tab-px);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    font: var(--_tab-font);
    letter-spacing: var(--_tab-ls);
    text-decoration: none;
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    /* L'anello sta dentro il tab: fuori lo taglierebbe lo scroll della lista. */
    &:focus-visible {
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }
  }

  :where(.oxq-tab-list[data-variant='soft'], .oxq-tab-list[data-variant='solid']) > .oxq-tab {
    border-radius: var(--oxq-radius-pill);
  }

  .oxq-tab-count {
    color: var(--_count-fg);
    font: var(--_count-font);
    letter-spacing: var(--_count-ls);
  }

  /* line: il numero in una pillola neutra. */
  :where(.oxq-tab-list[data-variant='line']) .oxq-tab-count {
    padding-inline: var(--oxq-space-gap-2xs);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-control);
  }

  /* Hover e pressed: testo in ink e overlay system/state/*; il solid selected cambia fondo. */
  @media (hover: hover) {
    .oxq-tab:where(:hover:not(:disabled)) {
      --_fg: var(--oxq-neutral-text-ink);
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-tab:where(:active:not(:disabled)) {
    --_fg: var(--oxq-neutral-text-ink);
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-tab:where([aria-selected='true'], [aria-current='page']) {
    --_fg: var(--oxq-neutral-text-ink);
  }

  /* line selected: l'indicatore sul fondo del tab, sopra la linea della lista. */
  :where(.oxq-tab-list[data-variant='line']) > .oxq-tab:is([aria-selected='true'], [aria-current='page'])::after {
    content: '';
    position: absolute;
    inset: auto 0 0;
    block-size: var(--oxq-stroke-indicator);
    background-color: var(--_indicator, var(--oxq-neutral-surface-solid));
  }

  :where(.oxq-tab-list[data-variant='soft']) > .oxq-tab:is([aria-selected='true'], [aria-current='page']) {
    --_bg: var(--oxq-neutral-surface-control);
  }

  :where(.oxq-tab-list[data-variant='solid']) > .oxq-tab:is([aria-selected='true'], [aria-current='page']) {
    --_bg: var(--oxq-neutral-surface-solid);
    --_fg: var(--oxq-neutral-text-on-ink);
    --_count-fg: var(--oxq-neutral-text-on-ink);
    --_overlay: transparent;
  }

  @media (hover: hover) {
    :where(.oxq-tab-list[data-variant='solid'])
      > .oxq-tab:is([aria-selected='true'], [aria-current='page']):where(:hover:not(:disabled)) {
      --_bg: var(--oxq-neutral-surface-solid-hover);
      --_fg: var(--oxq-neutral-text-on-ink);
      --_overlay: transparent;
    }
  }

  :where(.oxq-tab-list[data-variant='solid'])
    > .oxq-tab:is([aria-selected='true'], [aria-current='page']):where(:active:not(:disabled)) {
    --_bg: var(--oxq-neutral-surface-solid-pressed);
    --_fg: var(--oxq-neutral-text-on-ink);
    --_overlay: transparent;
  }

  /* Disabled: non riceve focus, testo muted; il selected perde il fondo pieno e l'indicatore si spegne. */
  .oxq-tab:where(:disabled) {
    --_fg: var(--oxq-neutral-text-muted);
    --_count-fg: var(--oxq-neutral-text-muted);
    --_indicator: var(--oxq-neutral-icon-muted);

    cursor: not-allowed;
  }

  :where(.oxq-tab-list[data-variant='line']) .oxq-tab:disabled .oxq-tab-count {
    background-color: transparent;
  }

  :where(.oxq-tab-list[data-variant='soft'], .oxq-tab-list[data-variant='solid'])
    > .oxq-tab:is([aria-selected='true'], [aria-current='page']):disabled {
    --_bg: var(--oxq-neutral-surface-control-disabled);
    --_fg: var(--oxq-neutral-text-muted);
    --_count-fg: var(--oxq-neutral-text-muted);
  }
}
/* Segmented control (Atoms › Segmented control): cambia sul posto la vista dello stesso contenuto, fra 2 e 5
   segmenti, sempre con uno scelto. Per un'altra pagina ci sono i tab, per un valore da salvare il segmented
   button, per on/off lo switch.
   Prop Figma → attributi: data-size sul controllo; selected è il radio :checked, disabled il radio disabled.
   Ogni segmento è una <label> con un radio nascosto: il gruppo, le frecce e il focus li dà il browser.
   Il selezionato è raised sul track sunken; in Figma il fondo scorre fra i segmenti, qui cambia in dissolvenza
   (ponytail: lo scorrimento vuole anchor positioning o JS, aggiungerlo quando Safari ha anchor positioning).
   Colori solo neutral. */
@layer components {
  .oxq-segmented-control {
    --_height: var(--oxq-size-control-sm);
    --_seg-px: var(--oxq-space-gap-sm);
    --_seg-font: var(--oxq-font-label-md);
    --_seg-ls: var(--oxq-label-md-letter-spacing);
    --_count-font: var(--oxq-font-label-sm);
    --_count-ls: var(--oxq-label-sm-letter-spacing);
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    flex-shrink: 0;
    gap: var(--oxq-space-inset-track);
    block-size: var(--_height);
    /* Il bordo sta dentro l'altezza e il track: i segmenti restano a space/inset/track dal bordo esterno. */
    padding: calc(var(--oxq-space-inset-track) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-sunken);
    vertical-align: middle;
  }

  .oxq-segmented-control:where([data-size='md']) {
    --_height: var(--oxq-size-control-md);
    --_seg-px: var(--oxq-space-inset-control-x);
  }

  .oxq-segmented-control:where([data-size='lg']) {
    --_height: var(--oxq-size-control-lg);
    --_seg-px: var(--oxq-space-inset-control-x);
    --_seg-font: var(--oxq-font-label-lg);
    --_seg-ls: var(--oxq-label-lg-letter-spacing);
    --_count-font: var(--oxq-font-label-md);
    --_count-ls: var(--oxq-label-md-letter-spacing);
    --_icon-size: var(--oxq-size-icon-md);
  }

  .oxq-segment {
    --_bg: transparent;
    --_border: transparent;
    --_shadow: none;
    --_fg: var(--oxq-neutral-text-secondary);
    --_count-fg: var(--oxq-neutral-text-ink);

    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--oxq-space-gap-2xs);
    /* Alto quanto il track; il bordo del selezionato sta dentro, come lo stroke inside di Figma. */
    padding-inline: calc(var(--_seg-px) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    box-shadow: var(--_shadow);
    color: var(--_fg);
    font: var(--_seg-font);
    letter-spacing: var(--_seg-ls);
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, border-color, box-shadow, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  /* Il radio resta nel flusso di focus e degli screen reader, ma non si vede. */
  .oxq-segment > input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    pointer-events: none;
  }

  .oxq-segment-count {
    color: var(--_count-fg);
    font: var(--_count-font);
    letter-spacing: var(--_count-ls);
  }

  /* Solo icona: la label resta per lo screen reader. */
  :where(.oxq-segmented-control[data-icon-only]) .oxq-segment-label {
    position: absolute;
    inline-size: 1em;
    block-size: 1em;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  @media (hover: hover) {
    .oxq-segment:where(:hover:not(:has(> input:disabled))) {
      --_fg: var(--oxq-neutral-text-ink);
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-segment:where(:active:not(:has(> input:disabled))) {
    --_fg: var(--oxq-neutral-text-ink);
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-segment:where(:has(> input:checked)) {
    --_bg: var(--oxq-neutral-surface-raised);
    --_border: var(--oxq-neutral-line-border-strong);
    --_shadow: var(--oxq-elevation-1);
    --_fg: var(--oxq-neutral-text-ink);
  }

  /* L'anello sta dentro il segmento: fuori lo coprirebbe il track. */
  .oxq-segment:where(:has(> input:focus-visible)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }

  /* Disabled: testo muted; il selezionato resta raised ma col bordo line/border e senza ombra. */
  .oxq-segment:where(:has(> input:disabled)) {
    --_fg: var(--oxq-neutral-text-muted);
    --_count-fg: var(--oxq-neutral-text-muted);

    cursor: not-allowed;
  }

  .oxq-segment:where(:has(> input:checked:disabled)) {
    --_border: var(--oxq-neutral-line-border);
    --_shadow: none;
  }
}
/* Segmented button (Atoms › Segmented button): sceglie un valore da salvare, fra 2 o più opzioni che si escludono,
   sempre con una scelta. Per cambiare solo la vista c'è il segmented control; con label lunghe o tante opzioni, il
   radio group.
   Prop Figma → attributi: data-variant (soft | solid), data-size e data-tone sul gruppo; selected è il radio
   :checked, disabled il radio disabled. Ogni opzione è una <label> con un radio nascosto: gruppo, frecce e focus li
   dà il browser, e il valore si invia col form.
   Il tone del gruppo è quello della regione: fondo, bordo, divisori, testo e scelta. brand solo solid, e allora
   resta neutral tutto tranne la scelta. Un'opzione può avere il suo data-tone, che si vede solo da scelta (Nega in
   danger, Concedi in success), o data-color, un accent, come tutto il gruppo. */
@layer components {
  .oxq-segmented-button {
    --_height: var(--oxq-size-control-sm);
    --_px: var(--oxq-space-gap-sm);
    --_font: var(--oxq-font-label-md);
    --_ls: var(--oxq-label-md-letter-spacing);
    --_icon-size: var(--oxq-size-icon-sm);
    --_line: var(--oxq-tone-line-border-strong);
    --_divider: var(--oxq-tone-line-hairline);
    --_off-fg: var(--oxq-tone-text-secondary);
    --_hover-fg: var(--oxq-tone-text-ink);
    --_muted: var(--oxq-tone-text-muted);
    --_disabled-bg: var(--oxq-tone-surface-control-disabled);
    --_group-bg: var(--oxq-tone-surface-raised);

    display: inline-flex;
    flex-shrink: 0;
    block-size: var(--_height);
    /* Il bordo sta dentro l'altezza; overflow ritaglia sulla pillola il fondo della prima e dell'ultima scelta. */
    overflow: hidden;
    border: var(--oxq-stroke-control) solid var(--_line);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_group-bg);
    vertical-align: middle;
  }

  .oxq-segmented-button:where([data-tone='brand']) {
    --_line: var(--oxq-neutral-line-border-strong);
    --_divider: var(--oxq-neutral-line-hairline);
    --_off-fg: var(--oxq-neutral-text-secondary);
    --_hover-fg: var(--oxq-neutral-text-ink);
    --_muted: var(--oxq-neutral-text-muted);
    --_disabled-bg: var(--oxq-neutral-surface-control-disabled);
    --_group-bg: var(--oxq-neutral-surface-raised);
  }

  .oxq-segmented-button:where([data-size='md']) {
    --_height: var(--oxq-size-control-md);
    --_px: var(--oxq-space-inset-control-x);
  }

  .oxq-segmented-button:where([data-size='lg']) {
    --_height: var(--oxq-size-control-lg);
    --_px: var(--oxq-space-inset-control-x);
    --_font: var(--oxq-font-label-lg);
    --_ls: var(--oxq-label-lg-letter-spacing);
    --_icon-size: var(--oxq-size-icon-md);
  }

  .oxq-segmented-button-item {
    --_bg: transparent;
    --_fg: var(--_off-fg);
    /* La scelta: soft su tone/surface/control, solid su tone/surface/solid. */
    --_sel-bg: var(--oxq-tone-surface-control);
    --_sel-fg: var(--oxq-tone-text-ink);

    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--oxq-space-gap-2xs);
    /* Il divisore (o il bordo del gruppo, per la prima) sta nel primo px del padding, come in Figma. */
    padding-inline: calc(var(--_px) - var(--oxq-stroke-control)) var(--_px);
    border-inline-start: var(--oxq-stroke-control) solid var(--_divider);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    font: var(--_font);
    letter-spacing: var(--_ls);
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    &:first-child {
      border-inline-start: 0;
      padding-inline-start: calc(var(--_px) - var(--oxq-stroke-control));
    }

    &:last-child {
      padding-inline-end: calc(var(--_px) - var(--oxq-stroke-control));
    }
  }

  :where(.oxq-segmented-button[data-variant='solid']) > .oxq-segmented-button-item {
    --_sel-bg: var(--oxq-tone-surface-solid);
    --_sel-fg: var(--oxq-tone-text-on-ink);
  }

  /* Il radio resta nel flusso di focus e degli screen reader, ma non si vede. */
  .oxq-segmented-button-item > input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    pointer-events: none;
  }

  /* L'anello sta attorno alla label, rettangolare, dentro l'opzione. */
  .oxq-segmented-button-label {
    position: relative;
  }

  .oxq-segmented-button-item:where(:has(> input:focus-visible)) > .oxq-segmented-button-label::after {
    content: '';
    position: absolute;
    inset: calc(-1 * (var(--oxq-offset-focus) + var(--oxq-stroke-focus)));
    border: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    border-radius: var(--oxq-radius-selection);
  }

  /* Solo icona: la label resta per lo screen reader, l'anello va sull'icona. */
  :where(.oxq-segmented-button[data-icon-only]) .oxq-segmented-button-label {
    position: absolute;
    inline-size: 1em;
    block-size: 1em;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  :where(.oxq-segmented-button[data-icon-only]) .oxq-segmented-button-item:has(> input:focus-visible) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * (var(--oxq-offset-focus) + var(--oxq-stroke-focus)));
  }

  @media (hover: hover) {
    .oxq-segmented-button-item:where(:hover:not(:has(> input:disabled))) {
      --_fg: var(--_hover-fg);
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-segmented-button-item:where(:active:not(:has(> input:disabled))) {
    --_fg: var(--_hover-fg);
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-segmented-button-item:where(:has(> input:checked)) {
    --_bg: var(--_sel-bg);
    --_fg: var(--_sel-fg);
  }

  /* Solid neutral o con un tone: hover e pressed cambiano il pieno, senza overlay. */
  :where(.oxq-segmented-button[data-variant='solid']:not([data-color]))
    > .oxq-segmented-button-item:where(:not([data-color]):has(> input:checked:not(:disabled))) {
    @media (hover: hover) {
      &:hover {
        --_bg: var(--oxq-tone-surface-solid-hover);
        --_overlay: transparent;
      }
    }

    &:active {
      --_bg: var(--oxq-tone-surface-solid-pressed);
      --_overlay: transparent;
    }
  }

  /* Accent, sull'opzione o su tutto il gruppo: soft sul soft dell'accent con il suo ink, solid sul pieno con on-ink. */
  :where(.oxq-segmented-button, .oxq-segmented-button-item):where([data-color='blue']) {
    --_acc-soft: var(--oxq-accent-blue-surface-soft);
    --_acc-solid: var(--oxq-accent-blue-surface-solid);
    --_acc-ink: var(--oxq-accent-blue-text-ink);
  }

  :where(.oxq-segmented-button, .oxq-segmented-button-item):where([data-color='green']) {
    --_acc-soft: var(--oxq-accent-green-surface-soft);
    --_acc-solid: var(--oxq-accent-green-surface-solid);
    --_acc-ink: var(--oxq-accent-green-text-ink);
  }

  :where(.oxq-segmented-button, .oxq-segmented-button-item):where([data-color='violet']) {
    --_acc-soft: var(--oxq-accent-violet-surface-soft);
    --_acc-solid: var(--oxq-accent-violet-surface-solid);
    --_acc-ink: var(--oxq-accent-violet-text-ink);
  }

  :where(.oxq-segmented-button, .oxq-segmented-button-item):where([data-color='magenta']) {
    --_acc-soft: var(--oxq-accent-magenta-surface-soft);
    --_acc-solid: var(--oxq-accent-magenta-surface-solid);
    --_acc-ink: var(--oxq-accent-magenta-text-ink);
  }

  :where(.oxq-segmented-button, .oxq-segmented-button-item):where([data-color='yellow']) {
    --_acc-soft: var(--oxq-accent-yellow-surface-soft);
    --_acc-solid: var(--oxq-accent-yellow-surface-solid);
    --_acc-ink: var(--oxq-accent-yellow-text-ink);
  }

  .oxq-segmented-button-item:where([data-color], [data-color] > *) {
    --_sel-bg: var(--_acc-soft);
    --_sel-fg: var(--_acc-ink);
  }

  :where(.oxq-segmented-button[data-variant='solid'])
    > .oxq-segmented-button-item:where([data-color], [data-color] > *) {
    --_sel-bg: var(--_acc-solid);
    --_sel-fg: var(--oxq-neutral-text-on-ink);
  }

  /* Tutto il gruppo in accent: anche bordo, divisori e testo delle altre opzioni. */
  .oxq-segmented-button:where([data-color]) {
    --_line: var(--_acc-solid);
    --_divider: var(--_acc-soft);
    --_off-fg: var(--_acc-ink);
    --_hover-fg: var(--_acc-ink);
  }

  /* Disabled: testo muted; la scelta resta su control-disabled. Tutto il gruppo, se il campo non si modifica. */
  .oxq-segmented-button-item:where(:has(> input:disabled)) {
    --_fg: var(--_muted);
    --_sel-bg: var(--_disabled-bg);
    --_sel-fg: var(--_muted);

    cursor: not-allowed;
  }
}
/* Dropdown (Atoms › Dropdown): campo che apre un menu per scegliere una voce da un elenco. È l'input field con un
   <select> nativo e la chevron: label, box, helper, size, status, hover, focus e disabled sono di input-field.css.
   Il select occupa tutto il box, così il campo intero è cliccabile; icon-start e chevron stanno sopra e non
   ricevono il puntatore. Senza scelta il select mostra il placeholder, un'option vuota e nascosta.
   Il menu è quello del browser. Dove c'è appearance: base-select (Chrome) è disegnato come il listbox che il dropdown
   apre in Figma, largo quanto il campo e a space/gap/2xs sotto; altrove resta il menu nativo, con la stessa tastiera.
   read-only non c'è: un select non si blocca senza disabilitarlo. */
@layer components {
  .oxq-dropdown > .oxq-input-field-box {
    position: relative;
    padding-inline: 0;
    cursor: pointer;

    /* Il select occupa tutto il box e ne dà la larghezza, come un select qualsiasi: quella della voce più lunga. */
    & > select {
      align-self: stretch;
      padding-inline: var(--oxq-space-inset-control-x)
        calc(var(--oxq-space-inset-control-x) + var(--_icon-size) + var(--oxq-space-gap-xs));
      border-radius: inherit;
      appearance: none;
      cursor: inherit;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    /* Con icon-start il valore parte dopo l'icona, come nell'input field. */
    &:has(> .oxq-icon + select) > select {
      padding-inline-start: calc(var(--oxq-space-inset-control-x) + var(--_icon-size) + var(--oxq-space-gap-xs));
    }

    /* icon-start e chevron stanno sopra il select e non ricevono il puntatore. */
    & > .oxq-icon {
      position: absolute;
      inset-block-start: 50%;
      inset-inline-start: var(--oxq-space-inset-control-x);
      translate: 0 -50%;
      pointer-events: none;
    }

    /* La chevron, sempre a destra. Da aperta punta in su. */
    & > select ~ .oxq-icon {
      inset-inline: auto var(--oxq-space-inset-control-x);
      transition: rotate var(--oxq-duration-open) var(--oxq-easing-transition);
    }

    /* Il placeholder: la voce vuota scelta, in text/secondary. */
    & > select:has(> option[value='']:checked) {
      color: var(--_fg-secondary);
    }
  }

  /* Aperto: bordo e anello come in focus anche col mouse, chevron in su. */
  @supports selector(:open) {
    .oxq-dropdown > .oxq-input-field-box:has(> select:open) {
      outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
      outline-offset: var(--oxq-offset-focus);

      & > select ~ .oxq-icon {
        rotate: 0.5turn;
      }
    }
  }

  @supports (appearance: base-select) {
    /* Lo stesso selettore che sopra toglie l'aspetto nativo. */
    .oxq-dropdown > .oxq-input-field-box > select,
    .oxq-dropdown select::picker(select) {
      appearance: base-select;
    }

    /* Con base-select il select si impagina come un contenitore: il valore va centrato in altezza. */
    .oxq-dropdown > .oxq-input-field-box > select {
      display: flex;
      align-items: center;
    }

    .oxq-dropdown select::picker-icon {
      display: none;
    }

    /* listbox: largo quanto il campo (il select sta dentro il bordo del box), oltre 7 voci scorre. */
    .oxq-dropdown select::picker(select) {
      box-sizing: border-box;
      inline-size: calc(anchor-size(inline) + 2 * var(--oxq-stroke-control));
      max-block-size: calc(
        7 * var(--_height) + 6 * var(--oxq-space-inset-track) + 2 * var(--oxq-space-gap-2xs) + 2 *
          var(--oxq-stroke-control)
      );
      margin-block-start: calc(var(--oxq-space-gap-2xs) + var(--oxq-stroke-control));
      margin-inline-start: calc(-1 * var(--oxq-stroke-control));
      padding: var(--oxq-space-gap-2xs);
      border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
      border-radius: var(--oxq-radius-surface);
      background-color: var(--oxq-neutral-surface-raised);
      box-shadow: var(--oxq-elevation-2);
    }

    /* _listbox-item: alto come il campo, la scelta su brand/surface/soft col check a destra. */
    .oxq-dropdown option {
      display: flex;
      align-items: center;
      gap: var(--oxq-space-gap-xs);
      min-block-size: var(--_height);
      padding-inline: var(--oxq-space-inset-item-x);
      border-radius: var(--oxq-radius-item);
      color: var(--oxq-neutral-text-ink);

      & + option {
        margin-block-start: var(--oxq-space-inset-track);
      }

      &::checkmark {
        content: '';
        order: 1;
        flex-shrink: 0;
        inline-size: var(--_icon-size);
        block-size: var(--_icon-size);
        margin-inline-start: auto;
        background-color: var(--oxq-neutral-icon-ink);
        /* Il check di Foundations › Icons (icons.json) come maschera: il menu non può contenere l'<svg>. */
        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16.6668 5L7.5001 14.1667L3.33344 10'/%3E%3C/svg%3E")
          center / contain no-repeat;
      }

      &:checked {
        background-color: var(--oxq-brand-surface-soft);
      }

      /* La voce attiva da tastiera: l'anello sta dentro, fuori lo taglierebbe il menu. */
      &:focus-visible {
        outline-offset: calc(-1 * var(--oxq-stroke-focus));
      }

      &:disabled {
        color: var(--oxq-neutral-text-muted);
      }
    }

    @media (hover: hover) {
      .oxq-dropdown option:hover:not(:disabled, :checked) {
        background-color: var(--oxq-system-state-hover);
      }
    }
  }
}
/* Search field (Atoms › Search field): campo di ricerca con l'icona search, il testo e il clear quando c'è un
   valore. È l'input field senza label né helper: box, size, hover, focus e disabled sono di input-field.css,
   il raggio è pill. Il nome è l'aria-label; il placeholder c'è sempre (di default la label), perché il clear si
   mostra solo quando non c'è il placeholder, cioè con un valore: così funziona anche senza JS.
   Il clear svuota il campo e ci rimette il focus (in Django lo fa oxq.js); Esc lo svuota già nel browser. */
@layer components {
  .oxq-search-field > .oxq-input-field-box {
    border-radius: var(--oxq-radius-pill);

    /* Il clear è il nostro: quello del browser si toglie, come la decorazione di Safari. */
    & > input {
      appearance: none;

      &::-webkit-search-cancel-button,
      &::-webkit-search-decoration {
        appearance: none;
      }
    }

    & > input:placeholder-shown ~ .oxq-search-field-clear {
      display: none;
    }

    & > .oxq-search-field-clear:disabled {
      cursor: not-allowed;
    }
  }
}
/* Scrim (Atoms › Scrim): il velo sotto un overlay, che attenua e blocca ciò che copre. Uno solo, sotto l'overlay
   più alto: con overlay annidati quello sotto non si somma. Prop Figma → data-intensity (soft | strong).
   - soft dietro drawer, menu e modal; strong dietro un modal a schermo intero
   - un solo fill, system/scrim/*: nero 16 e 32% in light, bianco in dark
   - copre il viewport (fixed); con data-contained solo il contenitore posizionato, col suo raggio
   Non è interattivo da solo ma intercetta i clic: se l'overlay non è bloccante, il clic sul velo lo chiude
   (lo decide chi lo usa). Compare e sparisce (hidden) in dissolvenza con duration/surface; con Reduced subito. */
@layer components {
  .oxq-scrim {
    position: fixed;
    inset: 0;
    border-radius: var(--oxq-radius-none);
    background-color: var(--oxq-system-scrim-soft);
    transition-behavior: allow-discrete;
    transition-property: opacity, display;
    transition-duration: var(--oxq-duration-surface);
    transition-timing-function: var(--oxq-easing-transition);

    /* All'apertura parte trasparente; dove @starting-style non c'è, compare e basta. */
    @starting-style {
      opacity: 0;
    }
  }

  .oxq-scrim:where([data-intensity='strong']) {
    background-color: var(--oxq-system-scrim-strong);
  }

  .oxq-scrim:where([data-contained]) {
    position: absolute;
    border-radius: inherit;
  }

  /* Chiuso: sfuma, poi display: none (base.css) a fine transizione. */
  .oxq-scrim:where([hidden]) {
    opacity: 0;
  }
}
/* Icon tile (Atoms › Icon tile): un'icona su un fondo quadrato, il segno di card, fact-card e righe di lista. Non si
   clicca: per un'azione c'è l'icon-button. Prop Figma → data-variant (soft | solid), data-tone, data-size.
   - la tile cresce con size/control, l'icona con size/icon; raggio radius/control
   - soft è il default; solid solo per l'elemento che deve spiccare fra altri soft
   - 7 tone come i button, senza brand: il rosso resta al button primary */
@layer components {
  .oxq-icon-tile {
    --_size: var(--oxq-size-control-sm);
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    inline-size: var(--_size);
    block-size: var(--_size);
    border-radius: var(--oxq-radius-control);
    background-color: var(--oxq-tone-surface-muted);
    color: var(--oxq-tone-icon-ink);
  }

  .oxq-icon-tile:where([data-size='md']) {
    --_size: var(--oxq-size-control-md);
    --_icon-size: var(--oxq-size-icon-md);
  }

  .oxq-icon-tile:where([data-size='lg']) {
    --_size: var(--oxq-size-control-lg);
    --_icon-size: var(--oxq-size-icon-lg);
  }

  .oxq-icon-tile:where([data-variant='solid']) {
    background-color: var(--oxq-tone-surface-solid);
    color: var(--oxq-tone-icon-on-ink);
  }
}
/* Card (Molecules › Card): il contenitore di un gruppo di contenuti sotto un titolo. header (icon-tile, titolo,
   sottotitolo, action) e content. Per un solo dato c'è la fact-card, per un vuoto l'empty-state.
   variant: elevated sul canvas, outlined su superfici già elevate, filled per i gruppi secondari; mai una elevated
   dentro un'altra card. size: sm nelle griglie dense e nei pannelli, md nelle page. La larghezza è della colonna.
   color (data-color) dà il filo a una card che appartiene a uno stato o a una categoria; neutral non ha filo.
   Cliccabile solo se tutta la card porta da qualche parte: il titolo è un link che la copre tutta, e hover e focus
   sono della card. Dentro non vanno altri button. */
@layer components {
  .oxq-card,
  .oxq-fact-card {
    --_bg: var(--oxq-neutral-surface-raised);
    --_border: transparent;
    --_shadow: var(--oxq-elevation-1);
    --_overlay: transparent;

    box-sizing: border-box;
    position: relative;
    /* Il bordo sta dentro il padding, come lo stroke inside di Figma che non entra nel layout. */
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    box-shadow: var(--_shadow);
    color: var(--oxq-neutral-text-ink);
    transition-property: border-color, box-shadow, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  .oxq-card:where([data-variant='outlined']),
  .oxq-fact-card:where([data-variant='outlined']) {
    --_border: var(--oxq-neutral-line-border);
    --_shadow: none;
  }

  .oxq-card:where([data-variant='filled']),
  .oxq-fact-card:where([data-variant='filled']) {
    --_bg: var(--oxq-neutral-surface-sunken);
    --_shadow: none;
  }

  .oxq-card {
    --_pad: var(--oxq-space-gap-md);
    --_gap: var(--oxq-space-gap-sm);

    display: flex;
    flex-direction: column;
    gap: var(--_gap);
    padding: calc(var(--_pad) - var(--oxq-stroke-control));
  }

  .oxq-card:where([data-size='md']) {
    --_pad: var(--oxq-space-inset-container);
    --_gap: var(--oxq-space-gap-md);

    border-radius: var(--oxq-radius-container);
  }

  .oxq-card-header {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
  }

  .oxq-card-titles {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-card-title {
    font: var(--oxq-font-title-sm);
    letter-spacing: var(--oxq-title-sm-letter-spacing);
  }

  .oxq-card-subtitle {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-card-content {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-card:where([data-size='md']) {
    & .oxq-card-title {
      font: var(--oxq-font-title-md);
      letter-spacing: var(--oxq-title-md-letter-spacing);
    }

    & .oxq-card-subtitle,
    & .oxq-card-content {
      font: var(--oxq-font-body-sm);
      letter-spacing: var(--oxq-body-sm-letter-spacing);
    }
  }

  /* Cliccabile: il link del titolo copre la card; l'anello di focus è della card, 2 px a 2 px dal bordo. */
  .oxq-card-link {
    color: inherit;
    text-decoration: none;
    outline: none;

    &::after {
      content: '';
      position: absolute;
      inset: calc(-1 * var(--oxq-stroke-control));
      border-radius: inherit;
    }
  }

  .oxq-card:where(:has(.oxq-card-link:focus-visible)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);
  }

  /* Hover: elevated passa a elevation/2, outlined a line/border-strong, filled aggiunge system/state/hover. */
  @media (hover: hover) {
    .oxq-card:where(:has(.oxq-card-link:hover)) {
      --_shadow: var(--oxq-elevation-2);
    }

    .oxq-card:where([data-variant='outlined']):where(:has(.oxq-card-link:hover)) {
      --_border: var(--oxq-neutral-line-border-strong);
      --_shadow: none;
    }

    .oxq-card:where([data-variant='filled']):where(:has(.oxq-card-link:hover)) {
      --_overlay: var(--oxq-system-state-hover);
      --_shadow: none;
    }
  }

  /* color: il filo nel colore, su ogni variant e anche in hover; fondo, ombra e testo restano neutral. */
  .oxq-card:where([data-color='brand']) {
    --_border: var(--oxq-brand-surface-solid);
  }

  .oxq-card:where([data-color='warning']) {
    --_border: var(--oxq-warning-line-border);
  }

  .oxq-card:where([data-color='danger']) {
    --_border: var(--oxq-danger-line-border-strong);
  }

  .oxq-card:where([data-color='success']) {
    --_border: var(--oxq-success-line-border-strong);
  }

  .oxq-card:where([data-color='info']) {
    --_border: var(--oxq-info-line-border-strong);
  }

  .oxq-card:where([data-color='discovery']) {
    --_border: var(--oxq-discovery-line-border-strong);
  }

  .oxq-card:where([data-color='yellow']) {
    --_border: var(--oxq-accent-yellow-line-border);
  }

  .oxq-card:where([data-color='green']) {
    --_border: var(--oxq-accent-green-line-border);
  }

  .oxq-card:where([data-color='blue']) {
    --_border: var(--oxq-accent-blue-line-border);
  }

  .oxq-card:where([data-color='violet']) {
    --_border: var(--oxq-accent-violet-line-border);
  }

  .oxq-card:where([data-color='magenta']) {
    --_border: var(--oxq-accent-magenta-line-border);
  }

  /* Fact card: un dato in evidenza, non cliccabile. Il value sta su una riga. */
  .oxq-fact-card {
    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
    padding: calc(var(--oxq-space-gap-sm) - var(--oxq-stroke-control));
  }

  .oxq-fact-card:where([data-size='md']) {
    padding: calc(var(--oxq-space-gap-md) - var(--oxq-stroke-control));
    border-radius: var(--oxq-radius-container);
  }

  .oxq-fact-card-texts {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-fact-card-label,
  .oxq-fact-card-caption {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-fact-card-value {
    font: var(--oxq-font-body-sm);
    font-weight: var(--oxq-body-sm-font-weight-strong);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    white-space: nowrap;
  }

  .oxq-fact-card:where([data-size='md']) .oxq-fact-card-value {
    font: var(--oxq-font-title-sm);
    letter-spacing: var(--oxq-title-sm-letter-spacing);
  }
}
/* File upload e file item (Molecules › File upload).
   file-upload: l'area dove si trascinano o si scelgono i file. L'input file la copre tutta, trasparente: un clic apre
   il selettore del sistema e un file lasciato sopra lo prende l'input, senza JS. La label e l'helper (formati e peso,
   o il motivo del rifiuto in status error) danno nome e descrizione all'input. drag-over (data-drag-over) lo mettono
   OxqFileUpload e oxq.js mentre un file passa sopra: fondo brand/surface/soft e bordo brand, non è un error.
   Il bordo è tratteggiato: il tratto 6 · 4 di Figma il CSS non lo regola, resta quello del browser.
   file-item: un file per riga sotto il file-upload, in caricamento (progress-bar), caricato (check) o rifiutato
   (il motivo nel meta). L'action annulla l'invio, rimuove il file o lo toglie dalla lista. */
@layer components {
  .oxq-file-upload {
    --_bg: var(--oxq-neutral-surface-sunken);
    --_overlay: transparent;
    --_border: var(--oxq-neutral-line-control);
    --_icon: var(--oxq-neutral-icon-secondary);
    --_fg: var(--oxq-neutral-text-ink);
    --_fg-helper: var(--oxq-neutral-text-secondary);
    --_pad-block: var(--oxq-space-gap-lg);
    --_icon-size: var(--oxq-size-icon-md);

    box-sizing: border-box;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
    /* Il bordo si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding: var(--_pad-block) var(--oxq-space-gap-lg);
    border: var(--oxq-stroke-control) dashed var(--_border);
    border-radius: var(--oxq-radius-control);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    text-align: center;
    transition-property: background-color, border-color, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--_icon);
    }

    /* L'input copre l'area: è lui che si clicca e su cui si lasciano i file. */
    & > input {
      position: absolute;
      inset: 0;
      inline-size: 100%;
      block-size: 100%;
      margin: 0;
      opacity: 0;
      cursor: pointer;
    }
  }

  /* md: più alto, non più largo: space/gap/xl sopra e sotto, space/gap/lg ai lati. */
  .oxq-file-upload:where([data-size='md']) {
    --_pad-block: var(--oxq-space-gap-xl);
    --_icon-size: var(--oxq-size-icon-lg);
  }

  .oxq-file-upload-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-file-upload-label {
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-file-upload-helper {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    color: var(--_fg-helper);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-file-upload:where([data-size='md']) {
    & .oxq-file-upload-label {
      font: var(--oxq-font-label-lg);
      letter-spacing: var(--oxq-label-lg-letter-spacing);
    }

    & .oxq-file-upload-helper {
      font: var(--oxq-font-body-sm);
      letter-spacing: var(--oxq-body-sm-letter-spacing);
    }
  }

  @media (hover: hover) {
    .oxq-file-upload:where(:has(> input:not(:disabled):hover)) {
      --_overlay: var(--oxq-system-state-hover);
      --_border: var(--oxq-neutral-line-control-hover);
    }
  }

  .oxq-file-upload:where(:has(> input:focus-visible)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);
  }

  /* error: bordo danger e il motivo nell'helper, con l'icona: il bordo da solo non dice cosa correggere. */
  .oxq-file-upload:where([data-status='error']) {
    --_border: var(--oxq-danger-line-border-strong);
    --_fg-helper: var(--oxq-danger-text-secondary);

    & .oxq-file-upload-helper > .oxq-icon {
      color: var(--oxq-danger-icon-secondary);
    }
  }

  .oxq-file-upload:where([data-drag-over]) {
    --_bg: var(--oxq-brand-surface-soft);
    --_overlay: transparent;
    --_border: var(--oxq-brand-surface-solid);
    --_icon: var(--oxq-neutral-icon-ink);
  }

  .oxq-file-upload:where(:has(> input:disabled)) {
    --_bg: var(--oxq-neutral-surface-control-disabled);
    --_overlay: transparent;
    --_border: var(--oxq-neutral-line-border);
    --_icon: var(--oxq-neutral-icon-muted);
    --_fg: var(--oxq-neutral-text-muted);
    --_fg-helper: var(--oxq-neutral-text-muted);

    transition: none;

    & > input {
      cursor: not-allowed;
    }
  }

  /* File item */
  .oxq-file-item {
    --_border: var(--oxq-neutral-line-border);
    --_icon: var(--oxq-neutral-icon-secondary);
    --_fg-meta: var(--oxq-neutral-text-secondary);
    --_icon-size: var(--oxq-size-icon-md);

    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
    padding: var(--oxq-space-gap-sm) var(--oxq-space-gap-md);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-control);
    background-color: var(--oxq-neutral-surface-raised);
    color: var(--oxq-neutral-text-ink);

    & > .oxq-icon {
      color: var(--_icon);
    }
  }

  .oxq-file-item:where([data-size='md']) {
    --_icon-size: var(--oxq-size-icon-lg);

    padding: var(--oxq-space-gap-md) var(--oxq-space-gap-lg);
  }

  .oxq-file-item:where([data-status='error']) {
    --_border: var(--oxq-danger-line-border-strong);
    --_icon: var(--oxq-danger-icon-secondary);
    --_fg-meta: var(--oxq-danger-text-secondary);
  }

  .oxq-file-item-content {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  /* Il nome intero, troncato a fine riga: il tipo resta nel meta. */
  .oxq-file-item-name {
    overflow: hidden;
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-file-item:where([data-size='md']) .oxq-file-item-name {
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  .oxq-file-item:where([data-size='md']) .oxq-file-item-meta {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-file-item-meta {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    color: var(--_fg-meta);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);

    & > .oxq-icon {
      color: var(--oxq-success-icon-secondary);
    }
  }

  .oxq-file-item:where([data-status='error']) .oxq-file-item-meta > .oxq-icon {
    color: var(--oxq-danger-icon-secondary);
  }

  /* Più file in colonna, sotto il file-upload, a space/gap/xs. */
  .oxq-file-list {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
  }
}
/* Empty state (Molecules › Empty state): cosa mostrare quando una lista, una tabella o una card non ha contenuti.
   Solo tipografico: title (cosa manca), description (perché e cosa fare, al massimo 2 righe) e al massimo un button.
   Mentre i dati arrivano si usa lo skeleton, non l'empty state.
   size: sm dentro card e tabelle, md al centro di una page vuota. align: center di default, start in una colonna
   allineata a sinistra. La larghezza è al massimo quella di Figma (sm 360, md 480): resta stretta anche in una
   tabella larga, centrata o a sinistra secondo align. */
@layer components {
  .oxq-empty-state {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--oxq-space-gap-md);
    max-inline-size: var(--oxq-size-empty-state-sm);
    margin-inline: auto;
    padding-block: var(--oxq-space-gap-xl);
    text-align: center;
  }

  .oxq-empty-state:where([data-size='md']) {
    max-inline-size: var(--oxq-size-layout-narrow-max);
    padding-block: var(--oxq-space-gap-2xl);
  }

  .oxq-empty-state:where([data-align='start']) {
    align-items: flex-start;
    margin-inline: 0;
    text-align: start;
  }

  .oxq-empty-state-texts {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
    inline-size: 100%;
  }

  .oxq-empty-state-title {
    color: var(--oxq-neutral-text-ink-hover);
    font: var(--oxq-font-title-md);
    letter-spacing: var(--oxq-title-md-letter-spacing);
  }

  .oxq-empty-state-description {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-empty-state:where([data-size='md']) {
    & .oxq-empty-state-title {
      font: var(--oxq-font-heading-sm);
      letter-spacing: var(--oxq-heading-sm-letter-spacing);
    }

    & .oxq-empty-state-description {
      font: var(--oxq-font-body-md);
      letter-spacing: var(--oxq-body-md-letter-spacing);
    }
  }
}
/* Modal (Organisms › Modal): chiede una decisione o raccoglie dati senza lasciare la pagina, e la blocca finché non si
   chiude. Un <dialog> aperto con showModal (o command="show-modal"): il browser lo mette sopra tutto, rende inerte la
   pagina, tiene il focus dentro e lo chiude con Esc, che vale come Annulla. Lo scrim è il ::backdrop, system/scrim/soft.
   size: sm per le conferme brevi, md per form corti e liste, lg per contenuti ricchi; oltre lg serve una pagina.
   tone danger per le azioni che non si annullano: il primary diventa danger. Niente modal annidati. */
@layer components {
  .oxq-modal {
    box-sizing: border-box;
    inline-size: var(--oxq-size-modal-sm);
    max-inline-size: calc(100% - 2 * var(--oxq-space-layout-margin));
    max-block-size: calc(100% - 2 * var(--oxq-space-layout-margin));
    /* La base toglie il margin del browser, che centra il dialog. */
    margin: auto;
    overflow: auto;
    /* Il bordo sta dentro il padding, come lo stroke inside di Figma. */
    padding: calc(var(--oxq-space-inset-overlay) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-overlay);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-3);
    color: var(--oxq-neutral-text-ink);
    opacity: 0;
    transition-behavior: allow-discrete;
    transition-property: opacity, display, overlay;
    transition-duration: var(--oxq-duration-surface);
    transition-timing-function: var(--oxq-easing-transition);

    &::backdrop {
      background-color: var(--oxq-system-scrim-soft);
      opacity: 0;
      transition-behavior: allow-discrete;
      transition-property: opacity, display, overlay;
      transition-duration: var(--oxq-duration-surface);
      transition-timing-function: var(--oxq-easing-transition);
    }

    /* Aperto: compare in dissolvenza col suo scrim, e sparisce allo stesso modo; con Reduced subito. */
    &[open],
    &[open]::backdrop {
      opacity: 1;

      @starting-style {
        opacity: 0;
      }
    }
  }

  .oxq-modal:where([data-size='md']) {
    inline-size: var(--oxq-size-modal-md);
  }

  .oxq-modal:where([data-size='lg']) {
    inline-size: var(--oxq-size-modal-lg);
  }

  .oxq-modal-form {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-md);
  }

  .oxq-modal-header {
    display: flex;
    align-items: flex-start;
    gap: var(--oxq-space-gap-sm);
  }

  .oxq-modal-title {
    flex: 1 1 0;
    min-inline-size: 0;
    font: var(--oxq-font-title-lg);
    letter-spacing: var(--oxq-title-lg-letter-spacing);
  }

  .oxq-modal-description {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  /* Lo slot: alert, input field, search field, liste da scegliere. */
  .oxq-modal-content {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
  }

  /* Annulla a sinistra del primary, a destra. */
  .oxq-modal-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--oxq-space-gap-sm);
    padding-block-start: var(--oxq-space-gap-xs);
  }
}
/* Sheet (Organisms › Sheet): un pannello laterale sopra la pagina, per dettagli e form lunghi senza lasciare il
   contesto; per conferme e scelte brevi c'è il modal. Un <dialog> aperto con showModal (o command="show-modal"), come
   il modal: scrim nel ::backdrop, Esc, focus dentro; closedby="any" lo chiude anche col clic sullo scrim.
   - entra dal bordo (data-side right, o left solo per navigazione e filtri) e prende tutta l'altezza; il raggio sta
     sugli angoli verso la pagina
   - size: sm per i dettagli, md per i form, lg per tabelle e contenuti larghi (size/sheet/*)
   - header e footer restano fermi, col filo hairline che in Figma conta nell'altezza (101 e 73); scorre il contenuto */
@layer components {
  .oxq-sheet {
    --_from: 100%;

    box-sizing: border-box;
    inline-size: var(--oxq-size-sheet-sm);
    /* ponytail: sotto viewport/sm Figma lo vuole largo quanto la pagina e senza raggio; una media query non legge il
       token, così si stringe solo quando la pagina è più stretta e il raggio resta. */
    max-inline-size: 100%;
    block-size: 100%;
    max-block-size: 100%;
    margin: 0 0 0 auto;
    overflow: hidden;
    padding: 0;
    border: 0;
    border-start-start-radius: var(--oxq-radius-overlay);
    border-end-start-radius: var(--oxq-radius-overlay);
    background-color: var(--oxq-neutral-surface-raised);
    /* Il bordo line/popover sta dentro, come lo stroke inside di Figma: header, contenuto e footer non si spostano. */
    box-shadow:
      inset 0 0 0 var(--oxq-stroke-control) var(--oxq-neutral-line-popover),
      var(--oxq-elevation-3);
    color: var(--oxq-neutral-text-ink);
    translate: var(--_from) 0;
    transition-behavior: allow-discrete;
    transition-property: translate, display, overlay;
    transition-duration: var(--oxq-duration-surface);
    transition-timing-function: var(--oxq-easing-transition);

    &::backdrop {
      background-color: var(--oxq-system-scrim-soft);
      opacity: 0;
      transition-behavior: allow-discrete;
      transition-property: opacity, display, overlay;
      transition-duration: var(--oxq-duration-surface);
      transition-timing-function: var(--oxq-easing-transition);
    }

    /* Aperto: scivola dal bordo col suo scrim che compare, e torna indietro allo stesso modo; con Reduced subito. */
    &[open] {
      translate: 0 0;

      @starting-style {
        translate: var(--_from) 0;
      }
    }

    &[open]::backdrop {
      opacity: 1;

      @starting-style {
        opacity: 0;
      }
    }
  }

  .oxq-sheet:where([data-side='left']) {
    --_from: -100%;

    margin: 0 auto 0 0;
    border-radius: 0 var(--oxq-radius-overlay) var(--oxq-radius-overlay) 0;
  }

  /* La handle resize sul bordo verso la pagina, a metà altezza; la larghezza che dà va nello style dello sheet. */
  .oxq-sheet > .oxq-handle {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 0;
    translate: 0 -50%;
  }

  .oxq-sheet:where([data-side='left']) > .oxq-handle {
    inset-inline: auto 0;
  }

  .oxq-sheet:where([data-size='md']) {
    inline-size: var(--oxq-size-sheet-md);
  }

  .oxq-sheet:where([data-size='lg']) {
    inline-size: var(--oxq-size-sheet-lg);
  }

  .oxq-sheet-form {
    display: flex;
    flex-direction: column;
    block-size: 100%;
  }

  .oxq-sheet-header {
    display: flex;
    flex-shrink: 0;
    align-items: flex-start;
    gap: var(--oxq-space-gap-sm);
    padding: var(--oxq-space-inset-overlay) var(--oxq-space-inset-overlay) var(--oxq-space-gap-md);
    border-block-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
  }

  .oxq-sheet-text {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-sheet-title {
    font: var(--oxq-font-title-lg);
    letter-spacing: var(--oxq-title-lg-letter-spacing);
  }

  .oxq-sheet-description {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  /* Lo slot: campi, tabelle, riepiloghi. È l'unica parte che scorre. */
  .oxq-sheet-content {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-md);
    min-block-size: 0;
    overflow: auto;
    padding: var(--oxq-space-gap-lg) var(--oxq-space-inset-overlay) var(--oxq-space-inset-overlay);
  }

  /* Annulla a sinistra del primary, a destra. */
  .oxq-sheet-actions {
    display: flex;
    flex-shrink: 0;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--oxq-space-gap-sm);
    margin-block-start: auto;
    padding: var(--oxq-space-gap-md) var(--oxq-space-inset-overlay);
    border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
  }
}
/* Property item (Atoms › Property item): un dato che si modifica sul posto, senza aprire un form. La label sopra,
   corta; il valore è un input che a riposo sembra testo. Un clic (o il Tab) lo apre, Invio salva, Esc annulla, e ogni
   riga si salva da sola (change: hx-patch in Django, v-model in Vue). Prop Figma → data-size (sm | md),
   data-status="error", data-divider="false"; content empty è l'input vuoto, read-only un testo.
   - rest senza bordo; hover il fondo system/state/hover e l'icona edit; aperto (focus ed editing di Figma insieme)
     neutral/surface/sunken col bordo line/control, l'anello e l'helper coi tasti; error col bordo danger e il motivo
   - vuoto: il link Aggiungi al posto del valore, mai un campo aperto; read-only senza hover, «—» se vuoto
   - origine: un badge outline accanto alla label, solo per i dati che arrivano da fuori
   Property list (Molecules › Property list): righe property-item sotto un titolo; vertical in colonna, horizontal
   affiancate e a capo, larghe size/property-item/inline. */
@layer components {
  .oxq-property-item {
    --_label-font: var(--oxq-font-label-sm);
    --_label-ls: var(--oxq-label-sm-letter-spacing);
    --_value-font: var(--oxq-font-body-sm);
    --_value-ls: var(--oxq-body-sm-letter-spacing);
    --_box: var(--oxq-size-control-sm);
    --_bg: transparent;
    --_border: transparent;

    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
    /* Il filo hairline sta nel padding sotto, come in Figma (sopra il padding, non in più). */
    padding-block: var(--oxq-space-gap-xs) calc(var(--oxq-space-gap-xs) - var(--oxq-stroke-divider));
    border-block-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    color: var(--oxq-neutral-text-ink);
  }

  .oxq-property-item:where([data-divider='false']) {
    padding-block-end: var(--oxq-space-gap-xs);
    border-block-end: 0;
  }

  .oxq-property-item-header {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-property-item-label {
    color: var(--oxq-neutral-text-secondary);
    font: var(--_label-font);
    letter-spacing: var(--_label-ls);
  }

  .oxq-property-item-box {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--_box);
    padding-inline: var(--oxq-space-gap-xs);
    border-radius: var(--oxq-radius-control);
    background-color: var(--_bg);
    /* Il bordo dentro il box: aprendo il campo il testo non si sposta. */
    box-shadow: inset 0 0 0 var(--oxq-stroke-control) var(--_border);
    font: var(--_value-font);
    letter-spacing: var(--_value-ls);
    transition-property: background-color, box-shadow;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      display: none;
      color: var(--oxq-neutral-icon-secondary);
    }

    /* Il plus del link Aggiungi, finché il campo è vuoto e chiuso. */
    &:has(> :placeholder-shown:not(:focus)) > .oxq-icon:first-child {
      display: block;
      color: var(--oxq-info-text-secondary);
    }
  }

  .oxq-property-item-input,
  .oxq-property-item-value {
    flex: 1;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-property-item-input {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    cursor: pointer;

    /* L'anello sta sul box, che è il campo aperto. */
    &:focus-visible {
      outline: none;
    }

    &:focus {
      cursor: text;
    }

    /* Vuoto e chiuso: il link Aggiungi. */
    &::placeholder {
      color: var(--oxq-info-text-secondary);
      font: var(--_add-font, var(--oxq-font-label-sm));
      letter-spacing: var(--_add-ls, var(--oxq-label-sm-letter-spacing));
      text-decoration-line: underline;
      text-decoration-thickness: var(--oxq-stroke-underline);
      text-underline-offset: var(--oxq-offset-underline);
      opacity: 1;
    }

    &:focus::placeholder {
      color: transparent;
    }
  }

  .oxq-property-item-value:empty::before {
    content: '—';
    color: var(--oxq-neutral-text-muted);
  }

  @media (hover: hover) {
    .oxq-property-item-box:where(:has(> input):hover:not(:focus-within)) {
      --_bg: var(--oxq-system-state-hover);

      & > .oxq-icon:last-child:not(:first-child) {
        display: block;
      }

      &:has(> :placeholder-shown) > .oxq-icon:last-child:not(:first-child) {
        display: none;
      }
    }
  }

  /* Aperto: il campo con fondo, bordo e anello, e l'helper coi tasti. */
  .oxq-property-item-box:where(:focus-within) {
    --_bg: var(--oxq-neutral-surface-sunken);
    --_border: var(--oxq-neutral-line-control);

    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }

  .oxq-property-item-helper {
    display: none;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);

    & > .oxq-icon {
      --_icon-size: var(--oxq-size-icon-sm);
    }
  }

  .oxq-property-item:where(:focus-within) > .oxq-property-item-helper {
    display: flex;
  }

  /* error: il valore resta in modifica, col bordo danger e il motivo. */
  .oxq-property-item:where([data-status='error']) {
    & > .oxq-property-item-box {
      --_bg: var(--oxq-neutral-surface-sunken);
      --_border: var(--oxq-danger-line-border-strong);
    }

    & > .oxq-property-item-helper {
      display: flex;
      color: var(--oxq-danger-text-secondary);
    }
  }

  .oxq-property-item:where([data-size='md']) {
    --_label-font: var(--oxq-font-label-md);
    --_label-ls: var(--oxq-label-md-letter-spacing);
    --_value-font: var(--oxq-font-body-md);
    --_value-ls: var(--oxq-body-md-letter-spacing);
    --_add-font: var(--oxq-font-label-md);
    --_add-ls: var(--oxq-label-md-letter-spacing);
    --_box: var(--oxq-size-control-md);
  }

  /* Property list. Il legend flotta: così è un elemento del flex del fieldset e prende il gap. */
  .oxq-property-list {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-property-list-title {
    float: inline-start;
    inline-size: 100%;
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-overline-sm);
    letter-spacing: var(--oxq-overline-sm-letter-spacing);
    text-transform: uppercase;
  }

  .oxq-property-list-items {
    display: flex;
    flex-direction: column;
  }

  .oxq-property-list:where([data-orientation='horizontal']) > .oxq-property-list-items {
    flex-flow: row wrap;
    column-gap: var(--oxq-space-gap-lg);

    & > .oxq-property-item {
      inline-size: var(--oxq-size-property-item-inline);
    }
  }
}
/* Task item (Atoms › Task item): una riga di cose da fare, col conteggio, il titolo che lo continua («rate da
   confermare»), una descrizione breve e la freccia. Con href è un link alla vista dove si fa il lavoro; senza, una riga
   ferma senza freccia. data-tone segue l'urgenza e colora solo il conteggio.
   - hover system/state/hover, pressed system/state/pressed, focus l'anello dentro la riga
   Task list (Molecules › Task list): le righe, dalla più urgente, su neutral/surface/raised con elevation/1; il filo
   hairline fra una riga e l'altra lo mette la lista, così l'ultima non lo ha. */
@layer components {
  .oxq-task-item {
    --_overlay: transparent;

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-md);
    padding: var(--oxq-space-inset-task-item-y) var(--oxq-space-inset-control-x);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-neutral-text-ink);
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition-property: --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      --_icon-size: var(--oxq-size-icon-sm);

      color: var(--oxq-neutral-icon-secondary);
    }

    /* L'anello sta dentro la riga: fuori lo taglierebbe la lista. */
    &:focus-visible {
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }
  }

  @media (hover: hover) {
    a.oxq-task-item:where(:hover) {
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  a.oxq-task-item:where(:active) {
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-task-item-count {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    inline-size: var(--oxq-size-control-md);
    block-size: var(--oxq-size-control-sm);
    border-radius: var(--oxq-radius-item);
    background-color: var(--oxq-tone-surface-muted);
    color: var(--oxq-tone-text-ink);
    font: var(--oxq-font-label-md);
    font-weight: var(--oxq-label-md-font-weight-strong);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  /* warning: il numero in text/ink-hover, come in Figma: text/ink sul fondo muted non basta. */
  .oxq-task-item:where([data-tone='warning']) > .oxq-task-item-count {
    color: var(--oxq-tone-text-ink-hover);
  }

  .oxq-task-item-text {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--oxq-space-gap-task-item-text);
    min-inline-size: 0;
  }

  .oxq-task-item-title {
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-task-item-description {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-task-list {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-1);

    /* Il filo fra le righe sta nel loro padding, come in Figma. */
    & > .oxq-task-item + .oxq-task-item {
      padding-block-start: calc(var(--oxq-space-inset-task-item-y) - var(--oxq-stroke-divider));
      border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    }
  }
}
/* Metric (Atoms › Metric): un valore numerico con label e caption. Prop Figma → data-size (sm | md | lg), data-tone
   (neutral | success | warning | danger): il tone colora solo il valore, quando supera una soglia.
   - value già formattato, con separatori e unità (€ 33.000,00 · 54,8% · 12 gg); caption il termine di confronto
   - il badge accanto alla label solo per qualificarla: stima, provvisorio
   - sm nei dettagli e nelle righe, md in card e KPI, lg per un solo dato in evidenza per vista
   KPI card (Molecules › KPI card): una metric md in una card, col dot di stato, il meter, il trend e la sparkline;
   elevated sul fondo pagina, outlined dentro un'altra superficie, filled nei gruppi fitti; muted quando il dato manca. */
@layer components {
  .oxq-metric {
    --_label-font: var(--oxq-font-label-sm);
    --_label-ls: var(--oxq-label-sm-letter-spacing);
    --_value-font: var(--oxq-font-label-md);
    --_value-weight: var(--oxq-label-md-font-weight-strong);
    --_value-ls: var(--oxq-label-md-letter-spacing);

    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-metric-header {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-metric-label {
    color: var(--oxq-neutral-text-secondary);
    font: var(--_label-font);
    letter-spacing: var(--_label-ls);
  }

  .oxq-metric-value {
    color: var(--oxq-tone-text-ink-hover);
    font: var(--_value-font);
    font-weight: var(--_value-weight);
    letter-spacing: var(--_value-ls);
    white-space: nowrap;
  }

  .oxq-metric-caption {
    color: var(--oxq-neutral-text-muted);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-metric:where([data-size='md']) {
    --_value-font: var(--oxq-font-heading-sm);
    --_value-weight: var(--oxq-heading-sm-font-weight);
    --_value-ls: var(--oxq-heading-sm-letter-spacing);
  }

  .oxq-metric:where([data-size='lg']) {
    --_label-font: var(--oxq-font-label-md);
    --_label-ls: var(--oxq-label-md-letter-spacing);
    --_value-font: var(--oxq-font-heading-lg);
    --_value-weight: var(--oxq-heading-lg-font-weight);
    --_value-ls: var(--oxq-heading-lg-letter-spacing);
  }

  .oxq-kpi-card {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
    padding: var(--oxq-space-inset-container);
    border-radius: var(--oxq-radius-container);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-1);
    color: var(--oxq-neutral-text-ink);
  }

  .oxq-kpi-card:where([data-state='muted']) {
    background-color: var(--oxq-neutral-surface-muted);
  }

  /* Il bordo si aggiunge al padding, come lo stroke incluso nel layout di Figma: la outlined è alta 2 px in più. */
  .oxq-kpi-card:where([data-variant='outlined']) {
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: none;
  }

  .oxq-kpi-card:where([data-variant='filled']) {
    background-color: var(--oxq-neutral-surface-sunken);
    box-shadow: none;
  }

  .oxq-kpi-card-header {
    display: flex;
    align-items: flex-start;
    gap: var(--oxq-space-gap-xs);

    & > .oxq-metric {
      flex: 1;
    }

    /* Il dot si allinea alla label della metric. */
    & > .oxq-dot-badge {
      margin-block-start: var(--oxq-space-gap-2xs);
    }
  }

  .oxq-kpi-card-trend {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }
}
/* Alert (Molecules › Alert): un messaggio in linea legato al contenuto vicino (conseguenze, esiti, avvisi), che resta
   finché la condizione vale. Le conferme che spariscono da sole sono toast, non alert.
   tone: neutral per una nota senza urgenza, info per proseguire, success per un esito da ricordare, warning per un
   rischio che si può ancora correggere, danger per perdita di dati o errore (nel modal distruttivo, cosa succede se si
   conferma). Fondo surface/canvas del tone, bordo line/border, icona ink, title text/ink-hover, description secondary; neutral ha
   il fondo sunken, perché il suo canvas è quello della pagina.
   Un title in grassetto (senza, la description basta da sola), al massimo un'action che risolve il messaggio e il
   close solo se si può ignorare: mai nei modal distruttivi. */
@layer components {
  .oxq-alert {
    --_bg: var(--oxq-tone-surface-canvas);
    --_icon-size: var(--oxq-size-icon-md);

    box-sizing: border-box;
    display: flex;
    align-items: flex-start;
    gap: var(--oxq-space-gap-sm);
    /* Il bordo si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding: var(--oxq-space-gap-md);
    border: var(--oxq-stroke-control) solid var(--oxq-tone-line-border);
    border-radius: var(--oxq-radius-control);
    background-color: var(--_bg);
    color: var(--oxq-tone-text-ink);

    & > .oxq-icon {
      color: var(--oxq-tone-icon-ink);
    }
  }

  .oxq-alert:where([data-tone='neutral']) {
    --_bg: var(--oxq-neutral-surface-sunken);
  }

  .oxq-alert-text {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-alert-title {
    color: var(--oxq-tone-text-ink-hover);
    font: var(--oxq-font-body-md);
    font-weight: var(--oxq-body-md-font-weight-strong);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-alert-description {
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-alert-actions {
    display: flex;
    padding-block-start: var(--oxq-space-gap-xs);
  }
}
/* Toast e toast-stack (Organisms › Toast). Il toast è l'esito di un'azione appena fatta: sopra la pagina, sparisce da
   solo e non contiene informazioni che servono dopo; per i messaggi che restano c'è l'alert.
   content: compact è una riga (conferme brevi, al massimo Annulla); detailed ha title, meta e description (esiti con
   dettagli, operazioni in corso, errori). tone come l'alert; neutral sta su surface/raised, gli altri sul canvas del
   tone. In corso (data-loading) lo spinner prende il posto dell'icona e il close non c'è.
   Durata: 5 secondi, 8 con un'action; il puntatore o il focus sopra sospendono il conto. danger e in corso restano
   finché non si chiudono. La durata la contano OxqToast.vue e oxq.js.
   toast-stack: in alto a destra, largo size/toast, mai più della pagina meno i margini.
   I toast nuovi si aggiungono in fondo e compaiono in cima; se ne vedono al massimo 3, i più recenti. È una regione
   live (aria-live polite): chi la usa la mette nella pagina vuota, e il lettore di schermo legge i toast che arrivano. */
@layer components {
  .oxq-toast {
    --_bg: var(--oxq-tone-surface-canvas);
    --_border: var(--oxq-tone-line-popover);
    --_icon-size: var(--oxq-size-icon-md);

    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
    inline-size: var(--oxq-size-toast);
    max-inline-size: 100%;
    /* Il bordo si aggiunge al padding, come lo stroke incluso nel layout di Figma. */
    padding: var(--oxq-space-gap-xs) var(--oxq-space-gap-xs) var(--oxq-space-gap-xs) var(--oxq-space-gap-md);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--_bg);
    box-shadow: var(--oxq-elevation-2);
    color: var(--oxq-tone-text-ink);
    transition-behavior: allow-discrete;
    transition-property: opacity, display;
    transition-duration: var(--oxq-duration-surface);
    transition-timing-function: var(--oxq-easing-transition);

    /* Compare e sparisce in dissolvenza; con Reduced subito. */
    @starting-style {
      opacity: 0;
    }

    & > :is(.oxq-icon, .oxq-spinner) {
      color: var(--oxq-tone-icon-ink);
    }
  }

  .oxq-toast:where([hidden]) {
    opacity: 0;
  }

  .oxq-toast:where([data-tone='neutral']) {
    --_bg: var(--oxq-neutral-surface-raised);
  }

  .oxq-toast:where([data-content='detailed']) {
    align-items: flex-start;
    padding: var(--oxq-space-gap-md);
  }

  .oxq-toast-text {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-toast-title {
    color: var(--oxq-tone-text-ink-hover);
    font: var(--oxq-font-body-md);
    font-weight: var(--oxq-body-md-font-weight-strong);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-toast-meta {
    color: var(--oxq-tone-text-muted);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-toast-description {
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* L'action: nel compact accanto al testo, nel detailed sotto la description. */
  .oxq-toast-actions {
    display: flex;
  }

  .oxq-toast-text > .oxq-toast-actions {
    padding-block-start: var(--oxq-space-gap-xs);
  }

  .oxq-toast-stack {
    position: fixed;
    inset-block-start: var(--oxq-space-layout-margin);
    inset-inline-end: var(--oxq-space-layout-margin);
    display: flex;
    flex-direction: column-reverse;
    gap: var(--oxq-space-gap-xs);
    /* ponytail: Figma vuole lo stack largo quanto la pagina sotto viewport/lg; qui solo quando la pagina è più
       stretta di size/toast, perché una media query non legge il token. */
    inline-size: min(var(--oxq-size-toast), 100% - 2 * var(--oxq-space-layout-margin));
    /* Vuoto o tra un toast e l'altro, non copre i clic sulla pagina. */
    pointer-events: none;

    & > * {
      inline-size: auto;
      pointer-events: auto;
    }

    /* I più recenti sono in fondo: oltre il terzo, quelli prima aspettano. */
    & > .oxq-toast:nth-last-child(n + 4 of .oxq-toast:not([hidden])) {
      display: none;
    }
  }
}
/* Tree view (Molecules › Tree view, Atoms › Tree item): una struttura ad albero, role=tree. Le righe (tree-item,
   role=treeitem) e i livelli (tree-group, role=group) stanno uno dopo l'altro come in Figma: il livello va subito
   dopo la riga che lo apre, e si nasconde quando la riga è chiusa (aria-expanded=false).
   - riga: freccia, icona, indice e codice (mono), label su una riga, azione a destra che compare su hover e focus
   - expand → aria-expanded: senza, la riga non ha figli e non ha freccia; aperta, la freccia gira verso il basso
   - hover system/state/hover; selected (aria-selected) brand/surface/soft con la label in grassetto; highlighted
     info/surface/canvas; focus solo l'anello, dentro la riga; disabled (aria-disabled) muted, senza hover
   - livello: rientra di space/inset/item-x + size/icon/sm, col filo che scende dal centro della freccia
   Senza tone: i colori sono quelli neutral del DS, il fondo è quello del piano su cui sta. */
@layer components {
  .oxq-tree-view,
  .oxq-tree-group {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-tree-group {
    padding-inline-start: calc(var(--oxq-space-inset-item-x) + var(--oxq-size-icon-sm));
    background: linear-gradient(var(--oxq-neutral-line-border), var(--oxq-neutral-line-border)) no-repeat
      calc(var(--oxq-space-inset-item-x) + (var(--oxq-size-icon-sm) - var(--oxq-stroke-divider)) / 2) 0 /
      var(--oxq-stroke-divider) 100%;
  }

  .oxq-tree-item[aria-expanded='false'] + .oxq-tree-group {
    display: none;
  }

  .oxq-tree-item {
    --_icon-size: var(--oxq-size-icon-sm);
    --_bg: transparent;
    --_overlay: transparent;
    --_strong: var(--oxq-body-sm-font-weight-strong);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--oxq-size-control-sm);
    padding: 0 var(--oxq-space-inset-item-x);
    border-radius: var(--oxq-radius-item);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    cursor: default;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--oxq-neutral-icon-secondary);
    }

    /* La freccia: verso destra chiusa, verso il basso aperta. È lei ad aprire e chiudere il livello. */
    &[aria-expanded] > .oxq-icon:first-child {
      cursor: pointer;
      transition: rotate var(--oxq-duration-state) var(--oxq-easing-transition);
    }

    &[aria-expanded='true'] > .oxq-icon:first-child {
      rotate: 90deg;
    }

    /* L'anello sta dentro la riga: fuori toccherebbe le righe vicine. */
    &:focus-visible {
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }
  }

  .oxq-tree-item-index,
  .oxq-tree-item-code {
    flex-shrink: 0;
    font: var(--oxq-font-code-sm);
    letter-spacing: var(--oxq-code-sm-letter-spacing);
    white-space: nowrap;
  }

  .oxq-tree-item-index {
    color: var(--oxq-neutral-text-secondary);
  }

  /* Una riga sola: a ogni livello la label ha meno spazio e si tronca. */
  .oxq-tree-item-label {
    flex: 1;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-tree-item-action {
    display: flex;
    flex-shrink: 0;
  }

  /* L'azione compare su hover e focus; dove non c'è hover resta sempre. */
  @media (hover: hover) {
    .oxq-tree-item:where(:not(:hover, :focus-within)) > .oxq-tree-item-action {
      opacity: 0;
    }

    .oxq-tree-item:where(:hover:not([aria-disabled='true'])) {
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-tree-item:where([data-size='md']) {
    --_strong: var(--oxq-body-md-font-weight-strong);

    min-block-size: var(--oxq-size-control-md);
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);

    & > :is(.oxq-tree-item-index, .oxq-tree-item-code) {
      font: var(--oxq-font-code-md);
      letter-spacing: var(--oxq-code-md-letter-spacing);
    }
  }

  .oxq-tree-item:where([data-highlighted]) {
    --_bg: var(--oxq-info-surface-canvas);
  }

  .oxq-tree-item:where([aria-selected='true']) {
    --_bg: var(--oxq-brand-surface-soft);

    & > .oxq-tree-item-label {
      font-weight: var(--_strong);
    }
  }

  .oxq-tree-item:where([aria-disabled='true']) {
    cursor: not-allowed;
    transition: none;

    &,
    & > .oxq-tree-item-index {
      color: var(--oxq-neutral-text-muted);
    }

    & > .oxq-icon {
      color: var(--oxq-neutral-icon-muted);
    }

    &[aria-expanded] > .oxq-icon:first-child {
      cursor: not-allowed;
    }
  }
}
/* Pagination (Molecules › Pagination): indietro, l'intervallo corrente e avanti, con un'azione facoltativa dopo il
   divider. Prop Figma → data-size (sm | md), data-surface (flat | floating); position spegne indietro o avanti.
   - indietro, avanti e l'azione sono icon-button ghost della stessa size; l'intervallo è un testo label, non si clicca
   - flat senza fondo, dentro tabelle e liste; floating una pillola neutral/surface/raised con elevation/2
   - il divider è alto quanto il testo: 16 in sm, 20 in md */
@layer components {
  .oxq-pagination {
    --_line: var(--oxq-label-sm-line-height);

    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;

    & > .oxq-divider {
      align-self: center;
      block-size: var(--_line);
    }
  }

  .oxq-pagination:where([data-size='md']) {
    --_line: var(--oxq-label-md-line-height);

    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-pagination:where([data-surface='floating']) {
    padding: var(--oxq-space-gap-2xs);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-2);
  }
}
/* Toolbar (Molecules › Toolbar): la barra di azioni di una vista, role=toolbar. Prop Figma → data-variant (docked |
   floating), aria-orientation, data-align (start | center | end | space-between), data-size (sm | md).
   - docked attaccata al contenuto che comanda, larga quanto lui, col filo sul lato interno (sotto, o a destra in
     vertical); floating sospesa, a pillola con line/popover ed elevation/2
   - controlli compatti della stessa size della toolbar: icon-button ghost, button ghost, switch, divider
   - toolbar-group: da 2 a 4 controlli affini, più vicini fra loro (gap 2xs) che fra un gruppo e l'altro (gap xs)
   - il divider è lungo quanto l'icona della size: 16 in sm, 20 in md */
@layer components {
  .oxq-toolbar {
    --_divider: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    /* Il filo sta dentro la toolbar, come in Figma: il padding di quel lato lo sconta. */
    padding: var(--oxq-space-inset-toolbar-y) var(--oxq-space-inset-item-x)
      calc(var(--oxq-space-inset-toolbar-y) - var(--oxq-stroke-divider));
    border-block-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-border);
    background-color: var(--oxq-neutral-surface-raised);
    color: var(--oxq-neutral-text-ink);

    & .oxq-divider {
      align-self: center;
      block-size: var(--_divider);
    }
  }

  .oxq-toolbar-group {
    display: flex;
    flex-direction: inherit;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-toolbar:where([data-size='md']) {
    --_divider: var(--oxq-size-icon-md);
  }

  .oxq-toolbar:where([data-align='center']) {
    justify-content: center;
  }

  .oxq-toolbar:where([data-align='end']) {
    justify-content: flex-end;
  }

  .oxq-toolbar:where([data-align='space-between']) {
    justify-content: space-between;
  }

  .oxq-toolbar:where([aria-orientation='vertical']) {
    flex-direction: column;
    inline-size: fit-content;
    padding: var(--oxq-space-inset-item-x) calc(var(--oxq-space-inset-toolbar-y) - var(--oxq-stroke-divider))
      var(--oxq-space-inset-item-x) var(--oxq-space-inset-toolbar-y);
    border-block-end: 0;
    border-inline-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-border);

    & .oxq-divider {
      inline-size: var(--_divider);
      block-size: var(--oxq-stroke-divider);
    }
  }

  .oxq-toolbar:where([data-variant='floating']) {
    display: inline-flex;
    padding: calc(var(--oxq-space-inset-toolbar-y) - var(--oxq-stroke-control))
      calc(var(--oxq-space-inset-item-x) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-pill);
    box-shadow: var(--oxq-elevation-2);
  }

  .oxq-toolbar:where([data-variant='floating'][aria-orientation='vertical']) {
    padding: calc(var(--oxq-space-inset-item-x) - var(--oxq-stroke-control))
      calc(var(--oxq-space-inset-toolbar-y) - var(--oxq-stroke-control));
  }
}
/* Menu item (Atoms › Menu item): la riga di un menu di azioni, role=menuitem. Ogni voce fa una cosa e la fa subito;
   per scegliere un valore c'è il dropdown. Prop Figma → data-size, data-tone (neutral | danger).
   - icona opzionale a sinistra (tutte le voci o nessuna), label su una riga, description sotto; a destra la
     scorciatoia o la freccia del sottomenu, mai insieme
   - hover system/state/hover, pressed system/state/pressed; danger ha il fondo danger/surface/canvas
   - active (Figma) è la voce evidenziata da tastiera: il fondo di hover e la label in grassetto, senza anello
   - disabled: resta visibile, spenta in neutral anche se danger, senza hover né focus
   Menu label: il titolo di un gruppo di voci, non cliccabile. Il pannello che le contiene è il menu. */
@layer components {
  .oxq-menu-item {
    --_icon-size: var(--oxq-size-icon-sm);
    --_strong: var(--oxq-body-sm-font-weight-strong);
    --_bg-active: transparent;
    --_overlay-active: var(--oxq-system-state-hover);
    --_bg: transparent;
    --_overlay: transparent;

    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    inline-size: 100%;
    margin: 0;
    padding: var(--oxq-space-gap-xs) var(--oxq-space-inset-item-y);
    border: 0;
    border-radius: var(--oxq-radius-item);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-tone-text-ink);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    text-align: start;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--oxq-tone-icon-ink);
    }

    /* La freccia del sottomenu, a destra. */
    & > .oxq-menu-item-text ~ .oxq-icon {
      color: var(--oxq-tone-icon-secondary);
    }
  }

  .oxq-menu-item-text {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-inline-size: 0;
  }

  /* Una riga sola: se non sta, si accorcia. */
  .oxq-menu-item-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-menu-item-description,
  .oxq-menu-item-shortcut {
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-menu-item-shortcut {
    flex-shrink: 0;
    white-space: nowrap;
  }

  .oxq-menu-item:where([data-size='md']) {
    --_strong: var(--oxq-body-md-font-weight-strong);

    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);

    & > .oxq-menu-item-text > .oxq-menu-item-description {
      font: var(--oxq-font-body-sm);
      letter-spacing: var(--oxq-body-sm-letter-spacing);
    }
  }

  .oxq-menu-item:where([data-size='lg']) {
    --_icon-size: var(--oxq-size-icon-md);
    --_strong: var(--oxq-body-lg-font-weight-strong);

    font: var(--oxq-font-body-lg);
    letter-spacing: var(--oxq-body-lg-letter-spacing);

    & > .oxq-menu-item-text > .oxq-menu-item-description {
      font: var(--oxq-font-body-md);
      letter-spacing: var(--oxq-body-md-letter-spacing);
    }

    & > .oxq-menu-item-shortcut {
      font: var(--oxq-font-body-sm);
      letter-spacing: var(--oxq-body-sm-letter-spacing);
    }
  }

  /* danger: hover e active col fondo danger/surface/canvas invece dell'overlay. */
  .oxq-menu-item:where([data-tone='danger']) {
    --_bg-active: var(--oxq-tone-surface-canvas);
    --_overlay-active: transparent;
  }

  @media (hover: hover) {
    .oxq-menu-item:where(:hover:not(:disabled, [aria-disabled='true'])) {
      --_bg: var(--_bg-active);
      --_overlay: var(--_overlay-active);
    }
  }

  .oxq-menu-item:where(:focus-visible) {
    --_bg: var(--_bg-active);
    --_overlay: var(--_overlay-active);

    outline: none;

    & > .oxq-menu-item-text > .oxq-menu-item-label {
      font-weight: var(--_strong);
    }
  }

  .oxq-menu-item:where(:active:not(:disabled, [aria-disabled='true'])) {
    --_bg: var(--_bg-active);
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-menu-item:where(:disabled, [aria-disabled='true']) {
    cursor: not-allowed;
    transition: none;

    &,
    & > .oxq-menu-item-text > .oxq-menu-item-description,
    & > .oxq-menu-item-shortcut {
      color: var(--oxq-neutral-text-muted);
    }

    & > .oxq-icon,
    & > .oxq-menu-item-text ~ .oxq-icon {
      color: var(--oxq-neutral-icon-muted);
    }
  }

  .oxq-menu-label {
    padding: var(--oxq-space-gap-xs) var(--oxq-space-inset-item-x) var(--oxq-space-gap-2xs);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-label-sm);
    font-weight: var(--oxq-label-sm-font-weight-strong);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-menu-label:where([data-size='lg']) {
    font: var(--oxq-font-label-md);
    font-weight: var(--oxq-label-md-font-weight-strong);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }
}
/* Menu (Molecules › Menu): il pannello di azioni su un elemento o su una selezione, role=menu. Voci menu-item,
   gruppi separati da menu-divider; le azioni distruttive in fondo, dopo un filo. Fino a 7 voci, un solo livello di
   sottomenu. La size è quella delle voci: il pannello è uguale in sm, md e lg.
   È un popover: sta sopra tutto (anche dentro una tabella con overflow nascosto) e si chiude con Esc o con un clic
   fuori, dal browser. Si ancora al trigger (popovertarget): sotto, allineato al suo bordo, sopra solo se sotto non
   c'è spazio; il sottomenu (data-submenu) a destra della sua voce. Dove l'anchor positioning non c'è, il browser
   lo mette al centro. Senza l'attributo popover è un pannello fermo, per le pagine di documentazione.
   Frecce, Invio, la voce scelta e il focus li gestiscono OxqMenu e, in Django, oxq.js. */
@layer components {
  .oxq-menu {
    box-sizing: border-box;
    inline-size: var(--oxq-size-menu);
    padding: var(--oxq-space-gap-xs);
    overflow: visible;
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-2);
    color: var(--oxq-neutral-text-ink);
  }

  /* display solo da aperto: chiuso il popover resta display: none, come lo vuole il browser. */
  .oxq-menu:where(:not([popover]), :popover-open),
  .oxq-menu > [role='group'] {
    display: grid;
    gap: var(--oxq-space-inset-track);
  }

  /* Compare in dissolvenza e sparisce allo stesso modo, restando nel top layer finché sfuma. */
  .oxq-menu:where([popover]) {
    transition-behavior: allow-discrete;
    transition-property: opacity, display, overlay;
    transition-duration: var(--oxq-duration-open);
    transition-timing-function: var(--oxq-easing-transition);

    @starting-style {
      opacity: 0;
    }
  }

  .oxq-menu:where([popover]:not(:popover-open)) {
    opacity: 0;
  }

  @supports (position-area: block-end) {
    .oxq-menu:where([popover]) {
      inset: auto;
      margin: var(--oxq-space-gap-2xs) 0 0;
      position-area: block-end span-inline-end;
      position-try-fallbacks:
        flip-block,
        flip-inline,
        flip-block flip-inline;
    }

    /* Il sottomenu a destra della voce, con la prima voce alla sua altezza. */
    .oxq-menu:where([popover][data-submenu]) {
      margin: calc(-1 * (var(--oxq-space-gap-xs) + var(--oxq-stroke-control))) 0 0 var(--oxq-space-gap-2xs);
      position-area: inline-end span-block-end;
    }
  }

  .oxq-menu-divider {
    padding: var(--oxq-space-gap-2xs) var(--oxq-space-inset-item-x);

    &::before {
      content: '';
      display: block;
      border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    }
  }
}
/* Caret e streaming cursor (Atoms › Caret, Atoms › Streaming cursor): barre in fondo al testo che si scrive o che
   arriva. Decorativi (aria-hidden): il testo si legge da solo. Alti un'interlinea del testo in cui stanno, come la
   line-height di body/md nel DS. I variant di Figma (visible e hidden; ink, secondary e brand) sono i fotogrammi
   dell'animazione, non prop.
   - caret: per mockup e animazioni di scrittura, lampeggia ogni duration/blink. Nei campi veri c'è quello del browser.
   - streaming-cursor: la firma di OXQ alla fine del testo che arriva; resta acceso e ogni duration/blink cambia
     colore, inchiostro, grigio, rosso. */
@layer components {
  .oxq-caret,
  .oxq-streaming-cursor {
    display: inline-block;
    flex-shrink: 0;
    block-size: 1lh;
    vertical-align: top;
    animation-timing-function: var(--oxq-easing-blink);
    animation-iteration-count: infinite;
  }

  .oxq-caret {
    inline-size: var(--oxq-size-caret-width);
    background-color: var(--oxq-neutral-icon-ink);
    animation-name: oxq-blink;
    /* Un ciclo è acceso e spento, mezzo ciclo ciascuno. */
    animation-duration: calc(2 * var(--oxq-duration-blink));
  }

  .oxq-streaming-cursor {
    inline-size: var(--oxq-size-streaming-cursor-width);
    background-color: var(--oxq-neutral-icon-ink);
    animation-name: oxq-stream;
    animation-duration: calc(3 * var(--oxq-duration-blink));
  }
}

@keyframes oxq-blink {
  50% {
    opacity: 0;
  }
}

@keyframes oxq-stream {
  33.333% {
    background-color: var(--oxq-neutral-icon-secondary);
  }

  66.667% {
    background-color: var(--oxq-brand-surface-solid);
  }
}
/* Checkbox (Atoms › Checkbox): una scelta sì/no, o più voci di un elenco. Label e helper fanno parte del component.
   Prop Figma → attributi: data-size, data-status (error). value (checked, indeterminate), hover, focus e disabled
   li decide il browser: il box è l'input nativo (appearance: none), check e minus gli stanno sopra senza prendere
   i clic. Il focus ring è quello di base.css: 2 px a 2 px dal box, col suo raggio.
   Il campo segue il tone del contenitore, come l'input field; error usa danger. */
@layer components {
  .oxq-checkbox {
    --_box: var(--oxq-size-icon-sm);
    --_line: var(--oxq-body-sm-line-height);
    --_state: transparent;
    --_bg: var(--oxq-tone-surface-sunken);
    --_border: var(--oxq-tone-line-control);
    --_border-hover: var(--oxq-neutral-line-control-hover);
    --_solid: var(--oxq-tone-surface-solid);
    --_solid-hover: var(--oxq-tone-surface-solid-hover);
    --_mark: var(--oxq-tone-icon-on-ink);
    --_fg: var(--oxq-tone-text-ink);

    display: flex;
    align-items: flex-start;
    gap: var(--oxq-space-gap-xs);
    color: var(--_fg);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* Il controllo è alto una riga della label: il box resta allineato alla prima riga. */
  .oxq-checkbox-control {
    --_icon-size: var(--_box);

    display: grid;
    flex-shrink: 0;
    place-items: center;
    inline-size: var(--_box);
    block-size: var(--_line);

    & > * {
      grid-area: 1 / 1;
    }

    /* --_overlay è registrata senza ereditarietà (button.css): l'input la prende da --_state del contenitore. */
    & > input {
      --_overlay: var(--_state);

      box-sizing: border-box;
      inline-size: var(--_box);
      block-size: var(--_box);
      margin: 0;
      border: var(--oxq-stroke-control) solid var(--_border);
      border-radius: var(--oxq-radius-selection);
      background-color: var(--_bg);
      background-image: linear-gradient(var(--_overlay), var(--_overlay));
      appearance: none;
      cursor: pointer;
      transition-property: background-color, border-color, --_overlay;
      transition-duration: var(--oxq-duration-state);
      transition-timing-function: var(--oxq-easing-transition);
    }

    /* check e minus: il primo per checked, il secondo per indeterminate, che vince su checked. */
    & > .oxq-icon {
      color: var(--_mark);
      opacity: 0;
      pointer-events: none;
      transition-property: opacity, color;
      transition-duration: var(--oxq-duration-state);
      transition-timing-function: var(--oxq-easing-transition);
    }

    & > :where(input:checked:not(:indeterminate)) + .oxq-icon,
    & > :where(input:indeterminate) + .oxq-icon + .oxq-icon {
      opacity: 1;
    }
  }

  .oxq-checkbox-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-checkbox-label {
    cursor: pointer;
  }

  .oxq-checkbox-helper {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    margin: 0;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-checkbox:where([data-size='md']) {
    --_box: var(--oxq-size-icon-md);
    --_line: var(--oxq-body-md-line-height);

    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-checkbox:where([data-size='lg']) {
    --_box: var(--oxq-size-icon-lg);
    --_line: var(--oxq-body-lg-line-height);

    font: var(--oxq-font-body-lg);
    letter-spacing: var(--oxq-body-lg-letter-spacing);
  }

  .oxq-checkbox:where([data-size='md'], [data-size='lg']) .oxq-checkbox-helper {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* Error: bordo danger da vuoto, danger solid da selezionato, icona e messaggio nell'helper.
     Sta prima di hover, che cambia solo i valori «-hover» e l'overlay. */
  .oxq-checkbox:where([data-status='error']) {
    --_border: var(--oxq-danger-line-border-strong);
    --_border-hover: var(--oxq-danger-line-border-strong);
    --_solid: var(--oxq-danger-surface-solid);
    --_solid-hover: var(--oxq-danger-surface-solid-hover);
    --_mark: var(--oxq-danger-icon-on-ink);

    & .oxq-checkbox-helper {
      color: var(--oxq-danger-text-secondary);

      & > .oxq-icon {
        color: var(--oxq-danger-icon-secondary);
      }
    }
  }

  /* Hover, sul box o sulla label: da vuoto l'overlay system/state/hover e il bordo line/control-hover,
     da selezionato surface/solid-hover. */
  @media (hover: hover) {
    .oxq-checkbox:where(:has(> .oxq-checkbox-control > input:hover, .oxq-checkbox-label:hover)) {
      --_state: var(--oxq-system-state-hover);
      --_border: var(--_border-hover);
      --_solid: var(--_solid-hover);
    }
  }

  .oxq-checkbox:where(:has(> .oxq-checkbox-control > input:is(:checked, :indeterminate))) {
    --_bg: var(--_solid);
    --_border: transparent;
    --_state: transparent;
  }

  /* Disabled: fondo control-disabled col bordo anche da selezionato, tutto in muted, senza hover. */
  .oxq-checkbox:where(:has(> .oxq-checkbox-control > input:disabled)) {
    --_state: transparent;
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: var(--oxq-tone-line-border);
    --_mark: var(--oxq-tone-icon-muted);
    --_fg: var(--oxq-tone-text-muted);

    & :is(input, .oxq-checkbox-label) {
      cursor: not-allowed;
    }

    & input {
      transition: none;
    }

    & .oxq-checkbox-helper {
      color: var(--oxq-tone-text-muted);
    }
  }
}
/* Radio button e radio-group (Atoms › Radio button): una sola scelta fra opzioni che si vedono tutte.
   Radio: data-size; checked, hover, pressed, focus e disabled li decide il browser sull'input nativo
   (appearance: none), col punto sopra senza prendere i clic. Il focus ring è quello di base.css.
   error e read-only sono data-status e data-readonly del radio: il radio-group li passa a ogni opzione.
   Pieno di brand da selezionato (Radio button › Regole d'uso); il resto segue il tone del contenitore.
   Radio-group: un <fieldset> con legend, opzioni e helper; data-size, data-orientation, data-status. */
@layer components {
  .oxq-radio {
    --_box: var(--oxq-size-icon-sm);
    --_line: var(--oxq-body-sm-line-height);
    --_dot: var(--oxq-size-dot-sm);
    --_state: transparent;
    --_bg: var(--oxq-tone-surface-raised);
    --_border: var(--oxq-tone-line-control);
    --_border-hover: var(--oxq-neutral-line-control-hover);
    --_solid: var(--oxq-brand-surface-solid);
    --_dot-color: var(--oxq-brand-icon-on-solid);
    --_fg: var(--oxq-tone-text-ink);
    --_fg-secondary: var(--oxq-tone-text-secondary);
    --_cursor: pointer;

    display: flex;
    align-items: flex-start;
    gap: var(--oxq-space-gap-xs);
    color: var(--_fg);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* Il controllo è alto una riga della label: il cerchio resta allineato alla prima riga. */
  .oxq-radio-control {
    display: grid;
    flex-shrink: 0;
    place-items: center;
    inline-size: var(--_box);
    block-size: var(--_line);

    & > * {
      grid-area: 1 / 1;
    }

    /* --_overlay è registrata senza ereditarietà (button.css): l'input la prende da --_state del radio. */
    & > input {
      --_overlay: var(--_state);

      box-sizing: border-box;
      inline-size: var(--_box);
      block-size: var(--_box);
      margin: 0;
      border: var(--oxq-stroke-control) solid var(--_border);
      border-radius: var(--oxq-radius-pill);
      background-color: var(--_bg);
      background-image: linear-gradient(var(--_overlay), var(--_overlay));
      appearance: none;
      cursor: var(--_cursor);
      transition-property: background-color, border-color, --_overlay;
      transition-duration: var(--oxq-duration-state);
      transition-timing-function: var(--oxq-easing-transition);
    }
  }

  .oxq-radio-dot {
    inline-size: var(--_dot);
    block-size: var(--_dot);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_dot-color);
    opacity: 0;
    pointer-events: none;
    transition-property: opacity, background-color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  .oxq-radio-control > :where(input:checked) + .oxq-radio-dot {
    opacity: 1;
  }

  .oxq-radio-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-radio-label {
    cursor: var(--_cursor);
  }

  .oxq-radio-helper {
    margin: 0;
    color: var(--_fg-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-radio:where([data-size='md']) {
    --_box: var(--oxq-size-icon-md);
    --_line: var(--oxq-body-md-line-height);
    --_dot: var(--oxq-size-dot-md);

    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-radio:where([data-size='lg']) {
    --_box: var(--oxq-size-icon-lg);
    --_line: var(--oxq-body-lg-line-height);
    --_dot: var(--oxq-size-dot-lg);

    gap: var(--oxq-space-gap-sm);

    font: var(--oxq-font-body-lg);
    letter-spacing: var(--oxq-body-lg-letter-spacing);
  }

  .oxq-radio:where([data-size='md'], [data-size='lg']) .oxq-radio-helper {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* Hover e pressed, sul cerchio o sulla label: da vuoto l'overlay e il bordo line/control-hover,
     da selezionato brand solid-hover e solid-pressed. */
  @media (hover: hover) {
    .oxq-radio:where(:has(> .oxq-radio-control > input:hover, .oxq-radio-label:hover)) {
      --_state: var(--oxq-system-state-hover);
      --_border: var(--_border-hover);
      --_solid: var(--oxq-brand-surface-solid-hover);
    }
  }

  .oxq-radio:where(:has(> .oxq-radio-control > input:active, .oxq-radio-label:active)) {
    --_state: var(--oxq-system-state-pressed);
    --_border: var(--_border-hover);
    --_solid: var(--oxq-brand-surface-solid-pressed);
  }

  .oxq-radio:where(:has(> .oxq-radio-control > input:checked)) {
    --_bg: var(--_solid);
    --_border: transparent;
    --_state: transparent;
  }

  /* Error: bordo danger; da selezionato il cerchio resta chiaro e il punto diventa danger. */
  .oxq-radio:where([data-status='error']) {
    --_border: var(--oxq-danger-line-border-strong);
    --_border-hover: var(--oxq-danger-line-border-strong);
  }

  .oxq-radio:where([data-status='error']):where(:has(> .oxq-radio-control > input:checked)) {
    --_bg: var(--oxq-tone-surface-raised);
    --_border: var(--oxq-danger-line-border-strong);
    --_dot-color: var(--oxq-danger-surface-solid);
  }

  /* Disabled: fondo control-disabled col bordo, tutto in muted, senza hover né transizioni. */
  .oxq-radio:where(:has(> .oxq-radio-control > input:disabled)) {
    --_state: transparent;
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: var(--oxq-tone-line-border);
    --_dot-color: var(--oxq-tone-icon-muted);
    --_fg: var(--oxq-tone-text-muted);
    --_fg-secondary: var(--oxq-tone-text-muted);
    --_cursor: not-allowed;

    & input {
      transition: none;
    }
  }

  /* Read-only: si legge ma non si cambia. Le opzioni non scelte sono disabled (l'input nativo non ha
     readonly), quella scelta resta focalizzabile e si invia; l'aspetto è uno solo, senza muted. */
  .oxq-radio:where([data-readonly]) {
    --_state: transparent;
    --_bg: transparent;
    --_border: var(--oxq-tone-line-border);
    --_dot-color: var(--oxq-tone-icon-ink);
    --_fg: var(--oxq-tone-text-ink);
    --_fg-secondary: var(--oxq-tone-text-secondary);
    --_cursor: default;
  }

  /* Radio-group. Il legend flotta: così è un elemento del flex del fieldset e prende il gap. */
  .oxq-radio-group {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
    min-inline-size: 0;
  }

  .oxq-radio-group-legend {
    float: inline-start;
    inline-size: 100%;
    color: var(--oxq-tone-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-radio-group-options {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
  }

  /* horizontal per 2–3 opzioni corte; su uno schermo stretto vanno a capo. */
  .oxq-radio-group:where([data-orientation='horizontal']) > .oxq-radio-group-options {
    flex-flow: row wrap;
    column-gap: var(--oxq-space-gap-lg);
  }

  .oxq-radio-group-helper {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    margin: 0;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-radio-group:where([data-size='md']) > .oxq-radio-group-legend {
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-radio-group:where([data-size='lg']) > .oxq-radio-group-legend {
    font: var(--oxq-font-label-lg);
    letter-spacing: var(--oxq-label-lg-letter-spacing);
  }

  .oxq-radio-group:where([data-size='md'], [data-size='lg']) > .oxq-radio-group-helper {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-radio-group:where([data-status='error']) > .oxq-radio-group-helper {
    color: var(--oxq-danger-text-secondary);

    & > .oxq-icon {
      color: var(--oxq-danger-icon-secondary);
    }
  }

  /* Un fieldset disabled spegne tutti gli input che contiene: legend e helper passano a muted. */
  .oxq-radio-group:where(:disabled) > :is(.oxq-radio-group-legend, .oxq-radio-group-helper) {
    color: var(--oxq-tone-text-muted);
  }
}
/* Switch (Atoms › Switch): on/off con effetto immediato, senza invio. Per una scelta che vale quando si
   invia il form c'è il checkbox. Un solo on, il rosso di brand.
   Prop Figma → attributi: data-size, data-label-position (start | end). checked, hover, pressed, focus e
   disabled li decide il browser: il track è l'input nativo (checkbox con role="switch", appearance: none),
   il thumb gli sta sopra senza prendere i clic e scorre con translate. Il focus ring è quello di base.css. */
@layer components {
  .oxq-switch {
    --_w: var(--oxq-size-switch-width-sm);
    --_h: var(--oxq-size-switch-height-sm);
    --_thumb: var(--oxq-size-icon-sm);
    --_state: transparent;
    --_bg: var(--oxq-tone-surface-control);
    --_border: var(--oxq-tone-line-control);
    --_solid: var(--oxq-brand-surface-solid);
    --_thumb-bg: var(--oxq-neutral-surface-thumb);
    --_thumb-border: var(--oxq-tone-line-control);
    --_thumb-x: 0;
    --_fg: var(--oxq-tone-text-ink);
    --_cursor: pointer;

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    color: var(--_fg);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-switch-control {
    display: grid;
    flex-shrink: 0;
    place-items: center start;
    inline-size: var(--_w);
    block-size: var(--_h);

    & > * {
      grid-area: 1 / 1;
    }

    /* --_overlay è registrata senza ereditarietà (button.css): l'input la prende da --_state dello switch. */
    & > input {
      --_overlay: var(--_state);

      box-sizing: border-box;
      inline-size: var(--_w);
      block-size: var(--_h);
      margin: 0;
      border: var(--oxq-stroke-control) solid var(--_border);
      border-radius: var(--oxq-radius-pill);
      background-color: var(--_bg);
      background-image: linear-gradient(var(--_overlay), var(--_overlay));
      appearance: none;
      cursor: var(--_cursor);
      transition-property: background-color, border-color, --_overlay;
      transition-duration: var(--oxq-duration-state);
      transition-timing-function: var(--oxq-easing-transition);
    }
  }

  /* Il thumb sta a space/inset/track dal bordo del track; da on scorre fino all'altro lato. */
  .oxq-switch-thumb {
    box-sizing: border-box;
    inline-size: var(--_thumb);
    block-size: var(--_thumb);
    margin-inline-start: var(--oxq-space-inset-track);
    border: var(--oxq-stroke-control) solid var(--_thumb-border);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_thumb-bg);
    pointer-events: none;
    translate: var(--_thumb-x) 0;
    transition-property: translate, background-color, border-color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  .oxq-switch-label {
    cursor: var(--_cursor);
  }

  .oxq-switch:where([data-label-position='start']) > .oxq-switch-label {
    order: -1;
  }

  .oxq-switch:where([data-size='md']) {
    --_w: var(--oxq-size-switch-width-md);
    --_h: var(--oxq-size-switch-height-md);
    --_thumb: var(--oxq-size-icon-md);

    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-switch:where([data-size='lg']) {
    --_w: var(--oxq-size-switch-width-lg);
    --_h: var(--oxq-size-switch-height-lg);
    --_thumb: var(--oxq-size-icon-lg);

    gap: var(--oxq-space-gap-sm);
    font: var(--oxq-font-body-lg);
    letter-spacing: var(--oxq-body-lg-letter-spacing);
  }

  /* Hover e pressed, sul track o sulla label: da off l'overlay (col bordo line/control-hover solo in hover),
     da on brand solid-hover e solid-pressed. */
  @media (hover: hover) {
    .oxq-switch:where(:has(> .oxq-switch-control > input:hover, > .oxq-switch-label:hover)) {
      --_state: var(--oxq-system-state-hover);
      --_border: var(--oxq-neutral-line-control-hover);
      --_solid: var(--oxq-brand-surface-solid-hover);
    }
  }

  .oxq-switch:where(:has(> .oxq-switch-control > input:active, > .oxq-switch-label:active)) {
    --_state: var(--oxq-system-state-pressed);
    --_border: var(--oxq-tone-line-control);
    --_solid: var(--oxq-brand-surface-solid-pressed);
  }

  .oxq-switch:where(:has(> .oxq-switch-control > input:checked)) {
    --_state: transparent;
    --_bg: var(--_solid);
    --_border: transparent;
    --_thumb-bg: var(--oxq-brand-icon-on-solid);
    --_thumb-border: transparent;
    --_thumb-x: calc(var(--_w) - var(--_thumb) - 2 * var(--oxq-space-inset-track));
  }

  /* Disabled: da off control-disabled col bordo e thumb muted; da on i token disabled di brand
     (quelli di danger, come nel tone brand di tokens.css). Label muted, senza hover né transizioni. */
  .oxq-switch:where(:has(> .oxq-switch-control > input:disabled)) {
    --_state: transparent;
    --_bg: var(--oxq-tone-surface-control-disabled);
    --_border: var(--oxq-tone-line-border);
    --_thumb-bg: var(--oxq-tone-icon-muted);
    --_thumb-border: transparent;
    --_fg: var(--oxq-tone-text-muted);
    --_cursor: not-allowed;

    & :is(input, .oxq-switch-thumb) {
      transition: none;
    }
  }

  .oxq-switch:where(:has(> .oxq-switch-control > input:disabled:checked)) {
    --_bg: var(--oxq-danger-surface-control-disabled);
    --_border: transparent;
    --_thumb-bg: var(--oxq-danger-icon-muted);
  }
}
/* Progress bar (Atoms › Progress bar): avanzamento di un'operazione. Label e valore sopra, helper sotto.
   Prop Figma → attributi: data-size, data-color (neutral | brand | yellow | green | blue | violet | magenta).
   Il valore arriva dal markup come --oxq-value sul track (style="--oxq-value: 50%"), insieme ad aria-valuenow;
   senza, la barra è indeterminate: un tratto che scorre a velocità costante, fermo con reduced motion.
   Il fill occupa tutto il track e trasla: la punta resta intera e l'avanzamento si anima con transform.
   color non ha significato (accent/*): per uno stato si scrive nel testo. */
@layer components {
  .oxq-progress {
    --_h: var(--oxq-size-progress-sm);
    --_fill: var(--oxq-neutral-surface-solid);
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
    min-inline-size: 0;
  }

  .oxq-progress-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-progress-label {
    min-inline-size: 0;
    color: var(--oxq-tone-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-progress-meta {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    margin-inline-start: auto;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
    font-variant-numeric: tabular-nums;

    & > .oxq-icon {
      color: var(--oxq-tone-icon-secondary);
    }
  }

  .oxq-progress-track {
    overflow: hidden;
    block-size: var(--_h);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-muted);
  }

  /* La punta è la metà dell'altezza, a destra; l'estremo sinistro lo arrotonda il track. */
  .oxq-progress-fill {
    block-size: 100%;
    background-color: var(--_fill);
    clip-path: polygon(0 0, calc(100% - var(--_h) / 2) 0, 100% 50%, calc(100% - var(--_h) / 2) 100%, 0 100%);
    translate: calc(var(--oxq-value, 0%) - 100%) 0;
    transition: translate var(--oxq-duration-open) var(--oxq-easing-transition);
  }

  /* Indeterminate: un tratto di 2/5 del track che lo attraversa. Fermo (reduced motion) resta dove lo
     disegna Figma, a 3/20 dall'inizio. */
  .oxq-progress-track:not([aria-valuenow]) > .oxq-progress-fill {
    inline-size: 40%;
    translate: 37.5% 0;
    transition: none;
    animation: oxq-progress-indeterminate var(--oxq-duration-shimmer) var(--oxq-easing-loop) infinite;
  }

  .oxq-progress-helper {
    margin: 0;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-progress:where([data-size='md']) {
    --_h: var(--oxq-size-progress-md);

    & .oxq-progress-label {
      font: var(--oxq-font-label-md);
      letter-spacing: var(--oxq-label-md-letter-spacing);
    }

    & :is(.oxq-progress-meta, .oxq-progress-helper) {
      font: var(--oxq-font-body-sm);
      letter-spacing: var(--oxq-body-sm-letter-spacing);
    }
  }

  .oxq-progress:where([data-size='lg']) {
    --_h: var(--oxq-size-progress-lg);
    --_icon-size: var(--oxq-size-icon-md);

    & .oxq-progress-label {
      font: var(--oxq-font-label-lg);
      letter-spacing: var(--oxq-label-lg-letter-spacing);
    }

    & .oxq-progress-meta {
      font: var(--oxq-font-body-md);
      letter-spacing: var(--oxq-body-md-letter-spacing);
    }

    & .oxq-progress-helper {
      font: var(--oxq-font-body-sm);
      letter-spacing: var(--oxq-body-sm-letter-spacing);
    }
  }

  .oxq-progress:where([data-color='brand']) {
    --_fill: var(--oxq-brand-surface-solid);
  }

  .oxq-progress:where([data-color='yellow']) {
    --_fill: var(--oxq-accent-yellow-surface-solid);
  }

  .oxq-progress:where([data-color='green']) {
    --_fill: var(--oxq-accent-green-surface-solid);
  }

  .oxq-progress:where([data-color='blue']) {
    --_fill: var(--oxq-accent-blue-surface-solid);
  }

  .oxq-progress:where([data-color='violet']) {
    --_fill: var(--oxq-accent-violet-surface-solid);
  }

  .oxq-progress:where([data-color='magenta']) {
    --_fill: var(--oxq-accent-magenta-surface-solid);
  }
}

@keyframes oxq-progress-indeterminate {
  from {
    translate: -100% 0;
  }

  to {
    translate: 250% 0;
  }
}
/* Meter e segmented-meter (Atoms › Meter): un valore noto in un intervallo, come lo spazio usato o la
   sicurezza di una password. Per l'avanzamento c'è la progress bar. Label e valore sopra, sempre scritti;
   helper sotto. Prop Figma → attributi: data-size, data-color (neutral | brand | yellow | green | blue |
   violet | magenta), senza significato: per uno stato si scrive nel testo.
   meter: il valore arriva come --oxq-value sul track (style="--oxq-value: 60%"), insieme ad aria-valuenow.
   segmented-meter: 4 segmenti, data-level (0–4) sul contenitore dei segmenti. */
@layer components {
  .oxq-meter {
    --_h: var(--oxq-size-meter-sm);
    --_fill: var(--oxq-neutral-surface-solid);
    --_track: var(--oxq-neutral-surface-muted);

    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
    min-inline-size: 0;
  }

  .oxq-meter-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--oxq-space-gap-xs);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-meter-label {
    min-inline-size: 0;
    color: var(--oxq-tone-text-ink);
  }

  .oxq-meter-value {
    flex-shrink: 0;
    margin-inline-start: auto;
    color: var(--oxq-tone-text-secondary);
    font-variant-numeric: tabular-nums;
  }

  .oxq-meter-track {
    block-size: var(--_h);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_track);
  }

  .oxq-meter-fill {
    inline-size: var(--oxq-value, 0%);
    block-size: 100%;
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_fill);
  }

  .oxq-meter-segments {
    display: flex;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-meter-segment {
    flex: 1;
    block-size: var(--_h);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_track);
  }

  .oxq-meter-segments:where([data-level='1']) > :nth-child(-n + 1),
  .oxq-meter-segments:where([data-level='2']) > :nth-child(-n + 2),
  .oxq-meter-segments:where([data-level='3']) > :nth-child(-n + 3),
  .oxq-meter-segments:where([data-level='4']) > * {
    background-color: var(--_fill);
  }

  .oxq-meter-helper {
    margin: 0;
    color: var(--oxq-tone-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-meter:where([data-size='md']) {
    --_h: var(--oxq-size-meter-md);

    & > .oxq-meter-header {
      font: var(--oxq-font-label-md);
      letter-spacing: var(--oxq-label-md-letter-spacing);
    }
  }

  .oxq-meter:where([data-size='lg']) {
    --_h: var(--oxq-size-meter-lg);

    & > .oxq-meter-header {
      font: var(--oxq-font-label-lg);
      letter-spacing: var(--oxq-label-lg-letter-spacing);
    }
  }

  .oxq-meter:where([data-size='md'], [data-size='lg']) > .oxq-meter-helper {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-meter:where([data-color='brand']) {
    --_fill: var(--oxq-brand-surface-solid);
  }

  .oxq-meter:where([data-color='yellow']) {
    --_fill: var(--oxq-accent-yellow-surface-solid);
  }

  .oxq-meter:where([data-color='green']) {
    --_fill: var(--oxq-accent-green-surface-solid);
  }

  .oxq-meter:where([data-color='blue']) {
    --_fill: var(--oxq-accent-blue-surface-solid);
  }

  .oxq-meter:where([data-color='violet']) {
    --_fill: var(--oxq-accent-violet-surface-solid);
  }

  .oxq-meter:where([data-color='magenta']) {
    --_fill: var(--oxq-accent-magenta-surface-solid);
  }
}
/* Listbox (Molecules › Listbox): il pannello di voci che apre un campo, il combobox o l'autocomplete. Nel combobox
   la search in cima, a fuoco appena si apre; le voci role=option, fino a 7 visibili e poi scorrono; il messaggio
   quando la ricerca non trova niente; un'azione sola in coda, dopo il filo. Prop Figma → data-size (quella del
   campo) e aria-multiselectable sull'elenco: single segna la scelta col check a destra su brand/surface/soft, multi
   con la checkbox a sinistra. La voce attiva da tastiera (data-active, aria-activedescendant) ha il fondo di hover.
   È un popover largo quanto il campo, a space/gap/2xs sotto: il campo ha anchor-name e il listbox position-anchor,
   col suo id nello style. Dove l'anchor positioning non c'è, il browser lo mette al centro.
   loading, more, label e footer del componente Figma arrivano con chi li usa (risultati dal server, filtri). */
@layer components {
  .oxq-listbox {
    --_height: var(--oxq-size-control-sm);
    --_check: var(--oxq-size-icon-sm);
    --_box: var(--oxq-size-icon-sm);
    --_line: var(--oxq-body-sm-line-height);
    --_font: var(--oxq-font-body-sm);
    --_letter-spacing: var(--oxq-body-sm-letter-spacing);
    --_count-font: var(--oxq-font-body-xs);
    --_count-letter-spacing: var(--oxq-body-xs-letter-spacing);

    box-sizing: border-box;
    inline-size: var(--oxq-size-menu);
    padding: var(--oxq-space-gap-2xs);
    overflow: visible;
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-2);
    color: var(--oxq-neutral-text-ink);
    font: var(--_font);
    letter-spacing: var(--_letter-spacing);
  }

  .oxq-listbox:where([data-size='md']) {
    --_height: var(--oxq-size-control-md);
    --_box: var(--oxq-size-icon-md);
    --_line: var(--oxq-body-md-line-height);
    --_font: var(--oxq-font-body-md);
    --_letter-spacing: var(--oxq-body-md-letter-spacing);
  }

  .oxq-listbox:where([data-size='lg']) {
    --_height: var(--oxq-size-control-lg);
    --_check: var(--oxq-size-icon-md);
    --_box: var(--oxq-size-icon-lg);
    --_line: var(--oxq-body-lg-line-height);
    --_font: var(--oxq-font-body-lg);
    --_letter-spacing: var(--oxq-body-lg-letter-spacing);
    --_count-font: var(--oxq-font-body-sm);
    --_count-letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  /* display solo da aperto: chiuso il popover resta display: none, come lo vuole il browser. */
  .oxq-listbox:where(:not([popover]), :popover-open) {
    display: grid;
    gap: var(--oxq-space-inset-track);
  }

  /* Compare in dissolvenza e sparisce allo stesso modo, come il menu. */
  .oxq-listbox:where([popover]) {
    transition-behavior: allow-discrete;
    transition-property: opacity, display, overlay;
    transition-duration: var(--oxq-duration-open);
    transition-timing-function: var(--oxq-easing-transition);

    @starting-style {
      opacity: 0;
    }
  }

  .oxq-listbox:where([popover]:not(:popover-open)) {
    opacity: 0;
  }

  @supports (position-area: block-end) {
    .oxq-listbox:where([popover]) {
      inline-size: anchor-size(inline);
      inset: auto;
      margin: var(--oxq-space-gap-2xs) 0 0;
      position-area: block-end span-inline-end;
      position-try-fallbacks: flip-block;
    }
  }

  /* Le voci: fino a 7 visibili, poi scorrono sotto la search, che resta ferma. */
  .oxq-listbox-options {
    display: grid;
    gap: var(--oxq-space-inset-track);
    max-block-size: calc(7 * var(--_height) + 6 * var(--oxq-space-inset-track));
    overflow-y: auto;
    outline: none;
    overscroll-behavior: contain;
  }

  /* _listbox-item: alto come il campo, la label su una riga. */
  .oxq-listbox-option {
    --_bg: transparent;
    --_overlay: transparent;
    --_fg: var(--oxq-neutral-text-ink);
    --_icon-size: var(--_check);

    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--_height);
    padding-inline: var(--oxq-space-inset-item-x);
    border-radius: var(--oxq-radius-item);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    /* Nell'autocomplete un risultato può essere un link. */
    text-decoration: none;
    cursor: pointer;
    transition-property: background-color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    /* Il check della scelta, a destra: si vede solo sulla voce scelta. */
    & > .oxq-icon {
      visibility: hidden;
      color: var(--oxq-neutral-icon-ink);
    }

    &:where([aria-selected='true']) > .oxq-icon {
      visibility: visible;
    }
  }

  .oxq-listbox-option-label {
    flex: 1;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* count: quante voci ha l'opzione. */
  .oxq-listbox-option-count {
    flex-shrink: 0;
    color: var(--oxq-neutral-text-secondary);
    font: var(--_count-font);
    letter-spacing: var(--_count-letter-spacing);
  }

  .oxq-listbox-option:where([data-active]) {
    --_overlay: var(--oxq-system-state-hover);
  }

  .oxq-listbox-options:where(:not([aria-multiselectable='true'])) > .oxq-listbox-option:where([aria-selected='true']) {
    --_bg: var(--oxq-brand-surface-soft);
  }

  /* multi: la checkbox a sinistra, disegnata come il checkbox (la voce è l'opzione, non un input). */
  .oxq-listbox-checkbox {
    --_icon-size: var(--_box);

    box-sizing: border-box;
    display: grid;
    flex-shrink: 0;
    place-items: center;
    inline-size: var(--_box);
    block-size: var(--_box);
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-control);
    border-radius: var(--oxq-radius-selection);
    background-color: var(--oxq-neutral-surface-sunken);
    color: var(--oxq-neutral-icon-on-ink);
    transition-property: background-color, border-color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      visibility: hidden;
    }
  }

  .oxq-listbox-option:where([data-active]) > .oxq-listbox-checkbox {
    border-color: var(--oxq-neutral-line-control-hover);
  }

  .oxq-listbox-option:where([aria-selected='true']) > .oxq-listbox-checkbox {
    border-color: transparent;
    background-color: var(--oxq-neutral-surface-solid);

    & > .oxq-icon {
      visibility: visible;
    }
  }

  /* disabled: resta visibile, spenta, e non si sceglie. */
  .oxq-listbox-option:where([aria-disabled='true']) {
    --_fg: var(--oxq-neutral-text-muted);
    --_overlay: transparent;

    cursor: not-allowed;

    & > .oxq-listbox-option-count {
      color: var(--oxq-neutral-text-muted);
    }

    & > .oxq-listbox-checkbox {
      border-color: var(--oxq-neutral-line-border);
      background-color: var(--oxq-neutral-surface-control-disabled);
    }
  }

  /* Senza risultati: il testo cercato fra « », al centro. */
  .oxq-listbox-empty {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    min-block-size: var(--_height);
    margin: 0;
    padding: var(--oxq-space-gap-md) var(--oxq-space-inset-item-x);
    color: var(--oxq-neutral-text-secondary);
    text-align: center;
  }

  /* L'azione in coda, dopo il filo: un link o un button, alto come una voce. */
  .oxq-listbox-action {
    --_overlay: transparent;

    box-sizing: border-box;
    display: flex;
    align-items: center;
    min-block-size: var(--_height);
    margin: 0;
    padding: 0 var(--oxq-space-inset-item-x);
    border: 0;
    border-radius: var(--oxq-radius-item);
    background-color: transparent;
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-neutral-text-secondary);
    font: inherit;
    letter-spacing: inherit;
    text-align: start;
    text-decoration: none;
    transition: --_overlay var(--oxq-duration-state) var(--oxq-easing-transition);

    &:focus-visible {
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }
  }

  @media (hover: hover) {
    .oxq-listbox-action:hover {
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-listbox-action:active {
    --_overlay: var(--oxq-system-state-pressed);
  }
}
/* Combobox (Molecules › Combobox): un campo che apre il listbox con la search, per scegliere da un elenco lungo
   cercando. È l'input field con un button al posto dell'input: label, box, helper, size, status, hover, focus e
   disabled sono di input-field.css. Il button prende tutto il box, così il campo intero apre il listbox; icon-start e
   chevron gli stanno sotto. Il valore è il testo del button: senza scelta è vuoto e mostra il placeholder.
   selection multi (data-multiple) mette le scelte in chip nel box, al massimo due, poi +N: i chip lasciano passare il
   clic al button, tranne la X che toglie la scelta. Aperto: l'anello di focus sul box e la chevron in su. */
@layer components {
  /* In una griglia il campo resta largo quanto la colonna: i chip si accorciano. */
  .oxq-combobox {
    min-inline-size: 0;
  }

  .oxq-combobox > .oxq-input-field-box {
    position: relative;
    cursor: pointer;

    /* Il button riempie il box (input-field.css) e col suo ::after ne copre tutta l'area. */
    & > .oxq-combobox-trigger {
      position: static;
      display: flex;
      align-items: center;
      cursor: inherit;
      text-align: start;

      &::after {
        inset: 0;
        translate: none;
        inline-size: auto;
        block-size: auto;
        border-radius: inherit;
      }
    }

    /* I chip stanno sopra il button ma il clic gli passa, tranne quello sulla X. */
    & > .oxq-chip {
      z-index: 1;
      flex-shrink: 1;
      min-inline-size: 0;
      pointer-events: none;

      & > button {
        pointer-events: auto;
      }
    }

    /* La chevron, sempre a destra. Da aperto punta in su. */
    & > .oxq-combobox-trigger ~ .oxq-icon {
      transition: rotate var(--oxq-duration-open) var(--oxq-easing-transition);
    }
  }

  /* La larghezza del campo non dipende dalla scelta: il valore non conta nella misura del box. */
  .oxq-combobox-value {
    flex: 1;
    min-inline-size: 0;
    contain: inline-size;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    /* Senza scelta il placeholder, in text/secondary. */
    &:empty::before {
      content: attr(data-placeholder);
      color: var(--_fg-secondary);
    }
  }

  /* multi: le scelte le mostrano i chip; il valore resta, nascosto, per il lettore di schermo. */
  .oxq-combobox:where([data-multiple]) .oxq-combobox-value:where(:not(:empty)) {
    clip-path: inset(50%);
  }

  /* +N: le scelte oltre i due chip. */
  .oxq-combobox-more {
    flex-shrink: 0;
    color: var(--_fg-secondary);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  /* Aperto: bordo e anello come in focus anche col mouse, chevron in su. */
  .oxq-combobox:where(:has(> .oxq-listbox:popover-open)) > .oxq-input-field-box {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: var(--oxq-offset-focus);

    & > .oxq-combobox-trigger ~ .oxq-icon {
      rotate: 0.5turn;
    }
  }
}
/* Breadcrumb (Molecules › Breadcrumb): il percorso sopra il titolo, dentro page-header. Mai nel contenuto.
   Prop Figma → attributi: data-type (trail | back) e data-size (sm | md) sulla radice.
   - trail: dal primo livello alla pagina corrente, al massimo 4. I livelli superiori sono link ghost neutral
     separati da chevron-right muted; la pagina corrente è l'ultima voce, in ink e strong, non link
   - back: un solo link di ritorno al livello superiore, con chevron-left, nelle pagine di dettaglio
   La size la dà il breadcrumb: le voci non la ripetono. md in page-header, sm nelle testate dense. */
@layer components {
  .oxq-breadcrumb {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-breadcrumb:where([data-size='md']) {
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-breadcrumb-list,
  .oxq-breadcrumb-item {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-breadcrumb-list {
    flex-wrap: wrap;
    list-style: none;
  }

  .oxq-breadcrumb .oxq-link {
    font: inherit;
    letter-spacing: inherit;
  }

  .oxq-breadcrumb-item > .oxq-icon {
    color: var(--oxq-neutral-icon-muted);
  }

  .oxq-breadcrumb-current {
    color: var(--oxq-neutral-text-ink);
    font-weight: var(--oxq-label-sm-font-weight-strong);
  }

  .oxq-breadcrumb:where([data-size='md']) .oxq-breadcrumb-current {
    font-weight: var(--oxq-label-md-font-weight-strong);
  }
}
/* Page header (Organisms › Page header): la testata della pagina, la prima zona sotto app-header, una per pagina.
   Sopra il titolo la navigazione (un breadcrumb trail o back), sotto la descrizione; le azioni a destra, che vanno
   a capo quando lo spazio non basta. Conteggi, KPI e filtri non stanno qui: vanno nelle zone sotto. */
@layer components {
  .oxq-page-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-page-header-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    align-self: stretch;
    gap: var(--oxq-space-gap-md);
  }

  .oxq-page-header-identity {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
  }

  .oxq-page-header-title {
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-heading-md);
    letter-spacing: var(--oxq-heading-md-letter-spacing);
  }

  .oxq-page-header-description {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-page-header-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }
}
/* Side nav (Organisms › Side nav), con nav-section e nav-item: la navigazione laterale.
   Prop Figma → attributi: data-type (global | local), data-collapsed e data-border (left | none; right, il default,
   non si scrive) sulla radice; data-size (sm | md) sulla nav-section, che vale per le sue voci; aria-current="page"
   sulla voce selected, aria-disabled sulla disabled.
   - global: tutta l'app, a sinistra e alta quanto il viewport, ferma mentre la pagina scorre. In alto il submark e
     il nome del prodotto, poi le sezioni e l'account in fondo; scorre solo la lista
   - collapsed: solo global, a sole icone. La label della voce diventa il balloon del tooltip (tooltip.css) su hover
     e focus, e resta il nome del link
   - local: dentro un'area, come Impostazioni: solo le sezioni, senza logo né account
   Fra due sezioni un divider border. Hover e pressed con l'overlay system/state, il focus dentro la voce: fuori lo
   taglierebbe lo scroll. */
@layer components {
  .oxq-side-nav {
    display: flex;
    flex-shrink: 0;
    flex-direction: column;
    gap: var(--oxq-space-gap-md);
    inline-size: var(--oxq-size-side-nav-expanded);
    border-inline-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-border);
  }

  .oxq-side-nav:where([data-border='left']) {
    border-inline-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-border);
    border-inline-end: 0;
  }

  .oxq-side-nav:where([data-border='none']) {
    border-inline-end: 0;
  }

  /* In global il bordo sta dentro il padding, come lo stroke inside di Figma. */
  .oxq-side-nav:where([data-type='global']) {
    --_pad: var(--oxq-space-gap-sm);

    position: sticky;
    inset-block-start: 0;
    block-size: 100dvh;
    padding: var(--oxq-space-gap-sm) calc(var(--_pad) - var(--oxq-stroke-divider)) var(--oxq-space-gap-sm) var(--_pad);
    background-color: var(--oxq-neutral-surface-canvas);
  }

  .oxq-side-nav:where([data-type='global'][data-border='left']) {
    padding-inline: calc(var(--_pad) - var(--oxq-stroke-divider)) var(--_pad);
  }

  .oxq-side-nav:where([data-type='global'][data-border='none']) {
    padding-inline: var(--_pad);
  }

  .oxq-side-nav-header,
  .oxq-side-nav-footer {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--oxq-size-control-md);
  }

  .oxq-side-nav-header {
    padding-inline-start: var(--oxq-space-inset-item-x);
  }

  .oxq-side-nav-home {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-inline-size: 0;
    border-radius: var(--oxq-radius-selection);
    color: inherit;
    text-decoration: none;

    /* Il submark OXQ o il simbolo dello slot: alto quanto il token, largo quanto il suo rapporto. */
    & > :not(.oxq-side-nav-product) {
      flex-shrink: 0;
      inline-size: auto;
      block-size: var(--oxq-size-logo-side-nav);
      min-block-size: 0;
    }
  }

  .oxq-side-nav-product {
    overflow: hidden;
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-label-md);
    font-weight: var(--oxq-label-md-font-weight-strong);
    letter-spacing: var(--oxq-label-md-letter-spacing);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* La lista scorre quando non ci sta; l'account resta in fondo. */
  .oxq-side-nav-nav {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-md);
    min-block-size: 0;
    overflow-y: auto;
  }

  .oxq-side-nav-footer {
    margin-block-start: auto;
    padding-inline: var(--oxq-space-inset-item-x);
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-nav-section {
    --_item-h: var(--oxq-size-control-sm);
    --_item-font: var(--oxq-font-label-sm);
    --_item-ls: var(--oxq-label-sm-letter-spacing);
    --_item-strong: var(--oxq-label-sm-font-weight-strong);
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-nav-section:where([data-size='md']) {
    --_item-h: var(--oxq-size-control-md);
    --_item-font: var(--oxq-font-label-md);
    --_item-ls: var(--oxq-label-md-letter-spacing);
    --_item-strong: var(--oxq-label-md-font-weight-strong);
    --_icon-size: var(--oxq-size-icon-md);
  }

  .oxq-nav-section-items {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    list-style: none;
  }

  .oxq-nav-item {
    --_bg: transparent;
    --_icon: var(--oxq-neutral-icon-secondary);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--_item-h);
    padding-inline: var(--oxq-space-inset-item-x);
    border-radius: var(--oxq-radius-item);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-neutral-text-ink);
    font: var(--_item-font);
    letter-spacing: var(--_item-ls);
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    &:focus-visible {
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }

    & > .oxq-icon {
      color: var(--_icon);
    }
  }

  .oxq-nav-item-label {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-nav-item-count {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  @media (hover: hover) {
    .oxq-nav-item:where(:hover:not([aria-disabled='true'])) {
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-nav-item:where(:active:not([aria-disabled='true'])) {
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-nav-item:where([aria-current='page']) {
    --_bg: var(--oxq-neutral-surface-raised);
    --_icon: var(--oxq-neutral-icon-ink);

    box-shadow: var(--oxq-elevation-1);
    font-weight: var(--_item-strong);
  }

  .oxq-nav-item:where([aria-disabled='true']) {
    --_icon: var(--oxq-neutral-icon-muted);

    color: var(--oxq-neutral-text-muted);
    cursor: not-allowed;
  }

  .oxq-side-nav:where([data-collapsed]) {
    --_pad: var(--oxq-space-gap-xs);

    inline-size: var(--oxq-size-side-nav-collapsed);

    & .oxq-side-nav-header,
    & .oxq-side-nav-footer {
      justify-content: center;
      padding-inline: 0;
    }

    & .oxq-side-nav-home > * {
      block-size: var(--oxq-size-logo-nav-submark);
    }

    /* ponytail: la lista collapsed non scorre, così il balloon esce dalla colonna. Con più voci di quante ne stanno
       in altezza servirebbe un balloon in popover. */
    & .oxq-side-nav-nav {
      overflow: visible;
    }

    & .oxq-menu-label,
    & .oxq-nav-item-count {
      display: none;
    }

    & .oxq-nav-item {
      position: relative;
      justify-content: center;
    }

    /* Il balloon resta nell'albero dell'accessibilità, nascosto solo alla vista: è il nome del link. */
    & .oxq-nav-item-label {
      overflow: visible;
      visibility: visible;
      pointer-events: none;
    }

    & .oxq-nav-item:where(:hover, :focus-visible):where(:not([data-dismissed])) > .oxq-nav-item-label {
      pointer-events: auto;
    }
  }
}
/* App header (Organisms › App header): la barra dell'applicazione, in cima a ogni pagina e a tutta larghezza, sopra
   page-header. A sinistra il logo e il nome dell'area di lavoro, o i moduli come tab solid sm (tabs.css, con
   aria-current sul modulo corrente). A destra le azioni globali (button elevated), dopo il divider gli strumenti
   (icon-button elevated) e per ultimo l'account. Le azioni della pagina stanno in page-header. */
@layer components {
  .oxq-app-header {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-md);
    padding: var(--oxq-space-inset-item-y) var(--oxq-space-layout-margin);
    background-color: var(--oxq-neutral-surface-canvas);
  }

  /* Logo e area di lavoro o moduli: si stringono loro, e i moduli scorrono. */
  .oxq-app-header-start {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: var(--oxq-space-gap-md);
    min-inline-size: 0;
  }

  .oxq-app-header-home {
    display: flex;
    flex-shrink: 0;
    border-radius: var(--oxq-radius-selection);
    color: inherit;
    text-decoration: none;

    /* Il logo OXQ o quello dello slot: alto quanto il token, largo quanto il suo rapporto. */
    & > * {
      inline-size: auto;
      block-size: var(--oxq-size-logo-nav);
      min-block-size: 0;
    }
  }

  .oxq-app-header-workspace {
    overflow: hidden;
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-app-header-modules {
    min-inline-size: 0;
  }

  .oxq-app-header-actions,
  .oxq-app-header-tools {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-app-header > .oxq-divider {
    align-self: center;
    block-size: var(--oxq-size-divider-controls);
  }
}
/* Trend indicator (Atoms › Trend indicator): freccia e valore con il segno, per una variazione rispetto a un
   riferimento. Prop Figma → attributi: data-direction (up | down | flat), data-tone, data-size (sm | md).
   direction segue il numero, tone il giudizio: un costo che sale è up + danger. Il segno sta sempre nel valore, e il
   termine di confronto nella label o nell'intestazione. A destra nella cella, come ogni colonna numerica. */
@layer components {
  .oxq-trend-indicator {
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    color: var(--oxq-tone-text-vivid-small);
    font: var(--oxq-font-body-xs);
    font-weight: var(--oxq-body-xs-font-weight-strong);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
    white-space: nowrap;
  }

  .oxq-trend-indicator:where([data-size='md']) {
    gap: var(--oxq-space-gap-xs);
    font: var(--oxq-font-body-sm);
    font-weight: var(--oxq-body-sm-font-weight-strong);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }
}
/* Amount percent (Atoms › Amount percent): importo e percentuale affiancati nelle celle di tabella.
   Prop Figma → attributi: data-emphasis (row | total), data-tone, data-tint (percent | all).
   - emphasis: row nelle righe, total solo nella riga di totale
   - tone: segue la soglia della percentuale e la colora; neutral senza soglia
   - tint all: colora anche l'importo, solo quando è lui il dato critico, come un margine sotto zero
   A destra nella cella, come ogni colonna numerica. */
@layer components {
  .oxq-amount-percent {
    --_amount: var(--oxq-neutral-text-secondary);

    display: inline-flex;
    align-items: baseline;
    gap: var(--oxq-space-gap-xs);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    white-space: nowrap;
  }

  .oxq-amount-percent-amount {
    color: var(--_amount);
  }

  .oxq-amount-percent-percent {
    color: var(--oxq-tone-text-vivid-small);
    font-weight: var(--oxq-body-sm-font-weight-strong);
  }

  .oxq-amount-percent:where([data-emphasis='total']) {
    --_amount: var(--oxq-neutral-text-ink);

    font-weight: var(--oxq-body-sm-font-weight-strong);

    & .oxq-amount-percent-percent {
      font: var(--oxq-font-label-md);
      font-weight: var(--oxq-label-md-font-weight-strong);
      letter-spacing: var(--oxq-label-md-letter-spacing);
    }
  }

  .oxq-amount-percent:where([data-tint='all']):where(:not([data-tone='neutral'])) {
    --_amount: var(--oxq-tone-text-vivid-small);
  }
}
/* KPI strip (Organisms › KPI strip) e KPI item (Molecules › KPI item): la fascia in testa alla pagina, una per vista,
   con da 3 a 5 kpi-item in riga e i segnali aperti come stat-chip.
   - kpi-item: una metric md con il dot di stato, una descrizione di una riga e il meter verso l'obiettivo. Il tone
     colora solo il dot. data-divider separa la prima voce, quella in evidenza
   - segnali: fino a 2 in coda alla riga, uno sotto l'altro. Da 3 in su in una riga che si apre e si chiude
     (data-collapsible, un details): il dot e il counter-badge nel sommario, danger prima di warning */
@layer components {
  .oxq-kpi-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--oxq-space-gap-md);
    padding: var(--oxq-space-gap-md);
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    color: var(--oxq-neutral-text-ink);
  }

  .oxq-kpi-strip:where([data-collapsible]) {
    flex-direction: column;
    align-items: stretch;
  }

  .oxq-kpi-strip-items {
    display: flex;
    flex-wrap: wrap;
    gap: var(--oxq-space-gap-xl);
  }

  .oxq-kpi-strip-signals {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-kpi-strip-group > .oxq-kpi-strip-signals {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    margin-block-start: var(--oxq-space-gap-md);
  }

  .oxq-kpi-strip-summary {
    --_icon-size: var(--oxq-size-icon-sm);

    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    padding-block-start: var(--oxq-space-gap-sm);
    border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
    list-style: none;
    cursor: pointer;

    &::-webkit-details-marker {
      display: none;
    }

    & > .oxq-icon {
      color: var(--oxq-neutral-icon-ink);
      transition: rotate var(--oxq-duration-state) var(--oxq-easing-transition);
    }
  }

  .oxq-kpi-strip-group[open] > .oxq-kpi-strip-summary > .oxq-icon {
    rotate: 90deg;
  }

  .oxq-kpi-item {
    display: flex;
    gap: var(--oxq-space-gap-xs);

    /* Il dot si allinea alla label della metric. */
    & > .oxq-dot-badge {
      margin-block-start: var(--oxq-space-gap-2xs);
    }
  }

  .oxq-kpi-item:where([data-divider]) {
    padding-inline-end: var(--oxq-space-gap-xl);
    border-inline-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
  }

  .oxq-kpi-item-content {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    inline-size: var(--oxq-size-kpi-item-content);
  }

  .oxq-kpi-item-description {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }
}
/* Stacked bar (Atoms › Stacked bar) e Legend (Molecules › Legend).
   - stacked-bar: una barra divisa in segmenti, ognuno una quota del totale; la parte vuota resta track ed è la quota
     non assegnata. data-size (sm | md | lg) sulla barra: sm nelle righe di tabella, md nelle card, lg nei riepiloghi.
     La quota arriva dal markup come --oxq-value sul segmento (style="--oxq-value: 40%"); un segmento non scende sotto
     size/segment/min. Fino a 5 categorie. È decorativa: nomi e valori stanno nella legend accanto
   - legend: spiega i colori di una barra, di un grafico o di una tabella. data-orientation (horizontal sotto barre e
     grafici larghi, vertical a fianco), data-size (sm | md) che vale per tutte le voci
   data-color sul segmento e sulla voce: neutral, neutral-secondary e i 5 accent. È la categoria, mai uno stato; la
   voce ha lo stesso color e lo stesso ordine del segmento che spiega. */
@layer components {
  :where(.oxq-stacked-bar-segment, .oxq-legend-item) {
    --_solid: var(--oxq-neutral-surface-solid);
  }

  :where(.oxq-stacked-bar-segment, .oxq-legend-item):where([data-color='neutral-secondary']) {
    --_solid: var(--oxq-neutral-surface-indicator);
  }

  :where(.oxq-stacked-bar-segment, .oxq-legend-item):where([data-color='yellow']) {
    --_solid: var(--oxq-accent-yellow-surface-solid);
  }

  :where(.oxq-stacked-bar-segment, .oxq-legend-item):where([data-color='green']) {
    --_solid: var(--oxq-accent-green-surface-solid);
  }

  :where(.oxq-stacked-bar-segment, .oxq-legend-item):where([data-color='blue']) {
    --_solid: var(--oxq-accent-blue-surface-solid);
  }

  :where(.oxq-stacked-bar-segment, .oxq-legend-item):where([data-color='violet']) {
    --_solid: var(--oxq-accent-violet-surface-solid);
  }

  :where(.oxq-stacked-bar-segment, .oxq-legend-item):where([data-color='magenta']) {
    --_solid: var(--oxq-accent-magenta-surface-solid);
  }

  .oxq-stacked-bar {
    display: flex;
    gap: var(--oxq-space-gap-segment);
    block-size: var(--oxq-size-progress-sm);
    overflow: hidden;
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-muted);
  }

  .oxq-stacked-bar:where([data-size='md']) {
    block-size: var(--oxq-size-progress-md);
  }

  .oxq-stacked-bar:where([data-size='lg']) {
    block-size: var(--oxq-size-progress-lg);
  }

  .oxq-stacked-bar-segment {
    flex: 0 1 var(--oxq-value);
    min-inline-size: var(--oxq-size-segment-min);
    background-color: var(--_solid);
  }

  .oxq-legend {
    --_dot: var(--oxq-size-dot-sm);
    --_label-font: var(--oxq-font-body-xs);
    --_label-ls: var(--oxq-body-xs-letter-spacing);
    --_value-font: var(--oxq-font-label-sm);
    --_value-ls: var(--oxq-label-sm-letter-spacing);

    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-md);
  }

  .oxq-legend:where([data-size='md']) {
    --_dot: var(--oxq-size-dot-md);
    --_label-font: var(--oxq-font-body-sm);
    --_label-ls: var(--oxq-body-sm-letter-spacing);
    --_value-font: var(--oxq-font-label-md);
    --_value-ls: var(--oxq-label-md-letter-spacing);
  }

  .oxq-legend-items {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-md);
    list-style: none;
  }

  .oxq-legend:where([data-orientation='vertical']),
  .oxq-legend:where([data-orientation='vertical']) > .oxq-legend-items {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-legend-title {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-legend-note,
  .oxq-legend-count {
    color: var(--oxq-neutral-text-muted);
  }

  .oxq-legend-note {
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-legend-item {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    font: var(--_label-font);
    letter-spacing: var(--_label-ls);
    white-space: nowrap;

    &::before {
      content: '';
      flex-shrink: 0;
      inline-size: var(--_dot);
      block-size: var(--_dot);
      border-radius: var(--oxq-radius-pill);
      background-color: var(--_solid);
    }
  }

  .oxq-legend-label {
    color: var(--oxq-neutral-text-secondary);
  }

  .oxq-legend-value {
    color: var(--oxq-neutral-text-ink);
    font: var(--_value-font);
    letter-spacing: var(--_value-ls);
  }
}
/* Distribution bar (Atoms › Distribution bar) e Distribution bar row (Molecules › Distribution bar row).
   - distribution-bar: una barra sempre piena, ogni segmento una quota del 100% con label e percentuale; l'ultimo
     prende lo spazio che resta. Per una parte non assegnata c'è stacked-bar. Da 2 a 6 segmenti, dalla quota più grande
   - la quota arriva dal markup come --oxq-value sul segmento (style="--oxq-value: 40%")
   - data-color sul segmento: neutral, neutral-secondary e i 5 accent, mai uno stato. Stessa categoria, stesso color
   - data-hide-label: nei segmenti stretti, sotto 64 px, resta la percentuale; la label resta per il lettore di schermo
   - distribution-bar-row: la fonte della ripartizione e la sua barra, da 2 a 4 righe da confrontare in colonna */
@layer components {
  .oxq-distribution-bar {
    display: flex;
    flex: 1 1 auto;
    gap: var(--oxq-space-gap-segment);
    min-inline-size: 0;
    block-size: var(--oxq-size-control-sm);
    overflow: hidden;
    border-radius: var(--oxq-radius-item);
  }

  .oxq-distribution-bar-segment {
    --_bg: var(--oxq-neutral-surface-control);
    --_fg: var(--oxq-neutral-text-ink);

    position: relative;
    display: flex;
    flex: 0 1 var(--oxq-value);
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
    padding-inline: var(--oxq-space-inset-item-x);
    overflow: hidden;
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;

    &:last-child {
      flex-grow: 1;
    }
  }

  .oxq-distribution-bar-label {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .oxq-distribution-bar-value {
    font-weight: var(--oxq-label-sm-font-weight-strong);
  }

  .oxq-distribution-bar-segment:where([data-hide-label]) > .oxq-distribution-bar-label {
    position: absolute;
    clip-path: inset(50%);
  }

  .oxq-distribution-bar-segment:where([data-color='neutral-secondary']) {
    --_bg: var(--oxq-neutral-surface-subtle);
    --_fg: var(--oxq-neutral-text-secondary);
  }

  .oxq-distribution-bar-segment:where([data-color='yellow']) {
    --_bg: var(--oxq-accent-yellow-surface-soft);
    --_fg: var(--oxq-accent-yellow-text-ink);
  }

  .oxq-distribution-bar-segment:where([data-color='green']) {
    --_bg: var(--oxq-accent-green-surface-soft);
    --_fg: var(--oxq-accent-green-text-ink);
  }

  .oxq-distribution-bar-segment:where([data-color='blue']) {
    --_bg: var(--oxq-accent-blue-surface-soft);
    --_fg: var(--oxq-accent-blue-text-ink);
  }

  .oxq-distribution-bar-segment:where([data-color='violet']) {
    --_bg: var(--oxq-accent-violet-surface-soft);
    --_fg: var(--oxq-accent-violet-text-ink);
  }

  .oxq-distribution-bar-segment:where([data-color='magenta']) {
    --_bg: var(--oxq-accent-magenta-surface-soft);
    --_fg: var(--oxq-accent-magenta-text-ink);
  }

  .oxq-distribution-bar-row {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-md);
  }

  .oxq-distribution-bar-row-label {
    flex-shrink: 0;
    inline-size: var(--oxq-size-distribution-bar-row-label);
    overflow: hidden;
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
/* Select chip (Atoms › Select chip) e Filter toggle (Atoms › Filter toggle): due trigger della barra sopra un elenco.
   - select-chip: apre un menu, un listbox o un date picker e mostra la scelta corrente, con la chevron in giù; da
     aperto (aria-expanded) la chevron va in su. Prop Figma → data-size (sm | md), data-tone; dot e icona prima della
     label. La label è il valore, mai il nome del campo. tone neutral per le scelte; gli altri, col dot, solo per lo
     stato di un record. Senza chevron è un valore a due stati che si alterna al clic
   - filter-toggle: apre e chiude il pannello dei filtri e conta quelli attivi. Prop Figma → data-shape (rounded
     accanto a button e input field, pill accanto ai chip), data-size, data-active (almeno un filtro applicato, anche a
     pannello chiuso), aria-expanded (open). Il conteggio resta visibile anche a 0: soft, e solid da 1 */
@layer components {
  .oxq-select-chip,
  .oxq-filter-toggle {
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    max-inline-size: 100%;
    border: var(--oxq-stroke-control) solid var(--_border);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--_fg);
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
    transition-property: background-color, border-color, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--_fg-icon);
    }

    /* La chevron, sempre l'ultima: da aperto punta in su. */
    & > .oxq-icon:last-child {
      transition: rotate var(--oxq-duration-open) var(--oxq-easing-transition);
    }
  }

  .oxq-select-chip {
    --_bg: var(--oxq-tone-surface-sunken);
    --_border: var(--oxq-tone-line-border);
    --_border-hover: var(--oxq-tone-line-border-strong);
    --_fg: var(--oxq-tone-text-ink);
    --_fg-icon: var(--oxq-tone-icon-ink);

    gap: var(--oxq-space-gap-2xs);
    min-block-size: var(--oxq-size-chip-sm);
    padding-inline: var(--oxq-space-gap-xs);
    border-radius: var(--oxq-radius-pill);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-select-chip:where([data-tone='neutral']) {
    --_border: var(--oxq-neutral-line-control);
    --_border-hover: var(--oxq-neutral-line-control-hover);
  }

  .oxq-select-chip:where([data-size='md']) {
    min-block-size: var(--oxq-size-chip-md);
    padding-inline: var(--oxq-space-gap-sm);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-select-chip-label {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .oxq-filter-toggle {
    --_bg: var(--oxq-neutral-surface-raised);
    --_border: var(--oxq-neutral-line-control);
    --_border-hover: var(--oxq-neutral-line-control-hover);
    --_fg: var(--oxq-neutral-text-secondary);
    --_fg-icon: var(--oxq-neutral-icon-secondary);

    gap: var(--oxq-space-gap-xs);
    block-size: var(--oxq-size-control-sm);
    padding-inline: var(--oxq-space-gap-sm);
    border-radius: var(--oxq-radius-control);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-filter-toggle:where([data-shape='pill']) {
    border-radius: var(--oxq-radius-pill);
  }

  .oxq-filter-toggle:where([data-size='md']) {
    block-size: var(--oxq-size-control-md);
    padding-inline: var(--oxq-space-inset-control-x);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-filter-toggle:where([data-active]) {
    --_fg: var(--oxq-neutral-text-ink);
  }

  @media (hover: hover) {
    :is(.oxq-select-chip, .oxq-filter-toggle):where(:hover:not(:disabled)) {
      --_border: var(--_border-hover);
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  :is(.oxq-select-chip, .oxq-filter-toggle):where([aria-expanded='true']:not(:disabled)) {
    --_border: var(--_border-hover);
    --_overlay: var(--oxq-system-state-pressed);

    & > .oxq-icon:last-child {
      rotate: 180deg;
    }
  }

  /* Disabled: fondo control-disabled, bordo border, testo e icone muted; i tone tornano neutral. */
  :is(.oxq-select-chip, .oxq-filter-toggle):where(:disabled) {
    --_bg: var(--oxq-neutral-surface-control-disabled);
    --_border: var(--oxq-neutral-line-border);
    --_fg: var(--oxq-neutral-text-muted);
    --_fg-icon: var(--oxq-neutral-icon-muted);

    cursor: not-allowed;
  }
}
/* Filter chip (Molecules › Filter chip) e il select dello scope switcher: il combobox con un chip al posto del campo
   (combobox.css e listbox.css). Il chip apre il listbox, con la ricerca e i conteggi; il valore lo scrive oxq.js.
   data-variant sulla radice:
   - filter: vuoto è un select-chip col nome del filtro e la chevron; con un valore è un chip col nome (key) in
     secondary, il valore e il close che toglie il filtro, e il clic sul chip riapre il listbox. Resta al suo posto,
     impostato o no
   - chip: il select-chip dello scope switcher, che mostra sempre il valore: uno scope non è mai vuoto
   Il listbox è largo size/filter-chip/listbox. */
@layer components {
  .oxq-combobox:where([data-variant]) {
    display: inline-flex;
  }

  .oxq-combobox-chip {
    --_icon-size: var(--oxq-size-icon-sm);
    --_bg: var(--oxq-neutral-surface-sunken);
    --_border: var(--oxq-neutral-line-control);
    --_fg-key: var(--oxq-neutral-text-ink);

    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    min-inline-size: 0;
    max-inline-size: 100%;
    min-block-size: var(--oxq-size-chip-sm);
    padding-inline: var(--oxq-space-gap-xs);
    border: var(--oxq-stroke-control) solid var(--_border);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;
    cursor: pointer;
    transition-property: background-color, border-color, color, --_overlay;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);

    & > .oxq-icon {
      color: var(--oxq-neutral-icon-ink);
      transition: rotate var(--oxq-duration-open) var(--oxq-easing-transition);
    }

    /* Il trigger copre tutto il chip col suo ::after; il close gli sta sopra. */
    & > .oxq-combobox-trigger {
      display: inline-flex;
      align-items: center;
      gap: var(--oxq-space-gap-2xs);
      min-inline-size: 0;
      background: transparent;
      cursor: inherit;

      &::after {
        content: '';
        position: absolute;
        inset: 0;
        border-radius: inherit;
      }

      &:focus-visible {
        outline: none;
      }
    }

    &:has(> .oxq-combobox-trigger:focus-visible) {
      outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
      outline-offset: var(--oxq-offset-focus);
    }
  }

  .oxq-combobox:where([data-variant][data-size='md']) > .oxq-combobox-chip {
    min-block-size: var(--oxq-size-chip-md);
    padding-inline: var(--oxq-space-gap-sm);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  .oxq-combobox-key {
    flex-shrink: 0;
    color: var(--_fg-key);
  }

  .oxq-combobox-chip .oxq-combobox-value {
    flex: 0 1 auto;
    contain: none;

    &:empty {
      display: none;
    }
  }

  .oxq-combobox-clear {
    position: relative;
    z-index: 1;
    display: flex;
    color: var(--oxq-neutral-icon-ink);
    background: transparent;
  }

  /* Con un valore: il chip, il key in secondary, il close al posto della chevron. */
  .oxq-combobox:where([data-variant='filter']:has(.oxq-combobox-value:not(:empty))) > .oxq-combobox-chip {
    --_bg: var(--oxq-neutral-surface-raised);
    --_fg-key: var(--oxq-neutral-text-secondary);

    & > .oxq-icon {
      display: none;
    }
  }

  .oxq-combobox:where(:not(:has(.oxq-combobox-value:not(:empty)))) .oxq-combobox-clear {
    display: none;
  }

  @media (hover: hover) {
    .oxq-combobox-chip:where(:hover:not(:has(:disabled))) {
      --_border: var(--oxq-neutral-line-control-hover);
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-combobox-chip:where(:has(> [aria-expanded='true'])) {
    --_border: var(--oxq-neutral-line-control-hover);

    & > .oxq-icon {
      rotate: 180deg;
    }
  }

  .oxq-combobox:where([data-variant='chip'], :not(:has(.oxq-combobox-value:not(:empty))))
    > .oxq-combobox-chip:has(> [aria-expanded='true']) {
    --_overlay: var(--oxq-system-state-pressed);
  }

  .oxq-combobox-chip:where(:has(> .oxq-combobox-trigger:disabled)) {
    --_bg: var(--oxq-neutral-surface-control-disabled);
    --_border: var(--oxq-neutral-line-border);
    --_fg-key: var(--oxq-neutral-text-muted);

    color: var(--oxq-neutral-text-muted);
    cursor: not-allowed;

    & .oxq-icon {
      color: var(--oxq-neutral-icon-muted);
    }
  }

  .oxq-combobox:where([data-variant]) > .oxq-listbox {
    inline-size: var(--oxq-size-filter-chip-listbox);
  }
}
/* Filter bar (Molecules › Filter bar): la barra subito sopra la tabella o la lista che filtra. In ordine la ricerca,
   larga size/filter-bar/search; i filtri attivi come filter-chip, nell'ordine in cui sono stati applicati; il
   filter-toggle col conteggio; in fondo, dopo il divider, la vista. Va a capo quando non ci sta. Con righe
   selezionate compare sotto la bulk-action-bar: le due convivono. */
@layer components {
  .oxq-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-sm);

    & > .oxq-search-field {
      inline-size: var(--oxq-size-filter-bar-search);
      max-inline-size: 100%;
    }
  }

  .oxq-filter-bar-view {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
    margin-inline-start: auto;

    & > .oxq-divider {
      align-self: center;
      block-size: var(--oxq-size-divider-controls);
    }
  }
}
/* Bulk action bar (Molecules › Bulk action bar): le azioni sulle righe selezionate. Compare alla prima selezione e
   resta finché la selezione torna a zero o si sceglie Deseleziona, sempre in fondo.
   Prop Figma → attributi: data-placement (docked | floating), data-size (sm | md, come le righe), data-emphasis.
   - docked: sopra l'intestazione della tabella, larga quanto la tabella
   - floating: in basso al centro della vista, nelle liste lunghe, con bordo e ombra
   - inverse: stacca la barra dal contenuto, scura in light e chiara in dark; la prima azione secondary con il filo
     on-ink-secondary, le altre ghost in on-ink
   count dice quante righe e di cosa (3 rate); summary un totale utile alla decisione. Da 1 a 3 azioni. */
@layer components {
  .oxq-bulk-action-bar {
    --_fg: var(--oxq-neutral-text-ink);
    --_fg-secondary: var(--oxq-neutral-text-secondary);

    display: flex;
    align-items: center;
    justify-content: space-between;
    block-size: var(--oxq-size-bulk-action-bar-sm);
    padding: var(--oxq-space-gap-xs) var(--oxq-space-gap-xs) var(--oxq-space-gap-xs) var(--oxq-space-gap-md);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-brand-surface-soft);
    color: var(--_fg);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-bulk-action-bar:where([data-size='md']) {
    block-size: var(--oxq-size-bulk-action-bar-md);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);

    & .oxq-bulk-action-bar-summary {
      font: var(--oxq-font-body-md);
      letter-spacing: var(--oxq-body-md-letter-spacing);
    }
  }

  .oxq-bulk-action-bar:where([data-placement='floating']) {
    position: fixed;
    z-index: 1;
    inset-block-end: var(--oxq-space-layout-margin);
    inset-inline-start: 50%;
    justify-content: flex-start;
    gap: var(--oxq-space-gap-xl);
    max-inline-size: calc(100vw - 2 * var(--oxq-space-layout-margin));
    /* Il bordo sta dentro il padding, come lo stroke inside di Figma. */
    padding: calc(var(--oxq-space-gap-xs) - var(--oxq-stroke-control))
      calc(var(--oxq-space-gap-xs) - var(--oxq-stroke-control))
      calc(var(--oxq-space-gap-xs) - var(--oxq-stroke-control))
      calc(var(--oxq-space-gap-md) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-2);
    translate: -50% 0;
  }

  .oxq-bulk-action-bar:where([data-emphasis='inverse']) {
    --_fg: var(--oxq-neutral-text-on-ink);
    --_fg-secondary: var(--oxq-neutral-text-on-ink-secondary);

    border-color: transparent;
    background-color: var(--oxq-neutral-surface-solid);

    & .oxq-button {
      --_bg: transparent;
      --_fg: var(--oxq-neutral-text-on-ink);
      --_fg-icon: var(--oxq-neutral-icon-on-ink);
    }

    & .oxq-button:where([data-variant='secondary']) {
      --_border: var(--oxq-neutral-text-on-ink-secondary);
    }
  }

  .oxq-bulk-action-bar-start {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-md);
  }

  .oxq-bulk-action-bar-selection {
    display: flex;
    align-items: baseline;
    gap: var(--oxq-space-gap-sm);
    white-space: nowrap;
  }

  .oxq-bulk-action-bar-count {
    font-weight: var(--oxq-label-sm-font-weight-strong);
  }

  .oxq-bulk-action-bar-summary {
    color: var(--_fg-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-bulk-action-bar-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }
}
/* Save status (Molecules › Save status): dice se le modifiche sono salvate, nelle viste con salvataggio automatico.
   Prop Figma → data-state (idle | saving | saved | failed). Il punto è un dot-badge; in saving lo spinner ne prende il
   posto, in un riquadro della stessa misura, così il cambio di state non sposta il resto. failed in warning.
   Sempre nello stesso punto, in testata o nel footer della vista. */
@layer components {
  .oxq-save-status {
    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-2xs);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-save-status:where([data-state='failed']) {
    color: var(--oxq-warning-text-secondary);
  }

  .oxq-save-status-indicator {
    --_icon-size: var(--oxq-size-icon-xs);

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    inline-size: var(--oxq-size-icon-xs);
    block-size: var(--oxq-size-icon-xs);
  }
}
/* Scope switcher (Molecules › Scope switcher): label e controllo per cambiare il perimetro dei dati di tutta la page:
   anno, mese, periodo, lingua, mercato. Nell'intestazione, prima dei filtri; più scope in riga, dal più ampio.
   Uno scope ha sempre un valore: è la differenza con il filter-chip. Prop Figma → type, che sceglie il controllo:
   - select: un filter-chip senza key né close (combobox.css) per scegliere da un elenco
   - stepper (scope-stepper): due frecce e il valore, per una sequenza come i mesi. Al limite si spegne la freccia
   - range: due select-chip con il calendario, ognuno apre un date picker in popover
   data-size (sm | md) sul controllo. */
@layer components {
  .oxq-scope-switcher {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-scope-switcher-label,
  .oxq-scope-switcher-separator {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-scope-switcher-label:where([data-hidden]) {
    position: absolute;
    clip-path: inset(50%);
  }

  .oxq-scope-stepper {
    --_icon-size: var(--oxq-size-icon-sm);

    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--oxq-size-chip-sm);
    padding-inline: var(--oxq-space-gap-2xs);
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-control);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--oxq-neutral-surface-sunken);
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;
  }

  .oxq-scope-stepper:where([data-size='md']) {
    min-block-size: var(--oxq-size-chip-md);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
  }

  /* Le frecce: link o button, ognuna col suo focus; al limite della sequenza si spegne solo quella. */
  .oxq-scope-stepper-step {
    display: flex;
    padding: var(--oxq-space-gap-2xs);
    border-radius: var(--oxq-radius-pill);
    background-color: transparent;
    background-image: linear-gradient(var(--_overlay), var(--_overlay));
    color: var(--oxq-neutral-icon-ink);
    text-decoration: none;
    transition: --_overlay var(--oxq-duration-state) var(--oxq-easing-transition);

    &:where([aria-disabled='true'], :disabled) {
      color: var(--oxq-neutral-icon-muted);
      cursor: not-allowed;
    }
  }

  @media (hover: hover) {
    .oxq-scope-stepper-step:where(:hover:not([aria-disabled='true'], :disabled)) {
      --_overlay: var(--oxq-system-state-hover);
    }
  }

  .oxq-scope-stepper:where([data-disabled]) {
    border-color: var(--oxq-neutral-line-border);
    background-color: var(--oxq-neutral-surface-control-disabled);
    color: var(--oxq-neutral-text-muted);
  }
}
/* Handle (Atoms › Handle): la maniglia per spostare (drag) o ridimensionare (resize).
   Prop Figma → attributi: data-type (drag | resize), data-orientation (vertical | horizontal), disabled.
   - drag: l'icona drag-handle in un'area di size/control/sm. vertical per le righe, horizontal (l'icona ruotata) per
     le colonne. Cursore grab, grabbing mentre si preme
   - resize: una barretta lungo il bordo che si muove, in un'area di 48 × 16. vertical è la barretta verticale, sul
     bordo destro o sinistro: cursore ew-resize; horizontal ns-resize
   - nello splitter (data-handle) la handle è solo il segno: hover e pressed sono quelli dello splitter
   hover, pressed e focus li decide il browser; spostare e ridimensionare sono dell'app. */
@layer components {
  .oxq-handle {
    --_icon: var(--oxq-neutral-icon-secondary);
    --_bar: var(--oxq-neutral-line-border-strong);
    --_bg: transparent;

    display: inline-grid;
    flex-shrink: 0;
    place-items: center;
    inline-size: var(--oxq-size-control-sm);
    block-size: var(--oxq-size-control-sm);
    border-radius: var(--oxq-radius-item);
    background-color: var(--_bg);
    color: var(--_icon);
    cursor: grab;
    touch-action: none;
    transition:
      background-color var(--oxq-duration-state) var(--oxq-easing-transition),
      color var(--oxq-duration-state) var(--oxq-easing-transition);

    > .oxq-icon {
      inline-size: var(--oxq-size-icon-md);
      block-size: var(--oxq-size-icon-md);
    }

    /* L'anello sta dentro l'area, come in Figma. */
    &:focus-visible {
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }
  }

  .oxq-handle:where([data-orientation='horizontal']) > .oxq-icon {
    rotate: 90deg;
  }

  .oxq-handle:where([data-type='resize']) {
    inline-size: var(--oxq-size-control-lg);
    block-size: var(--oxq-size-handle-resize);
    cursor: ns-resize;

    &::before {
      content: '';
      inline-size: var(--oxq-size-control-sm);
      block-size: var(--oxq-size-handle-bar);
      border-radius: var(--oxq-radius-pill);
      background-color: var(--_bar);
      transition: background-color var(--oxq-duration-state) var(--oxq-easing-transition);
    }
  }

  .oxq-handle:where([data-type='resize'][data-orientation='vertical']) {
    inline-size: var(--oxq-size-handle-resize);
    block-size: var(--oxq-size-control-lg);
    cursor: ew-resize;

    &::before {
      inline-size: var(--oxq-size-handle-bar);
      block-size: var(--oxq-size-control-sm);
    }
  }

  @media (hover: hover) {
    :is(.oxq-handle:where(:hover:not(:disabled)), .oxq-splitter:where(:hover) > .oxq-handle) {
      --_icon: var(--oxq-neutral-icon-ink);
      --_bar: var(--oxq-neutral-icon-secondary);
    }

    .oxq-handle:where([data-type='drag']:hover:not(:disabled)) {
      --_bg: var(--oxq-system-state-hover);
    }
  }

  :is(.oxq-handle:where(:active:not(:disabled)), .oxq-splitter:where(:active) > .oxq-handle) {
    --_icon: var(--oxq-neutral-icon-ink);
    --_bar: var(--oxq-neutral-icon-ink);
  }

  .oxq-handle:where([data-type='drag']:active:not(:disabled)) {
    --_bg: var(--oxq-system-state-pressed);

    cursor: grabbing;
  }

  /* disabled: la maniglia resta, ma non risponde. */
  .oxq-handle:where(:disabled) {
    --_icon: var(--oxq-neutral-icon-muted);
    --_bar: var(--oxq-neutral-line-border);

    cursor: default;
  }

  /* Nello splitter: al centro della linea, sopra; il trascinamento resta dello splitter. */
  .oxq-splitter > .oxq-handle {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    translate: -50% -50%;
    pointer-events: none;
  }
}
/* List (Organisms › List), List item (Atoms › List item) e Indent guide (Atoms › Indent guide).
   - list: un ul di list-item. data-variant: outlined da sola sulla pagina, plain dentro card, sheet e pannelli. Il
     divider fra le righe è automatico, l'ultima non lo ha
   - list-item: li, o div nella cella di una tabella (table-cell type list-item). data-size (sm | md). Con href il titolo è un link
     che copre la riga, con la chevron in fondo: hover, pressed e focus sono del link. data-selected (e aria-current
     sul link) e data-disabled da prop; la riga con una checkbox spuntata è selected da sé. data-indent: il testo
     rientra sotto l'elemento iniziale della padre
   - .oxq-disclosure: il button della chevron, con aria-expanded; aperta ruota in giù. Lo usano anche table-cell,
     table-band e table-tree-drilldown-group
   - indent-guide: dentro il list-item di una riga figlia. La riga rientra come il titolo della padre e il filo
     scende dal centro del suo avatar xs, dall'alto al basso della riga. Vale con la padre che ha disclosure e
     avatar xs, come in Figma; i 64 e i 55 px di Figma qui vengono da size, gap e avatar del list-item. */
@layer components {
  .oxq-list {
    display: flex;
    flex-direction: column;
    list-style: none;
  }

  .oxq-list:where([data-variant='outlined']) {
    overflow: hidden;
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
  }

  .oxq-list-item {
    --_py: var(--oxq-space-inset-list-item-y-sm);
    --_px: var(--oxq-space-inset-list-item-x-sm);
    --_gap: var(--oxq-space-gap-sm);
    --_indent: var(--oxq-size-icon-sm) + var(--_gap);
    --_bg: transparent;
    --_title: var(--oxq-neutral-text-ink);
    --_text: var(--oxq-neutral-text-secondary);
    --_icon: var(--oxq-neutral-icon-secondary);

    position: relative;
    display: flex;
    align-items: center;
    gap: var(--_gap);
    padding: var(--_py) var(--_px);
    background-color: var(--_bg);
    color: var(--_title);
    text-align: start;
    transition: background-color var(--oxq-duration-state) var(--oxq-easing-transition);

    > .oxq-icon {
      flex-shrink: 0;
      inline-size: var(--oxq-size-icon-sm);
      block-size: var(--oxq-size-icon-sm);
      color: var(--_icon);
    }
  }

  .oxq-list-item:where([data-size='md']) {
    --_py: var(--oxq-space-inset-list-item-y-md);
    --_px: var(--oxq-space-inset-list-item-x-md);
    --_gap: var(--oxq-space-gap-md);
  }

  .oxq-list-item:where([data-indent]) {
    padding-inline-start: calc(var(--_px) + var(--_indent));
  }

  .oxq-list > .oxq-list-item:not(:last-child)::before {
    content: '';
    position: absolute;
    inset: auto 0 0;
    block-size: var(--oxq-stroke-divider);
    background-color: var(--oxq-neutral-line-hairline);
  }

  .oxq-list-item-texts {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: var(--oxq-space-gap-item-text);
    min-inline-size: 0;
  }

  .oxq-list-item-title,
  .oxq-list-item-description {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-list-item-title {
    color: var(--_title);
    font: var(--oxq-font-label-md);
    letter-spacing: var(--oxq-label-md-letter-spacing);
    text-decoration: none;
  }

  .oxq-list-item-description,
  .oxq-list-item-meta {
    color: var(--_text);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-list-item-meta {
    flex-shrink: 0;
    white-space: nowrap;
  }

  /* Il link copre la riga; disclosure e azione finale restano sopra e si cliccano da sole. */
  a.oxq-list-item-title {
    outline: none;

    &::after {
      content: '';
      position: absolute;
      inset: 0;
    }
  }

  .oxq-list-item > :where(:not(.oxq-list-item-texts, .oxq-indent-guide)) {
    position: relative;
    flex-shrink: 0;
  }

  .oxq-list-item:where(:has(> .oxq-list-item-texts > a:focus-visible)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }

  @media (hover: hover) {
    .oxq-list-item:where(:has(> .oxq-list-item-texts > a:hover)) {
      --_bg: var(--oxq-system-state-hover);
    }
  }

  .oxq-list-item:where(:has(> .oxq-list-item-texts > a:active)) {
    --_bg: var(--oxq-system-state-pressed);
  }

  .oxq-list-item:where([data-selected], :has(> .oxq-checkbox input:checked)) {
    --_bg: var(--oxq-brand-surface-soft);
  }

  .oxq-list-item:where([data-disabled]) {
    --_title: var(--oxq-neutral-text-muted);
    --_text: var(--oxq-neutral-text-muted);
    --_icon: var(--oxq-neutral-icon-muted);
  }

  .oxq-disclosure {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    background-color: transparent;
    color: var(--oxq-neutral-icon-secondary);
    text-align: start;

    > .oxq-icon {
      flex-shrink: 0;
      inline-size: var(--oxq-size-icon-sm);
      block-size: var(--oxq-size-icon-sm);
      transition: rotate var(--oxq-duration-state) var(--oxq-easing-transition);
    }
  }

  .oxq-disclosure:where([aria-expanded='true']) > .oxq-icon {
    rotate: 90deg;
  }

  .oxq-list-item:where([data-disabled]) > .oxq-disclosure {
    color: var(--oxq-neutral-icon-muted);
  }

  /* Rientro della riga figlia: disclosure, avatar xs e i due gap della padre. */
  .oxq-list-item:where(:has(> .oxq-indent-guide)) {
    padding-inline-start: calc(var(--_px) + var(--oxq-size-icon-sm) + 2 * var(--_gap) + var(--oxq-size-avatar-xs));
  }

  /* In tabella copre anche il mezzo filo della riga sopra e sotto: i fili delle figlie si toccano. */
  .oxq-indent-guide {
    position: absolute;
    inset-block: calc(var(--oxq-stroke-divider) / -2);
    inset-inline-start: calc(
      var(--_px) + var(--oxq-size-icon-sm) + var(--_gap) +
        (var(--oxq-size-avatar-xs) - var(--oxq-stroke-indent-guide)) / 2
    );
    inline-size: var(--oxq-stroke-indent-guide);
    background-color: var(--oxq-neutral-line-border);
  }
}
/* Table (Organisms › Table), Table row (Molecules › Table row), Table cell e Table header cell (Atoms), Table band ed
   Expandable row (Molecules), Table tree drilldown (Organisms).
   - table: un div che scorre in orizzontale attorno a una table nativa. data-variant: outlined da sola sulla pagina,
     plain dentro card, modal e sheet. data-size (sm 32 px | md 40 px) vale per tutte le righe
   - le righe vanno direttamente nella table; band, expandable row e table-tree-drilldown-group sono un tbody
     ciascuna. Il padding della riga sono due celle vuote (::before e ::after), così fondi e fili arrivano al bordo
   - table-row: data-type (header, group, subtotal, total, add, empty, loading, loading-more, perimeter, band,
     drilldown; senza è body), data-state (selected, expanded, editing, read-only). hover lo decide il browser, e la
     riga con la checkbox spuntata è selected da sé. Le righe a tutta larghezza hanno una cella sola, con colspan
   - table-cell: data-type cambia il padding (le celle con un controllo non hanno padding sopra e sotto e restano
     strette), data-align (start per il testo, end per numeri e importi), data-emphasis (secondary, strong; nelle
     righe subtotal e total è strong da sé), data-highlight (la colonna del periodo corrente)
   - table-header-cell: th. Se la colonna si ordina, un button copre la cella; aria-sort sulla colonna ordinata.
     Nella riga group la label va in maiuscolo
   - la barra di table-band (type band), di table-tree-drilldown-group e della radice (type group): .oxq-table-bar,
     un th su tutte le colonne. Con la disclosure chiusa le altre righe del tbody non si vedono */
@layer components {
  .oxq-table {
    --_h: var(--oxq-size-control-sm);
    --_add: var(--oxq-size-control-md);
    --_empty: var(--oxq-space-gap-md);

    overflow-x: auto;
    color: var(--oxq-neutral-text-ink);

    > table {
      inline-size: 100%;
    }
  }

  .oxq-table:where([data-size='md']) {
    --_h: var(--oxq-size-control-md);
    --_add: var(--oxq-size-control-lg);
    --_empty: var(--oxq-space-gap-lg);
  }

  .oxq-table:where([data-variant='outlined']) {
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
  }

  .oxq-table-row {
    --_bg: transparent;

    border-block-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    background-color: var(--_bg);
    transition: background-color var(--oxq-duration-state) var(--oxq-easing-transition);

    &::before,
    &::after {
      content: '';
      display: table-cell;
      inline-size: var(--oxq-space-inset-item-x);
    }
  }

  .oxq-table-row:where([data-type='header']) {
    --_bg: var(--oxq-neutral-surface-subtle);

    border-block-end-color: var(--oxq-neutral-line-border);
  }

  .oxq-table-row:where([data-type='group'], [data-type='band'], [data-type='total']) {
    --_bg: var(--oxq-neutral-surface-subtle);
  }

  .oxq-table-row:where(
    [data-type='subtotal'],
    [data-type='total'],
    [data-type='add'],
    [data-type='empty'],
    [data-type='band'],
    [data-type='drilldown']
  ) {
    border-block-end-style: none;
  }

  .oxq-table-row:where([data-type='subtotal']) {
    border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-border);
  }

  /* Coi bordi collassati, a parità di spessore vince il filo della riga sopra: prende il colore del subtotal. */
  .oxq-table-row:where(:has(+ [data-type='subtotal'])) {
    border-block-end-color: var(--oxq-neutral-line-border);
  }

  .oxq-table-row:where([data-type='total'], [data-type='band']) {
    border-block-start: var(--oxq-stroke-emphasis) solid var(--oxq-neutral-line-border-strong);
  }

  .oxq-table-row:where([data-type='add']) {
    border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
  }

  .oxq-table-row:where([data-type='perimeter']) {
    --_bg: var(--oxq-brand-surface-soft);
  }

  @media (hover: hover) {
    .oxq-table-row:where(:not([data-type]), [data-type='add']):where(:hover) {
      --_bg: var(--oxq-system-state-hover);
    }
  }

  .oxq-table-row:where([data-state='expanded'], [data-state='editing']) {
    --_bg: var(--oxq-neutral-surface-subtle);
  }

  .oxq-table-row:where([data-state='selected'], :not([data-type]):has(> .oxq-table-cell .oxq-checkbox input:checked)) {
    --_bg: var(--oxq-brand-surface-soft);
  }

  .oxq-table-row:where([data-state='read-only']),
  .oxq-table-band:where([data-readonly]) > .oxq-table-row:where(:not([data-type='band'])) {
    --_bg: var(--oxq-neutral-surface-canvas);
  }

  /* Celle */
  .oxq-table-cell,
  .oxq-table-header-cell,
  .oxq-table-bar,
  .oxq-table-row-message {
    block-size: var(--_h);
    text-align: start;
    vertical-align: middle;
  }

  /* Il filo sotto la riga sta dentro la sua altezza, come in Figma: le celle più alte del minimo lo tolgono dal
     padding sotto. */
  .oxq-table-cell {
    padding: var(--oxq-space-inset-cell-y) var(--oxq-space-inset-item-x)
      calc(var(--oxq-space-inset-cell-y) - var(--oxq-stroke-divider));
    color: var(--oxq-neutral-text-ink);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);

    > * {
      vertical-align: middle;
    }
  }

  .oxq-table-cell:where([data-align='end']) {
    text-align: end;
  }

  .oxq-table-cell:where([data-emphasis='secondary']) {
    color: var(--oxq-neutral-text-secondary);
  }

  .oxq-table-cell:where([data-emphasis='strong']),
  .oxq-table-row:where([data-type='subtotal'], [data-type='total']) > .oxq-table-cell {
    font-weight: var(--oxq-body-sm-font-weight-strong);
  }

  .oxq-table-cell:where([data-highlight]) {
    background-color: var(--oxq-accent-yellow-surface-soft);
  }

  .oxq-table-cell-secondary {
    display: block;
    margin-block-start: var(--oxq-space-gap-item-text);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-table-cell:where([data-type='text-badge']) > .oxq-badge {
    margin-inline-start: var(--oxq-space-gap-xs);
  }

  .oxq-table-cell:where(
    [data-type='checkbox'],
    [data-type='disclosure'],
    [data-type='badge'],
    [data-type='thumbnail'],
    [data-type='action'],
    [data-type='edit-actions']
  ) {
    padding-block: 0;
  }

  /* Le colonne dei controlli si stringono al contenuto: con una larghezza minima in percentuale lo spazio va alle
     altre (con 0 la tabella la ignora). */
  .oxq-table-cell:where(
    [data-type='checkbox'],
    [data-type='disclosure'],
    [data-type='thumbnail'],
    [data-type='action'],
    [data-type='edit-actions']
  ) {
    inline-size: 1%;
    white-space: nowrap;
  }

  .oxq-table-cell:where([data-type='edit-actions']) > * + * {
    margin-inline-start: var(--oxq-space-gap-xs);
  }

  /* thumbnail: la thumbnail sm ridotta alla riga, come l'istanza scalata di Figma; zoom riduce anche il suo posto. */
  .oxq-table-cell:where([data-type='thumbnail']) > .oxq-thumbnail {
    zoom: var(--oxq-scale-thumbnail-table-sm);
  }

  .oxq-table:where([data-size='md']) .oxq-table-cell:where([data-type='thumbnail']) > .oxq-thumbnail {
    zoom: var(--oxq-scale-thumbnail-table-md);
  }

  /* list-item: la cella non ha padding e fa da riferimento al link e all'indent guide del list-item, che così coprono
     tutta l'altezza della riga. */
  .oxq-table-cell:where([data-type='list-item']) {
    position: relative;
    padding: 0;

    > .oxq-list-item {
      position: static;
      padding-block-end: calc(var(--_py) - var(--oxq-stroke-divider));
    }
  }

  /* field: in md il campo sm sta nella cella da 40, in sm la riempie. */
  .oxq-table-cell:where([data-type='field']) {
    padding: 0 var(--oxq-space-inset-cell-y);
  }

  .oxq-table:where([data-size='md']) .oxq-table-cell:where([data-type='field']) {
    padding-block: var(--oxq-space-inset-cell-y);
  }

  .oxq-table-header-cell {
    --_label: var(--oxq-neutral-text-secondary);
    --_arrow: var(--oxq-neutral-icon-muted);
    --_shown: 0;

    position: relative;
    padding: 0 var(--oxq-space-inset-item-x);
    color: var(--_label);
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
    white-space: nowrap;
  }

  .oxq-table-header-cell:where([data-align='center']) {
    text-align: center;
  }

  .oxq-table-header-cell:where([data-align='end']) {
    text-align: end;
  }

  .oxq-table-row:where([data-type='group']) > .oxq-table-header-cell {
    text-transform: uppercase;
  }

  .oxq-table-header-cell-operator {
    margin-inline-end: var(--oxq-space-gap-2xs);
  }

  /* Un button, o un link quando l'ordine lo fa il server (?o=-importo). */
  .oxq-table-header-cell-sort {
    display: inline-flex;
    align-items: center;
    background-color: transparent;
    color: inherit;
    text-decoration: none;
    text-transform: inherit;
    outline: none;

    &::after {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: var(--oxq-radius-selection);
    }

    &:focus-visible::after {
      outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
      outline-offset: calc(-1 * var(--oxq-stroke-focus));
    }

    > .oxq-icon {
      flex-shrink: 0;
      inline-size: var(--oxq-size-icon-sm);
      block-size: var(--oxq-size-icon-sm);
      margin-inline-start: var(--oxq-space-gap-2xs);
      color: var(--_arrow);
      opacity: var(--_shown);
      transition: opacity var(--oxq-duration-state) var(--oxq-easing-transition);
    }
  }

  /* La freccia compare all'hover e al focus della colonna, e resta sulla colonna ordinata. */
  @media (hover: hover) {
    .oxq-table-header-cell:where(:has(> .oxq-table-header-cell-sort:hover)) {
      --_label: var(--oxq-neutral-text-ink);
      --_shown: 1;
    }
  }

  .oxq-table-header-cell:where(:has(> .oxq-table-header-cell-sort:focus-visible)) {
    --_label: var(--oxq-neutral-text-ink);
    --_shown: 1;
  }

  .oxq-table-header-cell:where([aria-sort]) {
    --_label: var(--oxq-neutral-text-ink);
    --_arrow: var(--oxq-neutral-icon-ink);
    --_shown: 1;
  }

  /* Righe a tutta larghezza */
  .oxq-table-row-message {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    text-align: center;
  }

  .oxq-table-row-content {
    display: inline-flex;
    align-items: center;
    gap: var(--oxq-space-gap-table-row);
    vertical-align: middle;
  }

  .oxq-table-row:where([data-type='add']) > .oxq-table-row-message {
    block-size: var(--_add);
    padding-inline: calc(var(--oxq-space-inset-container) - var(--oxq-space-inset-item-x));
    text-align: start;
  }

  .oxq-table-row:where([data-type='empty']) > .oxq-table-row-message {
    padding-block: var(--_empty);
  }

  .oxq-table-row:where([data-type='perimeter']) > .oxq-table-row-message {
    color: var(--oxq-neutral-text-ink);
  }

  /* Il drilldown inline arriva ai bordi della riga, sopra le due celle del padding. */
  .oxq-table-row:where([data-type='drilldown']) > .oxq-table-row-message {
    text-align: start;

    > .oxq-drilldown {
      margin-inline: calc(-1 * var(--oxq-space-inset-item-x));
    }
  }

  /* Barra di band, group e radice */
  .oxq-table-bar {
    padding: 0;
    font: var(--oxq-font-label-sm);
    letter-spacing: var(--oxq-label-sm-letter-spacing);
  }

  .oxq-table-bar-content {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-table-row);

    > .oxq-disclosure {
      flex: 1 1 auto;
      gap: inherit;
      min-inline-size: 0;
    }
  }

  .oxq-table-bar-label {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    color: var(--oxq-neutral-text-ink);
    font-weight: var(--oxq-label-sm-font-weight-strong);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-table-bar-meta {
    flex-shrink: 0;
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
    white-space: nowrap;
  }

  .oxq-table-band:where([data-readonly]) .oxq-table-bar-label {
    color: var(--oxq-neutral-text-secondary);
    font-weight: var(--oxq-label-sm-font-weight);
  }

  /* group: la barra della radice e delle righe di table-tree-drilldown, con le misure di disclosure e header cell. */
  .oxq-table-row:where([data-type='group']) > .oxq-table-bar {
    padding-inline: var(--oxq-space-inset-item-x);

    .oxq-table-bar-content {
      gap: calc(2 * var(--oxq-space-inset-item-x));
    }

    :is(.oxq-table-bar-label, .oxq-table-bar-meta) {
      color: var(--oxq-neutral-text-secondary);
      font: var(--oxq-font-label-sm);
      letter-spacing: var(--oxq-label-sm-letter-spacing);
    }
  }

  /* Le righe della band rientrano: il primo testo parte dove parte la label della barra. */
  .oxq-table-band > .oxq-table-row:where(:not([data-type='band'])) > :first-child {
    padding-inline-start: calc(var(--oxq-size-icon-sm) + var(--oxq-space-gap-table-row));
  }

  .oxq-expandable-row > .oxq-table-row:first-child:where(:has(.oxq-disclosure[aria-expanded='true'])) {
    --_bg: var(--oxq-neutral-surface-subtle);
  }

  :where(.oxq-table-band, .oxq-expandable-row, .oxq-table-tree-drilldown-group):has(
      > .oxq-table-row:first-child .oxq-disclosure[aria-expanded='false']
    )
    > .oxq-table-row:not(:first-child) {
    display: none;
  }
}
/* Editable cell (Atoms › Editable cell): la cella di una griglia modificabile, dentro table-row.
   - il valore è un input readonly. Con il focus la cella è active (bordo system/focus/ring e quadratino); doppio clic,
     Invio o un carattere tolgono readonly ed è editing (fondo sunken). Invio conferma, Esc annulla, Tab passa alla
     cella dopo; da active le frecce spostano la cella. Fuori da Vue lo fa oxq.js
   - hover, active ed editing li decide il browser. data-state: range (le celle selezionate oltre l'active), error
     (con il message sotto il valore, che resta visibile), saved (un istante dopo il salvataggio), readonly (valori
     calcolati: testo e secondary, niente input), suggested (il valore proposto, con conferma e scarta)
   - placeholder: la riga in coda per aggiungere un valore, col testo secondary dell'input vuoto
   - data-align (start | end), il ramo dell'albero (tree-branch, tree-end, tree-line) prima del valore, il suffix
     (l'unità) solo in editing. La size viene dalla tabella, come in table-cell. */
@layer components {
  .oxq-editable-cell {
    --_bg: transparent;
    --_value: var(--oxq-neutral-text-ink);
    --_secondary: var(--oxq-neutral-text-secondary);

    position: relative;
    block-size: var(--_h, var(--oxq-size-control-sm));
    padding: var(--oxq-space-inset-cell-y) var(--oxq-space-inset-item-x)
      calc(var(--oxq-space-inset-cell-y) - var(--oxq-stroke-divider));
    background-color: var(--_bg);
    color: var(--_value);
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
    text-align: start;
    vertical-align: middle;
    transition: background-color var(--oxq-duration-state) var(--oxq-easing-transition);
  }

  .oxq-editable-cell:where([data-align='end']) {
    text-align: end;
  }

  .oxq-editable-cell-box {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-inset-item-x);
  }

  .oxq-editable-cell-content {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: var(--oxq-space-gap-item-text);
    min-inline-size: 0;
  }

  .oxq-editable-cell-line {
    display: flex;
    align-items: center;
    gap: var(--oxq-space-gap-cell-suffix);

    > .oxq-icon {
      flex-shrink: 0;
      inline-size: var(--oxq-size-icon-md);
      block-size: var(--oxq-size-icon-md);
      color: var(--oxq-neutral-icon-secondary);
    }
  }

  .oxq-editable-cell-input,
  .oxq-editable-cell-value {
    flex: 1 1 auto;
    min-inline-size: 0;
    color: inherit;
    text-align: inherit;
  }

  .oxq-editable-cell-input {
    inline-size: 100%;
    background-color: transparent;
    outline: none;

    &[readonly] {
      caret-color: transparent;
    }

    &::placeholder {
      color: var(--oxq-neutral-text-secondary);
      opacity: 1;
    }
  }

  .oxq-editable-cell-value,
  .oxq-editable-cell-secondary {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .oxq-editable-cell-suffix {
    display: none;
    flex-shrink: 0;
    color: var(--oxq-neutral-text-secondary);
  }

  .oxq-editable-cell-secondary,
  .oxq-editable-cell-message {
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }

  .oxq-editable-cell-secondary {
    color: var(--_secondary);
  }

  .oxq-editable-cell-message {
    color: var(--oxq-danger-text-ink);
  }

  .oxq-editable-cell-actions {
    display: flex;
    flex-shrink: 0;
    gap: var(--oxq-space-gap-xs);
  }

  @media (hover: hover) {
    .oxq-editable-cell:where(:hover:not(:focus-within)) {
      --_bg: var(--oxq-system-state-hover);
    }
  }

  .oxq-editable-cell:where([data-state='range']) {
    --_bg: var(--oxq-brand-surface-soft);
  }

  .oxq-editable-cell:where([data-state='saved']) {
    --_bg: var(--oxq-success-surface-control);
  }

  .oxq-editable-cell:where([data-state='suggested']) {
    --_value: var(--oxq-info-text-ink);
    --_secondary: var(--oxq-info-text-secondary);
  }

  /* active ed editing: il bordo dentro la cella. active ha il quadratino per trascinare il valore. */
  .oxq-editable-cell:where(:has(.oxq-editable-cell-input:focus)) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }

  .oxq-editable-cell:where(:has(.oxq-editable-cell-input:focus[readonly]))::after {
    content: '';
    position: absolute;
    inset-block-end: 0;
    inset-inline-end: 0;
    inline-size: var(--oxq-size-editable-cell-handle);
    block-size: var(--oxq-size-editable-cell-handle);
    background-color: var(--oxq-system-focus-ring);
  }

  .oxq-editable-cell:where(:has(.oxq-editable-cell-input:focus:not([readonly]))) {
    --_bg: var(--oxq-neutral-surface-sunken);

    .oxq-editable-cell-suffix {
      display: inline;
    }
  }

  .oxq-editable-cell:where([data-state='error']) {
    outline: var(--oxq-stroke-focus) solid var(--oxq-danger-line-control);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }
}
/* Drilldown (Molecules › Drilldown): il dettaglio che si apre sotto una riga di tabella o una voce di elenco.
   data-variant: inline sotto la riga che lo apre (in tabella, in una table-row drilldown), card quando sta da solo.
   Overline, titolo col codice accanto, i valori (metric sm, da 3 a 6) in riga, e il footer: chip a sinistra, la nota
   con autore e data a destra. */
@layer components {
  .oxq-drilldown {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-sm);
    padding: var(--oxq-space-gap-md) var(--oxq-space-gap-lg);
    border-block: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
    background-color: var(--oxq-neutral-surface-sunken);
    color: var(--oxq-neutral-text-ink);
    text-align: start;
  }

  .oxq-drilldown:where([data-variant='card']) {
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
  }

  .oxq-drilldown-header {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-drilldown-overline {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-overline-sm);
    letter-spacing: var(--oxq-overline-sm-letter-spacing);
    text-transform: uppercase;
  }

  .oxq-drilldown-title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-drilldown-title {
    font: var(--oxq-font-title-sm);
    letter-spacing: var(--oxq-title-sm-letter-spacing);
  }

  .oxq-drilldown-code {
    color: var(--oxq-neutral-text-muted);
    font: var(--oxq-font-code-sm);
    letter-spacing: var(--oxq-code-sm-letter-spacing);
  }

  .oxq-drilldown-fields {
    display: flex;
    flex-wrap: wrap;
    gap: var(--oxq-space-gap-xl);
  }

  .oxq-drilldown-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-drilldown-note {
    margin-inline-start: auto;
    color: var(--oxq-neutral-text-muted);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }
}
/* Description item (Atoms › Description item): un dato e il suo nome, in sola lettura, come dt e dd. Per modificare
   sul posto c'è property-item. Prop Figma → data-layout (inline | stacked), data-size (sm | md).
   - inline: la colonna della label è size/description-label, così i valori si allineano fra le righe; il valore va a
     capo sotto sé stesso e la label resta in alto
   - stacked: la label sopra, nelle colonne sotto i 360 px e su mobile
   - la larghezza la dà il contenitore: in Figma il componente è largo size/layout/narrow-max, nella voce del glossario
     riempie la riga
   - in gruppo le righe stanno a space/gap/2xs, senza bordo né fondo */
@layer components {
  .oxq-description-item {
    --_font: var(--oxq-font-body-sm);
    --_ls: var(--oxq-body-sm-letter-spacing);

    display: flex;
    gap: var(--oxq-space-gap-md);
    font: var(--_font);
    letter-spacing: var(--_ls);
  }

  .oxq-description-item:where([data-size='md']) {
    --_font: var(--oxq-font-body-md);
    --_ls: var(--oxq-body-md-letter-spacing);
  }

  .oxq-description-item:where([data-layout='stacked']) {
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-description-item-label {
    flex-shrink: 0;
    color: var(--oxq-neutral-text-secondary);
  }

  .oxq-description-item:where(:not([data-layout='stacked'])) > .oxq-description-item-label {
    inline-size: var(--oxq-size-description-label);
  }

  .oxq-description-item-value {
    flex: 1 1 auto;
    min-inline-size: 0;
    color: var(--oxq-neutral-text-ink);
  }
}
/* Glossary (Organisms › Glossary): il glossario dei numeri, con la ricerca. Lo stesso blocco nella page e in uno
   sheet di aiuto aperto da un KPI.
   - titolo heading/sm, che nello sheet si toglie; search field md, che filtra termine e definizione mentre si scrive
     (oxq.js, o OxqGlossary.vue); senza voci trovate l'empty state md, con la parola cercata
   - glossary-group: il titolo del gruppo (title/sm) e le sue voci; si nasconde quando la ricerca non ne trova
   - glossary-entry: termine, definizione e righe description-item inline, sotto un filo hairline. data-size: sm negli
     sheet, md nella page. :target è la voce a cui porta un link (state target): fondo brand/surface/soft */
@layer components {
  .oxq-glossary {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-lg);
    max-inline-size: var(--oxq-size-layout-prose-max);
    color: var(--oxq-neutral-text-ink);
  }

  .oxq-glossary-title {
    font: var(--oxq-font-heading-sm);
    letter-spacing: var(--oxq-heading-sm-letter-spacing);
  }

  .oxq-glossary-entries {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-glossary > .oxq-empty-state {
    padding-block: var(--oxq-space-gap-2xl);
  }

  .oxq-glossary-group {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-glossary-group:where(:not(:has(.oxq-glossary-entry:not([hidden])))) {
    display: none;
  }

  .oxq-glossary-group-title {
    font: var(--oxq-font-title-sm);
    letter-spacing: var(--oxq-title-sm-letter-spacing);
  }

  .oxq-glossary-group > dl {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-xs);
  }

  .oxq-glossary-entry {
    --_font: var(--oxq-font-body-sm);
    --_ls: var(--oxq-body-sm-letter-spacing);
    --_strong: var(--oxq-body-sm-font-weight-strong);
    --_py: var(--oxq-space-gap-sm);

    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    margin-block-start: var(--oxq-stroke-divider);
    padding: var(--_py) var(--oxq-space-inset-item-x);
    border-radius: var(--oxq-radius-item);
    font: var(--_font);
    letter-spacing: var(--_ls);
    scroll-margin-block: var(--oxq-space-gap-lg);
  }

  .oxq-glossary-entry:where([data-size='md']) {
    --_font: var(--oxq-font-body-md);
    --_ls: var(--oxq-body-md-letter-spacing);
    --_strong: var(--oxq-body-md-font-weight-strong);
    --_py: var(--oxq-space-gap-md);
  }

  /* Il filo sta sopra la voce, fuori dal fondo arrotondato della voce target. */
  .oxq-glossary-entry::before {
    content: '';
    position: absolute;
    inset: calc(-1 * var(--oxq-stroke-divider)) 0 auto;
    block-size: var(--oxq-stroke-divider);
    background-color: var(--oxq-neutral-line-hairline);
  }

  .oxq-glossary-entry:where(:target) {
    background-color: var(--oxq-brand-surface-soft);
  }

  .oxq-glossary-entry-term {
    font-weight: var(--_strong);
  }

  .oxq-glossary-entry-definition {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
  }

  .oxq-glossary-entry-details {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    padding-block-start: var(--oxq-space-gap-xs);
  }
}
/* Period picker (Organisms › Period picker): un periodo a mesi, aperto in un popover da una cella o da un campo.
   Scorciatoie a sinistra (al più 3, button con l'aspetto del menu-item), i 12 mesi dell'anno a destra, il riepilogo
   sotto. Con data-range il primo clic sceglie l'inizio e il secondo chiude il periodo; senza, un clic scrive l'ultimo
   giorno del mese. La scelta, la tastiera e il riepilogo li fanno OxqPeriodPicker e, in Django, oxq.js.
   Il mese (date-picker-month) ha le selection e gli stati del giorno del date picker: single, range-start,
   range-middle e range-end, col band brand/surface/soft; il mese in corso (aria-current) ha l'anello da 1 px. */
@layer components {
  .oxq-period-picker {
    --_cell: var(--oxq-size-control-md);
    --_band: var(--oxq-brand-surface-soft);

    box-sizing: border-box;
    flex-direction: column;
    /* Il bordo si aggiunge al padding, come lo stroke inside+layout di Figma. */
    padding: var(--oxq-space-gap-2xs);
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-2);
    color: var(--oxq-neutral-text-ink);
  }

  .oxq-period-picker:where(:not([popover]), :popover-open) {
    display: inline-flex;
  }

  .oxq-period-picker:where([popover]) {
    transition-behavior: allow-discrete;
    transition-property: opacity, display, overlay;
    transition-duration: var(--oxq-duration-open);
    transition-timing-function: var(--oxq-easing-transition);

    @starting-style {
      opacity: 0;
    }
  }

  .oxq-period-picker:where([popover]:not(:popover-open)) {
    opacity: 0;
  }

  /* Sotto la cella o il campo che lo apre, allineato a sinistra; sopra se sotto non c'è spazio. */
  @supports (position-area: block-end) {
    .oxq-period-picker:where([popover]) {
      inset: auto;
      margin: var(--oxq-space-gap-2xs) 0 0;
      position-area: block-end span-inline-end;
      position-try-fallbacks:
        flip-block,
        flip-inline,
        flip-block flip-inline;
    }
  }

  .oxq-period-picker-columns {
    display: flex;
  }

  /* Il filo verticale si aggiunge ai 200 px della colonna, come il divider di Figma. */
  .oxq-period-picker-shortcuts {
    box-sizing: content-box;
    display: flex;
    flex-direction: column;
    inline-size: var(--oxq-size-period-picker-shortcuts);
    border-inline-end: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
  }

  .oxq-period-picker-months {
    display: flex;
    flex-direction: column;
  }

  /* Figma non lega i margini della griglia e del riepilogo: qui sono item-x, gap/xs e gap/2xs, gli stessi valori. */
  .oxq-period-picker-grid {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-2xs);
    padding: 0 var(--oxq-space-inset-item-x) var(--oxq-space-gap-xs);

    & > [role='row'] {
      display: flex;
    }
  }

  .oxq-period-picker-grid [role='gridcell'] {
    block-size: var(--_cell);
    outline: none;
    cursor: pointer;
  }

  .oxq-period-picker-month {
    --_bg: transparent;
    --_fg: var(--oxq-neutral-text-ink);
    --_ring: transparent;

    box-sizing: border-box;
    display: grid;
    place-items: center;
    inline-size: var(--oxq-size-period-picker-month);
    block-size: var(--_cell);
    border: var(--oxq-stroke-control) solid var(--_ring);
    border-radius: var(--oxq-radius-pill);
    background-color: var(--_bg);
    color: var(--_fg);
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
    transition-property: background-color, border-color, color;
    transition-duration: var(--oxq-duration-state);
    transition-timing-function: var(--oxq-easing-transition);
  }

  /* Il band: a tutta cella in mezzo, la metà verso l'interno all'inizio e alla fine. */
  .oxq-period-picker-grid [role='gridcell']:where([data-selection='range-middle']) {
    background-color: var(--_band);
  }

  .oxq-period-picker-grid [role='gridcell']:where([data-selection='range-start']) {
    background-image: linear-gradient(to right, transparent 50%, var(--_band) 50%);
  }

  .oxq-period-picker-grid [role='gridcell']:where([data-selection='range-end']) {
    background-image: linear-gradient(to left, transparent 50%, var(--_band) 50%);
  }

  .oxq-period-picker-grid [role='gridcell']:where([aria-current='date']) > .oxq-period-picker-month {
    --_ring: var(--oxq-neutral-line-border-strong);
  }

  .oxq-period-picker-grid
    [role='gridcell']:where([data-selection='single'], [data-selection='range-start'], [data-selection='range-end'])
    > .oxq-period-picker-month {
    --_bg: var(--oxq-neutral-surface-solid);
    --_fg: var(--oxq-neutral-text-on-ink);
    --_ring: transparent;
  }

  @media (hover: hover) {
    .oxq-period-picker-grid [role='gridcell']:where(:not([aria-disabled='true'])):hover > .oxq-period-picker-month {
      --_bg: var(--oxq-system-state-hover);
    }

    .oxq-period-picker-grid
      [role='gridcell']:where(
        [data-selection='single'],
        [data-selection='range-start'],
        [data-selection='range-end']
      ):where(:not([aria-disabled='true'])):hover
      > .oxq-period-picker-month {
      --_bg: var(--oxq-neutral-surface-solid-hover);
    }
  }

  .oxq-period-picker-grid [role='gridcell']:focus-visible > .oxq-period-picker-month {
    outline: var(--oxq-stroke-focus) solid var(--oxq-system-focus-ring);
    outline-offset: calc(-1 * var(--oxq-stroke-focus));
  }

  .oxq-period-picker-grid [role='gridcell']:where([aria-disabled='true']) {
    cursor: not-allowed;

    & > .oxq-period-picker-month {
      --_fg: var(--oxq-neutral-text-muted);

      transition: none;
    }
  }

  .oxq-period-picker-grid
    [role='gridcell']:where([aria-disabled='true'][aria-current='date']):where(
      :not([data-selection='single'], [data-selection='range-start'], [data-selection='range-end'])
    )
    > .oxq-period-picker-month {
    --_ring: var(--oxq-neutral-line-border);
  }

  .oxq-period-picker-summary {
    display: flex;
    flex-direction: column;
    gap: var(--oxq-space-gap-item-text);
    padding: var(--oxq-space-gap-xs) var(--oxq-space-inset-item-x);
    border-block-start: var(--oxq-stroke-divider) solid var(--oxq-neutral-line-hairline);
  }

  .oxq-period-picker-value {
    font: var(--oxq-font-body-sm);
    letter-spacing: var(--oxq-body-sm-letter-spacing);
  }

  .oxq-period-picker-helper {
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }
}
/* Command palette (Organisms › Command palette): la ricerca globale da tastiera, Ctrl K o ⌘ K. Un dialog sopra lo
   scrim system/scrim/soft, in alto al centro: il campo (un combobox) e il listbox dei risultati, coi menu-label dei
   gruppi e i menu-item lg (role option) con icona e description. Per scegliere un valore in un campo c'è la listbox.
   - la voce attiva (aria-selected) segue le frecce: il fondo di hover, la label strong e il tasto ↵
   - senza risultati la riga che dice cosa non ha trovato; mentre arrivano, tre righe skeleton (aria-busy)
   - il footer ricorda i tasti; si toglie dopo il primo uso */
@layer components {
  .oxq-command-palette {
    box-sizing: border-box;
    flex-direction: column;
    inline-size: var(--oxq-size-command-palette);
    max-inline-size: calc(100% - 2 * var(--oxq-space-layout-margin));
    max-block-size: calc(100% - 2 * var(--oxq-space-layout-section));
    margin: var(--oxq-space-layout-section) auto auto;
    /* Il bordo sta dentro il padding, come lo stroke inside di Figma. */
    padding: calc(var(--oxq-space-gap-2xs) - var(--oxq-stroke-control));
    border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-popover);
    border-radius: var(--oxq-radius-surface);
    background-color: var(--oxq-neutral-surface-raised);
    box-shadow: var(--oxq-elevation-3);
    color: var(--oxq-neutral-text-ink);
    opacity: 0;
    transition-behavior: allow-discrete;
    transition-property: opacity, display, overlay;
    transition-duration: var(--oxq-duration-surface);
    transition-timing-function: var(--oxq-easing-transition);

    &::backdrop {
      background-color: var(--oxq-system-scrim-soft);
      opacity: 0;
      transition-behavior: allow-discrete;
      transition-property: opacity, display, overlay;
      transition-duration: var(--oxq-duration-surface);
      transition-timing-function: var(--oxq-easing-transition);
    }

    &[open] {
      display: flex;
    }

    &[open],
    &[open]::backdrop {
      opacity: 1;

      @starting-style {
        opacity: 0;
      }
    }
  }

  .oxq-command-palette-search {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--oxq-space-gap-sm);
    min-block-size: var(--oxq-size-control-lg);
    padding: 0 var(--oxq-space-inset-item-x);

    > .oxq-icon {
      flex-shrink: 0;
      inline-size: var(--oxq-size-icon-md);
      block-size: var(--oxq-size-icon-md);
      color: var(--oxq-neutral-icon-secondary);
    }
  }

  /* Il campo è l'unico controllo e ha sempre il focus: il cursore basta, come in Figma. */
  .oxq-command-palette-input {
    flex: 1 1 auto;
    min-inline-size: 0;
    background-color: transparent;
    font: var(--oxq-font-body-lg);
    letter-spacing: var(--oxq-body-lg-letter-spacing);
    outline: none;

    &::placeholder {
      color: var(--oxq-neutral-text-secondary);
      opacity: 1;
    }

    &::-webkit-search-cancel-button {
      display: none;
    }
  }

  .oxq-command-palette-list {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-block-size: 0;
    overflow-y: auto;
  }

  .oxq-command-palette-list:where(:not(:has([role='option']:not([hidden])))) {
    display: none;
  }

  .oxq-command-palette-list > [role='option']:where([aria-selected='true']) {
    --_bg: var(--_bg-active);
    --_overlay: var(--_overlay-active);

    > .oxq-menu-item-text > .oxq-menu-item-label {
      font-weight: var(--_strong);
    }

    /* Il tasto ↵, solo sulla voce attiva: decorativo, il footer lo dice. */
    &::after {
      content: '↵' / '';
      display: inline-flex;
      flex-shrink: 0;
      align-items: center;
      justify-content: center;
      min-inline-size: var(--oxq-size-kbd-sm);
      block-size: var(--oxq-size-kbd-sm);
      padding-inline: var(--oxq-space-gap-2xs);
      border: var(--oxq-stroke-control) solid var(--oxq-neutral-line-border);
      border-radius: var(--oxq-radius-selection);
      color: var(--oxq-neutral-text-secondary);
      font: var(--oxq-font-label-sm);
      letter-spacing: var(--oxq-label-sm-letter-spacing);
    }
  }

  .oxq-command-palette-empty {
    padding: var(--oxq-space-gap-xl) var(--oxq-space-inset-item-x);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-md);
    letter-spacing: var(--oxq-body-md-letter-spacing);
    text-align: center;
  }

  .oxq-command-palette-loading {
    display: flex;
    flex-direction: column;
  }

  .oxq-command-palette-loading > .oxq-skeleton {
    box-sizing: content-box;
    inline-size: auto;
    block-size: var(--oxq-size-skeleton-text);
    margin: var(--oxq-space-gap-sm) var(--oxq-space-inset-item-x);
    border-radius: var(--oxq-radius-selection);
  }

  .oxq-command-palette-footer {
    display: flex;
    flex-shrink: 0;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--oxq-space-gap-xs);
    min-block-size: var(--oxq-size-control-sm);
    padding: 0 var(--oxq-space-inset-item-x);
    color: var(--oxq-neutral-text-secondary);
    font: var(--oxq-font-body-xs);
    letter-spacing: var(--oxq-body-xs-letter-spacing);
  }
}
