/* ==========================================================================
   Casa Verdezza Family — app para familiares y amigos autorizados
   Depende de /shared/greenhouse.css.

   Decisiones propias de esta superficie:
   · Texto base 18px (el brief pide 17–18px aquí). Quien la usa puede tener
     70 años o ser un hijo leyendo a oscuras a las 11 de la noche.
   · Una sola columna. Nada compite con la respuesta a "¿cómo está?".
   · La cronología es estructura, no adorno: las novedades son una línea de
     tiempo, igual que el ritmo del día en el sitio público.
   ========================================================================== */

/* La app familiar sube toda la escala a 18px redefiniendo los tokens, no
   tocando la raíz: cambiar `html { font-size }` anularía el tamaño de letra
   que la persona haya configurado en su navegador, que es justo lo contrario
   de lo que necesita este público. Los componentes compartidos (botones,
   campos, badges, estados) heredan la escala nueva sin tocar una línea. */
:root {
  --t-micro: 0.875rem;    /* 14px — versalitas con tracking */
  --t-small: 1.125rem;    /* 18px — secundario */
  --t-body: 1.125rem;     /* 18px — cuerpo */
  --t-body-lg: 1.25rem;   /* 20px */
  --t-lead: 1.375rem;     /* 22px */
}

body { font-size: var(--t-body); }

.view { min-height: 100vh; }

/* ==========================================================================
   Ingreso
   La pantalla, la tarjeta, la bienvenida y el lockup de marca son del
   sistema compartido. Aquí solo el ritmo del formulario.
   ========================================================================== */

#login-submit { margin-top: var(--s-8); }
#login-error { margin-top: var(--s-5); }

/* ==========================================================================
   Barra superior
   ========================================================================== */
/* El logotipo es un enlace al sitio: como control, tiene que cumplir el
   objetivo tactil aunque el arte mida 38px. */
.brand { text-decoration: none; gap: var(--s-3); min-height: var(--tap); }
.brand-logo { height: 38px; width: auto; display: block; }
/* "Family" cuelga del logotipo como una submarca, con el mismo recurso que
   usa el manual: versalita en oro separada por un filete. */
.brand-app {
  padding-left: var(--s-3);
  border-left: 1px solid var(--rule-strong);
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.0625rem; line-height: 1;
  color: var(--accent);
  font-variation-settings: "SOFT" 40, "WONK" 1;
}

/* width:auto anula el width:100% global: aquí es un control de barra, no de formulario. */
.resident-switch select { width: auto; min-width: 190px; font-size: var(--t-small); }

/* ==========================================================================
   Estructura
   ========================================================================== */

/* Cinco pantallas, una visible (ver «Navegación» en app.js). La columna de
   lectura sigue estrecha: 720px es la medida en la que una novedad de tres
   líneas se lee de una pasada. El fondo deja sitio a la barra de abajo
   MIDIÉNDOLA (`--barra-alto`, de GH.publicarAltoDeBarra), no con un número:
   la barra crece cuando sus etiquetas parten en dos líneas. */
main {
  max-width: 720px;
  margin-inline: auto;
  padding: var(--s-5) var(--s-5) calc(var(--barra-alto, 110px) + var(--s-8));
}
.vista {
  display: grid;
  /* minmax(0, 1fr), no 1fr: `1fr` deja que el contenido más ancho reviente la
     pista (a 320px los bloques salían 321px en 288 disponibles). */
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--s-5);
}
.vista[hidden] { display: none; }
.vista:focus { outline: none; }
.vista-titulo {
  margin: var(--s-2) 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.9rem, 6vw, 2.4rem); line-height: 1.1; color: var(--sage);
  font-variation-settings: "SOFT" 50, "WONK" 1;
  letter-spacing: -0.015em;
}

.block { padding: var(--s-8) var(--s-6) var(--s-6); }

/* El rótulo de bloque de Family tiene voz: versalita en oro y título en
   Fraunces. Es la excepción a la regla del sistema —en el resto de
   superficies el rótulo es mobiliario en Atkinson— y está justificada:
   quien abre esto no viene a operar, viene a saber cómo está su madre. */
.block-titulo .label-micro { margin-bottom: var(--s-3); }
.block-head h2 {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--sage);
  font-variation-settings: "SOFT" 50, "WONK" 1;
  letter-spacing: -0.012em;
}
.block-head h2 .icon { color: var(--accent); }

/* A 320px el rótulo de dos líneas y el distintivo de "sin leer" no caben en
   la misma fila: el distintivo no parte (es una píldora) y se salía de la
   tarjeta. Se permite que bajen a dos filas. */
@media (max-width: 420px) {
  .block-head { flex-wrap: wrap; row-gap: var(--s-3); }
  .block-head .badge { order: 3; }
}
.block-refresh { min-width: var(--tap); padding-inline: var(--s-3); }
.block-refresh .icon { width: 19px; height: 19px; transition: transform var(--dur-slow) var(--ease); }
.block-refresh:hover .icon { transform: rotate(-90deg); }

/* ==========================================================================
   Estado del residente — el elemento audaz de esta superficie
   ========================================================================== */

/* Verde plano, no degradado: en Casa Verdezza el único degradado del
   sistema es el isotipo. Lo que da profundidad aquí es el tejado dorado del
   símbolo, dibujado a línea sobre el verde — el mismo recurso que usa la
   sección "Un día" del sitio público. */
.status-card {
  position: relative;
  border-radius: var(--r-xl);
  padding: var(--s-10) var(--s-8);
  background: var(--sage);
  color: var(--paper);
  box-shadow: var(--shadow-float);
  overflow: hidden;
}
.status-card:focus { outline: none; }
/* El tejado del símbolo, dibujado a línea. Se ancla al borde derecho con
   porcentaje —no con un desplazamiento fijo— porque la tarjeta pasa de
   290px en un teléfono a 1560px en escritorio: con un valor fijo, en ancho
   solo asomaba una esquina y el motivo no se reconocía. */
.status-card::before {
  content: ""; position: absolute;
  right: 6%; top: -34%;
  width: min(420px, 52%); aspect-ratio: 1;
  transform: rotate(45deg);
  border-top: 2px solid var(--accent-lit);
  border-left: 2px solid var(--accent-lit);
  border-radius: 54px 0 0 0;
  opacity: 0.3;
  pointer-events: none;
}
.status-card > * { position: relative; }

.status-head { display: flex; align-items: center; gap: var(--s-5); }
/* Por debajo de 420px el nombre completo de una persona y un avatar de 72px
   no caben en la misma línea sin partir el nombre en tres. El avatar sube y
   el nombre se queda con todo el ancho. */
