/* La app: lista de plantillas, galería, generar, plan, claves, docs y login.

   Los tokens, la tipografía, los botones y la cabecera vienen de base.css —
   los MISMOS que la landing. Acá va sólo lo propio de estas pantallas.

   No toca static/css/editor-modelo.css: la geometría de hoja del editor está
   atada al @page del PDF (motor/nucleo/pagina.py) y se rompe si se la mueve. */

.contenido {
  /* El aire de arriba, como variable: el editor lo cancela para que su
     cabecera quede pegada al navbar en vez de dejar una franja blanca. */
  --pad-arriba: clamp(1.75rem, 4vw, 3rem);

  max-width: 68rem;
  margin: 0 auto;
  padding: var(--pad-arriba) var(--canal) 4rem;
}
.contenido-ancho { max-width: 82rem; }

/* ── Encabezado de pantalla ─────────────────────────────────────────────── */

.pagina-cab {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin-bottom: 1.75rem;
}
.pagina-cab h1 {
  margin: 0;
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -.03em;
}
.pagina-cab p { margin: .4rem 0 0; color: var(--cuerpo); font-size: .98rem; }

h2 { font-size: 1.25rem; font-weight: 650; letter-spacing: -.02em; }

/* ── Formularios ────────────────────────────────────────────────────────── */

label { display: block; font-size: .88rem; font-weight: 550; margin-bottom: .3rem; }

/* `search` faltaba en esta lista, así que el buscador de la galería y el de
   /modelos/ NO tomaban ninguno de estos estilos: se dibujaban con el control
   nativo del sistema —en Chrome de macOS, una píldora con su propio borde
   oscuro— y encima se les pegaba el radio y el padding de `.buscador input`.
   Por eso se veía como un campo pegado de otra página. */
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], input[type="tel"],
input:not([type]), select, textarea {
  width: 100%;
  padding: .6rem .75rem;
  border: 1px solid var(--raya);
  border-radius: 8px;
  background: var(--blanco);
  color: var(--tinta);
  font-family: inherit;
  font-size: .95rem;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--verde);
  box-shadow: 0 0 0 3px var(--verde-tenue);
}
textarea { min-height: 5rem; resize: vertical; }
input[type="file"] { font-size: .9rem; }

.campo { margin-bottom: 1rem; }
.campo-linea { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.campo-linea input { width: auto; flex: 1; min-width: 12rem; }

.ayuda { margin: .35rem 0 0; font-size: .84rem; color: var(--apagado); }
.error { color: #B3261E; font-size: .88rem; }

/* ── Tarjetas y paneles ─────────────────────────────────────────────────── */

.tarjeta {
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  padding: 1.5rem 1.6rem 1.7rem;
}
.tarjeta + .tarjeta { margin-top: 1.25rem; }
.tarjeta h2 { margin-top: 0; }

.grilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); gap: 1.25rem; }

/* Caja centrada: login, registro, recuperar contraseña. */
.tarjeta-centro {
  max-width: 25rem;
  margin: clamp(1.5rem, 6vh, 4rem) auto;
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-media);
  padding: 2rem 1.9rem 2.1rem;
}
.tarjeta-centro h1 { margin: 0 0 .4rem; font-size: 1.5rem; font-weight: 700; letter-spacing: -.03em; }
.tarjeta-centro .intro { margin: 0 0 1.5rem; color: var(--cuerpo); font-size: .95rem; }
.tarjeta-centro .boton { width: 100%; margin-top: .5rem; }
.tarjeta-centro .pie-caja { margin: 1.25rem 0 0; font-size: .9rem; color: var(--cuerpo); text-align: center; }
.tarjeta-centro a { color: var(--verde); font-weight: 550; }

/* ── Lista de plantillas ────────────────────────────────────────────────── */

.lista {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  overflow: hidden;
}
.fila {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .95rem 1.15rem;
}
.fila + .fila { border-top: 1px solid var(--raya); }
.fila:hover { background: var(--lienzo); }
.fila form { margin: 0; }
.fila-nombre { font-weight: 600; color: inherit; text-decoration: none; letter-spacing: -.01em; }
.fila-nombre:hover { color: var(--verde); }
.fila-detalle { color: var(--apagado); font-size: .85rem; }
.fila .ms-auto, .ms-auto { margin-left: auto; }

.etiqueta {
  padding: .12rem .5rem;
  border-radius: 5px;
  background: var(--lienzo);
  color: var(--apagado);
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.etiqueta-viva { background: var(--verde-tenue); color: var(--verde); }

.vacio {
  padding: 3rem 1.5rem;
  text-align: center;
  color: var(--cuerpo);
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
}

/* ── Tablas ─────────────────────────────────────────────────────────────── */

.tabla { width: 100%; border-collapse: collapse; font-size: .92rem; }
.tabla th {
  text-align: left;
  padding: .5rem .7rem;
  border-bottom: 1px solid var(--raya);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--apagado);
}
.tabla td { padding: .65rem .7rem; border-bottom: 1px solid var(--raya); }
.tabla tr:last-child td { border-bottom: 0; }
.tabla form { margin: 0; }
.fila-apagada td { color: var(--apagado); }

/* ── Avisos ─────────────────────────────────────────────────────────────── */

