/*
 * Rice and Beans -- San Ignacio, Baja California Sur.
 *
 * Hoja de estilos propia de este negocio. No se comparte con ningun otro
 * sistema: cada cliente tiene la suya, escrita para su marca.
 *
 * La identidad sale del logotipo, no de un gusto: los verdes son los que ya
 * estan dibujados ahi. El militar #4c5c32 y el aguacate #678f34 se extrajeron
 * del archivo del logo, igual que el crema de las letras (#fafee8), el cafe del
 * frijol y el naranja del sombrero. Por eso la aplicacion y el logotipo se ven
 * del mismo sitio.
 *
 * Reparto de los dos verdes, que es lo unico delicado de esta paleta:
 *
 *   militar (primario)  cromo, botones, fichas OCUPADAS. Es oscuro y pesa.
 *   aguacate (acento)   marca y detalle. NUNCA un estado.
 *
 * El plano de ocupacion ya usa el hueco para decir "libre" y el relleno para
 * decir "ocupada". Si el verde claro pintara las fichas ocupadas, recepcion
 * leeria como disponible justo lo que esta vendido. Ese error se descarto a
 * proposito en El Padrino y aqui tampoco se comete: ocupada va en militar
 * oscuro, y ningun estado se apoya en el aguacate.
 *
 * Serif en los titulos, como antes. Sin fuentes externas ni CDN: la CSP solo
 * permite 'self'.
 */

/* === 1. Tokens de diseno === */
:root {
  /* Neutros de arena, tibios y sin rojo: es la cama sobre la que el verde del
     logotipo se ve verde. Ningun gris es puro. */
  --color-neutral-0: #fffefa;
  --color-neutral-50: #f8f6ee;
  --color-neutral-100: #efebdf;
  --color-neutral-200: #ded9c8;
  --color-neutral-300: #c2bca6;
  --color-neutral-400: #9b957e;
  --color-neutral-500: #757062;
  --color-neutral-600: #585449;
  --color-neutral-700: #403d35;
  --color-neutral-800: #282621;
  --color-neutral-900: #16150f;

  /* Verde militar del logotipo. Es el primario: cromo, botones y las fichas
     ocupadas del plano. Oscuro a proposito, para que lo vendido pese. */
  --color-primary-50: #f1f4ea;
  --color-primary-300: #9fb27e;
  --color-primary-500: #4c5c32;
  --color-primary-600: #3b4826;
  --color-primary-700: #2b351b;
  /* El crema de las letras del logotipo, no un blanco puro. */
  --color-primary-contrast: #fafee8;

  /* Verde aguacate del logotipo. Acento de marca y nada mas: ningun estado de
     la aplicacion se apoya en el (ver el encabezado de este archivo). */
  --color-accent-100: #e5f0d2;
  --color-accent-500: #678f34;

  /* Semanticos -- fijos, no dependen de marca */
  --color-success-50: #eaf7ee;
  --color-success-500: #1e7d3c;
  --color-success-700: #145a2a;
  --color-success-contrast: #ffffff;
  --color-warning-50: #fff6e5;
  --color-warning-500: #8a5a00;
  --color-warning-700: #6b4600;
  --color-warning-contrast: #ffffff;
  --color-danger-50: #fdecec;
  --color-danger-500: #b3261e;
  --color-danger-700: #8a1c16;
  --color-danger-contrast: #ffffff;
  --color-info-50: #fdf1e6;   /* naranja del sombrero, no azul de sistema */
  --color-info-500: #a5470a;  /* el mismo naranja, oscurecido para que se lea */
  --color-info-contrast: #ffffff;

  /* Superficie y texto (modo claro, unico tema del MVP) */
  --color-bg: var(--color-neutral-0);
  --color-bg-subtle: var(--color-neutral-50);
  --color-surface: var(--color-neutral-0);
  --color-border: var(--color-neutral-200);
  --color-text: var(--color-neutral-900);
  --color-text-muted: var(--color-neutral-600);
  --color-text-on-primary: var(--color-primary-contrast);
  --color-focus-ring: var(--color-primary-500);

  /* Tipografia: system font stack, sin fuentes externas */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Serif para titulos: da el aire de hospitalidad que un sans neutro no tiene.
     Solo fuentes del sistema, sin descargas. */
  --font-serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
  /* Densidad de panel de trabajo, no de pagina de lectura.
   *
   * La base baja de 16 a 14 y la escala de titulos se comprime. Es el cambio que mas
   * se nota de los que pidio el cliente al ensenar capturas de otro dashboard: lo que
   * hace que esas pantallas se vean "de sistema" no es su paleta ni sus bordes, es que
   * caben mas renglones en la misma altura. Recepcion lee listas de ocupacion todo el
   * dia y cada renglon que cabe es uno que no hay que ir a buscar.
   *
   * El xs NO baja: es el de las etiquetas de estado y las unidades del plano, y por
   * debajo de 12px deja de leerse de pie frente al mostrador. El sm baja un punto, de 14
   * a 13, porque viste las tablas y las ayudas, que es donde la densidad se nota y donde
   * el texto va en renglones cortos. */
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.8125rem;
  --font-size-base: 0.875rem;
  --font-size-lg: 1rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-bold: 700;
  --line-height-tight: 1.25;
  --line-height-base: 1.4285;

  /* Espaciado: escala base 4px */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;

  /* Radios y sombras: discretos */
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-full: 999px;
  /* El tinte de la sombra es el neutro 900 de esta paleta, no un gris azulado. */
  /* Una sola sombra, y minima. La media se quito porque no la usaba nadie: el comentario
   * que la justificaba hablaba de un menu desplegable que no existe en esta hoja. */
  --shadow-sm: 0 1px 2px rgba(22, 21, 15, 0.07);

  /* Foco (accesibilidad, nunca eliminar) */
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;

  /* Transiciones: cortas, solo retroalimentacion funcional */
  --transition-fast: 120ms ease;
  --transition-base: 180ms ease;

  --content-max-width: 1180px;
}

