/* ═══════════════════════════════════════════════════════════════════════════════════════════
   EL FRAMEWORK DEL CLIENTE — el port de `Resources/Styles/Styles.xaml` de la app MAUI.

   Es propio y no el kit del portal (`Cf`/`Cy`/`Px`), que es de escritorio (ningún control declara
   altura mínima y un botón mide ~30 px): este aplicativo se toca con el pulgar. Tampoco es Bootstrap.
   Tres botones y una tarjeta, como en MAUI: uno que empuja, uno que acompaña, uno que no pesa.
   Acá vive además lo que MAUI da gratis y la web hay que pedir para sentirse aplicación y no página;
   cada línea tiene su comentario.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* Las dos opacidades de los estados de más abajo: tokens y no literales, para que un apagado
   menos duro sea un número y no decenas de hojas. */
:root { --estado-tocado: .8; --estado-apagado: .45; }

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

html {
  /* Nada de `100vh`: en un teléfono `vh` mide la ventana con la barra de URL retraída y la app
     arranca con scroll. `dvh` es la altura dinámica, la que de verdad hay. */
  height: 100dvh;
  /* Sin esto, un tirón hacia abajo dispara el pull-to-refresh y recarga la app, borrando el
     estado en memoria. */
  overscroll-behavior: none;
  /* iOS/Safari agrandan el texto al girar a horizontal; en una app eso descuadra la escala. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  height: 100dvh;
  overflow: hidden;              /* el scroll vive dentro de cada cara, no en la página */
  font-family: var(--letra);
  font-size: var(--cuerpo);
  line-height: 1.45;
  /* Explícitos y desde token: un `body` transparente hereda el piso de quien lo aloja, y sale
     el texto de un tema sobre el fondo del otro. */
  color: var(--texto);
  /* El patrón del programa: el SVG que `bya identidad` dibuja con la paleta y sella en el .jshell,
     teselado sobre el fondo con su propia opacidad (~.12). Sin vestido, `--patron` no existe y queda el
     fondo liso. Va en el shorthand: un `background: var(--fondo)` posterior borraría un `background-image`. */
  background: linear-gradient(color-mix(in srgb, var(--fondo) 78%, transparent), color-mix(in srgb, var(--fondo) 78%, transparent)), var(--patron, none) 0 0 / 96px auto repeat, var(--fondo);
  -webkit-font-smoothing: antialiased;
}

/* ═══ EN PANTALLA GRANDE, LA APP NO SE ESTIRA ══════════════════════════════════════════════════
   Una interfaz para el pulgar, a lo ancho de un monitor, deja el campo y el botón de punta a punta.
   Se acota el contenedor, no se reescriben las pantallas: cada cara ocupa el 100% de lo que le den,
   y con 460 px se ven como en el teléfono. Por debajo de 560 px no se toca nada: ahí `#app` es el
   `body` entero, el caso del teléfono, que no se puede romper por arreglar el escritorio. */
#app {
  height: 100dvh;
  overflow: hidden;
}

@media (min-width: 560px) {
  body {
    /* El piso de afuera del «teléfono», más oscuro que el de la app para que el marco se lea: un gris
       cálido, del lado del papel. */
    background: #E6DFD3;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  @media (prefers-color-scheme: dark) { body { background: #0D0B08; } }

  #app {
    /* 460 × 900 es un teléfono grande de verdad. `min()` con `100dvh` evita que en una laptop de
       poca altura el marco se salga de la ventana y aparezca el scroll que `overflow:hidden` de
       `body` justamente evita. */
    width: 460px;
    height: min(900px, 100dvh);
    /* El patrón del programa: el SVG que `bya identidad` dibuja con la paleta y sella en el .jshell,
       teselado sobre el fondo con su propia opacidad (~.12). Sin vestido, `--patron` no existe y queda el
       fondo liso. Va en el shorthand: un `background: var(--fondo)` posterior borraría un `background-image`. */
  background: linear-gradient(color-mix(in srgb, var(--fondo) 78%, transparent), color-mix(in srgb, var(--fondo) 78%, transparent)), var(--patron, none) 0 0 / 96px auto repeat, var(--fondo);
    overflow: hidden;
    position: relative;
    border-radius: 22px;
    box-shadow: 0 2px 6px rgba(0,0,0,.10), 0 18px 50px rgba(0,0,0,.18);

    /* Esta línea hace que el marco sirva: las caras son `position: fixed`, que se mide contra la
       ventana, y se salían del marco. Un `transform` (aunque sea la identidad) vuelve al elemento bloque
       contenedor de sus descendientes fijos, y `fixed` pasa a ser «fijo dentro del teléfono». No se cambia
       `.panel` a `absolute`: `fixed` es lo correcto en el teléfono, que es el caso que manda. */
    transform: translateZ(0);
  }
}

/* ═══ EL MARCO CRECE CON LA PANTALLA ═══════════════════════════════════════════════════════════
   En una laptop el teléfono de 460 px ocupa un tercio y el texto queda chico para presentar. Se agranda
   el marco, no se reescribe nada: `zoom` multiplica el píxel de todo lo que cuelga de `#app`. `zoom` y
   no `transform: scale()`, porque `#app` ya usa `transform` como bloque contenedor (ver arriba).
   El factor lo decide el lado que primero se acaba: techo de 1,6, lo que cabe de alto y lo que cabe de
   ancho. La altura pasa a `900px` sólo donde el zoom se aplicó (`100dvh` no se divide por el zoom);
   el `@supports` pregunta por la división exacta, y si no la hay el marco queda como estaba.
   Por debajo de 820×760 no se toca nada: manda el bloque de arriba. */
@media (min-width: 820px) and (min-height: 760px) {
  #app {
    zoom: min(1.6, calc((100dvh - 40px) / 900px), calc((100vw - 80px) / 460px));
  }
}
@supports (zoom: min(1.6, calc((100dvh - 40px) / 900px), calc((100vw - 80px) / 460px))) {
  @media (min-width: 820px) and (min-height: 760px) {
    #app { height: 900px; }
  }
}

/* El destello gris del toque: Android dibuja un resalte sobre todo lo tocable, la marca más
   delatora de «esto es una página web». */
* { -webkit-tap-highlight-color: transparent; }

/* El cromo no se selecciona: un toque sostenido sobre un botón levanta el menú de selección.
   El contenido sí (un código de premio hay que poder copiarlo), así que va sobre los controles. */
