/* Estilos globales: solo reset, tipografía base y los elementos de formulario
   que comparten todas las pantallas. Lo específico va en el .razor.css de cada una. */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--fuente);
    font-size: var(--texto-base);
    line-height: var(--interlineado);
    color: var(--color-texto);
    background-color: var(--color-fondo);
    -webkit-text-size-adjust: 100%;
}

h1 {
    font-size: var(--texto-titulo);
    line-height: 1.25;
    margin: 0 0 var(--espacio-3);
}

p {
    margin: 0 0 var(--espacio-4);
}

a {
    color: var(--color-acento);
}

/* Formularios ------------------------------------------------------------ */

.campo {
    display: block;
    margin-bottom: var(--espacio-4);
}

.campo > label {
    display: block;
    margin-bottom: var(--espacio-2);
    font-weight: 600;
}

.campo input {
    width: 100%;
    min-height: var(--altura-tactil);
    padding: 0 var(--espacio-3);
    font-family: inherit;
    /* 16px como mínimo: por debajo, iOS hace zoom al enfocar el campo. */
    font-size: max(1rem, var(--texto-base));
    color: inherit;
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
}

.campo input:focus-visible {
    outline: 2px solid var(--color-acento);
    outline-offset: 1px;
}

.ayuda {
    margin: var(--espacio-2) 0 0;
    font-size: var(--texto-pequeno);
    color: var(--color-texto-tenue);
}

.boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: var(--altura-tactil);
    padding: 0 var(--espacio-5);
    font-family: inherit;
    font-size: var(--texto-base);
    font-weight: 600;
    color: #fff;
    background-color: var(--color-acento);
    border: none;
    border-radius: var(--radio-pequeno);
    cursor: pointer;
}

.boton:hover:not(:disabled) {
    background-color: var(--color-acento-oscuro);
}

.boton:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.boton:focus-visible {
    outline: 2px solid var(--color-texto);
    outline-offset: 2px;
}

.boton-secundario {
    color: var(--color-acento);
    background-color: transparent;
    border: 1px solid var(--color-borde);
}

.boton-secundario:hover:not(:disabled) {
    background-color: var(--color-superficie);
}

.boton-peligro {
    color: #fff;
    background-color: var(--color-error);
}

.boton-peligro:hover:not(:disabled) {
    background-color: #7d1c1f;
}

/* Botón que se lee como un enlace: para acciones secundarias dentro de texto. */
.enlace {
    padding: 0;
    font: inherit;
    color: var(--color-acento);
    text-decoration: underline;
    background: none;
    border: none;
    cursor: pointer;
}

.boton-icono {
    min-width: var(--altura-tactil);
    min-height: var(--altura-tactil);
    font-size: 1.25rem;
    line-height: 1;
    color: var(--color-texto-tenue);
    background: none;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
    cursor: pointer;
}

.boton-icono:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Avisos ----------------------------------------------------------------- */

.aviso {
    padding: var(--espacio-3) var(--espacio-4);
    margin-bottom: var(--espacio-4);
    border-radius: var(--radio-pequeno);
    font-size: var(--texto-pequeno);
}

.aviso-error {
    color: var(--color-error);
    background-color: var(--color-error-fondo);
    border: 1px solid currentColor;
}

.aviso-exito {
    color: var(--color-exito);
    background-color: var(--color-exito-fondo);
    border: 1px solid currentColor;
}

.validation-message {
    display: block;
    margin-top: var(--espacio-2);
    font-size: var(--texto-pequeno);
    color: var(--color-error);
}

/* Pantalla de carga ------------------------------------------------------- */

/*
 * Lo que se ve mientras Blazor descarga el runtime. Vive en index.html, fuera
 * del árbol de componentes, así que se estila aquí y no en un `.razor.css`:
 * el aislamiento por componente no alcanza a un marcado que existe antes de
 * que arranque la aplicación.
 */
.cargando {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--espacio-4);

    /* Centrado en la ventana, no en el flujo: en este momento la página está
       vacía y no hay nada más que la sitúe. */
    position: fixed;
    inset: 0;
}