/* === 2. Reset y base === */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  color: var(--color-text);
  background: var(--color-bg);
}
h1, h2, h3, h4 {
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-4);
  /* Reparte el texto entre renglones para que un titulo de dos lineas no deje una sola
   * palabra colgando abajo. Donde no se soporta no pasa nada: cae al salto normal. */
  text-wrap: balance;
}
h1 { font-size: var(--font-size-2xl); }
h2 { font-size: var(--font-size-xl); }
p { margin: 0 0 var(--space-4); }
a { color: var(--color-primary-600); }
img, svg { max-width: 100%; }
ul, ol { margin: 0; padding: 0; list-style: none; }
table { border-collapse: collapse; }
button { font-family: inherit; }

/* Sin esto, el navegador espera ~300ms por si el toque es un doble toque para hacer zoom.
 * Donde mas se siente es en el selector de habitaciones: son decenas de casillas que
 * recepcion marca una tras otra desde el telefono, y el retardo se acumula en cada una.
 *
 * `.hab` NO va en esta lista, aunque el plano sea la rejilla mas grande de la pantalla:
 * sus casillas son <span> sin enlace ni manejador, asi que no hay ningun click que el
 * retardo este frenando. Incluirlo no rompia nada, pero la linea no hacia lo que su
 * propio comentario decia. El dia que la casilla abra el detalle de la habitacion, se
 * agrega aqui y entonces si significa algo. */
button, a, label, summary, input[type="checkbox"], input[type="radio"] {
  touch-action: manipulation;
}

/* === 3. Accesibilidad: foco, sr-only, skip-link, honeypot === */
:focus { outline: none; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible, summary:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -48px;
  left: var(--space-3);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: var(--color-primary-700);
  color: var(--color-primary-contrast);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: var(--font-weight-medium);
  transition: top var(--transition-fast);
}
.skip-link:focus { top: var(--space-3); }

/* Honeypot: fuera de pantalla pero presente en el DOM (no display:none), para
   que bots simples que llenan cualquier campo lo capturen. El HTML ya lo
   excluye de lectores de pantalla con aria-hidden. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* === 4. Layout: contenedor y barra superior === */
.container { max-width: var(--content-max-width); margin: 0 auto; padding: 0 var(--space-4); }
/* El aire vertical de la pagina.
 *
 * El contenedor no lo lleva porque tambien lo usa la barra superior, y un selector
 * `main.container` le ganaria por especificidad a `.error-page`, que ya trae el suyo.
 * Por eso una clase propia.
 *
 * Sin esto, el titulo de cada pantalla tocaba el borde aguacate de la barra y el
 * ultimo boton de cada formulario quedaba pegado al fin del documento. Las pantallas
 * de acceso y la publica si tenian su aire; en las de trabajo faltaba. Es lo que el
 * cliente veia cuando pidio "mejorar el espaciado", y es una sola regla. */
.pagina { padding-block: var(--space-5); }
/* El ultimo bloque de la pagina ya trae su propio margen inferior -- panel, tabla,
   filtros, todos separan 24. Sumarlo al relleno de la pagina dejaba 24 arriba contra
   72 abajo y la pagina se leia descolgada. */
.pagina > :last-child { margin-bottom: 0; }
/* === La barra superior es la pieza verde de la aplicacion ===
 *
 * El cliente pidio "el fondo de la app en verde". El verde va aqui, en el
 * cromo, y no debajo del contenido: recepcion pasa el dia leyendo tablas de
 * ocupacion y montos, y un fondo de color debajo de una tabla densa se paga en
 * errores de lectura, no en gusto. Arriba el verde se ve en cada pantalla y no
 * le estorba a nadie.
 *
 * La franja aguacate del borde inferior es el unico sitio donde el verde claro
 * toca la interfaz: separa la barra del contenido y no significa nada. */
.topbar {
  background: var(--color-primary-700);
  border-bottom: 3px solid var(--color-accent-500);
}
.topbar-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding-block: var(--space-3);
}
.brand { display: inline-flex; align-items: center; margin-right: auto; text-decoration: none; }
/* El logotipo se manda con el alto, no con el ancho: es muy apaisado y lo que
   hay que controlar es cuanto crece la barra. */
.brand-logo { display: block; width: auto; height: 2.25rem; }
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 var(--space-3);
  background: transparent;
  border: 1px solid var(--color-primary-300);
  border-radius: var(--radius-md);
  color: var(--color-primary-contrast);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.nav-toggle:hover { background: var(--color-primary-600); }
/* Las divisiones dentro de la barra se pintan con el verde claro de la propia
   barra, no con el borde de las tarjetas: ahi seria una raya clara sobre verde. */
.mainnav { display: none; flex-direction: column; width: 100%; order: 10; gap: var(--space-1); padding-top: var(--space-2); border-top: 1px solid var(--color-primary-600); }
.mainnav.nav-open { display: flex; }
.navlink { display: block; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); color: var(--color-primary-contrast); text-decoration: none; font-weight: var(--font-weight-medium); }
.navlink:hover { background: var(--color-primary-600); }
/* La pagina actual se marca invirtiendo la ficha: crema encima, verde debajo.
   Es el mismo recurso que el plano usa para separar lo lleno de lo hueco. */
.navlink[aria-current="page"] { background: var(--color-primary-50); color: var(--color-primary-700); }
.topbar-user { display: flex; align-items: center; gap: var(--space-3); width: 100%; order: 11; padding-top: var(--space-2); border-top: 1px solid var(--color-primary-600); font-size: var(--font-size-sm); color: var(--color-primary-contrast); }
.user-name { font-weight: var(--font-weight-medium); }
.user-role { color: var(--color-primary-300); text-transform: capitalize; }
.topbar-user .inline { margin-left: auto; }
/* "Salir" es un boton de enlace, y su color por defecto es el verde de la marca:
   sobre la barra verde desapareceria. */
.topbar-user .btn-link { color: var(--color-primary-contrast); }
.topbar-user .btn-link:hover { color: var(--color-accent-100); }