.aviso {
  display: flex;
  align-items: center;
  gap: .7rem;
  flex-wrap: wrap;
  padding: .85rem 1.1rem;
  margin: 1.25rem 0;
  border-radius: 10px;
  background: var(--verde-tenue);
  color: #0B5C3E;
  font-size: .9rem;
}
.aviso input { flex: 1; min-width: 15rem; font-family: var(--mono); font-size: .82rem; }
.aviso-atencion { background: #FDF3E4; color: #7A4A11; }
.aviso-error { background: #FBEAE9; color: #8C1D18; }

/* ── Plan y uso ─────────────────────────────────────────────────────────── */

.plan-actual { display: flex; align-items: center; gap: .7rem; margin-bottom: 1rem; }
.plan-nombre { font-size: 1.3rem; font-weight: 700; letter-spacing: -.02em; }
.barra-uso { height: 8px; border-radius: 5px; background: var(--lienzo); overflow: hidden; margin-top: .6rem; }
.barra-uso-relleno { height: 100%; border-radius: 5px; background: var(--verde); }
.barra-uso-relleno.barra-llena { background: #B3261E; }
.precio-grande { font-size: 2rem; font-weight: 700; letter-spacing: -.035em; margin: .25rem 0; }

/* ── Galería (miniaturas reales) ────────────────────────────────────────────
   La hoja mide sus 210mm y se achica con transform; como transform NO achica la
   caja de layout, los márgenes negativos la dejan del tamaño visual. La
   tipografía la inyecta la vista con css_contenido(prefijo=".galeria-hoja ").
   Misma geometría que el PDF: no tocar. */

/* El buscador de la galería: un campo, sin filtros. El input no se estira a
   todo el ancho —a 68rem, un campo de búsqueda de una palabra se ve absurdo. */
.buscador {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: 1.25rem 0 1.5rem;
}

/* La lupa vive ADENTRO del campo. El botón «Buscar» de al lado sobra en cuanto
   el filtro corre al tipear: se esconde por JS, así que sin JavaScript sigue
   estando y sigue siendo el único camino. */
.buscador-campo {
  position: relative;
  display: flex; align-items: center;
  flex: 0 1 24rem; min-width: 12rem;
}
.buscador-lupa {
  position: absolute; left: .85rem;
  color: var(--apagado); pointer-events: none;
}
.buscador input {
  width: 100%;
  /* Píldora. El radio de 8px del resto de los inputs es para un campo dentro de
     un formulario; éste está suelto arriba de una grilla y se lee mejor como
     un control redondo. */
  border-radius: 999px;
  padding: .65rem 1rem .65rem 2.5rem;
}
/* `textfield` y no `none`: saca el marco nativo del control de búsqueda pero
   CONSERVA la crucecita de limpiar, que es de donde sale el evento `search`
   que escucha buscador.js. Con `none` desaparecen las dos cosas. */
.buscador input[type="search"] { -webkit-appearance: textfield; appearance: textfield; }
/* La crucecita, redibujada. La nativa sale en el color de acento del SISTEMA
   —azul en macOS— y arriba de un campo con foco verde se lee como si fuera de
   otra página. Se apaga la nativa y se pinta la misma equis del sprite con una
   máscara, así hereda `color` y queda en el gris del resto del campo.

   Sigue siendo el botón nativo, sólo repintado: el clic sigue disparando el
   evento `search` que escucha buscador.js. */
.buscador input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: .8rem;
  height: .8rem;
  margin-right: .2rem;
  cursor: pointer;
  background: var(--apagado);
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M4 4l8 8M12 4l-8 8'/%3E%3C/svg%3E");
  mask-repeat: no-repeat;
  mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M4 4l8 8M12 4l-8 8'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: contain;
}
.buscador input::-webkit-search-cancel-button:hover { background: var(--tinta); }
.buscador-vivo .buscador-campo { flex-basis: 26rem; }

.grilla-galeria { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 1.25rem; }
.tarjeta-galeria {
  display: flex;
  flex-direction: column;
  /* Para que `.enlace-extendido` del botón se estire sobre la tarjeta entera
     y no sobre el <body>: un absoluto se ancla al ancestro posicionado más
     cercano. La tarjeta ES el botón. */
  position: relative;
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  overflow: hidden;
  transition: transform .18s cubic-bezier(.3,.7,.4,1), box-shadow .18s;
}
.tarjeta-galeria:hover { transform: translateY(-3px); box-shadow: var(--sombra-alta); }

.galeria-preview {
  position: relative;
  height: 12.5rem;
  background: #EDEFEE;
  border-bottom: 1px solid var(--raya);
  overflow: hidden;
  padding-top: .85rem;
  pointer-events: none;
  user-select: none;
  display: flex;
  justify-content: center;
}
.galeria-preview::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 3rem;
  background: linear-gradient(to bottom, transparent, #EDEFEE 92%);
}
.galeria-hoja {
  --hoja-ancho: 210mm;
  --galeria-escala: .34;

  width: var(--hoja-ancho);
  min-height: var(--hoja-alto, 297mm);
  padding: 16mm 14mm;
  background: var(--blanco);
  box-shadow: 0 2px 8px rgba(23, 23, 26, .13);
  transform: scale(var(--galeria-escala));
  transform-origin: top center;
  flex: 0 0 auto;
  margin: 0 calc(var(--hoja-ancho) * (var(--galeria-escala) - 1) / 2);
}
.galeria-info { padding: 1rem 1.1rem 1.2rem; }
.galeria-info h2 { margin: 0 0 .3rem; font-size: 1.06rem; font-weight: 650; }
.galeria-info p { margin: 0 0 .9rem; font-size: .9rem; color: var(--cuerpo); line-height: 1.5; }
.galeria-info form { margin: 0; }
.galeria-agregada { margin: 0; padding: .45rem 0; font-size: .85rem; color: var(--verde); font-weight: 550; }

/* ── Docs ───────────────────────────────────────────────────────────────── */

/* La medida del texto corrido. El contenedor sigue en 46rem porque el código
   y las tablas necesitan ese ancho, pero a 46rem un párrafo mide ~92
   caracteres por renglón: al volver al margen izquierdo el ojo salta tan lejos
   que releer o saltear un renglón se vuelve habitual. No duele una vez, duele
   acumulado — y acá vive la lectura más larga del producto (términos,
   privacidad y la referencia de la API).

   68ch cae dentro del rango cómodo (45–75) y va en `ch` y no en `rem` para que
   la medida siga a la tipografía: si cambia la fuente o el cuerpo, el renglón
   se sigue cortando donde corresponde. Se aplica al TEXTO, no al contenedor,
   justamente para no angostar los bloques de código ni las tablas. */
.pagina-docs { max-width: 46rem; }
.pagina-docs > p,
.pagina-docs > ul,
.pagina-docs > ol,
.pagina-docs .docs-lista,
.pagina-docs .docs-intro { max-width: 68ch; }
.pagina-docs h2 { margin-top: 2.25rem; max-width: 34ch; }
.docs-intro { font-size: 1.05rem; color: var(--cuerpo); }
.docs-lista { line-height: 1.7; }
.bloque-codigo {
  margin: 1rem 0;
  padding: 1.1rem 1.25rem;
  border-radius: var(--radio);
  background: var(--tinta);
  color: #DCDCE2;
  font-family: var(--mono);
  font-size: .8rem;
  line-height: 1.65;
  overflow-x: auto;
}
.pagina-docs code {
  padding: .1em .35em;
  border-radius: 4px;
  background: var(--lienzo);
  font-family: var(--mono);
  font-size: .88em;
}
.pagina-docs .bloque-codigo code { background: none; padding: 0; }
.separador-docs { border: 0; border-top: 1px solid var(--raya); margin: 2.5rem 0; }
.tabla-docs { width: 100%; border-collapse: collapse; font-size: .9rem; }
.tabla-docs th {
  text-align: left; padding: .5rem .7rem; border-bottom: 1px solid var(--raya); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--apagado);
}
.tabla-docs td { padding: .6rem .7rem; border-bottom: 1px solid var(--raya); }

/* ── Clases que ya usaban los templates ─────────────────────────────────────
   Se conservan sus nombres en vez de renombrar 12 archivos: lo que cambia es
   que ahora se dibujan con los tokens de base.css, los mismos que la landing. */

.barra-usuario { font-size: .85rem; color: var(--apagado); }

/* ── La pantalla de entrada: elegir con qué generar ──────────────────────────
   Es donde cae el login. Está armada alrededor de UNA acción —generar— y no
   del CRUD: la tarjeta entera es el botón, editar es un link chico y borrar
   vive detrás del «···». Antes esto era una lista de nombres donde «Generar»
   pesaba lo mismo que «Borrar». */

.cabecera-app {
  display: flex; align-items: end; justify-content: space-between;
  gap: 1.25rem 2rem; flex-wrap: wrap; margin-bottom: 1.75rem;
}
.cabecera-app h1 { margin: 0 0 .3rem; font-size: clamp(1.6rem, 3vw, 2.1rem); font-weight: 700; letter-spacing: -.03em; }
.cabecera-app p { margin: 0; }

.cabecera-uso { min-width: 12rem; }
.uso-cifra { font-size: 1.25rem; font-weight: 700; letter-spacing: -.02em; }
.uso-de { font-size: .95rem; font-weight: 500; color: var(--apagado); }
.cabecera-uso .texto-suave { margin-left: .35rem; }
.cabecera-uso .barra-uso { margin-top: .45rem; }

.grilla-plantillas { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 1.25rem; }

.tarjeta-plantilla {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  overflow: hidden;
  transition: transform .18s cubic-bezier(.3,.7,.4,1), box-shadow .18s;
}
.tarjeta-plantilla:hover { transform: translateY(-3px); box-shadow: var(--sombra-alta); }
/* Inactiva: se ve apagada pero sigue siendo generable — el estado no esconde
   la acción, sólo la baja de tono. */
.tarjeta-apagada .galeria-preview { opacity: .5; }

.previa-vacia { align-self: center; margin-top: 3.5rem; color: var(--apagado); font-size: .85rem; }

.tarjeta-cuerpo { display: flex; flex-direction: column; flex: 1; padding: .95rem 1.1rem 1.05rem; }
.tarjeta-titulo {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin: 0 0 .2rem; font-size: 1.06rem; font-weight: 650; letter-spacing: -.01em;
}
.tarjeta-detalle { margin: 0 0 .9rem; font-size: .85rem; color: var(--apagado); }

.tarjeta-acciones { display: flex; align-items: center; gap: .75rem; margin-top: auto; }
.tarjeta-acciones form { margin: 0; }

/* El link que se estira sobre la tarjeta entera: clickeable toda, pero un solo
   link en el árbol de accesibilidad (de ahí el aria-label con el nombre). Lo
   que va por encima —Editar, «···»— sube con z-index. */
.enlace-extendido::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.tarjeta-acciones > .accion-secundaria,
.tarjeta-acciones > .menu-mas { position: relative; z-index: 1; }

/* Sin esto la tarjeta PARPADEA, y el motivo no se ve mirando la pantalla.
   `.boton:hover` levanta el botón con translateY(-1px), y un `transform`
   convierte al elemento en bloque contenedor de sus descendientes absolutos.
   O sea que al pasar el cursor, el ::after de acá arriba deja de medirse
   contra la tarjeta y se encoge al rectángulo del botón. Entonces: el cursor
   entra en el ::after → el botón queda en :hover → el ::after se encoge → el
   cursor ya no está sobre nada → se va el :hover → el ::after vuelve a
   estirarse → y otra vez. Es un lazo que se realimenta solo mientras el cursor
   esté sobre la tarjeta y fuera del botón.
   El link extendido no necesita ese movimiento: el que da la respuesta visual
   es el `translateY(-3px)` de la tarjeta entera. */
.enlace-extendido:hover { transform: none; }

.accion-secundaria { font-size: .88rem; color: var(--apagado); text-decoration: none; }
.accion-secundaria:hover { color: var(--tinta); text-decoration: underline; }

/* El menú «···»: <details>, sin JS. */
.menu-mas { margin-left: auto; }
.menu-mas > summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: .2rem .5rem; border-radius: 6px; line-height: 1;
  color: var(--apagado); font-weight: 700; letter-spacing: .05em;
}
.menu-mas > summary::-webkit-details-marker { display: none; }
.menu-mas > summary:hover { background: var(--lienzo); color: var(--tinta); }
.menu-mas-panel {
  position: absolute; right: .6rem; bottom: 2.6rem; z-index: 2;
  min-width: 9rem; padding: .3rem;
  background: var(--blanco); border-radius: 9px;
  box-shadow: var(--sombra-alta);
}
.menu-mas-panel button {
  display: block; width: 100%; padding: .5rem .6rem;
  border: 0; border-radius: 6px; background: none;
  color: var(--tinta); font: inherit; font-size: .88rem; text-align: left; cursor: pointer;
}
.menu-mas-panel button:hover { background: var(--lienzo); }
.menu-mas-panel .opcion-peligro { color: #B3261E; }
.menu-mas-panel .opcion-peligro:hover { background: #FCEEED; }

.form-inline { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.form-inline input { width: auto; min-width: 13rem; }

/* Debajo de la grilla, los otros dos caminos para sumar una plantilla. */
.otros-caminos { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--raya); }
.otros-caminos .importar { margin-bottom: .9rem; }
.otros-caminos p { margin: 0; }

/* La hoja en blanco: PRIMERA de la grilla, con o sin plantillas propias. Misma
   forma y tamaño que las demás —es un camino más, no el consuelo del que no
   encontró nada—, con el punteado como única señal de que ésta no viene hecha.
   Es un <form>, así que necesita el reset de margen que un <article> no pide. */
.tarjeta-en-blanco { margin: 0; outline: 2px dashed var(--raya); outline-offset: -2px; box-shadow: none; }
.tarjeta-en-blanco:hover { box-shadow: var(--sombra-baja); }
.tarjeta-en-blanco .galeria-preview { background: var(--lienzo); }
.tarjeta-en-blanco .galeria-preview::after { background: linear-gradient(to bottom, transparent, var(--lienzo) 92%); }
/* El botón se estira sobre la tarjeta entera, igual que el «Generar» de las
   otras: sin esto sólo sería clickeable el rectángulo del botón. */
.tarjeta-en-blanco .enlace-extendido { position: static; }

.etiqueta-inactiva {
  padding: .12rem .5rem; border-radius: 5px; background: var(--lienzo); color: var(--apagado); font-size: .66rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
}

/* Texto secundario, usado en casi todas las pantallas */
.texto-suave { color: var(--apagado); font-size: .88rem; }
.descripcion { color: var(--cuerpo); font-size: .95rem; }

/* Claves de API */
.aviso-clave {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .85rem 1.1rem; margin: 1.25rem 0; border-radius: 10px;
  background: var(--verde-tenue); color: #0B5C3E; font-size: .9rem;
}
.aviso-clave input { flex: 1; min-width: 15rem; font-family: var(--mono); font-size: .82rem; }
.tabla-claves { width: 100%; border-collapse: collapse; font-size: .92rem; margin-top: 1.25rem; }
.tabla-claves th {
  text-align: left; padding: .5rem .7rem; border-bottom: 1px solid var(--raya); font-size: .68rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--apagado);
}
.tabla-claves td { padding: .65rem .7rem; border-bottom: 1px solid var(--raya); }
.tabla-claves form { margin: 0; }
.clave-revocada td { color: var(--apagado); }

/* Plan, checkout y tiers */
.tarjeta-plan, .tarjeta-checkout, .tarjeta-generar {
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja); padding: 1.5rem 1.6rem 1.7rem;
}
.tarjeta-plan, .tarjeta-checkout { max-width: 30rem; margin-top: 1.25rem; }
.tarjeta-plan h2, .tarjeta-checkout h2, .tarjeta-generar h2 { margin-top: 0; }
.plan-uso { margin-bottom: 1.25rem; font-size: .95rem; }
.etiqueta-pro {
  padding: .12rem .5rem; border-radius: 5px; background: var(--verde-tenue); color: var(--verde); font-size: .66rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
}
.checkout-precio { font-size: 2rem; font-weight: 700; letter-spacing: -.035em; margin: .25rem 0; }
.checkout-detalle { padding-left: 1.1rem; font-size: .93rem; color: var(--cuerpo); line-height: 1.7; }
.banda-mock {
  padding: .6rem .9rem; margin-bottom: 1.25rem; border-radius: 8px;
  background: #FDF3E4; color: #7A4A11; font-size: .85rem; font-weight: 550;
}
/* ── Los tres pasos hasta el primer documento ───────────────────────────────
   No es un tour ni un popup: es una lista que se lee de un vistazo y se tacha
   sola. Desaparece para siempre cuando el primer documento sale. */
