/* GENERADO por scripts/build.mjs a partir de tokens/. No editar a mano. */

@layer ds.tokens, ds.base, ds.layout, ds.components;

/* Rutas relativas a dist/css/. Fuentes con licencia SIL OFL 1.1 (assets/fonts/geist/OFL.txt). */
@font-face {
  font-family: "Geist";
  src: url("/assets/fonts/Geist-Variable.a369fcf562.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Geist";
  src: url("/assets/fonts/Geist-Italic-Variable.5aa7d48f11.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Geist Mono";
  src: url("/assets/fonts/GeistMono-Variable.fba8f577f3.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@layer ds.tokens {
  :root {
    --ds-ref-color-brand-50: #fff4f1;
    --ds-ref-color-brand-100: #fee7e1;
    --ds-ref-color-brand-200: #facdc3;
    --ds-ref-color-brand-300: #f3a89a;
    --ds-ref-color-brand-400: #e57665;
    --ds-ref-color-brand-500: #cd4133;
    --ds-ref-color-brand-600: #9c1a15;
    --ds-ref-color-brand-700: #7d1010;
    --ds-ref-color-brand-800: #5f060a;
    --ds-ref-color-brand-900: #410304;
    --ds-ref-color-brand-950: #290102;
    --ds-ref-color-ember: #f58039;
    --ds-ref-color-neutral-0: #ffffff;
    --ds-ref-color-neutral-50: #f9f6f6;
    --ds-ref-color-neutral-100: #f1eded;
    --ds-ref-color-neutral-200: #e1dddc;
    --ds-ref-color-neutral-300: #cbc6c5;
    --ds-ref-color-neutral-400: #a9a3a2;
    --ds-ref-color-neutral-500: #857e7d;
    --ds-ref-color-neutral-600: #655f5e;
    --ds-ref-color-neutral-700: #494343;
    --ds-ref-color-neutral-800: #322c2b;
    --ds-ref-color-neutral-850: #272121;
    --ds-ref-color-neutral-900: #1d1817;
    --ds-ref-color-neutral-950: #130f0f;
    --ds-ref-color-neutral-1000: #0a0707;
    --ds-ref-color-band-light: #fff2ee;
    --ds-ref-color-band-dark: #301f1d;
    --ds-ref-color-success-50: #f1f9f3;
    --ds-ref-color-success-100: #e2f2e5;
    --ds-ref-color-success-200: #c3e3ca;
    --ds-ref-color-success-300: #96cea4;
    --ds-ref-color-success-400: #56b273;
    --ds-ref-color-success-500: #009149;
    --ds-ref-color-success-600: #00602e;
    --ds-ref-color-success-700: #005126;
    --ds-ref-color-success-800: #003b1a;
    --ds-ref-color-success-900: #00270f;
    --ds-ref-color-success-950: #001707;
    --ds-ref-color-warning-50: #fcf6ee;
    --ds-ref-color-warning-100: #f8ebdb;
    --ds-ref-color-warning-200: #efd4b5;
    --ds-ref-color-warning-300: #e1b57e;
    --ds-ref-color-warning-400: #ce8c25;
    --ds-ref-color-warning-500: #a56b00;
    --ds-ref-color-warning-600: #744900;
    --ds-ref-color-warning-700: #5d3a00;
    --ds-ref-color-warning-800: #452a00;
    --ds-ref-color-warning-900: #2e1a00;
    --ds-ref-color-warning-950: #1c0e00;
    --ds-ref-color-danger-50: #fff4f4;
    --ds-ref-color-danger-100: #ffe6e8;
    --ds-ref-color-danger-200: #ffc9ce;
    --ds-ref-color-danger-300: #fca0ab;
    --ds-ref-color-danger-400: #f1677f;
    --ds-ref-color-danger-500: #d91e56;
    --ds-ref-color-danger-600: #a6003c;
    --ds-ref-color-danger-700: #7f002c;
    --ds-ref-color-danger-800: #5f001f;
    --ds-ref-color-danger-900: #410013;
    --ds-ref-color-danger-950: #290009;
    --ds-ref-color-white: #ffffff;
    --ds-ref-color-black: #000000;
    --ds-ref-font-size-12: 0.75rem;
    --ds-ref-font-size-14: 0.875rem;
    --ds-ref-font-size-16: 1rem;
    --ds-ref-font-size-18: 1.125rem;
    --ds-ref-font-size-20: 1.25rem;
    --ds-ref-font-size-24: 1.5rem;
    --ds-ref-font-size-28: 1.75rem;
    --ds-ref-font-size-32: 2rem;
    --ds-ref-font-size-40: 2.5rem;
    --ds-ref-font-size-48: 3rem;
    --ds-ref-font-size-56: 3.5rem;
    --ds-ref-font-size-72: 4.5rem;
    --ds-ref-font-size-96: 6rem;
    --ds-ref-font-weight-regular: 400;
    --ds-ref-font-weight-medium: 500;
    --ds-ref-font-weight-semibold: 600;
    --ds-ref-font-weight-bold: 700;
    --ds-ref-font-line-height-100: 1;
    --ds-ref-font-line-height-110: 1.1;
    --ds-ref-font-line-height-120: 1.2;
    --ds-ref-font-line-height-130: 1.3;
    --ds-ref-font-line-height-150: 1.5;
    --ds-ref-font-tracking-tighter: -0.03em;
    --ds-ref-font-tracking-tight: -0.02em;
    --ds-ref-font-tracking-snug: -0.01em;
    --ds-ref-font-tracking-normal: 0em;
    --ds-z-base: 0;
    --ds-z-raised: 10;
    --ds-z-sticky: 100;
    --ds-z-overlay: 1000;
    --ds-z-modal: 1100;
    --ds-z-toast: 1200;
    --ds-material-glass-filter: saturate(180%) blur(24px);
    --ds-duration-instant: 100ms;
    --ds-duration-fast: 200ms;
    --ds-duration-base: 320ms;
    --ds-duration-slow: 560ms;
    --ds-ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1);
    --ds-ease-emphasized: cubic-bezier(0.32, 0.72, 0, 1);
    --ds-ease-exit: cubic-bezier(0.4, 0, 1, 1);
    --ds-radius-sm: 8px;
    --ds-radius-md: 12px;
    --ds-radius-lg: 24px;
    --ds-radius-full: 9999px;
    --ds-border-width-default: 1px;
    --ds-border-width-strong: 2px;
    --ds-size-control-md: 2.75rem;
    --ds-size-control-lg: 3.5rem;
    --ds-size-icon-sm: 1rem;
    --ds-size-icon-md: 1.25rem;
    --ds-size-icon-lg: 1.5rem;
    --ds-size-nav: 3.5rem;
    --ds-focus-ring-width: 2px;
    --ds-focus-ring-offset: 2px;
    --ds-opacity-disabled: 0.4;
    --ds-space-xs: 0.25rem;
    --ds-space-sm: 0.5rem;
    --ds-space-md: 1rem;
    --ds-space-lg: 1.5rem;
    --ds-space-xl: 2rem;
    --ds-space-2xl: 3rem;
    --ds-space-3xl: 4rem;
    --ds-space-4xl: 6rem;
    --ds-layout-gutter: clamp(1rem, 0.6479rem + 1.5023vw, 2rem);
    --ds-layout-section: clamp(4rem, 3.2958rem + 3.0047vw, 6rem);
    --ds-layout-measure: 34em;
    --ds-layout-paragraph: 1.5lh;
    --ds-container-narrow: 680px;
    --ds-container-default: 1120px;
    --ds-container-wide: 1440px;
    --ds-breakpoint-sm: 640px;
    --ds-breakpoint-md: 1024px;
    --ds-breakpoint-lg: 1440px;
    --ds-font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", "Arial", sans-serif;
    --ds-font-mono: "Geist Mono", ui-monospace, "SF Mono", "Menlo", "Consolas", monospace;
    --ds-text-display-xl-family: var(--ds-font-sans);
    --ds-text-display-xl-size: clamp(3.5rem, 2.6197rem + 3.7559vw, 6rem);
    --ds-text-display-xl-weight: var(--ds-ref-font-weight-bold);
    --ds-text-display-xl-leading: var(--ds-ref-font-line-height-100);
    --ds-text-display-xl-tracking: var(--ds-ref-font-tracking-tighter);
    --ds-text-display-lg-family: var(--ds-font-sans);
    --ds-text-display-lg-size: clamp(3rem, 2.4718rem + 2.2535vw, 4.5rem);
    --ds-text-display-lg-weight: var(--ds-ref-font-weight-bold);
    --ds-text-display-lg-leading: var(--ds-ref-font-line-height-100);
    --ds-text-display-lg-tracking: var(--ds-ref-font-tracking-tighter);
    --ds-text-display-md-family: var(--ds-font-sans);
    --ds-text-display-md-size: clamp(2.5rem, 2.1479rem + 1.5023vw, 3.5rem);
    --ds-text-display-md-weight: var(--ds-ref-font-weight-semibold);
    --ds-text-display-md-leading: var(--ds-ref-font-line-height-110);
    --ds-text-display-md-tracking: var(--ds-ref-font-tracking-tight);
    --ds-text-heading-xl-family: var(--ds-font-sans);
    --ds-text-heading-xl-size: clamp(2rem, 1.8239rem + 0.7512vw, 2.5rem);
    --ds-text-heading-xl-weight: var(--ds-ref-font-weight-semibold);
    --ds-text-heading-xl-leading: var(--ds-ref-font-line-height-110);
    --ds-text-heading-xl-tracking: var(--ds-ref-font-tracking-tight);
    --ds-text-heading-lg-family: var(--ds-font-sans);
    --ds-text-heading-lg-size: clamp(1.75rem, 1.662rem + 0.3756vw, 2rem);
    --ds-text-heading-lg-weight: var(--ds-ref-font-weight-semibold);
    --ds-text-heading-lg-leading: var(--ds-ref-font-line-height-120);
    --ds-text-heading-lg-tracking: var(--ds-ref-font-tracking-snug);
    --ds-text-heading-md-family: var(--ds-font-sans);
    --ds-text-heading-md-size: var(--ds-ref-font-size-24);
    --ds-text-heading-md-weight: var(--ds-ref-font-weight-semibold);
    --ds-text-heading-md-leading: var(--ds-ref-font-line-height-120);
    --ds-text-heading-md-tracking: var(--ds-ref-font-tracking-snug);
    --ds-text-heading-sm-family: var(--ds-font-sans);
    --ds-text-heading-sm-size: var(--ds-ref-font-size-20);
    --ds-text-heading-sm-weight: var(--ds-ref-font-weight-semibold);
    --ds-text-heading-sm-leading: var(--ds-ref-font-line-height-130);
    --ds-text-heading-sm-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-body-lg-family: var(--ds-font-sans);
    --ds-text-body-lg-size: clamp(1.125rem, 1.081rem + 0.1878vw, 1.25rem);
    --ds-text-body-lg-weight: var(--ds-ref-font-weight-regular);
    --ds-text-body-lg-leading: var(--ds-ref-font-line-height-150);
    --ds-text-body-lg-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-body-md-family: var(--ds-font-sans);
    --ds-text-body-md-size: var(--ds-ref-font-size-16);
    --ds-text-body-md-weight: var(--ds-ref-font-weight-regular);
    --ds-text-body-md-leading: var(--ds-ref-font-line-height-150);
    --ds-text-body-md-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-body-sm-family: var(--ds-font-sans);
    --ds-text-body-sm-size: var(--ds-ref-font-size-14);
    --ds-text-body-sm-weight: var(--ds-ref-font-weight-regular);
    --ds-text-body-sm-leading: var(--ds-ref-font-line-height-150);
    --ds-text-body-sm-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-label-lg-family: var(--ds-font-sans);
    --ds-text-label-lg-size: var(--ds-ref-font-size-16);
    --ds-text-label-lg-weight: var(--ds-ref-font-weight-medium);
    --ds-text-label-lg-leading: var(--ds-ref-font-line-height-120);
    --ds-text-label-lg-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-label-md-family: var(--ds-font-sans);
    --ds-text-label-md-size: var(--ds-ref-font-size-14);
    --ds-text-label-md-weight: var(--ds-ref-font-weight-medium);
    --ds-text-label-md-leading: var(--ds-ref-font-line-height-120);
    --ds-text-label-md-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-caption-family: var(--ds-font-sans);
    --ds-text-caption-size: var(--ds-ref-font-size-12);
    --ds-text-caption-weight: var(--ds-ref-font-weight-regular);
    --ds-text-caption-leading: var(--ds-ref-font-line-height-150);
    --ds-text-caption-tracking: var(--ds-ref-font-tracking-normal);
    --ds-text-code-family: var(--ds-font-mono);
    --ds-text-code-size: var(--ds-ref-font-size-14);
    --ds-text-code-weight: var(--ds-ref-font-weight-regular);
    --ds-text-code-leading: var(--ds-ref-font-line-height-150);
    --ds-text-code-tracking: var(--ds-ref-font-tracking-normal);
  }

  :root,
  [data-theme="light"] {
    color-scheme: light;
    --ds-bg-canvas: var(--ds-ref-color-neutral-0);
    --ds-bg-surface: var(--ds-ref-color-neutral-50);
    --ds-bg-raised: var(--ds-ref-color-neutral-0);
    --ds-bg-sunken: var(--ds-ref-color-neutral-100);
    --ds-bg-inverse: var(--ds-ref-color-neutral-950);
    --ds-bg-brand: var(--ds-ref-color-brand-600);
    --ds-bg-glow: color-mix(in srgb, var(--ds-ref-color-brand-500) 16%, transparent);
    --ds-bg-scrim: color-mix(in srgb, var(--ds-ref-color-neutral-1000) 48%, transparent);
    --ds-bg-band: var(--ds-ref-color-band-light);
    --ds-bg-band-glow: color-mix(in srgb, var(--ds-ref-color-brand-400) 6%, transparent);
    --ds-fg-primary: var(--ds-ref-color-neutral-950);
    --ds-fg-secondary: var(--ds-ref-color-neutral-700);
    --ds-fg-brand: var(--ds-ref-color-brand-600);
    --ds-fg-inverse: var(--ds-ref-color-neutral-50);
    --ds-fg-on-brand: var(--ds-ref-color-white);
    --ds-border-subtle: color-mix(in srgb, var(--ds-ref-color-neutral-950) 10%, transparent);
    --ds-border-control: var(--ds-ref-color-neutral-500);
    --ds-border-selected: var(--ds-ref-color-brand-600);
    --ds-action-primary-bg: var(--ds-ref-color-brand-600);
    --ds-action-primary-bg-hover: var(--ds-ref-color-brand-700);
    --ds-action-primary-bg-active: var(--ds-ref-color-brand-800);
    --ds-action-primary-fg: var(--ds-ref-color-white);
    --ds-action-secondary-bg: color-mix(in srgb, var(--ds-ref-color-neutral-950) 6%, transparent);
    --ds-action-secondary-bg-hover: color-mix(in srgb, var(--ds-ref-color-neutral-950) 10%, transparent);
    --ds-action-secondary-bg-active: color-mix(in srgb, var(--ds-ref-color-neutral-950) 14%, transparent);
    --ds-action-secondary-fg: var(--ds-ref-color-neutral-950);
    --ds-action-ghost-bg-hover: color-mix(in srgb, var(--ds-ref-color-neutral-950) 6%, transparent);
    --ds-action-ghost-bg-active: color-mix(in srgb, var(--ds-ref-color-neutral-950) 10%, transparent);
    --ds-action-ghost-fg: var(--ds-ref-color-neutral-950);
    --ds-action-danger-bg: var(--ds-ref-color-danger-600);
    --ds-action-danger-bg-hover: var(--ds-ref-color-danger-700);
    --ds-action-danger-bg-active: var(--ds-ref-color-danger-800);
    --ds-action-danger-fg: var(--ds-ref-color-white);
    --ds-status-info-fg: var(--ds-ref-color-neutral-950);
    --ds-status-info-bg: var(--ds-ref-color-neutral-100);
    --ds-status-info-border: var(--ds-ref-color-neutral-200);
    --ds-status-success-fg: var(--ds-ref-color-success-600);
    --ds-status-success-bg: var(--ds-ref-color-success-50);
    --ds-status-success-border: var(--ds-ref-color-success-200);
    --ds-status-warning-fg: var(--ds-ref-color-warning-600);
    --ds-status-warning-bg: var(--ds-ref-color-warning-50);
    --ds-status-warning-border: var(--ds-ref-color-warning-200);
    --ds-status-danger-fg: var(--ds-ref-color-danger-600);
    --ds-status-danger-bg: var(--ds-ref-color-danger-50);
    --ds-status-danger-border: var(--ds-ref-color-danger-200);
    --ds-focus-ring: var(--ds-ref-color-brand-500);
    --ds-material-glass-bg: color-mix(in srgb, var(--ds-ref-color-neutral-50) 80%, transparent);
    --ds-material-glass-border: color-mix(in srgb, var(--ds-ref-color-neutral-950) 8%, transparent);
    --ds-shadow-raised: 0px 1px 2px 0px #0000000f, 0px 4px 16px 0px #0000000d;
    --ds-shadow-overlay: 0px 4px 12px 0px #00000014, 0px 16px 40px 0px #0000001f;
    --ds-shadow-modal: 0px 8px 24px 0px #0000001a, 0px 32px 80px 0px #0000003d;
    --ds-gradient-brand: linear-gradient(135deg, var(--ds-ref-color-brand-950) 0%, var(--ds-ref-color-brand-700) 50%, var(--ds-ref-color-brand-600) 100%);
    --ds-gradient-text: linear-gradient(90deg, var(--ds-ref-color-brand-900) 0%, var(--ds-ref-color-brand-600) 100%);
    --ds-gradient-glow: radial-gradient(ellipse 80% 60% at 50% 0%, var(--ds-bg-glow) 0%, #00000000 100%);
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      color-scheme: dark;
      --ds-bg-canvas: var(--ds-ref-color-neutral-1000);
      --ds-bg-surface: var(--ds-ref-color-neutral-900);
      --ds-bg-raised: var(--ds-ref-color-neutral-850);
      --ds-bg-sunken: var(--ds-ref-color-black);
      --ds-bg-inverse: var(--ds-ref-color-neutral-50);
      --ds-bg-brand: var(--ds-ref-color-brand-600);
      --ds-bg-glow: color-mix(in srgb, var(--ds-ref-color-brand-600) 50%, transparent);
      --ds-bg-scrim: color-mix(in srgb, var(--ds-ref-color-black) 64%, transparent);
      --ds-bg-band: var(--ds-ref-color-band-dark);
      --ds-bg-band-glow: color-mix(in srgb, var(--ds-ref-color-brand-600) 28%, transparent);
      --ds-fg-primary: var(--ds-ref-color-neutral-50);
      --ds-fg-secondary: var(--ds-ref-color-neutral-300);
      --ds-fg-brand: var(--ds-ref-color-brand-300);
      --ds-fg-inverse: var(--ds-ref-color-neutral-950);
      --ds-fg-on-brand: var(--ds-ref-color-white);
      --ds-border-subtle: color-mix(in srgb, var(--ds-ref-color-white) 10%, transparent);
      --ds-border-control: var(--ds-ref-color-neutral-500);
      --ds-border-selected: var(--ds-ref-color-brand-400);
      --ds-action-primary-bg: var(--ds-ref-color-brand-600);
      --ds-action-primary-bg-hover: var(--ds-ref-color-brand-700);
      --ds-action-primary-bg-active: var(--ds-ref-color-brand-800);
      --ds-action-primary-fg: var(--ds-ref-color-white);
      --ds-action-secondary-bg: color-mix(in srgb, var(--ds-ref-color-white) 10%, transparent);
      --ds-action-secondary-bg-hover: color-mix(in srgb, var(--ds-ref-color-white) 16%, transparent);
      --ds-action-secondary-bg-active: color-mix(in srgb, var(--ds-ref-color-white) 22%, transparent);
      --ds-action-secondary-fg: var(--ds-ref-color-neutral-50);
      --ds-action-ghost-bg-hover: color-mix(in srgb, var(--ds-ref-color-white) 8%, transparent);
      --ds-action-ghost-bg-active: color-mix(in srgb, var(--ds-ref-color-white) 14%, transparent);
      --ds-action-ghost-fg: var(--ds-ref-color-neutral-50);
      --ds-action-danger-bg: var(--ds-ref-color-danger-600);
      --ds-action-danger-bg-hover: var(--ds-ref-color-danger-700);
      --ds-action-danger-bg-active: var(--ds-ref-color-danger-800);
      --ds-action-danger-fg: var(--ds-ref-color-white);
      --ds-status-info-fg: var(--ds-ref-color-neutral-50);
      --ds-status-info-bg: var(--ds-ref-color-neutral-850);
      --ds-status-info-border: var(--ds-ref-color-neutral-700);
      --ds-status-success-fg: var(--ds-ref-color-success-300);
      --ds-status-success-bg: var(--ds-ref-color-success-950);
      --ds-status-success-border: var(--ds-ref-color-success-800);
      --ds-status-warning-fg: var(--ds-ref-color-warning-300);
      --ds-status-warning-bg: var(--ds-ref-color-warning-950);
      --ds-status-warning-border: var(--ds-ref-color-warning-800);
      --ds-status-danger-fg: var(--ds-ref-color-danger-300);
      --ds-status-danger-bg: var(--ds-ref-color-danger-950);
      --ds-status-danger-border: var(--ds-ref-color-danger-800);
      --ds-focus-ring: var(--ds-ref-color-brand-400);
      --ds-material-glass-bg: color-mix(in srgb, var(--ds-ref-color-neutral-950) 80%, transparent);
      --ds-material-glass-border: color-mix(in srgb, var(--ds-ref-color-white) 8%, transparent);
      --ds-shadow-raised: inset 0px 1px 0px 0px #ffffff0f, 0px 8px 24px 0px #00000066;
      --ds-shadow-overlay: inset 0px 1px 0px 0px #ffffff14, 0px 16px 40px 0px #00000099;
      --ds-shadow-modal: inset 0px 1px 0px 0px #ffffff14, 0px 32px 80px 0px #000000b3;
      --ds-gradient-brand: linear-gradient(135deg, var(--ds-ref-color-brand-950) 0%, var(--ds-ref-color-brand-700) 50%, var(--ds-ref-color-brand-600) 100%);
      --ds-gradient-text: linear-gradient(90deg, var(--ds-ref-color-brand-400) 0%, var(--ds-ref-color-ember) 100%);
      --ds-gradient-glow: radial-gradient(ellipse 80% 60% at 50% 0%, var(--ds-bg-glow) 0%, #00000000 100%);
    }
  }

  [data-theme="dark"] {
    color-scheme: dark;
    --ds-bg-canvas: var(--ds-ref-color-neutral-1000);
    --ds-bg-surface: var(--ds-ref-color-neutral-900);
    --ds-bg-raised: var(--ds-ref-color-neutral-850);
    --ds-bg-sunken: var(--ds-ref-color-black);
    --ds-bg-inverse: var(--ds-ref-color-neutral-50);
    --ds-bg-brand: var(--ds-ref-color-brand-600);
    --ds-bg-glow: color-mix(in srgb, var(--ds-ref-color-brand-600) 50%, transparent);
    --ds-bg-scrim: color-mix(in srgb, var(--ds-ref-color-black) 64%, transparent);
    --ds-bg-band: var(--ds-ref-color-band-dark);
    --ds-bg-band-glow: color-mix(in srgb, var(--ds-ref-color-brand-600) 28%, transparent);
    --ds-fg-primary: var(--ds-ref-color-neutral-50);
    --ds-fg-secondary: var(--ds-ref-color-neutral-300);
    --ds-fg-brand: var(--ds-ref-color-brand-300);
    --ds-fg-inverse: var(--ds-ref-color-neutral-950);
    --ds-fg-on-brand: var(--ds-ref-color-white);
    --ds-border-subtle: color-mix(in srgb, var(--ds-ref-color-white) 10%, transparent);
    --ds-border-control: var(--ds-ref-color-neutral-500);
    --ds-border-selected: var(--ds-ref-color-brand-400);
    --ds-action-primary-bg: var(--ds-ref-color-brand-600);
    --ds-action-primary-bg-hover: var(--ds-ref-color-brand-700);
    --ds-action-primary-bg-active: var(--ds-ref-color-brand-800);
    --ds-action-primary-fg: var(--ds-ref-color-white);
    --ds-action-secondary-bg: color-mix(in srgb, var(--ds-ref-color-white) 10%, transparent);
    --ds-action-secondary-bg-hover: color-mix(in srgb, var(--ds-ref-color-white) 16%, transparent);
    --ds-action-secondary-bg-active: color-mix(in srgb, var(--ds-ref-color-white) 22%, transparent);
    --ds-action-secondary-fg: var(--ds-ref-color-neutral-50);
    --ds-action-ghost-bg-hover: color-mix(in srgb, var(--ds-ref-color-white) 8%, transparent);
    --ds-action-ghost-bg-active: color-mix(in srgb, var(--ds-ref-color-white) 14%, transparent);
    --ds-action-ghost-fg: var(--ds-ref-color-neutral-50);
    --ds-action-danger-bg: var(--ds-ref-color-danger-600);
    --ds-action-danger-bg-hover: var(--ds-ref-color-danger-700);
    --ds-action-danger-bg-active: var(--ds-ref-color-danger-800);
    --ds-action-danger-fg: var(--ds-ref-color-white);
    --ds-status-info-fg: var(--ds-ref-color-neutral-50);
    --ds-status-info-bg: var(--ds-ref-color-neutral-850);
    --ds-status-info-border: var(--ds-ref-color-neutral-700);
    --ds-status-success-fg: var(--ds-ref-color-success-300);
    --ds-status-success-bg: var(--ds-ref-color-success-950);
    --ds-status-success-border: var(--ds-ref-color-success-800);
    --ds-status-warning-fg: var(--ds-ref-color-warning-300);
    --ds-status-warning-bg: var(--ds-ref-color-warning-950);
    --ds-status-warning-border: var(--ds-ref-color-warning-800);
    --ds-status-danger-fg: var(--ds-ref-color-danger-300);
    --ds-status-danger-bg: var(--ds-ref-color-danger-950);
    --ds-status-danger-border: var(--ds-ref-color-danger-800);
    --ds-focus-ring: var(--ds-ref-color-brand-400);
    --ds-material-glass-bg: color-mix(in srgb, var(--ds-ref-color-neutral-950) 80%, transparent);
    --ds-material-glass-border: color-mix(in srgb, var(--ds-ref-color-white) 8%, transparent);
    --ds-shadow-raised: inset 0px 1px 0px 0px #ffffff0f, 0px 8px 24px 0px #00000066;
    --ds-shadow-overlay: inset 0px 1px 0px 0px #ffffff14, 0px 16px 40px 0px #00000099;
    --ds-shadow-modal: inset 0px 1px 0px 0px #ffffff14, 0px 32px 80px 0px #000000b3;
    --ds-gradient-brand: linear-gradient(135deg, var(--ds-ref-color-brand-950) 0%, var(--ds-ref-color-brand-700) 50%, var(--ds-ref-color-brand-600) 100%);
    --ds-gradient-text: linear-gradient(90deg, var(--ds-ref-color-brand-400) 0%, var(--ds-ref-color-ember) 100%);
    --ds-gradient-glow: radial-gradient(ellipse 80% 60% at 50% 0%, var(--ds-bg-glow) 0%, #00000000 100%);
  }
}

@layer ds.base {
  .ds-text-display-xl {
    font-family: var(--ds-text-display-xl-family);
    font-size: var(--ds-text-display-xl-size);
    font-weight: var(--ds-text-display-xl-weight);
    line-height: var(--ds-text-display-xl-leading);
    letter-spacing: var(--ds-text-display-xl-tracking);
  }

  .ds-text-display-lg {
    font-family: var(--ds-text-display-lg-family);
    font-size: var(--ds-text-display-lg-size);
    font-weight: var(--ds-text-display-lg-weight);
    line-height: var(--ds-text-display-lg-leading);
    letter-spacing: var(--ds-text-display-lg-tracking);
  }

  .ds-text-display-md {
    font-family: var(--ds-text-display-md-family);
    font-size: var(--ds-text-display-md-size);
    font-weight: var(--ds-text-display-md-weight);
    line-height: var(--ds-text-display-md-leading);
    letter-spacing: var(--ds-text-display-md-tracking);
  }

  .ds-text-heading-xl {
    font-family: var(--ds-text-heading-xl-family);
    font-size: var(--ds-text-heading-xl-size);
    font-weight: var(--ds-text-heading-xl-weight);
    line-height: var(--ds-text-heading-xl-leading);
    letter-spacing: var(--ds-text-heading-xl-tracking);
  }

  .ds-text-heading-lg {
    font-family: var(--ds-text-heading-lg-family);
    font-size: var(--ds-text-heading-lg-size);
    font-weight: var(--ds-text-heading-lg-weight);
    line-height: var(--ds-text-heading-lg-leading);
    letter-spacing: var(--ds-text-heading-lg-tracking);
  }

  .ds-text-heading-md {
    font-family: var(--ds-text-heading-md-family);
    font-size: var(--ds-text-heading-md-size);
    font-weight: var(--ds-text-heading-md-weight);
    line-height: var(--ds-text-heading-md-leading);
    letter-spacing: var(--ds-text-heading-md-tracking);
  }

  .ds-text-heading-sm {
    font-family: var(--ds-text-heading-sm-family);
    font-size: var(--ds-text-heading-sm-size);
    font-weight: var(--ds-text-heading-sm-weight);
    line-height: var(--ds-text-heading-sm-leading);
    letter-spacing: var(--ds-text-heading-sm-tracking);
  }

  .ds-text-body-lg {
    font-family: var(--ds-text-body-lg-family);
    font-size: var(--ds-text-body-lg-size);
    font-weight: var(--ds-text-body-lg-weight);
    line-height: var(--ds-text-body-lg-leading);
    letter-spacing: var(--ds-text-body-lg-tracking);
  }

  .ds-text-body-md {
    font-family: var(--ds-text-body-md-family);
    font-size: var(--ds-text-body-md-size);
    font-weight: var(--ds-text-body-md-weight);
    line-height: var(--ds-text-body-md-leading);
    letter-spacing: var(--ds-text-body-md-tracking);
  }

  .ds-text-body-sm {
    font-family: var(--ds-text-body-sm-family);
    font-size: var(--ds-text-body-sm-size);
    font-weight: var(--ds-text-body-sm-weight);
    line-height: var(--ds-text-body-sm-leading);
    letter-spacing: var(--ds-text-body-sm-tracking);
  }

  .ds-text-label-lg {
    font-family: var(--ds-text-label-lg-family);
    font-size: var(--ds-text-label-lg-size);
    font-weight: var(--ds-text-label-lg-weight);
    line-height: var(--ds-text-label-lg-leading);
    letter-spacing: var(--ds-text-label-lg-tracking);
  }

  .ds-text-label-md {
    font-family: var(--ds-text-label-md-family);
    font-size: var(--ds-text-label-md-size);
    font-weight: var(--ds-text-label-md-weight);
    line-height: var(--ds-text-label-md-leading);
    letter-spacing: var(--ds-text-label-md-tracking);
  }

  .ds-text-caption {
    font-family: var(--ds-text-caption-family);
    font-size: var(--ds-text-caption-size);
    font-weight: var(--ds-text-caption-weight);
    line-height: var(--ds-text-caption-leading);
    letter-spacing: var(--ds-text-caption-tracking);
  }

  .ds-text-code {
    font-family: var(--ds-text-code-family);
    font-size: var(--ds-text-code-size);
    font-weight: var(--ds-text-code-weight);
    line-height: var(--ds-text-code-leading);
    letter-spacing: var(--ds-text-code-tracking);
  }

  /* Reset y estilos de elemento. Todo valor sale de un token. */

  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  * {
    margin: 0;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    background: var(--ds-bg-canvas);
    color: var(--ds-fg-primary);
    font-family: var(--ds-text-body-md-family);
    font-size: var(--ds-text-body-md-size);
    font-weight: var(--ds-text-body-md-weight);
    line-height: var(--ds-text-body-md-leading);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
  }

  /* Ámbitos de tema anidados (bandas oscuras, superficies de marca) heredan su color de texto. */
  [data-theme] {
    color: var(--ds-fg-primary);
  }

  img,
  picture,
  video,
  canvas,
  svg {
    display: block;
    max-width: 100%;
  }

  input,
  button,
  textarea,
  select {
    font: inherit;
    color: inherit;
  }

  h1,
  h2,
  h3,
  h4 {
    text-wrap: balance;
  }

  p,
  li {
    text-wrap: pretty;
  }

  h1 {
    font: var(--ds-text-heading-xl-weight) var(--ds-text-heading-xl-size) / var(--ds-text-heading-xl-leading) var(--ds-text-heading-xl-family);
    letter-spacing: var(--ds-text-heading-xl-tracking);
  }

  h2 {
    font: var(--ds-text-heading-lg-weight) var(--ds-text-heading-lg-size) / var(--ds-text-heading-lg-leading) var(--ds-text-heading-lg-family);
    letter-spacing: var(--ds-text-heading-lg-tracking);
  }

  h3 {
    font: var(--ds-text-heading-md-weight) var(--ds-text-heading-md-size) / var(--ds-text-heading-md-leading) var(--ds-text-heading-md-family);
    letter-spacing: var(--ds-text-heading-md-tracking);
  }

  h4 {
    font: var(--ds-text-heading-sm-weight) var(--ds-text-heading-sm-size) / var(--ds-text-heading-sm-leading) var(--ds-text-heading-sm-family);
    letter-spacing: var(--ds-text-heading-sm-tracking);
  }

  a {
    color: var(--ds-fg-brand);
    text-decoration: none;
    text-underline-offset: 0.2em;
  }

  a:hover {
    text-decoration: underline;
  }

  strong,
  b {
    font-weight: var(--ds-ref-font-weight-semibold);
  }

  code,
  kbd,
  samp,
  pre {
    font-family: var(--ds-font-mono);
    font-size: 0.875em;
  }

  pre {
    padding: var(--ds-space-md);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-sunken);
    overflow-x: auto;
  }

  hr {
    border: 0;
    border-block-start: var(--ds-border-width-default) solid var(--ds-border-subtle);
  }

  ::selection {
    background: var(--ds-bg-brand);
    color: var(--ds-fg-on-brand);
  }

  :focus-visible {
    outline: var(--ds-focus-ring-width) solid var(--ds-focus-ring);
    outline-offset: var(--ds-focus-ring-offset);
  }

  :disabled,
  [aria-disabled="true"] {
    opacity: var(--ds-opacity-disabled);
    cursor: not-allowed;
  }

  /* Utilidades de sistema: las únicas permitidas fuera de componentes. */

  .ds-text-gradient {
    background: var(--ds-gradient-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  .ds-text-secondary {
    color: var(--ds-fg-secondary);
  }

  .ds-numeric {
    font-variant-numeric: tabular-nums;
  }

  .ds-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Colores elegidos por el usuario (WCAG 1.4.8): el texto degradado vuelve al color del sistema. */
  @media (forced-colors: active) {
    .ds-text-gradient {
      background: none;
      color: CanvasText;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}

@layer ds.layout {
  /* Primitivas de maquetación. Los gaps se ajustan con --ds-gap usando solo tokens space.* */

  .ds-container {
    width: 100%;
    max-width: calc(var(--ds-container-default) + 2 * var(--ds-layout-gutter));
    margin-inline: auto;
    padding-inline: var(--ds-layout-gutter);
  }

  .ds-container--narrow {
    max-width: calc(var(--ds-container-narrow) + 2 * var(--ds-layout-gutter));
  }

  .ds-container--wide {
    max-width: calc(var(--ds-container-wide) + 2 * var(--ds-layout-gutter));
  }

  .ds-section {
    padding-block: var(--ds-layout-section);
  }

  .ds-stack {
    display: flex;
    flex-direction: column;
    gap: var(--ds-gap, var(--ds-space-md));
  }

  .ds-cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-gap, var(--ds-space-sm));
  }

  .ds-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(var(--ds-grid-min, 18rem), 100%), 1fr));
    gap: var(--ds-gap, var(--ds-space-lg));
  }

  /* Bloques de texto (WCAG 1.4.8): ancho máximo de ~70 caracteres, sin justificar
     y separación entre párrafos de 1,5 veces el interlineado. */
  .ds-prose {
    max-width: var(--ds-layout-measure);
    text-align: start;
  }

  .ds-prose > * + * {
    margin-block-start: var(--ds-space-md);
  }

  .ds-prose > :is(p, ul, ol, blockquote, pre) + :is(p, ul, ol, blockquote, pre) {
    margin-block-start: var(--ds-layout-paragraph);
  }

  .ds-prose > * + :is(h2, h3, h4) {
    margin-block-start: var(--ds-space-2xl);
  }

  /* Superficie de marca: combinar siempre con data-theme="dark". El foco pasa a blanco (WCAG 2.4.13). */
  .ds-surface-brand {
    --ds-focus-ring: var(--ds-fg-on-brand);

    background: var(--ds-gradient-brand);
    color: var(--ds-fg-on-brand);
  }
}

@layer ds.components {
  .ds-alert {
    --_bg: var(--ds-status-info-bg);
    --_fg: var(--ds-status-info-fg);
    --_border: var(--ds-status-info-border);

    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--ds-space-sm);
    padding: var(--ds-space-md);
    border-radius: var(--ds-radius-md);
    background: var(--_bg);
    border: var(--ds-border-width-default) solid var(--_border);
    color: var(--ds-fg-primary);
    font-family: var(--ds-text-body-sm-family);
    font-size: var(--ds-text-body-sm-size);
    line-height: var(--ds-text-body-sm-leading);
  }

  .ds-alert__icon {
    width: var(--ds-size-icon-md);
    height: var(--ds-size-icon-md);
    margin-block-start: calc((1lh - var(--ds-size-icon-md)) / 2);
    color: var(--_fg);
  }

  .ds-alert__body {
    display: grid;
    gap: var(--ds-space-xs);
  }

  .ds-alert__title {
    color: var(--_fg);
    font-family: var(--ds-text-label-md-family);
    font-size: var(--ds-text-label-md-size);
    font-weight: var(--ds-ref-font-weight-semibold);
    line-height: inherit;
  }

  .ds-alert--success {
    --_bg: var(--ds-status-success-bg);
    --_fg: var(--ds-status-success-fg);
    --_border: var(--ds-status-success-border);
  }

  .ds-alert--warning {
    --_bg: var(--ds-status-warning-bg);
    --_fg: var(--ds-status-warning-fg);
    --_border: var(--ds-status-warning-border);
  }

  .ds-alert--danger {
    --_bg: var(--ds-status-danger-bg);
    --_fg: var(--ds-status-danger-fg);
    --_border: var(--ds-status-danger-border);
  }

  .ds-badge {
    --_bg: var(--ds-status-info-bg);
    --_fg: var(--ds-status-info-fg);
    --_border: var(--ds-status-info-border);

    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-xs);
    padding: var(--ds-space-xs) var(--ds-space-sm);
    border-radius: var(--ds-radius-full);
    background: var(--_bg);
    border: var(--ds-border-width-default) solid var(--_border);
    color: var(--_fg);
    font-family: var(--ds-text-label-md-family);
    font-size: var(--ds-text-label-md-size);
    font-weight: var(--ds-text-label-md-weight);
    line-height: var(--ds-text-label-md-leading);
    white-space: nowrap;
  }

  .ds-badge--brand {
    --_bg: var(--ds-bg-brand);
    --_fg: var(--ds-fg-on-brand);
    --_border: transparent;
  }

  .ds-badge--success {
    --_bg: var(--ds-status-success-bg);
    --_fg: var(--ds-status-success-fg);
    --_border: var(--ds-status-success-border);
  }

  .ds-badge--warning {
    --_bg: var(--ds-status-warning-bg);
    --_fg: var(--ds-status-warning-fg);
    --_border: var(--ds-status-warning-border);
  }

  .ds-badge--danger {
    --_bg: var(--ds-status-danger-bg);
    --_fg: var(--ds-status-danger-fg);
    --_border: var(--ds-status-danger-border);
  }

  .ds-button {
    --_bg: var(--ds-action-primary-bg);
    --_bg-hover: var(--ds-action-primary-bg-hover);
    --_bg-active: var(--ds-action-primary-bg-active);
    --_fg: var(--ds-action-primary-fg);
    --_highlight: inset 0 1px 0 color-mix(in srgb, var(--ds-ref-color-white) 16%, transparent);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ds-space-sm);
    min-height: var(--ds-size-control-md);
    padding-inline: var(--ds-space-lg);
    /* Borde transparente: en modo de alto contraste el sistema lo pinta y el botón sigue siendo visible. */
    border: var(--ds-border-width-default) solid transparent;
    border-radius: var(--ds-radius-full);
    background: var(--_bg);
    box-shadow: var(--_highlight);
    color: var(--_fg);
    font-family: var(--ds-text-label-lg-family);
    font-size: var(--ds-text-label-lg-size);
    font-weight: var(--ds-text-label-lg-weight);
    line-height: var(--ds-text-label-lg-leading);
    letter-spacing: var(--ds-text-label-lg-tracking);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition:
      background-color var(--ds-duration-fast) var(--ds-ease-standard),
      transform var(--ds-duration-instant) var(--ds-ease-standard);
  }

  .ds-button:hover {
    background: var(--_bg-hover);
    text-decoration: none;
  }

  .ds-button:active {
    background: var(--_bg-active);
    transform: scale(0.98);
  }

  .ds-button:disabled,
  .ds-button[aria-disabled="true"] {
    pointer-events: none;
  }

  .ds-button svg {
    flex: none;
    width: var(--ds-size-icon-md);
    height: var(--ds-size-icon-md);
  }

  .ds-button--secondary {
    --_bg: var(--ds-action-secondary-bg);
    --_bg-hover: var(--ds-action-secondary-bg-hover);
    --_bg-active: var(--ds-action-secondary-bg-active);
    --_fg: var(--ds-action-secondary-fg);
    --_highlight: none;
  }

  .ds-button--ghost {
    --_bg: transparent;
    --_bg-hover: var(--ds-action-ghost-bg-hover);
    --_bg-active: var(--ds-action-ghost-bg-active);
    --_fg: var(--ds-action-ghost-fg);
    --_highlight: none;
  }

  .ds-button--danger {
    --_bg: var(--ds-action-danger-bg);
    --_bg-hover: var(--ds-action-danger-bg-hover);
    --_bg-active: var(--ds-action-danger-bg-active);
    --_fg: var(--ds-action-danger-fg);
  }

  .ds-button--lg {
    min-height: var(--ds-size-control-lg);
    padding-inline: var(--ds-space-xl);
  }

  .ds-button--icon {
    width: var(--ds-size-control-md);
    padding-inline: 0;
  }

  .ds-button--icon.ds-button--lg {
    width: var(--ds-size-control-lg);
  }

  /* Sobre superficies de marca el primario se invierte: el carmesí no compite consigo mismo. */
  .ds-surface-brand .ds-button:not(.ds-button--secondary, .ds-button--ghost, .ds-button--danger),
  .ds-card--brand .ds-button:not(.ds-button--secondary, .ds-button--ghost, .ds-button--danger) {
    --_bg: var(--ds-bg-inverse);
    --_bg-hover: color-mix(in srgb, var(--ds-bg-inverse) 88%, transparent);
    --_bg-active: color-mix(in srgb, var(--ds-bg-inverse) 80%, transparent);
    --_fg: var(--ds-fg-inverse);
    --_highlight: none;
  }

  .ds-card {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-md);
    padding: var(--ds-space-xl);
    border: var(--ds-border-width-default) solid transparent;
    border-radius: var(--ds-radius-lg);
    background: var(--ds-bg-surface);
    color: var(--ds-fg-primary);
  }

  .ds-card > :is(.ds-badge, .ds-button, .ds-link) {
    align-self: flex-start;
  }

  .ds-card > :last-child:is(.ds-button, .ds-link) {
    margin-block-start: auto;
  }

  .ds-card--raised {
    background: var(--ds-bg-raised);
    box-shadow: var(--ds-shadow-raised);
  }

  /* Combinar con data-theme="dark". El foco pasa a blanco para mantener 3:1 sobre el carmesí (WCAG 2.4.13). */
  .ds-card--brand {
    --ds-focus-ring: var(--ds-fg-on-brand);

    background: var(--ds-gradient-brand);
    color: var(--ds-fg-on-brand);
  }

  .ds-card--interactive {
    transition:
      transform var(--ds-duration-base) var(--ds-ease-emphasized),
      box-shadow var(--ds-duration-base) var(--ds-ease-standard);
  }

  .ds-card--interactive:hover {
    transform: scale(1.01);
    box-shadow: var(--ds-shadow-overlay);
  }

  .ds-card__media {
    margin: calc(-1 * var(--ds-space-xl)) calc(-1 * var(--ds-space-xl)) 0;
    border-radius: var(--ds-radius-lg) var(--ds-radius-lg) 0 0;
    overflow: hidden;
  }

  .ds-card__media > img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
  }

  .ds-field {
    display: grid;
    gap: var(--ds-space-sm);
  }

  .ds-field__label {
    color: var(--ds-fg-primary);
    font-family: var(--ds-text-label-md-family);
    font-size: var(--ds-text-label-md-size);
    font-weight: var(--ds-text-label-md-weight);
    line-height: var(--ds-text-label-md-leading);
  }

  .ds-field__control {
    width: 100%;
    min-height: var(--ds-size-control-md);
    padding-inline: var(--ds-space-md);
    border: var(--ds-border-width-default) solid var(--ds-border-control);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-canvas);
    color: var(--ds-fg-primary);
    font-family: var(--ds-text-body-md-family);
    font-size: var(--ds-text-body-md-size);
    line-height: var(--ds-text-body-md-leading);
    transition: border-color var(--ds-duration-fast) var(--ds-ease-standard);
  }

  textarea.ds-field__control {
    min-height: calc(var(--ds-size-control-md) * 3);
    padding-block: var(--ds-space-sm);
    resize: vertical;
  }

  .ds-field__control::placeholder {
    color: var(--ds-fg-secondary);
  }

  .ds-field__control:hover {
    border-color: var(--ds-fg-secondary);
  }

  .ds-field__control:focus {
    border-color: var(--ds-border-selected);
    outline: var(--ds-focus-ring-width) solid var(--ds-focus-ring);
    outline-offset: var(--ds-focus-ring-offset);
  }

  .ds-field__hint {
    display: flex;
    gap: var(--ds-space-xs);
    color: var(--ds-fg-secondary);
    font-family: var(--ds-text-body-sm-family);
    font-size: var(--ds-text-body-sm-size);
    line-height: var(--ds-text-body-sm-leading);
  }

  .ds-field__hint svg {
    flex: none;
    width: var(--ds-size-icon-sm);
    height: var(--ds-size-icon-sm);
    margin-block-start: calc((1lh - var(--ds-size-icon-sm)) / 2);
  }

  .ds-field[data-invalid] .ds-field__control {
    border-color: var(--ds-status-danger-fg);
  }

  .ds-field[data-invalid] .ds-field__hint {
    color: var(--ds-status-danger-fg);
  }

  /* Enlace independiente: objetivo táctil de 44 px (WCAG 2.5.5). Los enlaces dentro de una frase son <a> sin clase. */
  .ds-link {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-xs);
    min-height: var(--ds-size-control-md);
    color: var(--ds-fg-brand);
    font-weight: var(--ds-ref-font-weight-medium);
    text-decoration: none;
  }

  .ds-link:hover {
    text-decoration: underline;
  }

  .ds-link--chevron::after {
    content: "";
    width: 0.45em;
    height: 0.45em;
    border-block-start: 0.1em solid currentColor;
    border-inline-end: 0.1em solid currentColor;
    transform: rotate(45deg);
    transition: transform var(--ds-duration-fast) var(--ds-ease-standard);
  }

  .ds-link--chevron:hover {
    text-decoration: none;
  }

  .ds-link--chevron:hover::after {
    transform: translateX(0.15em) rotate(45deg);
  }

  .ds-surface-brand .ds-link,
  .ds-card--brand .ds-link {
    color: inherit;
    text-decoration: underline;
  }

  /* La barra fija no puede tapar el elemento enfocado al navegar con teclado (WCAG 2.4.12). */
  html:has(.ds-nav) {
    scroll-padding-block-start: calc(var(--ds-size-nav) + var(--ds-space-md));
  }

  .ds-nav {
    position: sticky;
    inset-block-start: 0;
    z-index: var(--ds-z-sticky);
    height: var(--ds-size-nav);
    background: var(--ds-material-glass-bg);
    -webkit-backdrop-filter: var(--ds-material-glass-filter);
    backdrop-filter: var(--ds-material-glass-filter);
    border-block-end: var(--ds-border-width-default) solid var(--ds-material-glass-border);
  }

  .ds-nav__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-lg);
    height: 100%;
  }

  .ds-nav__brand {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-sm);
    min-height: var(--ds-size-control-md);
    color: var(--ds-fg-primary);
    font-family: var(--ds-text-label-lg-family);
    font-size: var(--ds-text-label-lg-size);
    font-weight: var(--ds-ref-font-weight-semibold);
    text-decoration: none;
  }

  .ds-nav__brand:hover {
    text-decoration: none;
  }

  .ds-nav__links {
    display: flex;
    gap: var(--ds-space-lg);
    padding: 0;
    list-style: none;
  }

  /* Sobre material translúcido solo se usa fg.primary: el contraste AAA no depende de lo que pase por detrás. */
  .ds-nav__link {
    display: inline-flex;
    align-items: center;
    min-height: var(--ds-size-control-md);
    color: var(--ds-fg-primary);
    font-family: var(--ds-text-label-md-family);
    font-size: var(--ds-text-label-md-size);
    font-weight: var(--ds-text-label-md-weight);
    text-decoration: none;
    text-underline-offset: 0.4em;
  }

  .ds-nav__link:hover {
    text-decoration: underline;
  }

  .ds-nav__link[aria-current="page"] {
    text-decoration: underline;
    text-decoration-thickness: var(--ds-border-width-strong);
  }

  @media (max-width: 1023.98px) {
    .ds-nav__links {
      display: none;
    }
  }
}

