/*
 * El panel. Un fichero, sin preprocesador y sin framework.
 *
 * Los colores viven todos aqui arriba como variables y el resto de la hoja los usa
 * por su papel (--surface, --series-1) y nunca por su valor. Asi el modo oscuro es
 * un bloque de variables y no una segunda hoja de estilos que se desincroniza.
 *
 * La paleta categorica esta validada para daltonismo: el orden de --series-1 a
 * --series-8 es el mecanismo de seguridad, no una eleccion estetica. Reordenarla o
 * cambiar un tono exige volver a pasar el validador (ver docs/panel.md).
 */

/* La fuente de los titulares, servida desde aqui y no desde Google Fonts: la
   politica de privacidad promete que no hay rastreadores, y una fuente de un CDN
   ajeno le dice a ese tercero la IP de cada visita. Recortada al alfabeto latino
   (149 KiB, variable en peso y anchura). Licencia OFL en /fonts/OFL.txt. */
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/fonts/bricolage-grotesque.woff2") format("woff2");
  font-weight: 200 800;
  font-stretch: 75% 100%;
  font-display: swap;
}

:root {
  color-scheme: light;

  /* La marca. Aparte de la paleta de las graficas y sin tocarla: aquellos ocho
     colores estan validados para daltonismo y su orden no se mueve. Estos visten
     la interfaz — cabecera, menu, botones — y no codifican ningun dato. */
  --brand-ink: #0e3b2c;
  --brand-ink-2: #155240;
  --brand-ink-soft: #4d6158;
  --brand-ink-text: #14231d;
  --brand-lime: #c8f169;
  --brand-cream: #f6f1e7;
  --brand-paper: #fffdf8;
  --font-display: "Bricolage Grotesque", var(--font);

  /* Crema y no gris: el papel de un ticket. Las graficas viven sobre --surface, que
     no cambia, asi que la paleta validada sigue viendose contra el mismo fondo. */
  --page: #f4efe4;
  --surface: #fcfcfb;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --text-muted: #898781;
  --grid: #e1e0d9;
  --axis: #c3c2b7;
  --border: rgba(11, 11, 11, 0.1);
  --wash: rgba(11, 11, 11, 0.04);

  /* Categoricos. Orden validado: no reordenar sin volver a validar. */
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-8: #e34948;
  /* Escalon claro del mismo azul, para lo que esta ahi pero no es lo elegido. */
  --series-1-soft: #86b6ef;

  --good: #0ca30c;
  --good-text: #006300;
  --warning: #fab219;
  --serious: #ec835a;
  --critical: #d03b3b;

  --radius: 10px;
  --font: system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Para lo que se copia y no se lee: una direccion, un codigo. En monoespaciada
     porque ahi la l y el 1 tienen que distinguirse. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;

    --page: #0d0d0d;
    --surface: #1a1a19;
    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --text-muted: #898781;
    --grid: #2c2c2a;
    --axis: #383835;
    --border: rgba(255, 255, 255, 0.1);
    --wash: rgba(255, 255, 255, 0.06);

    /* Los mismos ocho tonos, escalonados para el fondo oscuro. No es un volteo
       automatico del modo claro: cada valor esta elegido y validado contra este
       fondo. */
    --series-1: #3987e5;
    --series-2: #d95926;
    --series-3: #199e70;
    --series-4: #c98500;
    --series-5: #d55181;
    --series-6: #008300;
    --series-7: #9085e9;
    --series-8: #e66767;
    --series-1-soft: #1c5cab;

    --good-text: #0ca30c;
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font);
  background: var(--page);
  color: var(--text-primary);
  font-size: 15px;
  line-height: 1.5;
}

h1, h2, h3 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.01em;
}

h2 {
  font-size: 1rem;
}

button {
  font: inherit;
  cursor: pointer;
}

/* --- Estructura ----------------------------------------------------------- */

.page {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 20px 64px;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 20px 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 24px;
}

.brand {
  font-size: 1rem;
  font-weight: 600;
}