@media (max-width: 420px) {
  .status-head { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
}
/* El avatar es el componente del sistema en su variante grande sobre marca.
   Aquí solo se refuerza el trazo: sobre el verde saturado de la tarjeta, un
   borde de 1.5px se pierde. */
.status-head .avatar { border-width: 2px; }
.status-name {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.6rem, 6vw, 2rem);
  line-height: 1.12;
  font-variation-settings: "SOFT" 60, "WONK" 1;
  margin-bottom: var(--s-2);
}
.status-badges { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.status-badges { margin-top: var(--s-3); }
.status-badges .badge {
  background: color-mix(in srgb, var(--paper) 16%, transparent);
  color: var(--paper);
  border: 1px solid color-mix(in srgb, var(--paper) 22%, transparent);
}
.status-badges .badge::before { background: var(--accent-lit); }
/* "No está en la casa" es la única cosa de esta pantalla que una familia
   necesita ver antes que nada: se sale de la paleta del bloque a propósito. */
.status-badges .badge.is-out { background: var(--paper); color: var(--alert); border-color: var(--paper); }
.status-badges .badge.is-out::before { background: var(--alert); }

/* Tres datos en una fila de vidrio: habitación, antigüedad, última novedad. */
.status-facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin-top: var(--s-8);
  background: color-mix(in srgb, var(--paper) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--paper) 20%, transparent);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.status-fact {
  background: var(--sage-deep);
  padding: var(--s-5) var(--s-3);
  text-align: center;
}
.status-fact dt {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  font-size: var(--t-micro); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent-on-dark);
  margin-bottom: var(--s-3);
}
.status-fact dt .icon { width: 14px; height: 14px; }
.status-fact dd { margin: 0; font-size: var(--t-small); font-weight: 700; line-height: 1.35; color: var(--paper); }

@media (max-width: 480px) {
  .status-card { padding: var(--s-6) var(--s-5); }
  .status-head { gap: var(--s-4); }
  .status-head .avatar { width: 60px; height: 60px; font-size: 1.3125rem; }
  .status-facts { grid-template-columns: 1fr; }
  .status-fact { display: flex; align-items: center; justify-content: space-between; text-align: left; padding: var(--s-3) var(--s-4); }
  /* Apilado, la etiqueta comparte linea con el dato: sin nowrap
     "EN EL HOGAR" partia en dos y desalineaba la fila. */
  .status-fact dt { margin-bottom: 0; white-space: nowrap; }
  .status-fact dd { text-align: right; }
}

/* ==========================================================================
   Novedades
   La línea de tiempo es del sistema. Lo propio de Family es el vocabulario:
   qué tipo de registro es cada novedad.
   ========================================================================== */

.tag.is-vitals { background: var(--teal-wash); color: var(--teal); }

/* La novedad más reciente es la que la familia vino a leer: su punto va en
   oro, el color con el que esta marca señala. Los anteriores se apagan. */
.timeline li:first-child .timeline-dot {
  border-color: var(--accent-lit);
  background: var(--accent-lit);
  box-shadow: 0 0 0 5px var(--accent-wash);
}
.timeline::before { background: linear-gradient(180deg, var(--accent-lit), var(--rule)); }