/* Firma animada, desde @l0er/brand/assets/logo/logo-animated-white.svg */
.l0er-draw, .l0er-light { fill: none; stroke-width: 16; stroke-linecap: round; }
.l0er-draw { stroke: #ffffff; }
.l0er-light { stroke: #f58039; opacity: 0; filter: url(#l0er-glow); }
.l0er-glyph { fill: #ffffff; }
#l0er-draw-l { stroke-dasharray: 105.13 210.26; }
#l0er-light-l { stroke-dasharray: 12 315.39; }
#l0er-draw-r { stroke-dasharray: 49.13 98.26; }
#l0er-light-r { stroke-dasharray: 12 147.39; }
@media (prefers-reduced-motion: no-preference) {
  #l0er-draw-l { animation: l0er-draw-l 560ms cubic-bezier(0.32, 0.72, 0, 1) 0ms both; }
  #l0er-light-l { animation: l0er-light-l 560ms cubic-bezier(0.32, 0.72, 0, 1) 0ms both; }
  @keyframes l0er-draw-l { from { stroke-dashoffset: 105.14; } }
  @keyframes l0er-light-l { from { stroke-dashoffset: 12.01; opacity: 1; } 60% { opacity: 1; } to { stroke-dashoffset: -93.13; opacity: 0; } }
  #l0er-draw-r { animation: l0er-draw-r 560ms cubic-bezier(0.32, 0.72, 0, 1) 320ms both; }
  #l0er-light-r { animation: l0er-light-r 560ms cubic-bezier(0.32, 0.72, 0, 1) 320ms both; }
  @keyframes l0er-draw-r { from { stroke-dashoffset: 49.14; } }
  @keyframes l0er-light-r { from { stroke-dashoffset: 12.01; opacity: 1; } 60% { opacity: 1; } to { stroke-dashoffset: -37.13; opacity: 0; } }
  .l0er-glyph:nth-of-type(1) { animation: l0er-rise 560ms cubic-bezier(0.32, 0.72, 0, 1) 420ms both; }
  .l0er-glyph:nth-of-type(2) { animation: l0er-rise 560ms cubic-bezier(0.32, 0.72, 0, 1) 520ms both; }
  .l0er-glyph:nth-of-type(3) { animation: l0er-rise 560ms cubic-bezier(0.32, 0.72, 0, 1) 620ms both; }
  .l0er-glyph:nth-of-type(4) { animation: l0er-rise 560ms cubic-bezier(0.32, 0.72, 0, 1) 720ms both; }
  @keyframes l0er-rise { from { opacity: 0; transform: translateY(8px); } }
}

/* Estilos propios de la web de marca, con prefijo web-. Se añaden después de brand.css, sin capa.
   Solo tokens semánticos: nada de hex, px sueltos ni --ds-ref-* (scripts/check.mjs lo verifica). */

/* Cursor propio: un punto del carmesí de la marca, en toda la web. Es el cursor de verdad (una imagen que genera
   scripts/build.mjs con el color de los tokens), no un elemento que persigue al ratón: así no se retrasa, no hace
   falta JavaScript y es el mismo en todas las páginas. Sobre lo que se puede pulsar, el punto lleva un anillo; en
   los campos de texto se deja el del sistema, que es el que marca dónde se escribe. De cada forma hay dos
   imágenes: el SVG y, detrás, el PNG para Safari, que no dibuja cursores SVG. Si ninguna carga, queda la flecha
   del sistema. Solo con ratón: en pantallas táctiles no hay cursor que cambiar. */
@media (hover: hover) and (pointer: fine) {
  :root {
    --web-cursor: url("/assets/cursor-dot.8314bb8039.svg") 12 12, url("/assets/cursor-dot.42552d4856.png") 12 12;
    --web-cursor-press: url("/assets/cursor-ring.e653215ec2.svg") 12 12, url("/assets/cursor-ring.7eeed6b562.png") 12 12;
  }

  html {
    cursor: var(--web-cursor), auto;
  }

  /* `html` delante para ganar a .ds-button de la marca, que también pone cursor: pointer. */
  html :is(a[href], button, summary, select, label[for], [role="tab"], input:where([type="checkbox"], [type="radio"], [type="file"], [type="submit"], [type="button"])) {
    cursor: var(--web-cursor-press), pointer;
  }

  input:not([type], [type="checkbox"], [type="radio"], [type="file"], [type="submit"], [type="button"]),
  textarea {
    cursor: text;
  }

  :disabled,
  [aria-disabled="true"] {
    cursor: not-allowed;
  }
}

/* En alto contraste del sistema manda el cursor del sistema, que puede estar agrandado o recolorado a propósito. */
@media (forced-colors: active) {
  html,
  a[href],
  button,
  summary,
  select,
  label[for],
  [role="tab"] {
    cursor: revert;
  }
}

/* La web usa el contenedor ancho de la marca (1440 px) en todas partes menos donde se pide uno concreto,
   como el formulario del cuestionario, que se lee mejor estrecho. */
.ds-container:not(.ds-container--narrow):not(.ds-container--wide) {
  max-inline-size: var(--ds-container-wide);
}

/* Barra superior más alta que la del sistema, con el logotipo y los enlaces a mayor tamaño. Se cambia el token
   en la propia barra, así que todo lo que depende del alto de la barra (el salto de contenido, el alto máximo
   del copiloto y el primer bloque a pantalla completa) se ajusta solo. */
:root {
  --ds-size-nav: calc(var(--ds-space-3xl) + var(--ds-space-md));
}

.ds-nav__link,
.web-langs__toggle {
  font-family: var(--ds-text-label-lg-family);
  font-size: var(--ds-text-label-lg-size);
  font-weight: var(--ds-text-label-lg-weight);
}

/* Selector de idioma, en la barra. Cerrado ocupa lo que dos letras; abierto cae sobre el contenido, sin
   empujar nada, para que quepa igual en un móvil que en una pantalla grande. */
.web-langs {
  position: relative;
  flex: none;
}

.web-langs__toggle {
  display: flex;
  align-items: center;
  gap: var(--ds-space-xs);
  min-block-size: var(--ds-size-control-md);
  padding-inline: var(--ds-space-sm);
  color: var(--ds-fg-secondary);
  font-family: var(--ds-text-label-md-family);
  font-size: var(--ds-text-label-md-size);
  font-weight: var(--ds-text-label-md-weight);
  cursor: var(--web-cursor-press, pointer);
  list-style: none;
}

.web-langs__toggle::-webkit-details-marker {
  display: none;
}

.web-langs__toggle:hover {
  color: var(--ds-fg-primary);
}

.web-langs__chevron {
  inline-size: var(--ds-space-sm);
  aspect-ratio: 1;
  border-block-end: var(--ds-border-width-default) solid currentcolor;
  border-inline-end: var(--ds-border-width-default) solid currentcolor;
  rotate: 45deg;
  translate: 0 -25%;
}

.web-langs[open] .web-langs__chevron {
  rotate: 225deg;
  translate: 0 25%;
}

.web-langs__list {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-end: 0;
  z-index: var(--ds-z-overlay);
  display: grid;
  min-inline-size: max-content;
  margin-block-start: var(--ds-space-xs);
  padding: var(--ds-space-xs);
  list-style: none;
  border: var(--ds-border-width-default) solid var(--ds-material-glass-border);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-raised);
  box-shadow: var(--ds-shadow-overlay);
}

.web-langs__link {
  display: flex;
  align-items: center;
  gap: var(--ds-space-sm);
  min-block-size: var(--ds-size-control-md);
  padding-inline: var(--ds-space-sm);
  border-radius: var(--ds-radius-sm);
  color: var(--ds-fg-primary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  text-decoration: none;
}

.web-langs__code {
  color: var(--ds-fg-secondary);
  font-family: var(--ds-font-mono);
}

.web-langs__link:hover {
  background: var(--ds-action-ghost-bg-hover);
  text-decoration: none;
}

.web-langs__link[aria-current="true"],
.web-langs__link[aria-current="true"] .web-langs__code {
  color: var(--ds-fg-brand);
}

/* Enlace de salto: invisible hasta recibir el foco, con el objetivo de 44 px del botón. */
.web-skip {
  position: absolute;
  inset-block-start: var(--ds-space-sm);
  inset-inline-start: var(--ds-space-sm);
  z-index: var(--ds-z-overlay);
}

.web-skip:not(:focus) {
  clip-path: inset(50%);
}

.web-logo {
  width: auto;
  height: var(--ds-space-xl);
}

.web-eyebrow {
  color: var(--ds-fg-brand);
}

/* Hero: halo detrás del contenido y firma animada del logotipo, una vez por página. El halo va al 55% para
   dejarle el color a la aurora, que es la parte que se mueve, sin salirse del contraste AAA: el reparto entre los
   dos está calculado en scripts/check.mjs. */
.web-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: var(--ds-layout-section);
  background: var(--ds-bg-canvas);
}

/* El hero de la portada es una banda más: su difuminado es la aurora, que se mueve. */
.web-hero--band {
  background: var(--ds-bg-band);
}

.web-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--ds-gradient-glow);
  opacity: 0.35;
}

