/* =========================================================================
   QUOMYA — APP SHELL V1
   Wave: S4.2 (app shell + navigation + responsive foundation)
   Depends on: qy-tokens-v1.css, qy-foundation-v1.css

   Armazón de aplicación: barra lateral de escritorio, menú inferior de móvil,
   contenedor de contenido y cabecera de página. NADA de contenido de pantalla.

   ------------------------------------------------------------------------
   MÓVIL PRIMERO
   ------------------------------------------------------------------------
   Todo lo de fuera de una @media es el estado MÓVIL. La barra lateral solo
   aparece cuando hay sitio real para ella. Quomya no es un escritorio
   encogido: el móvil es donde se registra una venta en la calle.

   ------------------------------------------------------------------------
   PUNTO DE RUPTURA: 1024px  (medido, no heredado de un framework)
   ------------------------------------------------------------------------
   La barra lateral ocupa 280px. Por debajo de 1024px el contenido restante
   cae por debajo de ~740px, que es donde las tablas de Registro y los ejes de
   Evolución empiezan a comprimirse. Además 768-1023px es territorio de tablet
   en vertical, un dispositivo táctil que se sirve mejor con el menú inferior.
   Por eso el cruce es 1024 y no 768.

   ------------------------------------------------------------------------
   APILADO
   ------------------------------------------------------------------------
   Deliberadamente NO se declara `z-index` sobre `.bottom-nav`: su valor
   ganador ya lo fija `quomya-visual-system.css` y hay una prueba que compara
   ese número con el del aviso emergente. Introducir aquí un valor -- y menos
   aún un `var()`, que no es numérico -- rompería esa comparación.
   ========================================================================= */

/* =========================================================================
   ARMAZÓN
   ========================================================================= */

/*
   ÁMBITO DEL TEMA — decisión medida, no estética.

   `qy-theme` se aplica al CROMO del armazón (barra lateral, cabecera, menú
   inferior, hoja "Más") y NUNCA a `#view-root`.

   Se probó lo contrario: con el tema envolviendo también el contenido, una
   auditoría de contraste sobre las seis rutas encontró 35 combinaciones por
   debajo de AA y algunas en 1.34:1 -- ilegibles. La causa no es el tema, son
   las pantallas heredadas: pintan fondos claros a mano (`#e2e8f0` y
   parecidos) mientras su texto sí sigue el token, que en oscuro es claro.
   Resultado: claro sobre claro.

   Arreglarlo exigiría reescribir el interior de cada pantalla, que es
   justamente lo que S4.3-S4.8 tienen asignado. Así que el contenido heredado
   se queda exactamente como se renderiza hoy hasta que le toque su ola. El
   marco es Deep Ink; el contenido, todavía no. La inconsistencia es visible a
   propósito: marca lo que falta por migrar.

   El fondo usa el token directamente porque los tokens L1 son globales; solo
   los alias legados están acotados.
*/
.qy-shell {
  display: flex;
  align-items: flex-start;
  width: 100%;
  min-height: 100dvh;
  background: var(--qy-color-bg);
}

/*
   La columna de contenido conserva la clase `.app-shell` porque
   `scrollFix.js` la consulta y varias hojas heredadas la estilan. Lo que se
   neutraliza aquí es solo su GEOMETRÍA heredada: ancho máximo de 760px,
   centrado y relleno inferior pensados para un producto sin barra lateral.

   Los `!important` son intencionados y acotados: `compact-visual-v15-14-2.css`
   declara `padding-*: … !important` sobre `.app-shell`, y sin igualar la
   marca no habría forma de recuperar la geometría del armazón. Desaparecerán
   cuando esa hoja se retire en una ola posterior.
*/
.qy-shell__main {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  max-width: none;
  margin: 0;
  padding-left: var(--qy-pad-mobile) !important;
  padding-right: var(--qy-pad-mobile) !important;
  padding-bottom: calc(
    var(--qy-bottom-nav-h) + var(--qy-safe-bottom) + var(--qy-space-6)
  ) !important;
}

/* El contenido se centra dentro de la columna, no la columna dentro de la
   ventana: así la barra lateral no descentra la lectura. */
.qy-shell__main > #view-root {
  width: 100%;
  max-width: var(--qy-content-max);
  margin-inline: auto;
}