.brand small {
  display: block;
  font-weight: 400;
  font-size: 0.8rem;
  color: var(--text-secondary);
}

.topbar .spacer {
  flex: 1;
}

.month-picker {
  display: flex;
  align-items: center;
  gap: 4px;
}

.month-picker output {
  min-width: 11ch;
  text-align: center;
  font-weight: 600;
  font-size: 0.9rem;
}

.ghost {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-secondary);
  padding: 6px 12px;
  font-size: 0.85rem;
}

.ghost:hover:not(:disabled) {
  background: var(--wash);
  color: var(--text-primary);
}

.ghost:disabled {
  opacity: 0.4;
  cursor: default;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 20px;
}

.card > header {
  margin-bottom: 16px;
}

.caption {
  margin: 4px 0 0;
  font-size: 0.82rem;
  color: var(--text-secondary);
}

.two-up {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

@media (max-width: 780px) {
  .two-up {
    grid-template-columns: 1fr;
  }
}

/* --- Cifras de cabecera --------------------------------------------------- */

.hero {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}

.hero .figure {
  /* Cifras proporcionales, no tabulares: a este tamano las tabulares se ven sueltas. */
  font-size: 3rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.delta {
  font-size: 0.9rem;
  font-weight: 600;
}

/* Gastar menos es bueno, asi que la flecha hacia abajo es la verde. La direccion
   sola no basta: el signo y la palabra van siempre al lado. */
.delta.down { color: var(--good-text); }
.delta.up { color: var(--critical); }
.delta.flat { color: var(--text-secondary); }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-top: 20px;
}

.tile {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
}

.tile .label {
  font-size: 0.78rem;
  color: var(--text-secondary);
}

.tile .value {
  font-size: 1.35rem;
  font-weight: 600;
  margin-top: 2px;
}

.tile.attention {
  border-color: var(--warning);
}

.note {
  margin: 16px 0 0;
  font-size: 0.82rem;
  color: var(--text-secondary);
  padding-left: 12px;
  border-left: 2px solid var(--axis);
}

/* --- Graficas ------------------------------------------------------------- */

.chart {
  display: block;
  overflow: visible;
}

.chart .tick,
.chart .row-label {
  font-variant-numeric: tabular-nums;
}

.tooltip {
  position: fixed;
  z-index: 50;
  pointer-events: none;
  background: var(--text-primary);
  color: var(--page);
  padding: 7px 10px;
  border-radius: 7px;
  font-size: 0.8rem;
  line-height: 1.35;
  max-width: 240px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

.tooltip[hidden] {
  display: none;
}

/* La leyenda con importes es tambien la vista en tabla: tres de los tonos
   categoricos quedan por debajo de 3:1 sobre el fondo claro, y la regla es que
   entonces el valor tiene que estar escrito, no solo pintado. */
.legend {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.legend li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
}

.legend .swatch {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}

.legend .name {
  flex: 1;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.legend .value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* --- Tablas --------------------------------------------------------------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

th {
  text-align: left;
  font-weight: 600;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  padding: 0 10px 8px 0;
  border-bottom: 1px solid var(--border);
}

td {
  padding: 10px 10px 10px 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

tbody tr.clickable:hover {
  background: var(--wash);
  cursor: pointer;
}

td.amount, th.amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding-right: 0;
}

/* La fecha, el estado y el importe no envuelven -- son un token corto cada uno --
   asi que en una pantalla estrecha se quedan con su ancho natural y es el nombre
   del comercio el que se aprieta hasta partirse a media palabra. La fecha es la
   columna que menos falta hace de un vistazo (sigue en la ficha del documento), asi
   que es la que se quita para devolverle el sitio al nombre. */
@media (max-width: 640px) {
  .documents-table th:nth-child(2),
  .documents-table td:nth-child(2) {
    display: none;
  }
}

.reason {
  display: block;
  color: var(--text-secondary);
  font-size: 0.8rem;
  margin-top: 2px;
}

/* --- Estado del documento ------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  white-space: nowrap;
}

/* El color nunca va solo: cada estado lleva su punto y su palabra. */
.pill .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
}

.pill.processed .dot, .pill.confirmed .dot { background: var(--good); }
.pill.needs_review .dot { background: var(--warning); }
.pill.failed .dot { background: var(--critical); }
.pill.duplicate .dot { background: var(--serious); }
.pill.stored .dot, .pill.processing .dot, .pill.received .dot { background: var(--text-muted); }

.filters {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.filters button[aria-pressed="true"] {
  background: var(--text-primary);
  border-color: var(--text-primary);
  color: var(--page);
}

/* --- Login ---------------------------------------------------------------- */

.login {
  max-width: 380px;
  margin: 12vh auto;
}

.login h1 {
  font-size: 1.4rem;
  margin-bottom: 6px;
}

.field {
  display: block;
  margin-top: 16px;
}

.field span {
  display: block;
  font-size: 0.82rem;
  color: var(--text-secondary);
  margin-bottom: 5px;
}

input[type="email"],
input[type="password"],
input[type="search"],
input[type="text"] {
  width: 100%;
  font: inherit;
  padding: 9px 11px;
  border: 1px solid var(--axis);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text-primary);
}

input:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--series-1);
  outline-offset: 2px;
}