.cargando-icono {
    width: 6rem;
    height: 6rem;

    /* Latido lento: dice "sigue trabajando" sin la ansiedad de un giro rápido.
       Quien haya pedido menos movimiento no ve ninguno. */
    animation: cargando-latido 1.8s ease-in-out infinite;
}

.cargando-texto {
    margin: 0;
    font-size: var(--texto-pequeno);
    color: var(--color-texto-tenue);
}

@keyframes cargando-latido {
    50% {
        opacity: 0.45;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cargando-icono {
        animation: none;
    }
}

/* Error no controlado de Blazor. La plantilla lo trae oculto y lo muestra al fallar. */
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding: var(--espacio-3) var(--espacio-4);
    color: #fff;
    background-color: var(--color-error);
}

#blazor-error-ui .dismiss {
    float: right;
    cursor: pointer;
}

/* Selects y áreas de texto, con el mismo aspecto que los input ------------- */

.campo select,
.campo textarea,
.buscador input,
.buscador select,
.denuncia select,
.denuncia textarea {
    width: 100%;
    padding: var(--espacio-3);
    font-family: inherit;
    /* 16px como mínimo: por debajo, iOS hace zoom al enfocar el campo. */
    font-size: max(1rem, var(--texto-base));
    color: inherit;
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
}

.campo select,
.buscador select,
.denuncia select {
    min-height: var(--altura-tactil);
}

.campo textarea,
.denuncia textarea {
    line-height: var(--interlineado);
    resize: vertical;
}

/* Cabecera de página con acción a la derecha ------------------------------- */

.cabecera-de-pagina {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--espacio-3);
    margin-bottom: var(--espacio-5);
}

.cabecera-de-pagina h1 {
    margin: 0;
}

.cabecera-de-pagina .boton {
    width: auto;
    text-decoration: none;
}

/* Botón de ayuda (043) ------------------------------------------------------
   Siempre en la cabecera, con sesión o sin ella, así que no puede vivir en
   `.navegacion`. Icono + texto, sin subrayado —el icono ya lo distingue de
   un enlace de texto suelto—. */

.enlace-ayuda {
    display: inline-flex;
    align-items: center;
    gap: var(--espacio-1);
    height: var(--altura-tactil);
    padding: 0;
    font: inherit;
    font-size: var(--texto-pequeno);
    color: var(--color-texto);
    background: none;
    border: 0;
    cursor: pointer;
}

.enlace-ayuda:hover {
    color: var(--color-acento);
}

/* Navegación de la cabecera -------------------------------------------------
   Cinco enlaces no caben en línea en un móvil estrecho. Por debajo de 40rem
   —el mismo corte que ya separaba el padding de `.contenido`— la navegación
   se pliega detrás de un botón de menú; a partir de ahí se enseña entera,
   como siempre. Sin JavaScript: el estado abierto/cerrado es un bool de
   Blazor, igual que el resto de desplegables del producto. */

.boton-menu {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--altura-tactil);
    height: var(--altura-tactil);
    padding: 0;
    color: var(--color-texto);
    background: none;
    border: 0;
    cursor: pointer;
}

/* Cerrada por defecto en móvil: un panel que cuelga de la cabecera, no una
   fila que se aplasta. */
.navegacion {
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: var(--espacio-1);
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: var(--espacio-3) var(--espacio-4);
    background-color: var(--color-superficie);
    border-bottom: 1px solid var(--color-borde);
    box-shadow: var(--sombra);
    font-size: var(--texto-pequeno);
}

.navegacion-abierta {
    display: flex;
}

.navegacion a,
.navegacion button {
    padding: var(--espacio-2) 0;

    /* «Salir» es un <button>, y el navegador lo centra por defecto a
       diferencia de un <a>. Sin esto, en el panel de móvil quedaría el único
       enlace descentrado respecto a los demás. */
    text-align: left;
}

