:root {
  /* Tema Dark (base/por defecto). El atributo data-theme en <html> lo cambia en vivo — ver js/theme.js.
     Los tres temas comparten exactamente el mismo set de tokens; solo cambian los valores,
     nunca la arquitectura. Por eso Dark/White/Grey se sienten "un mismo sistema". */

  /* Brand tokens -- capa 1 del sistema de marca ASTRC (docs/ASTRC-BRAND-SYSTEM.md).
     Única fuente de verdad del azul de marca: NINGÚN otro bloque de este
     archivo (temas, #dash-shell) debe volver a declarar su propio hex de
     acento -- todos deben referenciar estas variables via var(). El violeta
     #6d3df5 que todavía usa astrc.com.co se migra a estas mismas variables
     cuando ese sitio adopte esta capa de tokens (Fase 4 del rebrand). */
  --brand-primary: #4865ff;
  --brand-primary-hover: #6b84ff;  /* tinte claro -- hover/texto sobre fondos oscuros, 5.67:1 sobre #121217 */
  --brand-primary-active: #2f4eef; /* tinte oscuro -- hover/texto sobre fondos claros, 6.07:1 sobre blanco / 5.01:1 sobre #e9e9ec */

  --bg: #121217;
  --bg-dark: #080b0d;
  --text: #ffffff;
  --text-dark: #ffffff;
  /* #6c7a89 medía 4.25-4.49:1 sobre los fondos oscuros (por debajo del 4.5:1 de WCAG AA
     para texto normal); este tono un poco más claro pasa holgadamente sin notarse "gris pálido". */
  --muted: #8291a3;
  --muted-dark: #8291a3;
  /* Alias temporal: el sistema de marca pide un nivel --text-secondary
     distinto de --text-muted, pero hoy no hay una decisión de diseño que
     los diferencie -- se alias-ea a --muted en vez de inventar un gris
     nuevo sin necesidad. Revisar cuando haya jerarquía real de 3 niveles. */
  --text-secondary: var(--muted);
  --accent: var(--brand-primary);
  --accent-hover: var(--brand-primary-hover);
  --brand-primary-text: var(--brand-primary-hover); /* texto de acento sobre fondo oscuro */
  /* Colores de estado (Fase de gráficos del dashboard) -- idénticos en los 3
     temas, igual que --accent. Antes vivían repetidos como hex sueltos
     dentro de .dash-status-pill; ahora son la única fuente de verdad, así
     que un gráfico (donut/leyenda) puede reusar exactamente el mismo verde/
     ámbar/rojo que ya significan "confirmado/stock bajo/cancelado" en el
     resto del dashboard, sin inventar un tono nuevo. */
  --status-good: #2f9e5c;
  --status-warning: #c9821f;
  --status-critical: #d0453c;
  /* Alias -- arregla un fallback roto: .ds-positive usaba
     var(--status-success, #35c759) pero --status-success nunca existió,
     así que ese fallback hardcodeado se estaba usando siempre. */
  --status-success: var(--status-good);
  /* No existía un tono "informativo" propio -- reusa el mismo azul que ya
     usa el dashboard para notices informativos (--sky en #dash-shell), para
     no inventar un tercer azul de marca. */
  --info: #5ba4f5;
  --border: rgba(255, 255, 255, 0.12);
  --border-dark: rgba(255, 255, 255, 0.14);
  --border-subtle: color-mix(in srgb, var(--border) 50%, transparent);
  /* Traslúcidas (glassmorphism) con la misma alpha que --header-bg ya usaba
     en .nav (0.72) -- reusa un valor probado en vez de inventar uno nuevo. */
  --surface: rgba(26, 26, 34, 0.72);
  --surface-2: rgba(36, 36, 46, 0.72);
  --shadow: rgba(0, 0, 0, 0.4);
  --shadow-soft: rgba(0, 0, 0, 0.28);
  --header-bg: rgba(8, 11, 13, 0.72);
  --hero-bg-image: url("../assets/hero/astrc-hero-bg-dark.png");
  --hero-glow: rgba(72, 101, 255, 0.16);
  --radius: 18px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* Glassmorphism: mismo blur que ya usaba .nav (14px) -- una sola fuente de
     verdad para que tarjetas/paneles/modales se sientan "un mismo material"
     en vez de un valor distinto por componente. */
  --glass-blur: 14px;
  /* Tipografía "Sistema Visual ASTRC" -- Plus Jakarta Sans como familia
     principal (cargada via Google Fonts en dashboard.html), JetBrains Mono
     SOLO para datos técnicos (códigos, SKU, identificadores, --font-mono).
     El stack de sistema queda como fallback si la fuente no cargó todavía. */
  --font: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  /* Ritmo vertical entre secciones de contenido (Así de simple, Tiendas, CTA final).
     El Hero usa su propio valor (más grande, es la "gran entrada") y no este token. */
  --space-section-y: 96px;
  --space-section-y-mobile: 64px;

  /* Escala tipográfica / espaciado / radio del "Sistema visual ASTRC"
     (astrc-sistema-visual.html). Tokens NUEVOS, no reemplazan valores
     puntuales ya usados en el CSS existente (evita un refactor masivo
     fuera de alcance) -- están disponibles para componentes nuevos y para
     ir migrando gradualmente los existentes. Base 4px, igual que el
     documento de dirección de arte. */
  --fs-display: 40px;
  --fs-title: 28px;
  --fs-section: 20px;
  --fs-card: 16px;
  --fs-body: 15px;
  --fs-table: 13.5px;
  --fs-label: 11px;
  /* Tres niveles que faltaban en la escala original para completar la
     jerarquía de 13 pasos del Sistema Visual (subtítulo de sección,
     cuerpo secundario/ayuda, y metadatos/caption). El resto de la
     jerarquía reutiliza los 7 tokens de arriba -- no se duplican valores
     que ya existen (ej. metric-value reusa --fs-title, no crea --fs-metric). */
  --fs-subsection: 18px;
  --fs-body-small: 13px;
  --fs-caption: 12px;
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-6: 24px;
  --sp-8: 32px;
  --r-input: 10px;
  --r-card: 16px;
  /* Escala de sombra -- reusa --shadow/--shadow-soft (ya correctos por tema)
     en vez de rgba fijos nuevos, así --sh-* automáticamente sigue siendo
     correcto en dark/light/grey sin redeclarar nada por tema. */
  --sh-sm: 0 1px 2px var(--shadow-soft), 0 6px 16px -12px var(--shadow);
  --sh-md: 0 2px 6px var(--shadow-soft), 0 22px 48px -28px var(--shadow);
  --r-panel: 20px;
  --r-modal: 22px;
}

[data-theme="light"] {
  --bg: #ffffff;
  --bg-dark: #ffffff;
  --text: #111111;
  --text-dark: #111111;
  --muted: #6e6e73;
  --muted-dark: #6e6e73;
  --accent: var(--brand-primary);
  --accent-hover: var(--brand-primary-active);
  --brand-primary-text: var(--brand-primary-active); /* texto de acento sobre fondo claro/gris */
  --border: #e5e5e7;
  --border-dark: #e5e5e7;
  --surface: rgba(247, 247, 248, 0.72);
  --surface-2: rgba(238, 238, 239, 0.72);
  --shadow: rgba(17, 17, 20, 0.10);
  --shadow-soft: rgba(17, 17, 20, 0.06);
  --header-bg: rgba(255, 255, 255, 0.72);
  --hero-bg-image: url("../assets/hero/astrc-hero-bg-white.png");
  --hero-glow: rgba(72, 101, 255, 0.10);
}

[data-theme="grey"] {
  --bg: #e9e9ec;
  --bg-dark: #e9e9ec;
  --text: #17171a;
  --text-dark: #17171a;
  --muted: #63636a;
  --muted-dark: #63636a;
  --accent: var(--brand-primary);
  --accent-hover: var(--brand-primary-active);
  --brand-primary-text: var(--brand-primary-active); /* texto de acento sobre fondo claro/gris */
  --border: #d3d3d9;
  --border-dark: #d3d3d9;
  --surface: rgba(245, 245, 247, 0.72);
  --surface-2: rgba(255, 255, 255, 0.72);
  --shadow: rgba(23, 23, 26, 0.12);
  --shadow-soft: rgba(23, 23, 26, 0.07);
  --header-bg: rgba(233, 233, 236, 0.72);
  --hero-bg-image: url("../assets/hero/astrc-hero-bg-grey.png");
  --hero-glow: rgba(72, 101, 255, 0.12);
}

/* Dentro de una tienda (tienda.html) la protagonista es la marca del cliente, no ASTRC.
   El tema (dark/light/grey) sigue controlando fondo/texto/superficies con normalidad;
   acá solo se fija un acento neutro por defecto. Si la tienda tiene colorPrimario,
   tienda-detalle.js sobreescribe --accent en línea sobre este mismo elemento y gana. */
body.tienda-experiencia {
  --accent: #52525c;
}

/* Menú público: una experiencia de restaurante, independiente del panel interno. */
body.menu-public-page {
  --menu-accent: var(--accent);
  min-height: 100vh;
  background: radial-gradient(circle at 50% -10%, color-mix(in srgb, var(--menu-accent) 18%, transparent), transparent 38%), var(--bg);
}

.menu-public-loading,
.menu-public-empty { max-width: 640px; margin: 0 auto; padding: 96px 24px; text-align: center; color: var(--muted); }
.menu-public-empty h1, .menu-public-empty h2 { color: var(--text); letter-spacing: -0.03em; }
.menu-public-empty small { display: block; margin-top: 28px; }
.menu-public-mark { display: grid; place-items: center; width: 56px; height: 56px; margin: 0 auto 20px; border-radius: 18px; background: color-mix(in srgb, var(--menu-accent) 16%, var(--surface)); color: var(--menu-accent); font-size: 24px; }
.menu-public-hero { max-width: 980px; margin: 0 auto; padding: 56px 24px 30px; text-align: center; }
.menu-public-logo { display: grid; place-items: center; width: 86px; height: 86px; margin: 0 auto 18px; overflow: hidden; border: 1px solid var(--border); border-radius: 28px; background: var(--surface); box-shadow: 0 16px 34px var(--shadow-soft); color: var(--menu-accent); font-size: 30px; }
.menu-public-logo img { width: 100%; height: 100%; object-fit: contain; padding: 8px; }
.menu-public-eyebrow { margin: 0 0 6px; color: var(--menu-accent); font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.menu-public-hero h1 { max-width: 760px; margin: 0 auto; color: var(--text); font-size: clamp(34px, 6vw, 58px); letter-spacing: -0.055em; line-height: 1.05; }
.menu-public-intro { max-width: 490px; margin: 15px auto 0; color: var(--muted); }
.menu-public-nav { display: flex; gap: 8px; justify-content: center; margin-top: 28px; overflow-x: auto; padding: 4px 2px 10px; scrollbar-width: none; }
.menu-public-nav a { flex: 0 0 auto; border: 1px solid var(--border); border-radius: 999px; padding: 8px 14px; background: var(--surface); color: var(--text); font-size: 14px; font-weight: 700; text-decoration: none; transition: transform .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease); }
.menu-public-nav a:hover { border-color: var(--menu-accent); color: var(--menu-accent); transform: translateY(-2px); }
.menu-public-content { max-width: 980px; margin: 0 auto; padding: 10px 24px 52px; }
.menu-public-category { scroll-margin-top: 18px; margin-top: 48px; }
.menu-public-category-head { display: flex; align-items: end; justify-content: space-between; gap: 20px; margin-bottom: 18px; }
.menu-public-category-head h2 { margin: 0; color: var(--text); font-size: clamp(26px, 4vw, 34px); letter-spacing: -0.04em; }
.menu-public-category-head .menu-public-eyebrow { margin-bottom: 4px; }
.menu-public-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.menu-public-item { display: grid; grid-template-columns: 118px 1fr; min-height: 142px; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: 0 10px 30px var(--shadow-soft); transition: transform .22s var(--ease), box-shadow .22s var(--ease); }
.menu-public-item:hover { transform: translateY(-3px); box-shadow: 0 16px 34px var(--shadow); }
.menu-public-item-image, .menu-public-item-placeholder { width: 100%; height: 100%; min-height: 142px; object-fit: cover; background: color-mix(in srgb, var(--menu-accent) 12%, var(--surface-2)); }
.menu-public-item-placeholder { display: grid; place-items: center; color: var(--menu-accent); font-size: 25px; }
.menu-public-item-body { display: flex; flex-direction: column; justify-content: space-between; gap: 14px; padding: 16px; }
.menu-public-item h3 { margin: 0; color: var(--text); font-size: 17px; line-height: 1.2; }
.menu-public-item p, .menu-public-muted { margin: 7px 0 0; color: var(--muted); font-size: 14px; }
.menu-public-item strong { color: var(--menu-accent); font-size: 16px; }
.menu-public-add, .menu-public-order { border: 0; border-radius: 10px; padding: 9px 12px; background: var(--menu-accent); color: #fff; font: inherit; font-weight: 800; cursor: pointer; }
.menu-public-add { align-self: flex-start; margin-top: -4px; font-size: 13px; }
.menu-public-cart { position: sticky; bottom: 12px; z-index: 5; max-width: 760px; margin: 0 auto 24px; padding: 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); box-shadow: 0 18px 44px var(--shadow); backdrop-filter: blur(var(--glass-blur)); }
.menu-public-cart > p { margin: 0; color: var(--muted); text-align: center; }
.menu-public-cart-head, .menu-public-cart-total, .menu-public-cart-lines > div { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.menu-public-cart-head { margin-bottom: 10px; color: var(--text); }.menu-public-cart-head span { color: var(--muted); font-size: 13px; }
.menu-public-cart-lines { display: grid; gap: 7px; }.menu-public-cart-lines > div { color: var(--text); font-size: 14px; }.menu-public-cart-lines button { border: 1px solid var(--border); border-radius: 8px; background: transparent; color: var(--text); cursor: pointer; }
.menu-public-cart-total { margin: 14px 0; padding-top: 12px; border-top: 1px solid var(--border); }.menu-public-cart-total strong { color: var(--menu-accent); }
.menu-public-cart form { display: grid; gap: 9px; }.menu-public-cart input, .menu-public-cart textarea { width: 100%; border: 1px solid var(--border); border-radius: 10px; padding: 10px; background: var(--bg); color: var(--text); font: inherit; }.menu-public-cart textarea { min-height: 58px; resize: vertical; }.menu-public-order { width: 100%; }.menu-public-order:disabled { cursor: wait; opacity: .7; }.menu-public-order-success { color: var(--text) !important; }
.menu-public-error { display: none; margin: 0; font-size: 13px; font-weight: 600; color: var(--rose, #d0453c); }.menu-public-error.visible { display: block; }
.menu-public-footer { display: flex; justify-content: space-between; max-width: 980px; margin: 0 auto; padding: 24px; border-top: 1px solid var(--border); color: var(--muted); font-size: 13px; }
@media (max-width: 640px) {
  .menu-public-hero { padding-top: 38px; }
  .menu-public-grid { grid-template-columns: 1fr; }
  .menu-public-item { grid-template-columns: 96px 1fr; min-height: 122px; }
  .menu-public-item-image, .menu-public-item-placeholder { min-height: 122px; }
  .menu-public-category { margin-top: 34px; }
  .menu-public-footer { flex-direction: column; gap: 6px; text-align: center; }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.3s ease, color 0.3s ease;
}

a { color: inherit; }

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

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.nav-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 16px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-size: 20px;
  text-decoration: none;
}

/* Header de tienda.html: pertenece visualmente al cliente, no a ASTRC */

.tienda-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
  font-weight: 700;
  font-size: 17px;
}

.tienda-brand-logo {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--muted);
  font-size: 14px;
  font-weight: 800;
  flex-shrink: 0;
}

.tienda-brand-logo img { width: 100%; height: 100%; object-fit: cover; }

.brand-logo-img {
  height: 26px;
  width: auto;
}

/* Los 3 PNG (astrc-logo-dark/white/grey) comparten el mismo lienzo (2172x724) pero
   el trazo del isotipo NO está dibujado con el mismo tamaño ni el mismo margen
   interno dentro de ese lienzo en los tres. Medido con análisis de píxeles sobre el
   render real (bounding box del contenido no transparente dentro del <img> ya
   escalado por CSS, no solo el tamaño del archivo):
     - dark:  alto de tinta 11.375px, arranque horizontal en x=188.125 (a height:26px)
     - white: alto de tinta 11.625px, arranque horizontal en x=187.000 (a height:26px)
     - grey:  a height:26px medía ~13-14px de alto (marca dibujada más grande dentro
       del lienzo) y arrancaba ~3px más a la izquierda que dark/white.
   Se corrige SOLO con CSS (altura de caja + margin-left), sin tocar los PNG:
   la altura de este logo se reduce a 23.86px (calibrado empíricamente contra el
   render real, no solo por proporción del archivo) hasta que el alto de tinta
   coincide con dark/white (11.5px, quedando entre ambos), y se corrige el
   corrimiento horizontal con un margin-left para que la "A" arranque en el mismo
   punto que en los otros dos temas. Ver verificación con Playwright en el historial:
   con esto los 3 temas quedan dentro de 0.25px de alto y arrancan en el mismo x. */
[data-theme="light"] .brand-logo-img {
  margin-left: 1.1px;
}

[data-theme="grey"] .brand-logo-img {
  height: 23.86px;
  margin-left: 3.1px;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
  font-size: 14px;
}

.nav-links a {
  text-decoration: none;
  color: var(--text);
}

.nav-links a:hover { color: var(--accent); }

/* Subrayado animado — solo en los links de primer nivel (Inicio, Explorar,
   Contacto), no en los items del menú "Explorar" ni en las opciones de tema,
   que ya tienen su propio hover (fondo resaltado). */
.nav-links > a,
.nav-links > .nav-dropdown > .nav-dropdown-link {
  position: relative;
}

.nav-links > a::after,
.nav-links > .nav-dropdown > .nav-dropdown-link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s var(--ease);
}

.nav-links > a:hover::after,
.nav-links > a:focus-visible::after,
.nav-links > .nav-dropdown > .nav-dropdown-link:hover::after,
.nav-links > .nav-dropdown > .nav-dropdown-link:focus-visible::after {
  transform: scaleX(1);
}

/* Nav dropdown (ver "Tiendas") */

.nav-dropdown {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.nav-dropdown-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  /* Área táctil ampliada a >=44px en ambos lados (antes medía 36x33 — el chevron
     es chico, 10x7). El margen negativo compensa el padding extra para no empujar
     el layout: vertical queda totalmente invisible (-19 cancela +19), horizontal
     conserva el mismo respiro visible que ya existía junto a "Explorar"/"Contacto"
     (footprint neto +13px, igual que antes: 18-5=13). */
  padding: 19px 18px;
  margin: -19px -5px;
  cursor: pointer;
  color: var(--muted);
  transition: color 0.2s var(--ease), transform 0.15s var(--ease);
}

.nav-dropdown-trigger:hover { color: var(--accent); }
.nav-dropdown-trigger:active { transform: scale(0.92); }

.nav-dropdown-trigger .chevron { transition: transform 0.2s ease; }

.nav-dropdown-trigger[aria-expanded="true"] .chevron { transform: rotate(180deg); }

.nav-dropdown-menu {
  position: absolute;
  /* Sin espacio muerto entre el trigger y el menú: si hay separación visual acá,
     mover el cursor de "Explorar" al menú cruza una zona sin hover y lo cierra antes
     de tiempo. El respiro visual lo da el padding interno, no un gap en "top". */
  top: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  min-width: 190px;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 8px;
  box-shadow: 0 16px 32px var(--shadow), 0 4px 24px var(--hero-glow);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease, background-color 0.3s ease, border-color 0.3s ease;
  z-index: 60;
}

.nav-dropdown-menu.open {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

.nav-links .nav-dropdown-menu a {
  display: block;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 14px;
  border-bottom: none;
}

.nav-links .nav-dropdown-menu a:hover,
.nav-links .nav-dropdown-menu a:focus-visible {
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--accent);
}

/* Selector de tema — mismo componente .nav-dropdown, anclado a la derecha para no
   salirse de la pantalla en mobile (el de "Explorar" queda centrado, este no). */