.primary {
  width: 100%;
  margin-top: 20px;
  padding: 11px;
  border: none;
  border-radius: 8px;
  background: var(--text-primary);
  color: var(--page);
  font-weight: 600;
}

.primary:disabled {
  opacity: 0.5;
  cursor: default;
}

.error {
  margin-top: 14px;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1px solid var(--critical);
  color: var(--critical);
  font-size: 0.85rem;
}

.empty {
  color: var(--text-secondary);
  font-size: 0.88rem;
  padding: 8px 0;
  margin: 0;
}

/* --- Ficha del documento -------------------------------------------------- */

dialog {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-primary);
  padding: 0;
  width: min(680px, calc(100vw - 32px));
  max-height: 86vh;
}

dialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}

.sheet {
  padding: 22px;
  overflow-y: auto;
  max-height: 86vh;
}

.sheet header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 4px;
}

.sheet header h2 {
  flex: 1;
  font-size: 1.15rem;
}

/* La direccion de reenvio. En monoespaciada y con `user-select: all` porque son doce
   caracteres aleatorios: nadie la lee, se copia — y en el movil, donde no hay boton
   de copiar del portapapeles fiable, un toque la selecciona entera. */
.address {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  user-select: all;
  overflow-wrap: anywhere;
  background: var(--wash);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 12px 0 0;
}

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 12px;
  margin: 18px 0;
}

.facts div span {
  display: block;
  font-size: 0.76rem;
  color: var(--text-secondary);
}

.facts div strong {
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.balance {
  margin: 4px 0 16px;
  font-size: 0.84rem;
  padding: 9px 12px;
  border-radius: 8px;
  background: var(--wash);
}

/* --- Subir un documento --------------------------------------------------- */

.dropzone {
  border: 1px dashed var(--axis);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 16px;
  text-align: center;
  font-size: 0.88rem;
}

.dropzone p {
  margin: 0;
}

.dropzone.over {
  border-color: var(--series-1);
  border-style: solid;
  background: var(--wash);
}

.linky {
  background: none;
  border: none;
  padding: 0;
  color: var(--series-1);
  font: inherit;
  text-decoration: underline;
}

.upload-status {
  margin-top: 10px;
  font-size: 0.85rem;
  font-weight: 600;
}

.upload-status.error {
  color: var(--critical);
}

/* Lo que ha pasado al compartir desde el móvil. Se recibe entrando a la página, así
   que va arriba del todo y no dentro de ninguna tarjeta. */
.banner {
  margin: 0 0 20px;
  padding: 12px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--good);
  background: var(--surface);
  font-size: 0.9rem;
  font-weight: 600;
}

.banner.warn {
  border-color: var(--warning);
}

/* Quien comparte el hogar. Una línea por persona y sin tabla: son dos o tres, y una
   tabla de tres filas es más chrome que dato. */
.people {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: grid;
  gap: 8px;
}

