/**
 * Order Press — estilos base.
 *
 * Todo está parametrizado con custom properties (variables CSS) para que
 * se pueda personalizar el diseño desde el CSS custom de Bricks (a nivel
 * página o elemento contenedor) sin tener que pisar reglas con !important.
 *
 * El color primario se configura en Ajustes → Cotizador y se inyecta sobre
 * :root, así que para cambiarlo no hace falta tocar CSS. El resto se pisa así:
 *
 *   .orderpress-widget {
 *     --orderpress-radius: 0;
 *     --orderpress-font-size: 16px;
 *   }
 */

/**
 * Las variables se declaran en :root y no en .orderpress-widget porque
 * [orderpress_contador] renderiza un <span> suelto, fuera de cualquier widget:
 * declaradas solo en .orderpress-widget, ese badge no resolvía
 * var(--orderpress-primary) y quedaba sin fondo.
 *
 * Sobreescribirlas en .orderpress-widget sigue funcionando igual (es más
 * específico), así que se puede seguir adaptando el diseño por contenedor
 * desde Bricks.
 */
/* ================================================================
   TOKENS DE DISEÑO — el sistema base del plugin, listo para maquetar.
   Escalas completas de tipografía, espaciado, color, radios y sombras.
   Que no todas se usen hoy no las vuelve código muerto: son un FRAMEWORK
   de estilos, un sistema del que los componentes toman en vez de inventar
   valores sueltos (ver CLAUDE.md, "CSS: todo por variables"). Documentadas
   en docs/IMPLEMENTACION.md.
   ================================================================ */
:root {
    /* --- Tipografía: escala modular sobre 1rem, razón ~1.25 --- */
    --orderpress-text-xs:   0.75rem;
    --orderpress-text-sm:   0.875rem;
    --orderpress-text-base: 1rem;
    --orderpress-text-lg:   1.125rem;
    --orderpress-text-xl:   1.375rem;
    --orderpress-text-2xl:  1.75rem;
    --orderpress-text-3xl:  2.25rem;
    --orderpress-text-4xl:  3rem;

    --orderpress-weight-normal:   400;
    --orderpress-weight-medium:   500;
    --orderpress-weight-semibold: 600;
    --orderpress-weight-bold:     700;

    --orderpress-leading-tight:   1.2;
    --orderpress-leading-snug:    1.35;
    --orderpress-leading-normal:  1.5;
    --orderpress-leading-relaxed: 1.7;

    /* --- Espaciado: escala de 4 px, en rem para acompañar el zoom --- */
    --orderpress-space-0:  0;
    --orderpress-space-1:  0.25rem;
    --orderpress-space-2:  0.5rem;
    --orderpress-space-3:  0.75rem;
    --orderpress-space-4:  1rem;
    --orderpress-space-5:  1.5rem;
    --orderpress-space-6:  2rem;
    --orderpress-space-8:  3rem;
    --orderpress-space-10: 4rem;
    --orderpress-space-12: 6rem;

    /* --- Radios --- */
    --orderpress-radius-sm:   3px;
    --orderpress-radius-md:   6px;
    --orderpress-radius-lg:   12px;
    --orderpress-radius-xl:   20px;
    --orderpress-radius-full: 999px;

    /* --- Sombras (elevación). El negro con alfa vive acá, en la definición
       del token, no suelto en una regla de componente. --- */
    --orderpress-shadow-sm: 0 1px 2px color-mix(in srgb, var(--orderpress-black) 6%, transparent);
    --orderpress-shadow-md: 0 2px 8px color-mix(in srgb, var(--orderpress-black) 10%, transparent);
    --orderpress-shadow-lg: 0 8px 24px color-mix(in srgb, var(--orderpress-black) 14%, transparent);

    /* --- Neutrales: la escala gris de la que salen los roles de abajo --- */
    --orderpress-gray-50:  #f7f7f7;
    --orderpress-gray-100: #efefef;
    --orderpress-gray-200: #e0e0e0;
    --orderpress-gray-300: #cccccc;
    --orderpress-gray-400: #aaaaaa;
    --orderpress-gray-500: #999999;
    --orderpress-gray-600: #666666;
    --orderpress-gray-700: #444444;
    --orderpress-gray-800: #333333;
    --orderpress-gray-900: #1e1e1e;
    --orderpress-white:    #ffffff;
    --orderpress-black:    #000000;

    /* --- Movimiento y capas --- */
    --orderpress-transition-fast: 100ms ease;
    --orderpress-transition:      150ms ease;
    --orderpress-transition-slow: 300ms ease;
    --orderpress-z-base:     1;
    --orderpress-z-dropdown: 100;
    --orderpress-z-sticky:   500;
    --orderpress-z-overlay:  1000;

    /* --- Anchos de contenedor --- */
    --orderpress-container-sm: 640px;
    --orderpress-container-md: 800px;
    --orderpress-container-lg: 1100px;
    --orderpress-container-xl: 1320px;
}

/* ================================================================
   ROLES Y AJUSTES — el resto del plugin usa estos nombres semánticos,
   que salen de los tokens de arriba. Cambiar un token acá arriba se
   propaga a todo el sistema.
   ================================================================ */
:root {
    --orderpress-primary: #0073aa;
    --orderpress-text: var(--orderpress-gray-900);
    --orderpress-text-muted: var(--orderpress-gray-600);
    --orderpress-border: var(--orderpress-gray-200);
    --orderpress-border-strong: var(--orderpress-gray-300);
    --orderpress-bg-alt: var(--orderpress-gray-50);
    --orderpress-superficie: var(--orderpress-white);
    --orderpress-danger: #c0392b;
    --orderpress-success: #2e7d32;
    --orderpress-warning: #a35b00;
    --orderpress-radius: var(--orderpress-radius-md);
    --orderpress-spacing: 12px;
    --orderpress-font-size: 15px;
    --orderpress-precio-size: 22px;
    /* El color del carrito del header. Por defecto hereda del contenedor, que es
       lo correcto en la mayoría de los headers; se pisa desde el CSS del
       constructor cuando el fondo no contrasta (un header oscuro, por ejemplo).
       Va por variable y no por un ajuste global porque el MISMO shortcode puede
       estar en un header oscuro y en un menú mobile claro a la vez: un solo valor
       no puede servir para los dos. */
    --orderpress-carrito-color: inherit;

    /* Página del pedido. El resumen va a la izquierda y se queda con TODO el ancho
       disponible; el formulario va a la derecha con ancho fijo, porque un campo de
       texto de 700px no se lee mejor que uno de 460. */
    /* El formulario es el que lleva fondo, así que su columna tiene padding: se sube
       el ancho para que los campos queden igual de anchos que antes y no se angosten
       por el relleno del panel. */
    --orderpress-form-ancho: 520px;
    /* Tope de ancho de cualquier formulario del plugin. 'none' = el que le dé el
       contenedor. Se le puede poner un valor desde el tema para acotar una página
       puntual sin tocar este archivo. */
    --orderpress-form-max: none;
    /* Ancho del panel lateral de la ficha del pedido. Es un resumen: mide lo suyo y no
       crece con el contenido de al lado. */
    --orderpress-panel-ancho: 320px;
    --orderpress-item-foto: 64px;
    --orderpress-pedido-gap: 40px;
    --orderpress-form-fondo: var(--orderpress-bg-alt);
    /* Cuánto baja el resumen fijo. Se sube si el sitio tiene un header pegajoso, o
       se pone 'static' en --orderpress-resumen-position para que no se fije. */
    --orderpress-resumen-top: 24px;
    --orderpress-resumen-position: sticky;

    /* Tamaño de los controles. El line-height se declara SIEMPRE, aunque parezca
       redundante: sin él, el tema gana. Bricks le pone line-height: 40px a los
       inputs desde frontend-layer.min.css, y con nuestro padding daba campos de
       62 px contra botones de 41. */
    --orderpress-control-padding-y: 10px;
    --orderpress-control-padding-x: 12px;
    --orderpress-control-line-height: 1.4;
    --orderpress-control-peso: 400;
    --orderpress-boton-peso: 600;

    /* La tipografía sí se hereda del sitio a propósito: un formulario con otra
       fuente que el resto de la página se ve como un injerto. Si algún sitio
       necesita fijarla, se pisa esta variable y nada más. */
    --orderpress-font-family: inherit;

    /* Derivados del primario con color-mix(), que es CSS nativo y hace de
       lighten/darken. Definir UN color en Ajustes alcanza para que hover, focus
       y fondos tenues queden coherentes: no hay pares de valores que mantener
       sincronizados a mano. */
    --orderpress-primary-hover: color-mix(in srgb, var(--orderpress-primary) 85%, black);
    --orderpress-primary-suave: color-mix(in srgb, var(--orderpress-primary) 15%, transparent);

    /* Texto sobre el color primario. Queda como variable y no como #fff fijo
       porque un primario claro (un amarillo, por ejemplo) necesita texto oscuro
       para seguir siendo legible. CSS todavía no tiene un contrast-color() con
       soporte parejo, así que se elige a mano si hace falta. */
    --orderpress-primary-contraste: var(--orderpress-white);

    /* El verde de WhatsApp para el botón de "enviar por WhatsApp": es la marca que el
       cliente reconoce, no un acento del sitio, por eso no sale del primario. El hover
       y el contraste se derivan igual que para el primario. */
    --orderpress-whatsapp: #25d366;
    --orderpress-whatsapp-hover: color-mix(in srgb, var(--orderpress-whatsapp) 85%, black);
    --orderpress-whatsapp-contraste: var(--orderpress-white);

    /* Vistas de página entera (la confirmación): ancho máximo centrado. Antes iba a mano
       en el componente; como token, Bricks lo cambia desde su CSS global. */
    --orderpress-page-max: 760px;
}

/* ==========================================================================
   COMPONENTES BASE
   Lo repetido se define una vez; las clases específicas solo agregan lo propio. En el
   markup van las dos: <div class="orderpress-caja orderpress-ficha-caja">. La base se
   SUMÓ al lado de las clases de siempre, no las reemplazó: el CSS del constructor puede
   estar apuntando a .orderpress-acceso, .orderpress-card o .orderpress-ficha-caja, y
   renombrarlas rompería sitios sin que nada avise. Van antes que todo lo demás para
   que, a igual especificidad, la clase específica gane.
   ========================================================================== */

/* La caja: borde, radio, superficie. Fondo propio ⇒ declara su color. */
.orderpress-caja {
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    background: var(--orderpress-superficie);
    color: var(--orderpress-text);
}

/* La caja centrada: un mensaje con icono, título, texto y una acción. Es el marco del
   aviso de acceso, de la sección vacía y de la guía de WhatsApp; cada una pone su
   borde y su fondo. place-items centra en los dos ejes de una. */
.orderpress-caja--centrada {
    display: grid;
    justify-items: center;
    gap: var(--orderpress-spacing);
    padding: calc(var(--orderpress-spacing) * 2);
    text-align: center;
    border-radius: calc(var(--orderpress-radius) * 2);
    color: var(--orderpress-text);
}

.orderpress-caja-icono {
    display: inline-grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: var(--orderpress-superficie);
    color: var(--orderpress-primary);
}

.orderpress-caja-icono .orderpress-icono {
    width: 24px;
    height: 24px;
}

.orderpress-caja-titulo {
    margin: 0;
    font-size: 1.25em;
    font-weight: 700;
}

.orderpress-caja-texto {
    margin: 0;
    max-width: 42ch;
    color: var(--orderpress-text-muted);
}

/* Una vista de página entera: una columna, ancho máximo centrado. */
.orderpress-pagina {
    display: grid;
    gap: var(--orderpress-spacing);
    max-width: var(--orderpress-page-max);
    margin: 0 auto;
}

.orderpress-widget {
    font-size: var(--orderpress-font-size);
}

/* El envoltorio de un elemento de Bricks del plugin: a lo ancho, como los elementos
   propios de Bricks (sus contenedores alinean al inicio y un hijo sin ancho se
   achica). Un ancho elegido en el builder va por id y gana. */
.orderpress-bricks-elemento {
    width: 100%;
}

/* ================================================================
   DE QUIÉN ES EL COLOR DEL TEXTO

   .orderpress-widget NO declara color: lo hereda del contenedor donde se embebe.
   El plugin se incrusta en headers oscuros, secciones de color y páginas claras,
   y un color fijo acierta en una sola de las tres.

   El caso que lo destapó: [orderpress_carrito] en un header negro se veía negro
   sobre negro. Y no era que faltara la variable —.orderpress-carrito ya usaba
   --orderpress-carrito-color: inherit— sino que ese 'inherit' heredaba de
   .orderpress-widget, que forzaba --orderpress-text. La variable estaba bien; el
   problema era que había algo arriba imponiendo un color.

   LA REGLA, entonces: **declara color solo lo que trae su propio fondo opaco.**
   Un panel con fondo #f7f7f7 tiene que decir que su texto es oscuro, porque ahí
   heredar del contenedor es justamente lo que lo rompería. Lo que no tiene fondo
   propio hereda, y así se adapta al lugar donde lo pongan.

   Los fondos tenues con color-mix(..., transparent) no cuentan como fondo propio:
   son translúcidos, el contenedor se ve a través, así que heredan igual.
   ================================================================ */


/* ================================================================
   RESET DE CONTROLES

   El plugin se incrusta en temas que no controlamos, así que no alcanza con
   estilar: hay que DECLARAR todo lo que afecta la caja y la apariencia. Lo que
   no se declara, lo decide el tema.

   Caso real que motivó esto: Bricks le imponía line-height: 40px a los inputs,
   y como no lo declarábamos, los campos medían 62 px contra botones de 41.

   Se excluyen checkbox y radio a propósito: appearance: none los deja invisibles
   y habría que redibujarlos enteros.
   ================================================================ */

.orderpress-widget input[type="text"],
.orderpress-widget input[type="email"],
.orderpress-widget input[type="password"],
.orderpress-widget input[type="tel"],
.orderpress-widget input[type="number"],
.orderpress-widget textarea,
.orderpress-widget button,
.orderpress-widget .orderpress-boton {
    box-sizing: border-box;
    margin: 0;
    font-family: var(--orderpress-font-family);
    font-size: var(--orderpress-font-size);
    font-weight: var(--orderpress-control-peso);
    line-height: var(--orderpress-control-line-height);
    letter-spacing: normal;
    text-transform: none;
    text-align: left;
    height: auto;
    min-height: 0;
    max-width: none;
    box-shadow: none;
    /* Una sola transición declarada para todos: si no, el tema mete la suya. */
    transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
}

/* appearance: none saca el estilo nativo del sistema operativo (sobre todo en
   Safari). No se aplica a number para no perder las flechitas de cantidad. */
.orderpress-widget input[type="text"],
.orderpress-widget input[type="email"],
.orderpress-widget input[type="password"],
.orderpress-widget input[type="tel"],
.orderpress-widget textarea,
.orderpress-widget button,
.orderpress-widget .orderpress-boton {
    -webkit-appearance: none;
    appearance: none;
}