.web-hero__inner {
  display: grid;
  gap: var(--ds-space-2xl);
  justify-items: start;
}

.web-hero__text {
  display: grid;
  gap: var(--ds-space-lg);
}

/* Una palabra larga a tamaño de titular no cabe en un móvil estrecho: en euskera, «Ikusgarritasuna» se salía
   del borde y quedaba cortada. Se parte solo cuando no cabe de otra manera, con guion si el navegador sabe
   partir en ese idioma. */
.web-hero h1 {
  overflow-wrap: break-word;
  hyphens: auto;
}

/* Cada frase del titular empieza línea; el degradado ocupa solo el ancho de su texto. */
.web-hero h1 .ds-text-gradient {
  display: block;
  /* fit-content se queda en el ancho de la palabra más larga: con el tope, esa palabra parte en vez de salirse. */
  width: fit-content;
  max-inline-size: 100%;
}

.web-hero .ds-cluster {
  --ds-gap: var(--ds-space-md);

  margin-block-start: var(--ds-space-sm);
}

/* A 96 px de alto, cada medida del símbolo es un token del sistema. */
.web-signature {
  width: auto;
  height: var(--ds-space-3xl);
}

.web-band {
  background: var(--ds-bg-canvas);
}

.web-band--surface {
  background: var(--ds-bg-surface);
}

