/* Paleta oscura: la de siempre y la que se usa por defecto. */

/* `hidden` es solo display:none del navegador, asi que CUALQUIER clase propia que
   defina display se lo come. Pasaba en 6 lugares, entre ellos la fila de nutrientes
   que se supone que solo aparece si hay datos. Esto lo cierra de raiz. */
[hidden] { display: none !important; }
:root {
  --bg: #0e1116;
  --bg2: #161b22;
  --card: #1a2029;
  --card2: #222a35;
  --line: #2c3542;
  --txt: #e6edf3;
  --txt2: #c3cede;           /* texto secundario: entre --txt y --dim */
  --dim: #99a7b8;
  --acc: #4ade80;
  --acc2: #22c55e;
  --sobre-acc: #06210f;      /* texto sobre el verde lleno */
  --warn: #fbbf24;
  --bad: #f87171;
  /* `--err` se usa en cuatro lugares del CSS y NO existía fuera de los temas
     alternativos, así que en el tema normal —el que usa casi todo el mundo—
     esos cuatro no tenían color: la marca "no entra" de la lista de comidas
     nunca se vio roja, ni en la lista ni en el resumen. Se resuelve contra
     `--bad`, que sí se redefine en claro y en oscuro. */
  --err: var(--bad);
  --prot: #60a5fa;
  --carb: #fbbf24;
  /* Violeta y no amarillo. Con #facc15 las grasas quedaban a un paso del
     ambar de los carbohidratos y las dos barras se leian como la misma; verde
     tampoco servia, porque en esa misma pantalla el verde ya significa
     "objetivo cumplido" —el anillo, la lectura de cada macro— y ademas verde y
     naranja son justo el par que no se distingue con el daltonismo mas comun.
     Azul, ambar y violeta se separan entre si y ninguno pisa una señal. */
  --gras: #a78bfa;
  --sombra: none;
  --r: 14px;
}

/* Paleta clara: mismos roles, colores más oscuros para que el contraste aguante. */
@media (prefers-color-scheme: light) {
  :root:not([data-tema="oscuro"]) {
    --bg: #f4f6fa;
    --bg2: #ffffff;
    --card: #ffffff;
    --card2: #eef1f7;
    --line: #d9e0ea;
    --txt: #16202c;
    --txt2: #3c4a5a;
    --dim: #5b6878;
    --acc: #0f6a31;
    --acc2: #15803d;
    --sobre-acc: #ffffff;
    --warn: #a16207;
    --bad: #d61f1f;
    --prot: #1d4ed8;
    --carb: #a16207;
    --gras: #6d28d9;
    --sombra: 0 1px 2px rgba(20, 30, 45, .06);
  }
}

/* Elegido a mano en Ajustes: gana sobre lo que diga el sistema. */
:root[data-tema="claro"] {
  --bg: #f4f6fa;
  --bg2: #ffffff;
  --card: #ffffff;
  --card2: #eef1f7;
  --line: #d9e0ea;
  --txt: #16202c;
  --txt2: #3c4a5a;
    --dim: #5b6878;
  --acc: #0f6a31;
  --acc2: #15803d;
  --sobre-acc: #ffffff;
  --warn: #a16207;
  --bad: #d61f1f;
  --prot: #1d4ed8;
  --carb: #a16207;
  --gras: #6d28d9;
  --sombra: 0 1px 2px rgba(20, 30, 45, .06);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

body {
  margin: 0;
  padding: 0 0 78px;
  background: var(--bg);
  color: var(--txt);
  font: 15px/1.45 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
}

/* ---------- topbar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 12px 12px;
  background: linear-gradient(var(--bg) 70%, transparent);
  backdrop-filter: blur(8px);
}
.topbar { gap: 8px; }
/* Tres cosas en un renglon de 375 px: el titulo cede primero —"Mediterránea"
   se puede cortar y se sigue reconociendo—, el ayuno se achica hasta su texto y
   la fecha no se toca, que es lo unico con lo que se navega. */
.topbar h1 {
  margin: 0; font-size: 17px; letter-spacing: -.4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar .tiras { flex: 0 1 auto; margin: 0; min-width: 0; }
.date-nav { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dim); flex: 0 0 auto; }
.date-nav span { min-width: 50px; text-align: center; }

.icon-btn {
  background: var(--card); border: 1px solid var(--line); color: var(--txt);
  width: 30px; height: 30px; border-radius: 9px; font-size: 16px; cursor: pointer; padding: 0;
}
.icon-btn:active { background: var(--card2); }

/*
 * `min-width: 0` y `width: 100%`: es lo que impide que un contenido ancho
 * estire la página entera.
 *
 * `body` es flex, así que `main` es un flex item, y un flex item arranca con
 * `min-width: auto`: no puede achicarse por debajo del ancho mínimo de lo que
 * tiene adentro. Un título largo, una fila que no entra o un número de muchos
 * dígitos hacían crecer a `main` más allá de la pantalla, y con él a TODO —el
 * encabezado quedaba fuera de vista y la app aparecía corrida hacia un lado.
 *
 * No era un problema del elemento culpable de turno: mientras esto faltara,
 * cualquier contenido podía volver a hacerlo.
 */
main { padding: 0 14px; max-width: 620px; margin: 0 auto; min-width: 0; width: 100%; }

/* ---------- tabs ---------- */
/*
 * UNA sola animación de entrada.
 *
 * `.tab` tenía `animation: fade` y encima el JS le agrega `tab-entrando` con
 * otra casi igual. Como `repetirClase()` quita la clase y la vuelve a poner,
 * se disparaban las dos en fila: dos fundidos desde opacidad 0, uno atrás del
 * otro. Eso es el parpadeo al entrar a una pestaña y al volver.
 *
 * Queda `tab-entrando`, que es la que el JS controla y la que respeta el
 * pedido de menos movimiento.
 */
.tab { display: none; }
.tab.active { display: block; }

.tabbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 30;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--bg2); border-top: 1px solid var(--line);
  padding: 6px 0 max(6px, env(safe-area-inset-bottom));
}
.tab-btn {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: none; border: 0; color: var(--dim); font-size: 11px; padding: 5px 0; cursor: pointer;
}
.tab-btn span { font-size: 19px; filter: grayscale(1); opacity: .6; }
.tab-btn.active { color: var(--acc); }
.tab-btn.active span { filter: none; opacity: 1; }

/* ---------- cards ---------- */
/* Doce pixeles entre tarjetas y catorce adentro eran comodos con cuatro
   tarjetas por pantalla; con diez, ese aire es media pantalla de scroll. */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); padding: 12px; margin-bottom: 9px;
  box-shadow: var(--sombra);
}
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.card-head h2 { margin: 0; font-size: 14px; font-weight: 600; color: var(--dim); text-transform: uppercase; letter-spacing: .5px; }
.pill { background: var(--card2); color: var(--dim); border-radius: 20px; padding: 2px 9px; font-size: 12px; }
/* Un pill sin texto igual dibujaba la pastilla: al lado de un titulo se lee
   como una mancha. Ahora un estado que no dice nada no ocupa nada. */
.pill:empty { display: none; }

/* ---------- anillo ---------- */
.ring-card { display: flex; flex-direction: column; align-items: center; padding-top: 18px; }
.ring-wrap { position: relative; width: 190px; height: 190px; }
.ring { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 9; stroke-linecap: round; }
.ring-bg { stroke: var(--card2); }
.ring-fg {
  stroke: var(--acc); stroke-dasharray: 326.7; stroke-dashoffset: 326.7;
  transition: stroke-dashoffset .5s cubic-bezier(.2,.8,.3,1), stroke .3s;
}
.ring-fg.over { stroke: var(--bad); }
.ring-fg.near { stroke: var(--warn); }

/* La vuelta que ya se dio, cuando el trazo pasó a medir el excedente. */
.ring.pasado .ring-bg { stroke: color-mix(in srgb, var(--bad) 55%, var(--card2)); }
.ring-center {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
}
.ring-center strong { font-size: 38px; font-weight: 700; letter-spacing: -1.5px; line-height: 1; }
/* Cinco cifras a 38 px se comen el diámetro entero; seis directamente no entran. */
.ring-center strong.largo { font-size: 31px; letter-spacing: -1.2px; }
.ring-center strong.enorme { font-size: 25px; letter-spacing: -1px; }
#ringGoal { display: block; font-size: 11.5px; color: var(--dim); text-align: center; margin-top: 6px; line-height: 1.25; }

.ring-stats { display: grid; grid-template-columns: repeat(3, 1fr); width: 100%; margin-top: 14px; text-align: center; }
.ring-stats div { display: flex; flex-direction: column; gap: 2px; }
.ring-stats span { font-size: 17px; font-weight: 600; }
.ring-stats small { font-size: 11px; color: var(--dim); }

/* ---------- macros ---------- */
.macro + .macro { margin-top: 12px; }
.macro-head { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 5px; }
.macro-head span { color: var(--dim); }
.bar { height: 7px; background: var(--card2); border-radius: 5px; overflow: hidden; }
.bar i { display: block; height: 100%; width: 0; border-radius: 5px; transition: width .4s ease; }
.bar i.prot { background: var(--prot); }
.bar i.carb { background: var(--carb); }
.bar i.gras { background: var(--gras); }

/* ---------- botones ---------- */
button { font-family: inherit; font-size: 14px; }
.primary {
  background: var(--acc2); color: var(--sobre-acc); border: 0; border-radius: 11px;
  padding: 11px 16px; font-weight: 650; cursor: pointer;
}
.primary:active { background: var(--acc); }
.primary:disabled { opacity: .4; cursor: default; }
.ghost {
  background: var(--card2); color: var(--txt); border: 1px solid var(--line);
  border-radius: 11px; padding: 11px 16px; cursor: pointer;
}
.danger { background: transparent; color: var(--bad); border: 1px solid var(--bad); border-radius: 11px; padding: 11px 16px; cursor: pointer; }
.big { width: 100%; padding: 14px; font-size: 15px; }
.small { padding: 7px 12px; font-size: 13px; }
.actions { display: grid; gap: 8px; margin-bottom: 12px; }
.actions-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- listas ---------- */
.lista { list-style: none; margin: 0; padding: 0; }
.lista li {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0; border-top: 1px solid var(--line);
}
.lista li:first-child { border-top: 0; }
.lista .thumb { width: 42px; height: 42px; border-radius: 9px; object-fit: cover; flex: 0 0 auto; background: var(--card2); }
.lista .info { flex: 1; min-width: 0; }
.lista .info b { display: block; font-weight: 550; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lista .info small { color: var(--dim); font-size: 12px; }
.lista .kcal { font-weight: 650; font-size: 15px; }
.lista .del { background: none; border: 0; color: var(--dim); font-size: 17px; cursor: pointer; padding: 4px; }

.dias li { justify-content: space-between; }
.dias .dia-bar { height: 5px; background: var(--card2); border-radius: 4px; margin-top: 5px; overflow: hidden; }
.dias .dia-bar i { display: block; height: 100%; background: var(--acc); }
.dias .dia-bar i.over { background: var(--bad); }

.vacio { color: var(--dim); font-size: 13px; text-align: center; margin: 14px 0 6px; }
.hint { color: var(--dim); font-size: 12px; margin: 10px 0 0; }

.kv { list-style: none; margin: 0; padding: 0; }
.kv li { display: flex; justify-content: space-between; padding: 8px 0; border-top: 1px solid var(--line); font-size: 14px; }
.kv li:first-child { border-top: 0; }
.kv li span { color: var(--dim); }
.kv li b { font-weight: 600; }

/* ---------- chart ---------- */
.chart { width: 100%; height: 120px; display: block; }
.chart .line { fill: none; stroke: var(--acc); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .area { fill: color-mix(in srgb, var(--acc) 14%, transparent); }
.chart .dot { fill: var(--acc); }
.chart .goal { stroke: var(--warn); stroke-width: 1; stroke-dasharray: 4 4; }
.chart text { fill: var(--dim); font-size: 9px; }

/* ---------- forms ---------- */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--dim); }
label.block { margin-bottom: 12px; }
input, select {
  background: var(--bg2); border: 1px solid var(--line); color: var(--txt);
  border-radius: 10px; padding: 10px; font: inherit; font-size: 15px; width: 100%;
}
input:focus, select:focus { outline: none; border-color: var(--acc2); }
.form-grid + button { margin-top: 14px; }

/* La cintura ocupa las dos columnas: su ayuda es una linea entera y en media
   grilla se partia en cuatro renglones. Lleva su rotulo de "opcional" porque un
   campo vacio al lado de tres obligatorios se lee como algo que falta. */
.campo-opcional { grid-column: 1 / -1; }
.campo-opcional .opcional {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--dim); border: 1px solid var(--line); border-radius: 6px;
  padding: 1px 5px; margin-left: 5px; vertical-align: 1px;
}
.campo-opcional .hint { margin: 0; }
.peso-row { display: flex; gap: 8px; }
.peso-row input { flex: 1; }

/* ---------- modal ---------- */
.modal {
  position: fixed; inset: 0; z-index: 50; display: none;
  align-items: flex-end; justify-content: center;
  background: rgba(0, 0, 0, .6); backdrop-filter: blur(3px);
}
.modal.open { display: flex; }
.modal-box {
  background: var(--bg2); width: 100%; max-width: 560px; max-height: 92vh;
  border-radius: 18px 18px 0 0; display: flex; flex-direction: column;
  animation: up .25s cubic-bezier(.2,.9,.3,1);
}
@keyframes up { from { transform: translateY(40px); opacity: .6; } }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.modal-head h2 { margin: 0; font-size: 16px; }
.modal-body { padding: 14px 16px; overflow-y: auto; flex: 1; }
.modal-foot { display: flex; gap: 8px; padding: 12px 16px max(12px, env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.modal-foot button { flex: 1; }

.loading { text-align: center; }
.loading img { max-width: 100%; max-height: 210px; border-radius: 12px; margin-bottom: 14px; }
.spinner {
  width: 26px; height: 26px; margin: 0 auto 10px;
  border: 3px solid var(--card2); border-top-color: var(--acc);
  border-radius: 50%; animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading p { color: var(--dim); font-size: 13px; margin: 0; }

.desc { margin: 0 0 8px; font-size: 15px; font-weight: 550; }

/* La foto de la comida en el editor: chica, al lado del nombre. En 375 px la
   cabecera entera son 64 px de alto y el campo del nombre no pierde ancho util
   —sin foto el boton esta hidden y el input ocupa toda la fila igual—. */
.res-cabecera { display: flex; align-items: center; gap: 10px; }
.res-cabecera .desc { flex: 1; min-width: 0; margin: 0 0 8px; }
.res-foto {
  position: relative; flex: 0 0 auto; width: 56px; height: 56px; padding: 0;
  margin-bottom: 8px; border: 1px solid var(--line); border-radius: 10px;
  overflow: hidden; background: var(--card); cursor: zoom-in;
}
.res-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.res-foto-lupa {
  position: absolute; right: 2px; bottom: 1px; font-size: 11px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9);
}
.conf { font-size: 12px; margin-bottom: 12px; }
.conf b { padding: 2px 8px; border-radius: 20px; font-weight: 600; }
.conf .alta { background: rgba(74,222,128,.15); color: var(--acc); }
.conf .media { background: rgba(251,191,36,.15); color: var(--warn); }
.conf .baja { background: rgba(248,113,113,.15); color: var(--bad); }

/*
 * Cada alimento es una tarjeta, no tres franjas sueltas.
 *
 * Estaban separados por una linea y nada mas: nombre, cuatro macros y cuatro
 * multiplicadores, todos del mismo peso visual y uno abajo del otro. Con tres
 * alimentos son doce campos apilados sin agrupacion, y desde afuera se lee como
 * un solo bloque de controles mezclados. La caja dice donde empieza y termina
 * cada alimento, que es lo que faltaba.
 */
.items { list-style: none; margin: 0 0 10px; padding: 0; display: grid; gap: 8px; }
.items li {
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--card2); padding: 8px;
}
.item-top { display: flex; gap: 6px; align-items: center; }
.item-top input.nombre { flex: 1; min-width: 0; font-size: 13.5px; padding: 6px 8px; }
.item-top input.kcal { width: 62px; text-align: right; font-size: 13.5px; padding: 6px 6px; }
.item-top .del { background: none; border: 0; color: var(--dim); font-size: 16px; cursor: pointer; padding: 0 2px; }

/* Los macros: la etiqueta va pegada arriba del campo y en el tamano mas chico
   que se sigue leyendo. Cuatro columnas iguales, que es como se comparan. */
/* La porcion es texto libre y larga —"120 g (4 tortillas)"— y los otros tres
   son numeros de dos digitos: partir el ancho en cuatro iguales cortaba lo
   unico que hay que leer entero. */
.item-sub { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 5px; margin-top: 6px; }
.item-sub input { font-size: 12px; padding: 5px 6px; width: 100%; }
.item-sub label { font-size: 9.5px; gap: 2px; text-transform: uppercase; letter-spacing: .2px; }

.total-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 0 0; border-top: 1px solid var(--line); margin-top: 10px; }
.total-row b { font-size: 20px; color: var(--acc); }