.primeros-pasos {
  margin-bottom: 1.5rem; padding: 1.2rem 1.4rem 1.3rem;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
}
.primeros-pasos h2 { font-size: 1rem; font-weight: 650; margin-bottom: .9rem; }
.primeros-pasos ol { list-style: none; margin: 0; padding: 0; }

.paso { display: flex; align-items: flex-start; gap: .75rem; padding: .4rem 0; }
.paso-marca {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; flex: none; border-radius: 50%;
  background: var(--lienzo); color: var(--apagado);
  font-size: .78rem; font-weight: 650;
}
.paso-hecho .paso-marca { background: var(--verde-tenue); color: var(--verde); }
.paso-txt { min-width: 0; }
.paso-txt strong { display: block; font-size: .92rem; font-weight: 600; }
.paso-txt .texto-suave { display: block; line-height: 1.45; }
/* El paso hecho baja de tono, no se tacha: una línea tachada se lee como
   «esto ya no vale» y lo que pasó es lo contrario. */
.paso-hecho .paso-txt strong { color: var(--apagado); font-weight: 500; }

/* ── Los tres caminos para sumar una plantilla ──────────────────────────────
   «¿Ya tenés el documento hecho?» vivía al pie de la grilla y no nombraba nada:
   no decía si hablaba del Excel, del PDF o de la plantilla. Ahora los tres
   están arriba, a la misma altura y llamados por lo que hacen. */
.caminos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1rem; margin-bottom: 1rem;
}

.camino {
  display: flex; align-items: flex-start; gap: .8rem;
  margin: 0; padding: 1rem 1.1rem;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  color: inherit; text-decoration: none;
  transition: box-shadow .18s;
}
.camino:hover { box-shadow: var(--sombra-media); }
.camino .ic-caja {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 2.4rem; flex: none; border-radius: .6rem;
  background: var(--verde-tenue); color: var(--verde);
}
.camino-txt { flex: 1; min-width: 0; }
.camino-txt h3 { font-size: .95rem; font-weight: 650; letter-spacing: -.01em; }
.camino-txt p { margin: .2rem 0 0; font-size: .82rem; color: var(--apagado); line-height: 1.45; }

/* Las dos grandes: cuadradas, con el contenido apilado y el botón abajo. En
   verde TENUE y no en el verde pleno de los botones primarios — abajo de esto
   están los lotes, y la acción de todos los días es generar. Dos tarjetas
   gritando «creá una plantilla» le ganarían el pulso a lo que el cliente
   viene a hacer. */
.camino-grande {
  flex-direction: column; align-items: flex-start; gap: .9rem;
  min-height: 12rem; padding: 1.5rem 1.6rem;
  background: var(--verde-tenue);
  box-shadow: none;
}
.camino-grande:hover { box-shadow: var(--sombra-media); }
.camino-grande .ic-caja {
  width: 3rem; height: 3rem; border-radius: .75rem;
  background: var(--blanco); color: var(--verde);
}
.camino-grande .camino-txt { flex: 1; }
.camino-grande h3 { font-size: 1.15rem; letter-spacing: -.02em; }
.camino-grande p { margin-top: .3rem; font-size: .9rem; color: var(--cuerpo); max-width: 34ch; }
/* Más específico que `.camino > .boton`, que centra: en las grandes el botón
   va alineado con el texto, no flotando en el medio de la tarjeta. */
.caminos .camino-grande > .boton { align-self: flex-start; }

/* El tercero es más chico a propósito: es el menos usado, y depende de que el
   OCR esté disponible. */
.camino-chico { margin-bottom: 1rem; }
.camino-chico .camino-txt { flex: 1 1 16rem; }
.camino-chico input[type="file"] { width: auto; font-size: .78rem; }

/* Generar con una plantilla que ya tenés. Tranquilo y no chico: es la acción
   de todos los días, pero quien ya tiene lotes abajo sabe llegar. */
.fila-generar-existente {
  margin: 0 0 2rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--raya);
}
.camino > .boton { flex: none; align-self: center; }
/* El de subir necesita el input, así que su botón baja al renglón siguiente. */
.camino-subir { flex-wrap: wrap; }
.camino-subir input[type="file"] { width: auto; margin-top: .6rem; font-size: .78rem; }
.camino-subir > .boton { margin-left: auto; }

/* ── La espera del lote ─────────────────────────────────────────────────────
   Subir 200 filas dejaba el navegador en blanco varios segundos, y ahí lo
   natural es recargar: justo lo peor que se puede hacer con un POST que ya
   está corriendo. La capa no acelera nada — acompaña. */
.espera {
  position: fixed; inset: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center;
  padding: var(--canal);
  background: rgba(242, 247, 244, .82);
  backdrop-filter: saturate(140%) blur(3px);
}
.espera-caja {
  max-width: 26rem; text-align: center;
  padding: 2.2rem 2rem 2rem;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-alta);
}
.espera-rueda {
  display: block; width: 2.2rem; height: 2.2rem; margin: 0 auto 1.1rem;
  border-radius: 50%;
  border: 3px solid var(--verde-tenue);
  border-top-color: var(--verde);
  animation: girar-espera .9s linear infinite;
}
@keyframes girar-espera { to { transform: rotate(360deg); } }

.espera-que { margin: 0; font-size: 1.05rem; font-weight: 650; letter-spacing: -.02em; }
/* El renglón de la frase tiene alto FIJO: sin esto la caja pega un salto cada
   vez que cambia a una frase de otro largo. */
.espera-frase {
  margin: .5rem 0 0; min-height: 1.5rem;
  font-size: .95rem; color: var(--verde); font-weight: 550;
}
.espera-aguante {
  margin: 1.25rem 0 0; padding-top: 1rem;
  border-top: 1px solid var(--raya);
  font-size: .85rem; color: var(--apagado); line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
  /* Se va el giro, NO el texto: la frase que cambia es la que dice que algo
     sigue pasando, y es justo lo que hay que conservar. */
  .espera-rueda { animation: none; border-top-color: var(--verde-tenue); }
  .espera { backdrop-filter: none; }
}

/* ── La home: lo que generaste, y a dónde fue ───────────────────────────────
   Era «elegí una plantilla», con los lotes en una lista al pie. Está al revés
   de cómo se usa: el que vuelve el martes viene a mirar el lote del lunes. */

/* La acción de todos los días, sola y arriba. Si la grilla es de lotes,
   generar uno nuevo no puede quedar detrás de «ver plantillas». */
.fila-primaria {
  display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
  padding-bottom: 1.6rem; margin-bottom: 1.6rem;
  border-bottom: 1px solid var(--raya);
}
.fila-primaria .boton { padding: .8rem 1.5rem; font-size: .97rem; }
.enlace-segundo {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .9rem; color: var(--cuerpo); text-decoration: none; padding: .5rem 0;
}
.enlace-segundo:hover { color: var(--tinta); }
.sep-punto { color: var(--raya); }

.rotulo-seccion { display: flex; align-items: baseline; gap: .75rem; margin-bottom: .9rem; }
.rotulo-seccion h2 { font-size: 1.05rem; font-weight: 650; }
/* Sólo un ENLACE se va a la derecha. Con `> :last-child` a secas, cuando el
   rótulo es lo único que hay, el propio <h2> se comía el auto y el título
   quedaba alineado a la derecha. */
.rotulo-seccion > a:last-child { margin-left: auto; }

.grilla-lotes { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 1.25rem; }
.tarjeta-lote {
  position: relative; display: flex; flex-direction: column;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja); overflow: hidden;
  transition: transform .18s cubic-bezier(.3,.7,.4,1), box-shadow .18s;
}
.tarjeta-lote:hover { transform: translateY(-3px); box-shadow: var(--sombra-alta); }
.tarjeta-lote .tarjeta-titulo { font-size: 1.02rem; }
.tarjeta-lote .tarjeta-detalle { margin-bottom: .35rem; }
.tarjeta-envio {
  display: flex; align-items: center; gap: .35rem;
  margin: 0 0 .85rem; font-size: .82rem; color: var(--verde); font-weight: 550;
}
/* Ámbar y no rojo: que falten tres correos de cien es un pendiente, no un
   error de la pantalla. Mismo criterio que la fecha de borrado. */
.tarjeta-envio.parcial { color: var(--comunicacion); }
.icono-accion {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: 7px; color: var(--apagado);
  box-shadow: inset 0 0 0 1px var(--raya);
}
.icono-accion:hover { color: var(--tinta); background: var(--lienzo); }

/* ── Envíos, agrupados por lote ─────────────────────────────────────────────
   Es lo que se mira cuando un cliente pregunta si le llegó. Agrupa por lote y
   no es una lista plana porque nadie se acuerda de un envío suelto: se acuerda
   de «las facturas de agosto». */