@media (min-width: 640px) {
  .nav-toggle { display: none; }

  /* Dos columnas: el logotipo a la izquierda, y a su derecha el menu encima del
     usuario.
     *
     * Antes era una sola fila con envoltura, y como los enlaces del menu suman mas de
     * mil pixeles, la barra se partia en tres renglones: el logotipo solo en el
     * primero, con todo el ancho de la pantalla vacio a su derecha, el menu en el
     * segundo y el usuario en el tercero. El cliente lo noto y pidio mover el
     * logotipo. El hueco no estaba a la izquierda del logotipo sino a su derecha, y
     * esta rejilla es la que lo ocupa: la barra baja de tres renglones a dos y el
     * logotipo cabe al doble de alto sin crecer ni un pixel la barra.
     *
     * El menu conserva la envoltura dentro de su columna: a 768 -- una tableta -- los
     * enlaces se salian de la pantalla y arrastraban la pagina entera a lo ancho. */
  .topbar-inner {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: var(--space-5);
    row-gap: var(--space-2);
    /* La barra va de borde a borde, no encajonada en el contenedor centrado.
       *
       * El contenedor topa en 1180px, asi que en un monitor de escritorio el logotipo
       * quedaba a 380 pixeles del borde con una franja verde vacia a su izquierda. El
       * cliente la senalo y pidio mover el logotipo ahi. El contenido de las pantallas
       * si sigue centrado: la barra es una banda de cromo y se lee como tal, no como
       * una columna mas del documento. */
    max-width: none;
  }
  .brand { grid-column: 1; grid-row: 1 / span 2; margin-right: 0; }
  /* Ocupa el alto de los dos renglones que tiene al lado. */
  .brand-logo { height: 4.25rem; }
  .mainnav { grid-column: 2; grid-row: 1; display: flex; flex-direction: row; flex-wrap: wrap; padding-top: 0; border-top: none; gap: var(--space-2); }
  .topbar-user { grid-column: 2; grid-row: 2; padding-top: 0; border-top: none; }
  /* "Salir" al extremo derecho. Se probo pegado al nombre y a 1920 la barra quedaba
     con seiscientos pixeles de verde vacio a la derecha: el hueco que el cliente
     senalo cambiaba de lado en vez de cerrarse. Anclando el cierre de sesion al borde,
     la barra ocupa su ancho. */
  .topbar-user .inline { margin-left: auto; }
}

/* === 5. Botones === */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast), opacity var(--transition-fast);
}
@media (min-width: 1024px) { .btn { min-height: 40px; } }
.btn-primary { background: var(--color-primary-500); border-color: var(--color-primary-500); color: var(--color-text-on-primary); }
.btn-primary:hover { background: var(--color-primary-600); border-color: var(--color-primary-600); }
.btn-secondary { background: transparent; border-color: var(--color-border); color: var(--color-text); }
.btn-secondary:hover { background: var(--color-bg-subtle); }
.btn-danger { background: var(--color-danger-500); border-color: var(--color-danger-500); color: var(--color-danger-contrast); }
.btn-danger:hover { background: var(--color-danger-700); border-color: var(--color-danger-700); }
.btn-link { min-height: auto; padding: var(--space-1) var(--space-2); background: transparent; border: none; color: var(--color-primary-600); font-weight: var(--font-weight-medium); text-decoration: underline; }
.btn-link:hover { color: var(--color-primary-700); }
.btn-block { display: flex; width: 100%; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.inline { display: inline-block; margin: 0; }

/* === 6. Formularios === */
.field { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-4); }
.field > label, form > label { font-weight: var(--font-weight-medium); font-size: var(--font-size-sm); }
label { color: var(--color-text); }
input, select, textarea {
  font-family: inherit;
  font-size: var(--font-size-base);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
}
@media (min-width: 1024px) { input, select, textarea { min-height: 40px; } }
textarea { min-height: auto; resize: vertical; }
input:hover, select:hover, textarea:hover { border-color: var(--color-neutral-400); }
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--color-danger-500); }
input[type="checkbox"], input[type="radio"] { min-height: auto; width: 18px; height: 18px; margin: 0 var(--space-2) 0 0; vertical-align: middle; }
.field-check { flex-direction: row; align-items: flex-start; }
.field-check label { display: flex; align-items: center; font-weight: var(--font-weight-normal); font-size: var(--font-size-base); }
.radio-option { display: inline-flex; align-items: center; margin: 0 var(--space-4) var(--space-2) 0; font-weight: var(--font-weight-normal); }
.field-error { display: flex; align-items: flex-start; gap: var(--space-1); color: var(--color-danger-700); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); }
/* El margen negativo que tenia esta regla se escribio para pegar la ayuda al parrafo
 * que la precede. Ese caso no existe en ninguno de los trece usos: se reviso uno por
 * uno y la ayuda sigue a un titulo, a una barra de herramientas, a una rejilla de
 * campos o a un valor de solo lectura, nunca a un parrafo corrido. El
 * resultado era que el texto se montaba cuatro pixeles SOBRE su propio titulo en cinco
 * sitios, y quedaba pegado al borde del input en otros dos.
 *
 * El tope de medida es aparte y vale igual: con 1180px de ancho util, estas lineas
 * corrian a mas de 140 caracteres y se leian amontonadas aunque el espaciado vertical
 * estuviera bien. */
.hint { color: var(--color-text-muted); font-size: var(--font-size-sm); margin: 0 0 var(--space-4); max-width: 70ch; }
/* Dentro de un campo, en cambio, la ayuda va DEBAJO del control, y ese mismo margen
   negativo la monta sobre el borde del input. Aqui lleva su propio aire. */
.field .hint { margin: var(--space-1) 0 0; }
fieldset { border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-4); margin: 0 0 var(--space-5); }
legend { padding: 0 var(--space-2); font-weight: var(--font-weight-bold); font-size: var(--font-size-sm); color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.02em; }
.form-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-5); }
.inline-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
.inline-form .field { margin-bottom: 0; min-width: 160px; }
.grid-2, .grid-3 { display: grid; grid-template-columns: 1fr; gap: 0 var(--space-4); }
@media (min-width: 640px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
}

/* === 7. Alertas y avisos === */
.alert { padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); border-left: 4px solid transparent; margin-bottom: var(--space-4); font-size: var(--font-size-sm); }
.alert-success { background: var(--color-success-50); border-left-color: var(--color-success-500); color: var(--color-success-700); }
.alert-danger { background: var(--color-danger-50); border-left-color: var(--color-danger-500); color: var(--color-danger-700); }
.notice { padding: var(--space-3) var(--space-4); margin-bottom: var(--space-5); background: var(--color-info-50); border-left: 4px solid var(--color-info-500); border-radius: var(--radius-md); font-size: var(--font-size-sm); }
/* Variante para lo que no es informativo sino un hueco abierto: el aviso de
 * privacidad sin capturar mientras el formulario publico ya recibe datos. El naranja
 * informativo de la marca no alcanza a decir eso. */