/*
   ESPACIO SUPERIOR EN MÓVIL (S4.11A, fase 3).

   Hasta ahora la columna no declaraba relleno superior: quien separaba el
   contenido del borde de la pantalla era la cabecera de marca, que aportaba
   entre 96 y 120 px a 390 px de ancho. Al retirarla hacía falta declarar ese
   espacio de forma explícita, y esa es justamente la ocasión de reducirlo a
   lo que hace falta en vez de heredar lo que sobraba.

   `--qy-safe-top` es obligatorio y NO es decoración: en un iPhone con la
   aplicación instalada, `viewport-fit=cover` mete el contenido bajo la barra
   de estado. Sin el inset, el antetítulo de cada pantalla quedaría debajo de
   la hora. Fuera de ese contexto `env()` vale 0 y la expresión se reduce al
   espacio base.

   Se resuelve con relleno real, nunca con márgenes negativos: un margen
   negativo no reduce espacio muerto, mueve contenido bajo lo que tenga
   encima, que es exactamente cómo se producen las colisiones con la barra de
   estado.
*/
.qy-shell__main {
  padding-top: calc(var(--qy-safe-top) + var(--qy-space-2));
}

.qy-skip-link {
  position: absolute;
  top: var(--qy-space-2);
  left: var(--qy-space-2);
  z-index: 900;
  padding: var(--qy-space-3) var(--qy-space-4);
  font: var(--qy-text-label-md);
  letter-spacing: var(--qy-tracking-label);
  color: var(--qy-color-text-on-brand);
  background: var(--qy-color-brand);
  border-radius: var(--qy-radius-md);
  transform: translateY(-200%);
}

.qy-skip-link:focus-visible {
  transform: none;
  outline: none;
  box-shadow: var(--qy-focus-ring);
}

/* =========================================================================
   CABECERA HEREDADA DENTRO DEL ARMAZÓN — RETIRADA EN S4.11A

   Aquí vivían las reglas que revestían `<header class="app-header">` dentro
   del armazón: fondo transparente, tinta secundaria en el lema y la píldora
   "Beta" recoloreada para alcanzar AA sobre Deep Ink.

   S4.11A retira ese nodo de `index.html` -- la banda de marca repetida en
   cada ruta interna que el propietario pidió eliminar --, así que las reglas
   se van con él en lugar de quedarse como selectores sin elemento. La
   identidad pasa a la barra lateral (escritorio) y a la pantalla de acceso.

   Las hojas heredadas que también estilan `.app-header` (brand-logos,
   brand-phase-1, compact-visual) NO se tocan: siguen siendo correctas para su
   propio contexto y simplemente ya no encuentran nodo.
   ========================================================================= */

/* =========================================================================
   CABECERA DE PÁGINA (patrón reutilizable, sin contenido de pantalla)
   ========================================================================= */

/*
   S4.11A: el relleno superior baja de 24 px a 12 px en móvil.

   Ese valor se calibró cuando la cabecera de marca iba encima y hacía de
   separador; sin ella, 24 px sobre el relleno del armazón dejaba el
   antetítulo flotando. En escritorio se recupera holgura más abajo, en la
   consulta de 1024 px, donde el espacio no es un recurso escaso.

   El patrón en sí no cambia: antetítulo de contexto, título de sección,
   línea secundaria opcional y acción opcional. Es la cabecera que sustituye
   a la banda de marca repetida.
*/
.qy-page-header {
  display: grid;
  gap: var(--qy-space-2);
  padding-block: var(--qy-space-3) var(--qy-space-5);
}

.qy-page-header__eyebrow {
  margin: 0;
  font: var(--qy-text-label-md);
  letter-spacing: var(--qy-tracking-label);
  text-transform: uppercase;
  color: var(--qy-color-text-tertiary);
}

.qy-page-header__title {
  margin: 0;
  font: var(--qy-text-headline-lg);
  letter-spacing: var(--qy-tracking-tight);
  color: var(--qy-color-text-primary);
}

.qy-page-header__subtitle {
  margin: 0;
  font: var(--qy-text-body-md);
  color: var(--qy-color-text-secondary);
}

.qy-page-header__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--qy-space-3);
  padding-top: var(--qy-space-2);
}

/*
   BANDA DE TÍTULO HEREDADA.

   Las pantallas actuales abren con `.personal-page-heading` o `.screen-header`:
   una fecha y un `<h2>` SIN fondo propio. Antes se apoyaban en el fondo claro
   de la página; ahora se apoyan en el marco Deep Ink, y su tinta oscura
   heredada quedaba ilegible -- lo detectó la auditoría de contraste, no la
   vista.

   Esa banda es cabecera de página, es decir, armazón (fase 8), no interior de
   pantalla: colorearla aquí no es migrar una pantalla. Se toca únicamente el
   color del título y su antetítulo; ni la maquetación, ni el tamaño, ni nada
   dentro de las tarjetas, que conservan su fondo claro y su tinta oscura.
*/
.qy-shell__main #view-root > .screen > .personal-page-heading > div > h2,
.qy-shell__main #view-root > .screen > .screen-header > h2,
.qy-shell__main #view-root > .screen > .screen-header > div > h2 {
  color: var(--qy-color-text-primary);
}