/* Signos vitales: cifras separadas, no una cadena con puntos medios. */
.vitals { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.vital {
  display: flex; flex-direction: column; gap: 1px;
  padding: var(--s-2) var(--s-4);
  background: var(--pane-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
}
/* Etiqueta en caja baja, asi que respeta el piso de 16px: no es una
   versalita con tracking y no le aplica esa excepcion. */
.vital-label { font-size: var(--t-small); color: var(--ink-faint); font-weight: 700; }
.vital-value { font-size: var(--t-body-lg); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Comunicados
   ========================================================================== */

.notice-item {
  display: grid; grid-template-columns: 12px 1fr;
  gap: 0 var(--s-4);
  padding-block: var(--s-4);
}
.notice-item + .notice-item { border-top: 1px solid var(--rule); }
.notice-dot {
  width: 11px; height: 11px; margin-top: 7px;
  border-radius: 50%;
  background: var(--clay);
  box-shadow: 0 0 0 4px var(--clay-wash);
}
.notice-dot.is-read { background: var(--rule-strong); box-shadow: none; }
.notice-title { font-weight: 700; font-size: var(--t-body-lg); margin-bottom: var(--s-1); }
.notice-body { color: var(--ink-soft); font-size: var(--t-body); max-width: none; }
.notice-meta {
  display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap;
  margin-top: var(--s-3);
  font-size: var(--t-small); color: var(--ink-faint);
}
.notice-item.is-read .notice-title { font-weight: 400; color: var(--ink-soft); }

/* ==========================================================================
   Fotografías
   ========================================================================== */

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: var(--s-3); }
.gallery-item {
  position: relative;
  padding: 0; border: 1px solid var(--rule); border-radius: var(--r-md);
  background: var(--pane-soft);
  aspect-ratio: 1;
  overflow: hidden;
  cursor: pointer; touch-action: manipulation;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur-fast) var(--ease-soft);
}
.gallery-item:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--sage); }
.gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-item.is-loading { animation: gh-shimmer 1.4s ease-in-out infinite; background: linear-gradient(90deg, var(--paper-sunk) 25%, #eef3ec 37%, var(--paper-sunk) 63%); background-size: 400% 100%; }

/* Visor */
.lightbox {
  position: fixed; inset: 0; z-index: 95;
  display: grid; place-items: center;
  padding: var(--s-5);
  background: rgba(18, 37, 27, 0.82);
  backdrop-filter: blur(6px);
  animation: gh-fade-in var(--dur-fast) var(--ease-soft);
}
.lightbox.is-leaving { animation: gh-fade-out var(--dur-fast) var(--ease-soft) forwards; }
.lightbox-inner {
  position: relative;
  max-width: min(760px, 100%);
  animation: lightbox-in var(--dur) var(--ease);
}
@keyframes lightbox-in { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }
.lightbox img {
  display: block;
  max-width: 100%; max-height: 74vh;
  border-radius: var(--r-lg);
  background: var(--pane);
  box-shadow: var(--shadow-float);
}
.lightbox-caption { margin-top: var(--s-4); color: #fff; text-align: center; font-size: var(--t-small); }
.lightbox-close { position: absolute; top: calc(-1 * var(--s-12)); right: 0; background: rgba(255,255,255,0.16); color: #fff; }
.lightbox-close:hover { background: #fff; color: var(--ink); }

/* ==========================================================================
   Responsive — 320 / 375 / 390 / 768 / 1024 / 1280 / 1440 / 1920
   ========================================================================== */

@media (max-width: 560px) {
  main { padding: var(--s-4) var(--s-4) var(--s-16); gap: var(--s-4); }
  .block { padding: var(--s-5); }
  /* `.logout-text` y `.perfil-text` los esconde `/shared` en este mismo ancho:
     las dos etiquetas de la barra se comportan igual en todas las superficies. */
  .resident-switch select { min-width: 0; max-width: 46vw; }
  .lightbox-close { top: calc(-1 * var(--s-10)); }
}

/* --------------------------------------------------------------------------
   Escritorio: la composición cambia, la medida de lectura no.
   Hasta ahora esta app era una columna de 720px centrada, así que a 1440px
   quedaba con dos tercios de pantalla vacíos y las fotografías —lo que más
   quiere ver la familia— caían por debajo del pliegue, a tres scrolls del
   estado. En dos columnas, "cómo está" sigue mandando a todo lo ancho y
   debajo el lector elige entre leer (izquierda) o mirar (derecha), sin
   ensanchar ni una línea de texto: la columna de novedades se queda en
   sus 68ch.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) {
  main { max-width: 1180px; padding-top: var(--s-8); }
  /* «Hoy» en dos columnas: el estado manda a todo lo ancho y debajo se elige
     entre leer (novedades, medicación, comida) o mirar (las fotos). */
  #vista-hoy {
    grid-template-columns: minmax(0, 1.35fr) minmax(320px, 1fr);
    grid-template-areas: "estado estado" "novedades fotos" "medicacion fotos" "comida fotos";
    gap: var(--s-6);
  }
  #vista-hoy #status-card { grid-area: estado; }
  #vista-hoy #novedades-card { grid-area: novedades; }
  #vista-hoy #medicacion-card { grid-area: medicacion; }
  #vista-hoy #comida-card { grid-area: comida; }
  #vista-hoy #gallery-card { grid-area: fotos; }
  /* Cada bloque mide lo que mide su contenido: una caja medio vacía estirada
     se lee como "falta algo". */
  #vista-hoy > .block { align-self: start; }
  /* El resto de pantallas conserva la medida de lectura. */
  /* Pegado al menú, no centrado: centrado dejaba un hueco de 300px entre el
     menú y lo que se lee, y el ojo no sabía a qué pertenecía cada cosa. */
  #vista-agenda, #vista-mensajes, #vista-cuenta { max-width: 760px; margin-inline: 0; width: 100%; }
  .gallery { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); }
}

/* Por encima de 1600px no se sigue ensanchando: se centra y se deja respirar.
   Una pantalla de 1920px no es una invitación a llenar 1920px. */
@media (min-width: 1600px) {
  main { padding-block: var(--s-10) var(--s-24); gap: var(--s-8); }
}

/* ==========================================================================
   Alimentación
   Vocabulario de dominio de Family: qué significa "comió bien" aquí.

   No hay rojo. Un consumo bajo se marca con un filete de color tierra y se
   cuenta con palabras; convertirlo en alerta haría que una hija que abre esto
   a las once de la noche llamara asustada por algo que enfermería ya vio.
   ========================================================================== */

.comida-dia {
  font-family: var(--font-body); font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--s-3);
}

.comida-lista { list-style: none; display: grid; gap: var(--s-2); }

.comida-fila {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  gap: var(--s-4);
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--paper);
  /* El filete de la izquierda es el único código de color de este bloque. */
  border-left: 3px solid var(--rule-strong);
}

.comida-fila.tono-bien { border-left-color: var(--sage); }
.comida-fila.tono-normal { border-left-color: var(--rule-strong); }
.comida-fila.tono-ojo { border-left-color: var(--clay); }

.comida-tiempo {
  font-weight: 700;
  color: var(--ink-soft);
}

.comida-consumo { font-weight: 700; }
.comida-plato { color: var(--ink-soft); margin-top: 2px; }
.comida-nota {
  margin-top: var(--s-2);
  color: var(--ink-soft);
  font-style: italic;
}

.comida-pendiente, .comida-resumen { color: var(--ink-soft); }

.comida-resumen {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
}

@media (max-width: 480px) {
  /* El nombre del tiempo pasa arriba: a 320px, dos columnas dejarían "Refrigerio
     de la noche" partido en tres líneas al lado de una sola de texto. */
  .comida-fila { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); }
}

/* ==========================================================================
   Mensajes con el equipo — solo lo propio de Family
   La conversación (burbujas, acuse, formulario) es lenguaje COMPARTIDO y vive
   en /shared: Care pinta la otra mitad de este mismo hilo. Aquí queda la voz
   de esta superficie y lo que solo existe de este lado.
   ========================================================================== */

/* El aviso de urgencias no existe en Care: allí el equipo ES el hogar. Va
   ARRIBA y se queda SIEMPRE, no solo la primera vez — alguien va a escribir
   "mi mamá se cayó" aquí si no se lo recordamos cada vez que abre el bloque.
   En azul, que es el color con el que este sistema informa; en rojo parecería
   que algo va mal ahora mismo. */
.msg-urgencias {
  display: flex; align-items: flex-start; gap: var(--s-3);
  padding: var(--s-4);
  margin-bottom: var(--s-5);
  border-radius: var(--r-md);
  background: var(--teal-wash);
  color: var(--teal);
}
.msg-urgencias .icon { width: 20px; height: 20px; flex: none; margin-top: 2px; }

.msg-vacio { color: var(--ink-soft); }

/* Lo que escribe la familia lleva el oro de la marca. Family es la superficie
   que puede permitírselo; Care hereda el filete neutro de /shared porque ahí
   el oro decorativo no entra. */
.msg-mio { border-right-color: var(--accent); }

@media (max-width: 480px) {
  .msg-form .btn { width: 100%; justify-content: center; }
}

/* ==========================================================================
   Actividades
   Lo que más gusta ver a una familia. Igual que en alimentación: se cuenta,
   no se alarma. "No quiso bajar" se dice tal cual, con la nota de quien
   estaba; quien decide si eso importa es el equipo, no esta pantalla.
   ========================================================================== */

.act-lista { list-style: none; display: grid; gap: var(--s-3); }