button, .barra, .cabecera, .chip, label { user-select: none; -webkit-user-select: none; }

/* `manipulation` apaga el doble toque para zoom y con él los ~300 ms que el navegador espera
   por un segundo toque: la sensación de «la app va lenta». */
button, a, input, select, textarea, .tocable { touch-action: manipulation; }

/* El foco se ve: se quita el anillo por defecto sólo para el puntero (`:focus-visible` no
   dispara con el dedo) y se dibuja uno propio para el teclado. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--primario);
  outline-offset: 2px;
  border-radius: 4px;
}

/* El título que recibe el foco por navegar no dibuja anillo. `<FocusOnNavigate Selector="h1" />`
   (en `App.razor`) enfoca el primer `<h1>` en cada cambio de ruta para que un lector de pantalla anuncie
   la pantalla nueva, y eso se queda. Pero Chrome considera visible ese foco programático tras un toque, y
   el título salía recuadrado. Con `tabindex="-1"` no está en el orden de tabulación: el anillo sólo era
   ruido, y el anuncio no depende del contorno. */
h1[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible { outline: none; }

/* ══ LOS CUATRO ESTADOS DE UN CONTROL, DECIDIDOS UNA SOLA VEZ ══════════════════════════════════
   Reposo · tocado · apagado · escribiendo (el foco de teclado lo decide el `:focus-visible` de arriba).
   Una sola forma para toda la app: el dueño pidió que se vea idéntico en todas las pantallas.
   Van con `!important` a propósito: las hojas de componente ganan por alcance y sin él esta regla no
   decidiría nada; el precio es que una cara ya no elige otra opacidad de apagado. No tocan la
   geometría (sólo opacidad y cursor): apagar un control no puede moverlo de donde va el dedo. */
:is(button, a[href], summary, [role="button"], .tocable):not(:disabled):not([aria-disabled="true"]):not([aria-busy="true"]):active {
  opacity: var(--estado-tocado) !important;
}
:is(button, input, select, textarea):disabled,
[aria-disabled="true"] {
  opacity: var(--estado-apagado) !important;
  cursor: default !important;
}
/* El control que está escribiendo no se apaga, se subraya: apagado se confunde con «no se
   puede», y hace tocar dos veces. El subrayado va por dentro (`inset`) y no agrega ancho. `disabled`
   sigue impidiendo el segundo envío; esto sólo lo cuenta. */
:is(button, a[href], [role="button"])[aria-busy="true"] {
  opacity: 1 !important;
  cursor: progress !important;
  box-shadow: inset 0 -3px 0 currentColor !important;
}

/* Quien pidió menos movimiento recibe menos movimiento. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

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


/* ══ LA ARMAZÓN ════════════════════════════════════════════════════════════════════════════════
   Un panel ocupa el alto entero y el scroll es suyo, no de la página: la barra de abajo no se va
   con el desplazamiento y el rebote de iOS no arrastra el cromo. */

.panel {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  /* El patrón del programa: el SVG que `bya identidad` dibuja con la paleta y sella en el .jshell,
     teselado sobre el fondo con su propia opacidad (~.12). Sin vestido, `--patron` no existe y queda el
     fondo liso. Va en el shorthand: un `background: var(--fondo)` posterior borraría un `background-image`. */
  background: linear-gradient(color-mix(in srgb, var(--fondo) 78%, transparent), color-mix(in srgb, var(--fondo) 78%, transparent)), var(--patron, none) 0 0 / 96px auto repeat, var(--fondo);
}

/* LA ATMÓSFERA DE CADA PROGRAMA. Son manchas amplias y quietas: distinguen el lugar sin
   convertirse en papel tapiz ni competir con fotografías, tarjetas o texto. */
.panel.programa--compraevora {
  background:
    radial-gradient(ellipse 70% 34% at 108% 12%, rgb(248 96 0 / .11), transparent 72%),
    radial-gradient(ellipse 65% 30% at -12% 78%, rgb(255 177 72 / .08), transparent 74%),
    var(--fondo);
}
.panel.programa--bazarevora {
  background:
    radial-gradient(circle at 108% 18%, rgb(120 84 62 / .12) 0 9%, transparent 9.4%),
    radial-gradient(circle at 104% 18%, transparent 0 15%, rgb(120 84 62 / .055) 15.3% 16%, transparent 16.4%),
    radial-gradient(ellipse 72% 32% at -18% 88%, rgb(188 139 96 / .09), transparent 72%),
    var(--fondo);
}
.panel.programa--puroevora {
  background:
    radial-gradient(ellipse 90% 28% at 12% -5%, rgb(30 112 150 / .10), transparent 72%),
    radial-gradient(ellipse 90% 24% at 96% 92%, rgb(76 155 166 / .07), transparent 72%),
    var(--fondo);
}
.panel.programa--saborevora {
  background:
    radial-gradient(ellipse 62% 34% at 105% 8%, rgb(42 122 78 / .10), transparent 72%),
    radial-gradient(ellipse 45% 26% at -8% 72%, rgb(224 158 49 / .07), transparent 74%),
    var(--fondo);
}
.panel.programa--vivasinaloa {
  background:
    radial-gradient(ellipse 75% 30% at 82% -4%, rgb(181 55 98 / .10), transparent 72%),
    radial-gradient(ellipse 60% 26% at -8% 92%, rgb(220 135 53 / .07), transparent 74%),
    var(--fondo);
}

.cuerpo {
  flex: 1;
  overflow-y: auto;
  /* En el marco de escritorio Windows pinta un riel gris de 17 px; en el teléfono la barra es una
     sombra. Fina y del color del borde en los dos. */
  scrollbar-width: thin;
  scrollbar-color: var(--borde-fuerte) transparent;
  /* El impulso nativo del scroll en iOS: sin esto la lista frena en seco. */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding: 16px;
  /* El hueco de la barra de abajo más el indicador de inicio: `env(safe-area-inset-bottom)` es la
     franja del gesto en un iPhone sin botón, y sin sumarla el último elemento queda debajo. */
  padding-bottom: calc(16px + var(--alto-barra, 0px) + env(safe-area-inset-bottom, 0px));
}

.pila { display: flex; flex-direction: column; gap: 12px; }
.fila { display: flex; align-items: center; gap: 10px; }
.crece { flex: 1; min-width: 0; }   /* `min-width:0` o un texto largo revienta la fila */

/* ══ LA CABECERA DE UNA CAPA ═══════════════════════════════════════════════════════════════════
   La barra de arriba de una pantalla que tapa a otra (el escáner, el selector de aplicativo): el
   botón de salida a la izquierda y el rótulo al lado. Vive acá y no en un `.razor.css` porque la usan
   varios componentes y el CSS con alcance es por componente.
   El relleno de arriba suma `safe-area-inset-top`: instalada, la app dibuja debajo de la franja del
   reloj (`viewport-fit=cover`), y sin ese hueco el botón de salir queda debajo de la hora. */
/* ══ LA BARRA DE UNA CAPA ═══════════════════════════════════════════════════════════════════
   La pinta `<Piezas/Barra.razor>`, y sus variantes (`--lisa`, `--con-foto`) viven en la hoja de esa
   pieza. Esta regla se queda acá porque `.cabecera__toque` lo comparten la barra y la cabecera.
   Se llama `.banda` y no `.barra`: `.barra` es la de secciones de abajo (`.barra__item`), y con el
   mismo nombre la regla de abajo ganaría por cascada sin error ni aviso. */
.banda {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 20px 12px 12px;
  /* Es una banda, como la cabecera de la armazón: del color de la marca con el texto encima. La
     tinta es `--sobre-banda` y no `--sobre-cabecera`: con degradado de marca la banda es `--primario`,
     que en oscuro es claro, igual que `--sobre-cabecera`. `--sobre-banda` la escribe el vestido junto al
     degradado; sin degradado cae a la tinta de la cabecera lisa. El botón de salir y el rótulo la heredan. */
  background: var(--cabecera-degradado, var(--cabecera));
  /* la tinta del degradado de marca; sin degradado, la de la cabecera lisa (ver `Vestido.Tokens`) */
  color: var(--sobre-banda, var(--sobre-cabecera));
  flex: none;
}

/* 48 px es el mínimo táctil, y por eso el botón es más grande que su ícono de 24. */
.cabecera__toque {
  flex: none;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: 0;
  padding: 0;
  background: none;
  /* `inherit` y no `--tenue`: los dos lugares que lo usan son bandas y el color lo pone la banda;
     con `--tenue` el botón de salir quedaba gris sobre la marca. */
  color: inherit;
  cursor: pointer;
}
.cabecera__toque:disabled { cursor: default; }

/* ══ LA TARJETA ════════════════════════════════════════════════════════════════════════════════
   Lo que la separa del fondo es que su piso sea otro color; el borde apenas la remata. */
.hoja {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio-tarjeta);
  padding: 16px;
}
.hoja--elevada { background: var(--elevada); }