.error-box { color: var(--bad); font-size: 14px; }
.error-box p { margin: 0; white-space: pre-wrap; word-break: break-word; }

/* ---------- toast ---------- */
.toast {
  position: fixed; bottom: 86px; left: 50%; transform: translate(-50%, 16px);
  background: var(--card2); border: 1px solid var(--line); color: var(--txt);
  padding: 10px 16px; border-radius: 22px; font-size: 13px; z-index: 60;
  opacity: 0; pointer-events: none; transition: .22s;
}
/* Entra con rebote en vez de aparecer: ver anim-toast-entra. */
.toast.show { opacity: 1; transform: translate(-50%, 0); animation: anim-toast-entra .38s cubic-bezier(.34, 1.4, .64, 1); }

@media (max-width: 380px) {
  .form-grid { grid-template-columns: 1fr; }
}

/* ---------- agrupado por momento ---------- */
.lista li.grupo {
  justify-content: space-between; padding: 12px 0 6px;
  font-size: 12px; text-transform: uppercase; letter-spacing: .5px; color: var(--dim);
}
.lista li.grupo b { font-weight: 600; }
.lista li.grupo + li { border-top: 0; }

/* ---------- selector de momento ---------- */
/* Los momentos, en UNA fila que se desliza: envueltos ocupaban dos renglones
   completos arriba de la comida, que es donde menos lugar hay. */
.momento-sel {
  display: flex; gap: 6px; flex-wrap: nowrap; margin-bottom: 10px;
  overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
}
.momento-sel::-webkit-scrollbar { display: none; }
.momento-sel button { flex: 0 0 auto; }
.momento-sel button {
  background: var(--card2); border: 1px solid var(--line); color: var(--dim);
  border-radius: 20px; padding: 6px 12px; font-size: 12.5px; cursor: pointer;
}
.momento-sel button.sel { background: rgba(74,222,128,.15); border-color: var(--acc2); color: var(--acc); }

/* ---------- agua ---------- */
.agua-row { display: flex; align-items: center; gap: 10px; }
.vasos { flex: 1; display: flex; gap: 5px; flex-wrap: wrap; }
.vasos i {
  width: 15px; height: 21px; border-radius: 3px 3px 6px 6px;
  border: 1.5px solid var(--line); background: transparent; transition: .2s;
}
.vasos i.lleno { background: var(--prot); border-color: var(--prot); }
.vasos i.extra { background: var(--acc); border-color: var(--acc); }
.icon-btn:disabled { opacity: .35; cursor: default; }

/* ---------- fila editable ---------- */
.lista li.clicable { cursor: pointer; border-radius: 8px; }
.lista li.clicable:hover { background: rgba(255,255,255,.025); }
.lista li.clicable:focus-visible { outline: 2px solid var(--acc2); outline-offset: -2px; }

/* ---------- accion dentro del toast ---------- */
.toast { display: flex; align-items: center; gap: 12px; }
.toast button {
  background: none; border: 0; color: var(--acc); font-weight: 650;
  font-size: 13px; cursor: pointer; padding: 2px 0;
}

/* ---------- multiplicador de porcion ---------- */
/* Los multiplicadores son un ajuste fino, no un control principal: van mas
   chicos que todo lo demas de la tarjeta. */
.escalas { display: flex; gap: 4px; margin-top: 6px; }
.escalas button {
  flex: 1; background: var(--bg2); border: 1px solid var(--line); color: var(--dim);
  border-radius: 7px; padding: 3px 0; font-size: 11px; cursor: pointer;
}
.escalas button.sel { background: rgba(74,222,128,.14); border-color: var(--acc2); color: var(--acc); }

/* ---------- autocompletado de alimentos ---------- */
.sugerencias {
  margin-top: 6px; border: 1px solid var(--line); border-radius: 10px;
  overflow: hidden; background: var(--bg2);
}
.sugerencias button {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  width: 100%; text-align: left; background: none; border: 0;
  border-bottom: 1px solid var(--line); color: var(--txt);
  padding: 9px 11px; font-size: 13.5px; cursor: pointer;
}
.sugerencias button:last-child { border-bottom: 0; }
.sugerencias button:hover { background: var(--card2); }
.sugerencias em { font-style: normal; color: var(--dim); font-size: 11.5px; white-space: nowrap; }

/* ---------- correccion y costo ---------- */
.correccion { display: flex; gap: 7px; margin-top: 12px; }
.correccion input { flex: 1; font-size: 13.5px; padding: 9px 10px; }
.costo { color: var(--dim); font-size: 11.5px; margin-top: 6px; }
.loading button { margin-top: 12px; }

/* ---------- grafico de barras y leyendas ---------- */
.chart.alto { height: 140px; }
.chart .barra { fill: var(--acc2); }
.chart .barra.over { fill: var(--bad); }
.chart .barra.vacia { fill: var(--line); }
.chart .line.diario { stroke: var(--dim); stroke-width: 1; opacity: .55; }
.chart .line.media { stroke: var(--acc); stroke-width: 2.2; }
.chart .dot { fill: var(--dim); }

.leyenda { display: flex; align-items: center; gap: 6px; color: var(--dim); font-size: 11px; margin: 2px 0 0; }
.leyenda i { display: inline-block; width: 14px; height: 2px; border-radius: 2px; margin-left: 8px; }
.leyenda i.l-diario { background: var(--dim); }
.leyenda i.l-media { background: var(--acc); height: 3px; }

/* ---------- progreso hacia la meta ---------- */
#progresoMeta { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.progreso-head { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 6px; }
.progreso-head span { color: var(--dim); }
.bar i.meta { background: linear-gradient(90deg, var(--acc2), var(--acc)); }

/* ---------- aviso de dia distinto de hoy ---------- */
.aviso-dia {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: rgba(251,191,36,.12); border: 1px solid rgba(251,191,36,.35);
  color: var(--warn); border-radius: var(--r); padding: 10px 12px;
  margin-bottom: 12px; font-size: 12.5px;
}
.aviso-dia button {
  background: none; border: 0; color: var(--warn); font-weight: 650;
  cursor: pointer; white-space: nowrap; font-size: 12.5px;
}

/* ---------- aviso de API key faltante ---------- */
.sin-key p { margin: 0 0 10px; font-size: 13px; color: var(--dim); }

/* ---------- errores de formulario ---------- */
input.invalido, select.invalido { border-color: var(--bad); }
.error-campo { color: var(--bad); font-size: 11px; margin-top: -1px; }

/* ---------- onboarding ---------- */
.onb {
  position: fixed; inset: 0; z-index: 70; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: var(--bg);
}
.onb[hidden] { display: none; }
.onb-box {
  background: var(--card); border: 1px solid var(--line); border-radius: 18px;
  padding: 22px 20px 16px; width: 100%; max-width: 440px;
  display: flex; flex-direction: column; gap: 4px;
}
.onb-pasos { display: flex; gap: 6px; justify-content: center; margin-bottom: 18px; }
.onb-pasos i { width: 22px; height: 4px; border-radius: 3px; background: var(--card2); transition: .25s; }
.onb-pasos i.activo { background: var(--acc); }
.onb-icono { font-size: 40px; text-align: center; margin-bottom: 8px; }
.onb-paso h2 { margin: 0 0 8px; font-size: 20px; text-align: center; }
.onb-paso p { margin: 0 0 10px; font-size: 14px; color: var(--txt); text-align: center; }
.onb-paso p.hint { text-align: center; }
.onb-paso .form-grid { margin-top: 14px; text-align: left; }
.onb-paso label { text-align: left; }
.onb-pie { display: flex; gap: 10px; align-items: center; margin-top: 18px; }
.onb-pie .primary { flex: 1; padding: 13px; }
#onbError:empty { display: none; }
#onbError { text-align: center; margin: 10px 0 0; }

/* ---------- aviso de version nueva ---------- */
.banner-update {
  position: fixed; left: 12px; right: 12px; bottom: 84px; z-index: 65;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--card2); border: 1px solid var(--acc2);
  border-radius: 12px; padding: 11px 14px; font-size: 13px;
  max-width: 596px; margin: 0 auto;
}
.banner-update[hidden] { display: none; }
/* Flota sobre todo (z-index 65), así que con un modal abierto tapaba sus botones.
   Mientras haya uno abierto se esconde; vuelve al cerrarlo. */
body:has(.modal.open) .banner-update { display: none; }
.banner-update button {
  background: var(--acc2); color: var(--sobre-acc); border: 0; border-radius: 9px;
  padding: 7px 13px; font-weight: 650; cursor: pointer; white-space: nowrap;
}