.theme-dropdown .nav-dropdown-menu {
  left: auto;
  right: 0;
  transform: translateY(-6px);
  min-width: 150px;
}

.theme-dropdown .nav-dropdown-menu.open { transform: translateY(0); }

/* Cuenta (Fase 5A) — mismo componente .nav-dropdown, mismo anclaje a la
   derecha que el selector de tema, para no salirse de la pantalla. */
.account-dropdown .nav-dropdown-menu {
  left: auto;
  right: 0;
  transform: translateY(-6px);
  min-width: 170px;
}

.account-dropdown .nav-dropdown-menu.open { transform: translateY(0); }

/* "+" de creación rápida global (Fase 3) -- mismo componente .nav-dropdown,
   mismo anclaje a la derecha que Tema/Cuenta. El wrapper entero queda
   `hidden` si el rol activo no tiene ningún permiso de escritura de los
   listados (pintarQuickCreate() en dashboard.js decide eso). */
.quick-create-dropdown .nav-dropdown-menu {
  left: auto;
  right: 0;
  transform: translateY(-6px);
  min-width: 190px;
}

.quick-create-dropdown .nav-dropdown-menu.open { transform: translateY(0); }

.quick-create-dropdown .nav-dropdown-menu a {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: var(--fs-body-small);
  color: var(--text);
  text-decoration: none;
}

.quick-create-dropdown .nav-dropdown-menu a:hover,
.quick-create-dropdown .nav-dropdown-menu a:focus-visible {
  background: var(--surface-2);
  color: var(--accent);
}

/* Botón flotante de ayuda del dashboard -- mismo componente .nav-dropdown,
   pero fijo a la ventana (no al topbar) y el menú se abre hacia ARRIBA
   porque vive pegado al borde inferior. */
.dash-help-fab {
  position: fixed;
  right: 20px;
  bottom: max(20px, env(safe-area-inset-bottom));
  z-index: 70;
}

.dash-help-fab .help-trigger {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--muted);
  box-shadow: var(--shadow-soft, 0 8px 24px var(--shadow));
  padding: 0;
  margin: 0;
}

.dash-help-fab .help-trigger:hover,
.dash-help-fab .help-trigger[aria-expanded="true"] { color: var(--accent); border-color: var(--jade-dim); }

.dash-help-fab .nav-dropdown-menu {
  top: auto;
  left: auto;
  right: 0;
  bottom: 100%;
  margin-bottom: 10px;
  transform: translateY(6px);
  min-width: 220px;
}

.dash-help-fab .nav-dropdown-menu.open { transform: translateY(0); }

.dash-help-fab .nav-dropdown-menu a {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: var(--fs-body-small);
  color: var(--text);
  text-decoration: none;
}

.dash-help-fab .nav-dropdown-menu a:hover,
.dash-help-fab .nav-dropdown-menu a:focus-visible {
  background: var(--surface-2);
  color: var(--accent);
}

@media (max-width: 640px) {
  .dash-help-fab { right: 14px; bottom: max(14px, env(safe-area-inset-bottom)); }
}

.theme-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 10px 14px;
  border-radius: 8px;
  font-family: var(--font);
  font-size: var(--fs-body-small);
  color: var(--text);
  background: none;
  border: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.2s ease;
}

.theme-option:hover,
.theme-option:focus-visible {
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--accent);
}

.theme-option.active { color: var(--accent-hover); font-weight: 600; }

.theme-option.active::after {
  content: "✓";
  font-size: 12px;
}

/* Mismo componente .theme-option reutilizado dentro de una tarjeta de
   Configuración (dashboard-configuracion.js) -- ahí no vive dentro de
   .nav-dropdown-menu (que le da el fondo/sombra flotante), así que se le
   agrega un borde propio para que se lea como opción clickeable suelta. */
.dash-settings-theme-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.dash-settings-theme-options .theme-option {
  border: 1px solid var(--border);
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 20px;
}

.nav-search-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  /* 43x43 medía antes (1px corto del mínimo táctil de 44px). El margen no
     compensa el padding entero a propósito: conserva el mismo respiro visible
     que ya tenía junto a los demás íconos del header (footprint neto +4px). */
  padding: 13px;
  margin: -9px;
  color: var(--text);
  cursor: pointer;
  transition: color 0.2s var(--ease), transform 0.15s var(--ease);
}

.nav-search-trigger:hover { color: var(--accent); }
.nav-search-trigger:active { transform: scale(0.92); }

.cart-link {
  position: relative;
  display: flex;
  align-items: center;
  padding: 12px;
  margin: -12px;
  color: var(--text);
  text-decoration: none;
  transition: color 0.2s var(--ease), transform 0.15s var(--ease);
}

.cart-link:hover { color: var(--accent); }
.cart-link:active { transform: scale(0.92); }

.cart-count {
  position: absolute;
  /* +12px respecto a los valores originales: compensa el padding que ahora tiene
     .cart-link (área táctil ampliada) para que el badge siga pegado al ícono. */
  top: 4px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent);
  color: #ffffff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* Feedback al agregar un producto: un pequeño "salto" en el badge del carrito
   cuando el total sube (ver actualizarContadorCarrito en js/carrito.js). No se
   dispara en la carga inicial de la página ni al restar/eliminar productos. */
@keyframes cart-count-bump {
  0% { transform: scale(1); }
  40% { transform: scale(1.35); }
  100% { transform: scale(1); }
}

.cart-count.bump { animation: cart-count-bump 0.45s var(--ease); }

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  /* Medía 46x40 (el icono de 3 barras es más ancho que alto, así que el lado
     corto -alto- quedaba bajo el mínimo táctil de 44px). Padding vertical más
     grande, compensado del todo por el margen: cero impacto de layout. */
  padding: 15px 12px;
  margin: -15px -12px;
}

.nav-toggle span {
  width: 22px;
  height: 2px;
  background: var(--text);
  display: block;
}

/* Hero */

.hero {
  position: relative;
  z-index: 0;
  overflow: hidden;
  min-height: 86vh;
  background-color: var(--bg-dark);
  background-image: var(--hero-bg-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  color: var(--text-dark);
  display: flex;
  align-items: center;
  padding: 120px 24px;
  transition: background-color 0.3s ease;
}

.hero-inner {
  position: relative;
  z-index: 1;
  max-width: 1120px;
  width: 100%;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 56px;
}

.hero-copy { text-align: left; }

/* Entrada escalonada del hero (ver js/hero.js, usa la librería "motion"). Estado
   inicial en CSS puro para que no haya parpadeo mientras carga el módulo JS. */
.hero-animate { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .hero-animate { opacity: 1 !important; }
}

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted-dark);
  margin: 0 0 20px;
}

.hero h1 {
  font-size: clamp(2.4rem, 5.5vw, 4.4rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin: 0 0 24px;
}

.accent-text { color: var(--accent); }

.hero-sub {
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  color: var(--muted-dark);
  max-width: 440px;
  margin: 0 0 36px;
  line-height: 1.5;
}

.hero-ctas {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}

.cta {
  display: inline-block;
  background: var(--accent);
  color: #ffffff;
  text-decoration: none;
  font-weight: 600;
  font-size: 15px;
  padding: 14px 32px;
  border-radius: 999px;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background-color 0.25s var(--ease);
}

.cta:hover {
  background: var(--accent-hover);
  transform: translateY(-2px);
  /* color-mix, no un rgba fijo: si una tienda define colorPrimario (--accent
     pasa a ser, por ej., naranja), este brillo debe seguir a ese color en vez de
     quedarse azul ASTRC — antes rompía la identidad de la tienda justo al hacer
     hover sobre su botón principal. */
  box-shadow: 0 12px 24px color-mix(in srgb, var(--accent) 35%, transparent);
}

.cta:active { transform: translateY(0); }

.cta-light {
  /* Invertido respecto a bg-dark/text-dark: así siempre contrasta, sea cual sea el tema
     (blanco-sobre-negro en Dark, negro-sobre-blanco en White/Grey), sin quedar invisible. */
  background: var(--text-dark);
  color: var(--bg-dark);
}

.cta-light:hover {
  box-shadow: 0 12px 24px var(--shadow-soft);
}

.cta-arrow {
  display: inline-block;
  margin-left: 6px;
  transition: transform 0.2s ease;
}

.cta:hover .cta-arrow { transform: translateX(3px); }

.cta-text {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text-dark);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
}

.cta-text:hover { color: var(--accent); }

.cta-text .play-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--text-dark) 35%, transparent);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.cta-text:hover .play-icon {
  border-color: var(--accent);
  transform: scale(1.05);
}

/* Hero — cápsula ASTRC (astrc-personaje-capsula.png, recortada con clip-path a su
   silueta real; ver detalle en la regla .hero-capsule-img más abajo) */

.hero-visual {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 320px;
}

.hero-capsule {
  position: relative;
  width: min(100%, 460px);
  transition: transform 0.3s ease;
}

/* Resplandor ambiental detrás de la cápsula, sin tocar el asset: un radial-gradient
   difuminado que le da profundidad al personaje contra el fondo del Hero. Usa
   --hero-glow, el mismo token ya calibrado por tema (más sutil en White/Grey, algo
   más presente en Dark) que hasta ahora solo se usaba en la sombra del dropdown. */
.hero-capsule::before {
  content: '';
  position: absolute;
  inset: -18%;
  background: radial-gradient(circle, var(--hero-glow) 0%, transparent 68%);
  filter: blur(18px);
  pointer-events: none;
}

.hero-capsule-img {
  width: 100%;
  height: auto;
  display: block;
  /* El PNG trae su propio fondo negro "quemado". Una máscara elíptica genérica
     recortaba contenido real (luces inferiores izquierdas, borde del aro). Este
     clip-path sigue el contorno REAL del personaje/cápsula: se generó analizando
     los píxeles del propio asset (contorno por fila + 28px de margen de seguridad
     hacia afuera), así que no hay ningún punto del recorte que caiga sobre
     contenido visible — solo sobre el fondo negro que lo rodea. Si se reemplaza
     astrc-personaje-capsula.png por otro asset con una silueta distinta, este
     clip-path debe regenerarse (ver notas de la Fase 1 en el historial del proyecto).
  */
  clip-path: polygon(52.17% 0.00%, 51.04% 0.78%, 49.54% 1.56%, 48.20% 2.34%, 47.06% 3.13%, 46.09% 3.91%, 45.29% 4.69%, 44.64% 5.47%, 44.18% 6.25%, 43.75% 7.03%, 43.34% 7.81%, 42.94% 8.59%, 42.55% 9.38%, 42.29% 10.16%, 42.09% 10.94%, 41.90% 11.72%, 41.51% 12.50%, 41.17% 13.28%, 40.95% 14.06%, 40.87% 14.84%, 40.79% 15.63%, 40.56% 16.41%, 40.19% 17.19%, 39.84% 17.97%, 39.58% 18.75%, 39.40% 19.53%, 39.28% 20.31%, 39.18% 21.09%, 39.14% 21.88%, 39.14% 22.66%, 39.14% 23.44%, 39.16% 24.22%, 39.24% 25.00%, 39.35% 25.78%, 39.55% 26.56%, 39.71% 27.34%, 40.00% 28.13%, 40.47% 28.91%, 41.19% 29.69%, 41.20% 30.47%, 40.25% 31.25%, 35.01% 32.03%, 29.95% 32.81%, 25.19% 33.59%, 22.90% 34.38%, 22.90% 35.16%, 22.90% 35.94%, 22.98% 36.72%, 23.13% 37.50%, 23.29% 38.28%, 23.42% 39.06%, 23.56% 39.84%, 23.72% 40.63%, 23.87% 41.41%, 24.03% 42.19%, 24.16% 42.97%, 24.31% 43.75%, 24.46% 44.53%, 24.62% 45.31%, 24.77% 46.09%, 24.66% 46.88%, 24.20% 47.66%, 23.53% 48.44%, 22.85% 49.22%, 22.14% 50.00%, 21.48% 50.78%, 20.82% 51.56%, 20.20% 52.34%, 19.66% 53.13%, 19.09% 53.91%, 18.53% 54.69%, 17.97% 55.47%, 17.36% 56.25%, 16.79% 57.03%, 16.29% 57.81%, 15.80% 58.59%, 15.37% 59.38%, 14.93% 60.16%, 14.43% 60.94%, 14.03% 61.72%, 13.59% 62.50%, 13.24% 63.28%, 12.87% 64.06%, 12.53% 64.84%, 12.19% 65.63%, 11.90% 66.41%, 11.56% 67.19%, 11.28% 67.97%, 11.02% 68.75%, 10.84% 69.53%, 10.74% 70.31%, 10.63% 71.09%, 10.50% 71.88%, 10.39% 72.66%, 10.29% 73.44%, 10.19% 74.22%, 10.17% 75.00%, 10.11% 75.78%, 10.08% 76.56%, 10.06% 77.34%, 10.06% 78.13%, 10.06% 78.91%, 10.10% 79.69%, 10.17% 80.47%, 10.26% 81.25%, 10.37% 82.03%, 10.51% 82.81%, 10.66% 83.59%, 10.87% 84.38%, 11.10% 85.16%, 11.38% 85.94%, 11.69% 86.72%, 12.02% 87.50%, 12.36% 88.28%, 12.81% 89.06%, 13.29% 89.84%, 13.85% 90.63%, 14.43% 91.41%, 15.13% 92.19%, 15.93% 92.97%, 16.83% 93.75%, 17.79% 94.53%, 18.93% 95.31%, 20.12% 96.09%, 21.60% 96.88%, 23.27% 97.66%, 25.54% 98.44%, 28.42% 99.22%, 29.13% 99.61%, 51.91% 99.61%, 52.63% 99.22%, 55.75% 98.44%, 58.60% 97.66%, 60.75% 96.88%, 62.83% 96.09%, 64.36% 95.31%, 66.09% 94.53%, 67.86% 93.75%, 69.40% 92.97%, 70.66% 92.19%, 71.72% 91.41%, 72.71% 90.63%, 73.82% 89.84%, 74.83% 89.06%, 75.83% 88.28%, 76.72% 87.50%, 77.63% 86.72%, 78.47% 85.94%, 79.30% 85.16%, 80.03% 84.38%, 80.78% 83.59%, 81.52% 82.81%, 82.21% 82.03%, 82.85% 81.25%, 83.44% 80.47%, 83.98% 79.69%, 84.52% 78.91%, 85.02% 78.13%, 85.51% 77.34%, 86.02% 76.56%, 86.51% 75.78%, 86.93% 75.00%, 87.39% 74.22%, 87.74% 73.44%, 88.14% 72.66%, 88.50% 71.88%, 88.84% 71.09%, 89.18% 70.31%, 89.59% 69.53%, 89.95% 68.75%, 90.30% 67.97%, 90.62% 67.19%, 90.96% 66.41%, 91.29% 65.63%, 91.60% 64.84%, 91.87% 64.06%, 92.09% 63.28%, 92.24% 62.50%, 92.35% 61.72%, 92.43% 60.94%, 92.49% 60.16%, 92.53% 59.38%, 92.56% 58.59%, 92.57% 57.81%, 92.57% 57.03%, 92.57% 56.25%, 92.55% 55.47%, 92.52% 54.69%, 92.49% 53.91%, 92.46% 53.13%, 92.44% 52.34%, 92.39% 51.56%, 92.32% 50.78%, 92.23% 50.00%, 92.14% 49.22%, 92.07% 48.44%, 91.97% 47.66%, 91.86% 46.88%, 91.71% 46.09%, 91.56% 45.31%, 91.42% 44.53%, 91.27% 43.75%, 91.12% 42.97%, 90.93% 42.19%, 90.72% 41.41%, 90.49% 40.63%, 90.29% 39.84%, 90.07% 39.06%, 89.79% 38.28%, 89.52% 37.50%, 89.22% 36.72%, 88.90% 35.94%, 88.60% 35.16%, 88.24% 34.38%, 87.87% 33.59%, 87.50% 32.81%, 87.07% 32.03%, 86.62% 31.25%, 86.10% 30.47%, 85.56% 29.69%, 85.02% 28.91%, 84.42% 28.13%, 83.78% 27.34%, 82.99% 26.56%, 82.13% 25.78%, 81.30% 25.00%, 80.08% 24.22%, 78.52% 23.44%, 76.29% 22.66%, 74.15% 21.88%, 72.54% 21.09%, 71.77% 20.31%, 71.69% 19.53%, 71.69% 18.75%, 71.67% 17.97%, 71.61% 17.19%, 71.61% 16.41%, 71.68% 15.63%, 71.70% 14.84%, 71.70% 14.06%, 71.67% 13.28%, 71.54% 12.50%, 71.40% 11.72%, 71.21% 10.94%, 71.02% 10.16%, 70.81% 9.38%, 70.60% 8.59%, 70.33% 7.81%, 70.01% 7.03%, 69.62% 6.25%, 69.18% 5.47%, 68.72% 4.69%, 68.16% 3.91%, 67.52% 3.13%, 66.75% 2.34%, 65.83% 1.56%, 64.70% 0.78%, 63.89% 0.00%);
  -webkit-clip-path: polygon(52.17% 0.00%, 51.04% 0.78%, 49.54% 1.56%, 48.20% 2.34%, 47.06% 3.13%, 46.09% 3.91%, 45.29% 4.69%, 44.64% 5.47%, 44.18% 6.25%, 43.75% 7.03%, 43.34% 7.81%, 42.94% 8.59%, 42.55% 9.38%, 42.29% 10.16%, 42.09% 10.94%, 41.90% 11.72%, 41.51% 12.50%, 41.17% 13.28%, 40.95% 14.06%, 40.87% 14.84%, 40.79% 15.63%, 40.56% 16.41%, 40.19% 17.19%, 39.84% 17.97%, 39.58% 18.75%, 39.40% 19.53%, 39.28% 20.31%, 39.18% 21.09%, 39.14% 21.88%, 39.14% 22.66%, 39.14% 23.44%, 39.16% 24.22%, 39.24% 25.00%, 39.35% 25.78%, 39.55% 26.56%, 39.71% 27.34%, 40.00% 28.13%, 40.47% 28.91%, 41.19% 29.69%, 41.20% 30.47%, 40.25% 31.25%, 35.01% 32.03%, 29.95% 32.81%, 25.19% 33.59%, 22.90% 34.38%, 22.90% 35.16%, 22.90% 35.94%, 22.98% 36.72%, 23.13% 37.50%, 23.29% 38.28%, 23.42% 39.06%, 23.56% 39.84%, 23.72% 40.63%, 23.87% 41.41%, 24.03% 42.19%, 24.16% 42.97%, 24.31% 43.75%, 24.46% 44.53%, 24.62% 45.31%, 24.77% 46.09%, 24.66% 46.88%, 24.20% 47.66%, 23.53% 48.44%, 22.85% 49.22%, 22.14% 50.00%, 21.48% 50.78%, 20.82% 51.56%, 20.20% 52.34%, 19.66% 53.13%, 19.09% 53.91%, 18.53% 54.69%, 17.97% 55.47%, 17.36% 56.25%, 16.79% 57.03%, 16.29% 57.81%, 15.80% 58.59%, 15.37% 59.38%, 14.93% 60.16%, 14.43% 60.94%, 14.03% 61.72%, 13.59% 62.50%, 13.24% 63.28%, 12.87% 64.06%, 12.53% 64.84%, 12.19% 65.63%, 11.90% 66.41%, 11.56% 67.19%, 11.28% 67.97%, 11.02% 68.75%, 10.84% 69.53%, 10.74% 70.31%, 10.63% 71.09%, 10.50% 71.88%, 10.39% 72.66%, 10.29% 73.44%, 10.19% 74.22%, 10.17% 75.00%, 10.11% 75.78%, 10.08% 76.56%, 10.06% 77.34%, 10.06% 78.13%, 10.06% 78.91%, 10.10% 79.69%, 10.17% 80.47%, 10.26% 81.25%, 10.37% 82.03%, 10.51% 82.81%, 10.66% 83.59%, 10.87% 84.38%, 11.10% 85.16%, 11.38% 85.94%, 11.69% 86.72%, 12.02% 87.50%, 12.36% 88.28%, 12.81% 89.06%, 13.29% 89.84%, 13.85% 90.63%, 14.43% 91.41%, 15.13% 92.19%, 15.93% 92.97%, 16.83% 93.75%, 17.79% 94.53%, 18.93% 95.31%, 20.12% 96.09%, 21.60% 96.88%, 23.27% 97.66%, 25.54% 98.44%, 28.42% 99.22%, 29.13% 99.61%, 51.91% 99.61%, 52.63% 99.22%, 55.75% 98.44%, 58.60% 97.66%, 60.75% 96.88%, 62.83% 96.09%, 64.36% 95.31%, 66.09% 94.53%, 67.86% 93.75%, 69.40% 92.97%, 70.66% 92.19%, 71.72% 91.41%, 72.71% 90.63%, 73.82% 89.84%, 74.83% 89.06%, 75.83% 88.28%, 76.72% 87.50%, 77.63% 86.72%, 78.47% 85.94%, 79.30% 85.16%, 80.03% 84.38%, 80.78% 83.59%, 81.52% 82.81%, 82.21% 82.03%, 82.85% 81.25%, 83.44% 80.47%, 83.98% 79.69%, 84.52% 78.91%, 85.02% 78.13%, 85.51% 77.34%, 86.02% 76.56%, 86.51% 75.78%, 86.93% 75.00%, 87.39% 74.22%, 87.74% 73.44%, 88.14% 72.66%, 88.50% 71.88%, 88.84% 71.09%, 89.18% 70.31%, 89.59% 69.53%, 89.95% 68.75%, 90.30% 67.97%, 90.62% 67.19%, 90.96% 66.41%, 91.29% 65.63%, 91.60% 64.84%, 91.87% 64.06%, 92.09% 63.28%, 92.24% 62.50%, 92.35% 61.72%, 92.43% 60.94%, 92.49% 60.16%, 92.53% 59.38%, 92.56% 58.59%, 92.57% 57.81%, 92.57% 57.03%, 92.57% 56.25%, 92.55% 55.47%, 92.52% 54.69%, 92.49% 53.91%, 92.46% 53.13%, 92.44% 52.34%, 92.39% 51.56%, 92.32% 50.78%, 92.23% 50.00%, 92.14% 49.22%, 92.07% 48.44%, 91.97% 47.66%, 91.86% 46.88%, 91.71% 46.09%, 91.56% 45.31%, 91.42% 44.53%, 91.27% 43.75%, 91.12% 42.97%, 90.93% 42.19%, 90.72% 41.41%, 90.49% 40.63%, 90.29% 39.84%, 90.07% 39.06%, 89.79% 38.28%, 89.52% 37.50%, 89.22% 36.72%, 88.90% 35.94%, 88.60% 35.16%, 88.24% 34.38%, 87.87% 33.59%, 87.50% 32.81%, 87.07% 32.03%, 86.62% 31.25%, 86.10% 30.47%, 85.56% 29.69%, 85.02% 28.91%, 84.42% 28.13%, 83.78% 27.34%, 82.99% 26.56%, 82.13% 25.78%, 81.30% 25.00%, 80.08% 24.22%, 78.52% 23.44%, 76.29% 22.66%, 74.15% 21.88%, 72.54% 21.09%, 71.77% 20.31%, 71.69% 19.53%, 71.69% 18.75%, 71.67% 17.97%, 71.61% 17.19%, 71.61% 16.41%, 71.68% 15.63%, 71.70% 14.84%, 71.70% 14.06%, 71.67% 13.28%, 71.54% 12.50%, 71.40% 11.72%, 71.21% 10.94%, 71.02% 10.16%, 70.81% 9.38%, 70.60% 8.59%, 70.33% 7.81%, 70.01% 7.03%, 69.62% 6.25%, 69.18% 5.47%, 68.72% 4.69%, 68.16% 3.91%, 67.52% 3.13%, 66.75% 2.34%, 65.83% 1.56%, 64.70% 0.78%, 63.89% 0.00%);
}