.act-fila {
  display: grid;
  grid-template-columns: minmax(0, 7.5rem) minmax(0, 1fr);
  gap: var(--s-4);
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--paper);
  border-left: 3px solid var(--rule-strong);
}
.act-fila.tono-bien { border-left-color: var(--sage); }
.act-fila.tono-normal { border-left-color: var(--rule-strong); }
.act-fila.tono-ojo { border-left-color: var(--clay); }

.act-cuando { font-weight: 700; color: var(--ink-soft); }
.act-titulo { font-weight: 700; }
.act-como { color: var(--ink-soft); margin-top: 2px; }
.act-nota { margin-top: var(--s-2); color: var(--ink-soft); font-style: italic; }

.act-vacio, .act-resumen { color: var(--ink-soft); }
.act-resumen {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
}

@media (max-width: 480px) {
  .act-fila { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); }
}

/* ==========================================================================
   CITAS MÉDICAS
   Para la familia una cita es "cuándo le toca" y "qué dijeron". Ni el
   transporte ni el estado interno le dicen nada, así que no aparecen.
   ========================================================================== */

.cita-proxima {
  background: var(--sage-wash);
  border-radius: var(--r-md);
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-4);
}
.cita-cuando { margin: var(--s-2) 0 0; font-size: 1.25rem; }
.cita-que { margin: var(--s-2) 0 0; }
.cita-donde, .cita-acompana { margin: var(--s-2) 0 0; color: var(--ink-soft); font-size: var(--t-small); }

.cita-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.cita-lista li { padding-block: var(--s-2); border-top: 1px solid var(--rule); }
.cita-lista li:first-child { border-top: none; }
.cita-resultado { display: block; color: var(--ink-soft); font-size: var(--t-small); margin-top: 4px; }

.cita-historia { margin-top: var(--s-5); padding-top: var(--s-4); border-top: 1px solid var(--rule); }
.cita-nota { margin: var(--s-4) 0 0; color: var(--ink-faint); font-size: var(--t-small); }

/* ==========================================================================
   Terapias
   Lo que la familia mira aquí es una sola cosa: si se está cumpliendo. Por
   eso el objetivo va en una línea y el avance ocupa el espacio.
   ========================================================================== */

.ter-lista { list-style: none; display: grid; gap: var(--s-4); }

.ter-fila {
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--paper);
  border-left: 3px solid var(--rule-strong);
}

.ter-disciplina { font-weight: 700; }
.ter-objetivo { color: var(--ink-soft); margin-top: 2px; }

.ter-avance { margin-top: var(--s-4); }

.ter-barra {
  height: 10px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--ink) 10%, transparent);
  overflow: hidden;
}
.ter-barra span {
  display: block; height: 100%;
  border-radius: var(--r-pill);
  background: var(--rule-strong);
}
/* El color lo pone el contenedor, no el relleno: así la barra y el filete
   izquierdo de la tarjeta no pueden acabar diciendo cosas distintas. */
.ter-avance.tono-bien  .ter-barra span { background: var(--sage); }
.ter-avance.tono-medio .ter-barra span { background: var(--clay); }
.ter-avance.tono-bajo  .ter-barra span { background: var(--alert); }

.ter-cifra { margin-top: var(--s-2); color: var(--ink-soft); }
.ter-cifra b { color: var(--ink); }

.ter-nota { margin: var(--s-4) 0 0; color: var(--ink-faint); font-size: var(--t-small); }

/* ==========================================================================
   Visitas

   El ESTADO se lee antes que la fecha, y por eso lleva su propio filete de
   color y su línea de texto: quien ve "sábado 3:00" sin más se presenta el
   sábado. El color acompaña a la palabra, nunca la sustituye.
   ========================================================================== */

.visita-horario {
  color: var(--ink-soft);
  margin: 0 0 var(--s-4);
}

.visita-lista { list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: var(--s-3); }
.visita {
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--paper-sunk);
  box-shadow: inset 4px 0 0 var(--rule-strong);
}
.visita.es-bien   { box-shadow: inset 4px 0 0 var(--sage); }
.visita.es-espera { box-shadow: inset 4px 0 0 var(--accent-lit); }
.visita.es-mal    { box-shadow: inset 4px 0 0 var(--alert); }
.visita-cuando { margin: 0; }
.visita-estado { margin: var(--s-1) 0 0; color: var(--ink-soft); font-weight: 700; }
.visita-motivo { margin: var(--s-2) 0 0; color: var(--ink-soft); }
.visita-gente  { margin: var(--s-1) 0 0; color: var(--ink-faint); }
.visita .btn { margin-top: var(--s-3); }

.visita-form { border-top: 1px solid var(--rule); padding-top: var(--s-5); }
.visita-titulo { font-family: var(--font-display); font-size: 1.15rem; margin: 0 0 var(--s-4); }
/* La aclaración va DEBAJO del botón, no encima: se lee justo después de
   pulsar, que es cuando alguien decide si ya puede contar con la visita. */
.visita-aclaracion { margin: var(--s-3) 0 0; color: var(--ink-soft); text-align: center; }

/* ==========================================================================
   Pedidos. La ficha de cada pedido es la de la visita (mismo filete de
   estado); aquí solo va el catálogo y su selector de cantidad.
   ========================================================================== */

.pedido .btn + .btn { margin-left: var(--s-2); }
.pedido-arts { list-style: none; margin: 0; padding: 0; }
/* min-width + overflow-wrap: un nombre largo sin espacios desbordaba la fila
   en la medicación; aquí se previene desde el principio. */
.pedido-art-txt { flex: 1; min-width: 0; }
.pedido-art-nombre { margin: 0; font-weight: 700; overflow-wrap: anywhere; line-height: 1.3; }
.pedido-art-precio { margin: var(--s-2) 0 0; font-size: var(--t-body-lg); font-weight: 700; color: var(--ink); }
.pedido-disp, .pedido-nodisp { margin: var(--s-1) 0 0; }
.pedido-disp { color: var(--sage-deep); }
.pedido-nodisp { color: var(--ink-soft); }
.pedido-art-cob { margin: var(--s-1) 0 0; color: var(--teal); }
.pedido-cant { display: flex; align-items: center; justify-content: space-between; gap: var(--s-1); flex: none; }
.pedido-cant .icon-btn { font-size: 1.4rem; font-weight: 700; border: 1px solid var(--rule-strong); border-radius: 999px; background: var(--pane); }
.pedido-cant .icon-btn:disabled { opacity: 0.35; cursor: default; }
.pedido-cant output { min-width: 2ch; text-align: center; font-weight: 700; font-size: var(--t-body-lg); }
.pedido-resumen { margin: 0 0 var(--s-4); font-size: var(--t-body-lg); }
.pedido-nopuede { margin: 0 0 var(--s-4); padding: var(--s-3) var(--s-4); background: var(--paper-sunk); border-radius: var(--r-md); }
.pedido-aviso { margin: var(--s-5) 0 0; color: var(--ink-soft); }