/* ---------- foco visible ---------- */
button:focus-visible, input:focus-visible, select:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}
.tab-btn:focus-visible { outline-offset: -2px; border-radius: 8px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- cuota de almacenamiento ---------- */
.cuota { margin-top: 12px; }
.cuota .bar { height: 5px; }
.cuota .bar i { background: var(--acc2); width: 0; }
.cuota .bar i.alerta { background: var(--warn); }
.cuota .bar i.critico { background: var(--bad); }
.aviso-cuota { color: var(--warn); }
.aviso-cuota[hidden] { display: none; }

/* ---------- favoritos ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chips button {
  display: flex; align-items: center; gap: 7px;
  background: var(--card2); border: 1px solid var(--line); color: var(--txt);
  border-radius: 20px; padding: 8px 13px; font-size: 13px; cursor: pointer;
}
.chips button:active { background: var(--line); }
.chips button em { font-style: normal; color: var(--dim); font-size: 11.5px; }

.estrella {
  background: none; border: 0; cursor: pointer; padding: 4px;
  font-size: 15px; line-height: 1; filter: grayscale(1); opacity: .45;
}
.estrella.on { filter: none; opacity: 1; }

/* ---------- recetas ---------- */
h3.sub {
  margin: 0 0 8px; font-size: 12px; color: var(--dim);
  text-transform: uppercase; letter-spacing: .5px; font-weight: 600;
}
#bloqueRecetas { margin-bottom: 16px; }
.acciones-editor { display: flex; gap: 8px; flex-wrap: wrap; }
.lista .receta-usos { color: var(--dim); font-size: 11px; }

/* ---------- suma rapida ---------- */
.quick { display: flex; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.quick input { flex: 1; font-size: 13.5px; padding: 8px 10px; }
.quick button { white-space: nowrap; }

/* ---------- mover de dia ---------- */
/* El dia, en linea: su etiqueta y su campo ocupaban dos renglones para un dato
   que casi nunca se toca. */
.fecha-comida {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  margin: 0 0 10px; font-size: 12px;
}
.fecha-comida input { flex: 1 1 auto; min-width: 0; font-size: 13px; padding: 6px 8px; }

/* ---------- nota del dia ---------- */
textarea {
  background: var(--bg2); border: 1px solid var(--line); color: var(--txt);
  border-radius: 10px; padding: 10px; font: inherit; font-size: 14px;
  width: 100%; resize: vertical; min-height: 56px;
}
textarea:focus { outline: none; border-color: var(--acc2); }

/* ---------- buscador ---------- */
.buscador { display: flex; gap: 8px; align-items: center; }
.buscador input { flex: 1; }
.buscador input[type=search]::-webkit-search-cancel-button { display: none; }
.lista .donde { color: var(--acc); font-size: 11px; }

/* ---------- visor de fotos ---------- */
.visor {
  position: fixed; inset: 0; z-index: 80;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 20px; background: rgba(0, 0, 0, .92);
}
.visor[hidden] { display: none; }
.visor img {
  max-width: 100%; max-height: 72vh; border-radius: 12px;
  object-fit: contain; background: var(--card);
}
.visor p { color: var(--dim); font-size: 13px; text-align: center; margin: 0; max-width: 460px; }
.visor-cerrar {
  position: absolute; top: 14px; right: 14px;
  background: var(--card2); border: 1px solid var(--line); color: var(--txt);
  width: 38px; height: 38px; border-radius: 12px; font-size: 16px; cursor: pointer;
}
.lista .thumb { cursor: zoom-in; }

/* La tira del peso es la unica forma de pesarse desde Hoy, asi que tiene que
   verse tocable: la balanza a la derecha es esa señal. Con un "+" mientras hoy
   no te pesaste, sola cuando ya esta. */
.peso-tira-cargar { flex: 0 0 auto; font-size: 15px; opacity: .55; letter-spacing: -1px; }
.peso-tira.sin-pesar .peso-tira-cargar { opacity: 1; }
.peso-tira-delta.pesarte { color: var(--acc); font-weight: 650; }

/* ---------- el recorte de la foto ---------- */

/* El lienzo mide exactamente lo que la imagen mostrada: el marco es hijo suyo y
   se posiciona en pixeles de pantalla, que es en lo que piensa recorte.js. */
.recortador .rec-lienzo { position: relative; line-height: 0; touch-action: none; }
.recortador img { max-height: 64vh; display: block; }

.rec-marco {
  position: absolute; box-sizing: border-box;
  border: 2px solid #fff; border-radius: 4px; cursor: move;
  /* La sombra hacia afuera es lo que oscurece el resto de la foto sin tapar
     nada: sin ella no se ve que es lo que queda adentro. */
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .55);
}
.rec-marco[hidden] { display: none; }

/* Los tiradores son mas grandes que su dibujo: 12 px se ven bien y 12 px no se
   agarran con el dedo. El recuadro transparente de 34 es lo que se toca. */
.rec-marco i {
  position: absolute; width: 34px; height: 34px;
}
.rec-marco i::after {
  content: ''; position: absolute; width: 14px; height: 14px;
  border: 3px solid #fff;
}
.rec-marco i[data-esq="no"] { top: -17px; left: -17px; cursor: nwse-resize; }
.rec-marco i[data-esq="no"]::after { top: 8px; left: 8px; border-right: 0; border-bottom: 0; border-radius: 3px 0 0 0; }
.rec-marco i[data-esq="ne"] { top: -17px; right: -17px; cursor: nesw-resize; }
.rec-marco i[data-esq="ne"]::after { top: 8px; right: 8px; border-left: 0; border-bottom: 0; border-radius: 0 3px 0 0; }
.rec-marco i[data-esq="so"] { bottom: -17px; left: -17px; cursor: nesw-resize; }
.rec-marco i[data-esq="so"]::after { bottom: 8px; left: 8px; border-right: 0; border-top: 0; border-radius: 0 0 0 3px; }
.rec-marco i[data-esq="se"] { bottom: -17px; right: -17px; cursor: nwse-resize; }
.rec-marco i[data-esq="se"]::after { bottom: 8px; right: 8px; border-left: 0; border-top: 0; border-radius: 0 0 3px 0; }

#recAyuda { color: var(--dim); font-size: 13px; text-align: center; margin: 0; }
.rec-acciones { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }

/* ---------- precision del analisis ---------- */
.bloque-precision { margin-bottom: 14px; }
.bloque-precision .etiqueta { display: block; font-size: 12px; color: var(--dim); margin-bottom: 6px; }
.bloque-precision .hint { margin-top: 6px; }

/* ---------- sugerencias ---------- */
.lista li.sugerencia { flex-direction: column; align-items: stretch; gap: 4px; }
.sugerencia-cab { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.sugerencia-cab b { font-size: 14.5px; }
.sugerencia-porque { color: var(--acc); font-size: 12px; }
.sugerencia-items { color: var(--dim); font-size: 12px; }

/* ---------- registro de analisis ---------- */
.detalle-analisis { margin-top: 12px; }
.detalle-analisis summary {
  cursor: pointer; color: var(--dim); font-size: 12.5px;
  padding: 6px 0; list-style-position: inside;
}
.detalle-analisis summary::-webkit-details-marker { color: var(--dim); }
.lista.analisis li { padding: 8px 0; font-size: 13px; }
.lista.analisis .cache { color: var(--acc); }

/* ---------- lectura de los datos ---------- */
.proyeccion {
  margin: 12px 0 0; padding: 10px 12px; font-size: 13px;
  background: var(--card2); border-radius: 10px; color: var(--txt);
}
.proyeccion[hidden] { display: none; }
.proyeccion b { color: var(--acc); }

.reparto-fila { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; font-size: 13px; }
.reparto-fila .nombre { width: 96px; color: var(--dim); flex: 0 0 auto; }
.reparto-fila .bar { flex: 1; }
.reparto-fila .bar i { background: var(--acc2); }
.reparto-fila .pct { width: 34px; text-align: right; font-weight: 600; }

#bloqueAdherencia, #bloqueReparto, #bloqueSemanas, #bloquePatron { margin-top: 16px; }
#bloqueAdherencia:first-child { margin-top: 0; }

.aviso-proteina {
  display: flex; align-items: center; gap: 10px;
  background: rgba(96,165,250,.12); border: 1px solid rgba(96,165,250,.35);
  color: var(--prot); border-radius: var(--r); padding: 10px 12px;
  margin-bottom: 12px; font-size: 12.5px;
}
.aviso-proteina[hidden] { display: none; }

/* ---------- recordatorios ---------- */
.switch { flex-direction: row; align-items: center; gap: 10px; color: var(--txt); font-size: 14px; cursor: pointer; }
.switch input { width: 20px; height: 20px; accent-color: var(--acc2); flex: 0 0 auto; }
/*
 * Los horarios de los avisos: una fila por comida, en una linea.
 *
 * Estaban en tres renglones cada uno —el tilde arriba, el nombre en el medio,
 * la hora abajo, todo centrado— y cuatro comidas ocupaban 400 px. No era el
 * diseno: es que la regla global de `label` las pone en columna, y ninguna de
 * las reglas de aca declaraba la direccion. Con cuatro comidas, la hora de
 * dormir y el estado fijo, el bloque no entraba en ninguna pantalla.
 */
.horarios { display: grid; gap: 2px; margin-top: 8px; }
/* Grilla y no flex: tres columnas fijas —tilde, nombre, hora— que no dependen
   de como negocie el ancho cada item. Con flex el nombre terminaba en 0 px de
   ancho, invisible, mientras la hora se quedaba con todo. */
.horarios .fila {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 10px; text-align: left;
}
.horarios .fila span {
  min-width: 0; font-size: 13.5px; color: var(--txt);
  /* Un renglon: el nombre se recorta antes de empujar a la hora, que es el
     dato que hay que poder tocar. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.horarios .fila input[type="time"] { width: 102px; font-size: 13px; padding: 5px 8px; }

/* ---------- atajos ---------- */
.tecla {
  display: inline-block; min-width: 24px; text-align: center;
  background: var(--card2); border: 1px solid var(--line); border-radius: 6px;
  padding: 2px 7px; font-family: ui-monospace, Consolas, monospace; font-size: 12px;
}

/* ---------- revision de datos ---------- */
.lista.problemas li { align-items: flex-start; }
.lista.problemas .info small { color: var(--warn); }

/* ---------- calibracion ---------- */
#calibResultado { margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
#calibError { font-size: 20px; }
.calib-bien { color: var(--acc); }
.calib-aceptable { color: var(--warn); }
.calib-flojo { color: var(--bad); }
.lista .ref-error { font-weight: 650; font-size: 13px; white-space: nowrap; }

/* ---------- sesgo aprendido ---------- */
.aviso-sesgo {
  background: rgba(251,191,36,.12); border: 1px solid rgba(251,191,36,.35);
  color: var(--warn); border-radius: 10px; padding: 10px 12px;
  margin: 0 0 14px; font-size: 12.5px;
}
.aviso-sesgo[hidden] { display: none; }

/* ---------- sincronizacion ---------- */
.llave-box { background: var(--bg2); border: 1px solid var(--line); border-radius: 10px; padding: 11px 12px; margin-bottom: 12px; }
.llave-box .etiqueta { display: block; font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; }
.llave-box code {
  display: block; margin: 6px 0 4px; font-size: 13.5px; letter-spacing: .5px;
  font-family: ui-monospace, Consolas, monospace; color: var(--acc); word-break: break-all;
}
.llave-box .hint { margin-top: 4px; }
.sync-ok { color: var(--acc); }
.sync-mal { color: var(--bad); }
#syncIntro code { color: var(--acc); font-size: 12px; }

/* ---------- aviso de respaldo ---------- */
.aviso-respaldo {
  background: rgba(251,191,36,.12); border: 1px solid rgba(251,191,36,.35);
  color: var(--warn); border-radius: 10px; padding: 10px 12px;
  margin: 12px 0 0; font-size: 12.5px;
}
.aviso-respaldo[hidden] { display: none; }

/* ---------- escaner de codigo de barras ---------- */
.escaner-caja { position: relative; margin-bottom: 12px; }
.escaner-caja video {
  width: 100%; max-height: 300px; border-radius: 12px; background: #000;
  object-fit: cover; display: block;
}
.escaner-caja video[hidden] { display: none; }
.escaner-caja .hint { text-align: center; }

.producto-cab { display: flex; gap: 12px; align-items: center; margin-bottom: 10px; }
.producto-cab img { width: 64px; height: 64px; object-fit: contain; border-radius: 10px; background: var(--card2); }
.producto-cab b { display: block; font-size: 16px; }
.producto-cab small { color: var(--dim); font-size: 12.5px; }
#productoTotal { flex: 1; margin: 0; align-self: center; }

/* ---------- tope de gasto ---------- */
#barraGasto { background: var(--acc2); width: 0; }
#barraGasto.alerta { background: var(--warn); }
#barraGasto.bloqueado { background: var(--bad); }

/* ---------- nutrientes opcionales ---------- */

/* Menú de dónde sacar la foto. Solo aparece en pantallas táctiles: en la compu
   el botón va derecho al explorador, porque "sacar una foto" no significa nada ahí. */
.opciones-origen { display: flex; flex-direction: column; gap: 10px; padding-bottom: max(14px, env(safe-area-inset-bottom)); }

/* Lo que ya viene resuelto con la app no se muestra: es plomeria, no una
   decision del usuario. Queda a mano por si alguna vez hace falta. */
.avanzado { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 10px; }
.avanzado > summary {
  cursor: pointer; font-size: 12.5px; color: var(--txt2);
  list-style: none; display: flex; align-items: center; gap: 6px;
}
.avanzado > summary::-webkit-details-marker { display: none; }
.avanzado > summary::before { content: '▸'; font-size: 10px; }
.avanzado[open] > summary::before { content: '▾'; }
.avanzado > summary:hover { color: var(--txt); }
.avanzado > *:not(summary) { margin-top: 10px; }
/* El ocultamiento nativo de <details> deberia alcanzar, pero acá se decide qué
   ve el usuario: si algún navegador no lo aplica, quedan expuestas credenciales
   que no tiene por qué tocar. Con esto no depende de eso. */
.avanzado:not([open]) > *:not(summary) { display: none; }

/* ---------- tablero de objetivos del día ---------- */

/* Los tres que se usan siempre, del mismo tamaño y en una sola línea: la
   decisión de "con qué cargo esto" tiene que ser de un vistazo. */
/* Una sola acción, a lo ancho.
   Era una grilla de tres columnas para Foto, Código y Etiqueta; con los otros
   dos mudados al menú de la flechita, Foto se quedaba en un tercio del ancho y
   los otros dos tercios en blanco. Y es la acción principal de la app: cuanto
   más grande, mejor. */
.acciones-fila { display: grid; grid-template-columns: 1fr; gap: 8px; margin: 12px 0; }
.acciones-fila .accion-doble { width: 100%; }
.acciones-fila .accion {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 12px 4px; border-radius: 14px; border: 1px solid var(--line);
  background: var(--card); color: var(--txt); font-size: 20px; cursor: pointer;
}
.acciones-fila .accion span { font-size: 11.5px; font-weight: 600; }
.acciones-fila .accion.primary { background: var(--acc); color: var(--sobre-acc); border-color: transparent; }
.acciones-fila .accion:active { transform: scale(.97); }

/* Cada objetivo cargado se apaga: lo que ya está hecho no tiene que seguir
   pidiendo atención. Es lo que hace que la pantalla se vacíe durante el día. */
/* minmax(0, 1fr) y no 1fr a secas: `1fr` respeta el ancho mínimo del contenido,
   así que un valor largo —"16.000 kcal"— ensancha su columna y empuja a las
   demás fuera de la pantalla. Con el 0 se reparten el ancho parejo pase lo que
   pase adentro. */
/* Tantas columnas como casilleros haya, sin numero fijo: eran siete, quedaron
   cuatro, y con repeat(7) los cuatro se apretaban en la mitad izquierda de la
   pantalla dejando media fila vacia. */
.objetivos { display: flex; gap: 8px; margin-bottom: 12px; }
.objetivos > * { flex: 1 1 0; min-width: 0; }
.objetivo b, .objetivo small { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Con cuatro casilleros en vez de siete sobra ancho, y lo que antes tenia que
   entrar en 48 px ahora tiene 87: el texto crece hasta donde se lee comodo. */
.objetivo {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 12px 4px; border-radius: 14px; border: 1px dashed var(--line);
  background: transparent; color: var(--txt2); cursor: pointer; font-size: 20px;
}
.objetivo b { font-size: 12.5px; font-weight: 600; }
.objetivo small { font-size: 11.5px; color: var(--dim); }
.objetivo.listo {
  border-style: solid; border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 12%, transparent); color: var(--txt);
}
.objetivo.listo b { color: var(--acc); }


/* vasos de agua: se toca al que llegaste */
.vasos { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 6px 0 10px; }
.vaso {
  width: 40px; height: 48px; border-radius: 6px 6px 12px 12px;
  border: 2px solid var(--line); background: transparent; cursor: pointer;
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 4px;
  font-size: 11px; color: var(--dim);
}
.vaso.lleno { border-color: var(--acc); background: color-mix(in srgb, var(--acc) 25%, transparent); color: var(--txt); }

.caritas { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-bottom: 12px; }
.carita {
  padding: 12px 2px; border-radius: 14px; border: 1px solid var(--line);
  background: var(--card); cursor: pointer; font-size: 24px;
}
.carita.elegida { border-color: var(--acc); background: color-mix(in srgb, var(--acc) 15%, transparent); }

.mas-opciones {
  width: 100%; padding: 10px; border-radius: 12px; border: 1px dashed var(--line);
  background: transparent; color: var(--txt2); font-size: 12.5px; cursor: pointer;
}

/* marca de si la comida entra en el modo */
.marca-apta { font-size: 11px; padding: 1px 6px; border-radius: 6px; font-weight: 650; }
.marca-apta.no { background: color-mix(in srgb, var(--err) 20%, transparent); color: var(--err); }
.marca-apta.justo { background: color-mix(in srgb, var(--warn) 20%, transparent); color: var(--warn); }

/* El anillo y los macros lado a lado: juntos se llevaban 428 de los 812 px de
   un celular, o sea media pantalla para dos cosas que se leen de un vistazo. */
.resumen { display: grid; grid-template-columns: minmax(0, 148px) 1fr; gap: 8px; align-items: stretch; }
.resumen > .card { margin: 0; }
.resumen .ring-card { display: flex; flex-direction: column; justify-content: center; padding: 10px 6px; }
.resumen .ring-stats { display: flex; flex-direction: column; gap: 1px; margin-top: 6px; font-size: 10.5px; }
.resumen .ring-stats > div { display: flex; justify-content: space-between; gap: 6px; }
.resumen .ring-stats small { font-size: 9.5px; }
.resumen .macros { padding: 10px 12px; display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.resumen .macro-head { font-size: 11.5px; }

/* Los tres números del día en una franja, a todo el ancho: en columna dentro de
   la tarjeta del anillo se llevaban 135 px para tres cifras. */
#tab-hoy > .ring-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
  margin: 8px 0 0; padding: 8px 10px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--line);
}
#tab-hoy > .ring-stats > div { display: flex; flex-direction: column; align-items: center; gap: 0; }
#tab-hoy > .ring-stats span { font-size: 15px; font-weight: 700; }
#tab-hoy > .ring-stats small { font-size: 10px; color: var(--dim); }

/* En el celular la pantalla del día tiene que entrar entera. Lo que crece sin
   límite es la lista de comidas, así que esa scrollea adentro de su caja y la
   estructura de arriba queda siempre a la vista. */
@media (max-width: 480px) {
  main { padding: 8px 10px 74px; }
  #tab-hoy .card { margin-bottom: 8px; padding: 10px 12px; }
  #tab-hoy .card-head { padding: 0 0 6px; }
  #tab-hoy .card-head h2 { font-size: 14px; }
  .acciones-fila { margin: 8px 0; }
  .objetivos { margin-bottom: 8px; }
  #listaComidas { max-height: 30vh; overflow-y: auto; }
  #cardComidas { margin-bottom: 6px; }
  .mas-opciones { padding: 8px; }
}

/* Perseguir alturas fijas es una carrera perdida: la lista crece con el día y
   cualquier número queda corto. Acá la estructura ocupa lo suyo y la lista se
   queda con lo que sobra, así entra siempre — con dos comidas o con ocho. */
@media (max-width: 480px) {
  /* Antes esto era `calc(100dvh - 216px)`. El 216 era una suma a ojo del alto
     del header, la barra de fecha y la nav, y quedaba corto: sobraban 120 px de
     pantalla vacia abajo mientras la lista de comidas se ahogaba en 37 px.
     Ahora el alto lo reparte el navegador, que sabe cuanto miden de verdad. */
  /* Alto exacto, no minimo: con `min-height` el padding de abajo se sumaba y
     el documento terminaba midiendo mas que la pantalla. El respiro para la
     barra de navegacion ya lo pone `main`. */
  body { display: flex; flex-direction: column; height: 100dvh; padding-bottom: 0; overflow: hidden; }
  /* El scroll se muda del documento a `main`: el body ahora mide exactamente
     una pantalla, y sin esto Historial, Progreso, Perfil y Ajustes —que son
     mas largos que la pantalla— quedaban sin poder scrollear. */
  main { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
  /* `flex: 0 0 auto` y no `1 1 auto`: estirado a la altura de `main`, el
     contenido que no entraba —la tira de comidas de un momento abierto— se
     comprimía adentro en vez de generar scroll, así que quedaba escondida
     detrás del botón sin forma de llegar a ella. Ahora manda el contenido: en
     el día normal entra entero y no aparece la barra; si abrís un momento y no
     alcanza, se scrollea, que es lo que uno espera al desplegar algo. */
  #tab-hoy.active {
    display: flex; flex-direction: column; min-height: 0; flex: 0 0 auto; height: auto;
  }
  /* Los siete en una sola fila, que es el pedido y tambien lo que venia
     haciendo la grilla desde que eran seis: dos filas cuestan 80 px de alto
     para decir lo mismo, en la pantalla que tiene que entrar entera.

     Siete en 375 px dan 47 px por casillero, y ahi la letra de 10 px ya no
     entra: "Ejercicio" se cortaba en "Ejerci…". Por eso baja a 8,5 px con el
     interletrado apretado y el emoji a 14 px — es la unica forma de que los
     siete conserven su NOMBRE, que es lo que los hace distinguibles de un
     vistazo. Sin nombre serian siete emojis y habria que aprenderselos. */
  #tab-hoy .objetivos { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
  /* La pantalla de Hoy tiene que entrar sin scroll, asi que aca todo se
     achicaba. Con cuatro casilleros el alto que se gano se reparte en el
     texto: sigue siendo mas chico que en grande, pero se lee. */
  #tab-hoy .objetivo { padding: 9px 2px; gap: 2px; font-size: 18px; }
  #tab-hoy .objetivo b { font-size: 11px; letter-spacing: -.2px; }
  #tab-hoy .objetivo small { font-size: 10px; }
  /* La lista de comidas NO tiene scroll propio.
     Lo tuvo, y era peor: con seis comidas cargadas la caja quedaba en 52 px y
     se veia una fila y media, mientras el resto de la pantalla estaba lleno de
     tarjetas fijas. Ahora la lista mide lo que mide y, si el dia es pesado, se
     scrollea la pantalla — que es lo que uno espera que pase. Con un dia normal
     de dos o tres comidas sigue entrando todo sin scroll. */
  #cardComidas { flex: 0 0 auto; display: flex; flex-direction: column; }
  #listaComidas { flex: 0 0 auto; min-height: 0; max-height: none; overflow: visible; }
  .resumen { grid-template-columns: minmax(0, 132px) 1fr; }

  /*
   * Sacar la foto es la acción principal y estaba a mitad de la pantalla: con
   * el día cargado había que scrollear para encontrarla. Apoyada sobre la
   * barra de pestañas queda siempre debajo del pulgar, y de paso libera los
   * 64 px de alto que se llevaba del flujo.
   */
  #tab-hoy .acciones-fila {
    position: fixed; left: 0; right: 0; bottom: var(--tabbar-h, 62px); z-index: 29;
    margin: 0 auto; padding: 6px 10px 8px; max-width: 620px;
    /* Degradado y no un fondo plano: lo que pasa por debajo se desvanece en
       vez de cortarse en una línea. */
    background: linear-gradient(to top, var(--bg) 55%, transparent);
  }
  /* El hueco que deja: sin esto la última tarjeta queda debajo del botón. */
  #tab-hoy.active { padding-bottom: 58px; }
  #tab-hoy .acciones-fila .accion { padding: 10px 4px; }
}

/* El cronómetro del ayuno: es lo único que hay que ver al abrirlo. */
.ayuno-reloj { font-size: 40px; font-weight: 700; text-align: center; margin: 8px 0 4px; font-variant-numeric: tabular-nums; }
.ayuno-reloj.completo { color: var(--acc); }
/* Los siete, en una sola fila. Ver la nota de la version movil, mas abajo. */
/* el reparto por columnas automaticas ya vale para cualquier cantidad */
.chip.activo { border-color: var(--acc); color: var(--acc); }

/* Mantener apretado un ejercicio abre su tiempo: sin esto el gesto selecciona
   el texto del chip y en iOS levanta el menu de copiar. */
.act-uno { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }

/* El veredicto: lo primero que se ve al entrar al historial. */
#cardVeredicto.bien { border-left: 3px solid var(--acc); }
#cardVeredicto.lento, #cardVeredicto.rapido { border-left: 3px solid var(--warn); }
#cardVeredicto.mal { border-left: 3px solid var(--err); }
#cardVeredicto.sin-datos { border-left: 3px solid var(--line); }
#veredictoTitulo { font-size: 15px; }
.lista-reco { list-style: none; margin: 0; padding: 0; }
.lista-reco li { padding: 7px 0 7px 18px; position: relative; font-size: 12.5px; color: var(--txt2); border-top: 1px solid var(--line); }
.lista-reco li:first-child { border-top: 0; }
.lista-reco li::before { content: '→'; position: absolute; left: 0; color: var(--acc); }

/* Negro puro: en OLED el píxel apagado no consume, así que esto es batería real. */
:root[data-tema="oled"] {
  --bg: #000000;
  --bg2: #0a0a0a;
  --card: #121212;
  --card2: #1c1c1c;
  --line: #262626;
  --txt: #f2f2f2;
  --txt2: #b8b8b8;
  --dim: #949494;   /* 17: no llegaba a 4.5:1 sobre el negro OLED */
  --acc: #4ade80;
  --sobre-acc: #04150a;
}

/* Cálido: menos azul, para cargar la cena sin quedar despierto después. */
:root[data-tema="calido"] {
  --bg: #1a1512;
  --bg2: #221b16;
  --card: #2a221c;
  --card2: #342a22;
  --line: #40342a;
  --txt: #f5ece2;
  --txt2: #c8b7a6;
  --dim: #a89a89;
  --acc: #e8a33d;
  --sobre-acc: #241705;
  --warn: #f0c674;
}

/* El anillo: el contenedor manda el tamano y el svg lo llena.
   Antes .ring-wrap estaba fijo en 190 px y yo habia achicado solo el <svg>:
   el numero del centro se posiciona sobre el wrap, asi que quedaba centrado en
   190 mientras el circulo media 104 —de ahi el desfasaje— y en escritorio el
   wrap no entraba en su columna y se cortaba. */
.resumen .ring-wrap {
  width: 100%;
  max-width: 132px;
  height: auto;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}
.resumen .ring-wrap .ring { width: 100%; height: 100%; }

/* El numero acompana al tamano del anillo en vez de quedar fijo. */
.resumen .ring-center strong { font-size: clamp(20px, 7vw, 30px); letter-spacing: -1px; }
.resumen .ring-center span { font-size: 11px; }

/* En pantallas grandes hay lugar de sobra: el anillo vuelve a respirar. */
@media (min-width: 700px) {
  .resumen { grid-template-columns: minmax(0, 210px) 1fr; }
  .resumen .ring-wrap { max-width: 180px; }
  .resumen .ring-center strong { font-size: 34px; }
}

/* El botón grande va derecho a la cámara, que es lo que se hace el 95% de las
   veces. La flechita es la salida para la galería, sin robarle lugar. */
.accion-doble { position: relative; display: flex; }
.accion-doble .accion { flex: 1; padding-right: 16px; }
/* 22 px era menos que la yema de un dedo: se erraba tanto que en la práctica
   la galería quedaba escondida. 46 px es el mínimo cómodo para tocar, y el
   triángulo más grande la hace visible como botón y no como adorno. */
.accion-doble .flechita {
  position: absolute; top: 0; right: 0; width: 46px; height: 100%;
  border: 0; border-radius: 0 14px 14px 0; cursor: pointer;
  background: rgba(0, 0, 0, .16); color: inherit; font-size: 16px;
  display: flex; align-items: center; justify-content: center;
}
.accion-doble .flechita:active { background: rgba(0, 0, 0, .28); }

/* El flex de la tarjeta estiraba el contenedor y el anillo quedaba ovalado
   (106 de ancho por 112 de alto). Con flex fijo el aspect-ratio manda. */
.resumen .ring-wrap { flex: 0 0 auto; display: block; }
.resumen .ring-wrap .ring { display: block; }

/* El número y el objetivo tienen que entrar DENTRO del círculo, no pasarse. */
/* Padding y no width: .ring-center se centra con inset:0, y fijarle un ancho
   entra en conflicto con eso y lo tira contra el borde izquierdo. */
.resumen .ring-center {
  padding: 0 10%;
  text-align: center;
  line-height: 1.05;
}
.resumen .ring-center span {
  display: block;
  font-size: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* El resumen de lo que se guardó solo. Grande y de un vistazo: no hay nada que
   revisar, solo confirmar que entendió bien. */
.resumen-comida { text-align: center; padding: 22px 18px max(18px, env(safe-area-inset-bottom)); }
.resumen-icono { font-size: 34px; line-height: 1; margin-bottom: 6px; }
.resumen-comida h2 { margin: 0 0 10px; font-size: 17px; }
.resumen-kcal { display: flex; align-items: baseline; justify-content: center; gap: 5px; margin-bottom: 12px; }
.resumen-kcal strong { font-size: 40px; font-weight: 700; letter-spacing: -1.5px; }
.resumen-kcal span { font-size: 13px; color: var(--dim); }
.marca-apta.grande {
  display: inline-block; font-size: 13px; padding: 5px 12px; border-radius: 999px;
  background: color-mix(in srgb, var(--acc) 18%, transparent); color: var(--acc);
  margin-bottom: 8px;
}
.marca-apta.grande.no { background: color-mix(in srgb, var(--err) 18%, transparent); color: var(--err); }
.marca-apta.grande.justo { background: color-mix(in srgb, var(--warn) 20%, transparent); color: var(--warn); }
.resumen-comida .actions-row { margin-top: 14px; }

/* ---------- el personaje ---------- */

.mascota {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 14px; margin-bottom: 8px; cursor: pointer; text-align: left;
  border-radius: 16px; border: 1px solid var(--line); background: var(--card);
}
.mascota:active { transform: scale(.995); }
/* Un <button> no hereda el color del texto: sin esto se queda con el del
   sistema, que en oscuro es casi negro sobre la tarjeta oscura. */
.mascota, .objetivo { color: var(--txt); }
.mascota-dibujo { flex: 0 0 auto; line-height: 0; }
.mascota-svg { display: block; }
.mascota-texto { min-width: 0; flex: 1; }
.mascota-texto b { display: block; font-size: 13.5px; margin-bottom: 2px; }
.mascota-texto small { display: block; font-size: 11.5px; color: var(--txt2); line-height: 1.35; }

.mascota-nivel { display: flex; align-items: center; gap: 6px; margin-top: 5px; font-size: 10px; color: var(--dim); }
.mascota-nivel #mascotaLvl { margin-left: auto; white-space: nowrap; }
.mascota-barra { display: block; height: 4px; border-radius: 3px; background: var(--card2); overflow: hidden; margin-top: 5px; }
.mascota-barra i { display: block; height: 100%; background: var(--acc); border-radius: 3px; transition: width .4s ease; }

/* ---- 20. Menos movimiento, de una sola vez ----

   Habia SEIS bloques de `prefers-reduced-motion` desperdigados, cada uno
   apagando lo suyo, y cada animacion nueva del ciclo siguiente nacia sin
   apagar. Esta regla los cubre a todos y a los que vengan: lo que se agregue
   despues queda contemplado sin acordarse. Los bloques puntuales quedan igual
   —no molestan— pero ya no son la unica defensa. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Visible solo para lectores de pantalla. No se usa `display:none` ni
   `visibility:hidden` porque los dos lo sacan tambien del lector. */
.solo-lectores {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* 19. Foco visible en todo. El navegador lo pone solo, pero varios controles
   propios le pisaban el outline con `outline:none` heredado del reset. */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ---------------- el selector de modos ----------------

   No tenia una sola linea de CSS: el nombre y el resumen salian pegados
   ("MantenimientoSostener el peso actual") porque el <small> es inline y los
   botones se apilaban como texto corrido. */
.modos { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 8px; }
/* La regla de clase le gana al display:none del navegador: sin esto el atributo
   hidden no plegaba nada. */
.modos[hidden] { display: none; }

/* El modo en uso, siempre a la vista, y la flecha que despliega los otros. */
.modo-actual { position: relative; padding-right: 34px; margin-bottom: 8px; }
/* La flecha cambia de caracter y no de rotacion: el transform sobre el
   pseudo-elemento no se veia. */
.modo-actual::after {
  content: '▾'; position: absolute; right: 12px; top: 9px;
  color: var(--dim); font-size: 15px; line-height: 1;
}
.modo-actual[aria-expanded="true"]::after { content: '▴'; }

.modo-btn {
  display: flex; align-items: flex-start; gap: 9px; text-align: left; width: 100%;
  background: var(--card2); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 12px; cursor: pointer; color: var(--txt);
  transition: border-color .15s, background .15s;
}
.modo-btn i { font-style: normal; font-size: 18px; line-height: 1.15; flex: 0 0 auto; }
.modo-btn span { min-width: 0; }
/* En bloque y no inline: es lo que separa el nombre del resumen. */
.modo-btn b { display: block; font-size: 13.5px; font-weight: 700; line-height: 1.25; }
.modo-btn small { display: block; font-size: 11.5px; color: var(--dim); line-height: 1.35; margin-top: 2px; }

.modo-btn:hover { border-color: var(--dim); }
.modo-btn.activo {
  border-color: var(--acc); background: color-mix(in srgb, var(--acc) 12%, var(--card2));
}
.modo-btn.activo b { color: var(--acc); }

@media (max-width: 480px) {
  .modos { grid-template-columns: 1fr; }
}

/* El desplegable de la barra: cuelga del titulo, tapando lo de abajo en vez de
   empujarlo. Con diecisiete modos no entra en pantalla, asi que scrollea el
   panel y no la app: el titulo tiene que seguir a la vista para cerrarlo. */
.modos-barra {
  position: absolute; top: 100%; left: 8px; right: 8px;
  max-height: 62vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 14px; padding: 8px; z-index: 30;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .3);
  /* Dos columnas: en una sola, quince modos son ocho pantallas de scroll dentro
     del panel para elegir uno. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

/* Y sin el resumen: en la mitad del ancho no entra, y el nombre de cada modo ya
   dice de que va. La explicacion sigue entera en Perfil, que es donde se los
   compara; aca se viene a cambiar el que ya conoces. */
.modos-barra .modo-btn small { display: none; }
.modos-detalle {
  grid-column: 1 / -1; margin: 2px 4px 6px;
  font-size: 11.5px; line-height: 1.4; color: var(--dim);
}
.modos-barra .modo-btn { padding: 10px; align-items: center; }
.modos-barra .modo-btn b { font-size: 13px; }

/* La flecha del titulo, como la del modo en Perfil: sin ella el nombre no dice
   que se pueda tocar. */
/* La flecha va en el contenedor y no en el h1: adentro del h1 entraba en el
   calculo de los puntos suspensivos y le comia una letra al nombre del modo. */
.titulo::after { content: '▾'; color: var(--dim); font-size: 11px; flex: 0 0 auto; }
.titulo.abierta::after { content: '▴'; }
/* Cuatro pixeles de la fecha para que el nombre del modo entre entero al lado
   del icono: "Hoy" y "12 sep" entran igual en 46. */
.topbar .date-nav span { min-width: 46px; }

/* A 320 px no entran las cuatro cosas: la que cede es la palabra "Ayuno", que
   el reloj ya dice. Con un ayuno corriendo el texto vuelve —ahi dice cuantas
   horas llevas— y lo que cede es el nombre del modo, que se lee igual cortado. */
@media (max-width: 360px) {
  .topbar .tira:not(.corriendo) > span { display: none; }
  /* Los ultimos nueve pixeles salen de los tres espacios entre las cuatro
     cosas y del boton de datos, que se toca igual con 26. */
  .topbar { gap: 5px; }
  .topbar #btnDatos { width: 26px; height: 26px; font-size: 14px; }
}

/* Ajustes eran trece tarjetas apiladas, cuatro pantallas de scroll para llegar
   a la ultima. Ahora cada una se pliega: el titulo y su estado siempre a la
   vista, el contenido a un toque. El indice entero entra en una pantalla. */
.card.plegable > summary { cursor: pointer; list-style: none; margin-bottom: 0; gap: 8px; }
.card.plegable[open] > summary { margin-bottom: 10px; }
.card.plegable > summary::-webkit-details-marker { display: none; }
.card.plegable > summary::after { content: '▾'; color: var(--dim); font-size: 13px; }
.card.plegable[open] > summary::after { content: '▴'; }
/* El estado se pega a la flecha: con space-between y tres piezas quedaba
   repartido por el medio del renglon. */
.card.plegable > summary .pill { margin-left: auto; margin-right: 8px; }
/* Sin esto un navegador que no aplique el ocultado nativo de <details> deja
   trece tarjetas abiertas, que es exactamente lo que se venia a arreglar. */
.card.plegable:not([open]) > *:not(summary) { display: none; }

/* Lo que un plegable esconde, dicho en el propio rotulo. */
.resumen-plegado { color: var(--dim); font-weight: 400; }

/* Sexo, edad y altura arriba de todo: sin la linea de arriba, que ahi separa
   del modo en vez de cerrar la tarjeta. */
.datos-fijos { border-top: 0; padding-top: 0; margin-bottom: 12px; }

/* El unico numero de la tarjeta del calculo que se mira todos los dias. */
.calc-objetivo { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.calc-objetivo b { font-size: 26px; font-weight: 700; color: var(--acc); line-height: 1.1; }
.calc-objetivo span { font-size: 13px; color: var(--dim); }

/* El boton de guardar quedo despues del plegable del objetivo manual, asi que
   la regla que lo separaba de la grilla ya no lo alcanzaba. */
.avanzado + button { margin-top: 14px; }

/* El selector del objetivo de agua. */
.meta-agua { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 12.5px; color: var(--dim); }
.meta-agua b { color: var(--txt); font-size: 13.5px; min-width: 62px; text-align: center; }
.meta-agua button {
  width: 30px; height: 30px; border-radius: 9px; font-size: 17px; line-height: 1;
  background: var(--card2); border: 1px solid var(--line); color: var(--txt); cursor: pointer;
}
.meta-agua button:disabled { opacity: .35; cursor: default; }
.meta-agua span { margin-right: auto; }

/* En pantallas anchas el modal se centra. Pegado abajo del todo se lee como si
   estuviera cortado por el borde, que es justo lo que parecia. */
@media (min-width: 620px) {
  .modal { align-items: center; padding: 20px; }
  .modal-box { border-radius: 18px; max-height: 84vh; }
}

/* La fase, al lado del titulo. El color lo pone el JS: cambia con la fase. */
.fase-chip {
  display: inline-block; margin-left: 6px; vertical-align: 1px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .3px; text-transform: uppercase;
  border: 1px solid; border-radius: 20px; padding: 1px 6px;
}

/* La fase que viene de ayer, con el día de hoy todavía en blanco. Apagada y
   con el borde cortado: se ve que está, y se ve que no está firme. Sin esto la
   pantalla mostraba el muñeco en llamas al lado de "el día está en blanco". */
.fase-chip.en-riesgo {
  opacity: .55; border-style: dashed; font-weight: 700;
}

/* El +XP que sube cuando se completa un objetivo. Sin esto, cumplir no se
   sentia: el casillero se ponia verde y nada mas. */
.objetivo { position: relative; }
.xp-flotante {
  position: absolute; left: 50%; top: 2px; transform: translateX(-50%);
  font-size: 12px; font-weight: 800; color: var(--acc); pointer-events: none;
  animation: subeXp 1.1s cubic-bezier(.2, .8, .3, 1) forwards;
}
@keyframes subeXp {
  0% { opacity: 0; transform: translate(-50%, 6px) scale(.8); }
  25% { opacity: 1; transform: translate(-50%, -2px) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -34px) scale(1); }
}
.objetivo.festeja { animation: pum .45s ease; }
@keyframes pum { 50% { transform: scale(1.13); } }
@media (prefers-reduced-motion: reduce) {
  .xp-flotante, .objetivo.festeja { animation: none; }
  .xp-flotante { display: none; }
}

/* La fila de chips de arriba: el modo activo y el ayuno. */
/* Las tiras se reparten el ancho en vez de quedar apretadas a la izquierda con
   media pantalla vacía al lado. Con una sola —lo normal, porque el ayuno solo
   aparece si hay uno corriendo— ocupa la fila entera. */
/*
 * Grid y no flex, y esto importa.
 *
 * Con `display: flex` y sin `flex-wrap`, cuando los chips no entran el
 * contenedor crece hasta su contenido y arrastra a toda la página: el ancho de
 * `main` pasaba de 375 a 486 px y la pantalla entera quedaba corrida, con el
 * título fuera de vista. `flex: 1 1 0` no alcanza para frenarlo porque el
 * contenido de cada chip tiene su propio mínimo.
 *
 * `grid-auto-columns: minmax(0, 1fr)` reparte las columnas que haya sin que
 * ninguna pueda pasarse de su parte, sin importar qué tan largo sea el texto
 * de adentro.
 */
.tiras {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  gap: 6px;
}
.tiras > * { min-width: 0; justify-content: center; overflow: hidden; }
.tira small, .tira span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tira {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; color: var(--txt);
  background: var(--card); border: 1px solid var(--line); border-radius: 20px;
  padding: 5px 11px; cursor: pointer;
}
.tira i { font-style: normal; font-size: 12px; }
.tira small { color: var(--dim); font-weight: 500; }
.tira.activa { border-color: var(--acc); color: var(--acc); }
/* El ayuno en curso late: es lo unico de la pantalla que corre solo. */
.tira.corriendo { border-color: var(--warn); color: var(--warn); }
.tira.corriendo i { animation: latir 2s ease-in-out infinite; }
@keyframes latir { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .tira.corriendo i { animation: none; } }

/* Las cuatro rachas. Las apagadas se ven, no desaparecen: un hueco donde antes
   había un número dice más que no mostrar nada. */
.rachas { display: flex; gap: 4px; }
.racha {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: 10.5px; font-weight: 700; color: var(--dim);
  background: var(--card2); border-radius: 20px; padding: 2px 7px 2px 5px;
  opacity: .55; transition: opacity .2s, background .2s;
}
.racha i { font-style: normal; font-size: 11px; filter: grayscale(1); }
.racha.viva { opacity: 1; color: var(--txt); }
.racha.viva i { filter: none; }
/* La que ya se cumplió HOY se marca aparte: la racha dice qué venís haciendo,
   esto dice qué te falta ahora. */
.racha.hoy { background: color-mix(in srgb, var(--ok) 22%, transparent); }

/* ---------------- el personaje en movimiento ----------------

   Todo con CSS y clases dentro del SVG. Se re-genera en cada render, así que
   las animaciones reinician solas y no hace falta guardar ningún estado.
   `prefers-reduced-motion` apaga todo al final del bloque, de una. */

/* El aura respira y se estira hacia arriba. */
.mascota-svg .aura { transform-origin: 60px 168px; animation: auraLate 1.15s ease-in-out infinite alternate; }
@keyframes auraLate {
  from { transform: scaleY(.94) scaleX(1.02); opacity: .8; }
  to { transform: scaleY(1.08) scaleX(.98); opacity: 1; }
}

/* Las partículas de ki suben y se apagan. */
.mascota-svg .ki { animation: kiSube 1.5s linear infinite; opacity: 0; }
@keyframes kiSube {
  0% { transform: translateY(6px); opacity: 0; }
  15% { opacity: .95; }
  100% { transform: translateY(-74px); opacity: 0; }
}

/* La electricidad parpadea con pasos, no con degradé: un rayo que se desvanece
   suave no se lee como un rayo. */
.mascota-svg .chispa { animation: chispea .5s steps(1, end) infinite; }
@keyframes chispea { 0%, 22% { opacity: 1; } 23%, 100% { opacity: 0; } }

/* El pelo de las fases se mece. */
.mascota-svg.fase-1 > g, .mascota-svg.fase-2 > g, .mascota-svg.fase-3 > g,
.mascota-svg.fase-4 > g, .mascota-svg.fase-5 > g, .mascota-svg.fase-6 > g {
  transform-origin: 60px 110px;
  animation: tension 2.4s ease-in-out infinite alternate;
}
@keyframes tension { from { transform: translateY(0); } to { transform: translateY(-1.6px); } }

/* El momento de transformarse: la pantalla tiembla y el personaje destella. */
.mascota-dibujo.transformando { animation: sacudon .75s cubic-bezier(.36, .07, .19, .97); }
@keyframes sacudon {
  10%, 30%, 50%, 70% { transform: translate(-3px, 1px); }
  20%, 40%, 60%, 80% { transform: translate(3px, -1px); }
  90% { transform: translate(-1px, 0); }
}
.mascota-dibujo.transformando .mascota-svg { animation: destello .75s ease-out; }
@keyframes destello {
  0% { filter: brightness(3.2) saturate(0); }
  35% { filter: brightness(1.7) saturate(1.4); }
  100% { filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .mascota-svg .aura, .mascota-svg .ki, .mascota-svg .chispa,
  .mascota-svg.fase-1 > g, .mascota-svg.fase-2 > g, .mascota-svg.fase-3 > g,
  .mascota-svg.fase-4 > g, .mascota-svg.fase-5 > g, .mascota-svg.fase-6 > g,
  .mascota-dibujo.transformando, .mascota-dibujo.transformando .mascota-svg { animation: none; }
  .mascota-svg .ki { opacity: .8; }
}

/* El personaje respira: quieto del todo parece un ícono, no un bicho. */
@keyframes respirar { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
.mascota-svg { animation: respirar 3.5s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .mascota-svg { animation: none; } }

/* Azules profundos con acento turquesa. */
:root[data-tema="oceano"] {
  --bg: #0a1622; --bg2: #0f1e2e; --card: #14283c; --card2: #1c3450;
  --line: #21405c; --txt: #e6f0f8; --txt2: #a8c0d4; --dim: #8fa9c0;
  --acc: #2dd4bf; --sobre-acc: #04201c; --warn: #fbbf24; --err: #f87171;
}

/* Verdes apagados: el que menos cansa de los oscuros. */
:root[data-tema="bosque"] {
  --bg: #101a14; --bg2: #16221a; --card: #1c2c22; --card2: #24382c;
  --line: #2c4436; --txt: #e8f2ea; --txt2: #b0c8b8; --dim: #97b0a1;
  --acc: #7cc47f; --sobre-acc: #08200c; --warn: #d9b166; --err: #e88a8a;
}

/* Oscuro con acento bordo, para el que quiere algo que no sea verde. */
:root[data-tema="vino"] {
  --bg: #171014; --bg2: #1e1418; --card: #281a20; --card2: #33222a;
  --line: #402a34; --txt: #f4e8ec; --txt2: #cbb0ba; --dim: #b6929e;
  --acc: #e0607f; --sobre-acc: #24060e; --warn: #e8b06a; --err: #ff8a8a;
}

/* Claro y calido, como una libreta de papel. */
:root[data-tema="papel"] {
  --bg: #f7f3ea; --bg2: #fffdf7; --card: #fffdf7; --card2: #f0e9db;
  --line: #e0d7c4; --txt: #2c2620; --txt2: #5f564a; --dim: #6e6658;
  --acc: #2f7d4f; --sobre-acc: #ffffff; --warn: #a06a1a; --err: #b3382f;
}

/* ---------- progreso ---------- */

/* Los cuatro rangos en una fila. Con tres columnas, "Todo" caía solo a un
   renglón aparte y se leía como si fuera otra cosa. */
.periodos { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 10px; }
.periodo {
  padding: 8px 4px; border-radius: 11px; border: 1px solid var(--line);
  background: var(--card); color: var(--txt2); font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.periodo.activo { border-color: var(--acc); background: color-mix(in srgb, var(--acc) 14%, transparent); color: var(--acc); }

.gr { width: 100%; height: 130px; display: block; overflow: visible; }

/* Editar actividades: la fila entera es el interruptor de favorita. */
.act-fila { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--line); }
.act-fila:first-child { border-top: 0; }
.act-nombre {
  flex: 1; text-align: left; background: transparent; border: 0; cursor: pointer;
  color: var(--txt2); font-size: 13px; padding: 4px 0;
}
.act-fila.fav .act-nombre { color: var(--acc); font-weight: 600; }
.act-nombre small { display: block; font-size: 10.5px; color: var(--dim); font-weight: 400; }
.act-min { width: 62px; text-align: center; }

/* La hora de dormir y el estado fijo: la misma fila de una linea que los
   horarios de arriba, para que el bloque se lea como una sola lista. */
.fila-dormir {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 10px; text-align: left;
  margin-top: 2px; font-size: 13px; min-height: 34px;
}
.fila-dormir span {
  min-width: 0; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fila-dormir input[type="time"] { width: 102px; font-size: 13px; padding: 5px 8px; }


/* ---------------- nivel, rachas grandes y logros ---------------- */

.nivel-barra { height: 9px; border-radius: 5px; background: var(--card2); overflow: hidden; margin: 2px 0 8px; }
.nivel-barra i { display: block; height: 100%; background: var(--acc); border-radius: 5px; transition: width .5s ease; }

.rachas-grande { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 10px; }
.racha-g {
  background: var(--card2); border-radius: 10px; padding: 8px 4px; text-align: center;
  opacity: .5; transition: opacity .2s;
}
.racha-g.viva { opacity: 1; }
.racha-g b { display: block; font-size: 17px; line-height: 1.1; }
.racha-g i { font-style: normal; font-size: 16px; filter: grayscale(1); }
.racha-g.viva i { filter: none; }
.racha-g small { display: block; font-size: 9.5px; color: var(--dim); margin-top: 1px; }
/* El récord solo aparece cuando la racha viva no lo alcanzó: si son iguales,
   repetir el número dos veces es ruido. */
.racha-g em { font-style: normal; font-size: 9px; color: var(--dim); opacity: .8; }

.logros { display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 7px; }
.logro {
  background: var(--card2); border-radius: 10px; padding: 9px 5px; text-align: center;
  opacity: .38; filter: grayscale(1);
}
.logro.ganado { opacity: 1; filter: none; }
.logro i { font-style: normal; font-size: 21px; display: block; }
.logro b { display: block; font-size: 10px; margin-top: 3px; line-height: 1.25; }
.logro small { display: block; font-size: 8.5px; color: var(--dim); margin-top: 2px; line-height: 1.25; }

/* El cartel de logro nuevo. Se muestra sobre todo lo demás y se va solo: pedir
   que lo cierren a mano convierte un premio en un trámite. */
.festejo {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .55); z-index: 90; padding: 24px;
  animation: aparecer .2s ease;
}
.festejo-caja {
  background: var(--card); border-radius: 18px; padding: 22px 20px; text-align: center;
  max-width: 300px; box-shadow: 0 18px 50px rgba(0, 0, 0, .4);
  animation: subir .35s cubic-bezier(.2, 1.3, .4, 1);
}
.festejo-caja .icono { font-size: 46px; line-height: 1; }
.festejo-caja h3 { margin: 10px 0 4px; font-size: 17px; }
.festejo-caja p { margin: 0; font-size: 12.5px; color: var(--dim); }
@keyframes aparecer { from { opacity: 0; } }
@keyframes subir { from { transform: translateY(18px) scale(.9); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .festejo, .festejo-caja { animation: none; }
}

.acciones-datos { margin-top: 8px; }

/* El boton sugerido segun la hora, y el "de mas" cuando te pasaste. */
.acciones-fila .sugerido { border-color: var(--acc); box-shadow: 0 0 0 1px var(--acc) inset; }
.ring-stats .pasado, #statRestante.pasado { color: var(--bad); }

/* El logro mas cerca: lo unico accionable de la pantalla de logros. */
.proximo-logro {
  background: var(--card2); border-radius: 10px; padding: 9px 11px; margin: 0 0 10px;
  border-left: 3px solid var(--acc);
}
.proximo-logro b { color: var(--txt); }
.proximo-logro i { font-style: normal; opacity: .8; }

/* La tarjeta del personaje se fue a 160 px al sumarle la fase, el XP y las
   rachas, y con eso Hoy dejaba de entrar con una sola comida cargada. El texto
   se corta en dos lineas: el detalle completo esta en el aria-label y en el
   title, asi que no se pierde nada. */
.mascota-texto small {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (max-width: 480px) {
  .mascota { padding: 9px 12px; margin-bottom: 6px; }
  .mascota-texto b { font-size: 13px; }
  .mascota-texto small { font-size: 11px; }
  .mascota-nivel { margin-top: 4px; }
  .mascota-barra { margin-top: 4px; }
}

/* El personaje por capas: fuego atras, el sprite del cuerpo, el pelo de la fase
   encima. Todas apiladas en el mismo lugar; el <img> es el que manda el tamano. */
.muneco { position: relative; display: inline-block; }
.muneco-cuerpo { display: block; width: 100%; height: 100%; object-fit: contain; }
.muneco-capa {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  pointer-events: none; overflow: visible;
}
.muneco-atras { z-index: 0; }
.muneco-cuerpo { position: relative; z-index: 1; }
.muneco .muneco-capa:last-child { z-index: 2; }
.muneco .muneco-atras { z-index: 0; }

/* El plan por etapas del peso objetivo. Una baja grande no se reta: se parte. */
.plan-etapas { margin-top: 6px; }
.plan-etapas .etapas { margin: 6px 0; padding-left: 18px; display: grid; gap: 4px; }
.plan-etapas .etapas li { font-size: 13px; }
.plan-etapas .etapas small { color: var(--dim); margin-left: 6px; }

/* ============================================================
   Animaciones. Ver animar.js: cada una tiene que DECIR algo.
   El bloque entero se apaga con prefers-reduced-motion, al final.
   ============================================================ */

@keyframes anim-pop {
  0% { transform: scale(1); }
  38% { transform: scale(1.16); }
  100% { transform: scale(1); }
}
.anim-pop { animation: anim-pop .42s cubic-bezier(.34, 1.56, .64, 1); }

@keyframes anim-salto {
  0%, 100% { transform: translateY(0) scale(1); }
  22% { transform: translateY(-14px) scale(1.04, .96); }
  45% { transform: translateY(0) scale(.96, 1.04); }
  62% { transform: translateY(-6px) scale(1); }
}
.anim-salto { animation: anim-salto .9s cubic-bezier(.28, .84, .42, 1); }

@keyframes anim-tiron {
  0%, 100% { transform: translateY(0); }
  30% { transform: translateY(-5px) rotate(-2deg); }
  60% { transform: translateY(1px) rotate(1deg); }
}
.anim-tiron { animation: anim-tiron .5s ease-out; }

@keyframes anim-error {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}
.anim-error { animation: anim-error .45s ease-out; }

/* Las partículas de un festejo. Se borran solas: ver particulas(). */
.particulas { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.particulas i {
  position: absolute; left: 50%; top: 45%;
  width: 6px; height: 6px; border-radius: 2px;
  animation: anim-particula .9s cubic-bezier(.2, .7, .35, 1) forwards;
}
@keyframes anim-particula {
  0% { transform: translate(-50%, -50%) scale(.4) rotate(0); opacity: 0; }
  15% { opacity: 1; }
  100% {
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.9) rotate(var(--giro));
    opacity: 0;
  }
}

/* La racha que se prende fuego al sumar un día. */
@keyframes anim-fuego {
  0%, 100% { transform: scale(1) rotate(0); filter: none; }
  30% { transform: scale(1.3) rotate(-6deg); filter: brightness(1.25); }
  60% { transform: scale(1.12) rotate(4deg); }
}
.anim-fuego { animation: anim-fuego .8s ease-out; }

/* El toast entra con rebote en vez de aparecer. */
@keyframes anim-toast-entra {
  0% { transform: translate(-50%, 18px) scale(.92); opacity: 0; }
  60% { transform: translate(-50%, -3px) scale(1.02); opacity: 1; }
  100% { transform: translate(-50%, 0) scale(1); opacity: 1; }
}

/* Al tocar, se hunde. Es el acuse de recibo mas barato que hay: sin esto, en un
   celular lento uno no sabe si el toque entro y toca de nuevo. */
.accion:active, .objetivo:active, button.primary:active, .chip:active, .vaso:active {
  transform: scale(.95);
}
.accion, .objetivo, button.primary, .chip, .vaso { transition: transform .12s ease-out; }

/* El cambio de pestaña. */
@keyframes anim-tab {
  0% { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}
.tab-entrando { animation: anim-tab .22s ease-out; }

/* Y todo esto se apaga si la persona pidio menos movimiento. Va al final para
   que gane por orden, sin depender de la especificidad de cada regla. */
@media (prefers-reduced-motion: reduce) {
  .anim-pop, .anim-salto, .anim-tiron, .anim-error, .anim-fuego,
  .particulas i, .tab-entrando, .toast {
    animation: none !important;
    transition: none !important;
  }
  .accion:active, .objetivo:active, button.primary:active, .chip:active, .vaso:active {
    transform: none;
  }
}

/* El anillo y las barras se mueven hasta su valor nuevo en vez de saltar. */
.ring-fg { transition: stroke-dashoffset .6s cubic-bezier(.2, .7, .35, 1); }
.bar i { transition: width .5s cubic-bezier(.2, .7, .35, 1); }
@media (prefers-reduced-motion: reduce) {
  .ring-fg, .bar i { transition: none !important; }
}

/* Cuánto comiste, en el resumen del análisis. */
.porciones { display: flex; gap: 6px; justify-content: center; margin: 10px 0 4px; flex-wrap: wrap; }
.porciones button {
  min-width: 40px; padding: 7px 9px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card2); color: var(--txt);
  font-size: 14px; font-weight: 700;
}
.porciones button.elegida { border-color: var(--acc); background: var(--acc); color: #fff; }

/* El aviso de la brecha con la balanza. Sobrio: es información, no un reto. */
.card.brecha { border-left: 3px solid var(--acc); }
.card.brecha.mala { border-left-color: var(--warn); }

/* Lo que solés comer a esta hora. */
.sugeridas { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 4px 0 2px; }
.sugeridas > small { color: var(--dim); font-size: 12px; }

/* La semana de un vistazo. Cuatro números grandes: un gráfico hay que leerlo. */
/* Los cuatro en UNA fila y no en un cuadrado de dos por dos: son cuatro
   numeros de cuatro caracteres, y en 2x2 se comian media pantalla de Progreso
   para decir lo mismo. */
.semana-nums { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin: 4px 0 8px; }
.semana-nums div { background: var(--card2); border-radius: 10px; padding: 8px 3px; text-align: center; min-width: 0; }
.semana-nums strong { display: block; font-size: 15px; letter-spacing: -.3px; }
.semana-nums small { display: block; color: var(--dim); font-size: 9.5px; line-height: 1.2; }

/* El deshacer del día. Discreto: aparece solo cuando hay algo que deshacer. */
.deshacer { display: block; width: 100%; margin-top: 8px; font-size: 13px; }

/* El aviso de "estás sin cuenta". Al pie, sobre la barra de pestañas, y por
   encima del contenido: es lo único que puede costar meses de datos. */
.barra-cuenta {
  /* Por encima del botón de Foto, que se apoya sobre la barra de pestañas: los
     dos son fijos y antes se pisaban. */
  position: fixed; left: 8px; right: 8px; z-index: 40;
  bottom: calc(var(--tabbar-h, 62px) + 74px);
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 12px;
  background: var(--card2); border: 1px solid var(--line);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
}
.barra-cuenta p { margin: 0; font-size: 12.5px; flex: 1; }
.barra-cuenta-acciones { display: flex; gap: 6px; align-items: center; flex: none; }
.barra-cuenta button { padding: 7px 12px; font-size: 12.5px; border-radius: 9px; }

/* Entrar con Google. Blanco con borde en los dos temas, que es como se ve en
   todos lados: un botón de Google teñido con la paleta de la app no se
   reconoce, y lo único que este botón tiene que hacer es reconocerse. */
.btn-google {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 11px 14px; margin-bottom: 4px;
  background: #fff; color: #1f1f1f;
  border: 1px solid #dadce0; border-radius: 10px;
  font-size: 14px; font-weight: 600;
}
.btn-google:hover { background: #f7f8f8; }
.btn-google svg { flex: none; }

/* "o con mail y contraseña", con una línea a cada lado. */
.separador-o {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 10px; font-size: 12px;
}
.separador-o::before, .separador-o::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}

/* El punto de "quién está entrado" se fue del encabezado: con una sola persona
   usando la app no decía nada que no estuviera en Ajustes, y se comía el lugar
   que ahora usa el ayuno. */
.titulo { min-width: 0; flex: 1 1 auto; display: flex; align-items: center; gap: 3px; }

/*
 * Tres estados y no cuatro: dorado es el optimo, verde es hecho, rojo es que
 * ese dato estuvo mal.
 *
 * El ambar del "flojo" se fue cuando llego el dorado. Seis horas de sueno
 * cargadas se veian ambar con un tilde adentro, al lado de un casillero dorado
 * con una estrella: dos amarillos distintos que querian decir cosas opuestas
 * —"esto estuvo justito" y "esto estuvo perfecto"— y a un metro de distancia no
 * se distinguen. Lo que estuvo mal de verdad sigue en rojo, que es la unica
 * senal que vale la pena interrumpir.
 */

.objetivo.nivel-mal {
  border-style: solid; border-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 12%, transparent); color: var(--txt);
}
.objetivo.nivel-mal b { color: var(--bad); }

/* ---------------- el optimo ---------------- */

/*
 * El dorado del dia completo.
 *
 * `--oro` es el mismo tono en los dos temas a proposito: el dorado es un
 * premio y tiene que leerse igual de noche que de dia. Lo unico que cambia es
 * cuanto se lo diluye contra el fondo.
 */
:root { --oro: #d4a017; --oro-txt: #fcd34d; }
@media (prefers-color-scheme: light) { :root { --oro-txt: #a37200; } }

/* Un casillero que llego a su optimo: dorado aunque el resto del dia no este.
   El nivel pierde contra esto, porque un optimo nunca es un dato flojo.

   El oro de verdad no es un color plano: tiene una parte clara arriba y una
   oscura abajo, que es lo que lo hace ver metal y no cartulina amarilla. Eso
   es el degradado; el resplandor lo pone el destello que barre, mas abajo. */
.objetivo.optimo {
  position: relative; overflow: hidden;
  border-style: solid; border-color: var(--oro);
  background:
    linear-gradient(160deg,
      color-mix(in srgb, var(--oro) 26%, transparent) 0%,
      color-mix(in srgb, var(--oro) 10%, transparent) 45%,
      color-mix(in srgb, var(--oro) 22%, transparent) 100%);
  color: var(--txt);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 45%, transparent),
    0 1px 10px color-mix(in srgb, var(--oro) 30%, transparent);
}

/*
 * El destello que lo hace resplandecer. SOLO con el dia completo.
 *
 * Un casillero suelto en su optimo ya se ve dorado y con su estrella; el
 * resplandor es del dia entero, y repartirlo entre casilleros sueltos le sacaba
 * lo que tiene de premio. Por eso el selector cuelga de `.dia-completo`.
 *
 * Una banda de luz difusa que cruza en diagonal cada tanto, no todo el tiempo:
 * un brillo continuo en una pantalla que se mira quince veces por dia cansa a
 * la tercera. Va escalonada por casillero, asi que la luz recorre la fila de
 * izquierda a derecha en vez de prenderse en los cuatro a la vez.
 */
.objetivos.dia-completo .objetivo.optimo::after {
  content: ''; position: absolute; inset: -40% -75%;
  /* Paradas separadas y un blur encima: lo que se busca es una zona de luz que
     pasa, no un reflejo con filo. Con la banda angosta parecia un escaner. */
  background: linear-gradient(102deg,
    transparent 30%,
    color-mix(in srgb, #fff 14%, transparent) 40%,
    color-mix(in srgb, #fff 46%, transparent) 50%,
    color-mix(in srgb, #fff 14%, transparent) 60%,
    transparent 70%);
  filter: blur(7px);
  transform: translateX(-120%);
  animation: brillo-oro 9s ease-in-out infinite;
  pointer-events: none;
}
.objetivos.dia-completo .objetivo.optimo:nth-child(2)::after { animation-delay: .5s; }
.objetivos.dia-completo .objetivo.optimo:nth-child(3)::after { animation-delay: 1s; }
.objetivos.dia-completo .objetivo.optimo:nth-child(4)::after { animation-delay: 1.5s; }

@keyframes brillo-oro {
  /* Casi tres segundos de barrido sobre nueve de ciclo: la luz se toma su
     tiempo en cruzar y despues no vuelve por un rato largo. */
  0%, 68% { transform: translateX(-120%); }
  100% { transform: translateX(120%); }
}

/* La estrella, con su propia luz. */
.objetivo.optimo > span[aria-hidden] {
  position: relative; z-index: 1;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--oro) 75%, transparent));
}

@media (prefers-reduced-motion: reduce) {
  .objetivos.dia-completo .objetivo.optimo::after { animation: none; opacity: 0; }
}
.objetivo.optimo b { color: var(--oro-txt); }
.objetivo.optimo small { color: var(--oro-txt); opacity: .85; }

/* Y el dia entero, marco incluido: la fila deja de ser cuatro casilleros
   sueltos y pasa a ser una sola cosa terminada. */
/* El marco sobresale a los lados, donde hay aire, pero NO hacia arriba: el
   -8px de arriba se comia la linea de texto que viene justo antes —el aviso de
   la foto esperando senal— y quedaba escrita encima del borde dorado. */
/* El halo del marco respira, muy despacio: es lo que separa un borde dorado de
   algo que parece tener luz propia. Seis segundos y poca amplitud, para que se
   note de reojo y no pida atencion. */
@keyframes respiro-oro {
  0%, 100% { box-shadow:
    0 0 0 1px color-mix(in srgb, var(--oro) 55%, transparent),
    0 0 14px color-mix(in srgb, var(--oro) 22%, transparent); }
  50% { box-shadow:
    0 0 0 1px color-mix(in srgb, var(--oro) 70%, transparent),
    0 0 26px color-mix(in srgb, var(--oro) 42%, transparent); }
}

.objetivos.dia-completo {
  padding: 8px; margin: 0 -8px 4px; border-radius: 18px;
  animation: respiro-oro 6s ease-in-out infinite;
  /* El marco del dia completo tambien es metal: claro arriba, oscuro abajo, y
     un halo alrededor que lo despega de la pantalla. */
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--oro) 16%, transparent) 0%,
    color-mix(in srgb, var(--oro) 6%, transparent) 55%,
    color-mix(in srgb, var(--oro) 14%, transparent) 100%);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--oro) 55%, transparent),
    0 0 18px color-mix(in srgb, var(--oro) 28%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .objetivos.dia-completo { animation: none; }
}
.objetivos.dia-completo .objetivo {
  border-style: solid; border-color: color-mix(in srgb, var(--oro) 60%, transparent);
}
.objetivos.dia-completo .objetivo b { color: var(--oro-txt); }

/* El dia completo tambien se ve abajo, en las comidas: el marco dorado, no el
   color de cada tarjeta. Lo que una comida tiene para decir por si misma —que
   no entra en el modo, que quedo justa— sigue mandando sobre su propio borde,
   asi que el rojo de un plato que rompe la dieta no se pierde adentro del
   festejo. */
#cardComidas.dia-completo {
  border-color: color-mix(in srgb, var(--oro) 45%, transparent);
  background: color-mix(in srgb, var(--oro) 7%, var(--card));
}
#cardComidas.dia-completo .momento:not(.n-no):not(.n-justo) {
  border-color: color-mix(in srgb, var(--oro) 55%, transparent);
}

/* El aviso de la cola es un boton, pero tiene que seguir leyendose como un
   renglon de ayuda y no como algo que grita. */
.aviso-cola {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  cursor: pointer; background: none; border: 0; padding: 0; font: inherit; color: var(--dim);
}
.cola-thumb {
  flex: 0 0 auto; width: 34px; height: 34px; object-fit: cover;
  border-radius: 7px; border: 1px solid var(--line);
}
.aviso-cola:hover { color: var(--txt); }

.total-macros { margin: 2px 0 8px; font-size: 12px; color: var(--dim); text-align: right; }

.filtro-oro {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  margin: 0 0 8px; font-size: 12.5px; color: var(--dim);
}

/* Los dias completos acumulados, en Progreso: el mismo oro, en tres numeros. */
.oro-resumen {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  margin: 4px 0 12px; padding: 10px 8px; border-radius: 12px;
  background: color-mix(in srgb, var(--oro) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--oro) 40%, transparent);
  text-align: center;
}
.oro-resumen b { display: block; font-size: 21px; color: var(--oro-txt); line-height: 1.15; }
.oro-resumen small { font-size: 10.5px; color: var(--dim); }

/* El dia completo, en la lista del historial: el mismo oro, sin el resplandor.
   Una lista de treinta renglones con treinta destellos seria una fiesta que no
   deja leer nada. */
.lista li.dia-dorado {
  background: color-mix(in srgb, var(--oro) 8%, transparent);
  box-shadow: inset 3px 0 0 var(--oro);
}
.lista li.dia-dorado .info b { color: var(--oro-txt); }

/* El renglon que dice como se gana la estrella, arriba del editor. */
.optimo-obj {
  margin: 0 0 12px; padding: 8px 11px; border-radius: 10px;
  background: var(--card2); border: 1px solid var(--line);
  font-size: 12.5px; line-height: 1.35; color: var(--dim);
}
.optimo-obj.cumplido {
  color: var(--oro-txt);
  border-color: color-mix(in srgb, var(--oro) 55%, transparent);
  background: color-mix(in srgb, var(--oro) 12%, transparent);
}

/* "No entra" tiene que leerse de lejos: es lo único de la pantalla que pide
   una decisión antes de comer. */
.marca-apta.grande.no { font-size: 15px; padding: 6px 14px; letter-spacing: -.2px; }

/* Y debajo, qué hacer al respecto. Un cartel que dice que está mal y no dice
   qué hacer deja a la persona en el peor lugar posible. */
.consejo-apta {
  margin: 6px 0 0; font-size: 13px; font-weight: 600; line-height: 1.35;
  color: var(--acc);
}
.consejo-apta.sin-vuelta { color: var(--err); font-weight: 650; }

/* La pregunta que la foto no puede contestar: de qué son las empanadas.
   Aparece después de guardar, así que no frena nada; es una corrección que se
   ofrece, no un formulario que se exige. */
.duda { margin-top: 10px; text-align: left; }
.duda p { margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--txt); }
.duda-opciones { display: flex; flex-wrap: wrap; gap: 6px; }
.duda-opcion {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 7px 11px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card2); color: var(--txt);
  font-size: 12.5px; font-weight: 600;
}
.duda-opcion small { font-size: 10px; color: var(--dim); font-weight: 500; }
.duda-opcion.elegida { border-color: var(--acc); color: var(--acc); }
.duda-opcion.elegida small { color: var(--acc); }