@media (min-width: 40rem) {
    .boton-menu {
        display: none;
    }

    /* A partir de aquí la navegación es siempre la fila de siempre, tanto si
       el usuario la había abierto en móvil como si no: ensanchar la ventana
       no debe dejar un panel desplegado a medias. */
    .navegacion,
    .navegacion-abierta {
        display: flex;
        flex-direction: row;
        align-items: center;
        position: static;
        gap: var(--espacio-4);
        padding: 0;
        background: none;
        border: 0;
        box-shadow: none;
    }

    .navegacion a,
    .navegacion button {
        padding: 0;
    }
}

/* Listados ---------------------------------------------------------------- */

.lista-de-recetas {
    padding: 0;
    margin: 0;
    list-style: none;
}

.lista-de-recetas li + li {
    margin-top: var(--espacio-2);
}

.lista-de-recetas a {
    display: flex;
    gap: var(--espacio-4);
    align-items: center;
    padding: var(--espacio-3);
    color: inherit;
    text-decoration: none;
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
}

/* Ocupa lo que sobra: sin esto, un nombre largo empujaría a la miniatura. */
.lista-de-recetas .datos {
    min-width: 0;
    flex: 1;
}

.lista-de-recetas a:hover,
.lista-de-recetas a:focus-visible {
    border-color: var(--color-acento);
}

.lista-de-recetas .nombre {
    display: block;
    font-weight: 600;
}

.meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--espacio-2);
    margin-top: var(--espacio-1);
    font-size: var(--texto-pequeno);
    color: var(--color-texto-tenue);
}

.marca {
    padding: 0 var(--espacio-2);
    font-size: 0.8125rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
}

.marca-publica {
    color: var(--color-exito);
    background-color: var(--color-exito-fondo);
    border-color: currentColor;
}

/* Etiquetas libres de la receta (024) --------------------------------------
   Mismo aspecto que .marca: son texto de apoyo, no una acción, así que no
   llevan más énfasis que el tipo de plato o la marca de visibilidad. */

.etiquetas-de-receta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espacio-1);
    margin: var(--espacio-2) 0 0;
    padding: 0;
    list-style: none;
}

.etiquetas-de-receta li {
    padding: 0 var(--espacio-2);
    font-size: 0.8125rem;
    color: var(--color-texto-tenue);
    background-color: var(--color-fondo);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
}

/* Estado vacío ------------------------------------------------------------ */

.vacio {
    padding: var(--espacio-6) var(--espacio-4);
    text-align: center;
    background-color: var(--color-superficie);
    border: 1px dashed var(--color-borde);
    border-radius: var(--radio);
}

.vacio .boton {
    width: auto;
    margin-top: var(--espacio-3);
    text-decoration: none;
}

/* Ficha de receta --------------------------------------------------------- */

.receta section {
    margin-top: var(--espacio-6);
}

.receta h2 {
    margin: 0 0 var(--espacio-3);
    font-size: 1.125rem;
}

.ingredientes-lista {
    padding: 0;
    margin: 0;
    list-style: none;
}

/* Importar desde una URL (011) -------------------------------------------- */

.importar {
    padding: var(--espacio-4);
    margin-bottom: var(--espacio-5);
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
}

.importar label {
    display: block;
    margin-bottom: var(--espacio-2);
    font-weight: 600;
}

.importar-fila {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espacio-2);
}

.importar-fila input {
    flex: 1 1 16rem;
    min-width: 0;
}

.importar-fila .boton {
    flex: 0 0 auto;
    width: auto;
}

/* Ajuste de comensales (010) --------------------------------------------- */

.comensales {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--espacio-2);
    margin-bottom: var(--espacio-3);
}

.comensales input {
    /* Justo para tres cifras: el máximo son 100 raciones. */
    width: 5rem;
}

/* Acción secundaria con aspecto de enlace: no compite con los botones de la
   ficha, que son las acciones de verdad sobre la receta. */
.boton-enlace {
    padding: 0;
    font: inherit;
    font-size: var(--texto-pequeno);
    color: var(--color-acento);
    text-decoration: underline;
    cursor: pointer;
    background: none;
    border: none;
}