.orderpress-widget button,
.orderpress-widget .orderpress-boton {
    font-weight: var(--orderpress-boton-peso);
    text-align: center;
    text-decoration: none;
}

.orderpress-widget textarea {
    resize: vertical;
    min-height: 6em;
}

/* BLOCKQUOTE entra al reset, y llegó tarde porque el plugin no usaba ninguno hasta que la
   ficha del pedido mostró el comentario del cliente como cita. Los temas los estilan con
   fuerza —serif, cursiva, un tamaño distinto, márgenes propios—, y sin declarar nada el
   comentario salía en una tipografía que no era la del resto de la pantalla. Es la misma
   lección que este reset ya tenía escrita para los inputs: lo que no se declara, lo decide
   el tema. */
.orderpress-widget blockquote {
    margin: 0;
    font-family: var(--orderpress-font-family);
    font-size: var(--orderpress-font-size);
    font-style: normal;
    font-weight: 400;
    line-height: var(--orderpress-leading-normal);
    quotes: none;
}

/* Y sin las comillas que algunos temas agregan con ::before: el bloque ya se lee como una
   cita por su filete, y una comilla suelta arriba a la izquierda desalinea el texto. */
.orderpress-widget blockquote::before,
.orderpress-widget blockquote::after {
    content: none;
}

.orderpress-widget ::placeholder {
    color: var(--orderpress-text-muted);
    opacity: 1; /* Firefox le baja la opacidad por su cuenta */
}

.orderpress-widget input:disabled,
.orderpress-widget textarea:disabled {
    background: var(--orderpress-bg-alt);
    color: var(--orderpress-text-muted);
    cursor: not-allowed;
}

/* Los labels del plugin: los temas suelen imponerles peso, tamaño y márgenes. */
.orderpress-widget label {
    display: block;
    box-sizing: border-box;
    margin: 0 0 4px;
    font-family: var(--orderpress-font-family);
    font-size: var(--orderpress-font-size);
    font-weight: 600;
    line-height: var(--orderpress-control-line-height);
    text-transform: none;
    letter-spacing: normal;
    color: var(--orderpress-text);
}

/* ---- Botón "Agregar a cotización" (en cards / detalle de producto) ---- */

/* El selector de cantidad y el botón, en una fila. El botón TOMA EL SOBRANTE y el
   selector se queda con lo suyo (0.141): en una card angosta el botón quedaba chico al
   lado de un selector que no cambia de ancho, y la acción principal terminaba siendo lo
   más chico de la card.

   El space-between no es redundante con el flex-grow: es lo que ordena la fila si el
   botón deja de crecer —el CSS del constructor puede pisar el grow— o si algún día la
   fila lleva un tercer elemento. */
.orderpress-add-box {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--orderpress-space-2);
}

.orderpress-add-box .orderpress-boton {
    flex-grow: 1;
}

.orderpress-qty-input {
    width: 72px;
    padding: var(--orderpress-control-padding-y) 8px;
    text-align: center;
    border: 1px solid var(--orderpress-border-strong);
    border-radius: var(--orderpress-radius);
}

.orderpress-boton {
    padding: var(--orderpress-control-padding-y) calc(var(--orderpress-control-padding-x) * 1.5);
    border: 1px solid transparent;
    border-radius: var(--orderpress-radius);
    line-height: var(--orderpress-control-line-height);
    background: var(--orderpress-primary);
    color: var(--orderpress-primary-contraste);
    cursor: pointer;
    font-size: inherit;
    transition: background-color .15s ease;
}

.orderpress-boton:hover {
    background: var(--orderpress-primary-hover);
}

.orderpress-boton:disabled {
    opacity: .6;
    cursor: default;
}

.orderpress-boton.in-cart {
    background: var(--orderpress-success);
}


.cart-qty-update {
    width: 72px;
    text-align: center;
    padding: calc(var(--orderpress-control-padding-y) / 2) 8px;
    border: 1px solid var(--orderpress-border-strong);
    border-radius: var(--orderpress-radius);
    font-size: inherit;
    font-family: inherit;
    line-height: var(--orderpress-control-line-height);
}

.orderpress-item-quitar {
    color: var(--orderpress-danger);
    background: none;
    border: none;
    cursor: pointer;
    font-size: inherit;
}

.orderpress-item-quitar:hover {
    text-decoration: underline;
}

/* ---- Formularios del plugin (cotización, solicitud de registro) ---- */

/* Sin tope de ancho propio: el formulario mide lo que le dé el contenedor donde se
   embebe, que es quien sabe cuánto lugar hay. Antes tenía 500px fijos, y eso dejaba
   aire muerto a la derecha en cualquier columna más ancha —el plugin decidiendo un
   ancho que no le corresponde—. Queda como variable para poder acotarlo desde el CSS
   del tema si una página puntual lo necesita, sin pelear especificidad. */
.orderpress-form {
    display: grid;
    gap: var(--orderpress-spacing);
    max-width: var(--orderpress-form-max);
}

.orderpress-form label {
    display: block;
    margin-bottom: var(--orderpress-space-1);
    font-weight: 600;
}

.orderpress-form input[type="text"],
.orderpress-form input[type="email"],
.orderpress-form input[type="password"],
.orderpress-form textarea {
    width: 100%;
    padding: var(--orderpress-control-padding-y) var(--orderpress-control-padding-x);
    border: 1px solid var(--orderpress-border-strong);
    border-radius: var(--orderpress-radius);
    font-size: inherit;
    font-family: inherit;
    line-height: var(--orderpress-control-line-height);
}

/* Fila de checkbox: el label va al lado del input, no encima como en el resto
   del formulario. Con dos pistas para que una etiqueta larga que envuelve no arrastre
   al control. */
.orderpress-form-check {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: var(--orderpress-space-2);
}

.orderpress-form-check label {
    margin-bottom: 0;
    font-weight: 400;
}

.orderpress-form-links {
    margin: 0;
    color: var(--orderpress-text-muted);
    font-size: .92em;
}

/* Cada link del pie va en su propia fila, así que cuando hay más de uno hacen
   falta unos pixeles entre ellos. Con el selector de hermano adyacente y no un
   contenedor con gap: el pie puede tener uno o dos, y así el caso de uno solo no
   arrastra un div que no hace nada. */
.orderpress-form-links + .orderpress-form-links {
    margin-top: calc(var(--orderpress-spacing) / 2);
}

/* El link secundario, en el gris del texto tenue.
   En el pie del login hay dos acciones que no pesan igual: "solicitar acceso" es
   un camino nuevo y se queda con el color; "olvidé mi contraseña" es una salida de
   emergencia. Con los dos del color primario no había jerarquía y había que leer
   los dos para saber cuál era cuál.
   Lleva .orderpress-widget adelante para ganarle a `.orderpress-form-links a`, que
   con 0-1-1 le empataría a una sola clase. */
.orderpress-widget .orderpress-link-suave {
    color: var(--orderpress-text-muted);
    text-decoration: underline;
}

.orderpress-widget .orderpress-link-suave:hover {
    color: var(--orderpress-primary);
}

.orderpress-form-links a,
.orderpress-logout {
    color: var(--orderpress-primary);
}

.orderpress-form-links a:hover,
.orderpress-logout:hover {
    color: var(--orderpress-primary-hover);
}

/* Foco visible: solo para navegación por teclado (:focus-visible no se dispara
   al hacer clic), así que no ensucia el diseño y el formulario sigue siendo
   usable sin mouse. */
.orderpress-widget input:focus-visible,
.orderpress-widget textarea:focus-visible {
    border-color: var(--orderpress-primary);
    outline: none;
    box-shadow: 0 0 0 3px var(--orderpress-primary-suave);
}

.orderpress-boton:focus-visible,
.orderpress-form-submit:focus-visible,
.orderpress-item-quitar:focus-visible,
.orderpress-widget a:focus-visible {
    outline: 2px solid var(--orderpress-primary);
    outline-offset: 2px;
}

.orderpress-form-submit {
    padding: var(--orderpress-control-padding-y) var(--orderpress-control-padding-x);
    background: var(--orderpress-primary);
    color: var(--orderpress-primary-contraste);
    /* Borde transparente en vez de none: así el botón tiene el mismo modelo de
       caja que los inputs y las alturas coinciden exactas. */
    border: 1px solid transparent;
    border-radius: var(--orderpress-radius);
    cursor: pointer;
    font-size: inherit;
    line-height: var(--orderpress-control-line-height);
}

.orderpress-form-submit:hover {
    background: var(--orderpress-primary-hover);
}

/* Los botones de envío, uno por canal de confirmación: lado a lado si entran, apilados
   si no. El de WhatsApp lleva su verde —es la marca que el cliente reconoce— y el
   contraste se calcula igual que para el primario. */
.orderpress-form-botones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--orderpress-space-2);
}

.orderpress-form-submit--whatsapp,
.orderpress-widget .orderpress-boton-whatsapp {
    background: var(--orderpress-whatsapp);
    color: var(--orderpress-whatsapp-contraste);
}

.orderpress-form-submit--whatsapp:hover,
.orderpress-widget .orderpress-boton-whatsapp:hover {
    background: var(--orderpress-whatsapp-hover);
}

.orderpress-widget .orderpress-boton-whatsapp {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--orderpress-space-2);
    padding: var(--orderpress-control-padding-y) var(--orderpress-control-padding-x);
    border: 1px solid transparent;
    border-radius: var(--orderpress-radius);
    text-decoration: none;
    font-weight: 600;
}

.orderpress-form-submit:disabled {
    opacity: .6;
    cursor: default;
}

/* ---- Mensaje vacío / estado de éxito post-envío ---- */

#orderpress-empty-msg {
    color: var(--orderpress-text-muted);
}

.orderpress-estado {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    gap: 10px;
    padding: var(--orderpress-spacing);
    /* Separa el aviso de lo que sigue (las pestañas de Mi cuenta, un formulario):
       sin esto quedaba pegado al contenido de abajo. Mismo paso que el resto de
       los bloques del frontend. */
    margin-bottom: calc(var(--orderpress-spacing) * 2);
    border-radius: var(--orderpress-radius);
    font-size: inherit;
}

.orderpress-estado svg {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    margin-top: 2px;
}

.orderpress-estado--exito {
    background: color-mix(in srgb, var(--orderpress-success) 12%, transparent);
    color: var(--orderpress-success);
}

.orderpress-estado--error {
    background: color-mix(in srgb, var(--orderpress-danger) 12%, transparent);
    color: var(--orderpress-danger);
}

/* Aviso: no es un error, es "esto cambió y te lo digo" (una cantidad ajustada a la
   regla del producto). */
.orderpress-estado--aviso {
    background: color-mix(in srgb, var(--orderpress-warning) 12%, transparent);
    color: var(--orderpress-warning);
}

/* ---- Página "Mi cuenta" ([orderpress_cuenta]) ---- */

/* LA NAV NO LLEVA PADDING ABAJO: lo lleva cada enlace.
   El filete de la pestaña activa tiene que caer EXACTAMENTE sobre el de la fila, y antes no
   caía por diseño sino por casualidad: el activo era un box-shadow pegado al texto y el de
   la fila un border 12px más abajo, así que coincidían solo mientras el tema le pusiera al
   <a> el padding justo. Con el padding en el enlace y su borde solapando el de la fila con
   un margin negativo, coinciden por construcción.

   La separación con el contenido son 24px, el mismo número que se fijó para las pestañas del
   admin: son la misma clase de navegación y no hay motivo para que respiren distinto. */
.orderpress-cuenta-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: calc(var(--orderpress-spacing) * 1.5);
    margin-bottom: calc(var(--orderpress-spacing) * 2);
    border-bottom: 1px solid var(--orderpress-border);
}

.orderpress-cuenta-nav a {
    padding-bottom: var(--orderpress-spacing);
    /* El filete transparente reserva el lugar del que lleva la activa: sin él, cambiar de
       pestaña movería todos los textos dos píxeles. Y el margen negativo hace que ese
       filete se apoye sobre el de la fila en vez de quedar arriba. */
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--orderpress-text-muted);
    text-decoration: none;
    font-weight: 600;
}

.orderpress-cuenta-nav a:hover {
    color: var(--orderpress-text);
}

.orderpress-cuenta-nav a:hover {
    color: var(--orderpress-primary);
}

/* El activo pinta ese filete. 2px contra el 1px de la fila a propósito: tiene que leerse
   como que REEMPLAZA ese tramo de la línea, no como una segunda línea encima. */
.orderpress-cuenta-nav a.is-activo {
    color: var(--orderpress-primary);
    border-bottom-color: var(--orderpress-primary);
}

/* Empujado al extremo opuesto: es una acción de salida, no una sección más. */
.orderpress-cuenta-nav-salir {
    margin-left: auto;
}

.orderpress-cuenta-panel > :first-child {
    margin-top: 0;
}

/* El panel es contenedor de consulta para que el formulario de datos se acomode por
   el ancho del PANEL y no de la pantalla: Mi cuenta puede estar en una columna
   angosta de Bricks y ahí dos columnas de campos no entran. */
.orderpress-cuenta-panel {
    container-type: inline-size;
}

/* ---- Formulario de dos campos por fila ---- */

/* Arranca en una columna y suma la segunda cuando hay lugar. Con cuatro campos
   cortos, dos filas se leen de un vistazo; cuatro filas de una línea hacen bajar el
   ojo por una columna larga para nada. */
.orderpress-form--pares {
    grid-template-columns: minmax(0, 1fr);
}