.notice-alerta { background: var(--color-warning-50); border-left-color: var(--color-warning-500); }

/* === 8. Tablas === */
/* `contain: paint` no es decoracion: sin el, en un telefono la pagina ENTERA se
   desplaza a lo ancho al abrir el calendario, aunque la tabla ya viva en un
   contenedor con overflow. Medido a 390px: el documento daba 711px de ancho y la
   pagina se movia de verdad. La contencion de pintado corta eso y la tabla sigue
   desplazandose por dentro, que es lo que se queria. */
.table-wrap { overflow-x: auto; contain: paint; border: 1px solid var(--color-border); border-radius: var(--radius-md); margin-bottom: var(--space-5); -webkit-overflow-scrolling: touch; }
.data-table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: var(--font-size-sm); }
.data-table th, .data-table td { padding: var(--space-3); vertical-align: middle; text-align: left; border-bottom: 1px solid var(--color-border); white-space: nowrap; }
.data-table th { background: var(--color-bg-subtle); font-weight: var(--font-weight-medium); color: var(--color-text-muted); }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--color-bg-subtle); }
.row-link { cursor: pointer; }

/* === 9. Cards, paneles y encabezados de seccion === */
/* Rejilla de paneles. .grid-2 esta hecha para campos, donde el hueco vertical lo pone
   el margen de cada .field; con paneles, que traen su propio margen inferior, los
   canalones quedaban asimetricos: 16 a lo ancho contra 24 a lo alto entre las mismas
   tarjetas. */
/* La fila de cifras que abre el panel.
 *
 * Los numeros grandes con su antetitulo, que es lo que recepcion lee desde el otro lado
 * del mostrador antes de acercarse al plano. auto-fit reacomoda las columnas segun lo
 * que quepa, sin un punto de corte escrito a mano: en escritorio salen los cuatro, en un
 * telefono comun dos, y en uno de 320px uno solo, porque dos columnas de 150 con su
 * canalon no caben en los 288px utiles que deja el contenedor. */
.cifras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.cifra {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
}

.cifra-valor {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* El signo de por ciento no compite con el numero: es la unidad, no el dato. */
.cifra-unidad {
  margin-left: 2px;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-normal);
  color: var(--color-text-muted);
}

.cifra-pie {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

.panel-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-5); }
.panel-grid > .panel { margin-bottom: 0; }
@media (min-width: 768px) { .panel-grid { grid-template-columns: 1fr 1fr; } }
.page-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); }
.page-head h1 { margin: 0; }
.section-title { font-size: var(--font-size-lg); margin-bottom: var(--space-3); }
/* Los iconos toman el tamano del texto que acompanan y su color, asi que no hay que
   declarar ninguno de los dos en cada sitio donde se usen. 1em los deja del alto de una
   mayuscula.
   *
   * `vertical-align` no hace nada en los sitios donde hoy se usan los iconos, porque los
   * tres son contenedores flex (.badge, .antetitulo, .field-error) y ahi manda
   * `align-items`. Se queda como red para el dia que un icono caiga en texto corrido,
   * que es donde si lo centra contra la linea base; el comentario decia que centraba
   * siempre, y eso ya no era cierto.
   *
   * Los atributos de trazo van aqui y no en el sprite porque son heredables: cruzan al
   * contenido referenciado con <use>, que de otro modo no recibe ningun estilo del
   * documento. Sin ellos los iconos se pintan rellenos, como cuadros negros -- eran de
   * trazo y el trazo vivia en el <svg> raiz de cada archivo original. */
.icono {
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Antetitulo en versalitas. Es el recurso que mas distingue un panel de trabajo de una
   pagina de lectura: dice de que es el numero que va abajo sin competir con el. */
.antetitulo {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-1);
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.panel { border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-4); margin-bottom: var(--space-5); background: var(--color-surface); }
.cards { display: grid; grid-template-columns: 1fr; gap: var(--space-3); margin-bottom: var(--space-5); }
@media (min-width: 640px) { .cards { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } }
.card { border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-4); background: var(--color-surface); }
.avail-card { display: flex; flex-direction: column; gap: var(--space-1); }
.avail-name { font-weight: var(--font-weight-medium); }
.avail-count { font-size: var(--font-size-xl); font-weight: var(--font-weight-bold); }
.avail-pending { color: var(--color-warning-700); font-size: var(--font-size-sm); }
.avail-tag { display: inline-block; width: fit-content; padding: 0 var(--space-2); background: var(--color-bg-subtle); color: var(--color-text-muted); border-radius: var(--radius-sm); font-size: var(--font-size-xs); }

/* === 10. Badges de estado === */
.badge { display: inline-flex; align-items: center; gap: var(--space-1); padding: var(--space-1) var(--space-3); border-radius: var(--radius-full); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); white-space: nowrap; }
.badge-success { background: var(--color-success-50); color: var(--color-success-700); }
.badge-warning { background: var(--color-warning-50); color: var(--color-warning-700); }
.badge-danger { background: var(--color-danger-50); color: var(--color-danger-700); }
.badge-info { background: var(--color-info-50); color: var(--color-info-500); }
.badge-muted { background: var(--color-neutral-100); color: var(--color-neutral-600); }

/* === 11. Listas: reservaciones, chips, filtros, detalle, bloqueos === */
.res-list { display: flex; flex-direction: column; gap: var(--space-2); }
.res-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--color-border); }
.res-line:last-child { border-bottom: none; }
.res-guest { display: inline-flex; align-items: center; min-height: 44px; font-weight: var(--font-weight-medium); color: var(--color-text); text-decoration: none; margin-right: auto; }
.res-guest:hover { text-decoration: underline; }
.res-dates { color: var(--color-text-muted); font-size: var(--font-size-sm); }
.chip-list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip { padding: var(--space-1) var(--space-3); background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: var(--radius-full); font-size: var(--font-size-sm); }
.detail-list { display: grid; grid-template-columns: minmax(120px, 180px) 1fr; column-gap: var(--space-4); row-gap: var(--space-2); margin: 0; }
.detail-list dt { color: var(--color-text-muted); font-size: var(--font-size-sm); }
.detail-list dd { margin: 0; }
@media (max-width: 479px) {
  .detail-list { grid-template-columns: 1fr; row-gap: var(--space-1); }
  .detail-list dd { margin-bottom: var(--space-2); }
}
/* El margen existe porque en Comisiones un parrafo sigue al estado vacio y arrancaba
   pegado al borde punteado. Cuando el estado vacio cierra su panel no hace falta: ahi
   se sumaba al padding del panel y dejaba el hueco de abajo al doble que el de arriba. */