.envios { margin-top: 2.5rem; }
.grupo-envios {
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja); overflow: hidden; margin-bottom: .75rem;
}
.grupo-cab {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  padding: .75rem 1.15rem; box-shadow: 0 1px 0 var(--raya);
}
.grupo-cab .nombre { font-weight: 600; font-size: .95rem; }
.grupo-cab .cuando { font-size: .82rem; color: var(--apagado); }
.grupo-cab .resumen { margin-left: auto; font-size: .84rem; color: var(--cuerpo); }
.grupo-cab .fallados { color: var(--comunicacion); font-weight: 600; }

.envio-fila {
  display: flex; align-items: center; gap: .9rem;
  padding: .6rem 1.15rem; box-shadow: 0 1px 0 var(--lienzo); font-size: .88rem;
}
.envio-fila .icono { flex: none; color: var(--apagado); line-height: 0; }
.envio-fila .dir {
  flex: 1; min-width: 0; font-family: var(--mono); font-size: .78rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.envio-fila .doc {
  width: 11rem; flex: none; color: var(--cuerpo);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.envio-fila .hora { width: 3rem; flex: none; font-family: var(--mono); font-size: .78rem; color: var(--apagado); }
.envio-fila .est { width: 6rem; flex: none; font-size: .82rem; color: var(--verde); }
.envio-fila .est.mal { color: var(--comunicacion); font-weight: 600; }
.envio-fila .est.pendiente { color: var(--apagado); }
.grupo-pie { margin: 0; padding: .65rem 1.15rem; font-size: .85rem; }
.grupo-pie a { display: inline-flex; align-items: center; gap: .35rem; color: var(--verde); font-weight: 550; }

/* ── Generar: los campos a la izquierda, el documento a la derecha ──────────
   Antes eran dos tarjetas lado a lado —«un documento» y «varios desde un CSV»—
   y el documento no se veía en ningún lado. Se llenaban siete campos a ciegas,
   y el único camino para mirar el resultado era un link que decía «Editar esta
   plantilla»: otra pantalla y otro trabajo.

   El ancho de la columna derecha (31,4rem = 502px) NO es libre: la caja
   descuenta su propio padding y quedan 470px, que es el número del que sale la
   escala en motor/views.py (_ANCHO_PREVIA_GENERAR_PX). Si cambia uno, cambia
   el otro o la hoja deja de entrar. */
.generar-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 31.4rem;
  gap: 1.75rem;
  align-items: start;
  margin-top: 1.5rem;
}
.generar-col { min-width: 0; }

/* La fila del título comparte grilla con la de abajo, así el rótulo «Vista
   previa» cae justo encima de la hoja y no flotando en el medio. `end` alinea
   por la base: el h1 es grande y el rótulo chico, y alineados por arriba el
   rótulo quedaba colgado. */
.generar-cab {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 31.4rem;
  gap: 1.75rem;
  align-items: end;
}

@media (max-width: 68rem) {
  /* La previa PRIMERO: en una pantalla angosta lo que se quiere ver es el
     documento, y la columna de campos es larga. Mismo criterio que el lote.

     El rótulo queda debajo del h1 y arriba de la hoja, que sigue siendo su
     lugar: no hace falta duplicarlo ni esconderlo. */
  .generar-grid, .generar-cab { grid-template-columns: 1fr; }
  .generar-cab { gap: .5rem; }
  .generar-previa { order: -1; }
}

.tarjeta-generar h2 { margin-bottom: .25rem; }
.tarjeta-generar .sub { margin: 0 0 1.1rem; font-size: .86rem; color: var(--apagado); }

/* ── Las tres vías, como acordeón ───────────────────────────────────────────
   Eran tres bloques apilados y abiertos: para llegar a la planilla había que
   pasar por los siete campos del formulario y scrollear hasta abajo. Ahora los
   tres títulos entran juntos arriba de todo.

   Es `<details>`, no JavaScript — el mismo mecanismo que el menú «···» de las
   tarjetas de plantilla. */
.via {
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  overflow: hidden;
}
.via + .via { margin-top: .75rem; }
.via[open] { box-shadow: var(--sombra-media); }

.via-cab {
  display: flex; align-items: center; gap: .8rem;
  padding: .95rem 1.15rem;
  cursor: pointer; user-select: none;
  /* El triangulito del navegador se va: se dibuja distinto en cada uno y
     tenemos el nuestro a la derecha. */
  list-style: none;
}
.via-cab::-webkit-details-marker { display: none; }
.via-cab:hover { background: var(--lienzo); }
.via[open] .via-cab { box-shadow: 0 1px 0 var(--raya); }
.via[open] .via-cab:hover { background: var(--blanco); }

.via-ic {
  flex: none; color: var(--verde);
}
.via-txt { flex: 1; min-width: 0; }
.via-titulo { display: block; font-size: 1.02rem; font-weight: 650; letter-spacing: -.015em; }
.via-nota { display: block; font-size: .82rem; color: var(--apagado); margin-top: .1rem; }

.via-flecha { flex: none; color: var(--apagado); transition: transform .18s; }
.via[open] .via-flecha { transform: rotate(180deg); }

.via-cuerpo, .via .soltar { padding: 1.1rem 1.2rem 1.3rem; }

/* La zona de soltar ya no es la tarjeta: la tarjeta es el <details>. Le queda
   sólo el punteado de «acá se suelta». */
.via .soltar {
  margin: .9rem 1.2rem 1.2rem;
  padding: 1.5rem 1.25rem;
  box-shadow: none;
}
.via .enlace-publico {
  margin: 0; padding: 1.1rem 1.2rem 1.3rem;
  background: none; box-shadow: none;
  display: block;
}

/* El formato y el botón en el mismo renglón: el select mide seis caracteres y
   estirado a todo el ancho se leía como si fuera un campo más del documento. */
.fila-generar { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; }
.fila-generar .campo-formato { flex: 0 0 9.5rem; margin-bottom: 0; }

/* «se repite» al lado de la etiqueta del campo. Es la misma palabra que usa el
   editor desde que «lista» resultó no querer decir nada para nadie. */
.chip-repite {
  margin-left: .4rem; padding: .05rem .4rem; border-radius: 4px;
  background: var(--verde-tenue); color: var(--verde);
  font-size: .68rem; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; vertical-align: 1px;
}

/* ── Soltar la planilla ─────────────────────────────────────────────────── */
.soltar {
  display: flex; flex-direction: column; align-items: center; gap: .55rem;
  margin-top: 1.25rem; padding: 1.9rem 1.5rem;
  border-radius: var(--radio); background: var(--blanco);
  outline: 2px dashed var(--raya); outline-offset: -2px;
  text-align: center;
  transition: outline-color .15s, background-color .15s;
}
/* Mientras el archivo está encima. Sin señal, soltar es un acto de fe. */
.soltar-encima { outline-color: var(--verde); background: var(--verde-tenue); }
.soltar .ic-caja {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; border-radius: .7rem;
  background: var(--verde-tenue); color: var(--verde);
}
.soltar h2 { font-size: 1.05rem; }
.soltar-ayuda { margin: 0; max-width: 56ch; font-size: .85rem; color: var(--apagado); line-height: 1.5; }
/* `nowrap` es lo que sostiene el orden. Con `wrap`, flexbox decide el corte de
   línea ANTES de encoger a nadie: si el grupo «control + nombre» no dejaba
   lugar, mandaba «Generar lote» al renglón de abajo — o sea, abajo y a la
   IZQUIERDA del nombre del archivo. Sin envolver, el que cede es el grupo (el
   nombre se corta con puntos suspensivos) y el botón se queda donde va. */
.soltar-acciones {
  display: flex; align-items: center; justify-content: center;
  gap: .75rem; flex-wrap: nowrap; margin-top: .5rem;
  max-width: 100%;
}
/* El control nativo de archivo dice «Seleccionar archivo · Sin archivos
   seleccionados» con la tipografía del SISTEMA, y al lado de los botones del
   sitio se lee como un pedazo de otra página. `::file-selector-button` le da
   la forma de nuestros botones sin esconderlo: sigue siendo el input de
   siempre, así que el teclado y el lector de pantalla no pierden nada. */
/* `font-size: 0` esconde el texto nativo («Sin archivos seleccionados», y
   después el nombre del archivo) y con eso el control colapsa al ancho de su
   propio botón. El nombre lo dibuja el span de al lado, que sí se puede
   acortar con puntos suspensivos: el input nativo no. */
.soltar-acciones input[type="file"] {
  width: auto;
  font-size: 0;
}
/* El grupo «control + nombre». `min-width: 0` es lo que le da permiso a
   encoger: sin él, un hijo flex nunca baja de su ancho de contenido y la fila
   envuelve en vez de achicarse. */
.soltar-elegido {
  display: inline-flex; align-items: center; gap: .6rem;
  flex: 0 1 auto; min-width: 0;
}
.soltar-nombre {
  min-width: 0; max-width: 13rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--mono); font-size: .78rem; color: var(--verde);
}
.soltar-acciones > .boton { flex: none; }
.soltar-invitacion { font-size: .95rem; color: var(--cuerpo); max-width: 30ch; }
.soltar-modelo { margin: .8rem 0 0; }
/* La regla del punto y coma, donde se la busca: al lado de la planilla modelo,
   que es lo que se mira cuando se está ARMANDO el archivo, no soltándolo. */
.soltar-regla {
  display: block; margin-top: .35rem;
  font-size: .78rem; color: var(--apagado); line-height: 1.45;
}

/* El botón del enlace y su acuse. La pastilla ocupa lugar desde el principio
   (`visibility`, no `display`) para que al aparecer no empuje al botón. */