.hero-orbit-icons {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.orbit-icon {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  color: var(--text-dark);
  box-shadow: 0 8px 20px var(--shadow);
  animation: flotar 4.5s ease-in-out infinite;
}

.orbit-icon-1 { top: 6%; left: 2%; animation-delay: 0s; }
.orbit-icon-2 { top: 0%; right: 8%; animation-delay: 1.1s; }
.orbit-icon-3 { bottom: 12%; right: -2%; animation-delay: 2.2s; }

@keyframes flotar {
  /* 6px, no 10px: estos íconos son decorativos, alrededor del personaje. Con 10px
     se movían MÁS que la propia cápsula (8px, ver js/hero.js), invirtiendo la
     jerarquía visual — lo secundario no debería moverse más que el protagonista. */
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

@media (max-width: 880px) {
  .hero-inner { grid-template-columns: 1fr; }
  .hero-copy { text-align: center; }
  .hero-sub { margin-left: auto; margin-right: auto; }
  .hero-ctas { justify-content: center; }
  .hero-visual { margin-top: 48px; min-height: 260px; }
  .hero-capsule { width: min(100%, 300px); }
}

/* Cómo funciona */

.how-it-works {
  max-width: 1120px;
  margin: 0 auto;
  padding: var(--space-section-y) 24px;
}

.how-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 32px;
}

.how-step {
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.how-number {
  display: block;
  font-size: 13px;
  font-weight: 700;
  /* --accent-hover, no --accent: a este tamaño --accent mide 3.8-4.3:1 contra
     --surface en los 3 temas (por debajo del 4.5:1 de WCAG AA para texto normal).
     --accent-hover es el mismo azul de marca, ajustado para pasar holgadamente
     (5.2-5.7:1) sin verse como un color distinto. */
  color: var(--accent-hover);
  letter-spacing: 0.08em;
  margin-bottom: 14px;
}

.how-step h3 {
  font-size: 18px;
  font-weight: 700;
  line-height: 1.3;
  margin: 0 0 8px;
}

.how-step p {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
}

/* Stores */

.stores {
  max-width: 1120px;
  margin: 0 auto;
  padding: var(--space-section-y) 24px;
}

.section-head {
  text-align: center;
  margin-bottom: 56px;
}

.section-head h2 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 10px;
}

.section-head p {
  color: var(--muted);
  margin: 0;
}

.store-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 40px;
}

.store-search {
  flex: 1 1 240px;
  max-width: 320px;
  padding: 12px 18px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font);
  /* 16px, no 14px: evita el zoom automático de Safari en iOS al enfocar el campo. */
  font-size: 16px;
  background: var(--bg);
  color: var(--text);
  transition: background-color 0.3s ease, border-color 0.2s var(--ease), color 0.3s ease;
}

.store-search:focus {
  outline: none;
  border-color: var(--accent);
}

.store-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.filter-btn {
  border: 1px solid var(--border);
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: 999px;
  padding: 10px 16px;
  font-family: var(--font);
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), transform 0.15s var(--ease);
}

.filter-btn:hover { color: var(--text); }

.filter-btn:active { transform: scale(0.96); }

.filter-btn.active {
  border-color: var(--accent);
  color: var(--accent-hover);
}

.store-empty {
  text-align: center;
  color: var(--muted);
  padding: 40px 0;
}

/* terminos.html / privacidad.html -- ver js/legal-page.js. */
.legal-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 64px 24px var(--space-section-y);
}

.legal-page h1 { margin-bottom: 24px; }

.legal-cuerpo p {
  color: var(--muted);
  line-height: 1.7;
  margin-bottom: 16px;
}

.placeholder-initial {
  font-size: 32px;
  font-weight: 800;
  color: var(--muted);
}

.store-visual img,
.product-visual img,
.store-logo img,
.product-detail-visual img,
.product-thumb img,
.cart-row-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

/* Microinteracción de imagen: un acercamiento MUY leve al pasar el mouse sobre la
   card completa (no sobre la imagen sola, para que se sienta como parte del mismo
   gesto que la elevación de la card). Contenido dentro de .store-visual/.product-visual
   gracias al overflow:hidden que se les agregó, así nunca se sale del borde redondeado. */
.store-card:hover .store-visual img,
.product-card:hover .product-visual img {
  transform: scale(1.06);
}

.store-visual img,
.product-visual img {
  transition: transform 0.5s var(--ease);
}

.store-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 260px));
  justify-content: center;
  gap: 28px;
}

.store-card {
  display: block;
  text-decoration: none;
  color: var(--text);
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  box-shadow: 0 1px 2px var(--shadow-soft);
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease), background-color 0.3s ease;
}

.store-card:hover {
  transform: translateY(-6px);
  border-color: var(--accent);
  box-shadow: 0 20px 40px var(--shadow-soft);
}

.store-card:active { transform: translateY(-6px) scale(0.98); }

.store-card-cta {
  display: block;
  margin-top: 14px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-hover);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.store-card:hover .store-card-cta,
.store-card:focus-visible .store-card-cta {
  opacity: 1;
  transform: translateY(0);
}

.store-visual {
  aspect-ratio: 1 / 1;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: calc(var(--radius) - 8px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  margin-bottom: 18px;
  overflow: hidden;
  transition: background-color 0.3s ease;
}

.store-visual svg { width: 40%; height: 40%; }

.store-card h3 {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 8px;
}

.tag {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
}

/* Store page */

.store-header {
  max-width: 1120px;
  margin: 0 auto;
  padding: 72px 24px 32px;
}

.store-banner {
  max-width: 1120px;
  margin: 0 auto 40px;
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 21 / 6;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  transition: background-color 0.3s ease;
}

.store-banner img { width: 100%; height: 100%; object-fit: cover; display: block; }

.store-header-inner {
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
}

.back-link {
  display: inline-block;
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
  margin-bottom: 32px;
}

.back-link:hover { color: var(--accent); }

.store-logo {
  width: 96px;
  height: 96px;
  margin: 0 auto 20px;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}

.store-logo svg { width: 42%; height: 42%; }

.store-name {
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 14px 0 8px;
}

.store-desc {
  color: var(--muted);
  margin: 16px 0 28px;
  line-height: 1.5;
}

.store-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

.secondary {
  display: inline-block;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 14px 28px;
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  color: var(--text);
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), transform 0.2s var(--ease);
}

.secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.secondary:active { transform: scale(0.97); }

/* Products */

.service-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 24px; }
.service-card { display: flex; flex-direction: column; gap: 16px; padding: 28px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); min-width: 0; overflow-wrap: anywhere; }
.service-card h3 { margin: 0; font-size: 22px; letter-spacing: -.025em; }
.service-card .tag { align-self: flex-start; }
.service-description { margin: 0; color: var(--muted); line-height: 1.6; white-space: pre-line; flex: 1; }
.service-details { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-variant-numeric: tabular-nums; }
.service-details span, .service-note { color: var(--muted); }
.service-card .secondary { min-height: 44px; text-align: center; }
.service-image { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: calc(var(--radius) - 8px); }
.service-note { margin-top: 24px; text-align: center; }

.products {
  max-width: 1120px;
  margin: 0 auto;
  padding: 64px 24px var(--space-section-y);
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 280px));
  justify-content: center;
  gap: 28px;
}

.product-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  text-decoration: none;
  color: var(--text);
  box-shadow: 0 1px 2px var(--shadow-soft);
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease), background-color 0.3s ease;
}

.product-card:hover {
  transform: translateY(-6px);
  border-color: var(--accent);
  box-shadow: 0 20px 40px var(--shadow-soft);
}

.product-card:active { transform: translateY(-6px) scale(0.98); }

/* Producto agotado: se sigue pudiendo abrir (puede tener variantes disponibles o
   volver a stock), pero se atenúa para que la falta de stock se note de un vistazo
   en la grilla, sin depender solo de leer el texto "Agotado" del tag. Selector con
   el tipo de elemento (a.product-card) a propósito: sube la especificidad por sobre
   .reveal.in-view (mismo número de clases), que si no le gana y deja el opacity en 1. */
a.product-card.agotado { opacity: 0.6; }
a.product-card.agotado:hover { opacity: 0.8; }

.product-visual {
  aspect-ratio: 1 / 1;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: calc(var(--radius) - 8px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  margin-bottom: 16px;
  overflow: hidden;
}

.product-visual svg { width: 36%; height: 36%; }

.product-name {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 4px;
}

.product-price {
  font-size: 15px;
  font-weight: 700;
  color: var(--accent-hover);
  margin: 0 0 10px;
  font-variant-numeric: tabular-nums;
}

.product-desc {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
  margin: 0 0 14px;
  flex-grow: 1;
}

.tag.avail { margin-bottom: 16px; align-self: flex-start; }

.buy-btn {
  width: 100%;
  text-align: center;
  padding: 12px 20px;
  font-size: 14px;
}

.store-meta {
  color: var(--muted);
  font-size: 14px;
  margin: 0 0 6px;
}

/* Product detail */

.product-detail {
  max-width: 1120px;
  margin: 0 auto;
  padding: 72px 24px var(--space-section-y);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: start;
}

.product-detail-visual {
  aspect-ratio: 1 / 1;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  transition: background-color 0.3s ease;
}

.product-detail-visual .placeholder-initial { font-size: 88px; }

.product-thumbs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-top: 12px;
}

.product-thumb {
  aspect-ratio: 1 / 1;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: calc(var(--radius) - 10px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}

.product-detail-info .tag { margin: 14px 0 0; }

.product-detail-info .store-name { margin: 12px 0 4px; }

.product-price-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 8px 0 4px;
}

.price-current {
  font-size: 22px;
  font-weight: 800;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.price-old {
  font-size: 15px;
  color: var(--muted);
  text-decoration: line-through;
  font-variant-numeric: tabular-nums;
}

.variant-group { margin: 20px 0; }

.variant-label {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 8px;
}

.variant-options {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.variant-chip {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 13px;
  min-height: 36px;
}

button.variant-chip {
  background: transparent;
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

button.variant-chip:hover {
  border-color: var(--accent);
}

button.variant-chip.active {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
}

.cart-row-variant,
.checkout-row-variant {
  font-size: 12px;
  color: var(--muted);
  margin: 2px 0 0;
}

.product-store-link {
  display: inline-block;
  margin: 20px 0 28px;
  font-size: 14px;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  padding-bottom: 2px;
}

.product-store-link:hover {
  color: var(--accent);
  border-color: var(--accent);
}

#add-to-cart {
  border: none;
  cursor: pointer;
  font-family: var(--font);
}

#add-to-cart[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

@media (max-width: 720px) {
  .product-detail { grid-template-columns: 1fr; padding: 56px 20px 72px; }
}

.not-found {
  max-width: 480px;
  margin: 0 auto;
  padding: 120px 24px;
  text-align: center;
}

.not-found h1 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
}

.not-found p {
  color: var(--muted);
  margin: 0 0 28px;
}

/* Cart */

.cart-page {
  max-width: 800px;
  margin: 0 auto;
  padding: 72px 24px var(--space-section-y);
}

.cart-empty-state {
  max-width: 480px;
  margin: 0 auto;
  padding: 120px 24px;
  text-align: center;
}

.cart-empty-state h1 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
}

.cart-empty-state p {
  color: var(--muted);
  margin: 0 0 28px;
}

.cart-store {
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  margin-bottom: 24px;
}

.cart-store-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.cart-store-head h2 {
  font-size: 18px;
  font-weight: 700;
  margin: 0;
}

.cart-clear {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 13px;
  cursor: pointer;
  text-decoration: underline;
}

.cart-clear:hover { color: var(--accent); }

.cart-rows {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.cart-row {
  display: grid;
  grid-template-columns: 56px 1fr auto auto auto;
  align-items: center;
  gap: 14px;
  /* Resalta la fila entera al pasar el mouse, para que se note cuál producto se
     está por tocar antes de usar +/-/eliminar (antes no había ningún feedback de
     hover a nivel de fila). Padding+margen negativo: el resaltado se ve, pero no
     mueve nada del layout ni la separación entre filas. */
  padding: 8px;
  margin: -8px;
  border-radius: 12px;
  transition: background-color 0.2s ease;
}

/* No usa --surface-2 lisa: es el mismo tono que el thumbnail (.cart-row-visual),
   así que la miniatura del producto "desaparecía" contra el fondo de la fila al
   pasar el mouse. Un tinte de acento muy leve se distingue de ambos sin gritar. */
.cart-row:hover { background: color-mix(in srgb, var(--surface) 90%, var(--accent) 10%); }

.cart-row-visual {
  width: 56px;
  height: 56px;
  border-radius: calc(var(--radius) - 10px);
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}

.cart-row-visual .placeholder-initial { font-size: 20px; }

.cart-row-name {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 2px;
}

.cart-row-price {
  font-size: 13px;
  color: var(--muted);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.cart-qty {
  display: flex;
  align-items: center;
  gap: 10px;
}

.qty-btn {
  position: relative;
  width: 26px;
  height: 26px;
  border: 1px solid var(--border);
  background: none;
  border-radius: 50%;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), transform 0.15s var(--ease);
}

/* El círculo visual queda en 26px; este pseudo-elemento invisible agranda el
   área táctil real a ~44px sin cambiar cómo se ve el botón. */
.qty-btn::before {
  content: "";
  position: absolute;
  inset: -9px;
}

.qty-btn:hover { border-color: var(--accent); color: var(--accent); }
.qty-btn:active { transform: scale(0.92); }

.qty-value {
  min-width: 16px;
  text-align: center;
  font-size: 14px;
}

.cart-row-subtotal {
  font-size: 14px;
  font-weight: 700;
  margin: 0;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.cart-remove {
  position: relative;
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  padding: 10px;
  margin: -10px;
  transition: color 0.2s var(--ease), transform 0.15s var(--ease);
}

.cart-remove:hover { color: var(--accent); }
.cart-remove:active { transform: scale(0.9); }

.cart-store-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.cart-total { margin: 0; font-size: 15px; font-variant-numeric: tabular-nums; }
.cart-total strong { color: var(--accent-hover); }

@media (max-width: 640px) {
  .cart-row {
    grid-template-columns: 44px 1fr auto;
    grid-template-areas:
      "visual info remove"
      "visual qty subtotal";
    row-gap: 8px;
  }
  .cart-row-visual { grid-area: visual; width: 44px; height: 44px; }
  .cart-row-info { grid-area: info; }
  .cart-remove { grid-area: remove; justify-self: end; }
  .cart-qty { grid-area: qty; }
  .cart-row-subtotal { grid-area: subtotal; justify-self: end; }

  .cart-store-footer { flex-direction: column; align-items: stretch; gap: 14px; }
  .cart-store-footer .cta { text-align: center; }
}

/* Checkout */

.checkout-page {
  max-width: 640px;
  margin: 0 auto;
  padding: 72px 24px var(--space-section-y);
}

.checkout-head {
  margin: 32px 0 28px;
}

.checkout-head h1 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 10px;
}

.checkout-head p {
  color: var(--muted);
  margin: 0;
}

.checkout-summary {
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  margin-bottom: 32px;
}

.checkout-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}

.checkout-row:last-of-type { border-bottom: none; }

.checkout-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 16px;
  margin-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}

.checkout-total strong { color: var(--accent-hover); }

.checkout-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.checkout-form label {
  font-size: 13px;
  font-weight: 600;
  margin-top: 14px;
}

.checkout-form label:first-child { margin-top: 0; }

.checkout-form input,
.checkout-form textarea {
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  font-family: var(--font);
  /* 16px, no 14px: por debajo de eso Safari en iOS hace zoom automático al enfocar
     el campo, lo cual se siente roto en un formulario de pago. */
  font-size: 16px;
  background: var(--bg);
  color: var(--text);
  resize: vertical;
  transition: border-color 0.2s var(--ease);
}

.checkout-form input:focus,
.checkout-form textarea:focus {
  outline: none;
  border-color: var(--accent);
}

.checkout-form button {
  margin-top: 20px;
  border: none;
  cursor: pointer;
  font-family: var(--font);
  font-size: 15px;
}

/* Auth (login, registro, recuperar/actualizar contraseña, perfil) — mismos
   tokens y el mismo patrón de tarjeta+formulario que .checkout-form, solo que
   centrado en una tarjeta angosta en vez de ocupar todo el ancho de la página. */

.auth-page {
  max-width: 440px;
  margin: 0 auto;
  /* Contiene el glow de .auth-card::before (inset negativo + blur) dentro
     del ancho de la página -- sin esto, en viewports angostos el glow se
     escapa más allá del borde de la pantalla y genera scroll horizontal. */
  overflow: hidden;
  padding: 72px 24px var(--space-section-y);
}