/* Lo que queda del día, dentro del anillo. Vivía en una fila de tres números
   que repetía el objetivo y el consumido, los dos ya presentes en el anillo. */
/* Con su propia chapita: los tres renglones tenían el mismo peso visual y el
   que decide qué comer —lo que queda, o lo que te pasaste— se perdía entre los
   otros dos. */
.ring-resta {
  display: block; margin-top: 4px; font-size: 11.5px; font-weight: 700; text-align: center;
  padding: 2px 7px; border-radius: 8px; line-height: 1.35;
  color: var(--acc); background: color-mix(in srgb, var(--acc) 14%, transparent);
}
.ring-resta.pasado { color: var(--bad); background: color-mix(in srgb, var(--bad) 18%, transparent); }
.ring-resta:empty { display: none; }

/* Fibra, azúcar y sodio a lo ancho de la pantalla, en tres columnas parejas.
   Adentro de la tarjeta de macros tenían 200 px y se envolvían en dos filas. */
.nutrientes {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
  margin: 0 0 12px; padding: 10px 12px;
  background: var(--card); border-radius: 14px;
}
.nutrientes div { min-width: 0; text-align: center; }
.nutrientes span { display: block; font-size: 11px; color: var(--dim); }
.nutrientes b { font-size: 15px; font-weight: 600; }
.nutrientes b.pasado { color: var(--warn); }