.empty { margin-bottom: var(--space-5); padding: var(--space-4); color: var(--color-text-muted); background: var(--color-bg-subtle); border: 1px dashed var(--color-border); border-radius: var(--radius-md); text-align: center; }
.empty:last-child { margin-bottom: 0; }
.filters { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-5); }
/* Los filtros, la casilla de unidad y el enlace de una fila son controles como
   cualquier otro: se tocan con el dedo, y quedaban en 31, 34 y 24 pixeles.
   *
   * 44px no es un incumplimiento que se corrige: el minimo de WCAG 2.2 AA son 24px y
   los tres ya lo pasaban. 44 es el criterio AAA y la medida de la casa, la misma que
   .btn y los inputs. Por eso bajan a 40 en escritorio, igual que ellos: ahi manda el
   raton y la densidad vale mas. */
.filter-chip { display: inline-flex; align-items: center; min-height: 44px; padding: var(--space-1) var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-full); color: var(--color-text); text-decoration: none; font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); }
.filter-chip:hover { background: var(--color-bg-subtle); }
.filter-chip[aria-current="true"] { background: var(--color-primary-500); border-color: var(--color-primary-500); color: var(--color-text-on-primary); }
.block-list { display: flex; flex-direction: column; gap: var(--space-2); }
.block-item { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--color-border); }
.block-item:last-child { border-bottom: none; }
.block-item .btn-link { margin-left: auto; }
.block-note { color: var(--color-text-muted); font-size: var(--font-size-sm); }

/* === 12. Login y formulario publico === */
.login-body, .public-body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-subtle);
  padding: var(--space-5) var(--space-4);
}
.login-card, .public-card {
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
}
.login-card { max-width: 380px; }
.public-card { max-width: 520px; }

/* El logotipo tiene las letras en crema y el contorno oscuro: fue dibujado para
   verse sobre algo oscuro. Puesto sobre la tarjeta clara se sostiene solo de su
   contorno y se ve apagado. Por eso encabeza la tarjeta en una banda del verde
   de la casa, que ademas es el "fondo verde" que el negocio pidio, en el unico
   sitio de estas dos pantallas donde no estorba a la lectura. */
.marca {
  margin: calc(var(--space-6) * -1) calc(var(--space-6) * -1) var(--space-5);
  padding: var(--space-5) var(--space-4);
  background: var(--color-primary-700);
  border-bottom: 3px solid var(--color-accent-500);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  text-align: center;
}
.marca-logo { display: inline-block; width: auto; max-width: 100%; height: 3.25rem; }
@media (min-width: 640px) { .marca-logo { height: 4rem; } }

.login-sub, .public-lead { color: var(--color-text-muted); margin-bottom: var(--space-5); }
.public-thanks { text-align: center; }
.privacy-details { margin-bottom: var(--space-4); font-size: var(--font-size-sm); }
.privacy-details summary { cursor: pointer; color: var(--color-primary-600); font-weight: var(--font-weight-medium); }
.privacy-details p { margin-top: var(--space-2); color: var(--color-text-muted); }

/* === 13. Calendario de ocupacion === */
/* Los tres bloques que anteceden a la rejilla separaban 24, 12 y 16: era la pantalla
   con el ritmo mas quebrado. Van los tres a la medida de bloque de pagina. */
.cal-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-5); }
.cal-nav { display: flex; gap: var(--space-2); }
.cal-range { font-weight: var(--font-weight-medium); margin-right: auto; }
.cal-views { display: flex; gap: var(--space-2); }
.cal-legend { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-bottom: var(--space-5); font-size: var(--font-size-sm); color: var(--color-text-muted); }
.legend-item { display: inline-flex; align-items: center; gap: var(--space-2); }
.swatch { display: inline-block; width: 16px; height: 16px; border-radius: var(--radius-sm); border: 1px solid var(--color-border); }
.calendar { width: 100%; min-width: 640px; font-size: var(--font-size-sm); }
.calendar th, .calendar td { border: 1px solid var(--color-border); }
.cal-corner, .cal-unit { background: var(--color-bg-subtle); padding: var(--space-2) var(--space-3); text-align: left; white-space: nowrap; position: sticky; left: 0; z-index: 1; }
.cal-day { padding: var(--space-2); text-align: center; font-weight: var(--font-weight-medium); background: var(--color-bg-subtle); white-space: nowrap; }
.cal-shared-row .cal-unit { font-style: italic; }
.cal-cell { height: 44px; min-width: 64px; padding: var(--space-1); text-align: center; vertical-align: middle; }
.cell-free { background: var(--color-neutral-0); }
/* El realce al pasar el raton se queda en arena. Si fuera verde claro, una
   celda libre bajo el cursor se veria como una celda vendida a medias. */
.cell-free:hover { background: var(--color-neutral-100); cursor: pointer; }
/* Ocupado se pinta como en el plano: relleno oscuro y letra crema.
 *
 * Antes era un verde palido con borde. Con la marca en verde eso deja la rejilla
 * con dos verdes que significan lo contrario, y el palido es el que el ojo lee
 * como disponible. El calendario y el plano tienen que hablar el mismo idioma,
 * porque recepcion salta de uno al otro todo el dia. */