.people li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

/* Un enlace que se comporta como botón: conectar Gmail es una navegación de verdad
   a la pantalla de permisos de Google, no una llamada del panel. */
.as-button {
  display: inline-block;
  text-decoration: none;
  text-align: center;
}

/* --- Corregir un documento ------------------------------------------------ */

.field.compact {
  margin-top: 0;
}

.field.compact span {
  font-size: 0.76rem;
}

.field.compact input,
.field.compact select {
  width: 100%;
  font: inherit;
  font-size: 0.9rem;
  padding: 6px 9px;
  border: 1px solid var(--axis);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text-primary);
}

form.facts {
  align-items: start;
}

.actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 18px;
}

.primary.compact {
  width: auto;
  margin-top: 0;
  padding: 8px 16px;
  font-size: 0.9rem;
}

/* El aviso de que esto se parece a un gasto que ya estaba. Va en ambar y no en rojo:
   no es un error, es una pregunta — y la respuesta puede ser perfectamente "son dos
   gastos distintos". */
.notice {
  margin: 18px 0 0;
  padding: 14px 16px;
  border: 1px solid var(--warning);
  border-radius: 8px;
  font-size: 0.88rem;
}

.notice p {
  margin: 6px 0 0;
}

.notice .actions {
  margin-top: 12px;
}

.search-row {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
}

.search-row input {
  flex: 1;
}

.search-row button {
  flex: none;
}

.product-result {
  border: none;
  background: transparent;
  color: var(--text-primary);
  text-align: left;
  padding: 8px 10px;
  border-radius: 8px;
  width: 100%;
  font-size: 0.88rem;
}

.product-result:hover,
.product-result[aria-pressed="true"] {
  background: var(--wash);
}

.product-result small {
  color: var(--text-secondary);
}

/* --- Lista de la compra ----------------------------------------------------
   Se usa con el pulgar y andando: filas altas y botones que no hace falta apuntar. */
.shopping-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.shopping-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 0;
  border-bottom: 1px solid var(--grid);
}

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

/* Los botones bajan de linea solo cuando el texto no cabe con ellos al lado. */
.shopping-text {
  flex: 1 1 14ch;
  min-width: 0;
  overflow-wrap: anywhere;
}

.shopping-text small {
  display: block;
  color: var(--text-secondary);
  font-size: 0.78rem;
}

.shopping-row .ghost {
  flex: none;
  min-height: 36px;
}

.shopping-list.done .shopping-text > span {
  text-decoration: line-through;
  color: var(--text-secondary);
}

.shopping-heading {
  margin: 20px 0 4px;
  font-size: 0.9rem;
}

.shopping-undo {
  margin: 0 0 8px;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.shopping-hidden {
  margin-top: 16px;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.shopping-hidden summary {
  cursor: pointer;
}

/* --- Modo compra -----------------------------------------------------------
   Una mano en el carro y el pulgar en la pantalla: filas de 56 px, todo el ancho
   pulsable, y el boton de pagar siempre a la vista abajo. */
.shop {
  max-width: 640px;
  padding-bottom: 140px;
}

.shop-bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 0;
  background: var(--page);
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}

.shop-bar output {
  font-weight: 600;
  font-size: 0.95rem;
}

.shop-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.shop-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 14px;
  width: 100%;
  min-height: 56px;
  padding: 10px 4px;
  border: none;
  border-bottom: 1px solid var(--grid);
  background: transparent;
  color: var(--text-primary);
  text-align: left;
  font-size: 1.05rem;
}

.shop-item small {
  flex-basis: 100%;
  padding-left: 40px;
  color: var(--text-secondary);
  font-size: 0.78rem;
}

.shop-name {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.shop-mark {
  flex: none;
  width: 26px;
  height: 26px;
  border: 2px solid var(--axis);
  border-radius: 6px;
}

.shop-mark {
  position: relative;
}

.shop-item[aria-pressed="true"] .shop-mark {
  border-color: var(--good);
  background: var(--good);
}

/* La marca de visto se dibuja con dos bordes girados: sin iconos ni fuentes. */
.shop-item[aria-pressed="true"] .shop-mark::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 2px;
  width: 7px;
  height: 13px;
  border: solid var(--surface);
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
}