/* ==========================================================================
   Tienda: tarjetas en rejilla, como cualquier tienda del teléfono.
   Sin fotos de producto —el catálogo es la bodega del hogar—: cada categoría
   tiene su dibujo sobre un fondo de su color, y eso basta para reconocer
   «pañales» sin leer. El precio va grande: es lo segundo que se busca.
   ========================================================================== */

/* La tienda no necesita el rótulo del bloque: el título de la pantalla ya lo
   dice, y repetirlo empuja las tarjetas medio teléfono más abajo. */
#pedidos-card { padding: 0; background: none; border: none; box-shadow: none; }
#pedidos-card > .block-head { display: none; }

.tienda-filtros {
  display: flex; gap: var(--s-2);
  overflow-x: auto; scrollbar-width: none;
  /* Se desliza dentro de su columna, sin sangrar hasta el borde: el relleno
     de \`main\` cambia por ancho (16 o 20px) y un margen negativo fijo dejaba
     4px de desplazamiento horizontal en toda la página. */
  margin: 0 0 var(--s-5);
  padding: 2px;
}
.tienda-filtros::-webkit-scrollbar { display: none; }
.tienda-filtros .segment { flex: none; white-space: nowrap; }

.tienda-grid {
  display: grid;
  /* Dos columnas también a 320px: una sola convierte la tienda en una lista
     larga y se pierde la vista de escaparate. */
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: var(--s-3);
}
.tienda-card {
  display: flex; flex-direction: column;
  padding: var(--s-3);
  background: var(--pane);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-pane);
  transition: border-color var(--dur-fast) var(--ease-soft), box-shadow var(--dur-fast) var(--ease-soft);
}
.tienda-card.en-carrito { border-color: var(--sage); box-shadow: 0 0 0 2px var(--sage-wash); }
.tienda-card .pedido-art-txt { padding: var(--s-3) var(--s-1) 0; }
.tienda-presentacion { margin: 2px 0 0; color: var(--ink-soft); }
.tienda-accion { margin-top: auto; padding-top: var(--s-3); }
.tienda-agregar { width: 100%; justify-content: center; gap: var(--s-2); }
.tienda-agregar .icon { width: 20px; height: 20px; }

.tienda-foto {
  display: grid; place-items: center;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  background: var(--sage-wash); color: var(--sage);
}
.tienda-foto .icon { width: 44%; height: auto; max-width: 64px; stroke-width: 1.4; }
.tienda-foto.cat-aseo { background: var(--teal-wash); color: var(--teal); }
.tienda-foto.cat-ropa { background: var(--accent-wash); color: var(--accent); }
.tienda-foto.cat-papeleria { background: var(--clay-wash); color: var(--clay); }
.tienda-foto.cat-otro { background: var(--paper-sunk); color: var(--ink-soft); }
.tienda-foto.is-sm { aspect-ratio: 1; width: 52px; flex: none; }
.tienda-foto.is-sm .icon { width: 26px; }

.tienda-pedidos { margin-top: var(--s-8); }

/* La barra del carrito flota justo encima del menú. Su `bottom` sale del alto
   del menú (`--fam-nav-alto`, medido), NO de `--barra-alto`: esta barra también
   cuenta en `--barra-alto`, y atarla a esa variable la haría subir cada vez
   que se mide a sí misma. */
.carrito-barra {
  position: fixed; z-index: 29;
  left: var(--s-3); right: var(--s-3);
  bottom: calc(var(--fam-nav-alto, 90px) + var(--s-2));
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 56px;
  padding: var(--s-2) var(--s-4) var(--s-2) var(--s-2);
  border: none; border-radius: var(--r-pill);
  background: var(--sage); color: #fff;
  font-family: inherit; font-size: var(--t-body); text-align: left;
  box-shadow: var(--shadow-float);
  cursor: pointer;
  animation: gh-sube var(--dur) var(--ease);
}
.carrito-barra[hidden] { display: none; }
.carrito-barra:active { transform: scale(0.99); }
.carrito-barra-icono {
  position: relative; display: grid; place-items: center;
  width: 42px; height: 42px; flex: none;
  border-radius: 50%; background: rgba(255, 255, 255, 0.16);
}
.carrito-barra-icono .icon { width: 22px; height: 22px; }
.carrito-barra-icono b {
  position: absolute; top: -4px; right: -6px;
  min-width: 22px; height: 22px; padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--accent-on-dark); color: var(--sage-deep);
  font-size: var(--t-micro); line-height: 22px; text-align: center;
}
.carrito-barra-txt { flex: 1; min-width: 0; font-weight: 700; overflow-wrap: anywhere; }
.carrito-barra-ver { flex: none; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
@keyframes gh-sube { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .carrito-barra { animation: none; } }
@media (min-width: 860px) {
  .carrito-barra { left: auto; right: var(--s-6); bottom: var(--s-6); max-width: 440px; }
}

.carrito-lineas { list-style: none; margin: 0 0 var(--s-5); padding: 0; display: grid; gap: var(--s-3); }
.carrito-linea {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  padding: var(--s-3); background: var(--paper); border-radius: var(--r-md);
}
.carrito-linea-txt { flex: 1; min-width: 0; }
.carrito-linea-precio { margin: 2px 0 0; color: var(--ink-soft); }
.carrito-linea .pedido-cant { margin-left: auto; }

/* ==========================================================================
   Cuenta: cuánto se debe, en grande, y el botón para pagarlo.
   ========================================================================== */

.cuenta-saldo {
  padding: var(--s-5);
  border-radius: var(--r-lg);
  background: var(--paper);
  border: 1px solid var(--rule);
  text-align: center;
}
.cuenta-saldo.es-vencido { border-color: var(--clay); background: var(--clay-wash); }
.cuenta-saldo.es-al-dia { background: var(--sage-wash); border-color: var(--sage-line); }
.cuenta-cifra {
  margin: var(--s-2) 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(2.2rem, 9vw, 3rem); line-height: 1.1;
  color: var(--sage-deep);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.cuenta-favor { margin: var(--s-2) 0 0; color: var(--sage-deep); }
.cuenta-pagar { margin-top: var(--s-5); gap: var(--s-2); justify-content: center; }
.cuenta-pagar .icon { width: 22px; height: 22px; }
.cuenta-medios { margin: var(--s-3) 0 0; color: var(--ink-soft); }
.cuenta-pruebas { margin: var(--s-2) 0 0; color: var(--clay); font-weight: 700; }

.cuenta-lista { list-style: none; margin: var(--s-4) 0 var(--s-5); padding: 0; display: grid; gap: var(--s-2); }
.cuenta-fila-dato {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--paper); border-radius: var(--r-md);
  border-left: 4px solid var(--rule-strong);
}
.cuenta-fila-dato > span { min-width: 0; overflow-wrap: anywhere; }
.cuenta-fila-dato small { display: block; font-size: var(--t-small); color: var(--ink-soft); }
.cuenta-fila-dato b { flex: none; font-variant-numeric: tabular-nums; }
/* En un teléfono estrecho el concepto («Mensualidad octubre · Plan…») quedaba
   en una columna de ocho letras junto al precio. Abajo, la cifra baja a su
   propia línea, alineada a la derecha. */
@media (max-width: 420px) {
  .cuenta-fila-dato { flex-wrap: wrap; }
  .cuenta-fila-dato > span { flex: 1 1 100%; }
  .cuenta-fila-dato b { margin-left: auto; }
}
.cuenta-fila-dato.es-vencido { border-left-color: var(--clay); }
.cuenta-fila-dato.es-pago, .cuenta-fila-dato.es-aprobado { border-left-color: var(--sage); }
.cuenta-fila-dato.es-rechazado, .cuenta-fila-dato.es-error { border-left-color: var(--alert); }

/* ¿Qué quieres pagar? Una fila por concepto —mensualidad, productos, todo,
   un pedido por adelantado—, cada una con su cifra y su botón. La primera
   va rellena: es la que casi siempre se viene a pagar. */
.cuenta-opciones { list-style: none; margin: var(--s-3) 0 0; padding: 0; display: grid; gap: var(--s-2); }
.cuenta-opcion {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  gap: var(--s-2) var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--pane); border: 1px solid var(--rule); border-radius: var(--r-md);
}
.cuenta-opcion-txt { min-width: 0; overflow-wrap: anywhere; }
.cuenta-opcion-txt small { display: block; font-size: var(--t-small); color: var(--ink-soft); }
.cuenta-opcion-cifra { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--sage-deep); text-align: right; }
.cuenta-opcion .btn { grid-column: 1 / -1; justify-content: center; gap: var(--s-2); }
@media (min-width: 560px) {
  .cuenta-opcion { grid-template-columns: minmax(0, 1fr) auto auto; }
  .cuenta-opcion .btn { grid-column: auto; }
}