.cell-reservation {
  background: var(--color-primary-600);
  border: 1px solid var(--color-primary-700) !important;
  color: var(--color-primary-contrast);
  cursor: pointer;
}
.cell-block {
  background-color: var(--color-neutral-200);
  background-image: repeating-linear-gradient(45deg, var(--color-neutral-300) 0, var(--color-neutral-300) 2px, transparent 2px, transparent 8px);
  border: 1px solid var(--color-neutral-400) !important;
}
.cell-label { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); }
.cal-today { box-shadow: inset 0 0 0 2px var(--color-primary-300); }
.availability { margin-top: var(--space-3); padding: var(--space-3); background: var(--color-bg-subtle); border-radius: var(--radius-md); }
.avail-none { margin: 0; color: var(--color-danger-700); }
.avail-hint { margin: 0; color: var(--color-text-muted); }
.units-picker { border: none; padding: 0; margin: 0; }
.units-picker legend { padding: 0; margin-bottom: var(--space-2); }
/* Cuantas unidades de la categoria se pueden tomar de verdad. Va en tono apagado
 * porque es un dato de apoyo, no un estado: el verde del primario esta reservado
 * para lo ocupado, y teñir de verde un "3 libres" diria lo contrario. */
.units-libres { margin-left: var(--space-2); font-size: var(--font-size-xs); font-weight: var(--font-weight-normal); color: var(--color-text-muted); }
/* Etiquetas dentro de la casilla de una unidad.
 *
 * "actual" NO puede llevar el fondo del primario claro: es el mismo que .unit-check usa
 * para la casilla marcada, y como toda unidad actual arranca marcada, la etiqueta se
 * fundia con su propia ficha. Se leia como etiqueta solo cuando el usuario ya la habia
 * desmarcado, que es cuando ya no importaba. Va con fondo propio y borde. */
.unit-actual,
.unit-ocupada {
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
}

.unit-actual {
  background: var(--color-surface);
  border-color: var(--color-primary-300);
  color: var(--color-primary-700);
}

/* Por que una unidad aparece aunque no se pueda tomar. Son tres motivos distintos y la
   casilla los dice con palabras: "ya no esta libre" (alguien se la gano en esas fechas),
   "dada de baja" (inventario la retiro) y "su categoria ya no se ofrece". Comparten
   estilo porque comparten consecuencia: hay que decidir sobre ella antes de guardar.

   Se muestran en vez de ocultarse porque sin casilla el formulario las omitiria al
   enviar y el guardado las soltaria en silencio. */
.unit-ocupada {
  background: var(--color-warning-50);
  border-color: var(--color-warning-500);
  color: var(--color-warning-700);
}
.unit-check { display: inline-flex; align-items: center; min-height: 44px; padding: var(--space-1) var(--space-3); margin: 0 var(--space-2) var(--space-2) 0; border: 1px solid var(--color-border); border-radius: var(--radius-full); font-weight: var(--font-weight-normal); cursor: pointer; }
/* Los tres bajan a 40 en escritorio, como .btn y los inputs. Va despues de sus
   reglas base a proposito: misma especificidad, gana la ultima. */
@media (min-width: 1024px) { .filter-chip, .unit-check, .res-guest { min-height: 40px; } }
.unit-check:has(input:checked) { border-color: var(--color-primary-500); background: var(--color-primary-50); }

/* === 14. Utilidades varias === */
.error-page { text-align: center; padding: var(--space-8) var(--space-4); }
.error-code { font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); color: var(--color-text-muted); margin-bottom: var(--space-2); }
.link-strong { font-weight: var(--font-weight-medium); color: var(--color-primary-600); }
.reset-details summary { cursor: pointer; color: var(--color-primary-600); font-size: var(--font-size-sm); }
.reset-details .inline-form { margin-top: var(--space-2); }
/* La bitacora guarda ids ademas de texto, y un uuid no tiene donde partirse. Las
 * celdas de .data-table van nowrap porque casi todas llevan un dato corto; esta no,
 * asi que renuncia al nowrap y parte donde sea. Sin esto la celda se pasaba de sus
 * 360px a todos los anchos de pantalla, hasta en 1920.
 *
 * El selector lleva `.data-table td` delante a proposito: con `.audit-changes` solo,
 * la regla de la tabla le gana por especificidad y el nowrap se queda. */
.data-table td.audit-changes {
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  max-width: 360px;
  white-space: normal;
  overflow-wrap: anywhere;
}
.action-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.actions-panel .action-row .btn, .actions-panel .action-row .inline { margin: 0; }

/* === Identidad de Rice and Beans ===
 *
 * Lo que sigue es propio de este negocio y no existe en ningun otro sistema.
 * Va al final para que pise los valores de arriba sin tener que editarlos.
 */

/* Titulos con serif: es el rasgo que mas distingue la marca de una plantilla. */
h1, h2, h3,
.public-card h1,
.login-card h1 {
  font-family: var(--font-serif);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* El fondo no es blanco ni gris: es la arena sobre la que se para el verde. */
body {
  background-color: var(--color-neutral-50);
}

/* Las tarjetas se apoyan en el papel, no flotan sobre una sombra azulada. */
.card,
.public-card,
.login-card {
  background-color: var(--color-neutral-0);
  border: 1px solid var(--color-neutral-200);
  box-shadow: 0 1px 2px rgba(22, 21, 15, 0.05);
}

/* Los campos de las pantallas que ve el huesped se quedan en 16px, no en la base densa
 * del panel. Safari en iOS hace zoom al enfocar un campo de menos de 16px, y la pantalla
 * salta sola en mitad de la captura: es el precio de tratar como panel de trabajo algo
 * que alguien llena una sola vez desde su telefono. */
.public-card input,
.public-card select,
.public-card textarea,
.login-card input,
.login-card select,
.login-card textarea { font-size: 1rem; }

/* El formulario publico es lo primero que ve el huesped: se le da aire. */
.public-body {
  background-color: var(--color-neutral-100);
}

/* Sin regla de borde superior: esa linea la dibuja ahora la banda del logotipo
   (.marca), que encabeza tanto el formulario como el acuse y el login. */

/* Lo libre NO va en verde.
 *
 * Antes lo estaba, y funcionaba mientras la marca era terracota. Con la marca
 * en verde, un verde claro para "libre" y un verde oscuro para "ocupada" son el
 * mismo color a dos intensidades: el ojo los agrupa en vez de oponerlos.
 *
 * Lo disponible se marca como en el plano, por ausencia: hueco, con el borde
 * punteado del casillero vacio. Es el mismo idioma en las dos pantallas. */
.avail-card .avail-free {
  color: var(--color-neutral-600);
  font-weight: var(--font-weight-medium);
}

.badge-libre,
.badge-disponible {
  background-color: var(--color-neutral-0);
  border: 1px dashed var(--color-neutral-300);
  color: var(--color-neutral-600);
}

/* El aviso informativo tambien es de la casa: un azul de sistema en medio de
   una paleta sacada del logotipo delata que la hoja no se escribio para aqui. */
.notice,
.info-banner,
.public-card .notice {
  background-color: var(--color-primary-50);
  border-left-color: var(--color-primary-500);
  color: var(--color-neutral-800);
}

/* === El plano del hotel ===
 *
 * Es la pieza donde se concentra el caracter de este panel. Recepcion no lee
 * "3 de 29 dobles libres": busca la 14. Por eso las habitaciones se muestran con
 * su numero real, en una rejilla que se recorre de un vistazo.
 *
 * Deliberadamente NO son tarjetas: son fichas pequenas y densas, como el tablero
 * de llaves que cuelga detras del mostrador. Una habitacion ocupada se ve llena;
 * una libre, hueca. El hueco es lo que se puede vender, asi que es lo que salta.
 */

.plano {
  margin-bottom: var(--space-6);
}

.plano-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--color-neutral-200);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-4);
}