.shop-item[aria-pressed="true"] .shop-name {
  text-decoration: line-through;
  color: var(--text-secondary);
}

.shop-add {
  margin-top: 16px;
}

.shop-staples {
  margin-top: 16px;
  color: var(--text-secondary);
}

.shop-staples summary {
  cursor: pointer;
  padding: 12px 0;
}

/* En modo compra no se ve nada mas que la compra. */
body:has(#shop:not([hidden])) > footer {
  display: none;
}

.shop-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 12px 20px 20px;
  background: var(--page);
  border-top: 1px solid var(--border);
}

.shop-footer > * {
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.shop-footer .primary {
  display: block;
  margin-top: 0;
  padding: 14px;
  font-size: 1rem;
}

/* La revision crece dentro del pie fijo, pero sin tapar la lista entera: con muchas
   cosas pendientes, se desplaza por dentro. */
.shop-check {
  max-height: 55vh;
  overflow-y: auto;
  margin-bottom: 10px;
  font-size: 0.95rem;
}

.shop-check-title {
  margin: 0 0 6px;
  font-weight: 600;
  color: var(--good-text);
}

.shop-check.missing .shop-check-title {
  color: var(--text-primary);
}

.shop-check-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.shop-check-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--grid);
}

.shop-check-actions {
  display: flex;
  gap: 6px;
}

.shop-check-actions .ghost,
.shop-check-back {
  min-height: 40px;
}

.shop-check-back {
  margin-top: 10px;
}

.shop-check-note {
  margin: 8px 0 0;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.shop-item.unavailable .shop-name {
  color: var(--text-secondary);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Prosa ----------------------------------------------------------------
   Para los documentos que no son el panel: hoy, la politica de privacidad. Va
   acotado a `.prose` y no suelto, porque el resto de la aplicacion son tarjetas con
   su propio ritmo y `h2 { margin: 0 }` esta puesto a proposito para ellas. Un texto
   largo necesita justo lo contrario. */

.prose {
  max-width: 68ch;
}

.prose h2 {
  margin: 28px 0 8px;
  font-size: 1.05rem;
}

.prose p,
.prose ul {
  margin: 0 0 12px;
  line-height: 1.6;
}

.prose ul {
  padding-left: 20px;
}

.prose li {
  margin-bottom: 6px;
}

.prose code {
  font-size: 0.88em;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--wash);
  /* Una etiqueta de Gmail o un scope de OAuth: se copian y se pegan tal cual, y una
     letra de mas rompe el montaje sin decir por que. */
  word-break: break-word;
}

/* --- Secciones del panel -------------------------------------------------
   Arriba en el ordenador; en el movil, fija al pie, donde llega el pulgar con el
   movil en una mano. La activa se marca con aria-current y el estilo cuelga de ahi,
   para que lo que ve un lector de pantalla y lo que se ve con los ojos no puedan
   decir cosas distintas. */

.brand {
  color: inherit;
  text-decoration: none;
}

.sections {
  display: flex;
  gap: 4px;
}

.sections a {
  position: relative;
  padding: 6px 12px;
  border-radius: 8px;
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 0.9rem;
}

.sections a:hover {
  background: var(--wash);
  color: var(--text-primary);
}

.sections a[aria-current="page"] {
  background: var(--wash);
  color: var(--text-primary);
  font-weight: 600;
}

/* Cuantos documentos esperan a que alguien los mire. Aviso y no adorno: es lo unico
   del panel que necesita a una persona. */
.badge {
  display: inline-block;
  min-width: 18px;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--warning);
  color: #0b0b0b;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}

.view-title {
  font-size: 1.35rem;
  margin: 0 0 16px;
}

@media (max-width: 780px) {
  .sections {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
    justify-content: space-around;
    gap: 0;
    padding: 4px 4px calc(4px + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--border);
  }

  .sections a {
    flex: 1;
    padding: 10px 2px;
    text-align: center;
    font-size: 0.78rem;
  }

  .sections .badge {
    position: absolute;
    top: 2px;
    right: 4px;
    margin: 0;
  }

  /* Que la barra fija no tape el final de la ultima tarjeta. */
  #dashboard {
    padding-bottom: 96px;
  }

  body:has(#dashboard:not([hidden])) > footer {
    padding-bottom: 80px;
  }
}