.auth-card {
  position: relative;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

/* Resplandor ambiental detrás de la tarjeta de login/registro -- mismo
   token y técnica que .hero-capsule::before (radial-gradient + blur con
   --hero-glow), solo que acá el resplandor es más grande y sutil porque
   la tarjeta es rectangular, no una cápsula pequeña. Le da profundidad al
   fondo negro plano sin agregar ninguna dependencia nueva. */
.auth-card::before {
  content: '';
  position: absolute;
  inset: -12%;
  z-index: -1;
  background: radial-gradient(circle, var(--hero-glow) 0%, transparent 70%);
  filter: blur(32px);
  pointer-events: none;
}

.auth-head {
  text-align: center;
  margin-bottom: 24px;
}

.auth-head h1 {
  font-size: clamp(1.4rem, 3vw, 1.7rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 8px;
}

.auth-head p {
  color: var(--muted);
  margin: 0;
  font-size: 14px;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Sin esto, [hidden] pierde contra ".auth-form { display: flex }" (misma
   especificidad, gana la última declarada) y el formulario de
   actualizar-password.html quedaría visible antes de validar el enlace de
   recuperación. */
.auth-form[hidden] {
  display: none;
}

.auth-form label {
  font-size: 13px;
  font-weight: 600;
  margin-top: 14px;
}

.auth-form label:first-child { margin-top: 0; }

.auth-form input,
.auth-form select,
.auth-form textarea {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  font-family: var(--font);
  /* 16px, no 14px: evita el zoom automático de Safari en iOS al enfocar el campo. */
  font-size: 16px;
  background: var(--bg);
  color: var(--text);
  transition: border-color 0.2s var(--ease), background-color 0.3s ease, color 0.3s ease;
}

.auth-form textarea { resize: vertical; font-family: var(--font); }

.auth-form input:focus,
.auth-form select:focus,
.auth-form textarea:focus {
  outline: none;
  border-color: var(--accent);
}

.auth-form input[aria-invalid="true"],
.auth-form select[aria-invalid="true"],
.auth-form textarea[aria-invalid="true"] {
  border-color: color-mix(in srgb, #d0453c 65%, var(--border));
}

/* Ayuda y error a nivel de UN campo (Fase 2, Sistema Visual ASTRC). No
   reemplaza .auth-message (error de TODO el formulario, ej. "no se pudo
   crear la cuenta") — esto es el mensaje puntual bajo un input/select
   puntual. Fuera de .auth-form a propósito: formularios del dashboard que
   arman su propio markup (no todos usan esa clase) también lo necesitan. */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: color-mix(in srgb, #d0453c 65%, var(--border));
}

.field-hint {
  margin-top: 4px;
  font-size: var(--fs-caption, 12px);
  line-height: 1.4;
  color: var(--muted);
}

.field-error {
  display: none;
  margin-top: 4px;
  font-size: var(--fs-caption, 12px);
  font-weight: 600;
  line-height: 1.4;
  color: var(--rose, #d0453c);
}

.field-error.visible { display: block; }

/* Selector de país + número local (Fase 5O). Apilados en columna por
   defecto para garantizar cero overflow en mobile (los nombres de país son
   largos); lado a lado recién a partir de un ancho cómodo. */
.auth-phone-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.auth-phone-field select {
  min-width: 0;
}

@media (min-width: 480px) {
  .auth-phone-field {
    flex-direction: row;
  }
  .auth-phone-field select {
    flex: 1 1 58%;
  }
  .auth-phone-field input {
    flex: 1 1 42%;
  }
}

/* Aviso de "correo ya registrado" (Fase 5O) — mismo tono neutro que
   .auth-message.info, pero con sus propios botones de acción en vez de solo
   texto (mostrarMensaje() no soporta HTML dentro del mensaje a propósito,
   para no tener que sanitizar texto dinámico en ningún otro lugar). */
.auth-existing-account {
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 18px;
}

.auth-existing-account p {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
}

.auth-existing-account p:last-of-type { margin-bottom: 0; }

.auth-existing-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
}

.auth-existing-actions a {
  flex: 1 1 auto;
  text-align: center;
  padding: 12px 20px;
  font-size: 14px;
}

.auth-password-field { position: relative; }
.auth-password-field input { padding-right: 44px; }

.auth-password-toggle {
  position: absolute;
  /* 36x36 medía antes (bajo el mínimo táctil de 44px). Al agrandar el botón
     8px se compensa el offset con la mitad (4px) para que el ícono quede en
     el mismo píxel exacto: cero impacto visual. */
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s var(--ease), background-color 0.2s ease, transform 0.15s var(--ease);
}

.auth-password-toggle:hover { color: var(--text); background: var(--surface-2); }
.auth-password-toggle:active { transform: translateY(-50%) scale(0.9); }

.auth-inline-link {
  align-self: flex-end;
  margin-top: 10px;
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
}

.auth-inline-link:hover { color: var(--accent); }

.auth-submit {
  margin-top: 22px;
  width: 100%;
  text-align: center;
  border: none;
  cursor: pointer;
  font-family: var(--font);
}

.auth-submit[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}

.auth-footer-text {
  margin: 20px 0 0;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
}

.auth-footer-text a { color: var(--accent); text-decoration: none; }
.auth-footer-text a:hover { text-decoration: underline; }

/* Mensaje de error/estado — una sola variante de color nueva (rojo) porque
   "errores claros" lo pide explícitamente; todo lo demás reusa --muted/--surface-2
   ya existentes en vez de inventar más colores semánticos (eso queda para
   cuando se diseñe el dashboard, ver docs/DASHBOARD-ARCHITECTURE.md). */
.auth-message {
  display: none;
  font-size: 13px;
  line-height: 1.5;
  padding: 11px 14px;
  border-radius: 10px;
  margin-bottom: 18px;
}

.auth-message.visible { display: block; }

.auth-message.error {
  background: color-mix(in srgb, #d0453c 12%, var(--surface));
  border: 1px solid color-mix(in srgb, #d0453c 35%, transparent);
  color: color-mix(in srgb, #d0453c 75%, var(--text));
}

.auth-message.info {
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  color: var(--text);
}

/* Selector Cliente/Tienda — solo UX (decide a qué formulario/mensaje se
   llega), nunca otorga acceso por sí solo: la autorización real sigue
   siendo Supabase Auth + RLS (ver js/login.js). */
.auth-mode-select {
  display: flex;
  gap: 12px;
  margin-bottom: 4px;
}

/* Mismo problema de especificidad que .auth-form[hidden] más arriba:
   [hidden] del navegador pierde contra ".auth-mode-select { display: flex }"
   (misma especificidad, gana el último declarado) sin este selector más
   específico. */
.auth-mode-select[hidden] {
  display: none;
}

.auth-mode-option {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 22px 12px;
  min-height: 44px;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: 14px;
  color: var(--text);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease), transform 0.15s var(--ease);
}

.auth-mode-option svg { color: var(--muted); transition: color 0.2s var(--ease); }

.auth-mode-option:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.auth-mode-option:hover svg { color: var(--accent); }

.auth-mode-option:active { transform: translateY(0); }

.auth-mode-option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.auth-back-link {
  align-self: flex-start;
  margin-bottom: 4px;
  background: none;
  border: none;
  padding: 0;
  color: var(--muted);
  font-family: var(--font);
  font-size: 13px;
  cursor: pointer;
}

.auth-back-link:hover { color: var(--accent); }

/* Perfil */

.profile-section {
  margin-bottom: 28px;
}

.profile-section:last-child { margin-bottom: 0; }

.profile-section h2 {
  font-size: 15px;
  font-weight: 700;
  margin: 0 0 14px;
}

.profile-role-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--accent-soft, color-mix(in srgb, var(--accent) 12%, var(--surface)));
  color: var(--accent-hover);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}

.profile-order-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  text-decoration: none;
  transition: opacity 0.15s ease;
}

.profile-order-row:hover { opacity: 0.8; }

.profile-order-row:last-child { border-bottom: none; }

.profile-order-row .store-meta { margin: 2px 0 0; font-size: 12px; }

/* Comprobante de pedido (Fase 5Q) — factura minimalista, reutilizada por
   checkout.html (recién creado) y pedido.html (histórico). */
.comprobante {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  margin: 24px 0;
}

.comprobante-head {
  text-align: center;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px dashed var(--border);
}

.comprobante-marca { font-weight: 800; letter-spacing: 0.04em; margin: 0; }
.comprobante-tipo { margin: 4px 0 0; font-size: 13px; color: var(--text-muted, inherit); opacity: 0.75; }

.comprobante-meta { margin-bottom: 20px; }
.comprobante-numero { font-weight: 700; margin: 0 0 4px; }
.comprobante-meta .store-meta { margin: 2px 0; }

.comprobante-bloque { margin-bottom: 20px; }
.comprobante-bloque h3,
.comprobante-detalle h3,
.comprobante-pago h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.65;
  margin: 0 0 8px;
}
.comprobante-bloque p { margin: 2px 0; }

.comprobante-detalle { margin-bottom: 20px; }

.comprobante-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.comprobante-item:last-child { border-bottom: none; }

.comprobante-item-visual {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-2, var(--surface));
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
}
.comprobante-item-visual img { width: 100%; height: 100%; object-fit: cover; display: block; }

.comprobante-item-info { flex: 1; min-width: 0; }
.comprobante-item-nombre { margin: 0; font-weight: 600; }
.comprobante-item-meta { margin: 2px 0 0; font-size: 12px; opacity: 0.75; }
.comprobante-item-subtotal { margin: 0; font-weight: 700; white-space: nowrap; }

.comprobante-totales {
  border-top: 1px dashed var(--border);
  padding-top: 12px;
  margin-bottom: 20px;
}
.comprobante-total-fila { display: flex; justify-content: space-between; padding: 4px 0; }
.comprobante-total-final { font-size: 17px; font-weight: 800; }

.comprobante-pago p { margin: 4px 0 0; font-size: 13px; opacity: 0.8; }

.checkout-comprobante-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

/* CTA band */

.cta-band {
  background: var(--bg-dark);
  color: var(--text-dark);
  text-align: center;
  padding: var(--space-section-y) 24px;
}

.cta-band h2 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 12px;
}

.cta-band p {
  color: var(--muted-dark);
  margin: 0 0 32px;
}

/* Footer */

.footer {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 24px;
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--muted);
}

/* Mención discreta de ASTRC dentro de una tienda */

.astrc-mini-mention {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px 56px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.astrc-mini-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  /* Presencia del personaje MUY sutil: solo esto se mueve, nunca cerca de productos/botones */
  animation: flotar-companero 6s ease-in-out infinite;
}

@keyframes flotar-companero {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-4px) rotate(-3deg); }
}

.astrc-mini-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

.astrc-mini-mention a {
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
}

.astrc-mini-mention a:hover { color: var(--text); }

.tienda-footer {
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

.tienda-footer-astrc {
  display: flex;
  align-items: center;
  gap: 10px;
  opacity: 0.55;
}

.astrc-mini-brand {
  display: inline-flex;
  align-items: center;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: -0.01em;
}

.astrc-mini-brand svg {
  width: 0.75em;
  height: 0.75em;
  margin-left: 1px;
}

.tienda-footer-astrc p { margin: 0; font-size: 12px; }

.footer-links { display: flex; gap: 20px; }
.footer-links a { text-decoration: none; }
.footer-links a:hover { color: var(--accent); }

/* Scroll reveal */

.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.in-view {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* El selector universal * NO alcanza a ::before/::after (son pseudo-elementos
     generados, no nodos reales del árbol) — sin esto, transiciones que viven en un
     ::after (como el subrayado animado del nav) seguían corriendo con reduced motion
     activado. Encontrado probando de verdad, no solo leyendo el código. */
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* Mobile */

@media (max-width: 720px) {
  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--bg-dark);
    border-bottom: 1px solid var(--border);
    flex-direction: column;
    gap: 0;
    padding: 8px 24px;
    display: none;
  }

  .nav-links.open { display: flex; }

  .nav-links a {
    padding: 14px 0;
    border-bottom: 1px solid var(--border);
  }

  .nav-links > a::after,
  .nav-links > .nav-dropdown > .nav-dropdown-link::after {
    display: none;
  }

  .nav-links .nav-dropdown {
    width: 100%;
    flex-wrap: wrap;
    justify-content: space-between;
    padding: 0;
    border-bottom: 1px solid var(--border);
  }

  .nav-links .nav-dropdown-link {
    flex: 1;
    padding: 14px 0;
    border-bottom: none;
  }

  .nav-links .nav-dropdown-menu {
    position: static;
    width: 100%;
    transform: none;
    opacity: 1;
    pointer-events: auto;
    box-shadow: none;
    border: none;
    padding: 0 0 0 4px;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
  }

  .nav-links .nav-dropdown-menu.open { max-height: 320px; }

  .nav-links .nav-dropdown-menu a { padding: 10px 0; }

  .nav-toggle { display: flex; }

  .hero { padding: 96px 24px; }
  .how-it-works { padding: var(--space-section-y-mobile) 20px; }
  .stores { padding: var(--space-section-y-mobile) 20px; }
  .cta-band { padding: var(--space-section-y-mobile) 20px; }
  .footer { flex-direction: column; gap: 12px; text-align: center; }
}

/* =========================================================
   Dashboard (Fase 3). Reutiliza tokens y componentes existentes
   (--surface/--border/--radius/--ease, .store-search/.store-filters/
   .filter-btn/.store-empty, .auth-form input/label) — nada nuevo salvo
   lo que el panel administrativo necesita y no existía todavía.
   ========================================================= */

.dash-shell {
  display: flex;
  min-height: 100vh;
  background: var(--bg);
}

/* Mismo problema de especificidad ya encontrado en .auth-form/.auth-mode-select:
   [hidden] del navegador pierde contra ".dash-shell { display: flex }" (misma
   especificidad, gana el último declarado), así que dashboard.js dejaba
   hidden=true sin ningún efecto visual real — el shell se veía a medio
   pintar aunque el propio código explícitamente esperaba a que todo
   terminara de resolverse antes de "revelarlo" (ver comentario en
   AstrcDashboard.init()). Este selector más específico hace que ese hidden
   sí oculte de verdad. */
.dash-shell[hidden] {
  display: none;
}

/* =========================================================
   Tokens del panel — superficies "Obsidiana" oscuras + acento AZUL de
   marca (docs/DASHBOARD-DESIGN-REFERENCE.md original proponía un acento
   verde jade; Gabriel pidió volver al azul #4865ff "que da confianza",
   el mismo de todo el sitio -- se mantienen los nombres de variable
   --jade/-l/-d/-dim/-glow por no reescribir cada regla que ya los usa,
   pero sus VALORES ahora son azules). Redefinidos SOLO dentro de
   #dash-shell (no en :root): el marketplace/checkout/tienda públicos ya
   usan ese mismo azul en :root y no cambian. Se alias-ean los tokens
   compartidos (--accent/--bg/--surface/--text/--muted/--border) para que
   TODO el CSS del dashboard que ya existía (tablas, pills, cards, modales)
   adopte la paleta sin tocar cada regla una por una. --status-good/warning/
   critical NO se alias-ean acá a propósito -- son un significado semántico
   (éxito/alerta/peligro) independiente del acento de marca, así que quedan
   heredando el verde/ámbar/rojo de :root sin importar qué color sea el
   acento del panel.

   FIX (docs/ASTRC-BRAND-SYSTEM.md): --jade decía ser "el mismo azul de
   marca" pero tenía su propio hex (#6D70F5), distinto del --accent real
   del resto del sitio (#4865ff) -- dos azules que se suponía eran uno
   solo. Ahora --jade es un alias literal de --brand-primary, así que es
   imposible que vuelvan a divergir. --jade-l/--jade-d quedan igual por
   ahora (estados de hover propios del panel, fuera de alcance de esta fase).
   ========================================================= */
#dash-shell {
  --jade: var(--brand-primary);
  --jade-l: #8B8DFF;
  --jade-d: #4A4DD4;
  --jade-dim: rgba(109, 112, 245, 0.14);
  --jade-glow: rgba(109, 112, 245, 0.26);
  --gold: #F0A030;
  --gold-dim: rgba(240, 160, 48, 0.11);
  --rose: #F26B5B;
  --rose-dim: rgba(242, 107, 91, 0.11);
  --sky: #5BA4F5;
  --sky-dim: rgba(91, 164, 245, 0.11);

  /* --bg-2/--bg-3 (superficies de cards/tablas/KPIs) son SÓLIDAS a
     propósito, no rgba -- el sistema visual ASTRC (astrc-sistema-visual.html,
     Ejecución B) reserva el glass exclusivamente para el chrome (--chrome)
     y los overlays de modal; las superficies de datos deben ser sólidas.
     Antes usaban rgba(...,.72) + backdrop-filter, heredado del jade verde
     original -- quedaba blur "de adorno" sin ninguna transparencia real que
     desenfocar. El backdrop-filter que sigue declarado en esas reglas ahora
     no tiene efecto visible sobre un fondo opaco (no rompe nada, pero ya no
     hace falta perseguir cada declaración para quitarlo). Los tonos también
     dejan el tinte verdoso heredado de jade por un neutro azulado, igual al
     resto del sistema. */
  --bg-0: #0C0E16;
  --bg-1: #0C0E16;
  --bg-2: #141726;
  --bg-3: #1B1F31;
  --bg-sidebar: #0A0D1C;
  --t1: #EDEEF6;
  --t2: #868BA1;
  --t3: #4A5068;
  --b0: #252A3D;
  --b1: rgba(109, 112, 245, 0.35);

  /* Alias: el resto del CSS del dashboard sigue usando estos nombres. */
  --bg: var(--bg-0);
  --bg-dark: var(--bg-0);
  --surface: var(--bg-2);
  --surface-2: var(--bg-3);
  --text: var(--t1);
  --text-dark: var(--t1);
  --muted: var(--t2);
  --muted-dark: var(--t2);
  --accent: var(--jade);
  --accent-hover: var(--jade-l);
  --border: var(--b0);
  --border-dark: var(--b0);
  --header-bg: rgba(9, 14, 12, 0.72);
  --shadow: rgba(0, 0, 0, 0.45);
  --shadow-soft: rgba(0, 0, 0, 0.3);

  /* Dirección de arte "Precisión que se siente cercana" (Ejecución B ·
     Contraste, elegida 2026-09-10). El chrome (sidebar + topbar) es un
     navy sólido propio -- NO sigue el tema claro/oscuro/gris como el resto
     del panel -- para que el panel se reconozca de un vistazo (marca) y
     aguante turnos largos de POS/restaurante sin el brillo de un fondo
     claro completo. El contenido (tablas, cards, POS, formularios) sigue
     usando --bg/--surface del tema normal; el glass (--glass-blur) queda
     reservado solo para el chrome, nunca para superficies de datos. */
  --chrome: #0A0D1C;
  --chrome-text: #E4E7F5;
  --chrome-muted: #8B90AE;
  --chrome-border: #1B2036;
  --chrome-active-bg: rgba(139, 141, 255, 0.2);
  --chrome-active-text: #ffffff;
  /* Acento de celebración: SOLO para logros puntuales (venta cerrada, caja
     cuadrada, meta alcanzada) -- nunca decorativo ni de navegación. */
  --celebrate: #F5C46A;
}

[data-theme="light"] #dash-shell,
[data-theme="grey"] #dash-shell {
  --jade: var(--brand-primary);
  --jade-l: #7A7DF7;
  --jade-d: #4A4DD4;
  --jade-dim: rgba(91, 95, 239, 0.11);
  --jade-glow: rgba(91, 95, 239, 0.22);

  /* Superficies sólidas -- ver comentario en el bloque oscuro de #dash-shell. */
  --bg-0: #F7F8FC;
  --bg-1: #F7F8FC;
  --bg-2: #FFFFFF;
  --bg-3: #EEF0F6;
  --bg-sidebar: #FFFFFF;
  --t1: #161822;
  --t2: #6E7387;
  --t3: #9AA0B8;
  --b0: #DDE0E9;
  --b1: rgba(91, 95, 239, 0.28);
  --header-bg: rgba(255, 255, 255, 0.72);
  --shadow: rgba(17, 17, 20, 0.1);
  --shadow-soft: rgba(17, 17, 20, 0.06);

  /* El chrome se mantiene navy sólido incluso en tema claro/gris -- es la
     esencia de la Ejecución B: consistencia de marca por encima del tema. */
  --chrome: #171F3D;
  --chrome-text: #E4E7F5;
  --chrome-muted: #97A0C7;
  --chrome-border: #232B52;
  --chrome-active-bg: rgba(139, 141, 255, 0.22);
  --chrome-active-text: #ffffff;
  --celebrate: #F0B23F;
}