/* Bandas de la portada (ADR 0010 de @l0er/brand): fondo bg.band, ni blanco ni negro, con dos difuminados de
   bg.band-glow en esquinas opuestas. Las bandas pares los llevan en las otras dos esquinas, así que bajan en zigzag y
   cada uno sigue en la banda de al lado. La marca garantiza AAA con el tinte a plena intensidad siempre que no se
   superpongan dos: con estas elipses, las de una misma banda no llegan a tocarse. */
.web-band--glow {
  --web-glow-a: 0% 0%;
  --web-glow-b: 100% 100%;

  background:
    radial-gradient(ellipse 55% 75% at var(--web-glow-a), var(--ds-bg-band-glow), transparent),
    radial-gradient(ellipse 55% 75% at var(--web-glow-b), var(--ds-bg-band-glow), transparent),
    var(--ds-bg-band);
}

.web-band--glow:nth-of-type(even) {
  --web-glow-a: 100% 0%;
  --web-glow-b: 0% 100%;
}

.web-head {
  display: grid;
  gap: var(--ds-space-md);
  margin-block-end: var(--ds-space-2xl);
}

.web-list {
  display: grid;
  gap: var(--ds-space-sm);
  padding-inline-start: var(--ds-space-lg);
}

.web-list li::marker {
  color: var(--ds-fg-brand);
}

.ds-surface-brand .web-list li::marker {
  color: currentColor;
}

.web-steps {
  display: grid;
  gap: var(--ds-space-xl) var(--ds-space-lg);
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.web-step,
.web-point {
  display: grid;
  align-content: start;
  gap: var(--ds-space-sm);
  padding-block-start: var(--ds-space-lg);
  border-block-start: var(--ds-border-width-default) solid var(--ds-border-subtle);
}

.web-step {
  counter-increment: step;
}

.web-step h3::before {
  content: counter(step, decimal-leading-zero);
  margin-inline-end: var(--ds-space-sm);
  color: var(--ds-fg-brand);
  font-variant-numeric: tabular-nums;
}

.web-faq {
  display: grid;
  gap: var(--ds-space-2xl) var(--ds-space-xl);
}

.web-faq__item {
  display: grid;
  align-content: start;
  gap: var(--ds-space-sm);
}

.web-contact {
  display: grid;
  gap: var(--ds-space-2xl);
  align-items: start;
}

.web-contact__main {
  display: grid;
  gap: var(--ds-space-lg);
}

.web-contact__main .ds-cluster {
  --ds-gap: var(--ds-space-md) var(--ds-space-lg);
}

.web-contact__brief {
  display: grid;
  gap: var(--ds-space-md);
}

.web-footer {
  padding-block: var(--ds-space-2xl);
  border-block-start: var(--ds-border-width-default) solid var(--ds-border-subtle);
}

/* El copiloto flota en esta esquina: el pie le deja el hueco para que no tape los enlaces legales. */
.web-footer__inner {
  padding-inline-end: calc(var(--ds-size-control-lg) + var(--ds-space-2xl));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--ds-space-md) var(--ds-space-lg);
}

.web-footer__links {
  --ds-gap: 0 var(--ds-space-lg);

  padding: 0;
  list-style: none;
}

/* Catálogo: galería horizontal de tarjetas, como «Get the highlights» de apple.com/ipad-pro. La primera tarjeta
   se alinea con el contenido de la página y el carril sigue hasta el borde de la pantalla, así que la siguiente
   asoma por la derecha. --web-gallery-inset es ese margen: el del contenedor ancho de la marca más su medianil.
   Sin JavaScript es un carril que se desplaza en horizontal y se ajusta a cada tarjeta; src/home.js le añade los
   puntos, el botón de pausa y el paso automático (final del archivo). */
.web-gallery {
  --web-gallery-inset: calc(max(0%, (100% - var(--ds-container-wide)) / 2) + var(--ds-layout-gutter));
  /* Lo que dura cada tarjeta con el paso automático: lo que tarda en llenarse su punto. */
  --web-gallery-time: 4s;

  display: grid;
  gap: var(--ds-space-xl);
}

.web-gallery__track {
  position: relative;
  display: flex;
  gap: var(--ds-space-lg);
  padding-block: var(--ds-space-sm);
  padding-inline: var(--web-gallery-inset);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--web-gallery-inset);
  scrollbar-width: thin;
}

/* El carril recibe el foco para poder recorrerlo con las flechas: el anillo va por dentro, que por fuera lo
   recortaría el propio desplazamiento. */
.web-gallery__track:focus-visible {
  outline-offset: calc(var(--ds-focus-ring-width) * -1);
}

/* Cada tarjeta es el mundo de su marca: el fondo es un tono más profundo de su propia paleta, para que la maqueta
   no se confunda con él y al pasar de una a otra se note que cambias de web. Los colores del texto salen de la misma
   paleta y los calcula scripts/build.mjs con el contraste puesto (7:1, como el resto de la web). */
.web-gallery__card {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--ds-space-lg);
  flex: 0 0 min(88%, calc(var(--ds-space-4xl) * 11));
  block-size: min(calc(var(--ds-space-4xl) * 6.5), 78svh);
  overflow: hidden;
  padding: var(--ds-space-lg);
  border-radius: var(--ds-radius-lg);
  background: var(--web-brand-shell, var(--ds-bg-surface));
  color: var(--web-brand-ink, var(--ds-fg-primary));
  scroll-snap-align: start;
}

.web-gallery__caption {
  display: grid;
  align-content: start;
  gap: var(--ds-space-sm);
  max-inline-size: var(--ds-layout-measure);
}

/* El nombre va en la tipografía de la marca del ejemplo, y el texto en la suya de lectura: algunas son de display
   (Kranky en el taller de cerámica) y un párrafo entero no se leería. Es una desviación de la escala tipográfica del
   sistema, que es toda Geist, y es a propósito: cada tarjeta se lee como otra marca.
   En el móvil el nombre baja a titular de sección, que a tamaño de display no cabría con su maqueta. */
.web-gallery__caption h3 {
  font-family: var(--web-brand-font, inherit);
  font-size: var(--ds-text-heading-lg-size);
  line-height: var(--ds-text-heading-lg-leading);
  letter-spacing: var(--ds-text-heading-lg-tracking);
}

.web-gallery__caption p {
  color: var(--web-brand-body, var(--ds-fg-secondary));
  font-family: var(--web-brand-font-body, var(--web-brand-font, inherit));
}

/* Escenario de la maqueta: ocupa lo que deja el texto y el dispositivo se mide contra él, a lo ancho y a lo alto
   (cqi y cqh), para caber entero sea cual sea la tarjeta. --web-device es el alto de referencia: el navegador mide
   1,2 veces de ancho y 0,675 de alto; el móvil, 0,47 de ancho y 1 de alto. */
.web-gallery__stage {
  container-type: size;
  display: grid;
  place-items: end center;
  min-block-size: 0;
}

.web-gallery__card--browser .web-gallery__stage {
  --web-device: min(83cqi, 125cqh);
}

.web-gallery__card--phone .web-gallery__stage {
  --web-device: min(200cqi, 97cqh);
}

.web-gallery__figure {
  display: grid;
  justify-items: center;
  margin: 0;
}

.web-gallery__card--browser .web-gallery__figure {
  inline-size: calc(var(--web-device) * 1.2);
}

/* Paleta y tipografía de la maqueta. Estos son los valores por defecto, con los tokens del sistema; cada ejemplo
   del catálogo los cambia por los de su marca con la clase .web-brand--*, que genera scripts/build.mjs desde
   BRANDS en src/render.mjs (en esta hoja no caben colores literales). */
.web-device {
  --web-mock-bg: var(--web-brand-bg, var(--ds-bg-canvas));
  --web-mock-surface: var(--web-brand-surface, var(--ds-bg-surface));
  --web-mock-sunken: var(--web-brand-sunken, var(--ds-bg-raised));
  --web-mock-edge: var(--web-brand-edge, var(--ds-border-subtle));
  --web-mock-muted: var(--web-brand-muted, var(--ds-border-control));
  --web-mock-ink: var(--web-brand-ink, var(--ds-fg-primary));
  --web-mock-ink-soft: var(--web-brand-ink-soft, var(--ds-fg-secondary));
  --web-mock-accent: var(--web-brand-accent, var(--ds-fg-brand));
  --web-mock-on-accent: var(--web-brand-on-accent, var(--ds-fg-on-brand));
  --web-mock-font: var(--web-brand-font, var(--ds-text-body-md-family));

  container-type: size;

  display: grid;
  overflow: hidden;
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  background: var(--web-mock-bg);
  box-shadow: var(--ds-shadow-overlay);
}

.web-device--browser {
  grid-template-rows: auto minmax(0, 1fr);
  inline-size: 100%;
  block-size: calc(var(--web-device) * 0.675);
  border-radius: var(--ds-radius-md);
}

.web-device__bar {
  display: flex;
  gap: var(--ds-space-xs);
  padding: var(--ds-space-sm) var(--ds-space-md);
  border-block-end: var(--ds-border-width-default) solid var(--ds-border-subtle);
  background: var(--ds-bg-surface);
}

.web-device__bar span {
  inline-size: var(--ds-space-sm);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full);
  background: var(--ds-border-control);
}

.web-device--phone {
  inline-size: calc(var(--web-device) * 0.47);
  block-size: var(--web-device);
  padding: var(--ds-space-sm);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-bg-raised);
}

/* Piezas de las maquetas. Solo formas: un rectángulo hace de titular, otro de foto, otro de mapa. Todas las
   medidas son tokens, así que la maqueta se dibuja con el espacio y los radios del sistema y luego se reduce
   entera, como la miniatura de una web de verdad: se dibuja al doble de tamaño y se muestra a la mitad, así
   caben todas las secciones que tendría la página sin inventar medidas fuera de la escala. */
.web-mock {
  /* Tope de alto de las formas que van en proporción (fotos y mapa), en tanto por ciento del alto del
     dispositivo: ninguna puede empujar el resto de la página fuera de la pantalla. */
  --web-mock-cap: 26cqh;

  display: grid;
  align-content: start;
  gap: var(--ds-space-sm);
  inline-size: 200%;
  block-size: 200%;
  min-block-size: 0;
  /* La maqueta es hija de una retícula: sin esto, el logotipo (que no parte palabra) la estiraba más allá de su
     ancho declarado y la página se salía del dispositivo por la derecha. */
  min-inline-size: 0;
  padding: var(--ds-space-md);
  background: var(--web-mock-bg);
  transform: scale(0.5);
  transform-origin: 0 0;
}

.web-device--phone .web-mock {
  inline-size: 160%;
  block-size: 160%;
  gap: var(--ds-space-sm);
  transform: scale(0.625);
}

/* Nada dentro de la maqueta puede empujar más allá del ancho del dispositivo: en retículas y flex, el mínimo
   automático es el contenido, y con el logotipo o las tarjetas estrechas la página se salía por la derecha. */
.web-mock > *,
.web-mock__bar > *,
.web-mock__split > *,
.web-mock__cols > *,
.web-mock__row > *,
.web-mock__plans > *,
.web-mock__price > * {
  min-inline-size: 0;
}

.web-mock__bar,
.web-mock__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ds-space-sm);
}

.web-mock__foot {
  margin-block-start: var(--ds-space-xs);
  padding-block-start: var(--ds-space-sm);
  border-block-start: var(--ds-border-width-default) solid var(--web-mock-edge);
}

/* Logotipo: el nombre del ejemplo, en la tipografía de su marca. Es lo único con letras dentro de la maqueta, y
   es el mismo nombre que se lee al lado. Se recorta si no cabe, como en una barra de verdad. */
.web-mock__logo {
  overflow: hidden;
  min-inline-size: 0;
  max-inline-size: 45%;
  color: var(--web-mock-ink);
  font-family: var(--web-mock-font);
  font-size: var(--ds-text-heading-sm-size);
  font-weight: var(--ds-text-heading-sm-weight);
  line-height: var(--ds-text-heading-sm-leading);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.web-mock__links {
  display: flex;
  gap: var(--ds-space-sm);
}

.web-mock__dot {
  inline-size: var(--ds-space-md);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full);
  background: var(--web-mock-accent);
}

.web-mock__line {
  block-size: var(--ds-space-xs);
  border-radius: var(--ds-radius-full);
  background: var(--web-mock-muted);
}

.web-mock__line--nav {
  inline-size: var(--ds-space-lg);
}

.web-mock__line--title {
  block-size: var(--ds-space-sm);
  background: var(--web-mock-ink-soft);
}

.web-mock__line--display {
  block-size: var(--ds-space-md);
  border-radius: var(--ds-radius-sm);
  background: var(--web-mock-ink);
}

.web-mock__line--mid { inline-size: 70%; }
.web-mock__line--short { inline-size: 40%; }

.web-mock__hero,
.web-mock__stack,
.web-mock__card,
.web-mock__brand,
.web-mock__form,
.web-mock__list,
.web-mock__plans {
  display: grid;
  align-content: start;
  gap: var(--ds-space-xs);
}