/* La línea que separa la foto de lo que casi no se usa. */
.separa-origen { border: 0; border-top: 1px solid var(--line); margin: 4px 0 2px; }

/* Con el botón a lo ancho, el ícono y la palabra van uno al lado del otro:
   apilados dejaban un botón muy alto y medio vacío. Va al final del archivo
   porque la regla de arriba lo define como columna y gana la última. */
.acciones-fila .accion { flex-direction: row; gap: 8px; padding: 14px 4px; }

/* El ícono y la palabra, centrados dentro del botón.
   Con `flex-direction: row` el reparto por defecto es desde la izquierda, así
   que en un botón que ocupa toda la pantalla el contenido quedaba pegado a un
   costado. */
.acciones-fila .accion { justify-content: center; }

/* Y la flechita deja de robarle ancho al texto: se apoya sobre el borde
   derecho en vez de ocupar su propia columna. */
.accion-doble .accion { padding-right: 4px; }

/* ---------- las comidas como recuerdos ---------- */

/*
 * Una tira horizontal por momento, con la foto como tarjeta.
 *
 * En filas de texto, cinco comidas se llevaban la pantalla entera y la foto
 * quedaba en una miniatura de 40 px que no se miraba nunca. Acá la foto ES la
 * tarjeta: el día se lee de un vistazo en vez de leerse.
 */