/* ══ LOS TRES BOTONES ══════════════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--alto-tactil);
  padding: 0 20px;
  border: 0;
  border-radius: var(--radio-control);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  background: none;
  color: inherit;
  transition: opacity .12s ease, background-color .12s ease;
}

/* El botón apagado tiene que verse apagado: `Tomar()` deshabilita los botones durante cada
   llamada, y uno inactivo idéntico a uno vivo hace creer que no pasó nada (como el `CommonStates`
   del `Tema.xaml`). */



/* La sombra teñida del primario despega el botón del papel sin dibujarle un borde. `color-mix` la
   saca del token, así en oscuro (primario claro) se aclara sola. */
.btn--principal { background: var(--primario); color: var(--sobre-primario); box-shadow: 0 5px 12px color-mix(in srgb, var(--primario) 16%, transparent); }
.btn--contorno  { border: 1px solid var(--borde-fuerte); color: var(--primario); padding: 0 14px; font-size: 15px; }
.btn--fantasma  { color: var(--tenue); font-size: 15px; font-weight: 500; }
.btn--ancho     { width: 100%; }

/* ══ EL ENLACE — un botón que se ve como texto ═════════════════════════════════════════════
   «Reenviar el código», «Cambiar mi número», «Ahora no»: acciones secundarias que no merecen un
   botón. Es un `<button>` de verdad —foco, Enter, lector de pantalla— vestido de enlace. */
.enlace {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 6px;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: var(--menor);
  font-weight: 600;
  color: var(--primario);
  cursor: pointer;
}

.enlace--centrado { align-self: center; }

/* ══ LA LISTA DE OPCIONES — filas tocables dentro de una hoja ══════════════════════════════
   El municipio que eliges, el programa que marcas, el renglón de la cuenta. Vive acá porque la
   usan varias pantallas y el CSS con alcance no cruza componentes. */
.lista { padding: 0; overflow: hidden; }
/* La etiqueta de un campo, compartida por todos los formularios (el CSS con alcance de una cara
   no la alcanza a otra). `bya estilo` acusa una clase usada sin regla. */
.campo__rotulo {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tenue);
}

.opcion {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 12px 14px;
  border: 0;
  border-bottom: 1px solid var(--elevada);
  background: none;
  color: var(--texto);
  font-family: inherit;
  font-size: inherit;
  text-align: start;
  cursor: pointer;
}
.opcion:last-child { border-bottom: 0; }
.opcion:disabled { cursor: default; }
.opcion--fija { cursor: default; }
.opcion__texto { display: flex; flex-direction: column; gap: 2px; }
.opcion__titulo { font-size: 15px; font-weight: 600; }
.opcion__dato { flex: none; font-weight: 700; color: var(--sutil); }
.opcion__dato--vivo { color: var(--primario); }
/* La casilla: cuadrada y redondeada, se llena del primario al elegir. */
.opcion__marca {
  flex: none;
  width: 20px;
  height: 20px;
  border: 2px solid var(--borde);
  border-radius: 6px;
  display: grid;
  place-items: center;
  color: var(--sobre-primario);
}
.opcion--elegida .opcion__marca { border-color: var(--primario); background: var(--primario); }
.opcion--elegida .opcion__titulo { color: var(--primario-fuerte); }

/* La insignia de un programa: la inicial sobre el color de su marca. El `style` lo pone quien la
   dibuja, derivado de la semilla del .jshell: es el único color que no es un token, porque es de otra
   marca a propósito. */
.insignia {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  color: #FFFFFF;
  display: grid;
  place-items: center;
  font-family: var(--letra-display);
  font-size: 16px;
  font-weight: 800;
}

/* La estrella de favorito: 44 de área para 20 de dibujo. */
.estrella {
  flex: none;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--sutil);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.estrella--puesta { color: var(--primario); }


/* ══ LOS CAMPOS ════════════════════════════════════════════════════════════════════════════════ */