.ingredientes-lista li {
    display: flex;
    gap: var(--espacio-3);
    padding: var(--espacio-2) 0;
    border-bottom: 1px solid var(--color-borde);
}

.ingredientes-lista .cantidad {
    flex: 0 0 7rem;
    color: var(--color-texto-tenue);
}

/* Los pasos, con margen generoso: se leen a distancia de brazo mientras se
   cocina, que es el caso de uso central de mission.md. */
.paso {
    margin-bottom: var(--espacio-4);
}

/* Fotos ------------------------------------------------------------------- */

.fotos {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--espacio-4);
}

.fotos figure {
    margin: 0;
}

.foto {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radio);
}

.foto-cargando,
.foto-rota {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    font-size: var(--texto-pequeno);
    color: var(--color-texto-tenue);
    background-color: var(--color-superficie);
    border: 1px dashed var(--color-borde);
}

/*
 * Miniatura de listado. Cuadrada y de tamaño fijo: las fotos de receta vienen
 * en cualquier proporción, y dejar que cada una imponga la suya haría que las
 * tarjetas tuvieran alturas distintas.
 */
.foto-miniatura {
    flex: 0 0 auto;
    width: 4.5rem;
    height: 4.5rem;

    /* Recorta para llenar el cuadro sin deformar la foto. El recorte es solo de
       la miniatura; el archivo guardado conserva su proporción entera. */
    object-fit: cover;

    /* Anula el aspect-ratio de los estados de carga y error, que está pensado
       para la foto grande de la ficha. */
    aspect-ratio: auto;
}

/* Receta sin ninguna foto: el hueco se pinta igual para que la lista no se
   descoloque, con el icono de la aplicación en tenue. */
.foto-sin-portada {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-texto-tenue);
    background-color: var(--color-fondo);
    border: 1px dashed var(--color-borde);
}

/* El icono viene con el tamaño de los botones, que en este hueco se pierde. */
.foto-sin-portada .icono {
    width: 2rem;
    height: 2rem;
}

.fotos figcaption {
    margin-top: var(--espacio-2);
}

/* Tira de miniaturas de la ficha ------------------------------------------
   Cada una es un botón: abre el visor. Se envuelve en un botón y no en un
   enlace porque no hay ninguna dirección a la que ir — la foto se sirve con
   cabecera de autorización y no se puede enlazar. */

.tira-de-fotos {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espacio-2);
}

/* El contenedor recibe el foco al cerrar el visor, pero no es un control: el
   anillo de foco lo dibujan las miniaturas, que sí lo son. */
.tira-de-fotos:focus {
    outline: none;
}

.tira-foto {
    position: relative; /* ancla la insignia de portada */
    padding: 0;
    background: none;
    border: 0;
    border-radius: var(--radio);
    cursor: pointer;
}

.tira-foto:focus-visible {
    outline: 2px solid var(--color-acento);
    outline-offset: 2px;
}

/* Insignia de portada (025): un aviso discreto sobre la miniatura, no un
   control — elegirla se hace desde el visor, con la foto grande delante. */
.tira-foto-portada {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    color: #fff;
    background-color: rgb(36 32 28 / 60%);
    border-radius: 50%;
}

.tira-foto-portada .icono {
    width: 0.75rem;
    height: 0.75rem;
}

/* Visor de fotos ----------------------------------------------------------
   Superposición a pantalla completa. El fondo oscuro no es decoración: la foto
   viene en cualquier proporción y sin él quedaría flotando sobre el texto de la
   receta. */

.visor {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--espacio-3);
    background-color: rgb(0 0 0 / 85%);
}

.visor:focus {
    outline: none;
}

.visor-contenido {
    display: flex;
    flex-direction: column;
    gap: var(--espacio-2);
    width: 100%;
    max-width: 60rem;
}

.visor-barra {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--espacio-3);
    color: #fff;
}

.visor-barra-acciones {
    display: flex;
    align-items: center;
    gap: var(--espacio-2);
}