/* --- La marca en el panel -------------------------------------------------
   Lo mismo que la landing: verde tinta, acento lima y la fuente de titulares. Va
   aqui al final, encima de lo de arriba, para que quitarlo devuelva el panel sobrio
   sin tocar nada mas. Ningun color de aqui codifica un dato: las cifras y las
   graficas siguen con sus colores de siempre. */

.brand-mark {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--brand-lime);
}

.brand-mark svg {
  width: 24px;
  height: 24px;
  fill: var(--brand-ink);
}

.brand-mark .brand-mark-lines {
  fill: none;
  stroke: var(--brand-lime);
  stroke-width: 1.8;
  stroke-linecap: round;
}

.view-title,
.card h2,
.hero .figure,
.login h1,
.brand {
  font-family: var(--font-display);
}

.view-title {
  font-size: clamp(1.6rem, 3.5vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  margin: 8px 0 20px;
}

.card {
  border-radius: 16px;
}

.card h2 {
  font-size: 1.1rem;
  font-weight: 700;
}

/* La barra de arriba: una pieza de tinta flotando sobre el crema. */
#dashboard .topbar {
  margin: 16px 0 24px;
  padding: 10px 12px 10px 16px;
  border: none;
  border-radius: 18px;
  background: var(--brand-ink);
  color: var(--brand-cream);
}

#dashboard .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  line-height: 1.2;
}

#dashboard .brand small {
  color: rgba(246, 241, 231, 0.65);
  font-family: var(--font);
}

#dashboard .topbar .ghost {
  border-color: rgba(246, 241, 231, 0.25);
  color: var(--brand-cream);
}

#dashboard .topbar .ghost:hover:not(:disabled) {
  background: rgba(246, 241, 231, 0.1);
  color: var(--brand-cream);
}

#dashboard .month-picker output {
  color: var(--brand-cream);
}

.sections a {
  border-radius: 999px;
  color: rgba(246, 241, 231, 0.75);
}

.sections a:hover {
  background: rgba(246, 241, 231, 0.1);
  color: var(--brand-cream);
}

.sections a[aria-current="page"] {
  background: var(--brand-lime);
  color: var(--brand-ink);
}

@media (max-width: 780px) {
  .sections {
    left: 8px;
    right: 8px;
    bottom: calc(8px + env(safe-area-inset-bottom));
    padding: 6px;
    border: none;
    border-radius: 20px;
    background: var(--brand-ink);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
  }

  #dashboard .topbar {
    margin-top: 10px;
  }
}

/* La cifra del mes: la tarjeta que se ve primero, en tinta. */
.summary-card {
  background:
    radial-gradient(600px 300px at 100% 0%, rgba(200, 241, 105, 0.14), transparent 60%),
    var(--brand-ink);
  border: none;
  color: var(--brand-cream);
  padding: 28px;
}

.summary-card .hero .figure {
  font-size: clamp(3rem, 8vw, 4.6rem);
  font-weight: 800;
  letter-spacing: -0.04em;
}

/* La comparacion va en una pastilla clara: el rojo y el verde de la direccion
   estan elegidos contra fondo claro y sobre la tinta no se leerian. */
.summary-card .delta {
  padding: 4px 12px;
  border-radius: 12px;
  background: var(--brand-paper);
}

/* Los colores de la direccion, fijados a los del modo claro: la pastilla es clara
   en los dos temas, y los del modo oscuro (pensados para fondo oscuro) no se leian
   encima. Son los mismos valores que --text-secondary, --good-text y --critical
   en claro. */