.enlace-acciones { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin: 0; }
.pastilla-copiado {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .3rem .7rem; border-radius: 999px;
  background: var(--verde-tenue); color: var(--verde);
  font-size: .82rem; font-weight: 600;
  animation: aparecer-pastilla .18s ease-out;
}
@keyframes aparecer-pastilla {
  from { opacity: 0; transform: translateX(-4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pastilla-copiado { animation: none; }
}
.enlace-a-mano { margin: .75rem 0 0; font-size: .85rem; color: var(--comunicacion); }
.enlace-a-mano .url-publica { margin-top: .35rem; display: block; flex: none; width: 100%; }
.soltar-acciones input[type="file"]::file-selector-button {
  margin-right: 0;
  padding: .55rem 1rem;
  border: 0;
  border-radius: 7px;
  background: var(--blanco);
  color: var(--tinta);
  box-shadow: inset 0 0 0 1px var(--raya), var(--sombra-baja);
  font-family: inherit;
  font-size: .88rem;
  font-weight: 550;
  cursor: pointer;
}
.soltar-acciones input[type="file"]::file-selector-button:hover { background: var(--lienzo); }

/* ── El enlace público, a la vista ──────────────────────────────────────────
   Existía desde antes, escondido en un menú del editor. El dueño mismo no lo
   tenía presente: eso no es una función que falta, es una que no se encuentra. */
.enlace-publico {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin-top: 1.25rem; padding: .9rem 1.1rem;
  background: var(--blanco); border-radius: var(--radio); box-shadow: var(--sombra-baja);
}
.enlace-publico .ic-caja {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.1rem; height: 2.1rem; flex: none; border-radius: .5rem;
  background: var(--operaciones-tenue); color: var(--operaciones);
}
.enlace-publico-txt { flex: 1 1 14rem; }
.enlace-publico-txt strong { display: block; font-size: .92rem; }
.enlace-publico form { margin: 0; }
.url-publica {
  flex: 1 1 16rem; width: auto;
  font-family: var(--mono); font-size: .78rem; color: var(--operaciones);
  background: var(--lienzo);
}

/* ── La previa ──────────────────────────────────────────────────────────────
   `sticky` para que la hoja siga estando al llegar al final de una lista larga
   de campos: sin esto, el que llena el último dato ya no ve el documento. */
/* `sticky` para que la hoja siga estando al llegar al final de una lista larga
   de campos: sin esto, el que llena el último dato ya no ve el documento.

   El `max-height` NO es decorativo. Un elemento sticky más ALTO que la ventana
   se pega del borde de abajo, no del de arriba: la hoja subía fuera de
   pantalla y el que escribía «Cliente» ya no veía dónde caía el nombre. Con la
   altura acotada el panel entra siempre, y la hoja scrollea adentro. */
.generar-previa {
  position: sticky; top: 1.25rem;
  display: flex; flex-direction: column; gap: .55rem;
  max-height: calc(100vh - 2.5rem);
}
/* El rótulo salió de acá y subió a la fila del título; sin margen propio, la
   hoja arranca exactamente a la altura del acordeón. */
.generar-cab .previa-rotulo { padding-bottom: .35rem; }
.generar-previa .hoja-caja {
  min-height: 0;              /* sin esto, flex no la deja achicarse */
  overflow-y: auto;
  align-items: flex-start;
}
/* Centrado sobre la hoja y no pegado a la izquierda: el rótulo titula la
   columna entera, así que alineado al borde parecía colgar de la nada. */
.generar-cab .previa-rotulo { justify-content: center; }
.previa-rotulo {
  display: flex; align-items: center; gap: .5rem;
  font-size: .72rem; font-weight: 600; letter-spacing: .08em;
  color: var(--apagado); text-transform: uppercase;
}
.previa-rotulo .vivo {
  margin-left: auto; display: inline-flex; align-items: center; gap: .4rem;
  text-transform: none; letter-spacing: 0; font-weight: 500;
  font-size: .78rem; color: var(--verde);
}
.punto-vivo { width: .45rem; height: .45rem; border-radius: 50%; background: var(--verde); }
/* El aviso de la previa: la caja del sitio, pero con la lista adentro. */
#previa-avisos { margin: 0; align-items: flex-start; }
#previa-avisos .ic { margin-top: .15rem; }
#previa-avisos .avisos-lista { margin: 0; }

/* Centrado bajo la hoja: es un pie de foto, no una línea de la columna. */
.previa-pie { margin: 0; text-align: center; }
.previa-pie a { color: var(--verde); font-weight: 550; }

/* ── El medidor de uso ──────────────────────────────────────────────────────
   Es el protagonista de /facturacion/ a propósito: el que entra casi siempre
   viene a ver cuánto le queda, no a comprar. La comparación de planes va
   después, para cuando la respuesta a eso es «poco». */
.medidor {
  /* Todo el ancho del contenedor, no una tarjeta angosta: así se lee como un
     medidor y no como una tarjeta más de la página. */
  margin-top: 1.25rem; padding: 1.4rem 1.6rem 1.5rem;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
}
/* Cifra a la izquierda, cuánto queda a la derecha, la barra cruzando abajo:
   la forma de una barra de progreso. */
.medidor-cab {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.medidor-cifra {
  margin: 0; font-size: 2.6rem; line-height: 1; font-weight: 700;
  letter-spacing: -.04em;
  /* Los dígitos alineados: sin esto la cifra «salta» de ancho al cambiar. */
  font-variant-numeric: tabular-nums;
}
.medidor-de { margin-left: .3rem; font-size: 1.35rem; color: var(--apagado); font-weight: 550; }
.medidor-rotulo {
  margin-left: .6rem; font-size: .95rem; font-weight: 400; color: var(--apagado);
  letter-spacing: normal;
}
.medidor-resto { margin: 0; font-size: 1rem; color: var(--cuerpo); }
.medidor .barra-uso { margin-top: 1rem; height: 12px; }
.medidor-letra { margin: .9rem 0 0; font-size: .85rem; }
/* Sin cuota, la cifra se tiñe: el número es el dato, no el cartel de al lado. */
.medidor-lleno .medidor-cifra { color: #B3261E; }

.acciones-plan { margin-top: 1rem; }
.acciones-plan form { display: inline; margin: 0; }

/* ── El panel de planes: título, selector y tabla en UN rectángulo ──────────
   Son una sola cosa —elegir plan— y sueltos se leían como tres bloques. */
.panel-planes {
  margin-top: 2.5rem; padding: 1.4rem 1.6rem 1.6rem;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
}
/* Tres columnas para que el título quede centrado en el PANEL y no en el
   espacio que le deja el selector: con flex, el título se corre a la izquierda
   tanto como mida el toggle. */
.planes-cab {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: .75rem;
}
.planes-cab .titulo-planes { grid-column: 2; }
.planes-cab .ciclo { grid-column: 3; justify-self: end; margin: 0; }
.titulo-planes {
  margin: 0; text-align: center;
  font-size: .78rem; font-weight: 650; letter-spacing: .12em;
  text-transform: uppercase; color: var(--apagado);
}
.panel-planes .tabla-planes-scroll { margin-top: 1.25rem; }
.panel-planes .tabla-planes tfoot td,
.panel-planes .tabla-planes tfoot th { border-bottom: 0; }
.planes-pie { margin: 1.1rem 0 0; font-size: .85rem; }

/* En pantalla angosta el selector no entra al lado del título: pasa abajo, y
   el título deja de necesitar las tres columnas. */
@media (max-width: 34rem) {
  .planes-cab { grid-template-columns: 1fr; }
  .planes-cab .titulo-planes, .planes-cab .ciclo { grid-column: 1; }
  .planes-cab .ciclo { justify-self: center; }
}

/* ── La tabla de planes ─────────────────────────────────────────────────────
   Tabla y no tarjetas: cuatro planes con varios atributos son datos
   tabulares, y en tarjetas hay que escanear de costado para comparar dos
   columnas que no están pegadas. */
.tabla-planes-scroll { overflow-x: auto; margin-top: 1.5rem; }
.tabla-planes {
  width: 100%; min-width: 34rem; border-collapse: collapse; font-size: .93rem;
}
.tabla-planes th, .tabla-planes td {
  padding: .7rem .8rem; text-align: left; border-bottom: 1px solid var(--raya);
}
.tabla-planes thead th {
  font-size: .8rem; font-weight: 650; letter-spacing: .04em;
  text-transform: uppercase; color: var(--apagado);
}
.tabla-planes tbody th { font-weight: 550; }
.tabla-planes .num { text-align: right; font-variant-numeric: tabular-nums; }
.tabla-planes thead th:not(:first-child),
.tabla-planes tfoot td { text-align: right; }
.tabla-planes tfoot td, .tabla-planes tfoot th { border-bottom: 0; padding-top: 1rem; }
.tabla-planes .moneda { font-size: .72em; color: var(--apagado); margin-right: .15rem; }
.tabla-planes .fila-precio td { font-weight: 650; }
/* La columna del plan que ya tenés, marcada con fondo y no con un borde
   lateral: una franja de color al costado desalinea la celda del resto. */
.tabla-planes .col-actual { color: var(--verde); }
.etiqueta-ahorro {
  margin-left: .35rem; padding: .1rem .4rem; border-radius: 5px;
  background: var(--verde-tenue); color: var(--verde);
  font-size: .68rem; font-weight: 650; letter-spacing: .04em;
  text-transform: uppercase; white-space: nowrap;
}

/* Para lectores de pantalla: encabezados que la tabla necesita y que
   visualmente sobran (la columna de características no lleva título). */
/* .visualmente-oculto se mudó a base.css: la landing no carga esta hoja y
   también la necesita. base.css la cargan las tres plantillas con <head>
   propio, así que es el único lugar donde una sola definición alcanza. */

/* Avisos de desajuste: los mismos en el editor y en la confirmación del lote.
   Ámbar y no rojo a propósito — el documento se genera igual, así que no es un
   error, es algo que conviene mirar. */
.avisos-lista { margin: 0; padding-left: 1.1rem; }
.avisos-lista li { margin: .35rem 0; line-height: 1.45; color: #454a4f; }
.avisos-lista li::marker { color: #b98900; }

/* Los botones de la pantalla de confirmación: generar igual, o ir a arreglarlo. */
.fila-acciones {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  margin-top: 1.25rem;
}
.fila-acciones form { margin: 0; }

/* Generar */
.campo-generar { display: block; margin-bottom: 1rem; font-size: .88rem; font-weight: 550; }
.campo-generar input, .campo-generar textarea,
.campo-generar select { margin-top: .3rem; font-weight: 400; }
.campo-generar textarea { min-height: 4.5rem; }

/* Login, registro, recuperar contraseña, formulario no disponible */
.tarjeta-login {
  max-width: 25rem; margin: clamp(1.5rem, 6vh, 4rem) auto;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-media); padding: 2rem 1.9rem 2.1rem;
}
.tarjeta-login h1 { margin: 0 0 1.25rem; font-size: 1.5rem; font-weight: 700; letter-spacing: -.03em; }
.tarjeta-login label { margin-bottom: 1rem; font-weight: 550; }
.tarjeta-login input { margin-top: .3rem; }
.tarjeta-login .boton { width: 100%; margin-top: .5rem; }

/* «Contraseña» a la izquierda y «¿La olvidaste?» a la derecha, en el mismo
   renglón: el input baja entero abajo (de ahí el 100% de ancho en la fila). */
.tarjeta-login .label-con-enlace {
  display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap;
}
.tarjeta-login .label-con-enlace input { flex: 0 0 100%; }
.enlace-menor { font-size: .82rem; font-weight: 450; color: var(--apagado); }
.enlace-menor:hover { color: var(--verde); }
/* La salida dentro del propio error: el que falla la contraseña es el que la
   necesita. El :not(.boton) importa — sin él, un botón dentro de un error
   hereda el color del texto de error y queda oscuro sobre oscuro. */
.error a:not(.boton) { color: inherit; font-weight: 600; }

/* La fila de vuelta de /generar: volver a la izquierda, editar a la derecha. */
/* La fila de «volver». Va en gris y SIN subrayado, en todo el sitio.
   Subrayada y en tinta competía con el título que tiene abajo: es orientación
   —dónde estás y de dónde venís—, no una acción que alguien vino a hacer. El
   subrayado se reserva para los enlaces dentro de texto corrido, que es donde
   de verdad hace falta para distinguirlos. */
.volver-fila { display: flex; gap: 1.25rem; align-items: baseline; flex-wrap: wrap; }
.volver-fila .texto-suave { margin-left: auto; }
.volver-fila a {
  display: inline-flex; align-items: center; gap: .35rem;
  color: var(--apagado); text-decoration: none; font-size: .88rem;
}
.volver-fila a:hover { color: var(--tinta); }

/* El error de CUOTA no es un error más: es el momento de conversión, así que
   lleva su propia caja con la salida adentro. */
.error-cuota {
  padding: 1.1rem 1.25rem;
  border-radius: var(--radio);
  background: #FDF3E4;
  color: #7A4A11;
}
.error-cuota p { margin: 0 0 .5rem; }
.error-cuota .texto-suave { color: inherit; opacity: .8; }
.error-cuota .boton { margin-top: .35rem; }

/* Formulario público (lo ve alguien sin cuenta) */
.form-publico { max-width: 34rem; margin: clamp(1.5rem, 6vh, 4rem) auto; }
.campo-web { display: block; margin-bottom: 1.1rem; font-size: .9rem; font-weight: 550; }
.campo-web input, .campo-web textarea { margin-top: .3rem; font-weight: 400; }
.barra-dueno {
  padding: .6rem .9rem; margin-bottom: 1.25rem; border-radius: 8px;
  background: #FDF3E4; color: #7A4A11; font-size: .85rem;
}
.pie-marca { margin-top: 2rem; text-align: center; font-size: .84rem; color: var(--apagado); }

/* ── Páginas de modelo (SEO) ────────────────────────────────────────────────
   Una por plantilla. El H1 es «Modelo de factura» porque es literalmente lo
   que se busca en español. La hoja se muestra grande: es el argumento. */

/* ── El índice de modelos ───────────────────────────────────────────────────
   Dos columnas, y cada ficha se abre con la miniatura del documento. La grilla
   de antes eran diecisiete rectángulos de texto: para saber cuál era el que
   buscabas había que leerlos uno por uno, en un producto cuya única promesa es
   que el documento ya está armado.

   Dos y no tres: a tres columnas la miniatura queda del tamaño de un sello y
   deja de cumplir su trabajo, que es distinguir una factura de un remito sin
   leer el título. */
/* El encabezado, el buscador y la grilla comparten UN borde izquierdo. Con
   tres anchos distintos —36rem el texto, 54 el buscador, 62 las fichas— la
   página arrancaba escalonada y nada se leía como una columna. */
.art.art-indice { max-width: 62rem; margin: 0 auto; }
.art.art-indice .art-bajada { max-width: 32rem; margin-top: 1.1rem; }
.buscador-ancho { max-width: 62rem; margin: 2rem auto 2.5rem; }
#buscador-vacio { max-width: 62rem; margin-inline: auto; }

.fichas {
  display: grid;
  /* DOS columnas fijas, no `auto-fit`. Con auto-fit, filtrar hasta un solo
     resultado colapsa la segunda pista y esa ficha se estira a los 62rem: la
     miniatura queda flotando en el medio de un rectángulo enorme. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem) clamp(1.5rem, 3vw, 2.5rem);
  max-width: 62rem;
  margin: 0 auto;
}
@media (max-width: 46rem) {
  .fichas { grid-template-columns: minmax(0, 1fr); }
  .ficha-previa { height: 13rem; }
}
.ficha { margin: 0; }

/* La miniatura. Sin marco ni sombra: la hoja YA es un rectángulo blanco con su
   propia sombra, y meterla adentro de una tarjeta la dibuja dos veces. */
.ficha-previa {
  position: relative;
  display: flex;
  justify-content: center;
  height: 15rem;
  overflow: hidden;
  border-radius: var(--radio);
  background: #EDEFEE;
  padding-top: 1.25rem;
  transition: box-shadow .18s;
}
.ficha-previa::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 4.5rem;
  background: linear-gradient(to bottom, transparent, #EDEFEE 92%);
}
.ficha:hover .ficha-previa { box-shadow: var(--sombra-media); }
.ficha-previa .hoja-real { --escala: .42; }
.ficha-sin-previa {
  align-self: center;
  font-size: .85rem;
  color: var(--apagado);
}

.ficha-texto { padding-top: 1.15rem; }
.ficha-familia {
  margin: 0 0 .45rem;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--fam, var(--apagado));
}
.ficha-texto h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.42rem;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.2;
}
/* El enlace del título se estira sobre la ficha entera: así la miniatura y el
   botón son clickeables sin repetir el <a> tres veces, y el lector de pantalla
   escucha un solo enlace con el nombre del modelo. */
.ficha-texto h2 a { text-decoration: none; }
.ficha-texto h2 a::after { content: ""; position: absolute; inset: 0; }
.ficha { position: relative; }
.ficha-detalle { margin: .5rem 0 0; color: var(--cuerpo); line-height: 1.6; }
.ficha-datos { margin: .6rem 0 0; font-size: .82rem; color: var(--apagado); }
.ficha-boton { margin-top: 1.1rem; }
.ficha:hover .ficha-boton { box-shadow: inset 0 0 0 1px var(--raya), var(--sombra-media); }

/* ── La página de un modelo, con forma de artículo ─────────────────────────
   Una columna con medida de lectura, y la hoja saliéndose de esa medida. La
   grilla de dos columnas de antes dejaba un hueco muerto entre el texto y la
   hoja, y no le daba al artículo ninguna jerarquía propia: sus h2 se dibujaban
   igual que los del producto.

   La medida es la decisión de fondo. `--medida` da unos 68 caracteres por
   renglón con el cuerpo a 1.08rem, que es donde el ojo salta de línea sin
   perderse. Antes eran 46rem de ancho a 1rem: más de noventa. */
.art {
  --medida: 36rem;
  --ancho-hoja-hero: 54rem;
  max-width: var(--medida);
  margin: 0 auto;
}

/* El ojo: el rótulo chiquito y espaciado que abre cada bloque. Es lo que dice
   «acá empieza otra cosa» sin gastar una raya ni un título. */
.art-ojo {
  margin: 0 0 .7rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--fam, var(--apagado));
}

.art-cab { padding-top: clamp(1rem, 4vw, 2.5rem); }
.art-cab h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(2.1rem, 4.4vw, 3.1rem);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.08;
}
/* La línea de datos. Los puntos separadores son ::before de cada hermano, así
   que no hay que dibujar un separador de más al final. */
.art-meta {
  display: flex;
  flex-wrap: wrap;
  margin: 1.1rem 0 0;
  font-size: .82rem;
  color: var(--apagado);
}
.art-meta span + span::before { content: "·"; margin: 0 .55rem; opacity: .55; }

/* ── La hoja como imagen de apertura ─────────────────────────────────────────
   Se sale de la medida del texto: es el gesto editorial de siempre, y acá
   además es lo único que muestra el producto. `margin-inline` negativo y no un
   contenedor aparte, para no romper el flujo del artículo. */
.art-hero {
  width: min(var(--ancho-hoja-hero), 100vw - 2.5rem);
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  margin-inline: calc((var(--medida) - min(var(--ancho-hoja-hero), 100vw - 2.5rem)) / 2);
}
.art-hoja {
  position: relative;
  height: 22rem;
  overflow: hidden;
  border-radius: var(--radio);
  background: #EDEFEE;
  box-shadow: var(--sombra-baja);
  padding-top: 1.5rem;
  display: flex;
  justify-content: center;
  pointer-events: none;
  user-select: none;
}
.art-hoja::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 5rem;
  background: linear-gradient(to bottom, transparent, #EDEFEE 92%);
}
.art-hero figcaption {
  margin-top: .7rem;
  font-size: .78rem;
  color: var(--apagado);
  line-height: 1.5;
}

/* Misma mecánica de siempre: la hoja mide 210mm y se achica con transform; los
   márgenes negativos dejan la caja del tamaño visual. No tocar la geometría. */
.hoja-real {
  --ancho-hoja: 210mm;
  --escala: .62;

  width: var(--ancho-hoja);
  min-height: 297mm;
  padding: 16mm 14mm;
  background: var(--blanco);
  box-shadow: 0 2px 12px rgba(23, 23, 26, .16);
  transform: scale(var(--escala));
  transform-origin: top center;
  flex: 0 0 auto;
  margin: 0 calc(var(--ancho-hoja) * (var(--escala) - 1) / 2);
}

/* ── El cuerpo ──────────────────────────────────────────────────────────── */
.art-cuerpo { margin-top: clamp(2rem, 4vw, 2.75rem); }

/* La bajada: serif, grande, oscura. Es el único párrafo que lee todo el mundo
   y separa el título del cuerpo sin gastar una raya. */
.art-bajada {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.34rem;
  line-height: 1.45;
  letter-spacing: -.005em;
  color: var(--tinta);
}

.art-cuerpo h2 {
  margin: 2.75rem 0 .85rem;
  font-family: var(--serif);
  font-size: 1.55rem;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.2;
}
.art-cuerpo p {
  margin: 0 0 1.15rem;
  font-size: 1.08rem;
  line-height: 1.72;
  color: var(--cuerpo);
}

.art-cta { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin: 1.9rem 0 0; }
.art-cta .ayuda { margin: 0; }
.art-cta-pie { margin-top: 2.75rem; }

/* La ficha de datos: la pausa visual del artículo. Es el lugar que en un
   artículo ocupa la cita destacada, y acá lleva contenido de verdad — los
   tokens son lo que hace útil la plantilla. */
.art-ficha {
  margin: 2.75rem 0 0;
  padding: 1.3rem 1.5rem 1.5rem;
  border-radius: var(--radio);
  background: var(--lienzo);
}
.art-ficha h2 {
  margin: 0 0 .9rem;
  font-family: var(--display);
  font-size: .95rem;
  font-weight: 650;
  letter-spacing: 0;
}
.campos { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .45rem; }
.campos li {
  padding: .28rem .65rem;
  border-radius: 6px;
  background: var(--blanco);
  color: var(--fam, var(--cuerpo));
  font-family: var(--mono);
  font-size: .78rem;
  font-weight: 550;
}

/* ── Las preguntas ──────────────────────────────────────────────────────────
   <dl> y no h3 + p: es una lista de definiciones, y así el lector la reconoce
   como bloque de consulta en vez de leerla como más artículo. Cada par va
   separado por una línea de pelo. */
.art-faq { margin-top: 3rem; padding-top: 1.75rem; border-top: 1px solid var(--raya); }
.art-faq dl { margin: 0; }
.art-faq dt {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--raya);
  font-family: var(--serif);
  font-size: 1.14rem;
  font-weight: 600;
  line-height: 1.35;
}
.art-faq dt:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
.art-faq dd {
  margin: .55rem 0 0;
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--cuerpo);
}