.web-mock__hero {
  gap: var(--ds-space-sm);
}

.web-mock__btns {
  display: flex;
  gap: var(--ds-space-xs);
  margin-block-start: var(--ds-space-xs);
}

.web-mock__btn {
  inline-size: 35%;
  block-size: var(--ds-space-lg);
  border-radius: var(--ds-radius-full);
  background: var(--web-mock-accent);
}

.web-mock__btn--small {
  inline-size: var(--ds-space-3xl);
  block-size: var(--ds-space-md);
}

.web-mock__btn--ghost {
  border: var(--ds-border-width-default) solid var(--web-mock-muted);
  background: none;
}

.web-mock__btn--wide {
  inline-size: 100%;
}

/* Ninguna imagen puede comerse la página: se queda en su proporción mientras quepa y, si no, se recorta en
   alto. El tope va en cqh, es decir en tanto por ciento del alto del dispositivo (.web-device es el contenedor),
   así que la maqueta entera cabe en la pantalla sea cual sea el tamaño al que se dibuje. */
.web-mock__media {
  max-block-size: var(--web-mock-cap);
  border-radius: var(--ds-radius-sm);
  background: radial-gradient(circle at 30% 20%, color-mix(in srgb, var(--web-mock-accent) 28%, transparent), transparent 70%), var(--web-mock-sunken);
}

.web-mock__media--square { aspect-ratio: 1; }
.web-mock__media--wide { aspect-ratio: 16 / 9; }
.web-mock__media--tall { aspect-ratio: 4 / 5; }

.web-mock__split {
  display: grid;
  grid-template-columns: 3fr 2fr;
  align-items: center;
  gap: var(--ds-space-md);
}

.web-mock__cols {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: var(--ds-space-sm);
}

.web-mock__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--ds-space-xs);
}

.web-device--phone .web-mock__grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.web-mock__card {
  padding: var(--ds-space-sm);
  border: var(--ds-border-width-default) solid var(--web-mock-edge);
  border-radius: var(--ds-radius-sm);
  background: var(--web-mock-surface);
}

.web-mock__brand {
  gap: var(--ds-space-sm);
  padding: var(--ds-space-md);
  border-radius: var(--ds-radius-sm);
  background: var(--web-mock-accent);
}

.web-mock__brand .web-mock__line {
  background: var(--web-mock-on-accent);
}

.web-mock__brand .web-mock__btn {
  background: var(--web-mock-on-accent);
}

.web-mock__brand .web-mock__btn--ghost {
  border-color: var(--web-mock-on-accent);
  background: none;
}

.web-mock__chips {
  display: flex;
  gap: var(--ds-space-xs);
}

.web-mock__chip {
  flex: 1;
  block-size: var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--web-mock-edge);
  border-radius: var(--ds-radius-full);
  background: var(--web-mock-surface);
}

.web-mock__tabs {
  display: flex;
  gap: var(--ds-space-md);
  padding-block-end: var(--ds-space-xs);
  border-block-end: var(--ds-border-width-default) solid var(--web-mock-edge);
}

.web-mock__tab {
  inline-size: var(--ds-space-2xl);
  block-size: var(--ds-space-xs);
  border-radius: var(--ds-radius-full);
  background: var(--web-mock-muted);
}

.web-mock__tab--on {
  background: var(--web-mock-accent);
}

.web-mock__field {
  block-size: var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--web-mock-muted);
  border-radius: var(--ds-radius-sm);
}

.web-mock__meter {
  display: grid;
  block-size: var(--ds-space-sm);
  overflow: hidden;
  border-radius: var(--ds-radius-full);
  background: var(--web-mock-sunken);
}

.web-mock__meter::before {
  content: "";
  inline-size: 60%;
  background: var(--web-mock-accent);
}

/* Fila de ventaja o de profesorado: foto redonda y dos líneas. */
.web-mock__row {
  display: flex;
  align-items: center;
  gap: var(--ds-space-sm);
}

.web-mock__row .web-mock__stack {
  flex: 1;
}

.web-mock__avatar {
  inline-size: var(--ds-space-xl);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full);
  background: radial-gradient(circle at 30% 20%, color-mix(in srgb, var(--web-mock-accent) 28%, transparent), transparent 70%), var(--web-mock-sunken);
}

/* Precio: cifra grande y botón al lado. */
.web-mock__price {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ds-space-sm);
  margin-block-start: var(--ds-space-xs);
}

.web-mock__amount {
  inline-size: var(--ds-space-2xl);
  block-size: var(--ds-space-md);
  border-radius: var(--ds-radius-sm);
  background: var(--web-mock-accent);
}

/* Valoración: cinco rombos. */
.web-mock__stars {
  display: flex;
  gap: var(--ds-space-xs);
}

.web-mock__stars span {
  inline-size: var(--ds-space-sm);
  aspect-ratio: 1;
  background: var(--web-mock-accent);
  rotate: 45deg;
}

/* Mapa: retícula de calles con una chincheta. */
.web-mock__map {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  max-block-size: var(--web-mock-cap);
  border-radius: var(--ds-radius-sm);
  background:
    repeating-linear-gradient(to right, var(--web-mock-edge) 0 var(--ds-border-width-default), transparent var(--ds-border-width-default) var(--ds-space-md)),
    repeating-linear-gradient(to bottom, var(--web-mock-edge) 0 var(--ds-border-width-default), transparent var(--ds-border-width-default) var(--ds-space-md)),
    var(--web-mock-sunken);
}

.web-mock__pin {
  inline-size: var(--ds-space-md);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full) var(--ds-radius-full) 0 var(--ds-radius-full);
  background: var(--web-mock-accent);
  rotate: 45deg;
}

/* Calendario: tres semanas, con los días de matrícula marcados. */
.web-mock__days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--ds-space-xs);
  max-block-size: var(--web-mock-cap);
  overflow: hidden;
}

.web-mock__days span {
  aspect-ratio: 1;
  border-radius: var(--ds-radius-sm);
  background: var(--web-mock-sunken);
}

.web-mock__days span:nth-child(3n + 2) {
  background: var(--web-mock-muted);
}

.web-mock__days span:nth-child(7n + 4) {
  background: var(--web-mock-accent);
}

/* Cuenta atrás: cuatro bloques de cifras. */
.web-mock__count {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--ds-space-xs);
}

.web-mock__num {
  aspect-ratio: 1;
  border-radius: var(--ds-radius-sm);
  background: color-mix(in srgb, var(--web-mock-on-accent) 22%, transparent);
}

/* Planes: el importe destaca y el periodo lo acompaña en la misma línea base. */
.web-price {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-xs);
}

.web-price__main {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--ds-space-xs) var(--ds-space-sm);
}

.web-plans-note {
  margin-block-start: var(--ds-space-lg);
}

/* Ofertas destacadas dentro de una card de plan: pago anual y continuidad de campaña. */
.web-highlight {
  padding: var(--ds-space-sm) var(--ds-space-md);
  border-radius: var(--ds-radius-md);
  border: var(--ds-border-width-default) solid var(--ds-border-selected);
  background: var(--web-mock-sunken);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
}

.web-note {
  margin-block-start: var(--ds-space-xl);
}

/* Páginas legales y de error. */
.web-page {
  display: grid;
  gap: var(--ds-space-lg);
  justify-items: start;
}

.web-facts {
  display: grid;
  gap: var(--ds-space-md);
}

.web-facts div {
  display: grid;
  gap: var(--ds-space-xs);
}

.web-facts dt {
  color: var(--ds-fg-secondary);
}

@media (min-width: 640px) {
  .web-signature {
    height: var(--ds-space-4xl);
  }

  .web-gallery__card {
    padding: var(--ds-space-2xl);
  }

  .web-gallery__caption {
    gap: var(--ds-space-md);
  }

  .web-gallery__caption h3 {
    font-size: var(--ds-text-display-md-size);
    line-height: var(--ds-text-display-md-leading);
    letter-spacing: var(--ds-text-display-md-tracking);
  }

  .web-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .web-steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  /* Tarjeta del catálogo: el texto arriba a la izquierda y la maqueta a la derecha, a toda la altura. */
  .web-gallery__card {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    grid-template-rows: minmax(0, 1fr);
    gap: var(--ds-space-2xl);
    block-size: min(calc(var(--ds-space-4xl) * 7), 78svh);
  }

  .web-gallery__stage {
    place-items: center;
  }

  .web-faq,
  .web-contact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Pantallas de ordenador bajas (portátiles de 768 o 800 de alto): la presentación se aprieta un poco para
   seguir cabiendo entera en una pantalla, en vez de empujar el catálogo hacia arriba. */
@media (min-width: 1024px) {
  /* En una pantalla de 900 basta con bajar la firma; en una de 768 hay que apretar también los huecos. */
  @media (max-height: 920px) {
    .web-signature {
      height: var(--ds-space-2xl);
    }
  }

  @media (max-height: 820px) {
    .web-signature {
      height: var(--ds-space-xl);
    }

    .web-hero__text {
      gap: var(--ds-space-md);
    }
  }
}

/* --- Movimiento ------------------------------------------------------------------------------------
   Todo lo que se mueve al hacer scroll o con el ratón lo enciende src/home.js poniendo data-motion="js"
   en <html> y escribiendo unas pocas variables por fotograma. Se hace así, y no con animation-timeline,
   porque Firefox todavía no lo soporta: de esta forma el despiece, el catálogo y el resto se ven igual en
   Chrome, Safari y Firefox. Sin JavaScript, con un error o con prefers-reduced-motion nada de esto se
   aplica y la portada queda completa y quieta, que es el estado del que parte el HTML. */

/* Avance de lectura, sobre el borde inferior de la barra fija. */
.web-progress {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: var(--ds-border-width-strong);
  background: var(--ds-gradient-brand);
  transform-origin: 0 50%;
  scale: var(--web-read, 0) 1;
}

/* Entrada de sección: una sola vez y desde un estado visible, así que solo se oculta lo que src/home.js
   marca justo antes de observar (guidelines/visual/motion.md de @l0er/brand). */
html[data-motion="js"] [data-reveal] {
  opacity: 0;
  translate: 0 var(--ds-space-md);
  transition:
    opacity var(--ds-duration-slow) var(--ds-ease-emphasized),
    translate var(--ds-duration-slow) var(--ds-ease-emphasized);
}

html[data-motion="js"] [data-reveal][data-seen] {
  opacity: 1;
  translate: 0 0;
}

/* Aurora: tres manchas del tinte de los difuminados de la marca (bg.band-glow), al 20 %, que se cruzan despacio
   por detrás de todo. Es lo único que se mueve sin que nadie haga nada, y son los difuminados del hero de la
   portada, que es una banda más. Con movimiento
   reducido se queda quieta y sigue dando el mismo color. Su intensidad entra en la comprobación de contraste de
   scripts/check.mjs: por debajo del halo del hero no puede bajar de AAA. */
.web-aurora {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
}

.web-aurora span {
  position: absolute;
  inline-size: 65%;
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full);
  background: radial-gradient(circle closest-side, color-mix(in srgb, var(--ds-bg-band-glow) 20%, transparent), transparent);
}

.web-aurora span:nth-child(1) { inset: -20% auto auto -10%; }
.web-aurora span:nth-child(2) { inset: auto -15% -30% auto; inline-size: 55%; }
.web-aurora span:nth-child(3) { inset: 10% 20% auto auto; inline-size: 45%; }

@media (prefers-reduced-motion: no-preference) {
  .web-aurora span:nth-child(1) { animation: web-aurora-a 34s ease-in-out infinite alternate; }
  .web-aurora span:nth-child(2) { animation: web-aurora-b 46s ease-in-out infinite alternate; }
  .web-aurora span:nth-child(3) { animation: web-aurora-c 28s ease-in-out infinite alternate; }
}

@keyframes web-aurora-a {
  to {
    translate: 42% 26%;
    scale: 1.35;
  }
}

@keyframes web-aurora-b {
  to {
    translate: -48% -30%;
    scale: 0.72;
  }
}

@keyframes web-aurora-c {
  to {
    translate: -36% 44%;
    scale: 1.3;
  }
}

/* Halo del hero: se desplaza con el ratón. Sobredimensionado para que al moverse no descubra los bordes. */
html[data-motion="js"] .web-hero::before {
  inset: calc(var(--ds-space-4xl) * -2);
  translate: calc(var(--web-pointer-x, 0) * var(--ds-space-4xl)) calc(var(--web-pointer-y, 0) * var(--ds-space-2xl));
  transition: translate var(--ds-duration-slow) var(--ds-ease-standard);
}

/* Tarjetas: foco de luz bajo el cursor y giro mínimo hacia él. Solo con ratón, y la escala es la del
   sistema para el hover de tarjeta. --web-card-* las escribe src/home.js sobre la tarjeta apuntada. Sobre blanco
   el carmesí se nota enseguida: al 10 % es un rubor, no una mancha. */
main .ds-card {
  position: relative;
  isolation: isolate;
  transition:
    border-color var(--ds-duration-fast) var(--ds-ease-standard),
    box-shadow var(--ds-duration-base) var(--ds-ease-standard);
}

/* Tarjetas sobre las bandas de la portada: dejan ver los difuminados. En claro son cristal blanco (fg.on-brand al
   70 %), que solo sube el contraste del texto oscuro. En oscuro son solo contorno: cualquier luz encima del
   difuminado bajaría el texto de AAA, y así el fondo que se ve es el de la banda, que la marca ya verifica. :where()
   deja que el borde del hover siga ganando. */
.web-band--glow :where(.ds-card) {
  background: color-mix(in srgb, var(--ds-fg-on-brand) 70%, transparent);
}

.web-band--glow[data-theme="dark"] :where(.ds-card) {
  border-color: var(--ds-border-subtle);
  background: transparent;
}

main .ds-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(circle at var(--web-card-x, 50%) var(--web-card-y, 50%), color-mix(in srgb, var(--ds-fg-brand) 10%, transparent), transparent 60%);
  opacity: var(--web-card-near, 0);
  transition: opacity var(--ds-duration-fast) var(--ds-ease-standard);
  pointer-events: none;
}

@media (hover: hover) {
  main .ds-card:hover {
    border-color: var(--ds-border-selected);
    box-shadow: var(--ds-shadow-overlay);
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html[data-motion="js"] main .ds-card {
    transform:
      perspective(calc(var(--ds-space-4xl) * 12))
      rotateX(calc(var(--web-card-ty, 0) * -3deg))
      rotateY(calc(var(--web-card-tx, 0) * 3deg))
      scale(var(--web-card-scale, 1));
    transition:
      transform var(--ds-duration-fast) var(--ds-ease-standard),
      border-color var(--ds-duration-fast) var(--ds-ease-standard),
      box-shadow var(--ds-duration-base) var(--ds-ease-standard);
  }

  html[data-motion="js"] main .ds-card:hover {
    --web-card-scale: 1.01;
  }
}

/* --- Despiece --------------------------------------------------------------------------------------
   La web como una máquina de taller: seis placas atornilladas que se separan del conjunto por cuatro guías.
   --web-machine-open va de 0 (montada, de frente) a 1 (despiezada, en tres cuartos) según entra la sección, y
   el conjunto gira hacia el ratón con --web-machine-yaw y --web-machine-pitch; las tres las escribe src/home.js.
   Sin él, las placas se quedan separadas y quietas. El esquema es decorativo (aria-hidden): el texto de cada
   pieza está en la lista, que con JavaScript pasa a ser un selector de capa con la ficha encima del escenario. */

/* El plano de trabajo y las placas abiertas se salen del escenario a propósito: se recortan aquí para que no
   aparezca scroll horizontal. overflow-x: clip no crea contenedor de scroll, así que el escenario sigue pudiendo
   quedarse fijo respecto a la ventana. */
.web-machine {
  overflow-x: clip;
}

.web-machine__layout {
  display: grid;
  gap: var(--ds-space-2xl);
  align-items: center;
}

/* El primer bloque y lo que lleva dentro pueden encoger: si no, la palabra más larga del titular (en euskera,
   «Ikusgarritasuna») fija el ancho mínimo y el texto se sale del borde en un móvil estrecho. En una retícula, el
   mínimo por defecto es el contenido, y a 56 px esa palabra mide más que la pantalla. */
.web-hero__text,
.web-machine__figure,
.web-hero__text > * {
  min-inline-size: 0;
}

.web-machine__figure {
  position: relative;
}

.web-machine__stage {
  position: relative;
  display: grid;
  place-items: center;
  container-type: inline-size;
  aspect-ratio: 4 / 5;
  perspective: 130cqi;
  perspective-origin: 50% 42%;
}

/* Todas las medidas del conjunto van en cqi, es decir en tanto por ciento del ancho del escenario: así el
   despiece se separa lo mismo en un móvil que en una pantalla grande. El desplazamiento vertical compensa que
   las placas se separan hacia arriba, para que el conjunto abierto quede centrado. */
.web-machine__assembly {
  --web-machine-open: 1;
  --web-machine-yaw: 0deg;
  --web-machine-pitch: 0deg;
  --web-machine-lift: 15cqi;
  --web-machine-span: calc(var(--web-machine-lift) * 5);
  /* Lado de la chapa. Todo lo que se dibuja dentro de una placa se mide en fracciones de este valor, no del
     escenario, para que la placa se vea igual de poblada en un móvil que en una pantalla grande. */
  --web-plate-size: 58cqi;

  position: relative;
  inline-size: var(--web-plate-size);
  aspect-ratio: 3 / 4;
  transform-style: preserve-3d;
  transform:
    translateY(calc(25cqi * var(--web-machine-open)))
    translateZ(calc(-30cqi * var(--web-machine-open)))
    rotateX(var(--web-machine-pitch))
    rotateY(var(--web-machine-yaw))
    rotateX(calc(56deg * var(--web-machine-open)))
    rotateZ(calc(-34deg * var(--web-machine-open)));
}

/* Plano de trabajo: la retícula sobre la que se apoya la máquina, visible solo cuando está abierta. */
.web-machine__assembly::before {
  content: "";
  position: absolute;
  inset: calc(var(--ds-space-2xl) * -1);
  background:
    repeating-linear-gradient(to right, var(--ds-border-subtle) 0 var(--ds-border-width-default), transparent var(--ds-border-width-default) var(--ds-space-lg)),
    repeating-linear-gradient(to bottom, var(--ds-border-subtle) 0 var(--ds-border-width-default), transparent var(--ds-border-width-default) var(--ds-space-lg));
  opacity: calc(0.6 * var(--web-machine-open));
  transform: translateZ(calc(var(--ds-space-xl) * -1));
}

/* Guías: cuatro ejes que atraviesan la pila por las esquinas, como los pernos de un despiece de taller.
   Cada barra se dibuja plana y se levanta 90° para quedar a lo largo del eje que separa las placas. */
.web-machine__guides {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}

.web-machine__guide {
  position: absolute;
  inset-block-end: 6cqi;
  inset-inline-start: 5cqi;
  inline-size: var(--ds-border-width-default);
  block-size: calc(var(--web-machine-span) * var(--web-machine-open));
  background: linear-gradient(to top, transparent, var(--ds-fg-brand));
  opacity: calc(0.55 * var(--web-machine-open));
  transform-origin: 50% 100%;
  transform: rotateX(-90deg);
}

.web-machine__guide:nth-child(2) {
  inset-inline: auto 5cqi;
}

.web-machine__guide:nth-child(3) {
  inset-block-end: calc(100% - 6cqi);
}

.web-machine__guide:nth-child(4) {
  inset-block-end: calc(100% - 6cqi);
  inset-inline: auto 5cqi;
}

/* Placa: chapa con borde doble, tornillos en las esquinas y etiqueta numerada. */
.web-plate {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: calc(var(--web-plate-size) * 0.08);
  padding: calc(var(--web-plate-size) * 0.12);
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-sm);
  background: color-mix(in srgb, var(--ds-bg-surface) 88%, transparent);
  box-shadow: var(--ds-shadow-overlay);
  translate: 0 0 calc(var(--web-depth) * var(--web-machine-lift) * var(--web-machine-open));
  transform: translateZ(calc(var(--web-plate-size) * 0.18 * var(--web-pick, 0)));
  transition:
    transform var(--ds-duration-base) var(--ds-ease-emphasized),
    border-color var(--ds-duration-fast) var(--ds-ease-standard),
    background-color var(--ds-duration-fast) var(--ds-ease-standard);
}