/* ============================================================
   JERARQUÍA TIPOGRÁFICA ASTRC -- Ejecución B, Fase 1 (Fundamentos)
   13 niveles semánticos reutilizables por cualquier módulo nuevo del panel.
   Un módulo nuevo aplica el nivel que corresponda por SIGNIFICADO (¿es un
   título de página? ¿un dato mono-espaciado?), nunca inventa un tamaño o
   peso suelto. Todos reusan los tokens --fs-*/--sp-* ya definidos arriba
   (ninguno crea un valor arbitrario nuevo). Disponibles como clases
   (.text-*) para markup nuevo, y ya aplicados a los selectores
   estructurales que todas las vistas del panel comparten (ver más abajo:
   .dash-view-head, .dash-panel h2, .dash-table th, .dash-kpi, etc.) --
   así las 9 pantallas de esta fase heredan la jerarquía sin tocar su JS. */
#dash-shell .text-display { font: 800 var(--fs-display, 40px)/1.1 var(--font); letter-spacing: -0.02em; color: var(--text); margin: 0; }
#dash-shell .text-page-title { font: 700 var(--fs-title, 28px)/1.2 var(--font); letter-spacing: -0.01em; color: var(--text); margin: 0; }
#dash-shell .text-section-title { font: 700 var(--fs-section, 20px)/1.3 var(--font); color: var(--text); margin: 0; }
#dash-shell .text-subsection-title { font: 600 var(--fs-subsection, 18px)/1.3 var(--font); color: var(--text); margin: 0; }
#dash-shell .text-card-title { font: 700 var(--fs-card, 16px)/1.35 var(--font); color: var(--text); margin: 0; }
#dash-shell .text-body { font: 400 var(--fs-body, 15px)/1.5 var(--font); color: var(--text); margin: 0; }
#dash-shell .text-body-small { font: 400 var(--fs-body-small, 13px)/1.45 var(--font); color: var(--muted); margin: 0; }
#dash-shell .text-label { font: 600 var(--fs-label, 11px)/1.3 var(--font); letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin: 0; }
#dash-shell .text-helper { font: 400 var(--fs-body-small, 13px)/1.5 var(--font); color: var(--muted); margin: var(--sp-1, 4px) 0 0; }
#dash-shell .text-caption { font: 500 var(--fs-caption, 12px)/1.3 var(--font); color: var(--muted); margin: 0; }
#dash-shell .text-table-header { font: 700 var(--fs-caption, 12px)/1.3 var(--font); letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin: 0; }
#dash-shell .text-metric-value { font: 800 var(--fs-title, 28px)/1.1 var(--font); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; color: var(--text); margin: 0; }
#dash-shell .text-mono-data { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
/* Reutilizable sin tocar JS: cualquier <code> nuevo dentro del panel hereda
   mono-data automáticamente (identificadores, SKU, códigos de terminal). */
#dash-shell code { font-family: var(--font-mono); white-space: nowrap; }

/* Botones de acción del panel -- para casos nuevos o donde .cta/.secondary
   (compartidos con el sitio público) no encajan bien. Texto blanco: el
   acento del panel es el mismo azul saturado que .cta usa en todo el
   sitio, donde también lleva texto blanco. */
.btn-jade {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--jade);
  color: #ffffff;
  font-weight: 700;
  font-family: var(--font);
  font-size: 14px;
  border: none;
  border-radius: var(--r-input, 10px);
  padding: 10px 20px;
  cursor: pointer;
  box-shadow: var(--sh-sm);
  transition: background-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.btn-jade:hover { background: var(--jade-l); box-shadow: var(--sh-md); }
.btn-jade:active { transform: scale(0.97); }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--surface-2);
  border: 1px solid var(--b0);
  color: var(--t2);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  /* Un <button> trae line-height:normal del user-agent, distinto del que
     hereda un <label> (ej. "Elegir imagen" vs "Quitar" en el uploader de
     imagen) -- con la misma fuente y el mismo padding terminaban de alto
     distinto. Fijarlo acá los iguala sin importar la etiqueta. */
  line-height: 1.4;
  border-radius: var(--r-input, 10px);
  padding: 10px 20px;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.btn-ghost:hover { border-color: var(--b1); color: var(--jade-l); background: var(--bg-3); }

/* Compacto (Fase 4): mismo .btn-ghost pero para acciones inline dentro de
   una celda de tabla (ej. Marcar pagado/Corregir/Devolver en Pedidos) --
   antes cada botón repetía padding/margin por style="" inline en el JS. */
#dash-shell .btn-ghost.is-compact { padding: 6px 12px; font-size: 12px; }

/* Destructivo (Fase 2: componentes globales) -- modificador sobre .btn-ghost
   o .secondary, nunca un botón nuevo. Nunca es la acción primaria de una
   pantalla: siempre acompaña "Eliminar"/"Borrar" con confirmación aparte. */
#dash-shell .btn-ghost.is-danger,
#dash-shell .secondary.is-danger {
  color: var(--status-critical);
  border-color: color-mix(in srgb, var(--status-critical) 35%, var(--b0));
}
#dash-shell .btn-ghost.is-danger:hover,
#dash-shell .secondary.is-danger:hover {
  color: #fff;
  background: var(--status-critical);
  border-color: var(--status-critical);
}

/* Estado disabled (Fase 5): ninguno de los 4 botones del panel tenía
   retroalimentación visual propia al deshabilitarse -- un disabled=true
   por código (ej. "Guardar nota" sin contenido) se veía igual que
   habilitado salvo por el cursor por defecto del navegador. */
#dash-shell .btn-jade:disabled,
#dash-shell .btn-ghost:disabled,
#dash-shell .cta:disabled,
#dash-shell .secondary:disabled {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* Botones/selectores del panel (Precisión que se siente cercana): rectángulo
   redondeado ~10px, NUNCA píldora -- .cta/.secondary son píldora a propósito
   en el sitio público, pero dentro del panel leen como más "template"/menos
   preciso mezclados con inputs de 12px. Se sombrean levemente (--sh-sm) para
   que se sientan objetos con peso, no líneas planas -- la queja de "se ven
   simples" viene de ahí: cero elevación, radios sin relación entre sí. */
#dash-shell .cta,
#dash-shell .secondary {
  border-radius: var(--r-input, 10px);
  box-shadow: var(--sh-sm);
}
#dash-shell .cta:hover { box-shadow: var(--sh-md); }
#dash-shell .glass-select-trigger,
#dash-shell .dash-store-select,
#dash-shell .auth-form input,
#dash-shell .auth-form select,
#dash-shell .auth-form textarea,
#dash-shell .auth-form .dash-daterange-trigger.is-field {
  box-shadow: var(--sh-sm);
}
#dash-shell .glass-select-trigger:focus-visible,
#dash-shell .auth-form input:focus,
#dash-shell .auth-form select:focus,
#dash-shell .auth-form textarea:focus,
#dash-shell .auth-form .dash-daterange-trigger.is-field:focus-visible {
  box-shadow: var(--sh-sm), 0 0 0 3px var(--jade-dim);
}

.dash-topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 64px;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 20px;
  background: var(--chrome, var(--header-bg));
  border-bottom: 1px solid var(--chrome-border, var(--border));
  color: var(--chrome-text, var(--text));
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

/* El chrome fija su propio texto/muted -- los hijos del topbar traían
   var(--text)/var(--muted) del tema de contenido, que sobre navy sólido
   podía quedar sin contraste (p.ej. tema claro). Una sola fuente de verdad
   acá en vez de tocar cada regla de texto del topbar por separado. */
.dash-topbar-left,
.dash-topbar-right { color: inherit; }
.dash-sidebar-toggle,
.dash-breadcrumb-vista,
.dash-user-email { color: var(--chrome-text, var(--text)); }
.dash-sidebar-toggle span { background: var(--chrome-text, var(--text)); }
.dash-store-name,
.dash-breadcrumb-sep,
.dash-topbar-date,
.dash-user-role { color: var(--chrome-muted, var(--muted)); }
.dash-logout-btn { color: var(--chrome-muted, var(--muted)); }
.dash-logout-btn:hover { color: var(--chrome-text, var(--text)); background: var(--chrome-active-bg, var(--surface-2)); }

.dash-topbar-left {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.dash-sidebar-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  flex-direction: column;
  gap: 5px;
}

/* color de .dash-sidebar-toggle / span, .dash-store-name, .dash-breadcrumb-*,
   .dash-user-*, .dash-logout-btn -- fijado arriba (bloque "el chrome fija su
   propio texto/muted") en vez de acá: repetirlo con var(--text)/var(--muted)
   en estas reglas más específicas los pisaba en White/Grey (--text ahí es
   #111 -- casi negro -- sobre el navy fijo del chrome, contraste roto). */
.dash-sidebar-toggle span { width: 20px; height: 2px; display: block; }

.dash-topbar .brand-logo-img { height: 22px; width: auto; }

.dash-store-name {
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dash-breadcrumb-sep {
  display: none;
  font-size: 13px;
  opacity: 0.6;
}

.dash-store-name:not([hidden]) + .dash-breadcrumb-sep { display: inline; }

.dash-breadcrumb-vista {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.dash-topbar-date {
  font-size: 13px;
  white-space: nowrap;
}

.dash-topbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.dash-user-pill {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.3;
  margin-right: 4px;
}

.dash-user-email {
  font-size: 13px;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash-user-role {
  font-size: 11px;
}

.dash-logout-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s var(--ease), background-color 0.2s ease;
}

.dash-logout-btn:hover { background: var(--chrome-active-bg, var(--surface-2)); }

/* Ícono del selector de tema: es .nav-dropdown-trigger, componente compartido
   con el sitio público (donde --muted/--text sí son correctos). Dentro del
   topbar del panel necesita los tokens de chrome, igual que sus hermanos. */
.dash-topbar .nav-dropdown-trigger { color: var(--chrome-muted, var(--muted)); }
.dash-topbar .nav-dropdown-trigger:hover,
.dash-topbar .nav-dropdown-trigger[aria-expanded="true"] { color: var(--chrome-text, var(--text)); }

.dash-sidebar {
  position: fixed;
  top: 64px;
  left: 0;
  bottom: 0;
  width: 240px;
  background: var(--chrome, var(--surface));
  color: var(--chrome-text, var(--text));
  border-right: 1px solid var(--chrome-border, var(--border));
  padding: 20px 12px;
  overflow-y: auto;
  z-index: 30;
  transition: background-color 0.3s ease, border-color 0.3s ease, transform 0.3s var(--ease);
}

.dash-sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 64px 0 0 0;
  background: color-mix(in srgb, var(--shadow) 60%, transparent);
  z-index: 29;
}

.dash-sidebar-backdrop.open { display: block; }

.dash-nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.dash-nav-group-label {
  padding: 18px 14px 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--chrome-muted, var(--muted));
  opacity: 0.8;
}

.dash-nav-group-label:first-child { padding-top: 4px; }
.dash-nav-group-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 44px; padding: 10px 14px; margin-top: 8px; border: 1px solid transparent; border-radius: 12px; background: transparent; color: var(--muted); font: inherit; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; cursor: pointer; transition: background .2s ease, border-color .2s ease; }
.dash-nav-group-toggle:hover { background: var(--surface); border-color: var(--border); backdrop-filter: blur(var(--glass-blur)); }
.dash-nav-group-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dash-nav-group-toggle::after { content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform .24s ease; flex-shrink: 0; }
.dash-nav-group-region { display: grid; grid-template-rows: 1fr; opacity: 1; transition: grid-template-rows .24s ease, opacity .24s ease; }
.dash-nav-group-region > ul { min-height: 0; overflow: hidden; list-style: none; padding: 0; margin: 0; }
.dash-nav-group.is-collapsed .dash-nav-group-region { grid-template-rows: 0fr; opacity: 0; }
.dash-nav-group.is-collapsed .dash-nav-group-toggle::after { transform: rotate(-45deg); }
@media (min-width: 768px) and (max-width: 1024px) {
  /* Sin texto no entra ni reduciendo la fuente (ej. "Restaurante",
     "Administración") -- se oculta y queda solo el chevron ::after
     (mide en px fijos, no em, así que no se achica con font-size:0). El
     nombre accesible se conserva vía texto + title, solo cambia lo visual. */
  .dash-nav-group-toggle { font-size: 0; padding: 10px 0; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .dash-nav-group-region, .dash-nav-group-toggle, .dash-nav-group-toggle::after { transition: none; }
}

.dash-nav-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-radius: 10px;
  color: var(--chrome-muted, var(--muted));
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  transition: color 0.2s var(--ease), background-color 0.2s ease;
}

.dash-nav-link svg { flex-shrink: 0; width: 18px; height: 18px; }

.dash-nav-link:hover { color: var(--chrome-text, var(--text)); background: var(--chrome-active-bg, var(--surface-2)); }

.dash-nav-link {
  position: relative;
}

.dash-nav-link.active { color: var(--chrome-active-text, var(--accent-hover)); background: var(--chrome-active-bg, var(--jade-dim, var(--surface-2))); }

.dash-nav-link.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 22%;
  bottom: 22%;
  width: 2.5px;
  border-radius: 0 2px 2px 0;
  background: var(--accent);
}

/* Badge de pendientes en el sidebar (Fase 5S, ej. "Solicitudes de tiendas 3") */
.dash-nav-badge {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

.dash-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-left: 240px;
  margin-top: 64px;
  padding: 32px;
  min-width: 0;
}

.dash-main {
  /* Red de seguridad: ningún hijo del panel (tabla ancha, selector con
     nombre largo, popover) debe poder abrir scroll horizontal en el body
     entero -- cada uno que lo necesite ya maneja su propio overflow-x:auto
     (.dash-table-wrap, .dash-daterange-panel). */
  overflow-x: clip;
}

.dash-view-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  /* Los hijos de un flex container miden min-width:auto por defecto -- un
     <h1>/<p> largo (ej. nombre de tienda largo en el saludo) empujaba el
     ancho del header más allá de .dash-main y forzaba scroll horizontal,
     aun con flex-wrap:wrap (que solo ayuda entre hijos, no adentro de uno). */
  min-width: 0;
  margin-bottom: var(--sp-6, 24px);
}

.dash-view-head h1 { font: 700 var(--fs-title, 28px)/1.2 var(--font); letter-spacing: -0.01em; margin: 0; }
.dash-view-head h2 { font: 600 var(--fs-subsection, 18px)/1.3 var(--font); margin: 0; }
.dash-view-head p { margin: var(--sp-1, 4px) 0 0; color: var(--muted); font: 400 var(--fs-body-small, 13px)/1.5 var(--font); }

/* El propio texto (h1/p) es el hijo flex que necesita min-width:0 -- no
   .dash-view-head (el container) sino ESTE div, para que pueda truncar/
   wrappear en vez de forzar el ancho del header entero. */
.dash-view-head > div:first-child {
  min-width: 0;
}

.dash-view-head h1,
.dash-view-head p {
  overflow-wrap: break-word;
}

.dash-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--sp-4, 16px);
  margin-bottom: var(--sp-8, 32px);
}

.dash-kpi-card.is-wide { grid-column: span 2; }

.dash-kpi-card {
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  min-width: 0;
  container-type: inline-size;
  transition: background-color 0.3s ease, border-color 0.3s ease, transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

/* Cards con más detalle disponible al hacer click (js/dashboard-resumen.js,
   abrirDetalleKpi) -- mismo levantamiento sutil que el resto de elementos
   interactivos del sitio (.cta, .hero-capsule), nunca un cambio de color
   solo (el cursor + el levantamiento ya bastan como affordance). */
.dash-kpi-card.is-clickable {
  cursor: pointer;
}

.dash-kpi-card.is-clickable:hover,
.dash-kpi-card.is-clickable:focus-visible {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 8px 20px var(--shadow-soft);
}

.dash-kpi-card.is-clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.dash-kpi-value { font: 800 clamp(15px, 9cqi, var(--fs-title, 28px))/1.1 var(--font); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; white-space: nowrap; overflow-wrap: anywhere; }
.dash-kpi-label { font: 600 var(--fs-label, 11px)/1.3 var(--font); letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin-top: var(--sp-1, 4px); }

/* .dash-kpis/.dash-kpi -- versión simple de tarjeta KPI (span/strong/small
   directo, sin drag/resize) usada por vistas que no son Resumen (Delivery,
   Personal y jornadas). Nunca tuvo CSS propio -- por eso salía como texto
   plano corrido ("Activos0En preparación o entrega"), sin tarjeta ni
   separación. Mismo lenguaje visual que .dash-kpi-card/-value/-label. */
.dash-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.dash-kpi {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card, 16px);
  padding: 18px 20px;
  box-shadow: var(--sh-sm);
}
.dash-kpi span { display: block; font: 600 var(--fs-label, 11px)/1.3 var(--font); letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.dash-kpi strong { display: block; margin-top: var(--sp-2, 8px); font: 800 var(--fs-title, 28px)/1.1 var(--font); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.dash-kpi small { display: block; margin-top: var(--sp-1, 4px); font: 500 var(--fs-caption, 12px)/1.3 var(--font); color: var(--muted); }

/* Fila de acciones sueltas sobre una tabla (Personal, Restaurante, Cocina) --
   tampoco tenía CSS propio, los botones quedaban pegados sin separación. */
.dash-toolbar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }

.dash-kpi-delta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 10px;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.dash-kpi-delta.is-up { color: var(--status-good); }
.dash-kpi-delta.is-down { color: var(--status-critical); }

.dash-kpi-sparkline {
  position: absolute;
  right: 18px;
  bottom: 18px;
  opacity: 0.85;
}

.dash-kpi-card.has-sparkline { padding-right: 84px; }

.dash-skeleton {
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 37%, var(--surface) 63%);
  background-size: 400% 100%;
  border-radius: 10px;
  animation: dash-shimmer 1.4s ease infinite;
}

@keyframes dash-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

.dash-table-wrap {
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

/* Título dentro de una tabla envuelta (ej. "Detalle de pedidos", "Platos
   más solicitados", "Delivery por canal", Comprobantes): .dash-table-wrap
   no tiene padding propio, así que un <h2>/<h3> puesto directo ahí queda
   pegado al borde con el margen por defecto del navegador -- 16px más a la
   izquierda que las celdas de la tabla que tiene debajo (que sí usan
   padding:14px 16px). */
.dash-table-wrap > h2,
.dash-table-wrap > h3 {
  margin: 0;
  padding: 16px 16px 12px;
  font: 700 var(--fs-card, 16px)/1.35 var(--font);
  border-bottom: 1px solid var(--border);
}

/* Las tablas de widgets nunca fuerzan el ancho de su tarjeta. En pantallas
   estrechas se desplazan dentro de la superficie Glass, manteniendo visibles
   las columnas y el resto del dashboard estable. */
.dash-chart-card .dash-table-wrap,
.dash-chart-card .dash-table-compacta {
  max-width: 100%;
}
.dash-chart-card .dash-table-wrap { overflow-x: auto; }
.dash-chart-card .dash-table { min-width: 0; table-layout: fixed; }
.dash-chart-card .dash-table th,
.dash-chart-card .dash-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dash-table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 560px; }

.dash-table th {
  text-align: left;
  font: 700 var(--fs-caption, 12px)/1.3 var(--font);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.dash-table td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}

.dash-table tr:last-child td { border-bottom: none; }

.dash-table tbody tr { transition: background-color 0.15s ease; }
.dash-table tbody tr:hover { background: var(--surface-2); }

.dash-row-actions { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
/* Variante en línea (Fase 4) -- cuando las acciones comparten celda con
   otro contenido (ej. un badge de pago) en vez de ocupar la celda entera. */
.dash-row-actions.is-inline { display: inline-flex; margin-left: 6px; vertical-align: middle; }

.dash-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 4px;
  margin: -4px;
  border-radius: 8px;
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s var(--ease), background-color 0.2s ease;
}