/* «Otros modelos» cierra el artículo. Va a un ancho mayor que la medida de
   lectura —son tarjetas, no texto— pero con la raya arriba y el ojo, para que
   se lea como el pie del artículo y no como otra pantalla de la app. */
.otros {
  max-width: 54rem;
  margin: clamp(3rem, 6vw, 4.5rem) auto 0;
  padding-top: 2rem;
  border-top: 1px solid var(--raya);
}
.otros h2 {
  margin: 0 0 1.25rem;
  font-family: var(--serif);
  font-size: 1.55rem;
  font-weight: 600;
  letter-spacing: -.015em;
}
.otros-todos { margin-top: 1.25rem; }
.otros-todos a { display: inline-flex; align-items: center; gap: .4rem; color: var(--verde); font-weight: 550; }
.otros-grilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1rem; }
.otro {
  display: block;
  padding: 1.15rem 1.25rem 1.3rem;
  border-radius: var(--radio);
  background: var(--blanco);
  box-shadow: var(--sombra-baja);
  text-decoration: none;
  transition: transform .16s cubic-bezier(.3,.7,.4,1), box-shadow .16s;
}
.otro:hover { transform: translateY(-2px); box-shadow: var(--sombra-media); }
/* La familia se marca con un punto delante del nombre. Antes era un
   border-left de 3px del color de la familia: esa franja lateral de color es
   un tic de plantilla, y además desalineaba el texto de esta tarjeta respecto
   de todas las demás por los 3px del borde. */