.visor-cuenta {
    font-size: var(--texto-pequeno);
}

.visor-imagen {
    display: flex;
    align-items: center;
    gap: var(--espacio-2);
}

/* La foto manda sobre su caja: entera y dentro de la pantalla, sin recortar.
   `.foto` de la ficha es de ancho completo, que aquí desbordaría en vertical. */
.visor-imagen .foto {
    flex: 1 1 auto;
    min-width: 0;
    max-height: 80vh;
    object-fit: contain;
}

/* Los huecos de carga y error de `.foto` traen fondo claro y borde punteado,
   pensados para la ficha. Sobre el fondo oscuro del visor hay que rehacerlos. */
.visor-imagen .foto-cargando,
.visor-imagen .foto-rota {
    flex: 1 1 auto;
    aspect-ratio: 4 / 3;
    color: #fff;
    background-color: rgb(255 255 255 / 8%);
    border-color: rgb(255 255 255 / 30%);
}

.visor-paso {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    color: #fff;
    background-color: rgb(255 255 255 / 12%);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}

.visor-paso:hover {
    background-color: rgb(255 255 255 / 24%);
}

/*
 * `.boton-accion` trae fondo claro (pensado para la ficha) y aquí solo se
 * cambiaba el color del icono: el resultado era un icono blanco sobre fondo
 * claro, invisible. Se rehace el fondo igual que `.visor-paso`, con el mismo
 * tono translúcido para que los tres controles de la barra se lean como un
 * conjunto.
 */
.visor .boton-accion {
    color: #fff;
    background-color: rgb(255 255 255 / 12%);
    border-color: rgb(255 255 255 / 30%);
}

.visor .boton-accion:hover:not(:disabled) {
    color: #fff;
    background-color: rgb(255 255 255 / 24%);
    border-color: rgb(255 255 255 / 30%);
}

/* La confirmación de borrado se pinta dentro de la barra, sobre el fondo
   oscuro: sin esto heredaría el color de texto de la página y no se leería. */
.visor .confirmacion {
    color: var(--color-texto);
}

/* En pantallas estrechas los botones de paso comen el ancho de la foto. Se
   quedan, porque son la única forma de pasar sin gestos, pero más pequeños. */
@media (max-width: 30rem) {
    .visor-paso {
        width: 2.25rem;
        height: 2.25rem;
    }

    .visor-imagen {
        gap: var(--espacio-1);
    }
}

/* Ayuda (043) --------------------------------------------------------------
   Mismo patrón de superposición que `.visor`, pero con tarjeta clara: aquí
   hay párrafos largos que leer, no una foto sobre fondo oscuro.

   Nombres con prefijo `superposicion-`, no `.ayuda`: esa clase ya la usan por
   toda la aplicación los párrafos de texto de ayuda bajo un campo
   (`<p class="ayuda">`) y un overlay de página entera con ese nombre los
   convertía a todos en una capa fija que tapaba la pantalla — justo el fallo
   que reportó el usuario nada más entrar a una ficha. */

.superposicion-ayuda {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--espacio-3);
    background-color: rgb(0 0 0 / 60%);
}

.superposicion-ayuda:focus {
    outline: none;
}

.superposicion-ayuda-contenido {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 40rem;
    max-height: 85vh;
    background-color: var(--color-superficie);
    border-radius: var(--radio);
    box-shadow: var(--sombra);
}

.superposicion-ayuda-barra {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 0 0 auto;
    gap: var(--espacio-3);
    padding: var(--espacio-3) var(--espacio-4);
    border-bottom: 1px solid var(--color-borde);
}

.superposicion-ayuda-barra h2 {
    margin: 0;
    font-size: var(--texto-base);
}

/* Cabecera y botón de cerrar fijos; solo el texto hace scroll, para no
   perder de vista cómo cerrar en un modal largo. */
.superposicion-ayuda-cuerpo {
    flex: 1 1 auto;
    padding: var(--espacio-4);
    overflow-y: auto;
}

.superposicion-ayuda-cuerpo section + section {
    margin-top: var(--espacio-5);
}