.summary-card .delta.flat { color: #52514e; }
.summary-card .delta.down { color: #006300; }
.summary-card .delta.up { color: #d03b3b; }

@media (max-width: 520px) {
  .summary-card {
    padding: 22px 18px;
  }

  .summary-card .tiles {
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }
}

.summary-card .delta:empty {
  display: none;
}

.summary-card .tile {
  border: 1px solid rgba(246, 241, 231, 0.14);
  border-radius: 12px;
  background: rgba(246, 241, 231, 0.06);
}

.summary-card .tile .label {
  color: rgba(246, 241, 231, 0.7);
}

.summary-card .tile.attention {
  border-color: var(--warning);
}

.summary-card .note {
  color: var(--brand-cream);
}

.primary {
  border-radius: 999px;
  background: var(--brand-ink);
  color: var(--brand-cream);
}

.ghost {
  border-radius: 999px;
}

/* Subir: una zona grande y evidente, que se ilumina en lima al arrastrar encima. */
.dropzone {
  padding: 32px 16px;
  border: 2px dashed color-mix(in srgb, var(--brand-ink) 35%, transparent);
  border-radius: 14px;
  background: color-mix(in srgb, var(--brand-lime) 10%, transparent);
  font-size: 0.95rem;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.dropzone::before {
  content: "";
  display: block;
  width: 44px;
  height: 44px;
  margin: 0 auto 12px;
  border-radius: 14px;
  background: var(--brand-ink)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c8f169' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 15V4M7.5 8.5 12 4l4.5 4.5M4 15v4a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-4'/%3E%3C/svg%3E")
    center / 24px no-repeat;
}

.dropzone.over {
  border-color: var(--brand-ink);
  border-style: solid;
  background: color-mix(in srgb, var(--brand-lime) 35%, transparent);
}

.linky {
  color: inherit;
  font-weight: 600;
  text-decoration-color: var(--brand-lime);
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .dropzone {
    border-color: rgba(246, 241, 231, 0.3);
  }
}

/* El modo compra: la casilla marcada en tinta con el visto en lima. */
.shop-item[aria-pressed="true"] .shop-mark {
  border-color: var(--brand-ink);
  background: var(--brand-ink);
  border-radius: 8px;
}

.shop-item[aria-pressed="true"] .shop-mark::after {
  border-color: var(--brand-lime);
}

.shop-mark {
  border-radius: 8px;
}

.shop-bar output {
  font-family: var(--font-display);
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .shop-item[aria-pressed="true"] .shop-mark {
    border-color: var(--brand-lime);
    background: var(--brand-lime);
  }

  :root:where(:not([data-theme="light"])) .shop-item[aria-pressed="true"] .shop-mark::after {
    border-color: var(--brand-ink);
  }
}

/* Entrar: la tinta de la landing de fondo, para que no parezca otro sitio. */
body:has(main.login:not([hidden])) {
  background:
    radial-gradient(700px 400px at 80% 10%, rgba(200, 241, 105, 0.14), transparent 60%),
    var(--brand-ink);
}

body:has(main.login:not([hidden])) > footer a {
  color: rgba(246, 241, 231, 0.7);
}

.login .card {
  padding: 32px;
  border: none;
  border-radius: 24px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3);
}

.login .card a:not(.login-brand) {
  color: inherit;
  font-weight: 600;
  text-decoration-color: var(--brand-lime);
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
}

.login-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 26px;
  color: inherit;
  font-family: var(--font-display);
  font-weight: 700;
  text-decoration: none;
}

.login h1 {
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .primary {
    background: var(--brand-lime);
    color: var(--brand-ink);
  }
}

footer.page a {
  color: var(--text-secondary);
}

/* El pie lleva .page y .caption a la vez, y el margen de .caption, declarado
   despues, le quitaba el centrado: se quedaba pegado al borde izquierdo. */
footer.page {
  margin: 0 auto;
}

.login-alt {
  margin-top: 18px;
  text-align: center;
}

/* El campo trampa: fuera de la pantalla y no con display:none, que algunos bots
   saben saltarse. */
input.trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

[hidden] {
  display: none !important;
}