.plano-resumen {
  margin: 0;
  color: var(--color-neutral-600);
  font-size: var(--font-size-sm);
}

.plano-resumen strong {
  font-family: var(--font-serif);
  font-size: var(--font-size-xl);
  color: var(--color-primary-700);
}

.plano-grupo + .plano-grupo {
  margin-top: var(--space-5);
}

.plano-tipo {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-neutral-600);
}

.plano-tipo-cuenta {
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-400);
  font-weight: 400;
}

/* El codigo de la categoria, solo cuando dos se llaman igual y hay que distinguirlas.
 * Va en monoespaciada y apagado: es un identificador interno, no parte del nombre. */
.plano-tipo-codigo {
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-normal);
  color: var(--color-text-muted);
}

.plano-rejilla {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* La ficha: cuadrada, pequena y del mismo tamano siempre, para que la vista
   recorra la fila sin saltos. */
.hab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 3.25rem;
  border-radius: 2px;
  font-variant-numeric: tabular-nums;
  cursor: default;
}

.hab-num {
  font-family: var(--font-serif);
  font-size: var(--font-size-lg);
  line-height: 1;
}

.hab-dato {
  font-size: 0.6875rem;
  line-height: 1.4;
  opacity: 0.75;
}

/* Libre: hueca, con el borde punteado del casillero vacio. */
.hab-libre {
  background-color: var(--color-neutral-0);
  border: 1px dashed var(--color-neutral-300);
  color: var(--color-neutral-500);
}

/* Ocupada: llena, en el verde militar oscuro. El tono mas pesado de la paleta
 * es el que dice "vendida"; el aguacate no aparece aqui a proposito. */
.hab-ocupada {
  background-color: var(--color-primary-600);
  border: 1px solid var(--color-primary-700);
  color: var(--color-primary-contrast);
}

.plano-pendiente {
  margin: var(--space-4) 0 0;
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--color-neutral-300);
  color: var(--color-neutral-600);
  font-size: var(--font-size-sm);
}

@media (max-width: 480px) {
  .hab { width: 3.25rem; height: 2.75rem; }
  .hab-num { font-size: var(--font-size-base); }
}

/* En pantallas que lo pidan, sin transiciones de cortesia. */
@media (prefers-reduced-motion: reduce) {
  /* Cubria solo las casillas del plano, y hay transiciones en el salto al contenido, en
   * los campos de formulario y en el indicador de carga. Quien pide menos movimiento lo
   * pide para toda la pantalla, no para la parte que el autor recordo. */
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* El precio del dia, junto al tipo de habitacion. Se lee al vuelo cuando alguien
   pregunta en el mostrador; por eso vive en el plano y no en otra pantalla. */
.plano-precio {
  margin-left: auto;
  font-family: var(--font-serif);
  font-size: var(--font-size-base);
  color: var(--color-neutral-700);
  font-variant-numeric: tabular-nums;
}

.plano-precio-unidad {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  font-weight: 400;
  color: var(--color-neutral-500);
}

.plano-precio-falta {
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  color: var(--color-warning-700);
}

/* === El costo de la estancia, al capturar ===
 *
 * Quien captura no deberia teclear un total que el sistema ya sabe. El desglose
 * explica de donde sale el numero: si el huesped pregunta por que son 3,900, la
 * respuesta esta en pantalla y no en la cabeza de quien atiende.
 */

.cotizacion {
  margin-bottom: var(--space-4);
}

.cotizacion-tabla {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--space-4);
  font-size: var(--font-size-sm);
}

.cotizacion-tabla th,
.cotizacion-tabla td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-neutral-200);
}

.cotizacion-tabla th[scope="row"] {
  font-weight: 500;
  color: var(--color-neutral-700);
}

.cotizacion-monto {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cotizacion-tabla tfoot th,
.cotizacion-tabla tfoot td {
  border-bottom: none;
  border-top: 2px solid var(--color-neutral-300);
  padding-top: var(--space-3);
}

.cotizacion-total {
  font-family: var(--font-serif);
  font-size: var(--font-size-xl);
  color: var(--color-primary-700);
}

.cotizacion-aviso {
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--color-warning-500);
  background-color: var(--color-warning-50);
  color: var(--color-neutral-800);
  font-size: var(--font-size-sm);
}

/* === Tarifas ===
 *
 * Una rejilla de categorias por temporadas. El precio se escribe donde se lee,
 * sin abrir una pantalla por celda.
 */

.tabla-scroll {
  overflow-x: auto;
  /* Mismo tratamiento que .table-wrap: hasta ahora Tarifas era la unica pantalla donde
     la tabla no se leia como tarjeta y separaba ocho pixeles menos que las demas. */
  contain: paint;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-5);
  -webkit-overflow-scrolling: touch;
}

.tarifas-tabla {
  width: 100%;
  border-collapse: collapse;
}

.tarifas-tabla th,
.tarifas-tabla td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-neutral-200);
  vertical-align: middle;
}

.tarifas-tabla thead th {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-neutral-600);
  border-bottom: 2px solid var(--color-neutral-300);
  white-space: nowrap;
}