.superposicion-ayuda-cuerpo h3 {
    margin: 0 0 var(--espacio-2);
    font-size: var(--texto-base);
}

.superposicion-ayuda-cuerpo p,
.superposicion-ayuda-cuerpo ul {
    margin: 0 0 var(--espacio-2);
}

.superposicion-ayuda-cuerpo ul {
    padding-left: var(--espacio-4);
}

/* Acciones ---------------------------------------------------------------- */

.acciones {
    padding-top: var(--espacio-4);
    border-top: 1px solid var(--color-borde);
}

.acciones .boton {
    text-decoration: none;
}

/* El input de archivo se oculta y lo dispara la etiqueta, que sí se puede
   estilar como el resto de botones. */
.subir-foto {
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

.subir-foto input[type="file"] {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.acciones-portada {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--espacio-4);
    margin-top: var(--espacio-6);
}

.acciones-portada .boton {
    text-decoration: none;
}

.enlace-secundario {
    font-size: var(--texto-pequeno);
}

/* Confirmación ------------------------------------------------------------ */

.confirmacion {
    padding: var(--espacio-4);
    background-color: var(--color-error-fondo);
    border: 1px solid var(--color-error);
    border-radius: var(--radio);
}

.confirmacion p {
    margin-bottom: var(--espacio-3);
    font-size: var(--texto-pequeno);
}

.confirmacion-botones {
    display: flex;
    gap: var(--espacio-3);
}

/* Formulario de ingredientes ---------------------------------------------- */

.ingredientes {
    padding: var(--espacio-4);
    margin: 0 0 var(--espacio-4);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
}

.ingredientes legend {
    padding: 0 var(--espacio-2);
    font-weight: 600;
}

.ingrediente {
    display: grid;
    /*
     * El nombre manda: es lo más largo ("aceite de oliva virgen extra") y lo que
     * más se lee. La cantidad necesita caber entera —"500" con su coma decimal si
     * la hay—, y antes se quedaba en 4,5 rem y truncaba el valor a la vista.
     * minmax(0, …) evita que el contenido ensanche la columna y desborde la fila.
     */
    grid-template-columns: minmax(0, 2.2fr) 6rem minmax(0, 1.4fr) auto;
    gap: var(--espacio-2);
    margin-bottom: var(--espacio-3);
}

.ingrediente input,
.ingrediente select {
    min-width: 0;
    min-height: var(--altura-tactil);
    padding: 0 var(--espacio-2);
    font-family: inherit;
    font-size: max(1rem, var(--texto-pequeno));
    color: inherit;
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
}

/* En pantallas estrechas, el nombre ocupa toda la fila y cantidad, unidad y
   el botón de quitar se reparten la siguiente. */
@media (max-width: 30rem) {
    .ingrediente {
        grid-template-columns: 1fr 1fr auto;
    }

    .ingrediente input:first-child {
        grid-column: 1 / -1;
    }
}

.buscador {
    padding: var(--espacio-4);
    margin-bottom: var(--espacio-5);
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
}

/* Pantallas de cuenta -------------------------------------------------------
   Alta, contraseña e inicio de sesión siguen en columna estrecha: son cuatro
   campos y estirarlos a lo ancho de la pantalla solo empeoraría la lectura. */

.pagina-estrecha {
    max-width: var(--ancho-formulario);
    margin-inline: auto;
}

/* Botones de icono -----------------------------------------------------------
   Sin texto visible, así que dependen del `title` y del `aria-label` que pone
   quien los usa. El tamaño no baja de la altura táctil: un icono pequeño es
   cómodo con ratón y desesperante con el dedo. */

.acciones-fila {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espacio-3);
    align-items: flex-start;
}

.boton-accion {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--altura-tactil);
    height: var(--altura-tactil);
    padding: 0;
    color: var(--color-acento);
    text-decoration: none;
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pequeno);
    cursor: pointer;
}

.boton-accion:hover:not(:disabled) {
    color: var(--color-acento-oscuro);
    border-color: var(--color-acento);
}