/* La fila que contiene la tira ocupa el ancho entero. */
.lista li.tira-fila { display: block; width: 100%; padding: 0; border-top: 0; }

.recuerdos {
  /* Grid y no flex, con las mismas columnas que la fila de momentos: así una
     tarjeta mide exactamente lo que mide un momento. Con flex el porcentaje se
     resolvía contra un contenedor sin ancho propio y daban 2 px. */
  width: 100%;
  display: grid; grid-auto-flow: column;
  grid-auto-columns: calc((100% - 4 * 6px) / 5);
  gap: 6px; overflow-x: auto; padding: 2px 0 4px;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
  /* la barra molesta más de lo que ayuda en una tira de tres tarjetas */
  scrollbar-width: none;
}
.recuerdos::-webkit-scrollbar { display: none; }

.recuerdo {
  /* El mismo lado que un momento de la fila de arriba: son la misma cosa vista
     con más detalle, y con dos tamaños distintos parecían dos secciones. La
     cuenta es la de la grilla de momentos —cinco columnas y cuatro gaps— para
     que sigan midiendo igual si el ancho de la pantalla cambia. */
  position: relative; aspect-ratio: 1; height: auto; width: auto;
  border-radius: 16px; overflow: hidden; scroll-snap-align: start;
  background: var(--card2); border: 1px solid var(--line);
}
.recuerdo.no { border-color: var(--bad); }
.recuerdo.justo { border-color: var(--warn); }