/* El umbral va como número literal: @container no acepta custom properties. */
@container (min-width: 560px) {
    .orderpress-form--pares {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Respaldo para navegadores sin container queries: por ancho de pantalla. */
@supports not (container-type: inline-size) {
    @media (min-width: 860px) {
        .orderpress-form--pares {
            grid-template-columns: repeat(2, minmax(0, 1fr));
        }
    }
}

/* La ayuda y el botón no son campos: cruzan las dos columnas. Y el botón se mide por
   su contenido, porque ahora que el formulario no tiene tope de ancho, estirarlo
   daría un botón de "Guardar cambios" de todo el ancho del panel. */
.orderpress-form--pares > .orderpress-campo-ayuda,
.orderpress-form--pares > .orderpress-form-submit {
    grid-column: 1 / -1;
}

.orderpress-form--pares > .orderpress-form-submit {
    justify-self: start;
}

.orderpress-dato-secundario {
    color: var(--orderpress-text-muted);
    font-size: .92em;
}

.orderpress-paginacion {
    display: grid;
    grid-auto-flow: column;
    justify-content: start;
    align-items: center;
    gap: var(--orderpress-spacing);
    color: var(--orderpress-text-muted);
    font-size: .92em;
}

/* ---- Badges de estado de pedido ---- */

/* Chico, igual que en el admin y por lo mismo: el estado es un dato de apoyo, no el
   contenido de la fila. En el listado de pedidos del cliente compite con el número y la
   fecha, que es lo que uno recorre con la vista.
   El tamaño va en em y no en px: acompaña la tipografía del sitio donde se embeba, que es
   la regla de todo el frontend del plugin. */
.orderpress-badge {
    display: inline-block;
    padding: 1px 7px;
    border-radius: var(--orderpress-radius-full);
    font-size: .68em;
    font-weight: 600;
    line-height: var(--orderpress-leading-relaxed);
    text-transform: uppercase;
    letter-spacing: .03em;
    vertical-align: middle;
    white-space: nowrap;
}

/* Los fondos se calculan del color base con color-mix(): un solo valor por
   estado alcanza, y no hay pares de colores que mantener sincronizados. */
.orderpress-badge--nuevo {
    background: color-mix(in srgb, var(--orderpress-warning) 15%, transparent);
    color: var(--orderpress-warning);
}

.orderpress-badge--respondido {
    background: color-mix(in srgb, var(--orderpress-success) 15%, transparent);
    color: var(--orderpress-success);
}

.orderpress-badge--completado {
    background: color-mix(in srgb, var(--orderpress-text-muted) 15%, transparent);
    color: var(--orderpress-text-muted);
}

/* Faltaba desde que se sumó el estado en 0.51.0: se estiló en el admin y no acá, así que
   un pedido cancelado mostraba la palabra sin fondo. Solo se veía cuando un cliente tenía
   uno, que es la clase de olvido que no aparece hasta que ya está en producción.
   Comparte el rojo de 'rechazado' del admin: las dos son una salida sin resolver. */
.orderpress-badge--cancelado {
    background: color-mix(in srgb, var(--orderpress-danger) 14%, transparent);
    color: var(--orderpress-danger);
}

/* El producto discontinuado, en el lugar del botón de agregar (F1). Neutro, no rojo: no
   es un problema, es un dato. */
.orderpress-badge--discontinuado,
.orderpress-badge--agotado {
    background: color-mix(in srgb, var(--orderpress-text-muted) 15%, transparent);
    color: var(--orderpress-text-muted);
}

/* ---- Contador de ítems y carrito del header ---- */

/* Clase y no id: el carrito puede estar en el header de escritorio y en el
   mobile a la vez, y los dos tienen que actualizarse. */
.orderpress-total-items {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--orderpress-radius-full);
    background: var(--orderpress-primary);
    color: var(--orderpress-primary-contraste);
    font-size: 12px;
    font-weight: 700;
}

/* ---- Iconos SVG inline ---- */

.orderpress-icono {
    width: 1.15em;
    height: 1.15em;
    flex-shrink: 0;
    vertical-align: -0.15em;
}

/* ---- Cajas con cuerpo: acceso y sección vacía ---- */

/* Las dos son el mismo componente con distinto contenido, así que comparten la
   definición en vez de ser dos bloques parecidos que se van separando con el
   tiempo. Se agrupan los selectores en lugar de renombrar las clases: el CSS del
   constructor puede estar apuntando a .orderpress-acceso-*. */
.orderpress-acceso,
.orderpress-vacio {
    border: 2px dashed var(--orderpress-border-strong);
    background: var(--orderpress-bg-alt);
}

/* Con .orderpress-widget adelante, y no por gusto: el reset de controles declara
   `max-width: none` con .orderpress-widget .orderpress-boton (0-2-0) para neutralizar lo que
   ponga el tema, y eso le ganaba al max-width de esta clase sola (0-1-0). El botón
   venía midiendo todo el ancho de la caja en vez de los 380 declarados. Es el mismo
   choque que tuvo el botón del ojo en los campos de contraseña. */
.orderpress-widget .orderpress-acceso-boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--orderpress-space-2);
    width: 100%;
    max-width: 380px;
    text-decoration: none;
}

.orderpress-acceso-link {
    color: var(--orderpress-text-muted);
    font-size: .92em;
    text-decoration: none;
}

.orderpress-acceso-link:hover {
    color: var(--orderpress-primary);
    text-decoration: underline;
}

/* La versión de un renglón ([orderpress_aviso formato="linea"]): candado y texto,
   todo enlace. Del tamaño de un precio, para una card o al lado de uno. Muted a
   propósito: es un recordatorio, no la invitación — esa es la caja. */
.orderpress-acceso-linea {
    display: inline-flex;
    align-items: center;
    gap: var(--orderpress-space-2);
    color: var(--orderpress-text-muted);
    text-decoration: none;
}

.orderpress-acceso-linea .orderpress-icono {
    width: 1em;
    height: 1em;
}

.orderpress-acceso-linea:hover {
    color: var(--orderpress-primary);
    text-decoration: underline;
}

/* La guía del pedido por WhatsApp, arriba de la ficha en Mi cuenta: es lo único que el
   cliente tiene que hacer en esa pantalla, así que va marcada con el verde del canal y
   el botón grande. Misma caja que el aviso de acceso, con el borde del canal. */
.orderpress-whatsapp-guia {
    gap: var(--orderpress-space-2);
    margin-bottom: var(--orderpress-spacing);
    border: 2px solid var(--orderpress-whatsapp);
    background: color-mix(in srgb, var(--orderpress-whatsapp) 10%, transparent);
}

.orderpress-whatsapp-guia-texto {
    max-width: 48ch;
}

/* La página de confirmación: una sola columna, angosta, con lo primero grande (el
   "listo" o la guía de WhatsApp), el resumen debajo y dos salidas. Reusa la caja y la
   tabla de la ficha; solo agrega el hero y las salidas. */
.orderpress-confirmacion-hero {
    display: grid;
    justify-items: center;
    gap: var(--orderpress-space-2);
    padding: calc(var(--orderpress-spacing) * 2) var(--orderpress-spacing);
    text-align: center;
}

.orderpress-confirmacion-icono {
    width: 64px;
    height: 64px;
    background: var(--orderpress-primary-suave);
}

.orderpress-confirmacion-icono .orderpress-icono {
    width: 28px;
    height: 28px;
}

.orderpress-confirmacion-titulo {
    font-size: var(--orderpress-text-xl);
}

.orderpress-confirmacion-texto {
    max-width: 48ch;
}

.orderpress-confirmacion-salidas {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--orderpress-spacing);
}

.orderpress-widget .orderpress-confirmacion-salidas .orderpress-boton {
    text-decoration: none;
}

.orderpress-confirmacion-link {
    color: var(--orderpress-text-muted);
    text-decoration: none;
}

.orderpress-confirmacion-link:hover {
    color: var(--orderpress-primary);
    text-decoration: underline;
}

/* ---- Mensajes junto al botón de agregar ---- */

.orderpress-add-wrap {
    display: flex;
    flex-direction: column;
    gap: var(--orderpress-space-2);
}

.orderpress-add-msg {
    margin: 0;
    font-size: .9em;
    /* Arranca ocupando lugar cero para que el layout no salte al aparecer. */
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    transition: opacity .2s ease, max-height .2s ease;
}

.orderpress-add-msg.is-visible {
    max-height: 4em;
    opacity: 1;
}

.orderpress-add-msg--exito {
    color: var(--orderpress-success);
}

.orderpress-add-msg--error {
    color: var(--orderpress-danger);
}

/* El selector de variantes de la ficha (F4): un select por atributo, en línea. */
.orderpress-variantes-selector {
    display: flex;
    flex-wrap: wrap;
    gap: var(--orderpress-spacing);
    margin-bottom: calc(var(--orderpress-spacing) / 1.5);
}

.orderpress-variantes-campo {
    display: flex;
    flex-direction: column;
    gap: calc(var(--orderpress-spacing) / 4);
    font-size: .9em;
}

.orderpress-variantes-nombre {
    color: var(--orderpress-text-muted);
}

.orderpress-widget .orderpress-variantes-selector select {
    padding: var(--orderpress-control-padding-y) var(--orderpress-control-padding-x);
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    background: var(--orderpress-superficie);
    color: var(--orderpress-text);
    font: inherit;
    line-height: var(--orderpress-control-line-height);
}

.orderpress-variantes-detalle {
    display: flex;
    gap: calc(var(--orderpress-spacing) / 1.5);
    margin: 0 0 calc(var(--orderpress-spacing) / 1.5);
    color: var(--orderpress-text-muted);
    font-size: .9em;
}

.orderpress-variantes-precio {
    color: var(--orderpress-text);
    font-weight: var(--orderpress-weight-semibold);
}

/* El botón apagado hasta elegir una combinación. */
.orderpress-widget .orderpress-boton[disabled] {
    opacity: .5;
    cursor: not-allowed;
}

/* La regla del producto debajo del botón: "Mínimo 12 · se pide de a 6" (F1). */
.orderpress-add-regla {
    margin: calc(var(--orderpress-spacing) / 3) 0 0;
    color: var(--orderpress-text-muted);
    font-size: .85em;
}

.orderpress-aviso-tabla:empty {
    display: none;
}

/* Destello de confirmación tras agregar: dura poco a propósito. Un verde
   permanente se leía como "recién ahora está habilitado", cuando en realidad
   el producto ya estaba agregado. */
.orderpress-boton.is-confirmado {
    background: var(--orderpress-success);
}

/* ---- Botón de mostrar contraseña ---- */

.orderpress-campo-password {
    position: relative;
    display: block;
}

.orderpress-campo-password input[type="password"],
.orderpress-campo-password input[type="text"] {
    padding-right: var(--orderpress-space-8);
}

/* Con .orderpress-widget adelante a propósito: el reset de controles usa
   `.orderpress-widget button`, que con 0-1-1 le gana a una sola clase y le
   imponía height: auto. Esto lo lleva a 0-2-0 y el botón recupera su tamaño. */
.orderpress-widget .orderpress-ver-password {
    position: absolute;
    right: 4px;
    /* Centrado contra el input, no contra el borde inferior: así no depende de
       la altura del control, que es configurable por variable. */
    top: 50%;
    transform: translateY(-50%);
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: var(--orderpress-radius);
    background: none;
    color: var(--orderpress-text-muted);
    cursor: pointer;
}

.orderpress-widget .orderpress-ver-password:hover {
    color: var(--orderpress-primary);
}

.orderpress-widget .orderpress-ver-password .orderpress-icono {
    width: 20px;
    height: 20px;
}

/* Utilidad de WordPress para texto solo audible por lectores de pantalla.
   Se redeclara porque el CSS del core no siempre está encolado en el frontend. */
.orderpress-widget .screen-reader-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---- Icono de carrito del header ([orderpress_carrito]) ---- */

.orderpress-carrito {
    display: inline-grid;
    grid-auto-flow: column;
    align-items: center;
    gap: var(--orderpress-space-2);
    color: var(--orderpress-carrito-color);
    text-decoration: none;
    line-height: 1;
}

.orderpress-carrito:hover {
    color: var(--orderpress-primary);
}

.orderpress-carrito .orderpress-icono {
    width: 1.6em;
    height: 1.6em;
}

.orderpress-carrito-texto {
    font-size: .95em;
}

/* El envoltorio del icono es el contexto de posicionamiento de la burbuja.

   Existe para que la burbuja se ancle al ICONO y no al enlace. Anclada al enlace
   había que desplazarla desde su borde izquierdo, y ese número solo daba bien
   cuando el carrito no llevaba etiqueta de texto al lado; con etiqueta, la burbuja
   caía en cualquier parte. Y como el envoltorio es nuestro, el anclaje no depende
   de que el tema o el constructor no le cambien el position al <a>, que es donde se
   escapaba. */
.orderpress-carrito-icono {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
}

/* La burbuja se monta en la esquina del icono. Con position absolute para que no
   empuje nada al aparecer y desaparecer.

   Se ancla CENTRÁNDOLA sobre la esquina superior derecha —left:100% top:0 y un
   translate de la mitad— en vez de con desplazamientos fijos. El motivo es concreto:
   con `right: -8px`, una burbuja de 28px sobre un icono de 25px arrancaba a 5px del
   borde izquierdo y lo tapaba entero. Con el translate queda bien puesta sin importar
   cuánto mida la burbuja ni el icono, que es lo que cambia cuando el número pasa de
   una a dos cifras o cuando el tema cambia el tamaño de fuente. */
.orderpress-carrito-burbuja {
    position: absolute;
    top: 0;
    left: 100%;
    transform: translate(-50%, -50%);
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    font-size: 11px;
}

/* En cero se oculta desde el CSS, por el data-count que escribe el servidor y
   actualiza el JS: así el JS no necesita lógica de mostrar y ocultar. */
.orderpress-carrito-burbuja[data-count="0"] {
    display: none;
}

/* Con ocultar_vacio="si" desaparece el carrito completo, no solo la burbuja.
   Se resuelve con :has() para no sumarle al JS lógica de visibilidad: el JS ya
   escribe el data-count de la burbuja y esto reacciona a eso, así que sigue
   funcionando al vaciar la lista sin recargar. */
.orderpress-carrito--ocultar-vacio:has(.orderpress-carrito-burbuja[data-count="0"]) {
    display: none;
}

/* ============================================================
   PRECIO
   ============================================================ */

/* Un bloque y no un texto suelto: el precio se pone al lado del botón de agregar,
   y necesita peso propio para no leerse como una línea más de la ficha. El tamaño
   sale de una variable para que se pueda ajustar desde el CSS del constructor sin
   pelear especificidad. */
.orderpress-widget.orderpress-precio {
    display: grid;
    grid-auto-flow: column;
    justify-content: start;
    align-items: baseline;
    gap: calc(var(--orderpress-spacing) / 2);
}

/* "desde $X" cuando las variantes tienen precios distintos (F3): el número es el
   mínimo, y la palabra lo dice en chico. */
.orderpress-precio-desde {
    font-size: .8em;
    color: var(--orderpress-text-muted);
}

.orderpress-precio-valor {
    font-size: var(--orderpress-precio-size);
    font-weight: var(--orderpress-boton-peso);
    line-height: var(--orderpress-control-line-height);
    color: var(--orderpress-text);
    /* Los dígitos con el mismo ancho: sin esto, en una grilla de productos los
       precios quedan de largos distintos y las columnas bailan. */
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   PÁGINA DEL PEDIDO EN CURSO
   ============================================================ */

/* Dos columnas: el formulario a la izquierda y el resumen a la derecha. El resumen
   queda fijo mientras se scrollea el formulario, así se ve lo que se está pidiendo
   mientras se completan los datos.

   Con grid y no con flex porque las dos columnas tienen anchos de naturaleza
   distinta —una fluida y una fija— y eso en grid es una línea. */
.orderpress-pedido-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--orderpress-form-ancho);
    gap: var(--orderpress-pedido-gap);
    align-items: start;
}

/* Se apilan por el ancho del CONTENEDOR y no de la pantalla: el shortcode puede
   estar en una columna angosta de una plantilla, y ahí dos columnas no entran aunque
   la pantalla sea grande.

   El umbral es 820px: con el formulario en 460 y el gap en 40, por debajo de eso al
   resumen le quedan menos de 320 y ahí sí conviene apilarlo para que se quede con todo
   el ancho. Arriba de 820 alcanza, porque el resumen es su propio contenedor y sus
   filas se reacomodan solas cuando la columna es angosta.

   Los umbrales van como número literal: @container no acepta custom properties. */