.qy-shell__main #view-root > .screen > .personal-page-heading > div > span,
.qy-shell__main #view-root > .screen > .screen-header > p,
.qy-shell__main #view-root > .screen > .screen-header > div > span {
  color: var(--qy-color-text-secondary);
}

/* =========================================================================
   ELEMENTO DE NAVEGACIÓN (compartido por barra lateral y hoja "Más")
   ========================================================================= */

.qy-nav-item {
  display: flex;
  align-items: center;
  gap: var(--qy-space-3);
  width: 100%;
  min-height: var(--qy-touch-min);
  padding: var(--qy-space-3) var(--qy-space-4);
  font: var(--qy-text-body-md);
  font-weight: 500;
  color: var(--qy-color-text-secondary);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--qy-radius-md);
  cursor: pointer;
  text-align: left;
  transition: background var(--qy-motion-fast) var(--qy-motion-ease),
    color var(--qy-motion-fast) var(--qy-motion-ease);
}

.qy-nav-item:hover {
  color: var(--qy-color-text-primary);
  background: var(--qy-color-hover);
}

.qy-nav-item:focus-visible {
  outline: none;
  box-shadow: var(--qy-focus-ring);
}

/*
   Estado activo con TRES señales, no solo color: fondo teñido, peso
   tipográfico y una barra lateral sólida. Sigue siendo legible en monocromo
   y para quien no distingue el turquesa.
*/
.qy-nav-item.is-active {
  position: relative;
  font-weight: 700;
  color: var(--qy-color-brand-text);
  background: var(--qy-color-brand-soft);
}

.qy-nav-item.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 60%;
  background: var(--qy-color-brand);
  border-radius: var(--qy-radius-pill);
  transform: translateY(-50%);
}

/* =========================================================================
   ICONOS DE NAVEGACIÓN

   El repositorio ya dibuja los iconos del menú con `mask-image` y un SVG en
   data-URI, coloreados por `background-color: currentColor`. Se sigue ese
   sistema en lugar de introducir otro.

   No se usan caracteres Unicode: se comprobó contra el `cmap` de la fuente que
   ◧ ▥ ☰ ▦ ◎ ⚙ ⋯ ⌂ NO existen en Plus Jakarta Sans. Como glifos caerían en
   fuente de reserva y se verían como cuadros.

   Las cinco rutas que ya tenían máscara conservan su dibujo exacto para que
   la barra lateral y el menú inferior muestren el mismo icono. Se añaden las
   tres que faltaban: nueva venta, objetivos y "Más".
   ========================================================================= */

:root {
  --qy-icon-dashboard: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 11.2 12 4l8 7.2V20H7a3 3 0 0 1-3-3v-5.8Z' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M9.5 20v-5h5v5' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --qy-icon-history: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 6h14M5 12h14M5 18h9' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3Ccircle cx='18' cy='18' r='2' fill='none' stroke='black' stroke-width='1.8'/%3E%3C/svg%3E");
  --qy-icon-calendar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='4' y='5.5' width='16' height='14.5' rx='3' fill='none' stroke='black' stroke-width='1.8'/%3E%3Cpath d='M8 3.5v4M16 3.5v4M4 10h16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  --qy-icon-charts: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 19V9M12 19V5M19 19v-7' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3Cpath d='M3.5 19.5h17' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  --qy-icon-settings: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='3' fill='none' stroke='black' stroke-width='1.8'/%3E%3Cpath d='M12 3v2.2M12 18.8V21M4.2 7.5l1.9 1.1M17.9 15.4l1.9 1.1M4.2 16.5l1.9-1.1M17.9 8.6l1.9-1.1' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  --qy-icon-objectives: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='8' fill='none' stroke='black' stroke-width='1.8'/%3E%3Ccircle cx='12' cy='12' r='3.4' fill='none' stroke='black' stroke-width='1.8'/%3E%3C/svg%3E");
  --qy-icon-sales: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 5v14M5 12h14' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E");
  --qy-icon-more: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='5.5' cy='12' r='1.7' fill='black'/%3E%3Ccircle cx='12' cy='12' r='1.7' fill='black'/%3E%3Ccircle cx='18.5' cy='12' r='1.7' fill='black'/%3E%3C/svg%3E");
}

.qy-nav-item__icon,
.qy-sidebar__cta-icon {
  flex: none;
  display: block;
  width: 22px;
  height: 22px;
  background-color: currentColor;
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: 21px 21px;
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: 21px 21px;
}

.qy-nav-item[data-route="dashboard"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-dashboard);
  mask-image: var(--qy-icon-dashboard);
}

.qy-nav-item[data-route="charts"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-charts);
  mask-image: var(--qy-icon-charts);
}

.qy-nav-item[data-route="history"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-history);
  mask-image: var(--qy-icon-history);
}