.tarifas-tabla tbody th[scope="row"] {
  font-family: var(--font-serif);
  font-size: var(--font-size-base);
  font-weight: 500;
  white-space: nowrap;
}

.tarifas-tabla input {
  width: 7rem;
  font-variant-numeric: tabular-nums;
}

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

.temporada + .temporada {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-neutral-200);
}

/* El nombre de la temporada se edita donde se lee.
 *
 * El campo renuncia al borde y al fondo que la regla global le da a todo input: con
 * ellos, un panel de tres temporadas pasaba de tres titulos a tres cajas de 44px
 * encima de otros dos campos de fecha, y dejaba de leerse como lista. El borde
 * aparece al apuntarlo o al enfocarlo, que es cuando el usuario ya quiere editarlo.
 * El foco visible no se toca: es lo unico que ve quien navega con teclado. */
.temporada-nombre-form {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.temporada-nombre {
  font-family: var(--font-serif);
  font-size: var(--font-size-lg);
  color: var(--color-primary-700);
  flex: 1 1 14rem;
  min-width: 0;
  max-width: 22rem;
  border-color: transparent;
  background: transparent;
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

.temporada-nombre:hover,
.temporada-nombre:focus {
  border-color: var(--color-border);
  background: var(--color-surface);
}

.temporada-nombre[aria-invalid="true"] {
  background: var(--color-surface);
}

.temporada-periodos {
  list-style: none;
  margin: var(--space-1) 0 var(--space-3);
  padding: 0;
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-600);
  font-size: var(--font-size-sm);
}

.temporada-sin-fechas {
  margin: var(--space-1) 0 var(--space-3);
  color: var(--color-warning-700);
  font-size: var(--font-size-sm);
}

/* El formulario de fechas va en una linea: es un gesto rapido, no una pantalla. */
.temporada-form {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.temporada-form label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-neutral-600);
}

/* Alta de una unidad: una linea, no una pantalla. Dar de alta una mesa es una
   operacion de todos los dias, no un cambio de sistema. */
.alta-unidad {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  background-color: var(--color-neutral-50);
  border: 1px dashed var(--color-neutral-300);
  border-radius: 2px;
}

.alta-unidad .field {
  margin-bottom: 0;
}

.alta-unidad input,
.alta-unidad select {
  min-width: 8rem;
}

/* === Restaurante ===
 *
 * El servicio de la noche se lee por hora, no por mesa: lo que el personal
 * pregunta es "que sigue", no "que pasa con la mesa 3".
 */

.dia-selector {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
}

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

.reserva-mesa {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

/* La hora manda: es lo primero que se busca al recorrer la lista. */
.reserva-hora {
  font-family: var(--font-serif);
  font-size: var(--font-size-lg);
  font-variant-numeric: tabular-nums;
  color: var(--color-primary-700);
  min-width: 8.5rem;
}

.reserva-mesa-nombre {
  min-width: 6rem;
  color: var(--color-neutral-600);
  font-size: var(--font-size-sm);
}

.reserva-huesped {
  flex: 1;
}

.reserva-personas {
  margin-left: var(--space-2);
  color: var(--color-neutral-500);
  font-size: var(--font-size-sm);
}

/* Una reserva liberada se queda a la vista, apagada: el personal necesita saber
   que la mesa se solto, no que la reserva nunca existio. */
.reserva-mesa-cancelada {
  opacity: 0.55;
}

.reserva-mesa-cancelada .reserva-huesped,
.reserva-mesa-cancelada .reserva-hora {
  text-decoration: line-through;
}

.reserva-estado {
  font-size: var(--font-size-sm);
  color: var(--color-neutral-500);
}

@media (max-width: 640px) {
  .reserva-mesa { flex-wrap: wrap; gap: var(--space-2); }
}

.cotizacion-unidades {
  margin-left: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 400;
  color: var(--color-neutral-500);
}

/* === Comisiones de plataformas ===
 *
 * La tabla no usa color para marcar nada. Una estancia sin monto capturado se
 * dice con texto debajo del conteo, no tiñendo la fila: el verde de esta marca
 * ya significa "ocupado" en el plano, y un segundo significado lo vuelve ruido.
 */
.comision-monto {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.comision-nota {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
}

.comisiones-tabla tfoot th,
.comisiones-tabla tfoot td {
  border-bottom: none;
  border-top: 2px solid var(--color-neutral-300);
}

.comision-total {
  font-weight: var(--font-weight-bold);
}

/* Un dato que se muestra dentro de un formulario pero no se edita. Se dibuja con el
   peso de un valor, no con el de un control: un input deshabilitado invita a pelearse
   con el. */
/* El nombre de un dato que se muestra sin control que lo edite. No es <label>: una
   etiqueta sin control al que apuntar se lee como texto suelto en un lector de
   pantalla. */
.etiqueta-fija {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Imita un input de solo lectura, asi que se le parece tambien en la caja: sin esto
   media 37px junto a un input de 44 y su texto arrancaba doce pixeles a la izquierda
   del texto del campo de al lado, en la misma fila. */
.valor-fijo {
  display: flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  padding: var(--space-2) 0;
  font-weight: var(--font-weight-medium);
}
/* El sangrado solo tiene sentido cuando de verdad hay un input al lado con el que
   alinearse: es el ancho al que .grid-2 se vuelve de dos columnas. Debajo de eso la
   rejilla colapsa y el sangrado dejaba tres bordes izquierdos distintos dentro del
   mismo campo -- etiqueta, valor y ayuda. */
@media (min-width: 768px) { .valor-fijo { padding-inline: var(--space-3); } }
/* Y el mismo par que los inputs, que bajan a 40 para raton. Sin esto media 44 junto a
   uno de 40 y quedaba desalineado por el otro lado. */
@media (min-width: 1024px) { .valor-fijo { min-height: 40px; } }

/* Indicadores de peticion de HTMX.
 *
 * HTMX inyecta estas reglas como una etiqueta <style> en linea, y la CSP de este
 * sistema solo permite hojas propias: el navegador las rechazaba y el indicador no
 * aparecia nunca. Se apaga esa inyeccion con la meta htmx-config y las reglas viven
 * aqui, que es donde la politica si las admite. */
.htmx-indicator {
  opacity: 0;
  transition: opacity var(--transition-base);
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}