@container (max-width: 820px) {
    .orderpress-pedido-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Respaldo para navegadores sin container queries: se apila por ancho de pantalla. */
@supports not (container-type: inline-size) {
    @media (max-width: 820px) {
        .orderpress-pedido-grid {
            grid-template-columns: minmax(0, 1fr);
        }
    }
}

.orderpress-pedido {
    container-type: inline-size;
}

/* El panel es la columna del formulario y no el resumen: el resumen es una lista y se
   lee mejor sobre el fondo de la página, mientras el formulario es un bloque de
   controles y el fondo lo agrupa como una unidad. */
.orderpress-pedido-col {
    padding: calc(var(--orderpress-spacing) * 1.5);
    border-radius: var(--orderpress-radius);
    background: var(--orderpress-form-fondo);
    /* Fondo propio ⇒ declara su color. */
    color: var(--orderpress-text);
}

/* ---- Títulos del pedido ---- */

.orderpress-pedido-titulo {
    margin: 0;
    font-size: 1.35em;
    font-weight: 700;
}

.orderpress-pedido-nota,
.orderpress-campo-ayuda {
    margin: calc(var(--orderpress-spacing) / 3) 0 0;
    color: var(--orderpress-text-muted);
    font-size: .9em;
}

/* La única diferencia con .orderpress-campo-ayuda es que esta separa del formulario
   que viene abajo. */
.orderpress-pedido-nota {
    margin-bottom: var(--orderpress-spacing);
}

/* El honeypot: fuera de la pantalla pero sin display:none, que algunos bots
   detectan y esquivan. Estaba con style inline en el markup. */
.orderpress-honeypot {
    position: absolute;
    left: -9999px;
}

/* ---- El resumen ---- */

/* Contenedor propio, y es lo que hace que los ítems funcionen: sin esto, sus
   @container medían el ancho de toda la pantalla del pedido y usaban el layout ancho
   dentro de una columna angosta — el título salía partido palabra por palabra y el
   stepper se le montaba encima. */
.orderpress-resumen {
    container-type: inline-size;
    position: var(--orderpress-resumen-position);
    top: var(--orderpress-resumen-top);
    /* Se conserva el padding aunque no haya fondo: el listado necesita respirar del
       borde igual, y sin él las filas quedarían pegadas al límite de la columna. */
    padding: var(--orderpress-spacing) calc(var(--orderpress-spacing) * 1.5);
}

/* Al apilarse deja de estar fijo: pegado arriba en una sola columna taparía el
   formulario mientras se scrollea. */
@container (max-width: 820px) {
    .orderpress-resumen {
        position: static;
    }
}

/* Grid y no flex con space-between: con dos pistas declaradas, la etiqueta y el valor
   caen siempre en el mismo lugar, sin depender de cuánto mida el texto. */
.orderpress-resumen-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--orderpress-spacing);
    padding-bottom: calc(var(--orderpress-spacing) / 1.5);
    border-bottom: 1px solid var(--orderpress-border-strong);
}

.orderpress-resumen-count {
    color: var(--orderpress-text-muted);
    font-size: .85em;
    font-weight: 600;
    white-space: nowrap;
}

.orderpress-resumen-items {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* ---- Cada ítem ---- */

/* Una sola grilla con áreas nombradas, y los cinco elementos como hijos directos.
   Antes eran envoltorios flex anidados con space-between, y eso tenía un problema que
   no se ve en una fila sola: el stepper de cada ítem quedaba en una x distinta según
   el largo del título. Con las mismas pistas en todas las filas, las columnas se
   alinean entre sí — que es lo que hace que una lista se lea como una lista. */
.orderpress-item {
    display: grid;
    grid-template-columns: var(--orderpress-item-foto) minmax(0, 1fr) auto auto auto;
    grid-template-areas: "foto datos cantidad subtotal quitar";
    align-items: center;
    gap: var(--orderpress-spacing);
    padding: var(--orderpress-spacing) 0;
    border-bottom: 1px solid var(--orderpress-border);
}

/* Angosto: la foto a la izquierda ocupando el alto, el texto arriba, y abajo la
   cantidad con el subtotal y el Quitar. Es el orden de la propuesta para mobile. */
@container (max-width: 620px) {
    .orderpress-item {
        grid-template-columns: var(--orderpress-item-foto) minmax(0, 1fr) auto;
        grid-template-areas:
            "foto datos    datos"
            "foto cantidad subtotal"
            "foto quitar   quitar";
        align-items: start;
        row-gap: calc(var(--orderpress-spacing) / 1.5);
    }
}

@supports not (container-type: inline-size) {
    @media (max-width: 620px) {
        .orderpress-item {
            grid-template-columns: var(--orderpress-item-foto) minmax(0, 1fr) auto;
            grid-template-areas:
                "foto datos    datos"
                "foto cantidad subtotal"
                "foto quitar   quitar";
            align-items: start;
            row-gap: calc(var(--orderpress-spacing) / 1.5);
        }
    }
}

.orderpress-item-foto {
    grid-area: foto;
    align-self: start;
    /* box-sizing acá y no heredado: el reset solo lo declara para los controles, así
       que sin esto el borde sumaría 2px y sacaría la miniatura de su pista del grid,
       desalineándola del resto de la columna. */
    box-sizing: border-box;
    display: block;
    width: var(--orderpress-item-foto);
    height: var(--orderpress-item-foto);
    overflow: hidden;
    /* El mismo borde que los campos de cantidad —misma variable, no un gris nuevo—
       para que la fila se lea como un conjunto y no como piezas de distinto origen. */
    border: 1px solid var(--orderpress-border-strong);
    border-radius: calc(var(--orderpress-radius) / 2);
    background: var(--orderpress-bg-alt);
}

.orderpress-item-foto img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.orderpress-item-datos {
    grid-area: datos;
}

.orderpress-item .orderpress-cantidad {
    grid-area: cantidad;
}

.orderpress-item-subtotal {
    grid-area: subtotal;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.orderpress-item .orderpress-item-quitar {
    grid-area: quitar;
    justify-self: start;
}

.orderpress-item-titulo {
    display: block;
    color: var(--orderpress-text);
    font-weight: 600;
    line-height: var(--orderpress-leading-snug);
    text-decoration: none;
}

.orderpress-item-titulo:hover {
    color: var(--orderpress-primary);
}

.orderpress-item-meta {
    margin: calc(var(--orderpress-spacing) / 4) 0 0;
    color: var(--orderpress-text-muted);
    font-size: .85em;
}

/* ---- El campo de cantidad ---- */

/* Dos estilos del MISMO control, elegidos en Ajustes. El contenedor existe en los
   dos —aunque en el nativo solo envuelve el input— porque es el que se engancha a la
   pista 'cantidad' de la grilla del ítem: sin él, cambiar de estilo movería el campo
   de lugar. */

/* Con botones: inline-grid con flujo en columna, que hace lo mismo que inline-flex y
   deja las tres pistas declaradas, en línea con el resto de la pantalla. */
.orderpress-cantidad--pasos {
    display: inline-grid;
    grid-auto-flow: column;
    align-items: stretch;
    justify-self: start;
    overflow: hidden;
    border: 1px solid var(--orderpress-border-strong);
    border-radius: var(--orderpress-radius);
    background: var(--orderpress-superficie);
    /* Fondo propio ⇒ declara su color, y de acá lo heredan el input y los botones. */
    color: var(--orderpress-text);
}

/* Con .orderpress-widget adelante para ganarle al reset de controles, que con
   `.orderpress-widget button` (0-1-1) le impondría su propia altura. */
.orderpress-widget .orderpress-stepper-btn {
    width: 40px;
    min-height: 40px;
    padding: 0;
    border: none;
    border-radius: 0;
    background: none;
    color: var(--orderpress-text);
    font-size: 1.1em;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.orderpress-widget .orderpress-stepper-btn:hover {
    background: var(--orderpress-primary-suave);
    color: var(--orderpress-primary);
}

/* El input del medio: sin borde propio —lo da el contenedor— y sin las flechas del
   navegador, que al lado de los botones son dos controles para lo mismo.

   Se apunta por el contexto y por el tipo, NO por la clase del input: esa clase dice
   qué hace el JS con el campo ('cart-qty-update' se manda solo, 'orderpress-qty-input'
   espera el botón), y el aspecto no tiene nada que ver con eso. Atarlos era lo que
   hacía que el mismo control se viera distinto en cada pantalla. */
.orderpress-widget .orderpress-cantidad--pasos input[type="number"] {
    width: 3.5em;
    min-height: 40px;
    padding: 0;
    border: none;
    border-left: 1px solid var(--orderpress-border);
    border-right: 1px solid var(--orderpress-border);
    border-radius: 0;
    background: none;
    text-align: center;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    -moz-appearance: textfield;
    appearance: textfield;
}

.orderpress-cantidad--pasos input[type="number"]::-webkit-outer-spin-button,
.orderpress-cantidad--pasos input[type="number"]::-webkit-inner-spin-button {
    margin: 0;
    -webkit-appearance: none;
    appearance: none;
}

/* Nativo: el contenedor no dibuja nada, solo agrupa para ocupar la pista de la
   grilla. El input se queda con el borde y el ancho que ya tenía por su clase. */
.orderpress-cantidad--nativo {
    display: grid;
    justify-self: start;
}

/* ---- El total ---- */

.orderpress-resumen-total {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--orderpress-spacing);
    padding-top: var(--orderpress-spacing);
    border-top: 1px solid var(--orderpress-border-strong);
    font-weight: 700;
}

.orderpress-resumen-total strong {
    font-size: 1.5em;
    font-variant-numeric: tabular-nums;
}

/* El total de productos reusa .orderpress-total-items para que el JS lo actualice sin
   una línea de lógica nueva, pero acá NO es la burbuja del header: es el número de
   cierre del resumen. Se le saca el aspecto de píldora, que es lo que se trajo de
   arrastre junto con el comportamiento. */
.orderpress-resumen-total .orderpress-total-items {
    min-width: 0;
    height: auto;
    padding: 0;
    border-radius: 0;
    background: none;
    color: inherit;
    font-size: 1.5em;
    font-weight: 700;
}

.orderpress-resumen-nota {
    margin: calc(var(--orderpress-spacing) / 1.5) 0 0;
    color: var(--orderpress-text-muted);
    font-size: .85em;
    line-height: var(--orderpress-leading-normal);
}

/* La compra mínima, debajo del total. Mientras falta, el "te faltan…" va en el color
   de peligro: es lo único que impide enviar y tiene que leerse antes que el botón
   apagado. Al llegar, el JS esconde ese tramo y queda solo el dato, en muted. */
.orderpress-resumen-minimo,
.orderpress-resumen-unidades {
    margin: calc(var(--orderpress-spacing) / 1.5) 0 0;
    color: var(--orderpress-text-muted);
    font-size: .9em;
    font-variant-numeric: tabular-nums;
}

.orderpress-resumen-minimo[data-cumple="0"] #orderpress-minimo-falta {
    color: var(--orderpress-danger);
    font-weight: 600;
}

/* El botón de enviar, con la flecha a la derecha. */
.orderpress-widget .orderpress-form-submit {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: calc(var(--orderpress-spacing) / 1.5);
}

.orderpress-form-submit .orderpress-icono {
    width: 1.1em;
    height: 1.1em;
}

/* ============================================================
   POR QUÉ QUEDA ALGO DE FLEXBOX
   ============================================================

   El criterio, para no convertir por convertir:

   - DISPOSICIÓN de filas o columnas → grid. Pilas, filas de dos pistas, y listas cuyas
     columnas tienen que alinearse entre ítems. Grid declara las pistas, así que el
     resultado no depende del largo del contenido.
   - CENTRAR un solo hijo → `place-items: center`. Una declaración en vez de tres.
   - CONTENIDO de un botón o control en línea (icono + texto) → flex. Ahí no hay pistas
     que declarar: es una línea de contenido fluyendo, y `gap` funciona igual.
   - CANTIDAD VARIABLE de elementos que tienen que envolver → flex. Es el único caso
     donde grid pierde de verdad: `flex-wrap` acomoda lo que venga, y para replicarlo en
     grid hay que decidir cuántas columnas hay, que es justo lo que no se sabe.

   Por eso siguen en flex: los botones (.orderpress-boton, .orderpress-acceso-boton,
   .orderpress-form-submit), que centran icono y texto en línea, y la navegación de Mi
   cuenta (.orderpress-cuenta-nav), que envuelve una cantidad de pestañas que depende de
   cuántas secciones tenga. */


/* ---- "Volver a pedir" ---- */

/* El formulario no ocupa lugar: es un botón envuelto en un <form> porque la acción
   modifica el carrito y no puede viajar por GET —la prefetch del navegador la
   dispararía sola—, pero visualmente tiene que ser un botón nada más. */
.orderpress-repetir {
    display: inline;
    margin: 0;
}

/* Separado del enlace que tiene al lado. Sin esto, en la celda del listado quedaba
   "Ver detalle Volver a pedir" pegado y se leía como una sola frase. El separador es un
   punto medio y no un espacio: dos acciones distintas necesitan que se vea que son dos. */
.orderpress-acciones-pedido {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px;
}

.orderpress-acciones-pedido > * + *::before {
    content: "·";
    margin-right: 6px;
    color: var(--orderpress-text-muted);
}

/* En la fila del listado va como enlace y no como botón: al lado de "Ver detalle"
   tienen el mismo peso, y dos botones en una celda de tabla compiten entre sí. */
.orderpress-repetir-link {
    padding: 0;
    border: none;
    background: none;
    color: var(--orderpress-primary);
    font-size: inherit;
    /* Declarado y no 'inherit': el reset de controles le pone --orderpress-boton-peso a
       todo <button>, así que heredar dejaba este link en negrita al lado de "Ver
       detalle", que va en peso normal. Son dos acciones del mismo rango. */
    font-weight: 400;
    line-height: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.orderpress-repetir-link:hover {
    color: var(--orderpress-primary-hover);
    text-decoration: underline;
}

/* En el detalle sí es un botón —usa .orderpress-form-submit— y se separa del título. */
.orderpress-repetir + h3 {
    margin-bottom: var(--orderpress-spacing);
}

.orderpress-aviso-repetido {
    margin-bottom: var(--orderpress-spacing);
}

/* ---- La conversación del pedido ---- */

/* Arriba de la respuesta y del detalle: lo último que se dijo es lo que uno viene a leer
   cuando vuelve a un pedido. */
.orderpress-conversacion {
    display: grid;
    gap: var(--orderpress-spacing);
    margin-bottom: calc(var(--orderpress-spacing) * 2);
}

.orderpress-conversacion h4 {
    margin: 0;
}

/* LAS DISTANCIAS DEL HILO dan la sensación de continuidad, y son tres, no una:

   - Entre mensajes de DISTINTO autor, un espacio normal: son turnos de la conversación.
   - Entre mensajes del MISMO autor, apenas 2px: se leen como un bloque, que es lo que son
     —alguien que escribió dos veces seguidas—. Es lo que hace cualquier chat, y sin esto
     dos mensajes propios seguidos parecen dos conversaciones.
   - El hilo separado del resto de la ficha por su título, no por aire extra. */
.orderpress-mensajes {
    display: grid;
    gap: calc(var(--orderpress-spacing) * 0.8);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Y en los consecutivos del mismo autor no se repite quién habló: el nombre otra vez
   debajo del anterior es ruido, y la fecha sola alcanza. */
.orderpress-mensaje--cliente + .orderpress-mensaje--cliente .orderpress-mensaje-quien,
.orderpress-mensaje--admin + .orderpress-mensaje--admin .orderpress-mensaje-quien {
    display: none;
}

/* Los mensajes usan el mismo componente. Filete a la izquierda y no burbujas alternadas:
   son unos pocos mensajes sobre un pedido, no una charla, y las burbujas piden un ancho
   que acá no hay. */

.orderpress-mensaje-quien {
    margin: 0 0 4px;
    font-size: .85em;
    font-weight: 600;
}

.orderpress-mensaje-fecha {
    margin-left: 6px;
    font-weight: 400;
    color: var(--orderpress-text-muted);
}

.orderpress-mensaje-texto {
    margin: 0;
}

/* El formulario del hilo no lleva el tope de ancho del resto: el textarea de un mensaje
   se aprovecha mejor ancho, igual que el listado del pedido. */
.orderpress-mensaje-form {
    gap: calc(var(--orderpress-spacing) / 1.5);
}

/* ================================================================
   FICHA DE UN PEDIDO EN MI CUENTA

   La estructura viene de una propuesta de diseño y se tomó casi entera: cabecera con el
   número y las acciones, dos columnas, y un panel lateral con el resumen. Lo que se
   cambió está dicho en cada lugar.
   ================================================================ */

/* DOS CONTENEDORES DE CONSULTA ANIDADOS, y hay que ser preciso con cuál es cuál porque
   ya me equivoqué una vez: una consulta de contenedor NO puede responder al elemento que
   estiliza, solo a un ancestro. La primera versión declaraba el contenedor en
   .orderpress-ficha-grid y consultaba .orderpress-ficha-grid, así que la regla nunca
   aplicaba y las dos columnas seguían lado a lado en 420 px.
   - .orderpress-ficha es contenedor para que el GRID decida si son una o dos columnas.
   - .orderpress-ficha-principal es contenedor para que las LÍNEAS decidan si son tabla o
     lista, y midan su propia columna: la columna izquierda es más angosta que la ficha
     por el panel de al lado, así que consultar la ficha las apilaría demasiado tarde. */
.orderpress-ficha {
    container-type: inline-size;
    display: grid;
    gap: var(--orderpress-spacing);
}

/* La ficha entera dentro de una tarjeta, con el mismo tratamiento que el panel de datos de
   la página del pedido: agrupa lo que es UN pedido y lo separa de la navegación de la
   cuenta que tiene arriba.
   Fondo blanco y no gris —a diferencia de ese panel— porque acá adentro hay bloques con
   fondo gris propio (la respuesta, los mensajes, la cita) y sobre gris no se distinguirían.
   El borde es lo que hace visible la tarjeta cuando la página también es blanca. */
.orderpress-ficha-caja {
    display: grid;
    gap: calc(var(--orderpress-spacing) * 2);
    padding: calc(var(--orderpress-spacing) * 2);
}

/* La fila de arriba de la ficha: volver a la izquierda, imprimir a la derecha.
   Las dos son acciones sobre la PANTALLA, no sobre el pedido —por eso viven fuera de la
   tarjeta, igual que el volver desde siempre—. Las del pedido (volver a pedir, escribir
   un mensaje) están adentro. */
.orderpress-ficha-acciones {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--orderpress-spacing);
}

.orderpress-ficha-volver {
    margin: 0;
}

/* El botón de imprimir es secundario y se ve como tal: sin relleno, con el borde suave.
   Compite a propósito con "Volver a pedir", que es la acción principal de la ficha y sí
   va en el color de marca y a todo el ancho. */
.orderpress-imprimir {
    display: inline-grid;
    grid-auto-flow: column;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    font: inherit;
    font-weight: 600;
    color: var(--orderpress-text);
    background: transparent;
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    cursor: pointer;
}

.orderpress-imprimir:hover {
    border-color: var(--orderpress-primary);
    color: var(--orderpress-primary);
}

.orderpress-imprimir .orderpress-icono {
    width: 1em;
    height: 1em;
}

/* LOS ENLACES DE LA FICHA EN NEGRO, no en el color de marca ni en el azul del tema.
   El motivo: en esta pantalla casi todo es un enlace —volver, cada producto— y con el
   color primario la ficha queda pintada de rojo y el acento pierde valor. El primario
   queda para lo que hay que hacer: el botón de volver a pedir y el filete de la respuesta.
   Se subrayan al pasar el mouse, que es lo que los distingue de texto común. */
.orderpress-ficha a:not(.orderpress-form-submit):not(.orderpress-ficha-dudas-boton):not(.orderpress-boton-whatsapp) {
    color: var(--orderpress-text);
    text-decoration: none;
}

.orderpress-ficha a:not(.orderpress-form-submit):not(.orderpress-ficha-dudas-boton):not(.orderpress-boton-whatsapp):hover {
    text-decoration: underline;
}

.orderpress-ficha-volver a {
    display: inline-grid;
    grid-auto-flow: column;
    align-items: center;
    gap: 6px;
    font-weight: 600;
}

/* La flecha del "volver" apunta a la izquierda: el icono es una flecha a la derecha y se
   gira, en vez de sumar un segundo archivo para el mismo dibujo espejado. */
.orderpress-ficha-volver .orderpress-icono {
    width: 1em;
    height: 1em;
    transform: rotate(180deg);
}

/* Solo el título y la fecha, con un filete que separa la cabecera del cuerpo.
   FINO Y CLARO, no 2px negro: la cabecera ya se distingue por el tamaño del título, y una
   regla gruesa y oscura pesaba más que la propia línea que separa. El filete acá solo
   marca dónde termina la identificación del pedido y empieza su contenido. */
.orderpress-ficha-cabecera {
    padding-bottom: calc(var(--orderpress-spacing) * 1.5);
    border-bottom: 1px solid var(--orderpress-border);
}

/* El número del pedido es lo que identifica la pantalla, así que va grande y no al tamaño
   que le dé el tema a un <h3>. Se declara en em para acompañar la tipografía del sitio. */
.orderpress-ficha-titulo {
    margin: 0 0 4px;
    font-size: 2.2em;
    font-weight: 700;
    line-height: 1.1;
}

/* La columna lateral: el panel de resumen y, debajo, la acción principal. */
.orderpress-ficha-lateral {
    display: grid;
    gap: var(--orderpress-spacing);
    align-content: start;
}

/* El botón a todo el ancho de su columna. El formulario que lo envuelve también, o el
   botón mediría su contenido dentro de un inline. */
.orderpress-boton-ancho {
    width: 100%;
    justify-content: center;
}

.orderpress-ficha-lateral .orderpress-repetir {
    display: block;
}

/* Dos columnas: el contenido a la izquierda y el panel a la derecha con ancho fijo, igual
   criterio que la página del pedido. El panel es un resumen, no crece con el contenido. */
.orderpress-ficha-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--orderpress-panel-ancho);
    gap: var(--orderpress-pedido-gap);
    align-items: start;
}

