/* =========================================================================
   CIERRE DE PEDIDO — líneas del carrito, aviso del pedido, filas de método y
   estados del campo

   Retirado el modal de revisión (C3), esta hoja es lo que SOBREVIVE de él y
   que usan el panel del carrito y la página de checkout: la línea de pedido
   (la pinta nvl-cart.js), el aviso del pedido (components/cart-adjusted.php),
   la fila de método de pago (.nvl-pay-option, que la página compone en su
   propia hoja) y los tres estados del campo de la página.

   Parte de la cadena de hojas de componentes. El ORDEN DE CASCADA lo
   garantiza la cadena de dependencias declarada en inc/assets.php: ninguna
   vista encola estas hojas directamente, todas dependen del handle
   'nvl-components', que cierra la cadena. Mover una regla de archivo puede
   cambiar qué gana; mover un archivo de sitio en la cadena, también.

   Mobile-first. Todo valor visual es token var(--nvl-*).
   ========================================================================= */

/* --- Líneas del carrito (las pinta nvl-cart.js en el panel — Fase 8) ------ */

/* TRES COLUMNAS DESDE C3 (R-OW1, §F.9): la miniatura cuadrada a la izquierda, y
   el contenido de siempre —nombre, precio, cantidad, quitar e importe— entero en
   las dos columnas de la derecha, sin cambiar de orden ni de fila.

   LA MINIATURA DEL PANEL MIDE 48 EN MÓVIL Y 64 DESDE 768 (medido en C3). El
   panel deja 240px útiles a 320px de ancho, y el control de cantidad ocupa 114
   fijos: con los 64 del recibo del checkout, el control se salía de la línea. El
   lado se redefine en el ÁMBITO de la línea, así que la foto y su columna bajan
   juntas —el <img> lee el mismo token— y el recibo del checkout no se toca. */
.nvl-cart-line {
    --nvl-line-thumb: 3rem;
    display: grid;
    grid-template-columns: var(--nvl-line-thumb) minmax(0, 1fr) auto;
    gap: var(--nvl-space-3xs) var(--nvl-space-2xs);
    align-items: center;
    padding: var(--nvl-space-xs) 0;
    border-bottom: var(--nvl-border-hairline) solid var(--nvl-color-border);
}

@media (min-width: 768px) {
    .nvl-cart-line {
        --nvl-line-thumb: 4rem;
        column-gap: var(--nvl-space-xs);
    }
}

/* La miniatura ocupa las dos filas de la línea: la del nombre y la de la
   cantidad. Sin insignia, a diferencia del recibo del checkout — aquí la
   cantidad tiene su propio control, a la vista. */
.nvl-cart-line__thumb {
    grid-column: 1;
    grid-row: 1 / span 2;
}

/* MINIATURA DE LÍNEA (R-OW1, owner 2026-10-07). Receta compartida por el recibo
   del checkout (components/checkout-summary.php) y la línea del panel del
   carrito (la pinta nvl-cart.js): la imagen es la PRIMERA foto de la galería de
   la ficha, que el campo ACF ya recortó 1:1, así que la caja es cuadrada
   (--nvl-ratio-gallery) y `cover` no recorta nada visible. El fondo es el de la tira de miniaturas de la ficha: un producto
   importado cuya foto no sea cuadrada se ve igual de pareja. */
.nvl-line-thumb__img {
    display: block;
    width: var(--nvl-line-thumb);
    aspect-ratio: var(--nvl-ratio-gallery);
    object-fit: cover;
    object-position: center;
    border-radius: var(--nvl-radius-sm);
    border: var(--nvl-border-hairline) solid var(--nvl-color-border);
    background: var(--nvl-color-section-alt);
}

/* Sin foto, la MISMA caja vacía. Sin ícono: el nombre al lado identifica el
   producto y un ícono genérico se leería como imagen rota. */
.nvl-line-thumb__img--empty {
    height: var(--nvl-line-thumb);
}


/* Columna 2, fila 1, declarado: con la miniatura ocupando las dos filas de la
   primera columna y la papelera fijada en la tercera, la colocación automática
   mandaría el nombre a la celda del importe (medido: el nombre salía a la
   derecha del control de cantidad). */