/* Borde interior: la marca de troquel de la chapa. */
.web-plate::after {
  content: "";
  position: absolute;
  inset: calc(var(--web-plate-size) * 0.055);
  border: var(--ds-border-width-default) dashed var(--ds-border-subtle);
  border-radius: var(--ds-radius-sm);
  opacity: 0.5;
  pointer-events: none;
}

/* La chapa es la pestaña de su pieza: se puede pulsar y recibir el foco. Apuntarla solo cambia su etiqueta,
   nunca su posición: levantarla la sacaba de debajo del cursor y parpadeaba. */
.web-machine[data-picker] .web-plate {
  cursor: var(--web-cursor-press, pointer);
}

.web-machine[data-picker] .web-plate:hover .web-plate__tag {
  border-color: var(--ds-border-selected);
  color: var(--ds-fg-brand);
}

.web-plate--d0 { --web-depth: 0; }
.web-plate--d1 { --web-depth: 1; }
.web-plate--d2 { --web-depth: 2; }
.web-plate--d3 { --web-depth: 3; }
.web-plate--d4 { --web-depth: 4; }
.web-plate--d5 { --web-depth: 5; }

/* Elegir una pieza la saca del conjunto. data-lit lo pone src/home.js al pulsar una chapa o una pestaña del
   selector, y cuando el copiloto repasa el despiece; las reglas con :has() son para cuando no hay JavaScript y
   la lista de piezas está a la vista. La chapa no reacciona al hover a propósito: al levantarse se salía de
   debajo del cursor, volvía a bajar y entraba y salía del estado sin parar. */
.web-plate[data-lit],
.web-machine__layout:has(.web-machine__part:nth-child(1):hover) .web-plate--d0,
.web-machine__layout:has(.web-machine__part:nth-child(2):hover) .web-plate--d1,
.web-machine__layout:has(.web-machine__part:nth-child(3):hover) .web-plate--d2,
.web-machine__layout:has(.web-machine__part:nth-child(4):hover) .web-plate--d3,
.web-machine__layout:has(.web-machine__part:nth-child(5):hover) .web-plate--d4,
.web-machine__layout:has(.web-machine__part:nth-child(6):hover) .web-plate--d5 {
  --web-pick: 1;

  border-color: var(--ds-border-selected);
  background: color-mix(in srgb, var(--ds-bg-raised) 94%, transparent);
}

/* Tornillos: cuatro en cada placa, en las esquinas de la chapa. */
.web-machine__stage .web-plate__screws {
  position: absolute;
  inset: calc(var(--web-plate-size) * 0.09);
  pointer-events: none;
}

.web-plate__screw {
  position: absolute;
  inline-size: calc(var(--web-plate-size) * 0.055);
  aspect-ratio: 1;
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-full);
  background: var(--ds-bg-canvas);
}

.web-plate__screw:nth-child(1) { inset: 0 auto auto 0; }
.web-plate__screw:nth-child(2) { inset: 0 0 auto auto; }
.web-plate__screw:nth-child(3) { inset: auto auto 0 0; }
.web-plate__screw:nth-child(4) { inset: auto 0 0 auto; }

.web-plate__tag {
  justify-self: start;
  padding-inline: calc(var(--web-plate-size) * 0.05);
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-sm);
  background: var(--ds-bg-raised);
  color: var(--ds-fg-secondary);
  font-size: calc(var(--web-plate-size) * 0.075);
  line-height: 2.2;
}

.web-plate[data-lit] .web-plate__tag {
  border-color: var(--ds-border-selected);
  color: var(--ds-fg-brand);
}

.web-plate__face {
  display: grid;
  align-content: start;
  gap: calc(var(--web-plate-size) * 0.07);
  min-block-size: 0;
}

.web-plate--frame .web-plate__face {
  grid-template-rows: auto minmax(0, 1fr);
  align-content: stretch;
}

.web-plate--grid .web-plate__face,
.web-plate--media .web-plate__face {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.web-plate__bar {
  display: flex;
  gap: calc(var(--web-plate-size) * 0.05);
}

.web-plate__bar span {
  inline-size: calc(var(--web-plate-size) * 0.07);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full);
  background: var(--ds-border-control);
}

.web-plate__void {
  border: var(--ds-border-width-default) dashed var(--ds-border-subtle);
  border-radius: var(--ds-radius-sm);
}

.web-plate__cell {
  aspect-ratio: 4 / 3;
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-sm);
  background: color-mix(in srgb, var(--ds-border-control) 40%, transparent);
}

.web-plate__line {
  block-size: calc(var(--web-plate-size) * 0.04);
  border-radius: var(--ds-radius-full);
  background: color-mix(in srgb, var(--ds-fg-secondary) 55%, transparent);
}

.web-plate__line--title {
  block-size: calc(var(--web-plate-size) * 0.075);
  background: var(--ds-fg-secondary);
}

.web-plate__line--mid { inline-size: 70%; }
.web-plate__line--short { inline-size: 40%; }

.web-plate__media {
  aspect-ratio: 4 / 3;
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-sm);
  background: var(--ds-gradient-glow), color-mix(in srgb, var(--ds-border-control) 35%, transparent);
}

.web-plate__field {
  block-size: calc(var(--web-plate-size) * 0.14);
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-sm);
}

.web-plate__pill {
  inline-size: 45%;
  block-size: calc(var(--web-plate-size) * 0.14);
  border-radius: var(--ds-radius-full);
  background: var(--ds-gradient-brand);
}

.web-plate__bars {
  display: flex;
  align-items: end;
  gap: calc(var(--web-plate-size) * 0.05);
  block-size: calc(var(--web-plate-size) * 0.34);
}

.web-plate__bars span {
  flex: 1;
  border-radius: var(--ds-radius-sm);
  background: var(--ds-gradient-brand);
}

.web-plate__bars span:nth-child(1) { block-size: 45%; }
.web-plate__bars span:nth-child(2) { block-size: 70%; }
.web-plate__bars span:nth-child(3) { block-size: 55%; }
.web-plate__bars span:nth-child(4) { block-size: 100%; }

.web-plate__pin {
  justify-self: start;
  inline-size: calc(var(--web-plate-size) * 0.17);
  aspect-ratio: 1;
  border: var(--ds-border-width-strong) solid var(--ds-fg-brand);
  border-radius: var(--ds-radius-full);
}

/* Piezas: el texto. Sin JavaScript se leen las seis seguidas; con JavaScript, src/home.js las esconde y pone en
   su lugar el selector de capa (web-machine__hud), que muestra una ficha cada vez. */
.web-machine__parts {
  display: grid;
  gap: var(--ds-space-lg);
  padding: 0;
  list-style: none;
  counter-reset: part;
}

.web-machine__part {
  display: grid;
  align-content: start;
  gap: var(--ds-space-xs);
  padding: var(--ds-space-md) var(--ds-space-lg);
  border-inline-start: var(--ds-border-width-strong) solid var(--ds-border-subtle);
  counter-increment: part;
  transition:
    border-color var(--ds-duration-fast) var(--ds-ease-standard),
    background-color var(--ds-duration-fast) var(--ds-ease-standard);
}

.web-machine__part h3::before {
  content: counter(part, decimal-leading-zero);
  margin-inline-end: var(--ds-space-sm);
  color: var(--ds-fg-brand);
  font-family: var(--ds-font-mono);
  font-variant-numeric: tabular-nums;
}

.web-machine__part:hover,
.web-machine__part[data-lit] {
  border-color: var(--ds-border-selected);
  background: var(--ds-bg-surface);
}

/* Con selector de capa la lista sobra: su texto es el que se clona en la ficha. */
.web-machine[data-picker] .web-machine__parts {
  display: none;
}

/* Ficha de la pieza elegida: se lee como la etiqueta de un componente y va bajo el escenario, en la misma
   columna que la máquina, para equilibrar la sección sin taparla. */
.web-machine__card {
  display: grid;
  gap: var(--ds-space-xs);
  justify-items: start;
  max-inline-size: var(--ds-layout-measure);
  margin-block-start: var(--ds-space-md);
  padding: var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--ds-border-selected);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-surface);
  box-shadow: var(--ds-shadow-overlay);
}

.web-machine__code {
  padding-inline: var(--ds-space-xs);
  border-radius: var(--ds-radius-sm);
  background: var(--ds-bg-raised);
  color: var(--ds-fg-brand);
}

@media (prefers-reduced-motion: no-preference) {
  .web-machine__card {
    animation: web-msg-in var(--ds-duration-base) var(--ds-ease-emphasized) both;
  }
}

@media (min-width: 1024px) {
  /* En pantalla de ordenador, la presentación y la máquina ocupan la pantalla entera: el catálogo empieza
     justo debajo del borde y no asoma hasta hacer scroll. Para que quepa sin recortar nada, el escenario se
     mide también contra el alto de la ventana, no solo contra el ancho de su columna. */
  .web-hero.web-machine {
    display: grid;
    align-content: center;
    /* La barra de navegación va en el flujo y ya ocupa su alto: lo que queda de pantalla es lo que tiene que
       llenar el bloque. Con el relleno de sección entero no cabía, así que aquí es más corto. */
    min-block-size: calc(100svh - var(--ds-size-nav));
    padding-block: var(--ds-space-xl) var(--ds-space-lg);
  }

  .web-machine__stage {
    inline-size: min(100%, 46svh);
    margin-inline: auto;
  }

  .web-machine__layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--ds-space-3xl);
  }

  .web-machine__parts {
    grid-column: 1 / -1;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ds-space-lg) var(--ds-space-xl);
  }

  .web-machine__stage {
    aspect-ratio: 1;
  }

  .web-machine__assembly {
    --web-machine-lift: 13.5cqi;
    --web-plate-size: 36cqi;

    transform:
      translateY(calc(22cqi * var(--web-machine-open)))
      translateZ(calc(-26cqi * var(--web-machine-open)))
      rotateX(var(--web-machine-pitch))
      rotateY(var(--web-machine-yaw))
      rotateX(calc(56deg * var(--web-machine-open)))
      rotateZ(calc(-34deg * var(--web-machine-open)));
  }

}

/* --- Copiloto (Lumic) --------------------------------------------------------------------------------
   Cerrado es solo un orbe: una esfera de puntos girando despacio sobre un disco blanco, sin una palabra. Al
   pulsarlo se abre el panel, que nunca pasa del alto de la pantalla: la conversación hace scroll por dentro y
   las preguntas y el botón se quedan siempre abajo, a la vista. Las respuestas son fijas y están en
   content.mjs. Sin JavaScript el panel es un acordeón nativo que funciona entero. */
/* Tope de alto del panel: lo que queda de pantalla bajo la barra fija, y nunca más de siete espacios grandes.
   Se aplica al panel y no al <details>, porque el contenido de un details vive en un hueco anónimo del navegador
   y no hereda las filas de la rejilla: en Chrome el pie se quedaba fuera. */
.web-copilot {
  --web-copilot-max: min(calc(100svh - var(--ds-size-nav) - var(--ds-space-2xl)), calc(var(--ds-space-4xl) * 7));

  position: fixed;
  inset-block-end: var(--ds-space-md);
  inset-inline: var(--ds-space-md);
  z-index: var(--ds-z-overlay);
  display: grid;
  gap: var(--ds-space-sm);
  justify-items: end;
  pointer-events: none;
}

/* Saludo de Lumic: un globo de texto que aparece con src/home.js a los 20 segundos, si el panel sigue cerrado. */
.web-copilot__intro {
  max-inline-size: min(calc(var(--ds-space-4xl) * 4.6), 100%);
  padding: var(--ds-space-sm) var(--ds-space-md);
  border: var(--ds-border-width-default) solid var(--ds-material-glass-border);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-material-glass-bg);
  -webkit-backdrop-filter: var(--ds-material-glass-filter);
  backdrop-filter: var(--ds-material-glass-filter);
  box-shadow: var(--ds-shadow-modal);
  color: var(--ds-fg-primary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
  cursor: var(--web-cursor-press, pointer);
  pointer-events: auto;
}

@media (prefers-reduced-motion: no-preference) {
  .web-copilot__intro {
    animation: web-msg-in var(--ds-duration-base) var(--ds-ease-emphasized) both;
  }
}

.web-copilot__shell {
  /* Crece con el ancho de pantalla: se queda en el mínimo hasta escritorio y luego escala con el viewport. */
  --web-orb: clamp(
    calc(var(--ds-size-control-lg) + var(--ds-space-md)),
    calc(var(--ds-size-control-lg) + 2vw),
    calc(var(--ds-size-control-lg) + var(--ds-space-xl))
  );

  inline-size: 100%;
  overflow: hidden;
  border: var(--ds-border-width-default) solid var(--ds-material-glass-border);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-material-glass-bg);
  -webkit-backdrop-filter: var(--ds-material-glass-filter);
  backdrop-filter: var(--ds-material-glass-filter);
  box-shadow: var(--ds-shadow-modal);
  pointer-events: auto;
}

/* Cerrado: solo el orbe, sobre un disco blanco (bg.raised) con contorno y sombra. Las bandas de la portada van del
   rubor al vino y al carmesí de marca, y los puntos, que son carmesí, se perdían en las oscuras: el disco los separa
   de cualquier fondo. Contra las bandas claras lo delimita el contorno (border.control) y contra las oscuras y la
   de marca, el propio blanco; scripts/check.mjs comprueba el 3:1 sobre cada una. El shell deja de recortar para
   que se vea la sombra. */
.web-copilot__shell:not([open]) {
  inline-size: max-content;
  max-inline-size: 100%;
  overflow: visible;
  border: none;
  background: none;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.web-copilot__shell:not([open]) .web-copilot__toggle {
  padding: var(--ds-space-sm);
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-full);
  background: var(--ds-bg-raised);
  box-shadow: var(--ds-shadow-overlay);
  transition: border-color var(--ds-duration-fast) var(--ds-ease-standard);
}

@media (hover: hover) {
  .web-copilot__shell:not([open]) .web-copilot__toggle:hover {
    border-color: var(--ds-border-selected);
  }
}

.web-copilot__shell:not([open]) .web-copilot__title,
.web-copilot__shell:not([open]) .web-copilot__chevron {
  display: none;
}

.web-copilot__shell[open] {
  --web-orb: var(--ds-space-xl);
}

.web-copilot__toggle {
  display: flex;
  align-items: center;
  gap: var(--ds-space-sm);
  min-block-size: var(--ds-size-control-md);
  padding: var(--ds-space-xs);
  cursor: var(--web-cursor-press, pointer);
  list-style: none;
}

.web-copilot__shell[open] .web-copilot__toggle {
  padding: var(--ds-space-sm) var(--ds-space-md);
}

/* Safari pinta el triángulo del acordeón aunque el summary sea flex. */
.web-copilot__toggle::-webkit-details-marker {
  display: none;
}

/* Orbe: una esfera de puntos. No se construye en 3D, sino recorriendo cada punto la elipse de su paralelo y
   cambiando de tamaño y de opacidad según esté delante o detrás: se lee como una esfera girando y, al no haber
   planos en el espacio, ningún punto llega a verse de canto ni parpadea. Los siete paralelos comparten la misma
   animación y se diferencian por el radio de su elipse (--web-lat-r), su altura (--web-lat-y) y cuánto sube y
   baja con la profundidad (--web-lat-d); cada punto entra en su sitio con un retardo negativo. */
.web-copilot__orbit {
  position: relative;
  flex: none;
  inline-size: var(--web-orb);
  aspect-ratio: 1;
}

.web-copilot__globe {
  --web-spin: 16s;

  position: absolute;
  inset: 0;
}

.web-copilot__ring {
  position: absolute;
  inset: 0;
}

/* Paralelos a 60°, 40°, 20°, 0°, -20°, -40° y -60° de una esfera de radio 0,44 del orbe, inclinada 22°. */
.web-copilot__ring:nth-child(1),
.web-copilot__ring:nth-child(7) {
  --web-lat-r: calc(var(--web-orb) * 0.22);
  --web-lat-d: calc(var(--web-orb) * 0.082);
}

.web-copilot__ring:nth-child(2),
.web-copilot__ring:nth-child(6) {
  --web-lat-r: calc(var(--web-orb) * 0.337);
  --web-lat-d: calc(var(--web-orb) * 0.126);
}

.web-copilot__ring:nth-child(3),
.web-copilot__ring:nth-child(5) {
  --web-lat-r: calc(var(--web-orb) * 0.414);
  --web-lat-d: calc(var(--web-orb) * 0.155);
}

.web-copilot__ring:nth-child(4) {
  --web-lat-r: calc(var(--web-orb) * 0.44);
  --web-lat-d: calc(var(--web-orb) * 0.165);
  --web-lat-y: 0;
}