/* El pedido pagado por adelantado y el botón de pagarlo, en su ficha. */
.pedido-pagado { display: flex; align-items: center; gap: var(--s-2); margin: var(--s-2) 0 0; color: var(--sage-deep); font-weight: 700; }
.pedido-pagado .icon { width: 20px; height: 20px; flex: none; }
.visita.pedido [data-pagar-pedido] { margin-top: var(--s-3); gap: var(--s-2); }

/* «Pedido enviado»: pagarlo ya o después. */
.pedido-hecho { text-align: center; }
.pedido-hecho-icono { margin: 0 0 var(--s-2); color: var(--sage); }
.pedido-hecho-icono .icon { width: 56px; height: 56px; }
.pedido-hecho .btn { margin-top: var(--s-3); gap: var(--s-2); justify-content: center; }

/* Su armario: cada artículo con cuánto le dura. Lo que se acaba, en terracota
   y con el aviso escrito: el color solo no lo lee todo el mundo. */
.armario-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.armario-item {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3);
  background: var(--paper); border-radius: var(--r-md);
  border-left: 4px solid var(--sage-line);
}
.armario-item.se-acaba { border-left-color: var(--clay); background: var(--clay-wash); }
.armario-txt { min-width: 0; overflow-wrap: anywhere; }
.armario-txt .pedido-art-nombre { margin: 0; }
.armario-dias { display: flex; align-items: center; gap: var(--s-1); margin: 2px 0 0; color: var(--ink-soft); }
.armario-item.se-acaba .armario-dias { color: var(--clay); font-weight: 700; }
.armario-dias .icon { width: 18px; height: 18px; flex: none; }
#armario-card .visita-titulo { margin-top: var(--s-5); }

.cuenta-otros { padding: var(--s-2); display: grid; }
.cuenta-fila {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: var(--tap); padding: var(--s-3) var(--s-4);
  border: none; border-radius: var(--r-md); background: none;
  font-family: inherit; font-size: var(--t-body); font-weight: 700; color: var(--ink);
  text-align: left; cursor: pointer;
}
.cuenta-fila + .cuenta-fila { border-top: 1px solid var(--rule); border-radius: 0; }
.cuenta-fila:hover { background: var(--sage-wash); }
.cuenta-fila .icon { color: var(--sage); }

/* El menú de abajo en Family: con cinco pestañas cabe a 320px con la letra a
   18px; el componente es el compartido de Care. */
.fam-tabs .tab-count { background: var(--clay); }

/* ==========================================================================
   Avisos en el teléfono

   El texto que explica qué NO se manda pesa más que el botón, y es a
   propósito: quien activa esto está dando permiso para que aparezcan cosas
   en su pantalla de bloqueo.
   ========================================================================== */

.push-que { margin: 0 0 var(--s-4); }
.push-urgencias {
  margin: var(--s-4) 0;
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--paper-sunk);
  color: var(--ink-soft);
}

/* ==========================================================================
   Actividades abiertas

   La que ya se confirmó se marca en verde y cambia lo que ofrece: mientras
   una diga "Vamos a ir" y la otra "Al final no podemos", nadie tiene que
   leer dos veces para saber en cuál está apuntado.
   ========================================================================== */

.abierta-intro { margin: 0 0 var(--s-4); color: var(--ink-soft); }
.abierta-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); }
.abierta {
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--paper-sunk);
  box-shadow: inset 4px 0 0 var(--rule-strong);
}
.abierta.es-voy { box-shadow: inset 4px 0 0 var(--sage); }
.abierta-cuando { margin: 0; }
.abierta-titulo { margin: var(--s-1) 0 0; font-weight: 700; }
.abierta-desc { margin: var(--s-2) 0 0; color: var(--ink-soft); }
.abierta-cuenta { margin: var(--s-2) 0 0; color: var(--ink-faint); }
.abierta-voy { margin: var(--s-3) 0 var(--s-2); }
.abierta-ir { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); margin-top: var(--s-3); }
.abierta-ir label { margin: 0; }
.abierta-ir input { width: 5rem; }