.dash-icon-btn:hover { color: var(--text); background: var(--surface-2); backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); }
.dash-icon-btn.is-danger:hover { color: #d0453c; }

/* Variante con texto corto junto al ícono (ej. flechas ↑/↓ de reordenar) --
   mismo lenguaje que .dash-icon-btn (Fase 2: componentes globales), ancho
   automático en vez de cuadrado fijo de 36px. */
.dash-icon-btn.has-label {
  width: auto;
  min-width: 36px;
  padding: 6px 10px;
  gap: 6px;
  border-radius: var(--r-input, 10px);
  font: 600 var(--fs-caption, 12px)/1 var(--font);
}

.dash-status-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--muted);
}

.dash-status-pill.is-confirmed,
.dash-status-pill.is-completed {
  background: color-mix(in srgb, var(--status-good) 16%, var(--surface));
  color: color-mix(in srgb, var(--status-good) 80%, var(--text));
}

.dash-status-pill.is-cancelled {
  background: color-mix(in srgb, var(--status-critical) 14%, var(--surface));
  color: color-mix(in srgb, var(--status-critical) 75%, var(--text));
}

/* Inventario (Fase 2) -- "stock bajo". Mismo patrón color-mix que
   is-confirmed/is-cancelled, ámbar en vez de verde/rojo -- nunca solo
   color: siempre va con ícono + texto ("Stock bajo"), nunca sola. */
.dash-status-pill.is-warning {
  background: color-mix(in srgb, var(--status-warning) 16%, var(--surface));
  color: color-mix(in srgb, var(--status-warning) 85%, var(--text));
}

/* Informativo (Fase 2: jerarquía semántica completa -- neutral/informativo/
   éxito/advertencia/crítico). Para un estado en curso que no es ni éxito
   ni alerta (ej. "Reservada" en Mesas). Reusa --accent, nunca un azul suelto. */
.dash-status-pill.is-info {
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  color: color-mix(in srgb, var(--accent) 82%, var(--text));
}

.dash-status-pill svg { width: 13px; height: 13px; margin-right: 4px; flex-shrink: 0; }

/* Dot de color semántico en las KPI cards de Inventario -- nunca es la
   única señal (siempre acompaña un label de texto). */
.dash-kpi-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  margin-right: 6px;
  vertical-align: middle;
}

.dash-table tr.is-critica { background: color-mix(in srgb, var(--status-warning) 7%, var(--surface)); }
.dash-table tr.is-critica:hover { background: color-mix(in srgb, var(--status-warning) 12%, var(--surface)); }

/* Oculta visualmente sin sacarlo del árbol de accesibilidad -- para el
   resumen textual (tabla de datos) que acompaña a cada gráfico del
   dashboard: un lector de pantalla lo lee igual que el SVG no dice nada. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* =========================================================
   Gráficos del dashboard (Fase de visualización de #resumen) — SVG plano
   generado en JS (js/dashboard-charts.js), sin librería de charts. Mismos
   tokens que el resto del dashboard (--surface/--border/--radius para la
   tarjeta contenedora, --accent para series únicas, --status-* para
   categorías de estado) -- ver docs/DASHBOARD-ARCHITECTURE.md.
   ========================================================= */
.dash-chart-card {
  position: relative;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 20px 16px;
}

.dash-chart-card:hover { border-color: var(--b1, var(--border)); box-shadow: 0 14px 32px var(--shadow-soft); }

.dash-chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 12px;
}

.dash-chart-head h2 { margin: 0; font: 700 var(--fs-card, 16px)/1.35 var(--font); }
.dash-chart-head .dash-chart-total { font-size: 13px; color: var(--muted); }

/* Las acciones de un widget pueden ocupar más de una línea dentro de SU
   tarjeta. Así nunca se desbordan hacia el widget vecino en tableros que
   el usuario hizo compactos. */
.dash-chart-head > h2 { flex: 1 1 110px; min-width: 0; overflow-wrap: anywhere; }
.dash-chart-controls { display: flex; flex: 0 1 auto; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; min-width: 0; max-width: 100%; }
.dash-chart-controls .dash-widget-tamano-btn { margin-left: 0; }

.dash-period-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border-radius: 999px;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  margin-right: 4px;
}

.dash-period-btn {
  position: relative;
  z-index: 1;
  border: none;
  background: none;
  border-radius: 999px;
  padding: 5px 12px;
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s var(--ease);
}

.dash-period-btn:hover { color: var(--text); }

.dash-period-btn.is-active { color: #ffffff; }

/* Pastilla deslizante compartida (js/dashboard-tabs.js) -- ver también
   .dash-badge-tabs más abajo, mismo mecanismo. Vive DETRÁS de los botones
   (z-index 0): un botón inactivo, con su propio fondo opaco, la tapa al
   pasar por encima mientras se desliza; solo se ve rellenando el botón
   activo (que queda transparente) -- efecto "un solo tab, se mueve". */
.dash-tab-glider {
  position: absolute;
  z-index: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 92%, white), var(--accent));
  box-shadow: 0 5px 14px color-mix(in srgb, var(--accent) 24%, transparent), inset 0 1px 0 rgba(255,255,255,.22);
  will-change: left, top, width, height;
  pointer-events: none;
  transition: left 0.35s cubic-bezier(0.16, 1, 0.3, 1), top 0.35s cubic-bezier(0.16, 1, 0.3, 1),
    width 0.35s cubic-bezier(0.16, 1, 0.3, 1), height 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.dash-chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

/* Tablero de Cocina (Nuevas/Preparando/Listas/Entregadas) -- la clase
   existía en el HTML (dashboard-cocina.js) pero nunca tuvo regla propia,
   así que las 4 columnas caían apiladas una debajo de otra en vez de
   mostrarse lado a lado. align-items:start para que cada columna mida
   según su propio contenido, no la más alta de las 4. */
.dash-kanban {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  align-items: start;
  margin-top: 16px;
}

.dash-chart-svg-wrap { position: relative; }
.dash-chart-svg-wrap svg { display: block; width: 100%; height: auto; overflow: visible; }

/* Tooltip flotante compartido por los 2 tipos de gráfico -- posicionado en
   JS (left/top inline), nunca tapa el punto/segmento que describe. */
.dash-chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 12px;
  white-space: nowrap;
  box-shadow: 0 8px 20px var(--shadow-soft);
  transform: translate(-50%, -100%);
  opacity: 0;
  transition: opacity 0.12s ease;
  z-index: 5;
}

.dash-chart-tooltip.is-visible { opacity: 1; }
.dash-chart-tooltip strong { font-variant-numeric: tabular-nums; }

.dash-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 18px;
  margin-top: 14px;
  font-size: 13px;
}

.dash-chart-legend-item { display: flex; align-items: center; gap: 6px; color: var(--muted); }
.dash-chart-legend-item strong { color: var(--text); font-variant-numeric: tabular-nums; }

.dash-chart-empty {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: 24px 0;
}

.dash-chart-link {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
}

.dash-chart-link:hover { text-decoration: underline; }

.dash-table-compacta th,
.dash-table-compacta td { padding: 8px 10px; font-size: 13px; }

/* Panel "Estado de caja" -- ver dashboard-resumen.js#pintarEstadoCaja(). */
.dash-estado-caja { display: flex; flex-direction: column; gap: 14px; }

.dash-estado-caja-pill { display: flex; justify-content: flex-end; }

.dash-estado-caja-filas {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}

.dash-estado-caja-filas > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 13px;
  color: var(--muted);
}

.dash-estado-caja-filas strong { font-variant-numeric: tabular-nums; color: var(--text); }
.dash-estado-caja-filas strong.is-up { color: var(--status-good); }
.dash-estado-caja-filas strong.is-down { color: var(--status-critical); }

.dash-estado-caja-saldo {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.dash-estado-caja-saldo span { font-size: 13px; color: var(--muted); }
.dash-estado-caja-saldo strong { font: 800 var(--fs-title, 28px)/1.1 var(--font); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }

.dash-estado-caja-acciones { display: flex; gap: 8px; }
.dash-estado-caja-acciones a { flex: 1; text-align: center; text-decoration: none; padding: 9px 14px; }

@media (prefers-reduced-motion: reduce) {
  .dash-chart-tooltip { transition: none; }
  .dash-tab-glider { transition: none; }
}

/* =========================================================
   Widgets reordenables/redimensionables (js/dashboard-widgets.js) --
   posición y tamaño sugeridos por defecto, editables por el usuario.
   ========================================================= */
.dash-widget-handle {
  cursor: grab;
  color: var(--muted);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, color 0.15s ease;
  padding: 2px;
  margin: -2px -2px -2px 4px;
  flex-shrink: 0;
}

.dash-kpi-card:hover .dash-widget-handle,
.dash-chart-card:hover .dash-widget-handle,
.dash-widget-handle:focus-visible,
.is-widget-editable .dash-widget-handle {
  opacity: 1;
  pointer-events: auto;
}

/* Los widgets se arrastran directamente; una pulsación sostenida activa el
   mismo gesto en pantallas táctiles. */
.is-widget-editable > * {
  cursor: grab;
  touch-action: pan-y;
}

.is-widget-editable > *:active {
  cursor: grabbing;
}

.dash-widget-handle:hover { color: var(--accent); }
.dash-widget-handle:active { cursor: grabbing; }

/* Grip de tamaño -- esquina inferior derecha, se arrastra horizontalmente
   (como el tamaño de un widget de iPhone) en vez de tocar un botón de texto
   "Compacto/Normal/Ancho". touch-action:none es necesario: sin esto un dedo
   arrastrando el grip en una pantalla táctil scrollea la página entera en
   vez de redimensionar. */
.dash-widget-resize {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  color: var(--muted);
  opacity: 0;
  cursor: ew-resize;
  touch-action: none;
  transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}
.dash-kpi-card:hover .dash-widget-resize,
.dash-chart-card:hover .dash-widget-resize,
.dash-widget-resize:focus-visible,
.is-widget-editable .dash-widget-resize {
  opacity: 1;
}
.dash-widget-resize:hover,
.dash-widget-resize:focus-visible { color: var(--accent); background: var(--surface-2); }
.dash-widget-resize:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.is-resizing { box-shadow: 0 0 0 2px var(--jade-glow, var(--accent)); transition: none; }
.is-resizing .dash-widget-resize { opacity: 1; color: var(--accent); }

/* Ancla el handle arriba a la derecha de una KPI card sin alterar su
   layout normal (value/label siguen apilados igual que siempre). */
.dash-kpi-card { position: relative; padding-top: 42px; }
.dash-kpi-card > .dash-widget-handle { position: absolute; top: 10px; right: 10px; }

.dash-widget-actions { position: absolute; display: flex; gap: 6px; top: 10px; right: 34px; opacity: 0; pointer-events: none; transform: translateY(-2px); transition: opacity .18s var(--ease), transform .18s var(--ease); }
.dash-kpi-card:hover .dash-widget-actions, .dash-kpi-card:focus-within .dash-widget-actions { opacity: 1; pointer-events: auto; transform: none; }
.dash-widget-actions button, .dash-widget-library-btn { min-height: 30px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface-2); color: var(--muted); font: 600 11px var(--font); cursor: pointer; padding: 4px 9px; }
.dash-widget-actions button:hover, .dash-widget-library-btn:hover { border-color: var(--accent); color: var(--text); }
.dash-widget-actions button:focus-visible, .dash-widget-library-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.dash-chart-head { position: relative; display: flex; align-items: flex-start; flex-wrap: wrap; gap: 6px; min-width: 0; }
.dash-chart-head > h2,
.dash-chart-head > h3,
.dash-chart-head > .dash-chart-title { flex: 1 1 120px; min-width: 0; overflow-wrap: anywhere; }
.dash-chart-head > * { min-width: 0; }

.is-dragging { opacity: 0.4; }

/* Botón de tamaño de un gráfico (normal <-> ancho) -- capsula chica junto
   al título, mismo lenguaje que .dash-badge-tab pero de un solo botón. */
.dash-widget-tamano-btn {
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--muted);
  font-family: var(--font);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  margin-left: 8px;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.dash-widget-tamano-btn:hover { color: var(--accent); border-color: var(--accent); }

.dash-chart-card.is-wide { grid-column: span 2; }
.dash-kpi-card.is-compact,
.dash-chart-card.is-compact { grid-column: span 1; }
.dash-widget-tamano-btn { transition: color .22s ease, background-color .24s ease, border-color .24s ease, transform .22s cubic-bezier(.16,1,.3,1); }
.dash-widget-tamano-btn:active { transform: scale(.97); }

.dash-widgets-restablecer {
  background: none;
  border: none;
  color: var(--muted);
  font-family: var(--font);
  font-size: 12px;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
}

.dash-widgets-restablecer:hover { color: var(--accent); }

.dash-widget-library-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 7px 12px; font-size: 12px; backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); }
.dash-widget-library { max-width: 580px; }
.dash-widget-library .dash-modal-head { align-items: flex-start; }
.dash-widget-library .dash-modal-head p { margin: 4px 30px 0 0; color: var(--muted); font-size: 13px; line-height: 1.45; }
.dash-widget-library-list { display: grid; gap: 8px; margin-top: 20px; }
.dash-widget-library-item { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 64px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px; cursor: pointer; }
.dash-widget-library-item:hover { background: var(--surface-2); border-color: var(--b1, var(--border)); }
.dash-widget-library-item span:first-child { min-width: 0; }
.dash-widget-library-item strong, .dash-widget-library-item small { display: block; overflow-wrap: anywhere; }
.dash-widget-library-item small { margin-top: 3px; color: var(--muted); font-size: 12px; }
.dash-widget-library-item input { position: absolute; opacity: 0; }
.dash-widget-switch { position: relative; width: 42px; height: 24px; flex: 0 0 auto; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); transition: background-color .2s var(--ease); }
.dash-widget-switch::after { content: ''; position: absolute; width: 18px; height: 18px; top: 2px; left: 2px; border-radius: 50%; background: var(--muted); transition: transform .2s var(--ease), background-color .2s var(--ease); }
.dash-widget-library-item input:checked + .dash-widget-switch { background: var(--accent); border-color: var(--accent); }
.dash-widget-library-item input:checked + .dash-widget-switch::after { transform: translateX(18px); background: #fff; }
.dash-widget-library-item input:focus-visible + .dash-widget-switch { outline: 2px solid var(--accent); outline-offset: 3px; }

.dash-view-head-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
}

/* Botón "Personalizar" -- icono de grilla 2x2, prendido/apagado (aria-pressed). */
.dash-personalizar-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 14px 6px 12px;
  color: var(--muted);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.dash-personalizar-btn:hover { color: var(--text); border-color: var(--accent); }

.dash-personalizar-btn.is-active {
  color: var(--accent-hover);
  border-color: var(--accent);
  background: var(--jade-dim, var(--surface-2));
}

/* Solo desktop -- en tablet/mobile el layout de #resumen es fijo (ver
   PASO 5 en docs/DASHBOARD-DESIGN-REFERENCE.md). */
@media (max-width: 1024px) {
  .dash-personalizar-btn { display: none; }
}

/* =========================================================
   Selector de rango de fechas (js/dashboard-daterange.js) — botón trigger +
   popover anclado, mismos tokens que el resto (--surface/--border/--radius),
   mismo lenguaje de "cápsula" que .dash-status-pill/.cta para los atajos.
   ========================================================= */
.dash-daterange-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Mismo padding vertical que .dash-badge-tab -- misma familia de
     "píldora" de filtro. Antes eran 2px más alto y, alineados por
     flex-start (ej. Pedidos), quedaba visiblemente más abajo/más grande
     que el resto de los filtros de la misma fila. */
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--text);
  font-family: var(--font);
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.dash-daterange-trigger::before {
  content: '';
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  background: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E") center / contain no-repeat;
}

.dash-daterange-trigger:hover { border-color: var(--accent); }
.dash-daterange-trigger.is-active { color: var(--accent); border-color: var(--accent); }

/* Variante "campo de formulario" -- mismo trigger, pero dentro de un
   .auth-form .dash-form-grid junto a inputs/selects normales necesita la
   misma caja rectangular que ellos (12px de radio, ancho completo, mismo
   padding/alto), no la píldora de filtro flotante de arriba. Reemplaza
   cualquier <input type="date"> suelto -- mismo calendario en toda la app. */
.auth-form .dash-daterange-trigger.is-field {
  width: 100%;
  justify-content: flex-start;
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--bg);
  font-size: 16px;
  color: var(--text);
}
.auth-form .dash-daterange-trigger.is-field:not(.is-active) { color: var(--muted); }

.dash-daterange-panel {
  position: absolute;
  z-index: 20;
  margin-top: 6px;
  background: var(--bg);
  background-color: var(--bg);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 16px 32px var(--shadow);
  padding: 14px;
  /* Ancho fijo, no max-content: con flex-wrap en .dash-daterange-badges,
     max-content mide como si las badges NUNCA envolvieran (todas en una
     sola fila), dejando el panel mucho más ancho de lo necesario -- hasta
     el punto de desbordar viewports angostos. 264px es lo que ocupa la
     grilla de 7 columnas del calendario (7×32px + 6×2px de gap) + padding. */
  width: 264px;
  max-width: calc(100vw - 32px);
  opacity: 0;
  transform: translateY(-6px) scale(.98);
  transform-origin: top left;
  transition: opacity .18s var(--ease), transform .18s var(--ease);
}

.dash-daterange-panel.is-open { opacity: 1; transform: translateY(0) scale(1); }

.dash-daterange-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.dash-daterange-badge {
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--text);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.dash-daterange-badge:hover { border-color: var(--accent); color: var(--accent); }
.dash-daterange-badge:active { transform: scale(.97); }

.dash-daterange-cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 13px;
  text-transform: capitalize;
}

.dash-daterange-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 32px);
  gap: 2px;
}

.dash-daterange-cal-weekday {
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  padding-bottom: 4px;
}

.dash-daterange-day {
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text);
  font-family: var(--font);
  font-size: 13px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.dash-daterange-day:hover { background: var(--surface-2); }
.dash-daterange-day.is-today { font-weight: 800; color: var(--accent); }
.dash-daterange-day.is-in-range { background: color-mix(in srgb, var(--accent) 12%, transparent); border-radius: 0; }

.dash-daterange-day.is-selected-start,
.dash-daterange-day.is-selected-end {
  background: var(--accent);
  color: #ffffff;
}

/* Sección de horas (conHora en dashboard-daterange.js) -- solo se agrega
   cuando el caller necesita precisión de hora, no solo el día (ej.
   Reportes). Mismo idioma visual del panel: borde superior como separador,
   igual que .dash-daterange-badges lo hace por abajo. */
.dash-daterange-horas {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.dash-daterange-horas-row { display: flex; gap: 10px; }
.dash-daterange-horas-row label {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: var(--muted);
}
.dash-daterange-horas-row input[type="time"] {
  min-height: 38px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: var(--font);
  font-size: 13px;
  background: var(--bg);
  color: var(--text);
  color-scheme: dark;
  width: 100%;
}
.dash-daterange-horas-row input[type="time"]:focus { outline: none; border-color: var(--accent); }
:root[data-theme="light"] .dash-daterange-horas-row input[type="time"],
:root[data-theme="grey"] .dash-daterange-horas-row input[type="time"] { color-scheme: light; }
.dash-daterange-aplicar {
  width: 100%;
  min-height: 38px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), opacity 0.2s var(--ease);
}
.dash-daterange-aplicar:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.dash-daterange-aplicar:disabled { opacity: .5; cursor: not-allowed; }

/* =========================================================
   Badge tabs -- filtro de un solo valor activo a la vez (ej. estado de
   producto/pedido), mismo lenguaje de cápsula que .dash-daterange-badge
   pero con estado "activo" persistente (no es un popover, es un filtro
   siempre visible). Genérico: cualquier vista del dashboard puede armar
   una fila de estas.
   ========================================================= */
.dash-badge-tabs {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}

.dash-badge-tab {
  position: relative;
  z-index: 1;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: var(--muted);
  font-family: var(--font);
  font-size: var(--fs-body-small, 13px);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.28s var(--ease), border-color 0.2s var(--ease), transform 0.28s var(--ease);
}

.dash-badge-tab:hover { color: var(--text); border-color: var(--accent); }