.web-copilot__ring:nth-child(1) { --web-lat-y: calc(var(--web-orb) * -0.353); }
.web-copilot__ring:nth-child(2) { --web-lat-y: calc(var(--web-orb) * -0.262); }
.web-copilot__ring:nth-child(3) { --web-lat-y: calc(var(--web-orb) * -0.14); }
.web-copilot__ring:nth-child(5) { --web-lat-y: calc(var(--web-orb) * 0.14); }
.web-copilot__ring:nth-child(6) { --web-lat-y: calc(var(--web-orb) * 0.262); }
.web-copilot__ring:nth-child(7) { --web-lat-y: calc(var(--web-orb) * 0.353); }

/* Un paralelo de cada dos entra medio paso después: la malla queda al tresbolillo, como en una esfera. */
.web-copilot__ring:nth-child(even) {
  --web-ring-offset: 0.083;
}

.web-copilot__ring span {
  position: absolute;
  inset: 0;
  margin: auto;
  inline-size: calc(var(--web-orb) * 0.05);
  block-size: calc(var(--web-orb) * 0.05);
  border-radius: var(--ds-radius-full);
  background: var(--ds-fg-brand);
  translate: var(--web-lat-r) var(--web-lat-y);
}

.web-copilot__ring:nth-child(1) span,
.web-copilot__ring:nth-child(7) span {
  inline-size: calc(var(--web-orb) * 0.042);
  block-size: calc(var(--web-orb) * 0.042);
}

.web-copilot__ring span:nth-child(1) { --web-phase: 0; }
.web-copilot__ring span:nth-child(2) { --web-phase: 0.111; }
.web-copilot__ring span:nth-child(3) { --web-phase: 0.222; }
.web-copilot__ring span:nth-child(4) { --web-phase: 0.333; }
.web-copilot__ring span:nth-child(5) { --web-phase: 0.444; }
.web-copilot__ring span:nth-child(6) { --web-phase: 0.556; }
.web-copilot__ring span:nth-child(7) { --web-phase: 0.667; }
.web-copilot__ring span:nth-child(8) { --web-phase: 0.778; }
.web-copilot__ring span:nth-child(9) { --web-phase: 0.889; }

/* Único bucle de la portada, y es el que pide el diseño del copiloto: la esfera gira mientras esté en pantalla.
   Con movimiento reducido se queda quieta, con los puntos repartidos por su paralelo. */
@media (prefers-reduced-motion: no-preference) {
  .web-copilot__ring span {
    animation: web-globe var(--web-spin) linear infinite;
    animation-delay: calc(var(--web-spin) * (var(--web-phase, 0) + var(--web-ring-offset, 0)) * -1);
  }

  /* Aviso de que el copiloto está ahí: dos latidos al pasar el despiece, nunca en bucle. */
  .web-copilot[data-nudge] .web-copilot__shell:not([open]) {
    animation: web-nudge var(--ds-duration-slow) var(--ds-ease-emphasized) 4 alternate;
  }
}

/* Con movimiento reducido no hay animación que reparta los puntos (la marca la acorta a nada), así que cada uno
   se coloca en su sitio con la misma geometría que web-globe: a la fase θ, x = r·cos θ, y sube con sin θ, y el
   tamaño y la opacidad bajan hacia el fondo. Sin esto, los nueve puntos de cada paralelo caían en el mismo sitio. */
@media (prefers-reduced-motion: reduce) {
  .web-copilot__ring span {
    --web-angle: calc((var(--web-phase, 0) + var(--web-ring-offset, 0)) * 1turn);

    translate: calc(var(--web-lat-r) * cos(var(--web-angle))) calc(var(--web-lat-y) - var(--web-lat-d) * sin(var(--web-angle)));
    scale: calc(1 - 0.375 * sin(var(--web-angle)));
    opacity: calc(0.7 - 0.3 * sin(var(--web-angle)));
  }
}

/* Un cuarto de vuelta es el punto más lejano (arriba, pequeño y apagado) y tres cuartos el más cercano. */
@keyframes web-globe {
  0% {
    translate: var(--web-lat-r) var(--web-lat-y);
    scale: 1;
    opacity: 0.75;
  }

  25% {
    translate: 0 calc(var(--web-lat-y) - var(--web-lat-d));
    scale: 0.6;
    opacity: 0.4;
  }

  50% {
    translate: calc(var(--web-lat-r) * -1) var(--web-lat-y);
    scale: 1;
    opacity: 0.75;
  }

  75% {
    translate: 0 calc(var(--web-lat-y) + var(--web-lat-d));
    scale: 1.35;
    opacity: 1;
  }

  100% {
    translate: var(--web-lat-r) var(--web-lat-y);
    scale: 1;
    opacity: 0.75;
  }
}

@keyframes web-nudge {
  to {
    scale: 1.06;
  }
}

.web-copilot__title {
  display: grid;
  min-inline-size: 0;
}

.web-copilot__title > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Chevrón con los mismos trazos que ds-link--chevron: un cuadrado girado con dos lados. */
.web-copilot__chevron {
  flex: none;
  inline-size: var(--ds-size-icon-sm);
  aspect-ratio: 1;
  margin-inline-start: auto;
  border-block-end: var(--ds-border-width-strong) solid var(--ds-fg-secondary);
  border-inline-end: var(--ds-border-width-strong) solid var(--ds-fg-secondary);
  rotate: 225deg;
}

/* El material translúcido se queda en el orbe cerrado y en la cabecera. El panel abierto es opaco: sobre
   material translúcido la marca solo admite fg.primary (components/nav de @l0er/brand) y aquí hay texto
   secundario. */
.web-copilot__panel {
  display: flex;
  flex-direction: column;
  max-block-size: calc(var(--web-copilot-max) - var(--ds-space-3xl));
  border-block-start: var(--ds-border-width-default) solid var(--ds-material-glass-border);
  background: var(--ds-bg-canvas);
}

.web-copilot__scroll {
  display: grid;
  align-content: start;
  gap: var(--ds-space-md);
  flex: 1;
  min-block-size: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--ds-space-md);
}

.web-copilot__greeting {
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
}

.web-copilot__legend {
  color: var(--ds-fg-secondary);
}

.web-copilot__list {
  display: grid;
  gap: var(--ds-space-xs);
  padding: 0;
  list-style: none;
}

.web-copilot__item {
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-surface);
}

.web-copilot__q {
  display: flex;
  align-items: center;
  min-block-size: var(--ds-size-control-md);
  padding: var(--ds-space-xs) var(--ds-space-md);
  color: var(--ds-fg-primary);
  font-family: var(--ds-text-label-md-family);
  font-size: var(--ds-text-label-md-size);
  font-weight: var(--ds-text-label-md-weight);
  cursor: var(--web-cursor-press, pointer);
  list-style: none;
}

.web-copilot__q::-webkit-details-marker {
  display: none;
}

.web-copilot__a {
  padding: 0 var(--ds-space-md) var(--ds-space-md);
  color: var(--ds-fg-secondary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
}

.web-copilot__foot {
  display: grid;
  flex: none;
  gap: var(--ds-space-sm);
  justify-items: start;
  padding: var(--ds-space-md);
  border-block-start: var(--ds-border-width-default) solid var(--ds-border-subtle);
  background: var(--ds-bg-surface);
}

/* Conversación: solo existe con JavaScript, que la rellena con el mismo texto del acordeón. */
.web-copilot__log:not(:empty) {
  display: grid;
  gap: var(--ds-space-sm);
}

.web-copilot__msg {
  max-inline-size: 90%;
  padding: var(--ds-space-sm) var(--ds-space-md);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-surface);
  color: var(--ds-fg-primary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
}

.web-copilot__msg--you {
  justify-self: end;
  background: var(--ds-gradient-brand);
  color: var(--ds-fg-on-brand);
}

.web-copilot__msg--wait {
  display: flex;
  gap: var(--ds-space-xs);
  align-items: center;
}

.web-copilot__msg--wait span {
  inline-size: var(--ds-space-xs);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-full);
  background: var(--ds-fg-secondary);
}

.web-copilot__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ds-space-xs);
  padding: 0;
  list-style: none;
}

.web-copilot__chip {
  min-block-size: var(--ds-size-control-md);
  padding: var(--ds-space-xs) var(--ds-space-md);
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-full);
  background: var(--ds-action-secondary-bg);
  color: var(--ds-action-secondary-fg);
  font-family: var(--ds-text-label-md-family);
  font-size: var(--ds-text-label-md-size);
  font-weight: var(--ds-text-label-md-weight);
  cursor: var(--web-cursor-press, pointer);
  transition: background-color var(--ds-duration-fast) var(--ds-ease-standard);
}

.web-copilot__chip:hover {
  background: var(--ds-action-secondary-bg-hover);
}

.web-copilot__chip--reset {
  border-style: dashed;
  background: none;
  color: var(--ds-fg-secondary);
}

.web-copilot__chip[data-used] {
  border-color: var(--ds-border-subtle);
  color: var(--ds-fg-secondary);
}

@media (prefers-reduced-motion: no-preference) {
  .web-copilot__msg {
    animation: web-msg-in var(--ds-duration-base) var(--ds-ease-emphasized) both;
  }

  /* Los puntos de «escribiendo» son un indicador de carga. */
  .web-copilot__msg--wait span {
    animation: web-wait var(--ds-duration-slow) var(--ds-ease-standard) infinite alternate;
  }

  .web-copilot__msg--wait span:nth-child(2) { animation-delay: var(--ds-duration-instant); }
  .web-copilot__msg--wait span:nth-child(3) { animation-delay: var(--ds-duration-fast); }
}

@keyframes web-msg-in {
  from {
    opacity: 0;
    translate: 0 var(--ds-space-sm);
  }
}

@keyframes web-wait {
  to {
    opacity: 0.3;
    scale: 0.7;
  }
}

@media (min-width: 640px) {
  .web-copilot {
    inset-block-end: var(--ds-space-lg);
    inset-inline: auto var(--ds-space-lg);
    max-inline-size: calc(var(--ds-space-4xl) * 4.6);
  }
}

/* Galería del catálogo con JavaScript: puntos, pausa y paso automático. src/home.js quita el atributo hidden de los
   controles y pone data-ready en la galería (con eso el carril esconde su barra de desplazamiento, que ya no hace
   falta) y data-state con el estado del paso automático:
   - playing: arranca la primera vez que se ve el carrusel entero (no al cargar la página); el punto de la
     tarjeta activa se llena en --web-gallery-time y, al llenarse, pasa a la siguiente, hasta pararse sola en
     la última;
   - stopped: antes de verse entero por primera vez, al llegar a la última tarjeta, con el botón de pausa o si
     el sistema pide movimiento reducido.
   Cada maqueta, además, se inclina hacia el cursor y un reflejo le recorre el cristal. Solo transform y opacidad,
   con las curvas del sistema (guidelines/visual/motion.md de @l0er/brand). */
.web-gallery[data-ready] .web-gallery__track {
  scrollbar-width: none;
}

.web-gallery[data-ready] .web-gallery__track::-webkit-scrollbar {
  display: none;
}

@media (prefers-reduced-motion: no-preference) {
  .web-gallery__track {
    scroll-behavior: smooth;
  }
}

.web-gallery__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--ds-space-sm);
  padding-inline: var(--ds-layout-gutter);
}

.web-gallery__controls[hidden] {
  display: none;
}

/* El copiloto flota en la esquina de abajo: al llegar a un punto o al botón con el teclado, el navegador los sube
   lo bastante para que no queden tapados por él (WCAG 2.4.11). */
.web-gallery__controls button {
  scroll-margin-block-end: calc(var(--ds-size-control-lg) + var(--ds-space-2xl));
}

/* Cápsula de puntos y botón redondo, con el material translúcido de la barra, como en la galería de Apple. Cada
   punto es un botón de 44 px de alto aunque se vea de 8: el objetivo táctil es el del sistema. */
.web-gallery__dots,
.web-gallery__play {
  border: var(--ds-border-width-default) solid var(--ds-material-glass-border);
  background: var(--ds-material-glass-bg);
  -webkit-backdrop-filter: var(--ds-material-glass-filter);
  backdrop-filter: var(--ds-material-glass-filter);
}

.web-gallery__dots {
  display: flex;
  align-items: center;
  padding-inline: var(--ds-space-sm);
  border-radius: var(--ds-radius-full);
}

.web-gallery__dot {
  display: grid;
  place-items: center;
  min-inline-size: var(--ds-space-xl);
  block-size: var(--ds-size-control-md);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: var(--web-cursor-press, pointer);
}

.web-gallery__pip {
  position: relative;
  overflow: hidden;
  inline-size: var(--ds-space-sm);
  block-size: var(--ds-space-sm);
  border-radius: var(--ds-radius-full);
  background: var(--ds-fg-secondary);
  transition: background-color var(--ds-duration-fast) var(--ds-ease-standard);
}

.web-gallery__dot:hover .web-gallery__pip {
  background: var(--ds-fg-primary);
}

/* El punto de la tarjeta activa se estira en cápsula y se llena. Parado, se ve lleno. */
.web-gallery__dot[aria-current="true"] {
  min-inline-size: calc(var(--ds-space-2xl) + var(--ds-space-md));
}

.web-gallery__dot[aria-current="true"] .web-gallery__pip {
  inline-size: var(--ds-space-2xl);
  background: var(--ds-border-control);
}

.web-gallery__fill {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--ds-fg-primary);
  transform-origin: 0 50%;
  scale: 0 1;
}

.web-gallery__dot[aria-current="true"] .web-gallery__fill {
  scale: 1 1;
}

.web-gallery[data-state="playing"] .web-gallery__dot[aria-current="true"] .web-gallery__fill {
  animation: web-gallery-fill var(--web-gallery-time) linear both;
}

@keyframes web-gallery-fill {
  from {
    scale: 0 1;
  }

  to {
    scale: 1 1;
  }
}

.web-gallery__play {
  display: grid;
  place-items: center;
  inline-size: var(--ds-size-control-md);
  block-size: var(--ds-size-control-md);
  padding: 0;
  border-radius: var(--ds-radius-full);
  color: var(--ds-fg-primary);
  cursor: var(--web-cursor-press, pointer);
}

.web-gallery__icon {
  inline-size: var(--ds-size-icon-md);
  block-size: var(--ds-size-icon-md);
}

/* Se ve el icono de lo que hará el botón: pausa mientras avanza, reproducir cuando está parada. */
.web-gallery[data-state="stopped"] .web-gallery__icon--pause,
.web-gallery:not([data-state="stopped"]) .web-gallery__icon--play {
  display: none;
}

.web-gallery__figure {
  transition: transform var(--ds-duration-fast) var(--ds-ease-standard);
}

.web-device {
  position: relative;
}

/* Reflejo sobre el cristal, en el punto donde está el cursor. Es luz blanca en cualquier tema: fg.on-brand. */
.web-device::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--ds-z-raised);
  border-radius: inherit;
  background: radial-gradient(circle at var(--web-item-lx, 50%) var(--web-item-ly, 0%), color-mix(in srgb, var(--ds-fg-on-brand) 14%, transparent), transparent 55%);
  opacity: var(--web-item-near, 0);
  transition: opacity var(--ds-duration-base) var(--ds-ease-standard);
  pointer-events: none;
}

/* El borde se enciende con la misma variable que el reflejo: así los dos siguen al cursor aunque lo que se
   mueva sea la página. */
.web-device {
  border-color: color-mix(in srgb, var(--ds-border-selected) calc(var(--web-item-near, 0) * 100%), var(--ds-border-subtle));
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html[data-motion="js"] .web-gallery__figure {
    transform:
      perspective(calc(var(--ds-space-4xl) * 14))
      rotateX(calc(var(--web-item-ty, 0) * -7deg))
      rotateY(calc(var(--web-item-tx, 0) * 10deg))
      translateZ(calc(var(--web-item-near, 0) * var(--ds-space-2xl)))
      scale(calc(1 + 0.04 * var(--web-item-near, 0)));
  }
}

/* Cuestionario: formulario completo, paso a paso y controles que no tiene la marca (opciones, casillas, horario,
   archivos y filas). Mismas normas que styles.css: prefijo web-, solo tokens semánticos y nada de literales.
   Pendiente de proponer a @l0er/brand cuando se cumpla la regla de tres: casilla y opción, selector y subida de archivos. */

/* El atributo hidden gana a los display de los componentes. */
[hidden] {
  display: none !important;
}

.web-optional {
  color: var(--ds-fg-secondary);
  font-weight: normal;
}

.web-error {
  color: var(--ds-status-danger-fg);
}

/* --- Portada del cuestionario --- */

.web-option {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: var(--ds-space-md);
}

.web-option .ds-button {
  margin-block-start: var(--ds-space-sm);
}

/* --- Formulario completo --- */

.web-form {
  display: grid;
  gap: var(--ds-space-3xl);
  counter-reset: web-form-step;
}

.web-form__toc {
  display: grid;
  gap: var(--ds-space-sm);
  padding: var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-bg-surface);
}

.web-form__toc-list {
  display: grid;
  gap: var(--ds-space-xs);
  margin: 0;
  padding-inline-start: var(--ds-space-lg);
}

.web-form__step {
  display: grid;
  gap: var(--ds-space-2xl);
  padding-block-start: var(--ds-space-2xl);
  border-block-start: var(--ds-border-width-default) solid var(--ds-border-subtle);
  counter-increment: web-form-step;
  scroll-margin-block-start: calc(var(--ds-size-nav) + var(--ds-space-md));
}

.web-form__step-title::before {
  content: counter(web-form-step, decimal-leading-zero);
  margin-inline-end: var(--ds-space-sm);
  color: var(--ds-fg-brand);
  font-variant-numeric: tabular-nums;
}

.web-form__submit {
  display: grid;
  gap: var(--ds-space-lg);
  justify-items: start;
  padding-block-start: var(--ds-space-2xl);
  border-block-start: var(--ds-border-width-default) solid var(--ds-border-subtle);
}

.web-error-summary {
  margin-block-end: var(--ds-space-2xl);
}

.web-error-summary__list {
  display: grid;
  gap: var(--ds-space-xs);
  margin: 0;
  padding-inline-start: var(--ds-space-lg);
}

.web-error-summary__list a {
  color: inherit;
}

/* Campo trampa: fuera de la vista y del orden de tabulación. */
.web-hp {
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: hidden;
  clip-path: inset(50%);
}

/* --- Preguntas y grupos --- */