.qy-nav-item[data-route="calendar"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-calendar);
  mask-image: var(--qy-icon-calendar);
}

.qy-nav-item[data-route="objectives"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-objectives);
  mask-image: var(--qy-icon-objectives);
}

.qy-nav-item[data-route="settings"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-settings);
  mask-image: var(--qy-icon-settings);
}

.qy-sidebar__cta-icon {
  -webkit-mask-image: var(--qy-icon-sales);
  mask-image: var(--qy-icon-sales);
}

/*
   Rutas del menú inferior que el sistema heredado nunca tuvo que dibujar:
   no existía entrada de venta, ni de objetivos, ni un disparador "Más". Sin
   máscara, la regla heredada `background-color: currentColor` las pintaba
   como un cuadrado macizo.
*/
.bottom-nav [data-route="sales"] .nav-icon {
  -webkit-mask-image: var(--qy-icon-sales);
  mask-image: var(--qy-icon-sales);
}

.bottom-nav [data-route="objectives"] .nav-icon {
  -webkit-mask-image: var(--qy-icon-objectives);
  mask-image: var(--qy-icon-objectives);
}

/* S4.11A: "Más" ya no es un disparador sin ruta, es `data-route="more"`. */
.bottom-nav [data-route="more"] .nav-icon,
.qy-nav-item[data-route="more"] .qy-nav-item__icon {
  -webkit-mask-image: var(--qy-icon-more);
  mask-image: var(--qy-icon-more);
}

/* =========================================================================
   BARRA LATERAL DE ESCRITORIO

   Oculta en móvil. `display` se controla en la consulta de 1024px; el
   atributo `hidden` que gestiona `sessionChrome` sigue mandando por encima.
   ========================================================================= */

.qy-sidebar {
  display: none;
}

.qy-sidebar[hidden] {
  display: none !important;
}

.qy-sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--qy-space-3);
  padding: var(--qy-space-2) var(--qy-space-4) var(--qy-space-6);
}

.qy-sidebar__logo {
  width: 30px;
  height: 30px;
}

.qy-sidebar__wordmark {
  font: var(--qy-text-headline-md);
  letter-spacing: var(--qy-tracking-tight);
  color: var(--qy-color-text-primary);
}

/*
   El distintivo de beta bajaba antes en la cabecera repetida. Se conserva --
   sigue siendo información cierta y relevante -- pero pasa a mostrarse UNA
   vez, junto a la marca, y no una vez por pantalla.
*/
.qy-sidebar__badge {
  padding: 2px var(--qy-space-2);
  font: var(--qy-text-label-md);
  letter-spacing: var(--qy-tracking-label);
  text-transform: uppercase;
  color: var(--qy-color-brand-text);
  background: var(--qy-color-brand-soft);
  border: 1px solid var(--qy-color-brand);
  border-radius: var(--qy-radius-pill);
}

.qy-sidebar__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--qy-space-2);
  width: 100%;
  min-height: var(--qy-touch-min);
  margin-bottom: var(--qy-space-6);
  padding: 0 var(--qy-space-4);
  font: var(--qy-text-body-md);
  font-weight: 700;
  color: var(--qy-color-text-on-brand);
  background: var(--qy-color-brand);
  border: 1px solid transparent;
  border-radius: var(--qy-radius-md);
  cursor: pointer;
  transition: background var(--qy-motion-fast) var(--qy-motion-ease);
}

.qy-sidebar__cta:hover {
  background: var(--qy-color-brand-hover);
}

.qy-sidebar__cta:active {
  background: var(--qy-color-brand-deep);
}

.qy-sidebar__cta:focus-visible {
  outline: none;
  box-shadow: var(--qy-focus-ring);
}

.qy-sidebar__cta-icon {
  font-size: 18px;
  line-height: 1;
}