.orderpress-ficha-principal {
    container-type: inline-size;
    display: grid;
    gap: calc(var(--orderpress-spacing) * 2.5);
    min-width: 0;
}

/* El umbral va como número literal: @container no acepta custom properties. */
@container (max-width: 820px) {
    .orderpress-ficha-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@supports not (container-type: inline-size) {
    @media (max-width: 900px) {
        .orderpress-ficha-grid {
            grid-template-columns: minmax(0, 1fr);
        }
    }
}

/* ---- Bloques del cuerpo ---- */

.orderpress-ficha-bloque {
    display: grid;
    gap: var(--orderpress-spacing);
    min-width: 0;
}

/* Título a la izquierda y el conteo a la derecha. SIN filete: los bloques ya se separan
   por el espacio entre ellos, y una línea abajo de cada título sumaba cuatro reglas
   horizontales en una pantalla que ya tiene la de la cabecera. */
.orderpress-ficha-bloque-titulo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--orderpress-spacing);
}

/* El mismo tratamiento que .orderpress-pedido-titulo de la página del pedido: los dos son
   el encabezado de un bloque de contenido, y con dos tamaños distintos el cliente pasa de
   una pantalla a la otra y no reconoce la jerarquía. Se declaran los valores en vez de
   agrupar los selectores porque uno es <h2> y el otro <h4> —la jerarquía del documento es
   distinta dentro de Mi cuenta, que ya tiene un h3 arriba— y el estilo no tiene por qué
   seguir al nivel del encabezado. */
/* Más chicos que el número del pedido y por encima del cuerpo. Estuvieron en 1.5em y
   pesaban de más: hay cuatro en la pantalla y competían entre ellos y con el título. */
.orderpress-ficha-bloque-titulo h4 {
    margin: 0;
    font-size: 1.2em;
    font-weight: 700;
    line-height: var(--orderpress-leading-tight);
}

.orderpress-ficha-conteo {
    font-size: .8em;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--orderpress-text-muted);
}

/* ---- La respuesta del vendedor ---- */

/* ================================================================
   TEXTO QUE ALGUIEN ESCRIBIÓ

   UN SOLO COMPONENTE para la respuesta al pedido, el comentario del cliente y cada
   mensaje del hilo. Antes eran tres bloques con el mismo dibujo y tres tratamientos
   distintos: la respuesta sin radio, los mensajes con radio en dos esquinas y la cita sin
   nada. No era criterio, era acumulación — cada uno se escribió en un momento distinto.

   Cuadrados, sin radio: es la forma que el plugin ya usa para este tipo de bloque en el
   admin, y un radio parcial en tres de cuatro esquinas no dice nada.

   Lo único que cambia entre variantes es el color del filete, que es lo que responde a la
   única pregunta que uno se hace al mirarlos: quién escribió esto.
   ================================================================ */

/* Dos familias, y la distinción es de contenido, no de gusto:

   - BLOQUE CITADO (la respuesta al pedido, el comentario del cliente): texto ya enviado que
     se lee como referencia. Ancho completo, filete a la izquierda.
   - MENSAJE (el hilo): turnos de una conversación. Alineados por autor, más angostos.

   Los dos CUADRADOS, sin radio, que es la forma que el plugin usa para este tipo de bloque
   en todas sus pantallas. Se declara border-radius: 0 explícitamente y no se omite: había
   una regla vieja de .orderpress-respuesta-vendedor que le filtraba el radio del tema, y
   omitir la propiedad dejaba que ganara. Declarada, ningún resto la puede pisar. */
.orderpress-respuesta-vendedor,
.orderpress-cita,
.orderpress-mensaje {
    display: grid;
    gap: var(--orderpress-space-1);
    margin: 0;
    padding: var(--orderpress-spacing);
    border-radius: 0;
    background: var(--orderpress-bg-alt);
    /* Fondo propio ⇒ declara su color. */
    color: var(--orderpress-text);
}

.orderpress-respuesta-vendedor,
.orderpress-cita {
    border-left: 3px solid var(--orderpress-border-strong);
}

/* EL GUIÑO DE CHAT, sin imitarlo: lo que hace que una captura de conversación se lea como
   tal no son las burbujas redondeadas —eso es el estilo de una app puntual— sino que cada
   turno esté alineado del lado de quien habló y no ocupe todo el ancho. Con eso alcanza, y
   se puede tener con módulos rectos, que es la forma del resto del plugin.
   El cliente a la derecha porque en Mi cuenta el que mira es el cliente, y en cualquier
   chat lo propio va a la derecha. */
.orderpress-mensaje {
    max-width: 82%;
}

.orderpress-mensaje--cliente {
    justify-self: end;
    /* Un tinte del color de marca en vez de otro gris: distingue el turno propio sin
       sumar un color nuevo al sistema. */
    background: color-mix(in srgb, var(--orderpress-primary) 14%, transparent);
}

.orderpress-mensaje--admin {
    justify-self: start;
}

/* El negativo se calcula A PARTIR DEL MISMO gap de arriba, no con un número suelto: si se
   ajusta el gap y este queda con el valor viejo, los consecutivos del mismo autor se
   separan o se superponen. Anular el gap y sumar 2px es lo que los deja como un bloque. */
.orderpress-mensaje--cliente + .orderpress-mensaje--cliente,
.orderpress-mensaje--admin + .orderpress-mensaje--admin {
    margin-top: calc(var(--orderpress-spacing) * -0.8 + 2px);
}

/* Estas reglas van DESPUÉS de la definición compartida a propósito: tienen la misma
   especificidad (0-1-0), así que a igual peso manda el orden del archivo. Estaban antes y
   el fondo gris de la definición compartida les ganaba — el tinte no se veía y parecía que
   la regla no existía. */


/* La respuesta al pedido lleva el color de marca: es lo que el cliente vuelve a buscar. */
.orderpress-respuesta-vendedor {
    border-left-color: var(--orderpress-primary);
}

.orderpress-respuesta-rotulo {
    display: grid;
    grid-auto-flow: column;
    justify-content: start;
    align-items: center;
    gap: var(--orderpress-space-2);
    margin: 0;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .85em;
}

.orderpress-respuesta-rotulo .orderpress-icono {
    width: 1.1em;
    height: 1.1em;
    color: var(--orderpress-primary);
}

.orderpress-respuesta-texto {
    font-size: 1.05em;
}

.orderpress-ficha-esperando {
    margin: 0;
    padding: var(--orderpress-spacing);
    border: 1px dashed var(--orderpress-border-strong);
    border-radius: var(--orderpress-radius);
    color: var(--orderpress-text-muted);
}

/* ---- Las líneas del pedido ---- */

/* UNA SOLA LISTA que se ve como tabla en ancho y como lista en angosto, en vez de dos
   markups. La propuesta mostraba tabla en desktop y lista en mobile; hacerlo con dos
   bloques distintos habría dejado dos versiones del detalle para mantener, y el día que
   se agregue una columna una de las dos se olvida. */
/* LAS COLUMNAS SE DEFINEN UNA VEZ, EN LA LISTA, y cada fila las hereda con subgrid.
   Sin esto cada <li> era su propia grilla y los códigos y las cantidades no caían bajo su
   encabezado: cada fila decidía sus anchos por su propio contenido. Se vio en la primera
   captura y es exactamente lo que una tabla resuelve gratis.
   Subgrid y no display:contents en el <li> porque contents haría perder el fondo y el
   borde de la fila, que son lo que separa un producto del siguiente. */
.orderpress-lineas {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--orderpress-border);
}

/* CINCO columnas, no cuatro: producto, código, precio, cantidad y subtotal. Estuvo en
   cuatro desde que se sumaron los precios, y el efecto era que el subtotal —la quinta
   celda— no entraba en la fila y se caía a una línea propia debajo, tanto en el
   encabezado como en cada producto. Se veía como si la tabla tuviera un renglón suelto
   con un número sin etiqueta. */
.orderpress-lineas--precios {
    grid-template-columns: minmax(0, 1fr) auto auto auto auto;
}