/* ------------------------------------------------ Medicación de hoy
   Lo REGISTRADO, no un horario. El diseño del estudio mostraba «2 de 4
   administrados» y estados «Pendiente»; el sistema no guarda a qué hora toca
   cada dosis (`frecuencia` es texto libre), así que esa cuenta no existe y
   pintarla sería inventarle una alarma a una familia.                      */

.medicacion-cuenta {
  margin-bottom: var(--s-4);
  color: var(--ink-soft);
}

.medicacion-lista { list-style: none; margin: 0; padding: 0; }

.medicacion-lista li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: var(--s-3);
  padding-block: var(--s-4);
}
.medicacion-lista li + li { border-top: 1px solid var(--rule); }

/* La hora primero y en cifras tabulares: la columna se lee en vertical sin
   que los dígitos bailen de una fila a otra. */
.medicacion-hora {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink-faint);
}

.medicacion-que {
  display: flex; flex-direction: column; gap: 2px;
  /* Las DOS cosas, o un nombre largo sin espacios desborda la fila entera:
     dejar que la columna se encoja (`min-width: 0`) y permitir partir la
     palabra. «Trimetoprima/Sulfametoxazol» existe, y lo encontro una inyeccion
     deliberada en la auditoria — 550px de ancho en una ventana de 375.
     Misma leccion que las etiquetas de la barra de Care. */
  min-width: 0;
  overflow-wrap: anywhere;
}
.medicacion-dosis { color: var(--ink-soft); }
.medicacion-nota { color: var(--ink-soft); }

.medicacion-nota-pie {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px dashed var(--rule);
  color: var(--ink-faint);
}

/* En un teléfono estrecho la etiqueta de resultado baja a su propia línea:
   apretada contra el nombre del medicamento, los dos se parten mal. */
@media (max-width: 460px) {
  .medicacion-lista li { grid-template-columns: auto 1fr; }
  .medicacion-lista li > .tag { grid-column: 2; justify-self: start; }
}

/* ------------------------------------------- El resumen del día, firmado
   La frase que preside la tarjeta verde: lo que una familia viene a leer.
   Solo aparece si hay una novedad de HOY — una de hace tres días presidiendo
   la pantalla dice «así está tu madre» sobre algo que ya no es hoy.         */

.status-resumen {
  margin-top: var(--s-4);
  color: var(--paper);
  line-height: 1.5;
}
/* La firma, en el verde claro que SÍ se lee sobre el verde de marca (5.8:1).
   En bloque propio: pegada al final del texto parecería parte de la frase. */
.status-firma {
  display: block;
  margin-top: var(--s-2);
  color: var(--sage-line);
  font-size: var(--t-small);
}

/* Quién escribió cada entrada de la línea de tiempo. */
.timeline-autor {
  margin-top: var(--s-2);
  color: var(--ink-faint);
  font-size: var(--t-small);
}

/* Cinco pestañas a 18px no caben en un teléfono: «Agenda» se partía en
   «Agend-a». Bajan a 16px —el piso del sistema, no por debajo— y se estrechan
   márgenes y relleno. Medido con la fuente cargada: a 320px cada pestaña da
   ~59px y la etiqueta más ancha («Agenda») mide 57. «Mensajes» (71px) no
   cabía ni a 375 y se partía en «Mensa-jes»: por eso la pestaña dice «Chat».
   Si se añade o renombra una, se vuelve a medir (web/tools/family-app.js). */
@media (max-width: 859px) {
  .fam-tabs { left: var(--s-2); right: var(--s-2); padding: 4px; }
}
.fam-tabs .tab { font-size: 1rem; padding-inline: 0; }

/* ==========================================================================
   Escritorio: el menú pasa a la IZQUIERDA.
   Abajo es para el pulgar; en una pantalla ancha no hay pulgar, y la barra
   compartida (que en Care sube a una fila pegada arriba) aquí acababa al FINAL
   de la página, porque en el documento va después del contenido. Una columna
   lateral fija es lo que cualquiera reconoce como el menú de una aplicación,
   y deja las cinco opciones a la vista sin quitarle alto al contenido.
   ========================================================================== */
@media (min-width: 860px) {
  #view-dashboard {
    display: grid;
    grid-template-columns: 248px minmax(0, 1fr);
    grid-template-areas: "barra barra" "menu contenido";
    /* La segunda fila se lleva el alto que sobra. Sin esto, en una pantalla
       con poco contenido (`.view` mide al menos 100vh) la rejilla repartía
       ese alto entre las dos filas y la barra superior crecía medio metro. */
    grid-template-rows: auto 1fr;
    column-gap: var(--s-6);
    align-items: start;
  }
  #view-dashboard > .topbar { grid-area: barra; }
  #view-dashboard > main { grid-area: contenido; margin-inline: 0; max-width: 1180px; padding-left: 0; }

  .fam-tabs {
    grid-area: menu;
    /* Pegado bajo la barra superior, MEDIDA (`--fam-topbar-alto`, ver
       navegación en app.js), no con un número: la barra crece si el nombre
       del residente es largo. */
    position: sticky; top: calc(var(--fam-topbar-alto, 76px) + var(--s-5));
    left: auto; right: auto; bottom: auto;
    margin: var(--s-8) 0 var(--s-8) var(--s-5);
    max-width: none;
    display: flex; flex-direction: column; gap: var(--s-1);
    padding: var(--s-3);
    background: var(--pane);
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-pane);
  }
  .fam-tabs .tab {
    flex-direction: row; justify-content: flex-start; gap: var(--s-3);
    min-height: 52px;
    padding: var(--s-2) var(--s-4);
    border-radius: var(--r-md);
    font-size: var(--t-body);
    text-align: left;
    color: var(--ink-soft);
  }
  .fam-tabs .tab:hover { background: var(--paper); color: var(--sage-deep); }
  .fam-tabs .tab[aria-selected="true"] { background: var(--sage-wash); color: var(--sage-deep); }
  /* El filete que marca la activa pasa de arriba a la izquierda. */
  .fam-tabs .tab::before {
    top: 22%; bottom: 22%; left: 0; right: auto;
    width: 3px; height: auto;
    border-radius: 0 3px 3px 0;
    /* Con solo `scaleY(0)` quedaba un punto de 3px en cada opción inactiva
       (el redondeo del filete no colapsa del todo en pantallas de 2x). */
    transform: scaleY(0);
    opacity: 0;
    transition: transform var(--dur) var(--ease), opacity var(--dur-fast) var(--ease-soft);
  }
  .fam-tabs .tab[aria-selected="true"]::before { transform: scaleY(1); opacity: 1; }
  .fam-tabs .tab-count { position: static; transform: none; margin-left: auto; }
}