.otro strong {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .25rem;
  font-size: 1.02rem;
  letter-spacing: -.015em;
}
.otro strong::before {
  content: "";
  width: .45rem;
  height: .45rem;
  flex: none;
  border-radius: 50%;
  background: var(--fam, var(--verde));
}
.otro span { font-size: .9rem; color: var(--cuerpo); }

.fam-cobro        { --fam: var(--cobro);        --fam-tenue: var(--cobro-tenue); }
.fam-operaciones  { --fam: var(--operaciones);  --fam-tenue: var(--operaciones-tenue); }
.fam-legales      { --fam: var(--legales);      --fam-tenue: var(--legales-tenue); }
.fam-comunicacion { --fam: var(--comunicacion); --fam-tenue: var(--comunicacion-tenue); }

/* ── Adaptación ─────────────────────────────────────────────────────────── */

@media (max-width: 40rem) {
  .barra .solo-ancho { display: none; }
  /* La marca no se parte en dos renglones. Con el botón «Menú» al lado,
     «Genera Informes» caía en dos líneas y estiraba la barra al doble de
     alto. A 390 px entra entera: ~140 px de marca, 74 del menú y 132 del
     CTA. */
  .marca { font-size: .9rem; gap: .45rem; white-space: nowrap; }

  /* Ergonomía de formularios en el teléfono.

     Medido en producción: el botón «Crear cuenta» daba 289×33 px y los inputs
     15,2 px. Dos problemas distintos:

     · 33 px de alto es el botón más importante del embudo y el más chico de
       la página. El mínimo de iOS es 44 y el de Android 48.
     · Safari en iOS hace zoom automático al enfocar cualquier input de menos
       de 16 px, y como el viewport no fija `maximum-scale`, el zoom se queda:
       tocás «Email», la página salta, y el botón se va de cuadro.

     El arreglo es el tamaño de fuente, NO `maximum-scale`: fijarlo apagaría
     el pinch zoom para todos, que es una regresión de accesibilidad a cambio
     de tapar el síntoma. */
  .tarjeta-login input,
  .tarjeta-login button,
  .tarjeta-login .boton,
  .form-publico input,
  .form-publico textarea,
  .form-publico button {
    min-height: 44px;
    font-size: 16px;
  }
  .barra .boton-chico { padding: .5rem .85rem; font-size: .78rem; }
  .contenido { padding-top: 1.5rem; }
  .pagina-cab { align-items: start; }
  .fila { flex-wrap: wrap; }
  .grilla-galeria, .grilla-plantillas { grid-template-columns: minmax(0, 1fr); }
  .cabecera-app { align-items: start; }
  .art-hero { margin-inline: 0; width: 100%; }
  .art-hoja { height: 18rem; }
  .art-hoja .hoja-real { --escala: .40; }
  .art-bajada { font-size: 1.16rem; }
  .galeria-hoja { --galeria-escala: .30; }
  .galeria-preview { height: 10rem; }
  .pie-nav { margin-left: 0; }
}

/* Importar una plantilla desde un documento ya hecho (OCR). Va debajo del
   encabezado de la lista y sólo aparece si hay motor configurado. */
.importar {
  display: flex;
  align-items: center;
  gap: .9rem;
  flex-wrap: wrap;
  margin: 0 0 1.25rem;
  padding: .9rem 1.15rem;
  border-radius: var(--radio);
  background: var(--lienzo);
}
.importar strong { display: block; font-size: .95rem; letter-spacing: -.01em; }
.importar .ayuda { margin: 0; }
.importar input[type="file"] { width: auto; flex: 1; min-width: 13rem; }

/* ── Selector mensual / anual ───────────────────────────────────────────────
   CSS puro: un checkbox oculto y selectores de hermano, igual que el carrusel
   de la landing. Sin JS no hay estado que se desincronice ni parpadeo inicial.
   El checkbox tiene que ser hermano ANTERIOR de lo que controla. */

.ciclo-check { position: absolute; opacity: 0; pointer-events: none; }

.ciclo {
  display: inline-flex;
  gap: .25rem;
  padding: .25rem;
  margin: 0 auto 1.5rem;
  border-radius: 999px;
  background: var(--lienzo);
  box-shadow: inset 0 0 0 1px var(--raya);
}
.ciclo-opcion {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: 0;
  padding: .45rem 1rem;
  border-radius: 999px;
  font-size: .88rem;
  font-weight: 550;
  color: var(--cuerpo);
  cursor: pointer;
  user-select: none;
  transition: background .15s, color .15s;
}
/* El activo según el estado del checkbox. */
.ciclo-check:not(:checked) ~ .planes-cab .ciclo-mes,
.ciclo-check:checked ~ .planes-cab .ciclo-anio {
  background: var(--blanco);
  color: var(--tinta);
  box-shadow: var(--sombra-baja);
}
.ciclo-ahorro {
  padding: .1rem .4rem;
  border-radius: 5px;
  background: var(--verde-tenue);
  color: var(--verde);
  font-size: .72rem;
  font-weight: 600;
}
.ciclo-check:focus-visible ~ .planes-cab .ciclo { outline: 2px solid var(--verde); outline-offset: 3px; }

/* Qué se muestra en cada estado. Se ocultan con display para que el precio
   que no corresponde no quede en el flujo ni lo lea un lector de pantalla. */
/* Las filas de precio y los botones del ciclo que NO está elegido se ocultan.
   Apunta a la tabla de planes: antes apuntaba a .grilla-tiers, la grilla de
   tarjetas que la tabla reemplazó. */
.ciclo-check:not(:checked) ~ .tabla-planes-scroll .solo-anio,
.ciclo-check:checked ~ .tabla-planes-scroll .solo-mes { display: none; }

/* El bloque del selector va centrado sin romper la grilla de tarjetas. */
.ciclo-check ~ .planes-cab .ciclo { display: inline-flex; }

/* Las herramientas en /cuenta/: nombre y para qué sirve, uno por renglón.
   Existen acá porque la barra de la app se quedó con tres cosas y estos
   enlaces se mudaron al contenido. En un menú entra el nombre; acá entra
   además la razón para tocarlo, que es lo que hace que se toque. */
.lista-herramientas { list-style: none; margin: 0; padding: 0; }
.lista-herramientas li { padding: .55rem 0; }
.lista-herramientas li + li { border-top: 1px solid var(--raya); }
.lista-herramientas a { font-weight: 600; }
.lista-herramientas .texto-suave { display: block; font-size: .88rem; }

/* ── La ficha de una plantilla de la galería ──────────────────────────────
   La hoja a la izquierda y lo que hay que saber a la derecha, como el dibujo.
   Se usa igual en la página suelta y adentro del <dialog>, así que el ancho
   sale del contenedor y no de la ventana. */