.orderpress-linea {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: center;
    gap: var(--orderpress-spacing);
    padding: var(--orderpress-spacing);
    border-top: 1px solid var(--orderpress-border);
}

/* Respaldo para navegadores sin subgrid: cada fila con sus propias pistas. Las columnas no
   quedan alineadas al píxel, pero la fila se sigue leyendo. */
@supports not (grid-template-columns: subgrid) {
    .orderpress-linea {
        grid-template-columns: minmax(0, 1fr) auto auto;
    }

    .orderpress-lineas--precios .orderpress-linea {
        grid-template-columns: minmax(0, 1fr) auto auto auto auto;
    }
}

.orderpress-linea:first-child {
    border-top: none;
}

/* El encabezado con el fondo del texto: es la fila que ordena la lectura de las demás. */
.orderpress-linea--encabezado {
    background: var(--orderpress-text);
    color: var(--orderpress-superficie);
    font-size: .78em;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.orderpress-linea-titulo {
    font-weight: 600;
}

.orderpress-linea-sku,
.orderpress-linea-precio,
.orderpress-linea-cantidad,
.orderpress-linea-subtotal {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Los números alineados a la derecha, que es como se comparan de un barrido vertical. */
.orderpress-linea-precio,
.orderpress-linea-cantidad,
.orderpress-linea-subtotal,
.orderpress-linea--encabezado span:not(:first-child):not(:nth-child(2)) {
    text-align: right;
}

.orderpress-linea-subtotal {
    font-weight: 700;
}

/* Los rótulos de cada dato solo se ven en la versión apilada, donde no hay encabezado que
   diga qué es cada número. */
.orderpress-linea-rotulo,
.orderpress-linea-unidad,
.orderpress-linea-unidades {
    color: var(--orderpress-text-muted);
    font-size: .85em;
    font-weight: 400;
}

.orderpress-linea-rotulo {
    display: none;
}



/* El total no usa subgrid: su rótulo cruza las columnas del medio y el valor va a la
   derecha, así que define sus propias dos pistas. */
.orderpress-linea--total {
    grid-template-columns: minmax(0, 1fr) auto;
    background: var(--orderpress-bg-alt);
    color: var(--orderpress-text);
    font-weight: 700;
}

/* Apilado: se esconde el encabezado y cada dato dice qué es. */
@container (max-width: 560px) {
    .orderpress-linea--encabezado {
        display: none;
    }

    /* Apilado se sale del subgrid: la lista vuelve a una sola columna y cada fila define
       sus dos pistas. */
    .orderpress-lineas,
    .orderpress-lineas--precios {
        grid-template-columns: minmax(0, 1fr);
    }

    .orderpress-linea,
    .orderpress-lineas--precios .orderpress-linea {
        grid-template-columns: minmax(0, 1fr) auto;
        gap: var(--orderpress-space-1) var(--orderpress-spacing);
    }

    .orderpress-linea-titulo {
        grid-column: 1 / -1;
    }

    .orderpress-linea-rotulo {
        display: inline;
    }

    .orderpress-linea-precio {
        text-align: left;
    }
}

/* ---- El comentario del cliente ---- */

/* La cita usa el componente compartido de arriba. Va como cita y no dentro de un campo
   con borde, que es lo que sugería la propuesta: un recuadro con forma de input invita a
   editar algo que no se puede editar. */

/* ---- El panel lateral ---- */

/* Los títulos DEL PANEL en versalita, como en la propuesta: es un bloque de referencia y
   sus títulos no compiten con los del contenido, que van en caja normal. */
.orderpress-ficha-panel .orderpress-ficha-bloque-titulo h4 {
    font-size: .85em;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* Este SÍ lleva filete, pero fino y gris: acá separa el título de la línea de tiempo
   dentro de una caja chica, donde un filete de 2px negro pesaría más que el contenido.
   Usa --orderpress-border-strong, que ya es #ccc: un gris nuevo escrito a mano sería un
   valor más que mantener. */
.orderpress-ficha-panel .orderpress-ficha-bloque-titulo {
    padding-bottom: var(--orderpress-space-2);
    border-bottom: 1px solid var(--orderpress-border-strong);
}

/* SIN FONDO. Lo tenía gris y se fue por una razón de criterio, no de gusto: ahora que la
   ficha entera es una tarjeta blanca, el gris quedó reservado para los bloques de "texto
   que alguien escribió" —la respuesta, la cita, los mensajes—. Un panel gris al lado
   competía con ellos y hacía que el gris dejara de significar algo.
   Sin caja, la columna se lee como una columna: la separan el espacio y el filete de su
   título, que es lo mismo que ordena el contenido de la izquierda. */
.orderpress-ficha-panel {
    display: grid;
    gap: calc(var(--orderpress-spacing) * 1.5);
}

/* Los hitos: cuadrado y línea, sin la línea de tiempo completa de la propuesta —solo se
   listan los que tienen fecha de verdad. */
.orderpress-hitos {
    display: grid;
    gap: var(--orderpress-spacing);
    margin: 0;
    padding: 0;
    list-style: none;
}

.orderpress-hito {
    display: grid;
    gap: 2px;
    padding-left: calc(var(--orderpress-spacing) * 1.75);
    position: relative;
}

.orderpress-hito::before {
    content: "";
    position: absolute;
    left: 0;
    top: .35em;
    width: 10px;
    height: 10px;
    background: var(--orderpress-text);
}

/* La línea que une un hito con el siguiente. En el último no se dibuja: una línea que
   sale del último hito y no llega a ninguna parte sugiere un paso que no existe. */
.orderpress-hito:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 4px;
    top: calc(.35em + 14px);
    bottom: calc(-1 * var(--orderpress-spacing));
    width: 2px;
    background: var(--orderpress-border-strong);
}

.orderpress-hito--actual::before {
    background: var(--orderpress-primary);
}

.orderpress-hito--actual .orderpress-hito-titulo {
    color: var(--orderpress-primary);
}

.orderpress-hito-titulo {
    font-weight: 700;
}

/* Los datos: rótulo a la izquierda, valor a la derecha. <dl> aplanado con grid. */
.orderpress-ficha-datos {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 6px var(--orderpress-spacing);
    margin: 0;
    padding-top: var(--orderpress-spacing);
    border-top: 1px solid var(--orderpress-border-strong);
}

.orderpress-ficha-datos dt {
    color: var(--orderpress-text-muted);
}

.orderpress-ficha-datos dd {
    margin: 0;
    text-align: right;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* El badge del estado dentro de la fila de datos: hereda el tamaño chico del badge
   general y solo se alinea con el resto de los valores. */
.orderpress-ficha-datos dd .orderpress-badge {
    vertical-align: baseline;
}

.orderpress-ficha-dudas {
    display: grid;
    gap: 6px;
    padding-top: var(--orderpress-spacing);
    border-top: 1px solid var(--orderpress-border-strong);
}

.orderpress-ficha-dudas-rotulo {
    margin: 0;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .85em;
}

/* Botón con contorno y no lleno: la acción principal de la ficha es "volver a pedir", y
   dos botones llenos compiten. */
.orderpress-ficha-dudas-boton {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--orderpress-space-2);
    margin-top: 6px;
    padding: var(--orderpress-control-padding-y) var(--orderpress-control-padding-x);
    border: 2px solid var(--orderpress-text);
    color: var(--orderpress-text);
    font-weight: var(--orderpress-boton-peso);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .85em;
}

.orderpress-ficha-dudas-boton:hover {
    background: var(--orderpress-text);
    color: var(--orderpress-superficie);
}

.orderpress-ficha-dudas-boton .orderpress-icono {
    width: 1em;
    height: 1em;
}

/* ================================================================
   LISTADO DE PEDIDOS EN MI CUENTA

   Reusa la tarjeta, la cabecera y el conteo de la ficha: son dos pantallas de la misma
   sección y tienen que leerse como la misma cosa. Lo propio es la fila.
   ================================================================ */

.orderpress-listado-cabecera {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--orderpress-spacing);
}

.orderpress-listado-acciones {
    display: grid;
    justify-items: end;
    gap: 6px;
}

/* "Nuevo pedido" es un <a> con la clase del botón: hay que sacarle el subrayado que el tema
   le pone a los enlaces, porque se lee como botón y no como enlace. */
.orderpress-listado-acciones .orderpress-form-submit {
    text-decoration: none;
}

/* Las columnas se declaran UNA vez en la lista y cada fila las hereda con subgrid, igual que
   las líneas del detalle: sin eso cada fila decide sus anchos por su contenido y las fechas
   y los estados no caen bajo su encabezado. */
.orderpress-pedidos {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto auto;
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--orderpress-border);
}

.orderpress-pedido-fila {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: center;
    gap: var(--orderpress-spacing);
    padding: var(--orderpress-spacing);
    border-top: 1px solid var(--orderpress-border);
}

@supports not (grid-template-columns: subgrid) {
    .orderpress-pedido-fila {
        grid-template-columns: auto auto minmax(0, 1fr) auto auto;
    }
}

.orderpress-pedido-fila:first-child {
    border-top: none;
}