.dash-badge-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.dash-badge-tab:active { transform: scale(.97); }

.dash-badge-tab:disabled,
.dash-badge-tab[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

.dash-badge-tab.is-active {
  background: transparent;
  border-color: transparent;
  color: #ffffff;
}

.dash-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}

.dash-form-grid .full { grid-column: 1 / -1; }
/* .dash-form-grid tiene row-gap:0 a propósito (el ritmo vertical lo dan los
   <label> con su propio margin-top:14px, ver 4798). Un <button> de envío
   como hijo directo de la grilla NO es un <label> -- sin este margen queda
   pegado a la fila de arriba (hallazgo real 2026-09-15: "Registrar pesaje"/
   "Confirmar venta"/"Guardar cambios" pegados al último campo). No aplica
   si el botón ya vive dentro de .dash-modal-actions (ese wrapper trae su
   propio margin-top:22px, ver línea ~4150) -- evita doble margen ahí. */
.dash-form-grid > button { margin-top: 22px; }
/* Hallazgo real 2026-09-15: ".auth-form label:first-child{margin-top:0}"
   (línea ~1940) está pensado para un formulario de 1 columna -- en una
   grilla de 2 columnas solo anula el margen del campo de la IZQUIERDA de
   la primera fila, dejando a su compañero de la derecha 14px más abajo
   (la fila entera queda "escalonada"). Afecta cualquier .dash-form-grid de
   2+ columnas de TODO el panel, no un formulario puntual. Se restaura el
   margen parejo para toda la primera fila; .dash-settings-card es de 1
   columna (grid-template-columns:1fr, línea ~4099) y sí necesita el
   comportamiento original, por eso se re-excluye con más especificidad. */
.dash-form-grid label:first-child { margin-top: 14px; }
.dash-settings-card .dash-form-grid label:first-child { margin-top: 0; }

.dash-panel {
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  margin-bottom: 24px;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.dash-panel h2 { font: 700 var(--fs-card, 16px)/1.35 var(--font); margin: 0 0 var(--sp-4, 16px); }

/* Grid de tarjetas por dominio (Configuración) -- cada tarjeta es un
   subconjunto temático de platform_settings, pero todas viven dentro del
   mismo <form>/submit único (ver dashboard-configuracion.js): reorganiza
   visualmente sin duplicar la lógica de guardado. */
.dash-settings-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 4px;
}

.dash-settings-card {
  min-width: 0;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
}

.dash-settings-card-wide { grid-column: 1 / -1; }

.dash-settings-card-head { margin-bottom: 14px; }
.dash-settings-card-head h2 { font: 700 var(--fs-card, 16px)/1.35 var(--font); margin: 0 0 4px; }
.dash-settings-card-head p { margin: 0; color: var(--muted); font: 400 var(--fs-body-small, 13px)/1.5 var(--font); }

.dash-settings-card .dash-form-grid { grid-template-columns: 1fr; gap: 12px 0; }

.dash-modal-overlay {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--shadow) 70%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}

.dash-modal {
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
}

.dash-modal[hidden],
.dash-modal-overlay[hidden] { display: none; }

/* Variante ancha reutilizable (Fase 2) para modales con contenido tabular
   (ej. Mesas del restaurante) -- mismo patrón que .dash-customer-detail/
   .dash-custom-modal más abajo: una clase adicional sobre .dash-modal que
   solo cambia max-width, nunca un componente de modal paralelo. */
.dash-modal-wide { max-width: 760px; }
@media (max-width: 820px) { .dash-modal-wide { max-width: calc(100vw - 40px); } }

.dash-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}

.dash-modal-head h2 { margin: 0; font: 700 var(--fs-card, 16px)/1.35 var(--font); }

.dash-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 22px;
}

.dash-store-select {
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 13px;
}

.dash-business-switcher { position: relative; z-index: 20; overflow: visible; display: grid; grid-template-columns: max-content minmax(160px, 300px) max-content minmax(180px, 360px) minmax(0, 1fr); align-items: center; gap: 12px 16px; padding: 16px 20px; margin-bottom: 24px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); box-shadow: 0 12px 30px var(--shadow-soft); }
.dash-business-switcher[hidden] { display: none; }
.dash-business-switcher:has(#dash-organization-select[hidden]) { grid-template-columns: max-content minmax(0, 360px) minmax(0, 1fr); }
@media (max-width: 1100px) {
  .dash-business-switcher,
  .dash-business-switcher:has(#dash-organization-select[hidden]) { grid-template-columns: minmax(0, 1fr); }
}
#dash-view { display: contents; }
.dash-main > .dash-business-switcher { order: -1; }
#dash-view > .dash-view-head { order: -2; }
.dash-business-switcher label { font-weight: 600; font-size: 14px; }
.dash-business-switcher span { min-width: 0; font-size: 13px; line-height: 1.45; color: var(--muted); overflow-wrap: anywhere; }
/* Hallazgo 2026-09-15 (previo a ganadería, no introducido por esa vertical):
   la última columna (minmax(0,1fr)) del switcher podía colapsar a unos
   pocos px de ancho según cómo el navegador repartía el espacio entre las 5
   columnas, dejando el texto de ayuda envuelto letra por letra. Un ancho
   mínimo legible evita el colapso sin tocar min-width:0 del resto de spans. */
#dash-business-switcher-help { min-width: 220px; }
.dash-business-switcher .dash-store-select { min-width: 0; min-height: 44px; width: 100%; font-size: 16px; border-radius: 12px; }
.dash-business-switcher select:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.dash-business-switcher .glass-select { width: 100%; }
.dash-business-switcher .glass-select-trigger { min-height: 44px; border-radius: 12px; }
/* Fase 3 (037_billing_plans.sql) -- banner de aviso (5 días de gracia) y
   pantalla de bloqueo completo (suspendida por impago). Mismo criterio de
   color semántico que .dash-status-pill.is-warning/is-cancelled: ámbar para
   "avisá pero todavía funciona", el crítico para "cortado de verdad". */
.dash-billing-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 18px;
  margin-bottom: 20px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--status-warning) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--status-warning) 35%, transparent);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  color: color-mix(in srgb, var(--status-warning) 85%, var(--text));
  font-size: 13px;
  line-height: 1.5;
}

.dash-billing-banner strong { display: block; margin-bottom: 2px; color: var(--text); }
.dash-billing-balance { display: grid; gap: 4px; margin-bottom: 16px; padding: 16px 18px; border: 1px solid var(--border); border-radius: 16px; background: var(--surface-2); backdrop-filter: blur(var(--glass-blur)); }
.dash-billing-balance span, .dash-billing-balance small { color: var(--muted); }
.dash-billing-balance strong { font: 800 var(--fs-display, 40px)/1.1 var(--font); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.dash-billing-notice { margin: 10px 0 16px; padding: 10px 13px; border: 1px solid color-mix(in srgb, var(--status-warning) 28%, transparent); border-radius: 12px; background: color-mix(in srgb, var(--status-warning) 8%, transparent); color: var(--muted); font-size: 13px; line-height: 1.45; }

.dash-billing-locked {
  max-width: 520px;
  margin: 48px auto;
  padding: 32px;
  text-align: center;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--status-critical) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--status-critical) 30%, transparent);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  box-shadow: 0 20px 50px var(--shadow-soft);
}

.dash-billing-locked h1 { margin: 0 0 12px; font-size: 20px; }
.dash-billing-locked p { margin: 0 0 8px; color: var(--muted); font-size: 14px; line-height: 1.55; }

.dash-report-period { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 24px; }
.dash-report-period select { min-height: 44px; }
html:has(.dash-shell) { scrollbar-width: thin; scrollbar-color: var(--muted) var(--bg); }
html:has(.dash-shell)::-webkit-scrollbar { width: 10px; }
html:has(.dash-shell)::-webkit-scrollbar-track { background: var(--bg); }
html:has(.dash-shell)::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 55%, transparent); border: 3px solid var(--bg); border-radius: 99px; }

@media (prefers-reduced-motion: reduce) {
  .dash-skeleton { animation: none; }
  .dash-sidebar { transition: none; }
}

/* Tablet (768-1024px): sidebar fijo, colapsado a solo íconos (64px) --
   distinto de mobile (sigue siendo un panel visible, no un drawer). */
@media (min-width: 768px) and (max-width: 1024px) {
  .dash-sidebar { width: 64px; padding: 20px 8px; }
  .dash-nav-link { justify-content: center; padding: 12px 0; }
  .dash-nav-link svg { margin: 0; }
  .dash-nav-label,
  .dash-nav-badge,
  .dash-nav-group-label { display: none; }
  .dash-main { margin-left: 64px; }
  .dash-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Última tarjeta sola en su fila (total de tarjetas impar, ej. 3 KPIs de
     Inventario) -- sin esto queda pegada a la izquierda con un hueco vacío
     al lado en vez de ocupar el ancho completo. */
  .dash-kpi-grid .dash-kpi-card:nth-child(odd):last-child { grid-column: 1 / -1; }
  .dash-chart-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-chart-card.is-wide { grid-column: span 2; }
}

/* Mobile (<768px): sidebar como drawer/overlay (toggle en el topbar),
   layout de una sola columna, tiles de KPI en grilla 2x2. */
@media (max-width: 767px) {
  .dash-sidebar-toggle { display: flex; }

  .dash-sidebar {
    transform: translateX(-100%);
    width: 260px;
    box-shadow: 0 20px 40px var(--shadow);
  }

  .dash-sidebar.open { transform: translateX(0); }

  .dash-main { margin-left: 0; padding: 24px 16px; }

  .dash-user-email { max-width: 120px; }

  .dash-form-grid { grid-template-columns: 1fr; }
  .dash-settings-grid { grid-template-columns: 1fr; }
  .dash-settings-card-wide { grid-column: auto; }

  .dash-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-kpi-grid .dash-kpi-card:nth-child(odd):last-child { grid-column: 1 / -1; }

  .dash-chart-grid { grid-template-columns: 1fr; }
  .dash-chart-card.is-wide { grid-column: auto; }
  .dash-kpi-card.is-wide { grid-column: span 2; }
  .dash-business-switcher { grid-template-columns: 1fr; gap: 8px; padding: 16px; }
  .dash-business-switcher label { margin-bottom: 2px; }
  .dash-business-switcher .dash-store-select { width: 100%; }
  /* right:42px (no 10px) -- .dash-widget-resize (el grip de tamaño) vive
     siempre en esa misma esquina inferior derecha, en TODAS las tarjetas
     (no solo en modo edición: hacerReordenable() agrega is-widget-editable
     sin condición). Con right:10px acá "Quitar" quedaba literalmente
     encimado con el ícono de redimensionar en mobile -- hallazgo de
     auditoría 2026-09-13. */
  .dash-widget-actions { opacity: 1; pointer-events: auto; top: auto; right: 42px; bottom: 10px; }
  .dash-kpi-card { padding-bottom: 48px; }
  /* La chispa de tendencia (.dash-kpi-sparkline) vive siempre abajo a la
     derecha de la tarjeta -- en mobile las acciones (Quitar/tamaño) también
     se anclan abajo para quedar siempre visibles, así que en las tarjetas
     con chispa hay que subirlas para no superponerse. */
  .dash-kpi-card.has-sparkline .dash-widget-actions { bottom: 52px; }
  .dash-kpi-card.has-sparkline { padding-bottom: 84px; }

  /* Objetivo táctil mínimo de 44px en los controles de acción del panel. */
  .dash-icon-btn,
  .dash-widget-tamano-btn,
  .btn-jade,
  .btn-ghost,
  .dash-daterange-trigger {
    min-height: 44px;
  }

  .dash-topbar-date { display: none; }
}

@media (max-width: 640px) {
  .dash-store-name,
  .dash-breadcrumb-sep,
  .dash-breadcrumb-vista { display: none; }
}

/* Punto de venta (#pos, js/dashboard-pos.js) — grilla táctil + carrito fijo,
   mismos tokens de superficie/glass que .dash-kpi-card, pensado para tocar
   rápido (referencias: Shopify POS smart grid, Square tile grid). */
.pos-layout {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 20px;
  align-items: start;
}

.pos-terminal-context {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 14px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  color: var(--text);
}
.pos-terminal-context label { font-size: 13px; font-weight: 700; }
.pos-terminal-context .glass-select,
.pos-terminal-context .dash-store-select { min-width: 190px; flex: 0 1 300px; }
.pos-terminal-context #pos-terminal-status { color: var(--muted); font-size: 13px; }
.pos-terminal-context #pos-terminal-status::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 6px; border-radius: 999px; background: var(--status-warning); }
.pos-terminal-context:has(#pos-terminal-status:not(:empty)) { backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); }

.terminales-pos-panel { margin-top: 24px; }
.terminales-pos-panel code { color: var(--muted); font: 600 var(--fs-caption, 12px)/1.3 var(--font-mono); }
.terminales-pos-form { margin-top: 18px; }

.pos-buscador,
.dash-search-input {
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 15px;
  margin-bottom: 16px;
}

.pos-buscador:focus,
.dash-search-input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.pos-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
}

.pos-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  min-height: 88px;
  text-align: left;
  color: var(--text);
  cursor: pointer;
  transition: transform 0.15s var(--ease), border-color 0.15s ease, box-shadow 0.15s ease;
}

.pos-tile:hover,
.pos-tile:focus-visible {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 8px 20px var(--shadow-soft);
}

.pos-tile:active { transform: scale(0.97); }

.pos-tile-nombre { color: var(--text); font-weight: 600; font-size: 14px; overflow-wrap: break-word; }
.pos-tile-precio { color: var(--text); font-weight: 800; font-variant-numeric: tabular-nums; }
.pos-tile-stock { font-size: 12px; color: var(--muted); }

.pos-carrito {
  position: sticky;
  top: 16px;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 140px);
}

.pos-carrito h2 { font-size: 16px; margin: 0 0 12px; }
.pos-carrito { color: var(--text); }

.pos-carrito-lineas {
  overflow-y: auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 12px;
}

.pos-linea {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: center;
  gap: 8px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

.pos-linea-info { display: flex; flex-direction: column; min-width: 0; }
.pos-linea-nombre { color: var(--text); font-size: 13px; font-weight: 600; overflow-wrap: break-word; }
.pos-linea-precio { font-size: 12px; color: var(--muted); }
.pos-linea-subtotal { display: flex; flex-direction: column; align-items: flex-end; color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 13px; }
.pos-linea-subtotal s { color: var(--muted); font-size: 11px; font-weight: 500; }
.pos-linea-descuento { display: flex; align-items: center; gap: 5px; margin-top: 5px; color: var(--muted); font-size: 11px; font-weight: 600; }
.pos-linea-descuento input { width: 88px; min-height: 30px; padding: 4px 7px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2); color: var(--text); font: inherit; }

.pos-linea-qty {
  display: flex;
  align-items: center;
  gap: 6px;
  font-variant-numeric: tabular-nums;
}

.pos-qty-btn {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
}

.pos-qty-btn:hover { border-color: var(--accent); }

.pos-linea-quitar {
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pos-linea-quitar:hover { color: var(--status-critical); }
.pos-linea-quitar svg { width: 14px; height: 14px; }

.pos-carrito-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 15px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  margin-bottom: 10px;
}

.pos-carrito-resumen { display: grid; grid-template-columns: 1fr auto; gap: 5px 12px; padding: 10px 0 2px; color: var(--muted); font-size: 12px; }
/* display:grid arriba empata en especificidad con [hidden] del navegador y
   gana por venir después en la cascada -- sin esto, "Subtotal/Descuentos"
   quedaba visible con ₡0 en un carrito vacío aunque dashboard-pos.js ya
   pone resumenEl.hidden = true. Hallazgo de auditoría 2026-09-13. */
.pos-carrito-resumen[hidden] { display: none; }
.pos-carrito-resumen strong { color: var(--text); text-align: right; font-variant-numeric: tabular-nums; }
.pos-carrito-resumen strong:last-child { color: var(--status-success); }
.pos-carrito-total strong { font-size: 22px; font-variant-numeric: tabular-nums; }
.pos-save-customer { width: fit-content; margin: -2px 0 2px; }

.pos-pagos-fieldset { display: grid; gap: 10px; margin: 0; padding: 14px; border: 1px solid var(--border); border-radius: 12px; }
.pos-pagos-fieldset legend { padding: 0 5px; color: var(--text); font-size: 13px; font-weight: 700; }
#pos-pagos-lista { display: grid; gap: 9px; }
.pos-pago-fila { display: grid; grid-template-columns: minmax(130px, 1fr) minmax(110px, .7fr) auto; gap: 8px; align-items: end; }
.pos-pago-fila label { display: grid; gap: 5px; margin: 0; color: var(--muted); font-size: 11px; font-weight: 600; }
.pos-pago-fila input { width: 100%; min-height: 42px; }
.pos-pago-fila .glass-select,
.pos-pago-fila .dash-store-select { width: 100%; min-width: 0; }
.pos-pago-fila .pos-linea-quitar { margin-bottom: 9px; }
.pos-agregar-pago { width: fit-content; }
.pos-pagos-balance { margin: 0; }
.pos-pagos-balance.is-complete { color: var(--status-success); }

.dash-refund-modal { max-width: 720px; }
.refund-items { display: grid; gap: 8px; margin: 0; padding: 12px; border: 1px solid var(--border); border-radius: 12px; }
.refund-items legend { padding: 0 5px; color: var(--text); font-size: 13px; font-weight: 700; }
.refund-item { display: grid; grid-template-columns: auto minmax(0, 1fr) 84px; gap: 10px; align-items: center; margin: 0; padding: 9px 0; border-bottom: 1px solid var(--border); }
.refund-item:last-child { border-bottom: 0; }
.refund-item > span { display: grid; gap: 2px; }
.refund-item small { color: var(--muted); font-weight: 500; }
.refund-item input[type="number"] { width: 100%; min-height: 38px; }
.refund-summary { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 0; border-bottom: 1px solid var(--border); }
.refund-summary strong { font-size: 20px; font-variant-numeric: tabular-nums; }

@media (max-width: 1024px) {
  .pos-layout { grid-template-columns: 1fr; }
  .pos-carrito { position: static; max-height: none; }
}

.pos-recibo-lineas {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
  font-size: 14px;
}