.boton-accion:focus-visible {
    outline: 2px solid var(--color-acento);
    outline-offset: 2px;
}

/* Estado activo: la receta ya está compartida, y pulsar deshace. Se marca con
   color porque el icono tachado por sí solo se ve tarde. */
.boton-accion-activo {
    color: var(--color-exito);
    background-color: var(--color-exito-fondo);
    border-color: currentColor;
}

.boton-accion-peligro {
    color: var(--color-error);
}

.boton-accion-peligro:hover:not(:disabled) {
    color: #fff;
    background-color: var(--color-error);
    border-color: var(--color-error);
}

.boton-accion .icono {
    pointer-events: none;
}

/* Texto solo para lectores de pantalla: mantiene la jerarquía de encabezados
   sin ocupar espacio. No se usa display:none, que lo ocultaría también a ellos. */
.solo-lectores {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Favoritos ----------------------------------------------------------------
   El botón no ocupa el ancho completo como en los formularios: aquí es una
   acción entre otras, no el final de una tarea. */

.favorito {
    margin-top: var(--espacio-5);
    padding-top: var(--espacio-4);
    border-top: 1px solid var(--color-borde);
}

.favorito .boton {
    width: auto;
}

.favorito .ayuda {
    margin-top: var(--espacio-2);
}

/* Denunciar una receta ajena ----------------------------------------------
   Discreto a propósito: es una salida de emergencia, no una acción principal.
   Un botón llamativo junto a una receta invita a usarlo por error. */

.denuncia {
    margin-top: var(--espacio-5);
    padding-top: var(--espacio-4);
    border-top: 1px solid var(--color-borde);
}

.denuncia-titulo {
    margin: 0 0 var(--espacio-2);
    font-size: var(--texto-base);
}

.denuncia label {
    display: block;
    margin-top: var(--espacio-3);
    margin-bottom: var(--espacio-1);
}

.denuncia .acciones-fila {
    margin-top: var(--espacio-4);
    align-items: center;
}

/* `.boton` es de ancho completo por defecto, pensado para formularios de una
   columna. Aquí convive con «Cancelar» en la misma fila. */
.denuncia .acciones-fila .boton {
    width: auto;
}

/* Retirada por moderación. Comparte separador con la denuncia: las dos son
   acciones excepcionales al pie de una receta ajena. */

.moderacion {
    margin-top: var(--espacio-5);
    padding-top: var(--espacio-4);
    border-top: 1px solid var(--color-borde);
}

/* Zona peligrosa: borrar la cuenta -----------------------------------------
   Separada del resto con un borde de error, no por dramatismo sino porque es
   la única acción del producto que no se puede deshacer. */

.zona-peligrosa {
    margin-top: var(--espacio-6);
    padding: var(--espacio-4);
    border: 1px solid var(--color-error);
    border-radius: var(--radio-pequeno);
}

.zona-peligrosa h2 {
    margin: 0 0 var(--espacio-3);
    font-size: var(--texto-base);
    color: var(--color-error);
}

/* Vista imprimible de una receta -------------------------------------------
   No es una hoja de estilos aparte: la misma página, con lo que no tiene
   sentido en papel quitado. Nada de esto cambia lo que se ve en pantalla. */

@media print {
    /* Navegación, fotos, y cualquier acción que no se pueda pulsar en papel. */
    .cabecera,
    .tira-de-fotos,
    .favorito,
    .acciones,
    .moderacion,
    .denuncia,
    .aviso,
    .no-imprimir {
        display: none !important;
    }

    /* El botón de "volver a las raciones guardadas": solo tiene sentido con
       el número ya ajustado delante, en pantalla. */
    .comensales button {
        display: none;
    }

    main.contenido {
        max-width: none;
        padding: 0;
    }

    /* Que un ingrediente o un paso no se parta entre dos páginas: se lee peor
       que dejar más hueco en blanco al final de una. */
    .ingredientes-lista li,
    .paso {
        break-inside: avoid;
    }
}