.orderpress-pedido-fila--encabezado {
    background: var(--orderpress-text);
    color: var(--orderpress-superficie);
    font-size: .78em;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.orderpress-pedido-numero {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.orderpress-pedido-fecha {
    color: var(--orderpress-text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* El contenido en dos líneas: el conteo arriba con peso, y abajo los nombres. Es la columna
   que hace reconocible la fila, así que es la que se queda con el ancho que sobra. */
.orderpress-pedido-contenido {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.orderpress-pedido-cuenta {
    font-weight: 600;
}

.orderpress-pedido-resumen {
    color: var(--orderpress-text-muted);
    font-size: .9em;
}

.orderpress-pedido-estado {
    display: grid;
    justify-items: start;
    gap: var(--orderpress-space-1);
}

.orderpress-pedido-ver {
    display: inline-grid;
    grid-auto-flow: column;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    font-weight: 600;
}

/* Las dos acciones de la fila en el color del texto. "Volver a pedir" es un <button>, así
   que la regla de enlaces en negro de la ficha no lo alcanzaba y quedaba en rojo al lado de
   uno negro: dos acciones del mismo rango con dos pesos distintos. */
.orderpress-pedido-fila .orderpress-repetir-link {
    color: var(--orderpress-text);
}

.orderpress-pedido-fila .orderpress-repetir-link:hover {
    color: var(--orderpress-text);
    text-decoration: underline;
}

.orderpress-pedido-ver .orderpress-icono {
    width: 1em;
    height: 1em;
}

/* Apilado: cada pedido pasa a ser una tarjeta. El encabezado se esconde y los datos que
   perdían su columna dicen qué son. */
@container (max-width: 720px) {
    .orderpress-pedidos {
        grid-template-columns: minmax(0, 1fr);
        border: none;
    }

    .orderpress-pedido-fila--encabezado {
        display: none;
    }

    .orderpress-pedido-fila,
    .orderpress-pedido-fila:first-child {
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 6px var(--orderpress-spacing);
        margin-bottom: var(--orderpress-spacing);
        padding: var(--orderpress-spacing);
        border: 1px solid var(--orderpress-text);
    }

    .orderpress-pedido-fila:last-child {
        margin-bottom: 0;
    }

    /* El número y el estado en la PRIMERA fila, uno a cada lado. La ubicación es explícita
       porque en el DOM el estado viene cuarto —después de la fecha y el contenido— y el
       acomodo automático lo mandaba al final de la tarjeta. */
    .orderpress-pedido-numero {
        grid-row: 1;
        grid-column: 1;
        font-size: 1.3em;
    }

    .orderpress-pedido-estado {
        grid-row: 1;
        grid-column: 2;
        justify-items: end;
        text-align: right;
    }

    .orderpress-pedido-fecha,
    .orderpress-pedido-contenido {
        grid-column: 1 / -1;
    }

    /* La fecha sin rótulo, a diferencia del código de un producto: "12/08/2026" se reconoce
       solo, mientras "Z7" sin la palabra Código no dice nada. Un rótulo que repite lo obvio
       es ruido. */
    .orderpress-pedido-fecha .orderpress-linea-rotulo {
        display: none;
    }

    /* Las acciones al pie, separadas por un filete: es el borde de la tarjeta lo que las
       agrupa con el pedido, así que necesitan su propia división interna. */
    .orderpress-pedido-fila .orderpress-acciones-pedido {
        grid-column: 1 / -1;
        margin-top: var(--orderpress-space-1);
        padding-top: var(--orderpress-spacing);
        border-top: 1px solid var(--orderpress-border);
    }
}


/* ====================================================================
   IMPRESIÓN
   ====================================================================

   Lo que sale impreso es la ficha del pedido y nada más. El cliente aprieta Imprimir y
   el diálogo de su sistema le ofrece "Guardar como PDF", así que **el PDF lo genera su
   máquina**: el plugin no escribe ningún archivo, y por eso no hace falta ni una
   librería de PDF ni un archivo en wp-content/uploads —que es público y fue el motivo
   por el que se descartó el PDF adjunto al email—.

   POR QUÉ `visibility` Y NO `display: none`, que fue lo primero que se probó:

   El plugin se embebe en páginas que armó otra persona. El header, el footer y el menú
   son markup del tema, y no hay forma de listarlos: cambian con el sitio. Entonces no se
   esconde lo de afuera, se hace invisible TODO y se vuelve visible nuestra rama.

   Con `display: none` no funciona: esconder un ancestro esconde a sus hijos y no hay
   forma de "des-esconder" al nieto. `visibility` sí se puede revertir hacia abajo, que
   es exactamente lo que hace falta acá.

   El `position: absolute` no es decorativo: un elemento con `visibility: hidden` SIGUE
   OCUPANDO SU LUGAR, así que sin sacar la ficha del flujo se imprimirían primero varias
   páginas en blanco —el hueco del header y del menú— y recién después el pedido. */
@media print {
    body * {
        visibility: hidden;
    }

    .orderpress-ficha-caja,
    .orderpress-ficha-caja * {
        visibility: visible;
    }

    .orderpress-ficha-caja {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        margin: 0;
        /* Se saca el borde y la sombra —el papel ya tiene bordes— pero NO el padding: sin
           él el texto arranca pegado al margen que pone la impresora y queda incómodo de
           leer. El margen de la hoja lo decide el diálogo de impresión; esto es el aire
           de adentro. */
        border: 0;
        box-shadow: none;
    }

    /* Los controles no se imprimen: en un papel, un botón es tinta que no hace nada.
       Se esconden con display para que además no dejen su hueco. */
    .orderpress-ficha-acciones,
    .orderpress-imprimir,
    .orderpress-repetir,
    .orderpress-mensaje-form,
    .orderpress-ficha-dudas {
        display: none !important;
    }

    /* Las dos columnas pasan a una: en 21 cm de ancho, el panel al costado deja la lista
       de productos en una franja ilegible. */
    .orderpress-ficha-grid {
        display: block;
    }

    /* Sin fondos de color: una tinta que en pantalla es un matiz suave, en papel sale
       como una mancha gris, y en una impresora en blanco y negro se come el texto. */
    .orderpress-mensaje,
    .orderpress-cita,
    .orderpress-respuesta-vendedor {
        background: transparent;
        border: 1px solid var(--orderpress-gray-300);
    }

    /* Que no se corte un producto ni un mensaje a la mitad entre dos hojas. */
    .orderpress-linea,
    .orderpress-mensaje {
        break-inside: avoid;
    }

    /* EL ENCABEZADO DE LA TABLA SE INVIERTE. En pantalla es una barra del color del texto
       —casi negra— y ordena la lectura; en papel son 21 cm de tinta sólida por producto
       impreso, y en una impresora hogareña sale con bandas. Se pasa a fondo claro con
       texto oscuro, que en papel cumple la misma función de separar el encabezado. */
    .orderpress-linea--encabezado {
        background: var(--orderpress-gray-100);
        color: var(--orderpress-black);
    }

    /* Los badges pierden su fondo de color por el mismo motivo, y se quedan con un borde
       que los sigue distinguiendo del texto corriente. */
    .orderpress-badge {
        background: transparent;
        color: var(--orderpress-black);
        border: 1px solid var(--orderpress-gray-500);
    }
}

/* ====================================================================
   CONSENTIMIENTO
   ==================================================================== */

/* La casilla y su texto en una grilla de dos columnas y no con el input flotando dentro
   del label: con un texto de dos o tres renglones —que es lo normal en un texto legal— el
   flujo normal alinea la segunda línea debajo del checkbox y se lee como si el texto
   estuviera indentado al azar. Con grid, el texto arma su propio bloque. */
.orderpress-consentimiento-label {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    gap: 10px;
    cursor: pointer;
}

/* El checkbox nativo no se centra con la primera línea del texto: nace alineado a la caja
   completa. Estos 2px lo bajan hasta la altura de la mayúscula. */
.orderpress-consentimiento-label input[type="checkbox"] {
    margin: 2px 0 0;
    flex: none;
}

/* Los enlaces del consentimiento SÍ van en el color de marca, al revés que los de la
   ficha del pedido. Ahí casi todo era un enlace y el primario pintaba la pantalla; acá
   hay dos, son lo único que hay que poder encontrar, y no distinguirlos del texto sería
   esconder justamente lo que la persona tiene derecho a leer antes de aceptar. */
.orderpress-consentimiento-label a {
    color: var(--orderpress-primary);
    text-decoration: underline;
}

.orderpress-consentimiento-nota {
    margin: 8px 0 0;
    font-size: 0.875em;
    color: var(--orderpress-text-muted);
}

/* ---- Catálogo del frontend ([orderpress_catalogo]) ---- */

/* Variables propias del front autogestionado. Se declaran en el contenedor y no
   en :root porque solo las usa el catálogo, y así se pueden adaptar por instancia
   desde el CSS del constructor sin pelear especificidad. Documentadas en
   docs/IMPLEMENTACION.md. */
.orderpress-catalogo {
    /* Grilla. La cantidad de columnas la fija una clase (.orderpress-cat-cols-N),
       porque es un dato del ajuste, no diseño. --...col-min es el ancho por
       debajo del cual una columna se parte a la fila siguiente. */
    --orderpress-cat-cols: 4;
    --orderpress-cat-col-min: 200px;
    --orderpress-cat-gap: calc(var(--orderpress-spacing) * 1.5);
    /* Proporción de la foto de cada card (1/1 = cuadrada). */
    --orderpress-card-foto: 1 / 1;
    /* El fondo de la caja de la foto. En los modos sin recorte queda a la vista
       alrededor, y una foto de estudio con fondo blanco muestra una costura contra el
       gris; un sitio con fotos así lo pisa con blanco y desaparece. */
    --orderpress-card-fondo: var(--orderpress-bg-alt);
}

/* ---- Catálogo: la barra de filtros al costado (0.143) ----

   Antes los cuatro ejes —categoría, marca, segmento y colección— iban en una fila
   arriba de la grilla. Con dos ejes entraba; con cuatro, esa fila crecía hasta empujar
   los productos abajo del pliegue y la pantalla abría mostrando filtros en vez de
   catálogo. Al costado ocupan ALTO, que es lo que sobra, en vez de ANCHO, que es lo que
   la grilla necesita. */
/* El aviso de acceso, separado de lo que sigue (0.143.1). Son dos cosas distintas —qué
   te falta para pedir, y qué hay para pedir— y pegadas se leen como un solo bloque: la
   caja punteada parecía el encabezado de la grilla. El aire lo pone el catálogo, que es
   quien decidió ponerlos uno arriba del otro; el aviso suelto no trae margen propio
   para no pelear con el espaciado del sitio donde lo ponga el constructor. */
.orderpress-catalogo > .orderpress-acceso {
    margin-bottom: calc(var(--orderpress-spacing) * 2);
}

.orderpress-cat-layout {
    /* Ancho de la barra: entra "Primavera-Verano" en un renglón, que es el término más
       largo que se puede esperar sin que sea culpa del sitio. */
    --orderpress-cat-barra: 230px;

    display: grid;
    grid-template-columns: var(--orderpress-cat-barra) minmax(0, 1fr);
    gap: calc(var(--orderpress-spacing) * 1.5);
    align-items: start;
}

/* Sin ejes con opciones no hay barra, y la grilla se queda con todo el ancho. */
.orderpress-cat-layout--sin-barra {
    grid-template-columns: minmax(0, 1fr);
}

/* CAMBIA LA ESTRUCTURA —de dos zonas lado a lado a apiladas—, así que acá un media
   query es legítimo. El corte es donde la barra más una grilla de dos columnas dejan
   de entrar. */
@media (max-width: 782px) {
    .orderpress-cat-layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

.orderpress-cat-barra {
    padding: var(--orderpress-spacing);
}

.orderpress-cat-barra-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--orderpress-spacing);
    margin-bottom: var(--orderpress-spacing);
}

.orderpress-cat-barra-titulo {
    margin: 0;
    font-size: 1em;
}

.orderpress-cat-limpiar {
    color: var(--orderpress-text-muted);
    font-size: 0.85em;
    text-decoration: underline;
}

.orderpress-cat-limpiar:hover,
.orderpress-cat-limpiar:focus {
    color: var(--orderpress-primary);
}

/* Entre grupos, una línea DEL PRIMARIO (0.143.1). El espacio solo no alcanza: con
   cuatro listas seguidas de links cortos, dónde termina un eje y empieza el otro deja
   de verse. Y con el color del sitio en vez de un gris, la línea deja de ser un borde
   más y pasa a leerse como la marca que separa — un acento, no una división.

   Es el mismo primario configurable de todo el plugin: definir uno solo alcanza. */
.orderpress-cat-grupo + .orderpress-cat-grupo {
    margin-top: var(--orderpress-spacing);
    padding-top: var(--orderpress-spacing);
    border-top: 1px solid var(--orderpress-primary);
}

.orderpress-cat-grupo-titulo {
    margin: 0 0 calc(var(--orderpress-spacing) / 2);
    font-size: 0.9em;
    line-height: var(--orderpress-leading-tight);
}

/* La lista pasa de chips en fila a filas apiladas: en una columna de 230px los chips se
   parten en dos renglones y el eje deja de leerse como un eje. */
.orderpress-cat-filtros {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.orderpress-cat-filtros a {
    display: block;
    padding: calc(var(--orderpress-spacing) / 2.5) calc(var(--orderpress-spacing) / 1.5);
    border-radius: var(--orderpress-radius);
    color: var(--orderpress-text-muted);
    text-decoration: none;
    font-size: 0.95em;
    line-height: var(--orderpress-leading-tight);
}

.orderpress-cat-filtros a:hover,
.orderpress-cat-filtros a:focus {
    background: var(--orderpress-bg-alt);
    color: var(--orderpress-text);
}

/* El activo se marca con el fondo tenue del primario, no con el primario pleno: en una
   columna con cuatro ejes, cuatro bloques de color saturado compiten con los productos.
   El tenue se calcula del mismo color, como el resto de los estados. */
.orderpress-cat-filtros a.is-activo,
.orderpress-cat-filtros a.is-activo:hover,
.orderpress-cat-filtros a.is-activo:focus {
    background: var(--orderpress-primary-suave);
    color: var(--orderpress-primary);
    font-weight: 600;
}

/* El orden, arriba de la grilla y a la derecha. Sigue siendo links y no un <select>:
   así cada estado del catálogo queda linkeable y el botón "atrás" funciona, que es la
   misma decisión que toman los filtros. */
.orderpress-cat-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: calc(var(--orderpress-spacing) / 2);
    margin-bottom: var(--orderpress-spacing);
}

.orderpress-cat-orden-rotulo {
    color: var(--orderpress-text-muted);
    font-size: 0.9em;
}

.orderpress-cat-orden {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--orderpress-spacing) / 2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.orderpress-cat-orden a {
    display: inline-block;
    padding: calc(var(--orderpress-spacing) / 2) var(--orderpress-spacing);
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    color: var(--orderpress-text-muted);
    text-decoration: none;
    font-size: 0.9em;
    line-height: var(--orderpress-leading-tight);
}

.orderpress-cat-orden a:hover {
    border-color: var(--orderpress-primary);
    color: var(--orderpress-primary);
}

.orderpress-cat-orden a.is-activo {
    background: var(--orderpress-primary);
    border-color: var(--orderpress-primary);
    color: var(--orderpress-primary-contraste);
}

/* Grilla intrínsecamente responsive, SIN un solo media query: hasta N columnas
   cuando hay ancho, y de a una menos a medida que se angosta. Es el patrón RAM
   (repeat + auto-fill + minmax) con tope: cada columna mide como mucho lo que le
   toca de N —(100% menos los gaps) / N— y como poco --orderpress-cat-col-min;
   cuando el contenedor no da para ese mínimo, auto-fill parte a menos columnas.
   El grid se encarga del responsive; el CSS no repite breakpoints. */
.orderpress-cat-grid {
    display: grid;
    gap: var(--orderpress-cat-gap);
    grid-template-columns: repeat(
        auto-fill,
        minmax(
            max(
                var(--orderpress-cat-col-min),
                calc((100% - (var(--orderpress-cat-cols) - 1) * var(--orderpress-cat-gap)) / var(--orderpress-cat-cols))
            ),
            1fr
        )
    );
}

/* La cantidad de columnas es un dato (del ajuste o del atributo del shortcode),
   así que va por clase y no por style inline —la regla de "nada inline"—. Cada
   clase solo setea la variable; la fórmula de arriba hace el resto. */
.orderpress-cat-cols-2 { --orderpress-cat-cols: 2; }
.orderpress-cat-cols-3 { --orderpress-cat-cols: 3; }
.orderpress-cat-cols-4 { --orderpress-cat-cols: 4; }
.orderpress-cat-cols-5 { --orderpress-cat-cols: 5; }
.orderpress-cat-cols-6 { --orderpress-cat-cols: 6; }

.orderpress-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.orderpress-card-foto {
    display: block;
    aspect-ratio: var(--orderpress-card-foto);
    background: var(--orderpress-card-fondo);
    overflow: hidden;
}

.orderpress-card-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ---- Cómo entra la foto en su caja (0.137) ----

   Los mismos tres modos que la galería de la ficha, con su propio ajuste: una grilla y
   una ficha quieren cosas distintas, y el comentario de resolver_ajuste() dice por qué.

   Lo de arriba es 'cover' —caja cuadrada, recorta— y queda de default. Los otros dos
   la pisan.

   OJO AL TOCAR ESTO, es la misma trampa que la galería: width tiene que ser 100% y
   NUNCA auto. Con width:auto un <img loading="lazy"> colapsa a 0×0 antes de cargar, y
   con área cero el navegador no dispara nunca la carga: la foto no aparece jamás.
   La card además imprime la foto con wp_get_attachment_image(), que emite width y
   height, así que el lugar queda reservado desde el primer pintado. */

/* 'fit': la foto usa todo el ancho de la card y el alto lo da ella. No se pierde nada,
   a cambio de que los títulos no queden alineados entre cards —el alto de la foto
   cambia con cada producto—. Es el precio de no recortar, y se avisa en Ajustes. */
.orderpress-cat-ajuste-fit .orderpress-card-foto {
    aspect-ratio: auto;
}

.orderpress-cat-ajuste-fit .orderpress-card-foto img {
    height: auto;
    /* Con la caja al tamaño exacto de la foto, object-fit no tiene nada que hacer. */
    object-fit: initial;
}

/* 'contain': la caja cuadrada se mantiene —la grilla queda pareja, los títulos
   alineados— y la foto entra entera y centrada. Es el modo de Tiendanube, y el que
   suele querer una grilla con fotos de recorte disparejo. */
.orderpress-cat-ajuste-contain .orderpress-card-foto img {
    object-fit: contain;
}

.orderpress-card-sinfoto {
    display: block;
    width: 100%;
    height: 100%;
}

.orderpress-card-cuerpo {
    display: flex;
    flex-direction: column;
    gap: calc(var(--orderpress-spacing) / 2);
    padding: var(--orderpress-spacing);
}

.orderpress-card-titulo {
    color: var(--orderpress-text);
    font-weight: 600;
    text-decoration: none;
    line-height: 1.3;
}

.orderpress-card-titulo:hover {
    color: var(--orderpress-primary);
}

.orderpress-card-meta {
    margin: 0;
    color: var(--orderpress-text-muted);
    font-size: 0.9em;
}

.orderpress-card-precio {
    margin: 0;
    color: var(--orderpress-primary);
    font-weight: 700;
    font-size: calc(var(--orderpress-precio-size) * 0.8);
}

/* El botón de agregar empuja hacia abajo: en una grilla, las cards de distinto
   alto quedan con el botón alineado al piso. */
.orderpress-card .orderpress-add-wrap {
    margin-top: auto;
}

.orderpress-cat-paginacion {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--orderpress-spacing);
    margin-top: calc(var(--orderpress-spacing) * 2);
}

.orderpress-cat-pag {
    padding: calc(var(--orderpress-spacing) / 2) var(--orderpress-spacing);
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    color: var(--orderpress-primary);
    text-decoration: none;
}

.orderpress-cat-pag:hover {
    border-color: var(--orderpress-primary);
}

.orderpress-cat-pag-info {
    color: var(--orderpress-text-muted);
    font-size: 0.9em;
}

.orderpress-catalogo-vacio {
    color: var(--orderpress-text-muted);
    text-align: center;
    padding: calc(var(--orderpress-spacing) * 2);
}

/* ---- Ficha del producto nativo ---- */

/* El contenedor de la plantilla propia: centra y acota el ancho, para que el
   header/footer del tema envuelvan una ficha con medida de lectura y no una a
   todo el ancho de la ventana. --orderpress-pd-max se puede pisar desde el tema. */
.orderpress-pd-main {
    --orderpress-pd-max: 1100px;
    /* Aire arriba generoso: muchos temas tienen el header fijo y, como esta
       plantilla no pasa por el wrapper del tema, sin esto el título queda tapado.
       Se puede ajustar desde el CSS del sitio si el header es más alto o no es fijo. */
    --orderpress-pd-top: calc(var(--orderpress-spacing) * 6);
    max-width: var(--orderpress-pd-max);
    margin-inline: auto;
    padding: var(--orderpress-pd-top) var(--orderpress-spacing) calc(var(--orderpress-spacing) * 2.5);
}

/* El bloque compacto (fallback de the_content) no necesita el aire de arriba: la
   ficha ya la dibujó el tema y esto solo cuelga el bloque de compra. */
.orderpress-pd--compacto {
    padding-top: 0;
}


.orderpress-producto-detalle {
    --orderpress-pd-gap: calc(var(--orderpress-spacing) * 3);
    /* Tamaño propio del título: el h1 del tema suele ser enorme para una ficha de
       producto. Se puede pisar desde el CSS del sitio. */
    --orderpress-pd-titulo-size: clamp(1.5rem, 1.1rem + 1.6vw, 2rem);
    /* Proporción de las dos columnas de la ficha: foto más angosta que el
       contenido, como en una ficha de e-commerce. */
    --orderpress-pd-foto-col: 5fr;
    --orderpress-pd-info-col: 6fr;
}

/* Migas de pan: Inicio › Producto, como el catálogo de referencia. */
.orderpress-pd-migas {
    margin-bottom: calc(var(--orderpress-spacing) * 1.5);
    color: var(--orderpress-text-muted);
    font-size: 0.9em;
}

.orderpress-pd-migas a {
    color: var(--orderpress-text-muted);
    text-decoration: none;
}

.orderpress-pd-migas a:hover {
    color: var(--orderpress-primary);
}

.orderpress-pd-migas span {
    margin: 0 0.4em;
}

.orderpress-pd-migas-actual {
    color: var(--orderpress-text);
}

/* Dos columnas: imagen a la izquierda, todo el contenido a la derecha. Acá el
   media query SÍ corresponde: no es una grilla que repite, son dos zonas
   distintas que pasan de lado a lado a apiladas. Una sola vez, no un breakpoint
   por cada cantidad de columnas. La proporción sale de variables. */
.orderpress-pd-top {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--orderpress-pd-gap);
}

@media (min-width: 782px) {
    .orderpress-pd-top {
        grid-template-columns: minmax(0, var(--orderpress-pd-foto-col)) minmax(0, var(--orderpress-pd-info-col));
        align-items: start;
    }
}

.orderpress-pd-foto img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--orderpress-radius);
}