.campo {
  width: 100%;
  min-height: var(--alto-tactil);
  padding: 0 14px;
  /* 16 px no es estética: por debajo iOS hace zoom al enfocar el campo y la pantalla salta. */
  font-size: var(--texto-campo);
  font-family: inherit;
  color: var(--texto);
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-control);
}
.campo::placeholder { color: var(--sutil); }
.campo:focus-visible { border-color: var(--primario); outline-offset: 0; }
.campo--cifras { font-family: var(--letra-cifras); letter-spacing: .08em; }

/* ══ LA TIPOGRAFÍA ═════════════════════════════════════════════════════════════════════════════ */

.t-grande   { font-family: var(--letra-display); font-size: var(--titulo-grande); font-weight: 800; line-height: 1.1; letter-spacing: -.025em; }
.t-titulo   { font-family: var(--letra-display); font-size: var(--titulo);        font-weight: 700; line-height: 1.2; text-wrap: balance; }
/* El rótulo de sección («Lo último que ganaste», «Dónde jugar»): mayúsculas chicas y
   espaciadas, en tenue, para decir «acá empieza otra cosa» sin competir con el contenido. */
.t-seccion  { font-size: var(--minimo); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--sutil); }
.t-sub      { font-size: var(--subtitulo);     font-weight: 600; }
.t-menor    { font-size: var(--menor); }
.t-minimo   { font-size: var(--minimo); }
.t-tenue    { color: var(--tenue); }
.t-sutil    { color: var(--sutil); }
/* Cifras que se comparan en columna: sin ancho fijo la coma baila entre filas. */
.t-cifra    { font-variant-numeric: tabular-nums; font-family: var(--letra-cifras); }

/* ══ LA BARRA DE ABAJO ═════════════════════════════════════════════════════════════════════════
   Cuatro destinos. El relleno de abajo suma el `safe-area`: en un teléfono sin botón la franja del
   gesto se dibuja encima de la app, y sin ese hueco los íconos quedan donde el dedo no alcanza. */
.barra {
  display: flex;
  background: var(--superficie);
  border-top: 1px solid var(--borde);
  padding: 5px 4px 4px;
  padding-bottom: calc(4px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 24px color-mix(in srgb, var(--texto) 7%, transparent);
}
.barra__item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 0;
  min-height: 58px;
  margin: 0 1px;
  padding: 4px 1px 3px;
  border: 0;
  border-radius: 14px;
  background: transparent;
  color: var(--sutil);
  font-family: inherit;
  font-size: var(--minimo);
  cursor: pointer;
  transition: background-color .16s ease, color .16s ease, transform .12s ease;
}
.barra__item:active { transform: scale(.96); }
.barra__icono {
  position: relative;
  /* La caja crece con el dibujo: con una caja menor que el ícono, el SVG desborda y pisa el rótulo. */
  width: 46px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  color: inherit;
  background: transparent;
  transition: transform .16s ease, box-shadow .16s ease;
}
/* EL GLOBO DE PENDIENTES sobre el ícono de una pestaña: cuántas conversaciones tienen algo sin
   leer. Va anclado al ícono y no al botón para que no se mueva con el rótulo. */
.barra__globo {
  position: absolute;
  top: -4px;
  inset-inline-start: 58%;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--primario);
  color: var(--sobre-primario);
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--superficie);
}

.barra__rotulo {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.barra__item[aria-current="page"] {
  color: var(--texto);
  background: transparent;
  font-weight: 700;
}
.barra__item[aria-current="page"] .barra__icono {
  color: var(--primario);
  background: color-mix(in srgb, var(--primario) 14%, var(--superficie));
  transform: translateY(-1px);
  box-shadow: 0 3px 9px color-mix(in srgb, var(--primario) 18%, transparent);
}

/* ══ LOS ESTADOS DE LA PANTALLA ════════════════════════════════════════════════════════════════
   Tres desenlaces y no dos: «cargando», «vacío» y «falló» son distintos. Una lista vacía porque no
   hay nada y una vacía porque la llamada murió no pueden verse igual. */
.vacio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 40px 24px;
  text-align: center;
  color: var(--sutil);
}
/* El reseteo del `<p>` va acá porque el elemento es compartido: `.vacio` es un flex column con
   `gap: 8px`, y en flex los márgenes del `<p>` no se colapsan, se suman al `gap`. Lo propio de una
   cara sigue en su CSS con alcance. */
.vacio p { margin: 0; }
.vacio--falla { color: var(--error-texto); }


/* ══ EL ARRANQUE Y LA CAÍDA ════════════════════════════════════════════════════════════════════
   Los estilos de `#blazor-error-ui` y `.loading-progress` que la plantilla de Blazor pone acá. Sin
   ellos no falla nada visible: la barra de «algo se rompió» queda encendida siempre, tapada por `.panel`. */

/* Oculto por defecto: Blazor lo enciende con `style.display = 'block'` cuando algo se rompe;
   sin este `none`, la app arranca diciendo que falló. */
#blazor-error-ui {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;   /* por encima de `.panel`, o el aviso queda debajo de lo que falló */
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom, 0px));
  background: var(--error-tinte);
  color: var(--error-texto);
  font-size: var(--menor);
  box-shadow: 0 -2px 12px rgb(0 0 0 / .18);
}
#blazor-error-ui .reload { color: var(--error-texto); text-decoration: underline; }
#blazor-error-ui .dismiss { float: right; cursor: pointer; padding: 0 6px; }

/* El anillo del arranque: los ~2 s en que WebAssembly se descarga y compila. Sin esto la app abre
   en blanco, que en un teléfono se lee como «no cargó» y provoca el recargue. */
.loading-progress {
  position: fixed;
  inset: 0;
  margin: auto;
  width: 8rem;
  height: 8rem;
}
.loading-progress circle {
  fill: none;
  stroke: var(--primario-tinte);
  stroke-width: .5rem;
  transform-origin: 50% 50%;
  transform: rotate(-90deg);
}
.loading-progress circle:last-child {
  stroke: var(--primario);
  /* `--blazor-load-percentage` lo va escribiendo el runtime: la barra es real, no una animación. */
  stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8) 500%;
  transition: stroke-dasharray .05s ease-in-out;
}
.loading-progress-text {
  position: fixed;
  inset: 0;
  display: grid;
  place-content: center;
  color: var(--tenue);
  font-size: var(--menor);
}
.loading-progress-text::after {
  content: var(--blazor-load-percentage-text, "Abriendo…");
}