.web-q,
.web-group,
.web-choices,
.web-colors,
.web-hours,
.web-rows,
.web-row,
.web-day {
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.web-q {
  scroll-margin-block-start: calc(var(--ds-size-nav) + var(--ds-space-md));
}

.web-group,
.web-choices,
.web-colors,
.web-hours,
.web-rows {
  display: grid;
  gap: var(--ds-space-sm);
}

.web-group__title {
  margin-block-end: var(--ds-space-xs);
}

.web-group__fields {
  display: grid;
  gap: var(--ds-space-lg);
  margin-block-start: var(--ds-space-sm);
}

.web-field--short .ds-field__control {
  max-inline-size: calc(var(--ds-space-4xl) * 3);
}

.web-check-field {
  display: grid;
  gap: var(--ds-space-xs);
}

/* --- Opciones y casillas --- */

.web-choices__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--ds-space-4xl) * 2.5), 100%), 1fr));
  gap: var(--ds-space-sm);
}

.web-choices--inline .web-choices__list {
  display: flex;
  flex-wrap: wrap;
}

.web-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--ds-space-sm);
  min-block-size: var(--ds-size-control-md);
  padding: var(--ds-space-sm) var(--ds-space-md);
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-canvas);
  cursor: var(--web-cursor-press, pointer);
  transition: border-color var(--ds-duration-fast) var(--ds-ease-standard), background-color var(--ds-duration-fast) var(--ds-ease-standard);
}

.web-choice:hover {
  border-color: var(--ds-fg-secondary);
}

.web-choice:has(:checked) {
  border-color: var(--ds-border-selected);
  background: var(--ds-bg-surface);
}

.web-choice:has(:focus-visible) {
  outline: var(--ds-focus-ring-width) solid var(--ds-focus-ring);
  outline-offset: var(--ds-focus-ring-offset);
}

.web-choice input,
.web-check input {
  flex: none;
  inline-size: var(--ds-size-icon-md);
  block-size: var(--ds-size-icon-md);
  margin: 0;
  margin-block-start: calc((1lh - var(--ds-size-icon-md)) / 2);
  accent-color: var(--ds-action-primary-bg);
}

/* La casilla ya lleva su anillo en la etiqueta: sin doble contorno. */
.web-choice input:focus-visible {
  outline: none;
}

.web-choice__body {
  display: grid;
  gap: var(--ds-space-xs);
}

.web-choice__title {
  font-family: var(--ds-text-label-md-family);
  font-size: var(--ds-text-label-md-size);
  font-weight: var(--ds-text-label-md-weight);
  line-height: var(--ds-text-body-md-leading);
}

.web-choice__text {
  color: var(--ds-fg-secondary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
}

.web-choices[data-invalid] .web-choice {
  border-color: var(--ds-status-danger-fg);
}

.web-check {
  display: flex;
  align-items: flex-start;
  gap: var(--ds-space-sm);
  min-block-size: var(--ds-size-control-md);
  padding-block: var(--ds-space-sm);
  cursor: var(--web-cursor-press, pointer);
}

.web-check-field[data-invalid] .web-check {
  color: var(--ds-status-danger-fg);
}

/* --- Colores --- */

.web-colors__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ds-space-sm) var(--ds-space-xl);
}

.web-color {
  display: flex;
  align-items: center;
  gap: var(--ds-space-sm);
}

.web-color__picker {
  inline-size: var(--ds-size-control-lg);
  block-size: var(--ds-size-control-md);
  padding: var(--ds-space-xs);
  border: var(--ds-border-width-default) solid var(--ds-border-control);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-canvas);
  cursor: var(--web-cursor-press, pointer);
}

.web-color:not(:has(:checked)) .web-color__picker {
  display: none;
}

/* --- Horario --- */

.web-hours__days {
  display: grid;
  gap: var(--ds-space-md);
}

.web-day {
  display: grid;
  gap: var(--ds-space-xs);
}

.web-day__name {
  padding: 0;
  font-family: var(--ds-text-label-md-family);
  font-size: var(--ds-text-label-md-size);
  font-weight: var(--ds-text-label-md-weight);
  line-height: var(--ds-text-label-md-leading);
}

/* «De … a …» y «y de … a …» alineados en columnas: etiqueta, apertura, etiqueta, cierre. */
.web-day__range {
  display: grid;
  grid-template-columns: var(--ds-space-xl) minmax(0, 1fr) var(--ds-space-sm) minmax(0, 1fr);
  align-items: center;
  gap: var(--ds-space-xs) var(--ds-space-sm);
}

.web-day__range .ds-field__control {
  min-inline-size: 0;
  padding-inline: var(--ds-space-sm);
}

.web-day__label {
  color: var(--ds-fg-secondary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
}

:is(.web-group, .web-choices, .web-colors, .web-hours, .web-rows, .web-day) > legend:not(.web-row__title) {
  padding: 0;
}

.web-hours__copy {
  display: grid;
  justify-items: start;
  gap: var(--ds-space-xs);
  margin-block-start: var(--ds-space-sm);
}

/* --- Archivos --- */

.web-file__input {
  max-inline-size: 100%;
  min-block-size: var(--ds-size-control-md);
  color: var(--ds-fg-secondary);
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
}

/* El botón del campo de archivo, con el tamaño y el aspecto del botón secundario (objetivo de 44 px). */
.web-file__input::file-selector-button {
  min-block-size: var(--ds-size-control-md);
  margin-inline-end: var(--ds-space-md);
  padding-inline: var(--ds-space-lg);
  border: var(--ds-border-width-default) solid transparent;
  border-radius: var(--ds-radius-full);
  background: var(--ds-action-secondary-bg);
  color: var(--ds-action-secondary-fg);
  font-family: var(--ds-text-label-lg-family);
  font-size: var(--ds-text-label-lg-size);
  font-weight: var(--ds-text-label-lg-weight);
  cursor: var(--web-cursor-press, pointer);
}

.web-file__input::file-selector-button:hover {
  background: var(--ds-action-secondary-bg-hover);
}

.web-file {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ds-space-sm) var(--ds-space-md);
  padding: var(--ds-space-sm);
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-md);
  background: var(--ds-bg-surface);
}

.web-file__preview {
  flex: none;
  inline-size: var(--ds-space-4xl);
  aspect-ratio: 1;
  border-radius: var(--ds-radius-sm);
  object-fit: cover;
}

.web-file__name {
  flex: 1;
  min-inline-size: 0;
  overflow-wrap: anywhere;
  font-family: var(--ds-text-body-sm-family);
  font-size: var(--ds-text-body-sm-size);
  line-height: var(--ds-text-body-sm-leading);
}

.web-file[data-file-slot] {
  flex-direction: column;
  align-items: flex-start;
}

/* «Añadir fotos»: el campo de archivos cubre el botón, así que recibe el clic y el foco. */
.web-rows__add {
  position: relative;
  inline-size: fit-content;
}

.web-file__input--button {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  opacity: 0;
  cursor: var(--web-cursor-press, pointer);
}

.web-rows__add:has(.web-file__input--button:focus-visible) .ds-button {
  outline: var(--ds-focus-ring-width) solid var(--ds-focus-ring);
  outline-offset: var(--ds-focus-ring-offset);
}

/* --- Filas: servicios, fotos, preguntas y opiniones --- */

.web-rows__list {
  display: grid;
  gap: var(--ds-space-md);
}

.web-row {
  display: grid;
  gap: var(--ds-space-md);
  padding: var(--ds-space-md) var(--ds-space-lg) var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-lg);
}

.web-row__title {
  padding-inline: var(--ds-space-xs);
  font-family: var(--ds-text-label-lg-family);
  font-size: var(--ds-text-label-lg-size);
  font-weight: var(--ds-text-label-lg-weight);
  line-height: var(--ds-text-label-lg-leading);
}

.web-row__fields {
  display: grid;
  gap: var(--ds-space-md);
}

.web-row__remove {
  justify-self: start;
}

.web-more > .web-row {
  margin-block-start: var(--ds-space-md);
}

.web-more__summary {
  display: flex;
  align-items: center;
  min-block-size: var(--ds-size-control-md);
  color: var(--ds-fg-brand);
  font-family: var(--ds-text-label-md-family);
  font-size: var(--ds-text-label-md-size);
  font-weight: var(--ds-text-label-md-weight);
  cursor: var(--web-cursor-press, pointer);
}

/* --- Paso a paso --- */

.web-guide {
  display: grid;
  gap: var(--ds-space-lg);
}

.web-guide__thread,
.web-guide__current {
  display: grid;
  gap: var(--ds-space-md);
}

.web-guide__thread:empty {
  display: none;
}

.web-guide__step {
  margin-block-start: var(--ds-space-lg);
  color: var(--ds-fg-brand);
}

.web-guide__done {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--ds-space-md);
  padding: var(--ds-space-md) var(--ds-space-md) var(--ds-space-md) var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-bg-surface);
}

.web-guide__done-body {
  display: grid;
  gap: var(--ds-space-xs);
  padding-block-start: var(--ds-space-sm);
}

.web-guide__answer {
  display: grid;
  gap: var(--ds-space-xs);
  margin: 0;
}

.web-guide__answer dt {
  color: var(--ds-fg-secondary);
  font-family: var(--ds-text-caption-family);
  font-size: var(--ds-text-caption-size);
  line-height: var(--ds-text-caption-leading);
}

.web-guide__answer dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.web-guide__skipped {
  color: var(--ds-fg-secondary);
}

.web-guide__intro,
.web-guide__confirm,
.web-guide__review {
  display: grid;
  justify-items: start;
  gap: var(--ds-space-md);
}

.web-guide__card {
  display: grid;
  gap: var(--ds-space-lg);
  padding: var(--ds-space-lg);
  border: var(--ds-border-width-default) solid var(--ds-border-subtle);
  border-radius: var(--ds-radius-lg);
  background: var(--ds-bg-raised);
  box-shadow: var(--ds-shadow-raised);
  scroll-margin-block-start: calc(var(--ds-size-nav) + var(--ds-space-md));
}

.web-guide__meta {
  display: grid;
  gap: var(--ds-space-sm);
}

.web-guide__progress {
  color: var(--ds-fg-secondary);
}

.web-guide__bar {
  appearance: none;
  inline-size: 100%;
  block-size: var(--ds-space-xs);
  overflow: hidden;
  border: 0;
  border-radius: var(--ds-radius-full);
  background: var(--ds-border-subtle);
}

.web-guide__bar::-webkit-progress-bar {
  background: var(--ds-border-subtle);
}

.web-guide__bar::-webkit-progress-value {
  background: var(--ds-gradient-brand);
  transition: inline-size var(--ds-duration-base) var(--ds-ease-standard);
}

.web-guide__bar::-moz-progress-bar {
  background: var(--ds-gradient-brand);
}

/* La pregunta hace de etiqueta del campo, con tamaño de titular. */
.web-guide__label {
  padding: 0;
  font-family: var(--ds-text-heading-lg-family);
  font-size: var(--ds-text-heading-lg-size);
  font-weight: var(--ds-text-heading-lg-weight);
  line-height: var(--ds-text-heading-lg-leading);
  letter-spacing: var(--ds-text-heading-lg-tracking);
  text-wrap: balance;
}

.web-guide__slot .web-group__fields {
  margin-block-start: var(--ds-space-md);
}

.web-guide__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ds-space-sm);
}

@media (min-width: 640px) {
  .web-guide__card {
    padding: var(--ds-space-xl);
  }

  .web-row__fields {
    grid-template-columns: repeat(auto-fill, minmax(calc(var(--ds-space-4xl) * 2.5), 1fr));
  }

  .web-row__fields > :is(.ds-field:not(.web-field--short), .web-check-field, .web-choices, .web-file) {
    grid-column: 1 / -1;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .web-guide__current > .web-guide__card {
    animation: web-guide-enter var(--ds-duration-slow) var(--ds-ease-emphasized) both;
  }

  @keyframes web-guide-enter {
    from {
      opacity: 0;
      translate: 0 var(--ds-space-md);
    }
  }
}

/* Cuestionario: lo que depende de otras respuestas, generado desde cuestionario.mjs */
form:not(:has([name="kind"][value="campaign"]:checked)) [data-when="kind:campaign"] {
  display: none;
}

form:not(:has([name="business.sector"] option[value="other"]:checked)) [data-when="business.sector:other"] {
  display: none;
}

form:not(:has([name="kind"][value="product"]:checked, [name="kind"][value="entity"]:checked)) [data-when="kind:product,entity"] {
  display: none;
}

form:not(:has([name="business.languages"][value="eu"]:checked, [name="business.languages"][value="gl"]:checked, [name="business.languages"][value="fr"]:checked, [name="business.languages"][value="de"]:checked, [name="business.languages"][value="it"]:checked, [name="business.languages"][value="pt"]:checked)) [data-when="business.languages:eu,gl,fr,de,it,pt"] {
  display: none;
}

form:not(:has([name="goal.primary"][value="booking"]:checked, [name="goal.primary"][value="signup"]:checked, [name="goal.primary"][value="membership"]:checked, [name="goal.primary"][value="donation"]:checked, [name="goal.primary"][value="purchase"]:checked)) [data-when="goal.primary:booking,signup,membership,donation,purchase"] {
  display: none;
}

form:not(:has([name="location.mode"][value="premises"]:checked)) [data-when="location.mode:premises"] {
  display: none;
}

form:not(:has([name="location.mode"][value="service-area"]:checked)) [data-when="location.mode:service-area"] {
  display: none;
}

form:not(:has([name="location.mode"][value="premises"]:checked, [name="location.mode"][value="service-area"]:checked)) [data-when="location.mode:premises,service-area"] {
  display: none;
}

.web-row:not(:has([name$=".showsPeople"]:checked)) [data-when="images.*.showsPeople=true"] {
  display: none;
}

form:not(:has([name="domain.status"][value="have"]:checked, [name="domain.status"][value="want"]:checked)) [data-when="domain.status:have,want"] {
  display: none;
}

form:not(:has([name="domain.status"][value="have"]:checked)) [data-when="domain.status:have"] {
  display: none;
}

/* Kranky, de Sideshow (Apache 2.0), para la maqueta del taller de cerámica */
@font-face {
  font-family: "Kranky";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/kranky-latin.230e883789.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}


/* Paletas y tipografías de los ejemplos del catálogo, generadas desde BRANDS en src/render.mjs */
.web-brand--service {
  --web-brand-bg: #f5f8f7;
  --web-brand-surface: #ffffff;
  --web-brand-sunken: #e4edea;
  --web-brand-edge: #d8e4e0;
  --web-brand-muted: #b6c7c2;
  --web-brand-ink: #10302b;
  --web-brand-ink-soft: #4a6762;
  --web-brand-accent: #0e7c6c;
  --web-brand-on-accent: #ffffff;
  --web-brand-font: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --web-brand-font-body: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --web-brand-shell: #dee4e3;
  --web-brand-quiet: #0f5248;
  --web-brand-body: #304e49;
}

.web-brand--event {
  --web-brand-bg: #0b1020;
  --web-brand-surface: #161d33;
  --web-brand-sunken: #1e2745;
  --web-brand-edge: #2a3455;
  --web-brand-muted: #3d4a6e;
  --web-brand-ink: #eef3ff;
  --web-brand-ink-soft: #9aa7c7;
  --web-brand-accent: #c8f24e;
  --web-brand-on-accent: #10162a;
  --web-brand-font: "Arial Narrow", "Avenir Next Condensed", "Helvetica Neue", sans-serif;
  --web-brand-font-body: "Arial Narrow", "Avenir Next Condensed", "Helvetica Neue", sans-serif;
  --web-brand-shell: #222736;
  --web-brand-quiet: #c8f24e;
  --web-brand-body: #a7b2cf;
}

.web-brand--gallery {
  --web-brand-bg: #faf3ea;
  --web-brand-surface: #fffaf3;
  --web-brand-sunken: #f0e3d4;
  --web-brand-edge: #e5d5c2;
  --web-brand-muted: #cbb49c;
  --web-brand-ink: #3a2a1f;
  --web-brand-ink-soft: #6f5a48;
  --web-brand-accent: #c25b34;
  --web-brand-on-accent: #fff8f2;
  --web-brand-font: Kranky, Georgia, serif;
  --web-brand-font-body: Georgia, "Times New Roman", serif;
  --web-brand-shell: #e7dfd6;
  --web-brand-quiet: #6a3b26;
  --web-brand-body: #554234;
}

.web-brand--members {
  --web-brand-bg: #121212;
  --web-brand-surface: #1d1d1d;
  --web-brand-sunken: #262626;
  --web-brand-edge: #333333;
  --web-brand-muted: #4d4d4d;
  --web-brand-ink: #f6f6f6;
  --web-brand-ink-soft: #a8a8a8;
  --web-brand-accent: #ff5c1a;
  --web-brand-on-accent: #1a0c04;
  --web-brand-font: "Avenir Next", Futura, "Trebuchet MS", sans-serif;
  --web-brand-font-body: "Avenir Next", Futura, "Trebuchet MS", sans-serif;
  --web-brand-shell: #292929;
  --web-brand-quiet: #fba17d;
  --web-brand-body: #b4b4b4;
}

.web-brand--courses {
  --web-brand-bg: #f6f5f0;
  --web-brand-surface: #ffffff;
  --web-brand-sunken: #e9e9f2;
  --web-brand-edge: #dcdce8;
  --web-brand-muted: #b9bccf;
  --web-brand-ink: #1a2547;
  --web-brand-ink-soft: #545d80;
  --web-brand-accent: #3f4fc4;
  --web-brand-on-accent: #ffffff;
  --web-brand-font: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --web-brand-font-body: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --web-brand-shell: #e0e0df;
  --web-brand-quiet: #303e92;
  --web-brand-body: #3a4466;
}

.web-brand--promo {
  --web-brand-bg: #190a20;
  --web-brand-surface: #26102f;
  --web-brand-sunken: #331640;
  --web-brand-edge: #46204f;
  --web-brand-muted: #6b3372;
  --web-brand-ink: #fdf2ff;
  --web-brand-ink-soft: #d3a6d8;
  --web-brand-accent: #ff2f8e;
  --web-brand-on-accent: #2b0618;
  --web-brand-font: Impact, "Arial Black", Haettenschweiler, sans-serif;
  --web-brand-font-body: Impact, "Arial Black", Haettenschweiler, sans-serif;
  --web-brand-shell: #302136;
  --web-brand-quiet: #fe91c7;
  --web-brand-body: #d3a6d8;
}