.ficha-galeria {
  display: grid;
  grid-template-columns: 24rem minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

/* La previa de la ficha es más alta que la de la tarjeta —acá el documento es
   el tema de la pantalla, no una miniatura de reconocimiento— y se escala un
   poco más grande. La geometría sigue siendo la del PDF: lo único que cambia
   es cuánto se ve y a qué tamaño. No tocar sin mirar motor/nucleo/pagina.py. */
.ficha-preview { height: 30rem; border-bottom: 0; border-radius: var(--radio); }
.ficha-preview .galeria-hoja { --galeria-escala: .46; }

.ficha-datos h1 { margin: .1rem 0 .4rem; }
.ficha-datos h2 {
  margin: 1.6rem 0 .5rem;
  font-size: .95rem; font-weight: 650;
}
.ficha-datos p { line-height: 1.6; }
.ficha-descripcion { margin: 0; font-size: 1.02rem; color: var(--cuerpo); }

/* La familia, como el «Lifestyle» de una revista: ubica el documento en una
   sección antes de que se lea una palabra. Los cuatro colores ya son tokens. */
.ficha-familia {
  margin: 0; font-size: .78rem; font-weight: 650;
  letter-spacing: .06em; text-transform: uppercase;
}
.ficha-familia-cobro        { color: var(--cobro); }
.ficha-familia-operaciones  { color: var(--operaciones); }
.ficha-familia-legales      { color: var(--legales); }
.ficha-familia-comunicacion { color: var(--comunicacion); }

.ficha-campos { list-style: none; margin: 0; padding: 0; }
.ficha-campos li {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  padding: .4rem 0;
}
.ficha-campos li + li { border-top: 1px solid var(--raya); }
.ficha-campos code {
  font-family: var(--mono); font-size: .85rem;
  color: var(--tinta); background: var(--lienzo);
  padding: .1rem .4rem; border-radius: 5px;
}
.ficha-campos .texto-suave { font-size: .85rem; }

.ficha-avisos { margin-top: 1.4rem; }

.ficha-accion {
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  margin-top: 1.6rem; padding-top: 1.2rem;
  border-top: 1px solid var(--raya);
}

/* Una sola columna cuando la hoja y el texto ya no conviven: la hoja mide
   24rem y el texto necesita su medida de lectura. Debajo de eso, primero el
   documento —que es lo que se vino a ver— y después lo que dice. */
@media (max-width: 56rem) {
  .ficha-galeria { grid-template-columns: 1fr; gap: 1.4rem; }
  .ficha-preview { height: 22rem; }
}

/* ── El modal ─────────────────────────────────────────────────────────────
   El dibujo muestra la grilla OSCURECIDA con la ficha flotando encima. Eso es
   exactamente un <dialog> con su ::backdrop, y así Esc, el foco atrapado y el
   click afuera los da el navegador: nada de eso hay que escribirlo.

   Sin JavaScript este diálogo no existe y la tarjeta navega a la página, que
   es la misma ficha. */
.dialogo-ficha {
  width: min(64rem, calc(100vw - 3rem));
  max-height: calc(100vh - 4rem);
  padding: 1.6rem;
  border: 0;
  border-radius: var(--radio);
  background: var(--blanco);
  box-shadow: var(--sombra-alta);
  overflow: auto;
}
.dialogo-ficha::backdrop { background: rgba(19, 28, 24, .45); }
/* El <dialog> recibe el foco al abrirse —para que un lector de pantalla lea la
   ficha y no el botón de cerrar— y el navegador le dibuja el anillo de foco.
   Acá sobra: es un contenedor, no un control. Los controles de adentro
   conservan el suyo, que es donde el anillo sí dice algo. */
.dialogo-ficha:focus { outline: none; }
.dialogo-ficha .volver-fila { display: none; }
.dialogo-cerrar {
  position: absolute; top: .8rem; right: .9rem;
  display: grid; place-items: center;
  width: 2rem; height: 2rem;
  border: 0; border-radius: 999px; background: none;
  color: var(--apagado); cursor: pointer;
}
.dialogo-cerrar:hover { background: var(--lienzo); color: var(--tinta); }

/* ── El asistente de generar ──────────────────────────────────────────────
   Tres pasos arriba, la fuente o el formulario a la izquierda, y la vista
   previa quieta a la derecha en todos los pasos.

   Los pasos NO son enlaces: se avanza eligiendo una fuente y se vuelve con
   «Cambiar de fuente». Un stepper clickeable prometería saltar al paso 3 sin
   datos, que no existe. */
/* Los tres pasos, como en el lienzo: círculos unidos por una línea que cruza el
   ancho de la pantalla, por encima de las dos columnas.

   La línea la estira `flex: 1` en el ::after de cada punto menos el último, así
   el reparto lo hace el navegador y no un ancho fijo que habría que corregir en
   cada corte. Los rótulos viven en `.visualmente-oculto`: se ven tres puntos,
   pero un lector de pantalla escucha «paso 2 de 3, cargá los datos». */
.pasos-generar {
  display: flex; align-items: center;
  list-style: none; margin: 0 0 1.4rem; padding: 0;
}
.paso-punto { display: flex; align-items: center; flex: 1; }
.paso-punto:last-child { flex: none; }
.paso-punto:not(:last-child)::after {
  content: ""; flex: 1; height: 2px; margin: 0 .6rem;
  background: var(--raya); border-radius: 2px;
}
/* El tramo YA recorrido se pinta: la línea deja de ser un adorno y pasa a decir
   cuánto falta, que es para lo que existe un stepper. */
.paso-punto.paso-hecho::after { background: var(--verde); opacity: .45; }
.paso-marca {
  width: .7rem; height: .7rem; border-radius: 999px;
  background: var(--raya); flex: none;
}
/* El punto en el que estás, con un halo: a 0,7rem la diferencia de color sola
   no alcanza para encontrarlo de un vistazo. */
.paso-punto.paso-actual .paso-marca {
  box-shadow: 0 0 0 4px var(--verde-tenue);
}

/* La caja del paso. Es la misma superficie que `.tarjeta` —fondo blanco, radio
   y sombra baja— porque es el mismo objeto: una cosa que se lee junta. Antes el
   contenido iba suelto sobre el fondo de la página y no se sabía dónde
   empezaba el paso y dónde terminaba la pantalla. */
.paso-caja {
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  padding: 1.5rem;
}
.paso-punto.paso-actual { color: var(--tinta); font-weight: 600; }
.paso-punto.paso-actual .paso-marca { background: var(--verde); }
.paso-punto.paso-hecho .paso-marca { background: var(--verde); opacity: .45; }

.paso-titulo { margin: 0 0 .3rem; font-size: 1.15rem; font-weight: 650; }
.paso-nota { margin: 0 0 1.1rem; }
.paso-volver { margin: 1.2rem 0 0; }

/* Las fuentes del paso 1. Dos columnas: son seis tarjetas cortas y en una sola
   columna la lista se vuelve un scroll para elegir algo que entra de una. */
/* Dos columnas, y el mínimo es 13rem por una razón medida: la columna
   izquierda de esta pantalla mide 478px, así que con un mínimo de 15rem (240px)
   dos columnas necesitaban 491px y `auto-fit` caía a una sola. Las seis fuentes
   quedaban apiladas y API y Airtable abajo del pliegue — justo en el paso cuyo
   trabajo es mostrar que hay seis. */
.fuentes-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: .7rem;
}
.fuente {
  display: flex; align-items: flex-start; gap: .7rem;
  padding: .9rem 1rem;
  background: var(--blanco); border-radius: var(--radio);
  box-shadow: var(--sombra-baja);
  text-decoration: none; color: inherit;
  transition: transform .18s cubic-bezier(.3,.7,.4,1), box-shadow .18s;
}
a.fuente:hover { transform: translateY(-2px); box-shadow: var(--sombra-alta); }
.fuente-txt { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.fuente-titulo { font-weight: 600; color: var(--tinta); }
.fuente-nota { font-size: .84rem; color: var(--apagado); line-height: 1.45; }

/* Lo que todavía no existe. En gris y sin sombra: se ve que está y se ve que
   no se toca, sin necesidad de un cartel que lo diga. */
.fuente-proxima {
  background: var(--lienzo); box-shadow: none; cursor: default;
}
.fuente-proxima .fuente-titulo { color: var(--apagado); }

/* La previa, enmarcada como en el lienzo. El marco es del CONTENEDOR y nunca de
   la hoja: la hoja es la del PDF y no se toca. El fondo se queda en `--lienzo`
   —lo pone `.hoja-caja`— para que el papel blanco se recorte contra algo; con
   la caja blanca la hoja desaparecía dentro del marco. */
/* El marco abraza la hoja: sin relleno ni fondo propio. Tenía 1rem de aire y
   el fondo `--lienzo` de `.hoja-caja`, así que entre el borde y el documento
   quedaba una franja gris que no decía nada. Que aparezca el documento y nada
   más. */
.generar-previa .hoja-caja {
  border: 1px solid var(--raya);
  border-radius: var(--radio);
  padding: 0;
  background: var(--blanco);
  overflow: hidden;
}

/* ── Bajar: un botón, y los formatos adentro ──────────────────────────────
   Eran tres botones sueltos con nombres de formato, repetidos en cada
   pantalla. Ahora el botón dice QUÉ HACE y los formatos viven adentro, cada
   uno con una línea que explica para qué sirve. */
.menu-bajar { position: relative; }
.menu-bajar > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: .4rem;
}
.menu-bajar > summary::-webkit-details-marker { display: none; }
.menu-bajar[open] > summary .menu-bajar-flecha { transform: rotate(180deg); }
.menu-bajar-panel {
  position: absolute; right: 0; top: calc(100% + .4rem); z-index: 5;
  width: 19rem; padding: .35rem;
  background: var(--blanco); border-radius: 9px;
  box-shadow: var(--sombra-alta);
}
.menu-bajar-panel .menu-opcion {
  display: block; padding: .5rem .6rem;
  border-radius: 6px; color: var(--tinta); text-decoration: none;
}
.menu-bajar-panel .menu-opcion:hover { background: var(--lienzo); }
.menu-bajar-panel .menu-opcion-titulo {
  display: flex; align-items: center; gap: .35rem;
  font-size: .88rem; font-weight: 600;
}
.menu-bajar-panel .menu-opcion-titulo .ic { color: var(--verde); }
.menu-bajar-panel .menu-opcion-ayuda {
  display: block; font-size: .78rem; color: var(--apagado); margin-top: .1rem;
}