/* ══ EL CANDADO — la pantalla de quien YA entró ═════════════════════════════════════════════════
   Vive acá y no en un componente: lo usan la app del consumidor (`Paneles/App.razor`) y la terminal
   del afiliado (`Paneles/Terminal.razor`), y el CSS con alcance de una no alcanza a la otra. */
.candado__centro {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 0 36px;
  text-align: center;
}
.candado__disco {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--primario-tinte);
  color: var(--primario-fuerte);
}
.candado__titulo { margin: 0; font-size: 24px; font-weight: 700; line-height: 1.15; }
.candado__texto { margin: 0; line-height: 1.5; }
.candado__pie {
  padding: 0 28px calc(44px + env(safe-area-inset-bottom, 0px));
}

/* Acá no va `::deep`: lo traduce el compilador de un `.razor.css`; en esta hoja global queda
   literal y el navegador tira la regla entera sin aviso. El descendiente se escribe pelado.

   ══ EL RIEL Y EL CHIP ═════════════════════════════════════════════════════════════════════════
   Una sola forma de chip para todas las caras; lo que cada una personaliza son tres tokens.

   Cómo se usa una fila de chips:
     <div class="riel" style="--chip-tinte: var(--seccion-bazar-tinte); --chip-texto: var(--seccion-bazar-texto)">
   y cada botón con `class="chip"` más `chip--activo` cuando manda. Sin los tokens, el elegido sale
   del color primario del programa, que es el respaldo correcto para una cara sin sección propia. */

/* LA FILA QUE SE DESPLAZA. Los márgenes negativos sacan el riel del relleno lateral de la cara para
   que el primer chip empiece pegado al borde y el último se asome: es lo que dice «hay más». */
.riel {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin: 0 -16px;
  padding: 0 16px 2px;
  scrollbar-width: none;
}
.riel::-webkit-scrollbar { display: none; }
/* En escritorio sí se ve la barra: con mouse no hay gesto de arrastre, y sin barra la fila
   parece terminar donde termina la pantalla. */
@media (pointer: fine) {
  .riel--con-barra { scrollbar-width: thin; scrollbar-color: var(--borde-fuerte) transparent; padding-bottom: 8px; }
  .riel--con-barra::-webkit-scrollbar { display: block; height: 6px; }
  .riel--con-barra::-webkit-scrollbar-thumb { background: var(--borde-fuerte); border-radius: 3px; }
}

.chip {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;                 /* el piso táctil: 40 con el gap del riel da los 44 de MAUI */
  padding: 0 14px;
  border: 1px solid var(--borde);
  border-radius: 12px;
  background: var(--superficie);
  color: var(--texto);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
}

/* EL ELEGIDO. Los tres tokens los pone la cara; sin ellos manda el color del programa. */
.chip--activo {
  background: var(--chip-tinte, var(--primario-lavado));
  border-color: var(--chip-borde, var(--chip-texto, var(--primario)));
  color: var(--chip-texto, var(--primario-fuerte));
}
.chip--activo .chip__rotulo { font-weight: 700; }
/* Dos tamaños menores, para las filas secundarias (el estante, el municipio, el tipo). */
.chip--chico { min-height: 34px; padding: 0 11px; font-size: 12.5px; }
.chip--mini  { min-height: 28px; padding: 0 10px; font-size: 12px; border-radius: 999px; }

/* ══ LOS TONOS DE `<Marca>` ════════════════════════════════════════════════════════════════════
   Una marca es un rótulo que afirma un estado («Cerrada», «Pagado», «Vencido»), no un control. Vive
   con el chip porque comparte forma y alto. Se nombran por significado y no por color (`aviso`,
   `bien`, `falla`): si cambia la paleta, cambian tres reglas y no las caras. */
.chip--aviso { background: color-mix(in srgb, var(--aviso) 14%, transparent); color: var(--aviso); }
.chip--bien  { background: color-mix(in srgb, var(--exito) 14%, transparent); color: var(--exito); }
.chip--falla { background: color-mix(in srgb, var(--peligro) 14%, transparent); color: var(--peligro); }
/* EL DE DOS RENGLONES (el bazar pone el costo del día debajo del nombre). */
.chip--pila { flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px; padding: 6px 14px; min-height: 44px; }
/* Las partes: el número que acompaña, el pie chico y el ícono de la categoría. */
.chip__n { font-weight: 500; color: var(--tenue); font-variant-numeric: tabular-nums; }
.chip--activo .chip__n { color: inherit; }
.chip__pie { font-size: 10px; color: var(--sutil); }
.chip--activo .chip__pie { color: inherit; opacity: .85; }
.chip__ico { width: 20px; height: 20px; object-fit: contain; }

/* ══ LA TARJETA DE LISTA ═══════════════════════════════════════════════════════════════════════
   Una sola tarjeta para todas las listas (miniatura, texto que crece, etiquetas, una acción al final);
   lo que cambia por cara son tres tokens y el tamaño de la miniatura.

   Cómo se usa:
     <button class="hoja tarj tarj--abrible" style="--tarj-tinte: var(--seccion-plaza-tinte);
                                                     --tarj-texto: var(--seccion-plaza-texto)">
       <span class="tarj__mini tarj__mini--redonda">…</span>
       <span class="crece pila tarj__texto">
         <span class="tarj__titulo">…</span>
         <span class="tarj__sub">…</span>
         <span class="fila tarj__tags">…</span>
       </span>
       <Icono … Clase="tarj__accion" />
     </button>

   La tarjeta no pinta su propio piso: eso lo hace `.hoja`, que decide fondo, borde y radio de toda
   superficie de la app. */
.tarj {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-width: 0;
  padding: 10px 12px;
  color: inherit;
  font: inherit;
  text-align: left;
}
/* La que se abre se comporta como tocable, y lo dice con el dedo y con el toque. */
.tarj--abrible { cursor: pointer; }
.tarj--abrible:active { background: var(--elevada); }
/* Alinea arriba cuando el texto es alto (tres renglones o más) y al centro cuando es una línea. */
.tarj--alta { align-items: flex-start; }

/* LA MINIATURA. Cuadrada por defecto; `--redonda` para un logotipo y `--grande` para una foto que
   manda en la tarjeta. El tinte de respaldo es el del programa: una miniatura vacía nunca sale gris
   de sistema, sale del color de la marca. */