.nvl-cart-line__info {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.nvl-cart-line__title {
    font-weight: var(--nvl-weight-bold);
    font-size: var(--nvl-text-sm);
    line-height: var(--nvl-leading-heading);
    overflow-wrap: anywhere;
}

.nvl-cart-line__unit {
    color: var(--nvl-color-text-secondary);
    font-size: var(--nvl-text-xs);
    font-weight: var(--nvl-weight-regular); /* microcopia (auditoría ui-ux §1.5) */
}

@media (min-width: 768px) {
    .nvl-cart-line__unit {
        font-size: var(--nvl-text-sm);
    }
}

/* Tope de existencias de la línea (owner, 2026-09-20). Tercer renglón dentro
   de .nvl-cart-line__info, que ya es una columna: no toca la retícula de la
   línea. En tinta PRIMARIA y no secundaria —a 12px el gris secundario se
   queda en 4.36:1 sobre la banda del panel, el mismo criterio ya aplicado a
   .nvl-pay-option__desc—. Dice el límite, no la escasez, y solo aparece
   cuando la línea ya está en el tope. */
/* EL AVISO DE TOPE, y su resalte al insistir en el + (owner, 2026-10-16).

   Se ciñe a su texto en vez de ocupar la columna —es un hijo de un flex en
   columna, que por defecto lo estiraría— porque el resalte de abajo pinta un
   fondo: a ancho completo sería una banda, y lo que hace falta es una pastilla
   sobre la frase. El relleno horizontal lo cancela un margen negativo igual,
   así que en reposo el texto sigue alineado con el título de arriba y la
   línea no se mueve ni un píxel al animarse. */
.nvl-cart-line__max {
    align-self: flex-start;
    margin-inline-start: calc(var(--nvl-space-3xs) * -1);
    padding-inline: var(--nvl-space-3xs);
    border-radius: var(--nvl-radius-xs);
    color: var(--nvl-color-text-primary);
    font-size: var(--nvl-text-2xs);
    font-weight: var(--nvl-weight-bold);
    font-variant-numeric: tabular-nums;
}

/* SOLO COLOR, SIN `transform`, por lo mismo que lo dice el bump del contador
   en nvl-base.css: este aviso vive dentro de una lista que se desplaza, y una
   escala podría desbordar o empujar una caja. Además, a 12px un pulso de
   escala no se percibe; un relleno que entra y se va, sí.

   El ámbar es RELLENO y la tinta se queda la que ya tenía: --nvl-color-text-primary
   sobre --nvl-color-warning da 6.81:1, por encima de AA, así que la frase se
   lee igual de bien en el pico de la animación que en reposo. Es la regla del
   tema desde septiembre —ámbar nunca como tinta— y aquí se cumple sola.

   SIN rama de movimiento reducido a propósito: no hay movimiento que reducir.
   `prefers-reduced-motion` protege del desplazamiento, y aquí no hay ninguno;
   quitarla dejaría el tope sin ninguna señal justo a quien más agradece una. */
@keyframes nvl-line-max-flash {
    0%   { background: transparent; }
    20%  { background: var(--nvl-color-warning); }
    70%  { background: var(--nvl-color-warning); }
    100% { background: transparent; }
}

.nvl-cart-line__max.nvl-is-flashing {
    animation: nvl-line-max-flash var(--nvl-duration-slower) var(--nvl-ease-out);
}

/* Fila 2, no 1: la fila del título la ocupa ahora la papelera por su derecha.
   El importe queda junto a la cantidad que lo produce, que es además la
   estructura de las tiendas que el dueño puso como referencia. */
.nvl-cart-line__total {
    grid-column: 3;
    grid-row: 2;
    font-weight: var(--nvl-weight-bold);
    font-size: var(--nvl-text-sm);
    color: var(--nvl-color-primary-dark);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Columna 2 (la de la derecha de la miniatura) y no 2/-1: la columna 3 de esta
   fila la ocupa el importe.

   SOLO la colocación en la rejilla (owner, 2026-09-22): `display`, `align-items`
   y `gap` se retiran de aquí. Los declaraba también nvl-elements.css y esta hoja
   va DESPUÉS en la cascada, así que su `gap: var(--nvl-space-2xs)` pisaba el
   `gap: 0` del grupo y separaba los tres segmentos 8px — el mismo fallo que
   nvl-product-card.css tenía con el stepper de la ficha. */
.nvl-cart-line__controls {
    grid-column: 2;
}

/* .nvl-cart-line__step vive en nvl-elements.css, compartido con el stepper del
   bloque de agregado. Aquí se declaraba por separado y había divergido: su
   borde era `2px solid var(--nvl-color-border-hover)`, literal sin token y
   1.48:1 sobre blanco — por debajo del 3:1 que WCAG 1.4.11 pide al límite de
   un control. No se redeclara: esta hoja va después en la cascada. */

.nvl-cart-line__qty {
    min-width: var(--nvl-space-lg);
    text-align: center;
    /* 400, en sincronía con .nvl-add-control__value (owner, 2026-09-22): son el
       mismo control en dos superficies y ya habían divergido una vez. */
    font-weight: var(--nvl-weight-regular);
    line-height: var(--nvl-leading-snug);
    font-variant-numeric: tabular-nums;
}

/* Acción SECUNDARIA, al extremo derecho de la fila del título.

   SIN font-size propio: el glifo hereda 1em del documento (16px), igual que el
   − y el + del stepper. El contrato de iconografía (nvl-icons.css) dice que el
   icono nunca lleva font-size propio, y el var(--nvl-text-xl) que había aquí
   —único de toda la fila— era la causa real de que se viera enorme. No se
   sustituye por otro valor: se borra.

   Tinta secundaria y cero rojo en todos los estados. #64748b da 4.76:1 sobre la
   superficie y 4.36:1 sobre el gris de su propio hover, muy por encima del 3:1
   que WCAG 1.4.11 pide a un elemento no textual; el rojo que había daba 3.45:1
   sobre ese mismo hover. La tinta primaria queda descartada en reposo porque es
   la del NOMBRE del producto, justo con lo que no debe competir. */
.nvl-cart-line__remove {
    /* Columna 3 desde C3: la miniatura corrió una columna a todo lo demás. Es
       EXPLÍCITA porque la colocación automática la metería en la celda del
       nombre (y el nombre se iría a la columna del importe). */
    grid-column: 3;
    grid-row: 1;
    /* La columna 3 la dimensiona el importe: sin esto la papelera quedaría
       flotando a su izquierda en vez de pegada al borde de la fila. */
    justify-self: end;
    align-self: start;
    /* Caja visible de 24px —4px de aire alrededor del glifo de 16px— para
       poder alinearla con la línea del título; el objetivo táctil completo lo
       restituye el ::after. El margen negativo centra ópticamente el glifo
       sobre esa línea, que mide --nvl-text-sm x --nvl-leading-heading. */
    position: relative;
    width: var(--nvl-icon-lead);
    height: var(--nvl-icon-lead);
    margin-block-start: calc((var(--nvl-text-sm) * var(--nvl-leading-heading) - var(--nvl-icon-lead)) / 2);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: var(--nvl-radius-circle);
    background: transparent;
    color: var(--nvl-color-text-secondary);
    line-height: 1;
    cursor: pointer;
    /* 120ms y no 200: mismo criterio ya escrito para el stepper en
       nvl-elements.css. Los dos controles de la fila responden al mismo ritmo. */
    transition:
        background-color var(--nvl-duration-fast) var(--nvl-ease-standard),
        color            var(--nvl-duration-fast) var(--nvl-ease-standard);
}

/* Devuelve el área pulsable de --nvl-tap-min sin agrandar la caja visible ni
   empujar la rejilla: el icono mide 16px y el objetivo sigue midiendo 44. */
.nvl-cart-line__remove::after {
    content: "";
    position: absolute;
    inset: calc((var(--nvl-icon-lead) - var(--nvl-tap-min)) / 2);
}

@media (hover: hover) and (pointer: fine) {
    .nvl-cart-line__remove:hover {
        background: var(--nvl-color-background);
        color: var(--nvl-color-text-primary);
    }
}

/* Mismo fondo que el hover: sin él, el anillo de foco encerraría un disco
   vacío alrededor de un glifo de 16px. El anillo lo pone el :focus-visible
   global; aquí no se redefine ni se anima. */
.nvl-cart-line__remove:focus-visible {
    background: var(--nvl-color-background);
    color: var(--nvl-color-text-primary);
}

/* El fondo TAMBIÉN aquí, no solo en hover: en táctil el bloque de arriba no
   aplica y sin esto el toque no tendría acuse. El cambio de tinta es portante
   —con movimiento reducido el scale desaparece y es lo único que queda. */
.nvl-cart-line__remove:active {
    background: var(--nvl-color-background);
    color: var(--nvl-color-secondary);
    transform: scale(0.94);
}

/* En colores forzados el sistema descarta el fondo y el hover se quedaría sin
   ninguna señal. Mismo agujero que el stepper cierra en nvl-elements.css. */
@media (forced-colors: active) {
    .nvl-cart-line__remove:hover,
    .nvl-cart-line__remove:focus-visible {
        color: Highlight;
    }
}

/* Línea de regalo (Etapa 2, Fase 2): no editable, sin controles de cantidad
   ni botón de eliminar — y SIN miniatura (el regalo lo define la campaña, no un
   producto del catálogo): grid de una sola fila entre info y el badge. */
.nvl-cart-line--gift {
    grid-template-columns: minmax(0, 1fr) auto;
}

/* Sin miniatura, el nombre vuelve a la primera columna y el sello a la segunda:
   las dos colocaciones explícitas de la línea normal (columnas 2 y 3) se
   corrigen aquí, o el regalo abriría una tercera columna implícita. */
.nvl-cart-line--gift .nvl-cart-line__info {
    grid-column: 1;
}

.nvl-cart-line--gift .nvl-cart-line__title {
    display: inline-flex;
    align-items: center;
    gap: var(--nvl-space-2xs);
}

/* El icono de regalo no puede llevar el verde oficial: 2.54:1, por debajo
   incluso del 3:1 de elemento no textual. La señal verde la da el chip de al lado. */
.nvl-cart-line--gift .nvl-icon {
    color: var(--nvl-color-text-primary);
}

/* Chip verde, misma anatomía que .nvl-availability; texto de
   --nvl-color-on-success (opción de Configuración del sitio). */
.nvl-cart-line__total--gift {
    /* NO es redundante: desde que el importe normal bajó a la fila 2 para
       dejarle sitio a la papelera, estas dos colocaciones son lo único que
       mantiene el sello del regalo en la fila del título y en la segunda
       columna de su rejilla de dos (la normal lo pone en la tercera). */
    grid-column: 2;
    grid-row: 1;
    display: inline-flex;
    align-items: center;
    padding: var(--nvl-space-3xs) var(--nvl-space-2xs);
    border-radius: var(--nvl-radius-xs);
    border: var(--nvl-border-hairline) solid transparent;
    background: var(--nvl-color-success);
    color: var(--nvl-color-on-success);
    text-transform: uppercase;
    font-size: var(--nvl-text-2xs);
    font-weight: var(--nvl-weight-bold);
}

/* --- AVISO DEL PEDIDO (components/cart-adjusted.php) ----------------------
   Rediseño de C3 (§F.9). Lo que el owner no quería: una caja ámbar con borde y
   relleno, título en 700, viñetas y pie, y una SEGUNDA caja del mismo peso para
   el mínimo, lejos del botón que bloquea — tres recuadros en un panel de 372px.

   Ahora el aviso no es una caja: es TEXTO CON UN FILO, y cada aviso va donde
   actúa. Este, encima de las líneas que cambiaron (la nota del mínimo se pegó al
   botón, en nvl-cart-summary.css). Misma receta que el aviso de la página de
   checkout (.nvl-checkout-notice) y que los avisos de las páginas legales.

   SE VE SOLO CON data-kind, que el JS pone cuando tiene algo que decir y quita
   con la siguiente acción sobre el carrito. Antes bastaba con que su lista
   tuviera <li>, y eso ya no sirve: de los cuatro casos, «total» y «quote» no
   llevan lista. El nodo NUNCA sale del árbol, que es lo que hace fiable el
   anuncio de una región viva (mismo criterio que components/cart-toast.php).

   El filo ámbar es DECORATIVO: 2.15:1 sobre blanco no llega al 3:1 que pide un
   elemento no textual, así que la información está entera en el texto, nunca en
   el color. En colores forzados lo pinta el sistema.

   Sin temporizador a propósito: hay que poder leerlo. */
.nvl-cart-adjusted {
    display: grid;
    gap: var(--nvl-space-3xs);
    padding-inline-start: var(--nvl-space-xs);
    margin-bottom: var(--nvl-space-sm);
    border-inline-start: var(--nvl-border-accent) solid var(--nvl-color-warning);
    color: var(--nvl-color-text-primary);
    font-size: var(--nvl-text-sm);
    line-height: var(--nvl-leading-normal);
    text-align: start;
    animation: nvl-reveal var(--nvl-duration-base) var(--nvl-ease-out) both;
}

.nvl-cart-adjusted:not([data-kind]) {
    display: none;
}

/* SIN ANILLO DE FOCO (owner, 2026-11-05). El bloque lleva tabindex="-1" y el JS
   lo enfoca al aparecer para que un lector de pantalla lo anuncie; eso disparaba
   el :focus-visible global de nvl-base.css y dibujaba un contorno azul alrededor
   del aviso hasta que se hacía clic en otro sitio.

   SE QUITA EL DIBUJO, NO EL FOCO: el anuncio sigue intacto. Y se puede quitar
   porque este bloque NO es operable con teclado —tabindex="-1" lo deja fuera del
   orden de tabulación—, así que el anillo no señalaba nada que nadie pudiera
   recorrer. Quitarlo de un elemento que SÍ se tabula sería otra cosa, y estaría
   mal.

   Acotado al contenedor: los descendientes conservan su anillo si algún día
   alguno es interactivo. */
.nvl-cart-adjusted:focus,
.nvl-cart-adjusted:focus-visible {
    outline: none;
}

/* No se pudo COTIZAR (P-8.3): el único caso que no cuenta un ajuste ya hecho,
   sino algo que no se pudo hacer. Rojo de borde, donde el umbral es 3:1. */
.nvl-cart-adjusted--danger {
    border-inline-start-color: var(--nvl-color-danger);
}

.nvl-cart-adjusted__title {
    margin: 0;
    /* Era 700. Un aviso de tres renglones no necesita el peso del título de una
       pantalla para que se lea primero: ya es lo primero. */
    font-weight: var(--nvl-weight-bold);
}

.nvl-cart-adjusted__body {
    margin: 0;
}

.nvl-cart-adjusted__body[hidden],
.nvl-cart-adjusted__foot[hidden] {
    display: none;
}

/* Un renglón por producto, con el nombre delante: sin viñetas, que eran la
   tercera capa de ornamento del aviso viejo. */
.nvl-cart-adjusted__list {
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--nvl-space-3xs);
    list-style: none;
}

.nvl-cart-adjusted__foot {
    margin: 0;
    font-size: var(--nvl-text-xs);
    font-weight: var(--nvl-weight-regular);
    /* 4.76:1 sobre el blanco del panel. */
    color: var(--nvl-color-text-secondary);
}

@keyframes nvl-flash {
    0%, 100% { transform: scale(1); }
    25%, 75% { transform: scale(1.03); }
    50% { transform: scale(1); }
}

/* Resalte de la frase del recorrido cuando se pulsa el botón bloqueado: el
   motivo de que no deje continuar está ahí, y un botón que no responde sin
   explicar nada es lo que hace dudar de si se pulsó. Duración tokenizada: el
   literal de 900ms se fue con la nota del mínimo a la que servía. */
.nvl-reward__phrase.nvl-is-flashing {
    animation: nvl-flash var(--nvl-duration-slower) var(--nvl-ease-standard);
}

/* Aparición de bloques que el JS revela quitando [hidden] (progreso de
   campaña, banner promocional): sin clase nueva, arranca sola al pintarse. */
@keyframes nvl-reveal {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

/* SIN ESTADO DE HOVER (owner, 2026-10-14). El campo lo tuvo —el borde pasaba a
   tinta primaria— y era el borde oscuro que el owner pidió retirar, volviendo
   por la puerta de atrás en cuanto el puntero rozaba el campo. Pasar el ratón
   por encima no es una decisión del cliente y no tiene por qué pintar nada: el
   campo cambia cuando se ENFOCA, que es cuando el cliente lo eligió. Si alguien
   quiere devolver una señal de puntero aquí, que no sea el borde. */

/* Inválido: borde + sombra de un hairline del mismo color leen como un trazo
   de 2px sin mover el texto (mismo recurso que la opción de pago elegida). Va
   ANTES del foco: con el mismo peso, el campo que se está corrigiendo se ve en
   azul; el error lo sigue diciendo el mensaje bajo el campo. */
.nvl-checkout-field__control[aria-invalid="true"] {
    border-color: var(--nvl-color-danger);
    box-shadow: 0 0 0 var(--nvl-border-hairline) var(--nvl-color-danger);
}

/* ESTADOS DEL CAMPO DE LA PÁGINA DE CHECKOUT (receta F3.1). Inválido y foco de
   un solo trazo —el hover se retiró el 2026-10-14, ver arriba—. Hasta C2 cada
   regla era una lista de dos selectores,
   porque el campo del modal usaba la misma receta; retirado el modal (C3) queda
   solo el de la página. El autorrelleno y el alto del campo viven en
   nvl-checkout-page.css, que es donde está su base: estas tres reglas se quedan
   aquí para no cambiar el orden de cascada que ya estaba medido.

   Foco: UN solo trazo de 2px en primario —borde + sombra de 1px, la receta de
   la opción de pago elegida— (owner, 2026-10-07: el anillo global separado del
   borde se leía como doble borde). :focus y no :focus-visible: en el select
   :focus-visible no casa con el ratón y el owner quiere todo campo enfocado
   marcado igual. El outline NO se quita: queda transparente y pegado, y solo se
   pinta en forced-colors, donde el navegador descarta las sombras. */
.nvl-checkout-field__control:focus {
    border-color: var(--nvl-color-primary);
    box-shadow: 0 0 0 var(--nvl-border-hairline) var(--nvl-color-primary);
    outline: var(--nvl-focus-width) solid transparent;
    outline-offset: 0;
}

/* Rejilla de tres filas de la fila de método (docs/checkout-pagina-especificacion.md §F.7):
   radio · título / descripción / nota. __body y __amount son display:contents,
   así sus hijos se colocan directamente aquí sin cambiar el marcado. Son <span> sin rol: el <label> sigue recibiendo el clic y su nombre
   accesible no cambia. */
.nvl-pay-option {
    display: grid;
    /* Dos columnas desde C4: el importe por método se retiró de la fila (el
       total se dice una sola vez, en el recibo), así que la tercera columna —la
       que lo sostenía— ya no tiene contenido. */
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
        "radio title"
        ".     desc"
        ".     note";
    column-gap: var(--nvl-space-xs);
    row-gap: var(--nvl-space-3xs);
    align-items: baseline;
    /* Grid item: su tamaño mínimo automático es min-content (333.6px medidos,
       contra los 310 disponibles a 390px), así que ensancharía el fieldset
       aunque este ya pueda encoger. Mismo patrón que .nvl-cart-line__info. */
    min-width: 0;
    padding: var(--nvl-space-xs);
    /* El gris de los controles de formulario, el mismo que el campo y el que
       dibuja su envoltura en el checkout (owner, 2026-10-14). Hoy esta
       declaración no llega a verse —.nvl-checkout-method la anula con border: 0
       desde C4, porque la caja pasó a ser la lista—, pero si la fila vuelve a
       tener caja propia en otra superficie, tiene que nacer con el mismo trazo
       que todo lo demás. */
    border: var(--nvl-border-hairline) solid var(--nvl-color-border-field);
    border-radius: var(--nvl-radius-md);
    cursor: pointer;
    /* Solo color, nunca layout. El foco NO se anima (criterio de nvl-base.css).
       En prefers-reduced-motion todo esto queda anulado por el bloque de
       nvl-components.css, que lista .nvl-pay-option. */
    transition:
        border-color var(--nvl-duration-base) var(--nvl-ease-standard),
        box-shadow var(--nvl-duration-base) var(--nvl-ease-standard);
}

@media (hover: hover) and (pointer: fine) {
    .nvl-pay-option:hover {
        border-color: var(--nvl-color-border-hover);
    }
}

/* Su display:grid anula hidden: el JS oculta la opción que el servidor dice que
   ya no se puede cobrar. */
.nvl-pay-option[hidden] {
    display: none;
}

/* La opción NO pinta foco a nivel de caja. Lo hacía con :focus-within, que no
   distingue teclado de ratón: al abrir el modal el JS enfocaba el primer radio
   (nvl-cart.js, antes de F3), así que la primera opción salía ya rodeada de azul sin estar
   siquiera elegida, y al elegir una el anillo desplazado se sumaba al filo de
   la propia selección y se leía como un borde doble. El radio conserva su
   anillo por el :focus-visible global de nvl-base.css, que sí lo distingue y
   que resuelve exactamente a la misma regla que la landing declara a mano
   sobre su radio. Misma decisión que .nvl-product-card y .nvl-category-card.
   No reintroducir: si alguna vez hace falta reforzar el foco tras un error de
   validación, se marca desde el JS, no con :focus-within. Desde F3 el foco de
   apertura va al título, pero la decisión se mantiene: el radio se enfoca con
   el teclado y tras un error de validación. */

/* El filo de la opción elegida son DOS declaraciones adyacentes del mismo
   color —borde de 1px y sombra de spread 1px sin hueco— que juntas leen como
   un único trazo de 2px. Es la réplica literal de la landing. No sustituir la
   sombra por border-width: 2px: eso restaría 1px al contenido por lado y
   movería el texto al seleccionar. Sin fondo tintado (2026-10-06): el filo y el
   radio marcado bastan, y sobre blanco la tinta secundaria de la descripción y
   la nota cumple AA (4.76:1; sobre la banda daba 4.36). */

.nvl-pay-option:has(input:checked) {
    border-color: var(--nvl-color-primary);
    box-shadow: 0 0 0 var(--nvl-border-hairline) var(--nvl-color-primary);
}

/* El ícono del método elegido pasa a azul junto con el filo y el punto del
   radio (owner, 2026-10-07). Solo color: el título y el precio siguen en tinta
   (el azul nunca va en una cifra). Cambia a la vez que el borde de la opción. */
.nvl-pay-option__title .nvl-icon {
    transition: color var(--nvl-duration-base) var(--nvl-ease-standard);
}

.nvl-pay-option:has(input:checked) .nvl-pay-option__title .nvl-icon {
    color: var(--nvl-color-primary);
}

/* Sin esto el punto del radio elegido lo pinta el navegador con su propio azul
   (#0b57d0 en Chrome), que no está entre los 20 colores oficiales: la opción
   elegida mostraba dos azules distintos, el del sistema en el punto y el de
   marca en el filo. La landing lo declara igual sobre su radio. */
.nvl-pay-option input[type="radio"] {
    grid-area: radio;
    accent-color: var(--nvl-color-primary);
}

.nvl-pay-option__body,
.nvl-pay-option__amount {
    display: contents;
}

.nvl-pay-option__title {
    grid-area: title;
    display: inline-flex;
    align-items: center;
    gap: var(--nvl-space-2xs);
    font-weight: var(--nvl-weight-bold);
    font-size: var(--nvl-text-sm);
}

/* Microcopia en regular, mismo criterio que .nvl-microcopy y
   .nvl-cart-line__unit: con tres pesos no hay escalón intermedio, y su título
   (.nvl-pay-option__title, bold) es el que carga el par. */
.nvl-pay-option__desc {
    grid-area: desc;
    color: var(--nvl-color-text-secondary);
    font-size: var(--nvl-text-xs);
    font-weight: var(--nvl-weight-regular);
}

@media (min-width: 768px) {
    .nvl-pay-option__desc {
        font-size: var(--nvl-text-sm);
    }
}

/* Alineada con la descripción y no al borde derecho: desde C4 la fila no lleva
   importe, así que no hay columna derecha con la que alinearse. */
.nvl-pay-option__note {
    grid-area: note;
    justify-self: start;
    text-align: start;
    color: var(--nvl-color-text-secondary);
    font-size: var(--nvl-text-xs);
    font-weight: var(--nvl-weight-regular);
    line-height: var(--nvl-leading-normal);
}

.nvl-pay-option__note:empty {
    display: none;
}

/* El ahorro de la transferencia, en píldora verde (owner, 2026-10-07: la
   transferencia se prioriza y su ahorro tiene que verse). La receta de la
   etiqueta de logro de la cápsula: sin relleno vertical (el alto lo da el
   interlineado de la nota) y el filo transparente como outline y no border,
   para que la opción no crezca ni un píxel; se ve en forced-colors, donde el
   relleno se descarta. La tinta es la de todas las etiquetas verdes y la elige
   el owner en Configuración del sitio (--nvl-color-on-success). */
.nvl-pay-option__note--saving {
    padding-inline: var(--nvl-space-2xs);
    border-radius: var(--nvl-radius-pill);
    outline: var(--nvl-border-hairline) solid transparent;
    background: var(--nvl-color-success);
    color: var(--nvl-color-on-success);
    font-weight: var(--nvl-weight-bold);
    white-space: nowrap;
}

@media (min-width: 768px) {
    .nvl-pay-option__note {
        font-size: var(--nvl-text-sm);
    }
}