.recuerdo-foto, .recuerdo-foto img { position: absolute; inset: 0; width: 100%; height: 100%; }
.recuerdo-foto img { object-fit: cover; }
.recuerdo-foto.sin-foto {
  display: flex; align-items: center; justify-content: center;
  font-size: 40px; opacity: .35;
}

/* Un degradado desde abajo: sin esto, el texto blanco sobre una foto clara
   —un plato de arroz, una ensalada con luz— no se lee. */
.recuerdo::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, .78) 0%, rgba(0, 0, 0, .35) 42%, transparent 70%);
}

.recuerdo-kcal {
  position: absolute; top: 4px; left: 5px; z-index: 2;
  font-size: 14px; font-weight: 700; color: #fff; line-height: 1;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .6);
}
.recuerdo-kcal small { font-size: 7px; font-weight: 600; margin-left: 2px; opacity: .85; }

.recuerdo-pie { position: absolute; left: 4px; right: 4px; bottom: 4px; z-index: 2; color: #fff; }
.recuerdo-pie b {
  display: block; font-size: 8.5px; line-height: 1.15; font-weight: 650;
  /* dos renglones y corta: un título largo taparía media tarjeta */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* A este tamaño la hora y los macros no entran: viven en el title. */
.recuerdo-pie small { display: none; }

/* Sobre una foto, el fondo translúcido de la marca no se lee: acá va sólida.
   Es el único aviso de la tarjeta y compite con lo que haya en la imagen. */
.recuerdo .marca-apta {
  position: absolute; top: 3px; right: 3px; z-index: 3;
  font-size: 7px; padding: 0 3px; letter-spacing: 0;
}
.recuerdo .marca-apta.no { background: var(--bad); color: #1a0000; }
.recuerdo .marca-apta.justo { background: var(--warn); color: #241a00; }

/* La tarjeta entera edita. Es un botón transparente por encima de todo menos
   de la ✕ y la lupa, así que el área de toque es la tarjeta completa. */
.recuerdo-abrir { position: absolute; inset: 0; z-index: 2; background: none; border: 0; cursor: pointer; }
.recuerdo-del, .recuerdo-lupa {
  position: absolute; z-index: 4; width: 18px; height: 18px; border-radius: 50%;
  border: 0; cursor: pointer; display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .5); color: #fff; font-size: 13px; line-height: 1;
}
.recuerdo-del { bottom: 3px; right: 3px; font-size: 12px; }
.recuerdo-lupa { bottom: 3px; right: 24px; font-size: 8px; }
.recuerdo:hover .recuerdo-del, .recuerdo:hover .recuerdo-lupa { background: rgba(0, 0, 0, .72); }

/* ---------- los cinco momentos del día ---------- */

/*
 * Cinco tarjetas fijas, una por momento. La sección mide lo mismo con tres
 * comidas que con doce, y se ve de un vistazo lo que falta.
 */
/* `.lista li` le gana en especificidad a `.momentos` a secas, así que el grid
   no se aplicaba y los cinco quedaban como flex items dimensionados por su
   texto: "Desayuno" salía más ancho que "Cena". */
.lista li.momentos {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px;
  padding: 2px 0 4px; list-style: none; border-top: 0;
  /* `start` y no `stretch`: estirado, la altura la manda la fila y el
     `aspect-ratio` recalcula el ancho, con lo que las tarjetas dejaban de
     medir lo que dice su columna y quedaban desparejas. */
  align-items: start;
}
.momento {
  position: relative; aspect-ratio: 1; border-radius: 12px; overflow: hidden;
  border: 1.5px solid var(--line); background: var(--card2); color: var(--txt);
  cursor: pointer; padding: 0;
  /* El pie pegado abajo en las cinco, tengan foto o no: es lo que hace que los
     nombres queden en una sola línea y no en cinco alturas distintas. */
  display: flex; flex-direction: column; justify-content: flex-end;
}
.momento img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* El emoji, centrado en el hueco de arriba y fuera del pie, para no empujarlo. */
/* El emoji arranca debajo de la hora: pegados se leian como una sola cosa. */
.momento-emoji {
  position: absolute; left: 0; right: 0; top: 14px; bottom: 20px;
  display: flex; align-items: center; justify-content: center;
  font-style: normal; font-size: 19px; opacity: .5;
}

/* El degradado solo cuando hay foto: sobre la tarjeta vacía oscurecería de
   gratis un casillero que ya es tenue. */
.momento:has(img)::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, .82) 0%, rgba(0, 0, 0, .25) 55%, transparent 80%);
}
.momento:has(img) .momento-pie { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .75); }