.tarj__mini {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: var(--tarj-mini, 46px);
  height: var(--tarj-mini, 46px);
  border-radius: 10px;
  overflow: hidden;
  background: var(--tarj-tinte, var(--primario-lavado));
  color: var(--tarj-texto, var(--primario-fuerte));
  /* La inicial, cuando no hay imagen, a tamaño de seña y no de cuerpo de texto. */
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
}
.tarj__mini--redonda { border-radius: 50%; }
.tarj__mini--grande  { --tarj-mini: 102px; }

/* El recuadro manda sobre la imagen: un ícono generado trae su propio fondo y va pegado al borde.
   Con `--mini-relleno` la imagen respira y el fondo que se ve es el nuestro, `contain` no la recorta, y
   el ribete interior le da un borde propio. */
.tarj__mini--icono {
  padding: var(--mini-relleno, 7px);
  /* Crema y no el tinte de la sección: los íconos del catálogo llegan del acervo con su fondo crema
     en los bytes, y con un recuadro del mismo crema ícono y marco son una sola pieza. Cuando el acervo
     reciba los íconos recortados, esto puede volver a ser un tinte normal. */
  background: #FFF3E2;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .06);
}
.tarj__mini--icono .foto { background: transparent; border-radius: 0; }
.tarj__mini--icono .foto__img { object-fit: contain; }