.pos-recibo-linea {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.pos-recibo-linea small { color: var(--status-success); }

@media (max-width: 520px) {
  .pos-linea { grid-template-columns: minmax(0, 1fr) auto auto; }
  .pos-linea-subtotal { grid-column: 2; }
  .pos-pago-fila { grid-template-columns: 1fr auto; }
  .pos-pago-fila label { grid-column: 1; }
  .pos-pago-fila .pos-linea-quitar { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
}

/* Recibo imprimible (mostrarRecibo() en dashboard-pos.js) -- oculta todo lo
   demás de la página al imprimir, solo deja el contenido del recibo. */
@media print {
  body * { visibility: hidden; }
  #pos-recibo-print, #pos-recibo-print * { visibility: visible; }
  #pos-recibo-print { position: absolute; top: 0; left: 0; width: 100%; }
}
/* Catálogo interno ASTRC Glass — visible solo en #design-system para super_admin. */
.ds-preview-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px; }
.ds-preview-card { min-width:0; padding:20px; border:1px solid var(--border); border-radius:var(--radius); background:var(--surface); box-shadow:0 12px 30px var(--shadow-soft); }
.ds-preview-card-wide { grid-column:span 2; }
.ds-preview-card h2 { margin:0 0 16px; font-size:18px; }
.ds-eyebrow { margin:0 0 6px; color:var(--muted); font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; }
.ds-demo-switcher { display:grid !important; grid-template-columns:max-content minmax(150px,1fr) max-content minmax(150px,1fr); margin:0; }
.ds-demo-switcher span { grid-column:1 / -1; color:var(--muted); font-size:13px; }
.ds-kpis { grid-template-columns:repeat(2,minmax(0,1fr)); margin:0; }
.ds-positive { color:var(--status-success,#35c759); }
.ds-notice-stack { display:grid; gap:8px; }
.ds-notice { padding:12px 14px; border:1px solid var(--border); border-radius:12px; font-size:13px; }
.ds-notice-info { background:color-mix(in srgb,#4da3ff 12%,var(--surface)); }
.ds-notice-warning { background:color-mix(in srgb,var(--status-warning,#f5a623) 12%,var(--surface)); }
.ds-notice-critical { background:color-mix(in srgb,var(--status-critical,#ff453a) 12%,var(--surface)); }
.ds-actions { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:18px; }
.ds-actions .cta,.ds-actions .secondary { margin:0; width:auto; }
.ds-empty { display:grid; gap:4px; padding:18px; border:1px dashed var(--border); border-radius:12px; color:var(--muted); text-align:center; }
.ds-empty strong { color:var(--text); }
.ds-pos-line { display:grid; grid-template-columns:minmax(0,1fr) auto auto; align-items:center; gap:12px; padding:12px 0; border-bottom:1px solid var(--border); }
.ds-pos-line small { display:block; margin-top:4px; color:var(--muted); }
.ds-qty { display:flex; align-items:center; gap:8px; }
.ds-qty button { width:28px; height:28px; border:1px solid var(--border); border-radius:9px; color:var(--text); background:var(--surface-2); cursor:pointer; }
.ds-pos-total { display:flex; justify-content:space-between; padding-top:16px; font-size:17px; }
.glass-select { position:relative; min-width:0; }
.glass-select > select { position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
.glass-select-trigger { display:flex; width:100%; align-items:center; justify-content:space-between; gap:12px; min-height:44px; padding:10px 14px; border:1px solid var(--border); border-radius:12px; color:var(--text); background:color-mix(in srgb,var(--surface-2) 84%,transparent); font:inherit; text-align:left; cursor:pointer; transition:border-color .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease); }
.glass-select-trigger:hover { background:color-mix(in srgb,var(--surface-2) 96%,transparent); }
.glass-select-trigger:focus-visible { outline:0; border-color:var(--accent); box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 22%,transparent); }
.glass-select-trigger:disabled { opacity:.55; cursor:not-allowed; }
/* Dentro de un formulario estándar, el trigger debe verse igual que sus
   inputs vecinos (mismo fondo que .auth-form input/select/textarea) -- sin
   esto hereda el tinte "jade" de --surface-2, pensado para superficies
   elevadas (switcher de negocio), y desentona junto a campos de texto planos. */
.auth-form .glass-select-trigger, .auth-form .glass-select-trigger:hover { background: var(--bg); }

/* Selector de código de país (phone-input.js): código a la izquierda con
   ancho fijo razonable, número de teléfono ocupa el resto. */
.phone-input { display: flex; gap: 8px; align-items: stretch; }
.phone-input .glass-select { flex: 0 0 168px; min-width: 0; }
.phone-input-numero { flex: 1 1 auto; min-width: 0; }
.glass-select-chevron { color:var(--muted); font-size:18px; line-height:1; transition:transform .18s var(--ease); }
.glass-select.open .glass-select-chevron { transform:rotate(180deg); }
/* position:fixed + z-index alto a propósito: glass-select.js porta este menú
   a <body> y lo posiciona con getBoundingClientRect() del trigger (ver
   posicionar() ahí). Cualquier tarjeta "glass" (backdrop-filter) que
   contenga el selector crea su propio contexto de apilamiento y atraparía
   un menú anidado sin importar su z-index interno -- vivir en <body> con
   position:fixed evita ese bug de raíz en cualquier lugar donde aparezca,
   incluso dentro de un modal (z-index:100). */
.glass-select-menu { position:fixed; z-index:1000; max-width:min(420px, calc(100vw - 32px)); display:grid; gap:3px; max-height:240px; padding:6px; overflow:auto; isolation:isolate; border:1px solid color-mix(in srgb,var(--border) 88%,var(--text) 12%); border-radius:14px; background:var(--bg); background-color:var(--bg); backdrop-filter:blur(calc(var(--glass-blur) + 6px)); -webkit-backdrop-filter:blur(calc(var(--glass-blur) + 6px)); box-shadow:0 18px 42px color-mix(in srgb,var(--shadow) 85%,transparent), inset 0 1px 0 rgba(255,255,255,.32); opacity:0; pointer-events:none; transform:translateY(-5px) scale(.98); transform-origin:top; transition:opacity .16s var(--ease), transform .16s var(--ease); }
.glass-select-menu.open { opacity:1; pointer-events:auto; transform:translateY(0) scale(1); }
.glass-select-option { display:flex; width:100%; align-items:center; min-height:36px; padding:9px 12px; border:0; border-radius:9px; color:var(--text); background:transparent; font:inherit; font-size:14px; text-align:left; white-space:normal; overflow-wrap:break-word; cursor:pointer; }
.glass-select-option:hover,.glass-select-option:focus-visible { outline:0; background:color-mix(in srgb,var(--accent) 12%,var(--surface-2)); }
.glass-select-option.selected { color:var(--accent); font-weight:650; background:color-mix(in srgb,var(--accent) 9%,transparent); }
.glass-select-option.selected::after { margin-left:auto; content:'✓'; font-size:13px; }
.glass-select-option { position: relative; z-index: 1; }

/* Superficies flotantes: el material conserva profundidad Glass, pero el
   contenido debe tener una base suficientemente sólida para no mezclarse
   con tablas, gráficas o tarjetas del dashboard. */
.dash-modal-overlay {
  background: color-mix(in srgb, var(--bg) 72%, var(--shadow) 28%);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.dash-modal {
  background: var(--bg);
  background-color: var(--bg);
  box-shadow: 0 24px 60px color-mix(in srgb, var(--shadow) 88%, transparent), inset 0 1px 0 rgba(255,255,255,.22);
}

/* Ficha CRM: bloques breves y legibles dentro de la capa Glass opaca. */
.dash-customer-detail,.dash-supplier-detail { max-width: 880px; }
.dash-custom-modal { max-width: 680px; }
.custom-request-detail { display: grid; gap: 13px; }
.custom-request-detail h3,.custom-request-detail p { margin: 0; }
.custom-request-detail section { padding: 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.custom-request-detail section h3 { margin: 0 0 6px; font-size: 14px; }
/* Fase 5: align-items:start (el default "stretch" de grid hacía que la
   sección más corta -- ej. Contactos con 0 items -- se estirara a la altura
   de su vecina, quedando un bloque gris vacío enorme; ver comentario de
   .store-empty más abajo, el mismo problema en dos capas). */
.customer-detail-columns,.supplier-detail-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; }
.customer-detail-columns > section,.supplier-detail-columns > section { min-width: 0; padding: 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.customer-detail-columns h3,.supplier-detail-columns h3 { margin: 0 0 12px; font-size: 15px; }
.customer-detail-item,.supplier-detail-item { padding: 10px 0; border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }
.customer-detail-item small,.supplier-detail-item small { display: block; margin-top: 3px; color: var(--muted); line-height: 1.45; }
.customer-notes { display: grid; max-height: 260px; overflow: auto; }
.customer-detail-columns .btn-ghost,.supplier-detail-columns .btn-ghost { width: auto; margin-top: 12px; }
.customer-detail-columns .auth-form,.supplier-detail-columns .auth-form { gap: 8px; margin-top: 12px; }
.customer-purchase-history { grid-column: 1 / -1; }
.customer-purchase-history .dash-table-wrap { margin-top: 8px; }
@media (max-width: 720px) { .customer-detail-columns,.supplier-detail-columns { grid-template-columns: 1fr; } }
/* .store-empty (línea 947) trae padding:40px 0 pensado para una pantalla
   entera vacía ("Todavía no hay pedidos...") -- reusarlo tal cual dentro de
   una sección de 300px de ancho dejaba ~80px de aire solo por el mensaje.
   Acá se compacta y alinea a la izquierda, coherente con el resto de la
   sección en vez de centrado como un estado vacío de página completa. */
.customer-detail-columns .store-empty,.supplier-detail-columns .store-empty { padding: 4px 0; text-align: left; }
/* Cabecera de la ficha (Fase 5): reemplaza el <p> con <br> -- la cantidad de
   <br> variaba según qué campos opcionales existieran (teléfono, fiscal),
   dejando un espaciado distinto cada vez. flex+gap da el mismo ritmo
   siempre, tenga el cliente 1 o 3 líneas de datos. */
.customer-detail-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 16px; }
.customer-detail-head .btn-ghost { width: fit-content; margin-top: 4px; }

/* Compras: líneas y recepción con el mismo material opaco y legible. */
.dash-purchase-modal { max-width: 940px; }
.purchase-lines-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 8px; }
.purchase-lines-head .btn-ghost { width: auto; margin: 0; }
.purchase-line-form { display: grid; grid-template-columns: minmax(190px, 1fr) 110px 150px auto; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.purchase-line-form input,.purchase-receipt-form input { min-width: 0; }
.purchase-receipt-form { margin-top: 16px; padding: 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.purchase-receipt-form h3 { margin: 0 0 10px; font-size: 16px; }
.purchase-receipt-form label small { color: var(--muted); }
@media (max-width: 720px) { .purchase-line-form { grid-template-columns: 1fr 1fr auto; } .purchase-line-form .glass-select { grid-column: 1 / -1; } }

/* Conteo físico: captura clara, sin exponer el saldo esperado durante el conteo. */
.dash-inventory-count-modal { max-width: 680px; }
.inventory-count-lines { display: grid; gap: 8px; max-height: 52vh; overflow: auto; padding-right: 2px; }
.inventory-count-line { display: grid; grid-template-columns: minmax(0, 1fr) 132px; align-items: center; gap: 12px; padding: 11px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); }
.inventory-count-line span { min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.inventory-count-line input { margin: 0; min-width: 0; }
.inventory-count-list { display: grid; gap: 8px; }
.inventory-count-list-item { display: grid; gap: 3px; width: 100%; padding: 14px; border: 1px solid var(--border); border-radius: 12px; color: var(--text); background: var(--surface-2); font: inherit; text-align: left; cursor: pointer; }
.inventory-count-list-item:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 7%, var(--surface-2)); }
.inventory-count-list-item small { color: var(--muted); overflow-wrap: anywhere; }
@media (max-width: 520px) { .inventory-count-line { grid-template-columns: 1fr; } }
@media (max-width: 720px) { .ds-preview-grid { grid-template-columns:1fr; } .ds-preview-card-wide { grid-column:auto; } .ds-demo-switcher { grid-template-columns:1fr; } .ds-demo-switcher label { margin-top:4px; } .ds-kpis { grid-template-columns:1fr; } .ds-pos-line { grid-template-columns:1fr auto; } .ds-pos-line > strong { grid-column:1 / -1; } }
.dash-nav-link {
  transition: color .22s ease, background-color .28s ease, border-color .28s ease,
    box-shadow .28s ease, transform .22s cubic-bezier(.16, 1, .3, 1);
  border: 1px solid transparent;
  will-change: transform, background-color;
}

.dash-nav-link:hover {
  border-color: color-mix(in srgb, var(--border) 72%, transparent);
  transform: translateX(2px);
}

.dash-nav-link:active {
  transform: translateX(1px) scale(.985);
}

.dash-nav-link.active {
  border-color: color-mix(in srgb, var(--accent) 22%, var(--border));
  box-shadow: inset 3px 0 0 var(--accent), 0 5px 16px color-mix(in srgb, var(--accent) 10%, transparent);
}

.dash-nav-group-toggle {
  transition: color .22s ease, background-color .28s ease, border-color .28s ease,
    transform .22s cubic-bezier(.16, 1, .3, 1);
}

.dash-nav-group-toggle:active {
  transform: scale(.985);
}

@media (prefers-reduced-motion: reduce) {
  .dash-nav-link,
  .dash-nav-group-toggle {
    transition: none;
    transform: none;
  }
}

/* Acciones Glass: misma respuesta en botones principales, secundarios y
   controles compactos del dashboard. */
.btn-jade,
.btn-ghost,
.dash-icon-btn,
.pos-qty-btn,
.pos-linea-quitar {
  transition: color .22s ease, background-color .24s ease, border-color .24s ease,
    box-shadow .24s ease, transform .22s cubic-bezier(.16, 1, .3, 1);
}

.btn-jade:hover,
.btn-ghost:hover,
.dash-icon-btn:hover,
.pos-qty-btn:hover,
.pos-linea-quitar:hover {
  transform: translateY(-1px);
}

.btn-jade:active,
.btn-ghost:active,
.dash-icon-btn:active,
.pos-qty-btn:active,
.pos-linea-quitar:active {
  transform: scale(.97);
}

.btn-jade:focus-visible,
.btn-ghost:focus-visible,
.dash-icon-btn:focus-visible,
.pos-qty-btn:focus-visible,
.pos-linea-quitar:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .btn-jade,
  .btn-ghost,
  .dash-icon-btn,
  .pos-qty-btn,
  .pos-linea-quitar {
    transition: none;
    transform: none;
  }
}
/* Tienda: controles compactos para identidad y archivos, con superficies
   opacas suficientes para leerse sobre el fondo Glass. */
.store-brand-color { display:flex; align-items:center; flex-wrap:wrap; gap:10px; min-height:44px; }
.store-brand-color input[type="color"] { width:44px; height:44px; padding:3px; border-radius:12px; cursor:pointer; }
.store-brand-color input[type="text"], .store-brand-color input:not([type]) { width:96px; text-transform:uppercase; }
.store-color-swatches { display:flex; gap:7px; flex-wrap:wrap; }
.store-color-swatch { width:26px; height:26px; border:2px solid color-mix(in srgb, var(--border) 78%, transparent); background:var(--swatch); border-radius:50%; padding:0; cursor:pointer; box-shadow:0 1px 3px rgba(0,0,0,.12); transition:transform .18s ease, box-shadow .18s ease; }
.store-color-swatch:hover, .store-color-swatch.active { transform:scale(1.12); box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.store-asset-upload, .store-documents { border:1px solid var(--border); border-radius:16px; padding:16px; background:color-mix(in srgb, var(--surface) 88%, transparent); display:grid; grid-template-columns:minmax(150px,1fr) minmax(220px,1.2fr) auto; gap:12px; align-items:center; }
/* .dash-form-grid tiene row-gap:0 -- sin esto, la caja (con su propio
   borde redondeado) queda pegada al texto de ayuda de arriba (ej.
   "Stock mínimo" en Productos) o al selector de color en Tienda, dando
   la sensación de que el borde corta el texto. Mismo margen que ya usa
   .auth-form label entre campos, para que se vea como un campo más. */
.store-asset-upload { margin-top:14px; }
.store-asset-upload p { margin:4px 0 0; }
.store-asset-upload-actions { position:relative; display:grid; grid-template-columns:max-content max-content; gap:7px 8px; align-items:center; }
.store-asset-upload-actions .store-meta { grid-column:1 / -1; }
/* .store-asset-pick es un <label> dentro de .auth-form -- ".auth-form
   label" (font-size:13px, margin-top:14px) le gana en especificidad a
   .btn-ghost porque combina clase+tipo. Sin esto, "Elegir imagen" salía
   con otra tipografía y un margen que "Quitar" (un <button>, no
   alcanzado por esa regla) no tenía, y los dos terminaban de alto y
   posición distintos pese a compartir .btn-ghost. */
.store-asset-upload-actions .store-asset-pick { font-size:14px; font-weight:600; margin-top:0; }
.store-asset-file { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; }
.store-asset-file:focus-visible + .store-asset-pick { outline:3px solid color-mix(in srgb, var(--accent) 38%, transparent); outline-offset:2px; }
.store-asset-pick { display:inline-flex; align-items:center; justify-content:center; min-height:40px; margin:0; cursor:pointer; }
.store-asset-pick:hover { transform:translateY(-1px); }
.store-asset-preview { display:grid; place-items:center; width:84px; height:84px; overflow:hidden; border:1px dashed var(--border); border-radius:14px; background:var(--surface); color:var(--muted); font-size:12px; }
.store-asset-preview img { display:block; width:100%; height:100%; object-fit:cover; }
.store-asset-preview img[hidden] { display:none; }
/* .store-asset-remove es <button class="btn-ghost is-danger" ... [hidden]> --
   .btn-ghost ya fija display:inline-flex con la misma especificidad que la
   regla [hidden] del user-agent, y una regla de autor le gana a la del UA
   aunque empate en especificidad -- sin esto, "Quitar" quedaba visible
   incluso sin imagen (encontrado al construir el catálogo de Fase 2 con el
   componente real en vez de una demo estática). */
.store-asset-remove[hidden] { display:none; }
.store-asset-preview-logo img { object-fit:contain; padding:6px; }
.store-asset-preview-cover { width:160px; aspect-ratio:8 / 3; height:auto; }
.store-asset-preview-cover img { object-fit:cover; }
.store-documents { display:block; margin-top:18px; }
.store-documents h2 { margin:0 0 6px; font-size:18px; }
.store-documents > input { margin:8px 0; }
.store-document-list { display:grid; gap:8px; margin-top:12px; }
.store-document-row { display:flex; justify-content:space-between; gap:12px; align-items:center; padding:10px 0; border-top:1px solid var(--border); }
.store-document-row span { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.store-document-row small { color:var(--muted); }
@media (max-width: 640px) { .store-asset-upload { grid-template-columns:1fr; } .store-asset-preview, .store-asset-preview-cover { width:100%; height:120px; } .store-document-row { align-items:flex-start; flex-direction:column; } }
/* El grid de 3 columnas (mín. ~478px) asume el ancho completo de
   .dash-panel (Tienda). Dentro de .dash-modal (480px, ~424px útiles tras
   el padding) no entra: se ve apretado y con los botones desalineados
   (Productos/Servicios/Menú digital reusan el mismo AstrcAssetUpload).
   Mismo layout apilado que ya usa el breakpoint móvil de arriba, pero acá
   activado por el contenedor angosto, no por el viewport. */
.dash-modal .store-asset-upload { grid-template-columns:1fr; }
.dash-modal .store-asset-preview,
.dash-modal .store-asset-preview-cover { width:100%; height:120px; }

/* Resumen: guía corta para que el dueño complete la puesta en marcha sin SQL. */
.dash-onboarding { margin-bottom:18px; padding:18px; border:1px solid color-mix(in srgb, var(--accent) 30%, var(--border)); border-radius:18px; background:color-mix(in srgb, var(--surface) 94%, var(--accent) 6%); }
.dash-onboarding.is-complete { border-color:color-mix(in srgb, var(--status-good) 42%, var(--border)); }
.dash-onboarding-head { display:flex; align-items:flex-start; justify-content:space-between; gap:18px; }
.dash-onboarding-head h2 { margin:2px 0 3px; font-size:20px; }
.dash-onboarding-head p { margin:0; color:var(--muted); font-size:13px; }
.dash-onboarding-head > strong { flex:0 0 auto; color:var(--accent); font-size:22px; font-variant-numeric:tabular-nums; }
.dash-onboarding-eyebrow { color:var(--accent); font-size:11px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; }
.dash-onboarding-progress { height:6px; margin:14px 0; overflow:hidden; border-radius:999px; background:color-mix(in srgb, var(--border) 75%, transparent); }
.dash-onboarding-progress span { display:block; height:100%; border-radius:inherit; background:var(--accent); transition:width .35s ease; }
.dash-onboarding.is-complete .dash-onboarding-progress span { background:var(--status-good); }
.dash-onboarding-steps { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px 14px; margin:0; padding:0; list-style:none; }
.dash-onboarding-steps li { display:flex; align-items:center; gap:8px; min-width:0; color:var(--muted); font-size:13px; }
.dash-onboarding-steps li > span:first-child { display:grid; place-items:center; flex:0 0 22px; width:22px; height:22px; border:1px solid var(--border); border-radius:50%; font-weight:800; }
.dash-onboarding-steps li.is-done { color:var(--text); }
.dash-onboarding-steps li.is-done > span:first-child { border-color:color-mix(in srgb, var(--status-good) 45%, transparent); background:color-mix(in srgb, var(--status-good) 16%, transparent); color:var(--status-good); }
.dash-onboarding-steps li.is-unknown { opacity:.72; }
.dash-onboarding-steps small { display:block; margin-top:1px; }
.dash-onboarding-next { display:inline-flex; width:auto; min-height:40px; margin-top:16px; align-items:center; justify-content:center; }
@media (prefers-reduced-motion: reduce) { .dash-onboarding-progress span { transition:none; } }
@media (max-width:640px) { .dash-onboarding { padding:15px; } .dash-onboarding-steps { grid-template-columns:1fr; } .dash-onboarding-next { width:100%; } }