/* ==========================================================================
   Instalación obligatoria (solo teléfono): una hoja que SUBE desde abajo.
   Flota sobre el ingreso, que se ve detrás atenuado: así se entiende que la
   aplicación está ahí y lo que falta es instalarla. No tiene «cerrar» ni se
   va tocando fuera — en el teléfono no se sigue sin instalar.
   ========================================================================== */
.instalar-capa {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(20, 38, 31, 0.48);
  animation: gh-fade-in var(--dur) var(--ease-soft);
}
.instalar-capa[hidden] { display: none; }
.instalar-hoja {
  width: 100%; max-width: 560px;
  max-height: 92vh; overflow-y: auto;
  padding: var(--s-3) var(--s-6) calc(var(--s-6) + env(safe-area-inset-bottom, 0px));
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  border-bottom: none;
  box-shadow: var(--shadow-float);
  animation: gh-hoja-sube var(--dur-slow) var(--ease);
}
.instalar-hoja:focus { outline: none; }
@keyframes gh-hoja-sube { from { transform: translateY(100%); } to { transform: none; } }
@keyframes gh-fade-in { from { opacity: 0; } to { opacity: 1; } }
/* El asa dice «esto es una hoja», aunque esta no se arrastre. */
.instalar-asa { display: block; width: 44px; height: 5px; margin: 0 auto var(--s-5); border-radius: 3px; background: var(--rule-strong); }
.instalar-cabeza { display: flex; align-items: center; gap: var(--s-4); }
.instalar-cabeza .label-micro { margin: 0 0 var(--s-1); }
.instalar-icono { border-radius: 16px; box-shadow: var(--shadow-pane); flex: none; }
.instalar-titulo {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.5rem; line-height: 1.15; color: var(--sage);
  font-variation-settings: "SOFT" 50, "WONK" 1;
}
.instalar-porque { margin: var(--s-5) 0; color: var(--ink-soft); }
.instalar-lista { margin: 0 0 var(--s-5); padding-left: 1.4em; display: grid; gap: var(--s-3); }
.instalar-lista li { padding-left: var(--s-1); }
.instalar-lista .icon { width: 22px; height: 22px; vertical-align: -5px; color: var(--teal); }
.instalar-boton { gap: var(--s-2); justify-content: center; min-height: 56px; font-size: var(--t-body-lg); }
.instalar-nota { margin: var(--s-3) 0 0; color: var(--ink-soft); text-align: center; }
.instalar-ayuda { margin: var(--s-5) 0 0; color: var(--ink-soft); text-align: center; }
#instalar-pago { margin-top: var(--s-5); }
@media (prefers-reduced-motion: reduce) {
  .instalar-capa, .instalar-hoja { animation: none; }
}

/* Instalada, la app ocupa toda la pantalla, también bajo la muesca: la barra
   de arriba se separa del borde lo que el sistema diga. */
@media (display-mode: standalone) {
  .topbar { padding-top: calc(var(--s-3) + env(safe-area-inset-top, 0px)); }
}

/* En escritorio, las tarjetas de la tienda a su tamaño de tarjeta: con el
   mínimo del teléfono (128px) salían cinco columnas de nombres partidos. */
@media (min-width: 860px) {
  .tienda-grid { grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: var(--s-4); }
}

/* El aviso de instalación del computador: una barra FLOTANTE abajo, centrada,
   que aparece al abrir. Pide sin obligar: «Instalar» o «Ahora no». */
.instalar-aviso {
  position: fixed; z-index: 28;
  left: 50%; bottom: var(--s-5);
  transform: translateX(-50%);
  /* 680px: a 560 el texto partía en tres líneas y la píldora quedaba alta. */
  width: min(680px, calc(100% - 2 * var(--s-4)));
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-3) var(--s-3) var(--s-3) var(--s-4);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-float);
  animation: gh-aviso-sube var(--dur-slow) var(--ease);
}
.instalar-aviso[hidden] { display: none; }
.instalar-aviso img { border-radius: 12px; flex: none; }
.instalar-aviso > div { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--s-4); }
.instalar-aviso-titulo { margin: 0; font-weight: 700; color: var(--sage-deep); }
.instalar-aviso-texto { margin: 2px 0 0; color: var(--ink-soft); font-size: var(--t-small); }
.instalar-aviso-botones { display: flex; gap: var(--s-2); flex: none; margin-left: auto; }
@keyframes gh-aviso-sube { from { opacity: 0; transform: translate(-50%, 16px); } to { opacity: 1; transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .instalar-aviso { animation: none; } }
/* Una ventana de computador estrecha (o una tableta) sin modo de app: la
   píldora no cabe en una fila y aplastaba el texto hasta sacar «Ahora no» por
   el borde. Pasa a tarjeta, los botones bajan a su propia fila, y flota ENCIMA
   del menú de abajo —medido, `--fam-nav-alto`— en vez de taparlo. */
@media (max-width: 640px) {
  .instalar-aviso {
    align-items: flex-start;
    bottom: calc(var(--fam-nav-alto, 0px) + var(--s-3));
    border-radius: var(--r-lg);
    padding: var(--s-4);
  }
  .instalar-aviso > div { flex-wrap: wrap; gap: var(--s-3); }
  .instalar-aviso > div > div:first-child { flex: 1 1 100%; }
  .instalar-aviso-botones { flex: 1 1 100%; margin-left: 0; }
  .instalar-aviso-botones .btn { flex: 1; justify-content: center; }
}

/* Con el indicador que viaja (motion.js), la pestaña activa no pinta su
   propio fondo: lo pone la pieza que se desliza, y en escritorio lleva el
   filete a la izquierda que antes llevaba la pestaña. */
.fam-tabs.gh-con-indicador .tab[aria-selected="true"] { background: transparent; }
@media (min-width: 860px) {
  .fam-tabs .gh-indicador { box-shadow: inset 3px 0 0 var(--sage); }
}

/* Hoja «¿Te avisamos…?» al entrar: los dos botones juntos, el de activar a la
   derecha (el que se lee último en un teléfono es el que se pulsa). */
.avisos-acciones { display: flex; gap: var(--s-3); justify-content: flex-end; flex-wrap: wrap; margin-top: var(--s-6); }
.avisos-acciones .btn { flex: 1 1 160px; }
#avisos-panel .notice { margin: var(--s-4) 0; }