.momento-pie {
  position: relative; z-index: 2; width: 100%; padding: 3px 3px 5px;
  display: flex; flex-direction: column; align-items: center; gap: 0; line-height: 1.15;
}
.momento-pie b { font-size: 14px; font-weight: 700; }
.momento-pie small {
  font-size: 8.5px; font-weight: 600; opacity: .9; letter-spacing: .1px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* El porque del borde rojo, en texto. Sin esto el color avisa pero no explica,
   y el motivo solo existia en un tooltip que en el celular no se puede abrir. */
/* Con la lista adelante: `.lista li` ya declara flex y le ganaba en
   especificidad, asi que el nombre del momento se iba a una columna y el
   motivo a otra. */
.lista .motivo-momento, .motivo-momento {
  display: block; list-style: none; margin: 6px 0 0; padding: 0;
  font-size: 11.5px; line-height: 1.35; color: var(--bad);
  /* Un renglon, con puntos suspensivos. Se abre al tocarla. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: pointer;
}
.motivo-momento.abierto { white-space: normal; overflow: visible; }
.motivo-momento b { font-weight: 700; }

/*
 * El borde dice si lo del momento entra en el modo: verde entra, ámbar entra
 * justo, rojo no entra. Es el mismo semáforo que ya usan los casilleros del
 * día y las comidas, así que no hay una convención nueva que aprender.
 */
.momento.n-si { border-color: var(--acc); }
.momento.n-justo { border-color: var(--warn); }
.momento.n-no { border-color: var(--bad); }
.momento.n-justo .momento-pie b { color: var(--warn); }
.momento.n-no .momento-pie b { color: var(--bad); }
/* Con foto, el número va en blanco: sobre la imagen el color se pierde y el
   borde ya lo dice. */
.momento:has(img) .momento-pie b { color: #fff; }

/* El vacío se ve como un lugar donde falta algo, no como un error.

   `sin-cargar` y no `vacio`: ya existe una clase `.vacio` genérica para los
   mensajes de "todavía no hay nada", con su propio `margin: 14px 0 6px`. Las
   tarjetas la heredaban por compartir el nombre y quedaban 14 px más abajo que
   las llenas, con los cinco nombres a dos alturas distintas. */
/*
 * Los cinco pesan lo mismo, aunque solo cuatro tengan foto.
 *
 * Miden exactamente igual —61 px de lado— pero el vacío se veía más chico:
 * sin fondo ni imagen, un cuadrado con borde punteado ocupa el mismo lugar y
 * no lo parece. Conserva el punteado, que es lo que dice "acá falta algo",
 * pero con el mismo fondo que los demás y el emoji más grande para llenarlo.
 */
.momento.sin-cargar {
  border-style: dashed; border-color: var(--line);
  background: var(--card2); color: var(--txt2);
}
.momento.sin-cargar .momento-emoji { font-size: 24px; opacity: .42; }
.momento.abierto { box-shadow: inset 0 0 0 2px var(--acc); }

/* Cuántas hay, solo si es más de una: un "1" en cada tarjeta es ruido. */
.momento-n {
  position: absolute; top: 4px; right: 4px; z-index: 3;
  min-width: 15px; height: 15px; border-radius: 8px; padding: 0 3px;
  background: var(--acc); color: var(--sobre-acc);
  font-size: 9.5px; font-weight: 700; line-height: 15px; text-align: center;
}

/* El día que se está mirando, cuando no es hoy.
   Reemplaza a un cartel de dos renglones con un botón que decía lo mismo que
   esta palabra: si arriba dice "Ayer", estás en ayer. */
.date-nav #dateLabel.otro-dia {
  color: var(--warn); font-weight: 700; cursor: pointer;
  text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px;
}

/* Un ejercicio con sus minutos al lado. El − y el + son lo que evita ir a
   Ajustes por el número que más cambia de un día a otro. */
/* Cuatro por fila: los ocho deportes entran en dos filas y se ven todos juntos
   sin scrollear. El chip pasa a ser un cuadrado —emoji arriba, nombre, y el
   rato con sus calorias abajo— porque en 76 px no entra un renglon de texto. */
.act-todas {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px;
}
.act-uno {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  line-height: 1.15; padding: 8px 3px; text-align: center; min-width: 0;
}
.act-uno i { font-style: normal; font-size: 17px; }
.act-uno b { font-size: 10.5px; font-weight: 600; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-uno small { font-size: 9.5px; opacity: .75; font-weight: 600; }
.chip-nuevo { border-style: dashed; color: var(--txt2); }

/* La hoja de abajo del menu de un momento. */
.hoja-menu {
  position: fixed; inset: 0; z-index: 85;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(0, 0, 0, .55);
}
.hoja-menu[hidden] { display: none; }
.hoja-caja {
  width: 100%; max-width: 520px; background: var(--card);
  border-radius: 18px 18px 0 0; padding: 16px; display: grid; gap: 8px;
}
.hoja-titulo { margin: 0 0 4px; font-size: 13px; color: var(--dim); text-transform: uppercase; letter-spacing: .5px; }
.hoja-op {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--card2); border: 1px solid var(--line); border-radius: 12px; padding: 12px;
  color: var(--txt);
}
.hoja-op b { display: block; font-size: 14px; }
.hoja-op small { display: block; color: var(--dim); font-size: 12px; margin-top: 2px; }

/* Cada aviso con su interruptor. Apagado se ve, en gris: esconderlo obligaria a
   buscar donde volver a prenderlo. */
.fila-aviso { display: flex; flex-direction: row; align-items: center; gap: 9px; cursor: pointer; min-height: 34px; }
.fila-aviso span { flex: 1 1 auto; min-width: 0; }
.fila-aviso.apagada span { color: var(--dim); }
.fila-aviso.apagada input[type="time"] { opacity: .5; }

/* El nombre de la carita elegida: en el celular no hay hover, asi que cinco
   caras parecidas sin texto son una adivinanza. */
.carita-nombre { margin: 6px 0 0; font-size: 12.5px; font-weight: 600; color: var(--acc); }

/* Con que cuenta estas entrado, arriba de Tus datos. */
.cuenta-linea {
  display: block; width: 100%; text-align: left; margin-bottom: 10px;
  background: var(--card2); border: 1px solid var(--line); border-radius: 11px;
  padding: 9px 12px; font-size: 12.5px; color: var(--txt); cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cuenta-linea.sin-cuenta { color: var(--dim); border-style: dashed; }

/* La hora de cada momento, arriba de la tarjeta. La sugerida va mas apagada:
   es una propuesta, no un dato —y tiene que distinguirse de la hora real. */
.momento-hora {
  position: absolute; top: 5px; left: 0; right: 0;
  font-style: normal; font-size: 10.5px; font-weight: 700;
  color: var(--txt); text-align: center; letter-spacing: -.2px;
}
/* La sugerida se distingue de la real: mas chica, gris y con el ~ adelante.
   Con las dos iguales no habia forma de saber si ese numero era la hora a la
   que comiste o la hora a la que deberias comer. */
.momento-hora.sugerida { font-size: 9.5px; font-weight: 600; color: var(--dim); opacity: .75; }

/* Los cinco pasos, en una fila: envueltos ocupaban dos renglones para cinco
   numeros de cuatro cifras. */
#pasosEscalones { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 5px; }
/* `.chips button` es flex, asi que el numero se centra con justify-content y no
   con text-align: con text-align quedaban los cinco pegados a su izquierda. */
#pasosEscalones .chip { padding: 9px 2px; font-size: 12.5px; justify-content: center; }

/* Agregar un ejercicio no es elegir uno: era el cuarto chip de una fila de
   tres y se leia como uno mas de los de siempre. */
.otro-ejercicio {
  display: flex; align-items: center; gap: 10px; width: 100%; margin-top: 10px;
  background: var(--card2); border: 1px dashed var(--line); border-radius: 12px;
  padding: 10px 12px; cursor: pointer; color: var(--txt); text-align: left;
  transition: border-color .15s, background .15s;
}
.otro-ejercicio:hover { border-color: var(--acc2); background: color-mix(in srgb, var(--acc) 8%, var(--card2)); }
.otro-ejercicio .oe-mas {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  background: color-mix(in srgb, var(--acc) 18%, transparent); color: var(--acc);
  display: grid; place-items: center; font-size: 17px; font-weight: 700; line-height: 1;
}
.otro-ejercicio .oe-txt { min-width: 0; }
.otro-ejercicio b { display: block; font-size: 13.5px; font-weight: 650; }
.otro-ejercicio small { display: block; font-size: 11px; color: var(--dim); margin-top: 1px; }

/* El ticket del ejercicio: que sumaste, cuanto duro, cuanto quemo y el total.
   Con un solo numero no se puede ni revisar ni corregir. */
.carrito { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 6px; }
.carrito-fila {
  display: flex; align-items: center; gap: 8px; padding: 6px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.carrito-fila .cf-que { flex: 1 1 auto; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.carrito-fila .cf-cuanto { flex: 0 0 auto; font-size: 11.5px; color: var(--dim); }
.carrito-fila .cf-kcal { flex: 0 0 auto; font-size: 13px; font-weight: 650; font-variant-numeric: tabular-nums; }
.carrito-fila .cf-x {
  flex: 0 0 auto; background: none; border: 0; color: var(--dim); cursor: pointer;
  font-size: 12px; padding: 2px 2px 2px 4px; line-height: 1;
}
.carrito-fila .cf-x:hover { color: var(--bad); }
.carrito-total {
  display: flex; align-items: baseline; justify-content: space-between;
  padding-top: 9px; font-size: 13px; color: var(--dim);
}
.carrito-total b { font-size: 18px; font-weight: 700; color: var(--acc); font-variant-numeric: tabular-nums; }
/* El total cierra el ticket: lo que sigue necesita aire propio o se lee como
   parte de la misma cuenta. */
.carrito + .sub { margin-top: 18px; }

/* Las seis formas ocasionales de cargar, de a dos. Apiladas eran seis filas
   iguales para cosas que no se usan igual, y el menú no entraba en pantalla. */
.origen-grilla { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.origen-grilla button {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 12px 4px; border-radius: 12px; font-size: 19px; min-width: 0;
}
.origen-grilla span {
  font-size: 10.5px; font-weight: 600; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* La fase y el título, en una línea: el chip primero porque es lo que cambia
   todos los días, y el título al lado. */
.mascota-linea { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-width: 0; }
.mascota-linea .fase-chip { flex: 0 0 auto; }
.mascota-linea b { min-width: 0; }

/* La lectura del macro: cuánto falta o cuánto sobra. Es lo que evita tener que
   hacer la resta de cabeza y acordarse de si en ese macro conviene llegar o no
   pasarse. */
.macro-lee { display: block; margin-top: 3px; font-size: 10.5px; font-weight: 600; color: var(--dim); }
.macro-lee.bien { color: var(--acc); }
.macro-lee.cerca { color: var(--warn); }
.macro-lee.falta { color: var(--txt2); }
.macro-lee.mal { color: var(--bad); }
.macro-lee:empty { display: none; }

/* El marcador de hábitos. Chiquito: acompaña a los casilleros, no compite. */

/* La tira del peso: el objetivo real de la app, en una línea.
   Es un botón porque lleva al historial, que es donde se mira la curva. */
.peso-tira {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 12px; margin-bottom: 8px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--card); color: var(--txt);
  cursor: pointer; text-align: left;
}
.peso-tira-num { flex: 0 0 auto; display: flex; flex-direction: column; line-height: 1.1; }
.peso-tira-num b { font-size: 17px; font-weight: 700; }
.peso-tira-num small { font-size: 9.5px; color: var(--dim); }
.peso-tira-barra { flex: 1 1 auto; height: 6px; border-radius: 4px; background: var(--card2); overflow: hidden; min-width: 0; }
.peso-tira-barra i { display: block; height: 100%; background: var(--acc); border-radius: 4px; transition: width .5s ease; }
.peso-tira-delta { flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--dim); }
.peso-tira-delta.bien { color: var(--acc); }
.peso-tira-delta.mal { color: var(--bad); }

/* Aclararle al análisis qué era el plato. Un renglón: es una corrección
   ocasional, no un campo que haya que ver siempre. */
.aclarar { display: flex; gap: 6px; margin-top: 10px; }
.aclarar input {
  flex: 1; min-width: 0; padding: 8px 10px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card2); color: var(--txt); font-size: 12.5px;
}
.aclarar button { flex: 0 0 auto; }

/* El aviso de que el modo no cuadra hace días. Ámbar y no rojo: no es un
   error, es una observación sobre un patrón. */
.aviso-modo {
  margin-bottom: 10px; padding: 10px 12px; border-radius: 12px;
  border: 1px solid var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent);
  font-size: 12.5px; line-height: 1.35;
}
.aviso-modo .actions-row { margin-top: 8px; }

/* Los primeros pasos: lo que falta para que la app pueda decir algo.
   Se va sola cuando ya no falta nada, así que no necesita un botón de cerrar. */
.primeros .paso {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-top: 1px solid var(--line);
}
.primeros .paso:first-child { border-top: 0; }
.primeros .paso > div { flex: 1; min-width: 0; }
.primeros .paso b { display: block; font-size: 13px; font-weight: 600; }
.primeros .paso small { display: block; font-size: 11.5px; color: var(--dim); margin-top: 1px; }
.primeros .paso button { flex: 0 0 auto; }
.primeros .paso.hecho b { color: var(--acc); font-weight: 550; }

/*
 * Pantallas bajas.
 *
 * "Que entre todo en una pantalla" no es una medida fija: 812 px de alto y 640
 * no son la misma pantalla, y todo el compactado de arriba miraba solo el
 * ancho. Estos dos tramos aprietan de a poco según el alto que haya, en vez de
 * elegir un número y que ande en un teléfono y en otro no.
 */
@media (max-width: 480px) and (max-height: 800px) {
  #tab-hoy .card { margin-bottom: 6px; }
  .resumen .macros { padding: 8px 10px; gap: 5px; }
  .resumen .ring-card { padding: 6px; }
  .macro-lee { font-size: 10.5px; }
  #tab-hoy .objetivos { gap: 3px; }
  #tab-hoy .objetivo { padding: 6px 2px; }
  .mascota-dibujo > * { zoom: .84; }
  #tab-hoy .momento { aspect-ratio: 1.12; }
}

@media (max-width: 480px) and (max-height: 700px) {
  /* Acá ya no alcanza con apretar: el muñeco se achica y la lectura de cada
     macro se va. El número y la barra siguen estando, que es lo que se mira. */
  #tab-hoy .card { margin-bottom: 5px; padding: 8px 10px; }
  .macro-lee { display: none; }
  .resumen .ring-wrap { max-width: 100px; }
  /* El muñeco es un sprite en un div, así que no alcanza con topearle el alto:
     `zoom` lo achica de verdad y arrastra la caja, que es lo que ocupa. */
  .mascota-dibujo > * { zoom: .64; }
  /* Los momentos, un poco más chatos: el nombre y el número siguen entrando. */
  #tab-hoy .momento { aspect-ratio: 1.4; }
  #tab-hoy .acciones-fila .accion { padding: 8px 4px; }
  #tab-hoy.active { padding-bottom: 50px; }
  .mascota { padding: 6px 10px; }
  .peso-tira { padding: 7px 10px; }
  #tab-hoy .card-head { padding: 0 0 3px; }
  .momento-pie b { font-size: 12.5px; }
  .tira, .tiras-hoy .tira { padding: 5px 9px; }
  .momento-emoji { font-size: 16px; }
  #tab-hoy .objetivo { padding: 5px 2px; }
}

/* El plazo: cuándo llegás, y si vas a tiempo. */
.plazo-hint { margin: -4px 0 8px; color: var(--txt2); }
.plazo-aviso { margin: -4px 0 8px; }
.plazo-aviso.no-entra { color: var(--warn); }
.plazo-veredicto { margin: 8px 0 0; padding-top: 8px; border-top: 1px solid var(--line); font-size: 12.5px; }
.plazo-veredicto.tarde, .plazo-veredicto.sin-datos { color: var(--bad); }
.plazo-veredicto.adelantado, .plazo-veredicto.en-fecha { color: var(--acc); }

/* Compartir la sugerencia con quien cocina. */
.sugerencia { position: relative; }
.sugerencia-enviar {
  margin-top: 8px; padding: 5px 12px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--card2); color: var(--txt);
  font-size: 12px; font-weight: 650;
}
.sugerencia-enviar:active { transform: scale(.97); }

/* Los tres nutrientes, en un renglón.
   En tres columnas con el número grande arriba se llevaban 50 px de la pantalla
   que tiene que entrar entera, para tres datos que se miran de reojo. */
@media (max-width: 480px) {
  #tab-hoy > .ring-stats, #listaNutrientes {
    display: flex; flex-wrap: wrap; justify-content: space-between;
    gap: 2px 10px; padding: 6px 10px;
  }
  #tab-hoy > .ring-stats > div, #listaNutrientes > div,
  #listaNutrientes > li { flex-direction: row; align-items: baseline; gap: 4px; }
  #tab-hoy > .ring-stats span, #listaNutrientes span { font-size: 12.5px; }
  #tab-hoy > .ring-stats small, #listaNutrientes small { font-size: 10.5px; }
}

/* Para qué comida se piden las sugerencias.
   Los cinco en una fila: en dos se leen como dos grupos de cosas distintas. */
.momento-sug { margin-bottom: 10px; gap: 4px; flex-wrap: nowrap; }
.momento-sug .chip { font-size: 11.5px; padding: 5px 7px; white-space: nowrap; }

/* El cálculo del rato de movimiento, antes de sumarlo. */

/* ---------- el muñeco respira ----------
   La respiración mueve torso, brazos y cabeza —las piernas quedan plantadas—
   y su ritmo lo pone el día vía --resp: descansado 3 s, hecho polvo 5 s.
   El parpadeo es una elipse color piel que vive en escala 0 y aparece un
   instante: es lo que hace que el muñeco esté vivo aunque no pase nada. */
.mascota-svg .anim-respira { animation: mascota-respira var(--resp, 3.4s) ease-in-out infinite; }
@keyframes mascota-respira { 50% { transform: translateY(-1.2px); } }

.mascota-svg .anim-parpado {
  transform-box: fill-box; transform-origin: center;
  transform: scaleY(0);
  animation: mascota-parpadea 4.7s linear infinite;
}
@keyframes mascota-parpadea {
  0%, 91%, 97%, 100% { transform: scaleY(0); }
  93%, 95% { transform: scaleY(1); }
}

/* El cabeceo del que se está quedando dormido: asiente despacio y se endereza. */
.mascota-svg .anim-cabecea {
  transform-box: fill-box; transform-origin: 50% 88%;
  animation: mascota-cabecea 5.2s ease-in-out infinite;
}
@keyframes mascota-cabecea {
  0%, 100% { transform: rotate(0deg); }
  35% { transform: rotate(3deg); }
  55% { transform: rotate(-1.2deg); }
}

.mascota-svg .anim-zzz { animation: mascota-flota 2.6s ease-in-out infinite; }
@keyframes mascota-flota { 50% { transform: translateY(-3px); opacity: .35; } }

@media (prefers-reduced-motion: reduce) {
  .mascota-svg .anim-respira, .mascota-svg .anim-parpado,
  .mascota-svg .anim-cabecea, .mascota-svg .anim-zzz { animation: none; }
}

/* El aviso de que el ejercicio se cuenta dos veces. No es un error —los dos
   numeros son validos por separado— asi que va en ambar y no en rojo. */
.aviso-doble {
  margin: 10px 0 0; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent);
  font-size: 13px; line-height: 1.45;
}

/* Lo que la comida significa para el dia. Neutro y sin color de alarma: no es
   un reto, es la informacion que faltaba para leer el aviso de arriba. */
.efecto-modo {
  margin: 8px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--dim);
  text-align: center;
}