.qy-sidebar__list {
  display: grid;
  gap: var(--qy-space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* =========================================================================
   MENÚ INFERIOR DE MÓVIL

   Se reestiliza el elemento existente. Cinco objetivos táctiles a 390px dan
   ~78px cada uno, muy por encima del mínimo de 48px, y el pulgar alcanza
   todos sin recolocar la mano.
   ========================================================================= */

/*
   `brand-phase-1` y `compact-visual` fijan
   `background: rgba(255,255,255,.96/.97) !important` sobre `.bottom-nav`.
   Sin igualar la marca, el menú se quedaría blanco bajo el marco Deep Ink.
*/
.bottom-nav.qy-theme {
  padding-bottom: var(--qy-safe-bottom);
  background: var(--qy-color-surface-1) !important;
  border-top: 1px solid var(--qy-color-border);
}

.bottom-nav.qy-theme .bottom-nav-item {
  min-height: var(--qy-touch-min);
  color: var(--qy-color-text-tertiary);
  background: transparent;
  border: none;
  transition: color var(--qy-motion-fast) var(--qy-motion-ease);
}

.bottom-nav.qy-theme .bottom-nav-item small {
  font: var(--qy-text-label-md);
  letter-spacing: 0;
  text-transform: none;
}

.bottom-nav.qy-theme .bottom-nav-item:focus-visible {
  outline: none;
  box-shadow: var(--qy-focus-ring);
}

/* Activo: color + peso + punto indicador. Nunca solo color. */
.bottom-nav.qy-theme .bottom-nav-item.is-active {
  position: relative;
  color: var(--qy-color-brand-text);
}

.bottom-nav.qy-theme .bottom-nav-item.is-active small {
  font-weight: 700;
}

.bottom-nav.qy-theme .bottom-nav-item.is-active::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 50%;
  width: 5px;
  height: 5px;
  background: var(--qy-color-brand);
  border-radius: var(--qy-radius-pill);
  transform: translateX(-50%);
}

/*
   `home-workspace.css` y `personal-order.css` ocultan
   `.bottom-nav [data-route="sales"]` con `display: none !important`. Era una
   regla defensiva de cuando el menú no tenía una entrada de venta: no existía
   y se blindaba por si aparecía.

   Ahora la acción primaria de móvil ES esa ruta, así que hay que recuperarla.
   El override se acota al elemento CTA -- nunca al menú entero -- para no
   tocar las reglas que sí deben seguir ocultándolo, como `restricted-mode` o
   `modal-ui-open`. `grid` iguala el display que el resto de posiciones ya
   reciben del CSS heredado.
*/
.bottom-nav.qy-theme .bottom-nav-item--cta[data-route="sales"] {
  display: grid !important;
}

/*
   Acción primaria central: alcanzable con el pulgar en una mano.

   El disco turquesa NO puede ir en `.nav-icon`: ese elemento es la máscara y
   su `background-color` es la tinta del icono. Se dibuja con `::before`, y el
   icono se recorta encima.
*/
.bottom-nav.qy-theme .bottom-nav-item--cta {
  position: relative;
  color: var(--qy-color-text-primary);
}

.bottom-nav.qy-theme .bottom-nav-item--cta .nav-icon {
  position: relative;
  z-index: 1;
  margin-inline: auto;
  color: var(--qy-color-text-on-brand);
  background-color: var(--qy-color-text-on-brand);
}

.bottom-nav.qy-theme .bottom-nav-item--cta::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 50%;
  width: 38px;
  height: 38px;
  background: var(--qy-color-brand);
  border-radius: var(--qy-radius-pill);
  transform: translateX(-50%);
}

.bottom-nav.qy-theme .bottom-nav-item--cta.is-active::after {
  content: none;
}

/* =========================================================================
   HOJA "MÁS" — RETIRADA EN S4.11A

   Aquí vivía el diálogo inferior: posición fija, telón, panel deslizante,
   título y botón de cerrar. El propietario lo revisó en móvil real y lo
   describió como provisional -- un panel corto flotando sobre una pantalla
   mayoritariamente negra --, así que "Más" ha pasado a ser una ruta completa.

   Su revestimiento vive ahora en qy-ia-v1.css, junto al resto de la
   arquitectura de información de esta ola, y su comportamiento ha dejado de
   necesitar código: es navegación normal.
   ========================================================================= */

/* =========================================================================
   ESCRITORIO — 1024px

   Aparece la barra lateral, desaparece el menú inferior y el contenido
   recupera el relleno inferior normal.
   ========================================================================= */

@media (min-width: 1024px) {
  .qy-sidebar:not([hidden]) {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    flex: none;
    width: var(--qy-sidebar-width);
    height: 100dvh;
    padding: calc(var(--qy-space-6) + var(--qy-safe-top)) var(--qy-space-4)
      var(--qy-space-6);
    background: var(--qy-color-surface-1);
    border-right: 1px solid var(--qy-color-border);
    overflow-y: auto;
  }

  .qy-shell__main {
    padding-top: var(--qy-space-4);
    padding-left: var(--qy-pad-desktop) !important;
    padding-right: var(--qy-pad-desktop) !important;
    padding-bottom: var(--qy-space-12) !important;
  }

  /* En escritorio el espacio no es escaso: la cabecera de página recupera
     holgura sin que eso afecte al alto útil de un móvil. */
  .qy-page-header {
    padding-block: var(--qy-space-6) var(--qy-space-5);
  }

  .bottom-nav.qy-theme {
    display: none !important;
  }
}

/* =========================================================================
   MÓVIL ESTRECHO — 360px y menos

   Las etiquetas de cinco posiciones dejan de caber cómodamente. Se reducen
   sin tocar el objetivo táctil, que sigue por encima del mínimo.
   ========================================================================= */