.orderpress-pd-info {
    display: flex;
    flex-direction: column;
    gap: var(--orderpress-spacing);
}

.orderpress-pd-titulo {
    margin: 0;
    font-size: var(--orderpress-pd-titulo-size);
    line-height: var(--orderpress-leading-tight);
}

.orderpress-pd-sku {
    margin: 0;
    color: var(--orderpress-text-muted);
}

.orderpress-pd-unidad,
.orderpress-pd-bulto {
    margin: 0;
    color: var(--orderpress-text-muted);
}

.orderpress-pd-desc {
    /* Un poco de aire alrededor de la descripción para separarla del título y del
       bloque de compra. */
    margin: calc(var(--orderpress-spacing) / 2) 0;
}

/* El precio, más grande en la ficha que en la card. */
.orderpress-pd-info .orderpress-precio-valor {
    font-size: var(--orderpress-precio-size);
    font-weight: 700;
    color: var(--orderpress-primary);
}

/* ---- [orderpress_campo] y [orderpress_galeria] (F1, 0.89) ---- */

/* Un dato suelto del producto para quien arma la ficha en el constructor. Inline, sin
   más diseño que el rótulo atenuado: el resto lo pone el constructor. */
.orderpress-campo-rotulo {
    color: var(--orderpress-text-muted);
}

.orderpress-campo--descripcion {
    display: block;
}

/* La galería: la misma grilla intrínseca del catálogo (una clase fija las columnas, la
   fórmula parte a menos cuando no entra). Sin lightbox: es del constructor. */
.orderpress-galeria {
    --orderpress-galeria-cols: 4;
    --orderpress-galeria-col-min: 120px;
    --orderpress-galeria-gap: calc(var(--orderpress-spacing) / 1.5);
    display: grid;
    gap: var(--orderpress-galeria-gap);
    grid-template-columns: repeat(
        auto-fill,
        minmax(
            max(
                var(--orderpress-galeria-col-min),
                calc((100% - (var(--orderpress-galeria-cols) - 1) * var(--orderpress-galeria-gap)) / var(--orderpress-galeria-cols))
            ),
            1fr
        )
    );
    margin-top: var(--orderpress-spacing);
}

.orderpress-galeria-cols-1 { --orderpress-galeria-cols: 1; }
.orderpress-galeria-cols-2 { --orderpress-galeria-cols: 2; }
.orderpress-galeria-cols-3 { --orderpress-galeria-cols: 3; }
.orderpress-galeria-cols-4 { --orderpress-galeria-cols: 4; }
.orderpress-galeria-cols-5 { --orderpress-galeria-cols: 5; }
.orderpress-galeria-cols-6 { --orderpress-galeria-cols: 6; }

/* El fondo de la caja, como variable: en los modos SIN recorte queda a la vista
   alrededor de la foto, y una foto de estudio con fondo blanco muestra una costura
   contra el gris. Un sitio con fotos así lo pisa con blanco y desaparece. */
.orderpress-galeria {
    --orderpress-galeria-fondo: var(--orderpress-bg-alt);
}

.orderpress-galeria-item {
    display: block;
    overflow: hidden;
    border-radius: var(--orderpress-radius);
    background: var(--orderpress-galeria-fondo);
    aspect-ratio: 1 / 1;
}

.orderpress-galeria-item img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ---- Cómo entra cada foto en su caja (0.133) ----

   La base de arriba es el modo 'cover' —caja cuadrada, recorta— y se deja como está
   para no cambiarle el look a ningún sitio en producción. Los otros dos la pisan.

   'fit': la foto usa todo el ancho y el alto lo da ella. No se pierde nada, a cambio de
   filas desparejas cuando hay varias columnas.

   OJO AL TOCAR ESTO: tiene que ser width:100% y NUNCA width:auto. Con width:auto un
   <img loading="lazy"> colapsa a 0×0 antes de cargar, y con área cero el navegador no
   dispara nunca la carga lazy: la imagen no aparece jamás. Es un deadlock real — Shopr
   lo tuvo en producción y lo revirtió al día siguiente, y acá se reprodujo en el
   navegador antes de elegir este camino. Con width:100% la caja se reserva desde los
   atributos width/height que emite wp_get_attachment_image(), así que nunca hay área
   cero. */
.orderpress-galeria-ajuste-fit {
    /* Filas desparejas: que cada foto arranque arriba y no estirada al alto de la fila. */
    align-items: start;
}

.orderpress-galeria-ajuste-fit .orderpress-galeria-item {
    aspect-ratio: auto;
}

.orderpress-galeria-ajuste-fit .orderpress-galeria-item img {
    height: auto;
    /* Con la caja al tamaño exacto de la foto, object-fit no tiene nada que hacer. */
    object-fit: initial;
}

/* 'contain': la caja cuadrada se mantiene —la grilla queda pareja— y la foto entra
   entera y centrada. Es el modo de Tiendanube. */
.orderpress-galeria-ajuste-contain .orderpress-galeria-item img {
    object-fit: contain;
}

/* ---- [orderpress_variantes]: la grilla de pedido (F5, 0.94) ---- */

/* Filas = valores del atributo visual (con foto), columnas = los del otro, celda = una
   cantidad. Componente base: .orderpress-grilla. La tabla scrollea sola si no entra. */
.orderpress-grilla {
    --orderpress-grilla-celda: 64px;
    --orderpress-grilla-foto: 40px;
}

.orderpress-grilla-scroll {
    overflow-x: auto;
}

.orderpress-grilla-tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: .95em;
}

.orderpress-grilla-tabla th,
.orderpress-grilla-tabla td {
    padding: calc(var(--orderpress-spacing) / 2);
    border-bottom: 1px solid var(--orderpress-border);
    text-align: center;
    vertical-align: middle;
}

/* La primera columna (los nombres de fila y la esquina) va a la izquierda: misma
   especificidad que la regla de arriba, después en la hoja, sin !important. */
.orderpress-grilla-tabla .orderpress-grilla-esquina,
.orderpress-grilla-tabla .orderpress-grilla-fila-cab {
    text-align: left;
}

.orderpress-grilla-tabla thead th {
    color: var(--orderpress-text-muted);
    font-weight: var(--orderpress-weight-semibold);
    font-size: .85em;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.orderpress-grilla-por {
    font-weight: var(--orderpress-weight-normal);
}

.orderpress-grilla-fila-cab {
    font-weight: var(--orderpress-weight-semibold);
    white-space: nowrap;
}

.orderpress-grilla-fila-cab > * {
    vertical-align: middle;
}

.orderpress-grilla-fila-cab .orderpress-muestra {
    margin-right: calc(var(--orderpress-spacing) / 3);
}

.orderpress-grilla-foto {
    width: var(--orderpress-grilla-foto);
    height: var(--orderpress-grilla-foto);
    margin-right: calc(var(--orderpress-spacing) / 2);
    object-fit: cover;
    border-radius: var(--orderpress-radius-sm);
    background: var(--orderpress-bg-alt);
}

/* La muestra de color del valor: el color llega por variable (wp_add_inline_style). */
.orderpress-muestra {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 1px solid color-mix(in srgb, var(--orderpress-black) 20%, transparent);
    border-radius: var(--orderpress-radius-full);
    background: var(--orderpress-muestra, var(--orderpress-bg-alt));
}

.orderpress-widget .orderpress-grilla-input {
    width: var(--orderpress-grilla-celda);
    padding: calc(var(--orderpress-control-padding-y) / 1.5) calc(var(--orderpress-spacing) / 3);
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    background: var(--orderpress-superficie);
    color: var(--orderpress-text);
    font: inherit;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.orderpress-widget .orderpress-grilla-input:focus {
    outline: none;
    border-color: var(--orderpress-primary);
    box-shadow: 0 0 0 3px var(--orderpress-primary-suave);
}

.orderpress-grilla-celda--inactiva,
.orderpress-grilla-celda--agotada {
    color: var(--orderpress-text-muted);
    background: color-mix(in srgb, var(--orderpress-bg-alt) 60%, transparent);
}

.orderpress-grilla-celda--agotada .orderpress-grilla-vacia {
    font-size: .8em;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.orderpress-grilla-subtotal {
    color: var(--orderpress-text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.orderpress-grilla-pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--orderpress-spacing);
    margin-top: var(--orderpress-spacing);
}

.orderpress-grilla-total {
    display: flex;
    gap: calc(var(--orderpress-spacing) / 2);
    align-items: baseline;
    margin: 0;
    color: var(--orderpress-text-muted);
}

.orderpress-grilla-total-precio {
    color: var(--orderpress-text);
    font-size: 1.15em;
    font-variant-numeric: tabular-nums;
}

.orderpress-grilla-pie .orderpress-add-regla,
.orderpress-grilla-pie .orderpress-add-msg {
    flex-basis: 100%;
    margin: 0;
}

/* La píldora de un término del producto: un segmento ([orderpress_campo
   campo="segmentos"]) o una colección (campo="colecciones"). El aspecto vive acá una
   sola vez; cada taxonomía suma su propia clase con el modificador por slug
   (.orderpress-segmento--dama, .orderpress-coleccion--verano-2026), que son ganchos
   para que el tema las coloree y no tienen estilos nuestros. */
.orderpress-pildora {
    display: inline-block;
    margin: 0 calc(var(--orderpress-spacing) / 3) calc(var(--orderpress-spacing) / 3) 0;
    padding: 1px calc(var(--orderpress-spacing) / 1.5);
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius-full);
    background: var(--orderpress-bg-alt);
    color: var(--orderpress-text-muted);
    font-size: .8em;
    line-height: var(--orderpress-leading-relaxed);
    white-space: nowrap;
}

/* Las muestras de color de un producto en la card ([orderpress_campo campo="colores"]). */
.orderpress-muestras {
    display: inline-flex;
    flex-wrap: wrap;
    gap: calc(var(--orderpress-spacing) / 3);
    margin: calc(var(--orderpress-spacing) / 3) 0;
}

/* ---------------------------------------------------------------------------
   Formas de pago y de envío en el checkout.

   Cada opción es una caja clicable entera, no un radio con una etiqueta al lado:
   el área de toque de un radio son 16px y en un teléfono se falla. La elegida se
   marca con el primario, derivado como el resto de los estados.
   --------------------------------------------------------------------------- */

.orderpress-widget .orderpress-formas-grupo {
    margin: 0 0 var(--orderpress-space-4);
    padding: 0;
    border: 0;
}

.orderpress-widget .orderpress-formas-grupo legend {
    padding: 0;
    margin-bottom: var(--orderpress-space-2);
    font-weight: 600;
}

.orderpress-widget .orderpress-formas-opcion {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: var(--orderpress-space-1) var(--orderpress-space-2);
    margin-bottom: var(--orderpress-space-2);
    padding: var(--orderpress-space-3);
    border: 1px solid var(--orderpress-border);
    border-radius: var(--orderpress-radius);
    cursor: pointer;
}

.orderpress-widget .orderpress-formas-opcion:hover {
    border-color: var(--orderpress-border-strong);
}

/* El estado elegido se calcula del primario, no se declara: un fondo tenue y el
   borde del color, como el resto del sistema. */
.orderpress-widget .orderpress-formas-opcion:has(input:checked) {
    border-color: var(--orderpress-primary);
    background: color-mix(in srgb, var(--orderpress-primary) 6%, transparent);
}

.orderpress-widget .orderpress-formas-opcion input {
    margin: 0;
}

.orderpress-widget .orderpress-formas-nombre {
    font-weight: 500;
}

/* La nota arranca en la segunda columna: debajo del nombre, no debajo del radio. */
.orderpress-widget .orderpress-formas-nota {
    grid-column: 2;
    color: var(--orderpress-text-muted);
    font-size: var(--orderpress-text-sm);
}

/* El desglose del resumen: subtotal y un renglón por ajuste, arriba del total. Más
   chicos y en gris que el total, que es el renglón que importa. */
.orderpress-widget .orderpress-resumen-subtotal,
.orderpress-widget .orderpress-resumen-ajuste {
    display: flex;
    justify-content: space-between;
    gap: var(--orderpress-space-2);
    color: var(--orderpress-text-muted);
    font-size: var(--orderpress-text-sm);
}

.orderpress-widget .orderpress-resumen-ajustes:not(:empty) {
    margin-bottom: var(--orderpress-space-1);
}

/* En la ficha del pedido (Mi cuenta y la confirmación) los renglones del desglose usan
   la misma fila que los ítems, con el peso del texto secundario. */
.orderpress-widget .orderpress-linea--subtotal,
.orderpress-widget .orderpress-linea--ajuste {
    color: var(--orderpress-text-muted);
    font-size: var(--orderpress-text-sm);
}