.tarj__texto { gap: 3px; min-width: 0; justify-content: center; }
/* Una sola línea y corta: en una lista, dos títulos de alto distinto se leen como desorden. */
.tarj__titulo { font-size: 15px; font-weight: 700; line-height: 1.3; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tarj__sub { color: var(--tenue); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* El sobrerrótulo: chico, en el color de la sección, arriba del título. */
.tarj__kicker { color: var(--tarj-texto, var(--primario)); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.tarj__accion { flex: none; color: var(--sutil); }

/* Las etiquetas: el renglón que dice el resto (categoría, estado, dónde) sin gastar una línea
   por cosa. Hermanas del chip pero no son chips: no se tocan, no eligen nada. */
/* El renglón que comparte el título con el dato fuerte de la derecha (el precio). */
.tarj__renglon { align-items: baseline; gap: 10px; }
.tarj__tags { flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.tarj__tag {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  background: var(--elevada);
  color: var(--tenue);
  white-space: nowrap;
}
.tarj__tag--seccion { background: var(--tarj-tinte, var(--primario-lavado)); color: var(--tarj-texto, var(--primario-fuerte)); }
.tarj__tag--contorno { background: transparent; border: 1px solid var(--borde); }
.tarj__tag--ojo { background: transparent; border: 1px dashed var(--borde-fuerte); }
/* El dato fuerte de la derecha del título (el precio). */
.tarj__dato { flex: none; font-size: 14px; font-weight: 800; color: var(--tarj-texto, var(--primario-fuerte)); font-variant-numeric: tabular-nums; }

/* ══ LA TARJETA VERTICAL Y LA HOJA QUE SUBE ════════════════════════════════════════════════════
   Las otras dos formas compartidas: la vertical (foto arriba, texto abajo) y la hoja que sube desde
   abajo, con un solo alto máximo y un solo velo para todas las caras. */

/* LA VERTICAL. `--tarj-foto` cambia la proporción sin tocar la regla: 16/10 en una lista ancha,
   4/3 en una grilla de dos columnas. */
.tarj--vertical {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 0;
  overflow: hidden;
}
.tarj--vertical:active { transform: scale(.99); }
.tarj__foto {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: var(--tarj-foto, 16 / 10);
  background: var(--tarj-tinte, var(--primario-lavado));
  color: var(--tarj-texto, var(--primario));
  overflow: hidden;
}
.tarj__foto .foto { position: absolute; inset: 0; width: 100%; height: 100%; }
/* El sello que va sobre la foto (la operación de un inmueble, el estado de una publicación). */
.tarj__sello {
  position: absolute; left: 10px; top: 10px;
  padding: 3px 9px; border-radius: 999px;
  background: var(--superficie); color: var(--tarj-texto, var(--primario-fuerte));
  font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.tarj--vertical .tarj__texto { gap: 3px; padding: 10px 12px 12px; }
.tarj--vertical .tarj__titulo { white-space: normal; line-height: 1.25; }

/* LA HOJA QUE SUBE. Se consulta y se cierra: por eso llega desde abajo y no desde el centro, y por
   eso su alto máximo deja ver que hay algo detrás. */
.hojita__velo { position: fixed; inset: 0; background: rgb(0 0 0 / .4); z-index: 40; border: 0; padding: 0; cursor: pointer; }
.hojita {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  display: flex; flex-direction: column; gap: 10px;
  max-height: 92vh; overflow-y: auto;
  padding: 14px 16px calc(16px + env(safe-area-inset-bottom));
  border-radius: 20px 20px 0 0;
  background: var(--superficie); color: var(--texto);
  box-shadow: 0 -8px 30px rgb(0 0 0 / .2);
}

/* ══ EL BOLETO ═════════════════════════════════════════════════════════════════════════════════
   El premio dibujado como un ticket con su talón, una sola vez para todas las caras.
   Los hex del talón son a propósito y los únicos de esta hoja: imitan un boleto impreso (magenta de
   la marca, ocre por vencer, gris vencido) y no siguen al programa, porque un boleto de otro color
   dejaría de leerse como boleto. La muesca es una máscara radial en los dos bordes. */
.boleto {
  --talon: 86px;
  --muesca: 7.7px;
  --talon-claro: #A73156;
  --talon-hondo: #7A1338;
  display: flex;
  align-items: stretch;
  width: 100%;
  min-height: 104px;
  padding: 0;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--superficie);
  color: inherit;
  font-family: inherit;
  text-align: start;
  cursor: pointer;
  overflow: hidden;
  -webkit-mask: radial-gradient(circle var(--muesca) at var(--talon) 0,    #0000 98%, #000) top    / 100% 50% no-repeat,
                radial-gradient(circle var(--muesca) at var(--talon) 100%, #0000 98%, #000) bottom / 100% 50% no-repeat;
          mask: radial-gradient(circle var(--muesca) at var(--talon) 0,    #0000 98%, #000) top    / 100% 50% no-repeat,
                radial-gradient(circle var(--muesca) at var(--talon) 100%, #0000 98%, #000) bottom / 100% 50% no-repeat;
}
.boleto:not(:disabled):active { filter: brightness(.97); }
.boleto:disabled { cursor: default; }
.boleto--porvencer { --talon-claro: #A24300; --talon-hondo: #712C00; }
.boleto--terminal  { --talon-claro: #8A7B7D; --talon-hondo: #5E5153; }
/* El boletín con su ventana abierta: verde, el único talón que dice «esto está pasando ahora», para
   encontrarlo de un vistazo en la lista. */
.boleto--abierto   { --talon-claro: #1E7A4B; --talon-hondo: #125A37; }
.boleto__talon {
  flex: none;
  width: var(--talon);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 11px 7px 9px;
  color: var(--blanco);
  background: linear-gradient(145deg, var(--talon-claro), var(--talon-hondo));
  border-right: 1px dashed rgb(255 255 255 / .38);
}
.boleto__caja { flex: 1; min-height: 0; display: grid; place-items: center; overflow: hidden; }
.boleto__rotulo { writing-mode: vertical-rl; transform: rotate(180deg); white-space: nowrap; font-size: 11px; font-weight: 700; letter-spacing: .2em; line-height: 1; }
.boleto__folio { max-width: 100%; padding: 0 2px; font-family: var(--letra-cifras); font-size: 8px; letter-spacing: .04em; opacity: .62; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.boleto__cuerpo { display: flex; align-items: center; gap: 10px; padding: 10px 14px; color: var(--sutil); }
.boleto__texto { display: flex; flex-direction: column; gap: 2px; }
.boleto__marca { font-size: 11px; font-weight: 600; color: var(--tenue); }
/* Una sola línea con puntos suspensivos, como el `TailTruncation`/`MaxLines=1` del XAML: un nombre
   en dos renglones estira la fila y rompe la silueta del boleto. */
.boleto__nombre { font-size: 15.5px; font-weight: 700; color: var(--texto); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.boleto__origen { font-size: 12px; color: var(--tenue); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.boleto__donde { font-size: 12px; color: var(--tenue); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.boleto__vence { font-size: 11.5px; font-weight: 700; color: var(--exito-texto); }
/* «Vence pronto» es aviso y no error: un premio que todavía sirve no es una falla, es una prisa. */
.boleto__vence--urge { color: var(--aviso-texto); }
.boleto__vence--paso { color: var(--sutil); font-weight: 600; }
.boleto__aviso { font-size: var(--minimo); line-height: 1.3; color: var(--sutil); }

/* ══ LA LOSETA ═════════════════════════════════════════════════════════════════════════════════
   La insignia cuadrada con su nombre debajo, en grilla: los programas de la casa y de la bienvenida,
   y los logotipos de los fundadores. Toma el color de la marca por `--marca`, que la cara pone en
   cada loseta; sin él, el primario del programa. */
.losetas { display: grid; grid-template-columns: repeat(var(--losetas-columnas, 4), minmax(0, 1fr)); gap: 10px 8px; }
.loseta {
  /* Ancla del globo de premios, que se posa en la esquina y NO debe recortarse. */
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  min-width: 0; padding: 0; border: 0; background: none;
  color: var(--texto); font-family: inherit; text-align: center; cursor: pointer;
}

.loseta__insignia {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 12px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--marca, var(--primario));
  color: var(--blanco);
  font-family: var(--letra-display);
  font-size: 22px;
  font-weight: 800;
}
/* CON LOGOTIPO la insignia deja de ser un bloque de color: se aclara al 8 % de la marca y se ribetea
   con ella, para que el dibujo se lea sobre un fondo casi blanco sin perder de quién es. */
.loseta__insignia--logo {
  background: color-mix(in srgb, var(--marca, var(--primario)) 8%, #fff);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--marca, var(--primario)) 55%, transparent), 0 2px 8px rgb(0 0 0 / .06);
}
.loseta__insignia--mas { background: var(--elevada); border: 1px dashed var(--borde-fuerte); color: var(--tenue); font-size: 17px; }
.loseta__nombre { max-width: 100%; font-size: var(--minimo); font-weight: 600; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loseta__nota { font-size: 10.5px; color: var(--sutil); }
.loseta--suelta .loseta__nombre { font-weight: 400; color: var(--tenue); }
/* El contador que se posa en la esquina (premios sin usar de ese programa). */
.loseta__badge {
  position: absolute; right: -4px; top: -4px;
  min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 10px;
  background: var(--texto); color: var(--fondo); border: 2px solid var(--fondo);
  display: grid; place-items: center;
  font-family: var(--letra-cifras); font-size: 11px; font-weight: 700; line-height: 1;
}
/* MIENTRAS CARGA: la loseta ocupa su lugar en gris y no se toca. Un hueco que aparece y empuja el
   resto se siente peor que una espera dibujada. */
.loseta--espera { cursor: default; }
.loseta--espera .loseta__insignia { background: var(--elevada); }
.loseta__nombre--espera { display: block; width: 70%; height: 12px; margin-top: 3px; border-radius: 6px; background: var(--elevada); }
/* DOS COLUMNAS Y MÁS GRANDE: la grilla de los fundadores, donde el logotipo ES el contenido. */
.losetas--grandes { --losetas-columnas: 2; gap: 12px 10px; }
.losetas--grandes .loseta__insignia { max-width: 132px; border-radius: 16px; }
.losetas--grandes .loseta__nombre { font-size: inherit; font-weight: 700; white-space: normal; }

/* El cupón es `<Cupon>` y sus reglas viven en `Piezas/Cupon.razor.css`. Acá quedan las clases de
   tipografía y de layout que usa cualquier cara (`.hoja`, `.fila`, `.crece`), que no tienen dueño. */

/* ══ LA HOJA DE DETALLE ════════════════════════════════════════════════════════════════════════
   La hoja que sube a pantalla completa desde abajo, con su agarre, su cabeza y su cuerpo; el nombre
   va en la letra de títulos. Se distingue de `.hojita` en que es una capa completa (velo propio,
   agarre, alto de pantalla) y aquélla una hoja corta anclada abajo. */
.detalle { background: transparent; justify-content: flex-end; }
.detalle__velo { position: absolute; inset: 0; border: 0; padding: 0; background: rgb(0 0 0 / .45); cursor: pointer; }
.detalle__hoja {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-height: 100%;
  overflow-y: auto;
  padding: 8px 20px 28px;
  padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px));
  background: var(--superficie);
  border-radius: 22px 22px 0 0;
}
.detalle__agarre { flex: none; align-self: center; width: 38px; height: 4px; border-radius: 2px; background: var(--borde); }
.detalle__cabeza { align-items: flex-start; }
.detalle__programa { margin: 0 0 4px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--primario); }
.detalle__nombre { margin: 0; font-family: var(--letra-display); font-size: 24px; font-weight: 800; line-height: 1.1; letter-spacing: -.02em; color: var(--texto); }
.detalle__donde { margin: 4px 0 0; }
.detalle__cerrar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; border: 0; padding: 0; background: none; color: var(--tenue); cursor: pointer; }
.detalle__texto { margin: 0; font-size: var(--menor); line-height: 1.5; color: var(--tenue); }
.detalle__datos { display: flex; gap: 12px; margin: 0; padding: 12px 0; border-top: 1px solid var(--borde); border-bottom: 1px solid var(--borde); }
.detalle__dato { flex: 1; min-width: 0; }
.detalle__dato dt { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--sutil); }
.detalle__dato dd { margin: 2px 0 0; font-size: 13px; font-weight: 600; color: var(--texto); }
.detalle__pie { margin: -6px 0 0; text-align: center; line-height: 1.45; }

/* ══ EL BUSCADOR ═══════════════════════════════════════════════════════════════════════════════
   El campo con su lupa, una sola forma para todas las caras. */
.buscador {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--alto-tactil, 48px);
  padding: 0 14px;
  border: 1px solid var(--borde-fuerte);
  border-radius: 12px;
  background: var(--superficie);
  color: var(--tenue);
}
.buscador:focus-within { border-color: var(--primario); }
.buscador input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  font: inherit;
  /* 16 px y no `inherit`: por debajo, iOS hace zoom al enfocar (como en `.campo`, más arriba). */
  font-size: var(--texto-campo, 16px);
  color: var(--texto);
  outline: none;
}
/* La «x» de limpiar que pone el navegador con `type=search`: se le da el color del texto para que no
   sea el gris de sistema del fabricante, que en oscuro desaparece. */
.buscador input::-webkit-search-cancel-button { filter: invert(.5); cursor: pointer; }

/* ══ LA CABEZA DE LA HOJA QUE SUBE ═════════════════════════════════════════════════════════════
   Lo que `<Hojita>` pone arriba de su contenido: el sobrerrótulo, el título y el botón de cerrar. */
.hojita__cabeza { align-items: flex-start; gap: 10px; }
.hojita__kicker { color: var(--primario); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.hojita__titulo { font-family: var(--letra-display); font-size: 22px; font-weight: 800; line-height: 1.15; letter-spacing: -.02em; }
/* El renglón de una lista de opciones (`<Renglon>`): la marca de cheque y el dato vivo. */
.opcion__cheque { flex: none; color: var(--primario); }
.opcion__dato--vivo { color: var(--primario-fuerte); }

/* ── EL SELECTOR DE EMOJIS ──────────────────────────────────────────────────────────────────── */
/* Panel anclado sobre el compositor; las categorías usan botones con estado pulsado. */
.emojis__panel {
  --emojis-toque: max(44px, var(--alto-tactil));
  --emojis-espacio: .5rem;
  --emojis-separacion: .25rem;
  --emojis-alto-maximo: 20rem;
  --emojis-glifo: 1.5rem;
  --emojis-linea: 1px;
  --emojis-foco: 2px;

  position: absolute;
  inset-inline: 0;
  bottom: calc(100% + var(--emojis-espacio));
  z-index: 2;
  box-sizing: border-box;
  min-width: 0;
  max-height: min(var(--emojis-alto-maximo), 40dvh);
  gap: var(--emojis-espacio);
  padding: var(--emojis-espacio);
  padding-bottom: max(var(--emojis-espacio), env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  overscroll-behavior: contain;
  border: var(--emojis-linea) solid var(--borde);
  border-radius: var(--radio-control);
  background: var(--superficie);
  color: var(--texto);
}

/* Sin barra de scroll, con desvanecido: en un teléfono la barra ocupa alto, no se arrastra con
   el dedo y tapa la fila de pestañas. El dedo arrastra igual; sólo se esconde el adorno. El
   desvanecido va sólo del lado final: al principio no hay nada hacia atrás. */
.emojis__categorias {
  flex: none;
  flex-wrap: nowrap;
  gap: var(--emojis-separacion);
  min-width: 0;
  overflow-x: auto;
  padding: var(--emojis-foco);
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
}
.emojis__categorias::-webkit-scrollbar { display: none; }

.emojis__categoria {
  flex: none;
  min-width: var(--emojis-toque);
  min-height: var(--emojis-toque);
  padding: var(--emojis-separacion) var(--emojis-espacio);
  border: var(--emojis-linea) solid var(--borde);
  border-radius: var(--radio-control);
  background: var(--superficie);
  color: var(--tenue);
  font-size: var(--menor);
  white-space: nowrap;
}

.emojis__categoria[aria-pressed="true"] {
  border-color: var(--primario);
  background: var(--fondo);
  color: var(--primario);
}

.emojis__rejilla {
  flex: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--emojis-toque), 1fr));
  gap: var(--emojis-separacion);
  min-width: 0;
}

.emojis__emoji {
  display: grid;
  place-items: center;
  min-width: var(--emojis-toque);
  min-height: var(--emojis-toque);
  padding: var(--emojis-separacion);
  border: var(--emojis-linea) solid var(--borde);
  border-radius: var(--radio-control);
  background: var(--superficie);
  color: var(--texto);
  font-size: var(--emojis-glifo);
  line-height: 1;
}

.emojis__cerrar {
  flex: none;
  align-self: flex-end;
  min-width: var(--emojis-toque);
  min-height: var(--emojis-toque);
  padding: var(--emojis-separacion) var(--emojis-espacio);
  background: var(--superficie);
  color: var(--primario);
  font-size: var(--menor);
}

.emojis__emoji:hover,
.emojis__categoria:hover,
.emojis__cerrar:hover {
  background: var(--fondo);
}

.emojis__panel :focus-visible {
  outline: var(--emojis-foco) solid var(--primario);
  outline-offset: var(--emojis-foco);
}

/* ── EL TAMAÑO DE LETRA PARA LEER ──────────────────────────────────────────────────────────
   Tres pasos que se eligen en Cuenta. `normal` es la ausencia del atributo, igual que `sistema` en
   el tema. Sólo lo multiplican las reglas `.hilo__*`: escalar la app entera descuadraría las demás
   pantallas. */
:root { --escala-lectura: 1; }
:root[data-letra="grande"] { --escala-lectura: 1.15; }
:root[data-letra="mayor"]  { --escala-lectura: 1.32; }