@media (max-width: 360px) {
  .bottom-nav.qy-theme .bottom-nav-item small {
    font-size: 10px;
  }

  .qy-shell__main {
    padding-left: var(--qy-space-3) !important;
    padding-right: var(--qy-space-3) !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .qy-nav-item,
  .qy-sidebar__cta,
  .bottom-nav.qy-theme .bottom-nav-item {
    transition: none;
  }
}

/* ==========================================================================
   S4.11B — BOTTOM NAV Y TECLADO

   La barra usa el borde inferior real de la ventana. No se reposiciona con la
   altura del teclado ni se convierte en una segunda superficie flotante. Cuando
   un campo de Nueva Venta tiene el foco, se oculta temporalmente para que el
   teclado pueda ocupar su espacio y el body conserve el scroll normal.
   ========================================================================== */

.bottom-nav.qy-theme {
  bottom: 0 !important;
  left: 0 !important;
  right: 0 !important;
  width: 100% !important;
  max-width: none !important;
  transform: none !important;
  border-radius: 0 !important;
}

.bottom-nav.qy-theme .bottom-nav-item {
  overflow: visible;
}

.bottom-nav.qy-theme .bottom-nav-item small {
  overflow: visible;
  text-overflow: clip;
}

/* Los desplazamientos compensatorios que S4.11B aplicaba aquí
   (`padding-top: 23px`, `justify-content: flex-start`, `::before { top: 1px }`)
   se retiran en S4.11D: la acción central pasa a ser concéntrica por
   construcción y ya no hay nada que compensar. Ver el bloque S4.11D al final
   de esta hoja. */

@supports selector(body:has(*)) {
  body:has(.qy-sales-screen input:focus, .qy-sales-screen textarea:focus, .qy-sales-screen select:focus) .bottom-nav.qy-theme {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bottom-nav.qy-theme .bottom-nav-item {
    transition: none;
  }
}

/* ==========================================================================
   S4.11C — LENGUAJE GLOBAL DE ORIENTACIÓN, PROFUNDIDAD Y MOVIMIENTO

   La cabecera compacta conserva su altura y gana una señal de contexto. Las
   superficies principales comparten luz superior y elevación semántica; la
   entrada de ruta usa un único gesto breve de opacidad/desplazamiento.
   ========================================================================== */

#view-root > .screen.qy-theme {
  animation: qy-route-enter-s4-11c var(--qy-motion-base) var(--qy-motion-ease) both;
}

.screen.qy-theme > .qy-page-header {
  position: relative;
  padding-left: var(--qy-space-4);
}

.screen.qy-theme > .qy-page-header::before {
  position: absolute;
  top: var(--qy-space-3);
  bottom: var(--qy-space-5);
  left: 0;
  width: 3px;
  border-radius: var(--qy-radius-pill);
  background: linear-gradient(180deg, var(--qy-color-brand), var(--qy-color-brand-deep));
  content: "";
}

.screen.qy-theme > .qy-dashboard-panel {
  box-shadow:
    0 1px 0 var(--qy-color-surface-highlight) inset,
    var(--qy-elevation-card);
}

.screen.qy-theme :is(
  .qy-btn,
  .qy-nav-item,
  .bottom-nav-item,
  .secondary-btn,
  .qy-quiet-action
) {
  transition:
    transform var(--qy-motion-fast) var(--qy-motion-ease),
    background-color var(--qy-motion-fast) var(--qy-motion-ease),
    border-color var(--qy-motion-fast) var(--qy-motion-ease),
    color var(--qy-motion-fast) var(--qy-motion-ease);
}

@media (hover: hover) and (pointer: fine) {
  .screen.qy-theme :is(
    .qy-btn,
    .secondary-btn,
    .qy-quiet-action
  ):not(:disabled):hover {
    transform: translateY(-1px);
  }
}

@keyframes qy-route-enter-s4-11c {
  from {
    opacity: 0.72;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  #view-root > .screen.qy-theme {
    animation: none;
  }

  .screen.qy-theme :is(
    .qy-btn,
    .qy-nav-item,
    .bottom-nav-item,
    .secondary-btn,
    .qy-quiet-action
  ) {
    transition: none;
  }
}

/* ==========================================================================
   S4.11D — ACCIÓN CENTRAL "NUEVA": CONCÉNTRICA POR CONSTRUCCIÓN

   El propietario vio el "+" fuera del disco turquesa. No era un ajuste fino
   mal calibrado: eran DOS sistemas de posicionamiento distintos decidiendo
   cada uno por su cuenta dónde estaba el centro.

   - El disco lo dibujaba `::before` en posición ABSOLUTA (`top: 1px`,
     `left: 50%`), medido contra la caja del botón.
   - El "+" lo colocaba la REJILLA del botón, medido contra la primera fila
     de `grid-template-rows` después de `padding-top: 23px`.

   Centro del disco: 20px desde arriba. Centro del icono: 34px. Catorce
   píxeles de desajuste vertical. Y `justify-content: flex-start` -- heredado
   de S4.11B -- empujaba además la columna de la rejilla al borde izquierdo
   mientras el disco seguía centrado en `left: 50%`, así que el desajuste era
   también horizontal.

   La corrección no es otro desplazamiento compensatorio. Se elimina el
   segundo sistema: `::before` deja de ser absoluto y pasa a ser un ELEMENTO
   DE REJILLA en la misma celda (fila 1, columna 1) que `.nav-icon`. Con
   `place-items: center` -- que la barra ya declara -- dos elementos en la
   misma celda son concéntricos por definición, en cualquier ancho, con
   cualquier relleno y con cualquier tamaño de fuente. No queda ni un solo
   offset mágico que recalibrar.
   ========================================================================== */

.bottom-nav.qy-theme .bottom-nav-item--cta {
  /* Se revierte el relleno compensatorio de S4.11B: ya no hay nada que
     compensar. La fila 1 mide el disco; el resto lo reparte la rejilla. */
  padding-top: var(--qy-space-2) !important;
  padding-bottom: var(--qy-space-2) !important;
  grid-template-rows: var(--qy-nav-cta-size) auto !important;
  justify-content: center;
  justify-items: center;
  align-content: center;
  row-gap: 2px !important;
}

.bottom-nav.qy-theme {
  --qy-nav-cta-size: 40px;
}

.bottom-nav.qy-theme .bottom-nav-item--cta::before {
  position: static;
  grid-row: 1;
  grid-column: 1;
  top: auto;
  left: auto;
  width: var(--qy-nav-cta-size);
  height: var(--qy-nav-cta-size);
  transform: none;
  /* La sombra de contacto separa el disco de la barra. Es la rampa de
     tarjeta del sistema, no un valor propio: un literal aquí sería justo la
     isla que S4.11D retira en el resto de la aplicación. */
  box-shadow: var(--qy-elevation-card);
}

.bottom-nav.qy-theme .bottom-nav-item--cta .nav-icon {
  grid-row: 1;
  grid-column: 1;
  align-self: center;
  justify-self: center;
  /* El icono se dibuja sobre el disco: caja fija, nunca encogible. */
  flex: none;
  width: var(--qy-icon-box) !important;
  height: var(--qy-icon-box) !important;
  -webkit-mask-size: var(--qy-icon-glyph) var(--qy-icon-glyph);
  mask-size: var(--qy-icon-glyph) var(--qy-icon-glyph);
}

.bottom-nav.qy-theme .bottom-nav-item--cta small {
  grid-row: 2;
  grid-column: 1;
}

/*
   Contraste de la acción central.

   El disco usa `--qy-color-brand` y la tinta del icono era
   `--qy-color-text-on-brand`, que los tokens declaran medida en 7.07:1 sobre
   esa marca. Se reafirma aquí porque el CTA está dentro del ámbito
   `.bottom-nav.qy-theme`, donde `color: currentColor` de las hojas heredadas
   podría teñir la máscara con el color de estado del propio botón (terciario
   en reposo, marca en activo): marca sobre marca es 1:1.
*/
.bottom-nav.qy-theme .bottom-nav-item--cta .nav-icon,
.bottom-nav.qy-theme .bottom-nav-item--cta.is-active .nav-icon {
  color: var(--qy-color-text-on-brand);
  background-color: var(--qy-color-text-on-brand) !important;
}

/* La etiqueta del CTA no hereda el gris terciario: va bajo un disco de marca
   y necesita el mismo peso de lectura que el resto de la barra. */
.bottom-nav.qy-theme .bottom-nav-item--cta small {
  color: var(--qy-color-text-secondary);
}

.bottom-nav.qy-theme .bottom-nav-item--cta.is-active small {
  color: var(--qy-color-brand-text);
}

/*
   S4.11D — INTEGRIDAD DE LOS ICONOS DE LA BARRA (puntos 12 y J).

   `ux-fixes-v15-9.css` declara `overflow: hidden` sobre cada elemento del
   menú y `width: 100%` sobre `.nav-icon`. Con cinco posiciones a 320px cada
   celda mide ~58px, la máscara de 21px se dibuja centrada en una caja
   elástica y el recorte del contenedor podía comerse el trazo. Se fija la
   caja, se prohíbe encoger y se devuelve el desbordamiento visible: el
   dibujo ya no depende del ancho de la ventana.
*/
.bottom-nav.qy-theme .bottom-nav-item .nav-icon {
  flex: none;
  width: 22px !important;
  min-width: 22px;
  height: 22px !important;
  overflow: visible;
}

.bottom-nav.qy-theme .bottom-nav-item {
  overflow: visible !important;
}

/* ==========================================================================
   S4.11F — MOVIMIENTO DIRECCIONAL COMPARTIDO

   UNA sola gramática de transición lateral para las dos superficies que
   cambian de contenido por un gesto horizontal del usuario:

     · el menú inferior al cambiar de ruta
     · el conmutador Hoy / Resumen financiero

   Antes el conmutador tenía su propia animación -- que entraba siempre desde
   la derecha, fuera cual fuera el sentido del cambio -- y el menú no animaba
   nada. Dos comportamientos distintos para el mismo gesto. Aquí hay uno.

   --------------------------------------------------------------------------
   LA DIRECCIÓN LA DECIDE EL JAVASCRIPT, NO EL CSS
   --------------------------------------------------------------------------
   `core/router.js` compara la POSICIÓN de origen y destino en el eje del menú
   y añade `qy-route-motion--forward` o `--back`. El CSS solo sabe pintar un
   lado o el otro: no adivina, no consulta el historial y no anima nada que no
   traiga la marca.

   Es lo que mantiene el movimiento acotado: una recarga, un redirect de
   autenticación, la puerta legal, el botón de volver, un acordeón, un filtro
   o un modal NO pasan por el manejador del menú, así que no reciben la clase
   y siguen exactamente igual que antes de esta ola.

   --------------------------------------------------------------------------
   S4.11G — POR QUÉ ESTA ANIMACIÓN NO SE VEÍA
   --------------------------------------------------------------------------
   La ola anterior declaró estas reglas y sus contratos pasaron, pero en el
   móvil del propietario NO se movía nada. La causa no estaba en el
   JavaScript, que sí ponía la clase: `compact-visual-v15-14-2.css` declara

       .screen { animation: rt-screen-in ... both !important; }

   y una declaración `!important` de una hoja heredada gana a cualquier regla
   normal de esta, cargue después o no. La pantalla entrante recibía la marca
   direccional y seguía animándose con la aparición vertical de siempre.

   Por eso aquí se declara `!important`: no es descuido ni fuerza bruta
   preventiva, es la única forma de recuperar la propiedad de una animación
   que otra hoja se había reservado. Se limita a los dos selectores
   direccionales, que solo existen cuando el usuario ha hecho el gesto.

   El conmutador Hoy / Resumen financiero sí animaba -- su contenedor no es
   `.screen` --, pero con 10 px y 160 ms el movimiento era tan corto que el
   propietario tampoco lo percibía como dirección.

   --------------------------------------------------------------------------
   RECORRIDO Y DURACIÓN
   --------------------------------------------------------------------------
   16 px y 200 ms: dentro del objetivo de 180-220 ms y de 12-20 px de
   recorrido. Es una PISTA de dirección, no un viaje -- mover la pantalla
   entera obligaría a esperar la animación en cada toque --, pero ahora el ojo
   la registra. Sin rebote y sin desplazamiento de carrusel.

   Se usa `translate3d` para que el compositor la resuelva sin repintar el
   contenido de la pantalla entrante.
   ========================================================================== */

@keyframes qy-route-motion-forward-s4-11g {
  from {
    opacity: 0;
    transform: translate3d(var(--qy-motion-route-travel), 0, 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes qy-route-motion-back-s4-11g {
  from {
    opacity: 0;
    transform: translate3d(calc(var(--qy-motion-route-travel) * -1), 0, 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

/*
   `will-change` NO se declara a propósito: la animación dura 200 ms y crear
   una capa de composición para cada cambio de ruta cuesta más memoria de la
   que ahorra en pintado.
*/
.qy-route-motion--forward {
  animation: qy-route-motion-forward-s4-11g
    var(--qy-motion-route) var(--qy-motion-ease) both !important;
}

.qy-route-motion--back {
  animation: qy-route-motion-back-s4-11g
    var(--qy-motion-route) var(--qy-motion-ease) both !important;
}

/*
   El desplazamiento lateral de un hijo NO puede crear barra horizontal en el
   documento. Dieciséis píxeles hacia dentro no desbordan, pero el contenedor
   lo declara igualmente: es una garantía, no una confianza.
*/
.qy-route-motion {
  overflow-x: clip;
}

@media (prefers-reduced-motion: reduce) {
  /*
     Con movimiento reducido NO se traslada nada: queda una aparición por
     opacidad, que comunica el cambio de contenido sin desplazamiento. No se
     suprime del todo porque la aparición sigue siendo información útil.

     El recorrido se anula en el token además de en la animación: así ninguna
     regla que lo use puede reintroducir el desplazamiento por otra vía.
  */
  .qy-route-motion--forward,
  .qy-route-motion--back {
    --qy-motion-route-travel: 0px;

    animation: none !important;
  }
}
