/* =============================================================================
   MonkeyCams — Componentes UI compartidos

   Guía de uso (siempre partir de `.btn` en <button> salvo excepciones):

   · Cerrar/quitar (X): ac-icon-btn ac-icon-btn--neutral|frosted|subtle [+ tamaño --l|--m|--s] [+ --dim]
     (--neutral --l = 44×44, tono "surface" siempre visible — cerrar modal/panel;
      --frosted --l = igual pero sobre overlay/imagen; --subtle --s [--dim] =
      invisible hasta tocar, rojo — quitar/borrar etiqueta)
   · Acciones planas (modales, barras): contenedor .ac-btn-bar + btn-accent | btn-muted | btn-danger
   · CTA sólido:     btn ac-btn ac-btn--primary ac-btn--m
   · Peligro sólido: btn ac-btn ac-btn--danger ac-btn--m
   · Texto plano:    btn ac-btn ac-btn--plain ac-btn--accent|--neutral (+ tamaño)
   · Tinte accent:   btn ac-btn ac-btn--accent ac-btn--s
   · Menú:           btn ac-icon-btn ac-icon-btn--neutral ac-icon-btn--s | ac-btn-menu-item [--danger]
   · Acción en texto de cabecera de sección: ac-btn-inline [+ --danger]
   · Segmentado:     ac-segment > btn ac-segment-btn
     (+ ac-segment--pill: cada opción como chip — a partir de 3 opciones)
   · Icono circular:  ac-icon-btn ac-icon-btn--danger|success|accent [+ --l]
     (papelera 44×44 cabecera con --l; confirmar/añadir 28×28 (--s) filas de formulario;
      --frosted también cubre icono-sobre-foto/overlay — flechas de lightbox, favorito,
      comparar, pantalla completa, descarga)
   · Volver arriba:  ac-icon-btn ac-icon-btn--frosted ac-icon-btn--l + ac-scroll-top-btn
     (posición fija, se funde con `[inert]`; un solo botón en el DOM sirve a
      las cinco pantallas — el scroll es de `window`, no por panel; ver
      assets/js/scroll-top.js)
   · Filtros:        ac-pill (toggle) | select-pill / news-brand-select (dropdown) — altura --ac-filter-h
   · Buscador pill:  ac-search-input  (Inventario, Cámaras, Películas, Recetas, Noticias — lupa + alto unificado)
   · Buscador flat:  ac-search-input ac-search-input--flat  (formularios / panel editor)
   · Confirmación:   ac-confirm-dialog
   · Carga:          ac-spinner (el indicador) | ac-boot (cortina de arranque,
                     tapa la app entera) | ac-loading (spinner centrado en el
                     sitio de una lista). UNO en toda la app: ver más abajo.
   · Solo lectores:  ac-sr-only
   ============================================================================= */

/* `hidden` tiene que esconder, siempre.
   El `[hidden] { display: none }` del navegador va en la hoja del user-agent,
   así que CUALQUIER regla de autor que declare `display` lo pisa por origen —
   y aquí abajo lo declaran `.ac-btn`, `.ac-icon-btn`, `.ac-pill`… Resultado:
   un botón con el atributo `hidden` puesto seguía viéndose. Pasó dos veces:
   con «Quitar» del campo de foto (a la vista sin haber foto, y borrando la
   que hubiera al pulsarlo) y con el «+» de etiqueta nueva (a la vista con su
   propio formulario ya abierto). Ya había dos parches locales para lo mismo
   (`#editor-new-btn` en editor.css, `.app-layout > [hidden]` en site-nav.css),
   que es la señal de que el arreglo va aquí y una sola vez. `!important`
   porque es exactamente lo que hay que ganar: cualquier `display` de clase.
   Corolario para los tests: `getComputedStyle(el).display !== "none"` NO es
   una prueba de visibilidad — usar `el.offsetParent === null`. */
[hidden] {
    display: none !important;
}

/* Foco de alto contraste — excepto iconos circulares (tienen su propio foco). */
:where(button:not(.ac-icon-btn), a, input, select, textarea, [tabindex]):focus-visible {
    outline: 3px solid var(--focus-ring, #ffd60a) !important;
    outline-offset: 3px !important;
}

/* Contenedores de diálogo (tabindex="-1": sheet de filtros, ficha de cámara,
   panel de revisión) reciben el foco al abrirse solo para que Tab entre
   dentro — no son controles reales y no deben pintar el anillo amarillo de
   arriba. Antes "funcionaba" porque el navegador no marca :focus-visible en
   un foco por script inmediatamente después de un clic/toque real — pero
   tras un `await` (p. ej. verificar el PIN, ~1s de PBKDF2) se pierde esa
   atribución y el anillo aparece igualmente, ahora rodeando el diálogo
   entero. El primer control interactivo de dentro (X, casilla, botón) sigue
   pintando su propio anillo al llegar por Tab, así que no se pierde foco
   visible para teclado, solo el del contenedor en sí. */
.filter-sheet-panel:focus-visible,
.cam-drawer:focus-visible,
#editor-review-backdrop .editor-modal:focus-visible {
    outline: none !important;
}

/* Los campos de entrada ya definen su propio anillo de acento en :focus
   (box-shadow azul), para no destacar tanto como el amarillo de arriba en un
   campo de texto normal. Chromium marca :focus-visible en cualquier input o
   select tocado con el dedo o el ratón, no solo por teclado — así que sin esto,
   CADA clic mostraba el amarillo encima del azul propio (doble anillo, parecía
   un fallo). Se arma el color al acento y se conserva el resto (grosor/offset)
   del global de arriba.

   POR TIPO DE ELEMENTO, no por clase. Hasta el 2026-08-03 esto era una lista de
   catorce selectores de clase (`.ac-search-input`, `.ep-textarea`,
   `.lb-notes-area`…) que había que ampliar a mano con cada campo nuevo — y
   `.ep-input` nunca llegó a entrar, así que **todos** los campos del formulario
   de carrete y del de parte se abrían con el anillo amarillo de 3px encima de su
   propio borde azul. Lo reportó el usuario. Las catorce clases de aquella lista
   eran, sin excepción, un `input`, un `select` o un `textarea`: enumerarlas no
   añadía precisión, solo daba una forma de olvidarse.

   Se excluyen casilla, radio y deslizador: no tienen anillo propio y el amarillo
   es lo único que los marca (las casillas del panel de revisión de cambios). */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline-color: var(--accent) !important;
}
/* ── Solo para lectores de pantalla ────────────────────────────────────────
 *
 * Texto que hay que anunciar pero no pintar. Existía ya en el repo, pero
 * escrito a mano dentro de `.skip-link:not(:focus)` (site-nav.css): al
 * necesitarlo el indicador de carga —alguien tiene que decir «cargando» a quien
 * no ve el spinner— sube a utilidad con nombre en vez de copiar las seis
 * declaraciones. `clip-path` con `clip` de reserva: `clip` está obsoleto pero
 * sigue siendo lo que entienden algunos lectores antiguos.
 */
.ac-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ── Carga: un spinner, y nada más ─────────────────────────────────────────
 *
 * Aquí hubo un esqueleto —bloques grises con la forma de lo que iba a
 * llegar— durante dos días. El usuario lo probó y pidió lo contrario: «que no
 * se viera nada hasta que no se cargue, solamente un spinner y ya». El
 * diagnóstico era bueno: con el esqueleto seguían a la vista el título, el
 * desplegable «Marcas», el buscador y las cabeceras de la tabla — media
 * pantalla de mobiliario encima de unos datos que no existían.
 *
 * La regla, ahora: **mientras una pantalla no tiene datos, no enseña nada de
 * sí misma.** Un solo indicador para toda la app, en dos tamaños de uso:
 * `.ac-boot` tapa la aplicación al arrancar y `.ac-loading` ocupa el sitio de
 * una lista que aún no ha llegado.
 */
.ac-spinner {
    display: block;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    /* El anillo es del color del borde y solo un cuarto se tiñe de acento: un
       círculo entero de acento gira sin que se note que gira. */
    border: 2px solid var(--border);
    border-top-color: var(--accent);
    animation: ac-spin 0.7s linear infinite;
}
@keyframes ac-spin {
    to {
        transform: rotate(360deg);
    }
}
/* Sin movimiento no puede girar, así que late. Sigue diciendo «esto está
   trabajando» sin nada que se desplace. */
@keyframes ac-pulse {
    50% {
        opacity: 0.3;
    }
}
@media (prefers-reduced-motion: reduce) {
    .ac-spinner {
        animation: ac-pulse 1.4s ease-in-out infinite;
        border-color: var(--accent);
    }
}

/* La cortina de arranque. Va en el HTML y no la crea el JS: si la creara el
   JS habría un parpadeo de la app a medio dibujar antes de que corriera nada,
   que es exactamente lo que se está evitando. Opaca, no translúcida — el
   `--bg-body` de debajo tiene grano y a media opacidad se leía el mobiliario. */
.ac-boot {
    position: fixed;
    inset: 0;
    /* `100vw` y no el `right: 0` de `inset`: el hueco que reserva
       `scrollbar-gutter: stable` queda FUERA del bloque contenedor de un
       elemento fijo, y sin esto la cortina medía 380 sobre un viewport de 390
       (medido en un 390×844). Diez píxeles de franja vertical enseñando que
       detrás hay una página larguísima. `100vw` sí incluye ese hueco. */
    width: 100vw;
    z-index: var(--z-boot);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-body);
    transition: opacity 0.3s var(--ease-out);
}
.ac-boot--out {
    opacity: 0;
    pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
    .ac-boot {
        transition: none;
    }
}

/* El spinner en el sitio de una lista que todavía no ha llegado. El alto
   mínimo evita que la página encoja hasta nada y luego dé un salto: no es
   reservar la forma —eso era el esqueleto— sino no quedarse en cero. */
.ac-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 220px;
    width: 100%;
}
/* Dentro de un campo de la ficha de una cámara: ahí no falta la pantalla
   entera, falta UN dato de una pantalla que ya está delante y se puede leer.
   Así que ni tapa nada ni reserva media página — solo dice que ese campo
   todavía está en camino. */
.ac-loading--inline {
    justify-content: flex-start;
    min-height: 0;
    padding: 4px 0;
}
.ac-loading--inline .ac-spinner {
    width: 18px;
    height: 18px;
}

/* ── Barra de acciones planas (estilo modal token) ───────────────────────── */
.ac-btn-bar {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
    flex-wrap: wrap;
}
.btn-accent {
    color: var(--accent);
}
.btn-muted {
    color: var(--text-muted);
}
.btn-danger {
    color: var(--err-color, #ff453a);
    border-color: transparent;
    background: transparent;
}
/* Todos los contenedores de acciones llevan .ac-btn-bar en el markup
   (convención de COMPONENTS §3.1): un único selector cubre modales, panel
   editor, ficha, sheet de filtros y estados vacíos. */
.ac-btn-bar .btn {
    border-color: transparent;
    background: transparent;
    min-height: 44px;
    padding: 8px 16px;
    font-weight: 600;
    border-radius: var(--radius-sm);
}
.ac-btn-bar .btn:hover {
    border-color: transparent;
}
/* Casi todos los botones de estas barras son solo texto, pero «Usar mi foto»
   lleva icono. Un SVG inline sin `width`/`height` no tiene tamaño propio: dentro
   de un botón flex que ocupa todo el ancho del panel, se estiraba hasta
   llenarlo — de ahí la cámara gigante del panel de la receta. `.ac-btn svg` ya
   resolvía esto para el botón de texto del sistema; al pasar esa fila de
   `ac-btn--primary` a la barra plana el 2026-07-31 (ver recipes.css,
   §«Usar mi foto») se quedó sin la regla. El tamaño es el mismo token que usa
   `.ac-btn svg`, para que el icono de la cámara se vea igual aquí que en su
   gemelo «Mi foto» de la hoja de contactos. */
.ac-btn-bar .btn svg {
    width: var(--ac-icon-xs);
    height: var(--ac-icon-xs);
    flex-shrink: 0;
}
@media (hover: hover) {
    .ac-btn-bar .btn-accent:hover {
        background: var(--accent-dim);
        color: var(--accent);
    }
    .ac-btn-bar .btn-muted:hover {
        background: var(--bg-hover);
        color: var(--text-main);
    }
    .ac-btn-bar .btn-danger:hover,
    .btn-danger:hover {
        background: rgba(255, 69, 58, 0.1);
        color: var(--err-color);
        border-color: transparent;
    }
}

/* ── Botón de texto (ac-btn) — único componente de texto+fondo del sistema.
   Eje 1: color (--primary|--accent|--danger|--neutral|--plain|--frosted).
   Eje 2: tamaño (--xs|--s|--m|--l|--xl). Se especifican siempre los dos.
   Sustituye a los antiguos botones sólidos y tinte accent, además de las
   variantes de texto del extinto botón fantasma y ac-btn-text — ver
   docs/superpowers/specs/2026-07-15-design-system-consolidation-design.md */
.ac-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: none;
    border-radius: 8px;
    font-family: inherit;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition:
        background 0.13s var(--ease-out),
        color 0.13s var(--ease-out),
        opacity 0.13s var(--ease-out);
}
.ac-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.ac-btn svg {
    width: var(--ac-icon-xs);
    height: var(--ac-icon-xs);
    flex-shrink: 0;
}

/* Tamaños */
.ac-btn--xs { min-height: 22px; padding: 4px 9px; font-size: 0.68rem; letter-spacing: 0.02em; }
.ac-btn--s  { min-height: 32px; padding: 6px 12px; font-size: 0.75rem; }
.ac-btn--m  { min-height: 44px; padding: 8px 18px; font-size: 0.8rem; }
.ac-btn--l  { min-height: 52px; padding: 10px 24px; font-size: 0.9rem; }
.ac-btn--xl { min-height: 60px; padding: 12px 30px; font-size: 1rem; }

/* Colores */
.ac-btn--primary {
    background: var(--accent-fill, var(--accent));
    color: var(--on-accent, #fff);
    font-weight: 700;
}
@media (hover: hover) {
    .ac-btn--primary:hover:not(:disabled) { opacity: 0.88; }
}
.ac-btn--primary:disabled { opacity: 0.45; cursor: not-allowed; }

.ac-btn--accent {
    background: var(--accent-dim);
    color: var(--accent);
}
@media (hover: hover) {
    .ac-btn--accent:hover { background: rgba(var(--accent-rgb), 0.22); }
}

.ac-btn--danger {
    background: rgba(var(--err-rgb), 0.10);
    color: rgba(var(--err-rgb), 0.65);
}
@media (hover: hover) {
    .ac-btn--danger:hover { background: rgba(var(--err-rgb), 0.18); color: var(--err-tx); }
}

.ac-btn--neutral {
    background: rgba(var(--ac-overlay-white), 0.07);
    color: var(--text-muted);
}
@media (hover: hover) {
    .ac-btn--neutral:hover { background: rgba(var(--ac-overlay-white), 0.13); color: var(--text-main); }
}

/* --plain: sin fondo nunca, solo texto de color. Se combina con --accent o --neutral
   para fijar el color de texto (mismos nombres que el resto, sin inventar tonos nuevos). */
.ac-btn--plain {
    background: none !important;
    padding-left: 4px;
    padding-right: 4px;
}
.ac-btn--plain.ac-btn--accent { color: var(--accent); }
.ac-btn--plain.ac-btn--neutral { color: var(--text-faint); }
@media (hover: hover) {
    .ac-btn--plain.ac-btn--accent:hover { opacity: 0.8; }
    .ac-btn--plain.ac-btn--neutral:hover { color: var(--text-muted); }
}

.ac-btn--frosted {
    background: rgba(var(--ac-overlay-surface-1), 0.72);
    color: rgba(var(--ac-overlay-white), 0.65);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
@media (hover: hover) {
    .ac-btn--frosted:hover { background: rgba(var(--ac-overlay-surface-2), 0.85); color: #fff; }
}
.ac-btn--frosted.active {
    background: var(--accent-fill, var(--accent));
    color: var(--on-accent, #fff);
}

/* ── Texto plano (utilidad de layout que sobrevive) ──────────────────────
   La familia de botones de texto plano (colores muted/accent) migró a
   .ac-btn --plain --accent|--neutral. La variante de toast se mantiene: no es
   un color, es la forma/relleno del botón dentro del toast. */
.ac-btn-text--toast {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 10px;
    border-radius: var(--radius-pill);
    background: rgba(var(--ac-overlay-white), 0.16);
    color: inherit;
    font-size: 0.8rem;
    font-weight: 600;
}
@media (hover: hover) {
    .ac-btn-text--toast:hover {
        background: rgba(var(--ac-overlay-white), 0.22);
    }
}

/* ── Acción en texto, sin caja ────────────────────────────────────────────
   Para la acción de una cabecera de sección, junto a su rótulo: dentro de un
   bloque que ya tiene su botón principal, un segundo botón relleno competía
   con él. Mismo peso visual que un enlace, con área de pulsación de sobra
   (el margen negativo compensa el padding, así que no descuadra la fila).
   La usan la ficha (Carretes) y el panel de edición (Foto). */
.ac-btn-inline {
    background: none;
    border: 0;
    padding: 4px 2px;
    margin: -4px 0;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--accent);
    cursor: pointer;
    border-radius: var(--radius-sm);
}
/* Destructiva (quitar la foto): mismo peso, y el MISMO rojo que `.btn-danger`
   —el «Borrar» de los diálogos de confirmación—, porque es el mismo papel
   (acción destructiva en texto plano) y encima se ven seguidos: pulsar
   «Quitar» abre justo ese diálogo. Los otros dos rojos del sistema se
   probaron aquí y no valen: `--err-tx` (#ff8579) es el rojo de texto sobre
   fondo TEÑIDO (`.ac-pill--err`, mensajes de error), y de pastel al lado del
   azul saturado de «Cambiar» se lee apagado; ese mismo al 70%, que es como
   estuvo primero, se veía descolorido del todo.
   Contraste de #ff453a sobre el fondo del panel (#1d1d1f): 4,9:1. */
.ac-btn-inline--danger {
    color: var(--err-color);
}
@media (hover: hover) {
    .ac-btn-inline:hover {
        color: var(--text-main);
    }
    /* Al pasar por encima se ACLARA: sobre fondo oscuro, subir de
       luminosidad es lo que se lee como «encendido». */
    .ac-btn-inline--danger:hover {
        color: var(--err-tx);
    }
}
.ac-btn-inline:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
/* Con el dedo, 44px de alto de zona pulsable — el mismo mínimo que la X del
   panel, la papelera y los botones de los diálogos. El texto mide 17px, así
   que el resto lo pone el padding, y el margen negativo lo devuelve: la zona
   crece hacia fuera y la fila no se mueve ni un píxel. Medido en un Pixel 7:
   17px de caja de margen (igual que antes), 45px de zona pulsable. */
@media (pointer: coarse) {
    .ac-btn-inline {
        /* Solo crece a lo alto: ensanchar también (padding/margen negativo
           horizontal) sacaba el último botón de la fila 8px por la derecha y
           el contenedor pasaba a desbordar. */
        padding: 14px 4px;
        margin: -14px 0;
    }
}

/* ── Menú desplegable (⋮) — disparador: ver .ac-icon-btn--s arriba ──────── */
.ac-btn-menu-item {
    display: block;
    width: 100%;
    padding: 9px 14px;
    border: none;
    background: none;
    color: rgba(var(--ac-overlay-white), 0.88);
    font: inherit;
    font-size: 0.72rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
@media (hover: hover) {
    .ac-btn-menu-item:hover {
        background: rgba(var(--ac-overlay-white), 0.08);
        color: #fff;
    }
}
.ac-btn-menu-item--danger {
    color: rgba(var(--err-tx-rgb), 0.70);
}
@media (hover: hover) {
    .ac-btn-menu-item--danger:hover {
        background: rgba(var(--err-rgb), 0.10);
        color: var(--err-tx);
    }
}

/* ── Menú contextual ⋮ (lightbox + styleguide) ─────────────────────────── */
.lb-detail-actions-wrap {
    position: relative;
    display: block;
    flex-shrink: 0;
}
.lb-detail-actions-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 5px);
    right: 0;
    flex-direction: column;
    background: rgba(var(--ac-overlay-surface-1), 0.97);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border: 1px solid rgba(var(--ac-overlay-white), 0.12);
    border-radius: 10px;
    overflow: hidden;
    min-width: 168px;
    z-index: 30;
    box-shadow: 0 8px 28px rgba(var(--ac-overlay-black), 0.65),
                0 2px 6px rgba(var(--ac-overlay-black), 0.35);
}
.lb-detail-actions-dropdown.open {
    display: flex;
}
.lb-detail-actions-item {
    display: flex;
    align-items: center;
    font-size: 0.70rem;
    letter-spacing: 0.01em;
}
.lb-detail-actions-item + .lb-detail-actions-item {
    border-top: 1px solid rgba(var(--ac-overlay-white), 0.06);
}

/* Papelera destructiva — ver .ac-icon-btn--danger al final del archivo. */

/* ── Control segmentado ────────────────────────────────────────────────── */
.ac-segment {
    display: flex;
    gap: 2px;
    background: rgba(var(--ac-overlay-white), 0.04);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 3px;
    flex-shrink: 0;
}
.ac-segment-btn {
    padding: 5px 11px;
    border-radius: 8px;
    background: none;
    border: none;
    box-shadow: none;
    color: var(--text-muted);
    font-size: 0.73rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
    white-space: nowrap;
    letter-spacing: 0.01em;
}
.ac-segment-btn.active {
    background: var(--accent-dim);
    color: var(--accent);
}
@media (hover: hover) {
    .ac-segment-btn:hover:not(.active) {
        color: var(--text-main);
    }
}
/* .btn aporta borde/fondo genérico — anular en segmentos */
.btn.ac-segment-btn {
    border: none;
    background: none;
    box-shadow: none;
    padding: 5px 11px;
}

/* ── Variante pill: cada opción es un chip ─────────────────────────────────
 *
 * La otra cara del mismo control. El segmentado base (caja con borde y texto
 * plano dentro) se lee bien con DOS opciones y etiquetas cortas; en cuanto hay
 * cuatro o cinco, los separadores desaparecen y parece una fila de texto. La
 * variante pill le da fondo propio a cada opción y quita la caja de fuera.
 *
 * Vivía suelta en `recipes.css` como override de `.recipe-config-tabs`, así
 * que el mismo control se veía de dos maneras según la pestaña — el usuario lo
 * señaló el 2026-07-31 comparando «Por marca / En el tiempo» con las pestañas
 * de cámara de una receta. Sube aquí como modificador con nombre para que
 * elegirla sea una decisión y no un copiar-pegar, y para que exista en el
 * styleguide, que es donde se mira antes de inventar nada.
 *
 * Lo que NO sube: el `border-bottom` y los márgenes de `.recipe-config-tabs`
 * (colocación dentro de la tarjeta, no aspecto del control) ni el
 * `.lb-config-picker` del lightbox, que va sobre foto y se pinta en la escala
 * de blancos del overlay a propósito.
 */
.ac-segment--pill {
    background: none;
    border: none;
    border-radius: 0;
    padding: 0;
    gap: 5px;
}
.ac-segment--pill .ac-segment-btn,
.ac-segment--pill .btn.ac-segment-btn {
    padding: 3px 11px;
    border-radius: var(--radius-pill);
    font-size: 0.68rem;
    background: rgba(var(--ac-overlay-white), 0.07);
    color: var(--text-muted);
}
.ac-segment--pill .ac-segment-btn.active,
.ac-segment--pill .btn.ac-segment-btn.active {
    background: var(--accent-dim);
    color: var(--accent);
}
@media (hover: hover) {
    .ac-segment--pill .ac-segment-btn:hover:not(.active) {
        background: rgba(var(--ac-overlay-white), 0.13);
        color: var(--text-main);
    }
}
/* En táctil cada opción es un objetivo de pulsación: 44px sin engordar el
   control en escritorio (mismo criterio que los chips de la franja de
   resumen). */
@media (pointer: coarse) {
    .ac-segment--pill .ac-segment-btn {
        min-height: 44px;
        padding-inline: 14px;
    }
}

/* ── Confirmación ──────────────────────────────────────────────────────── */
.ac-confirm-dialog {
    animation: acConfirmIn 0.24s var(--ease-out);
}
@keyframes acConfirmIn {
    from {
        opacity: 0;
        transform: scale(0.96) translateY(6px);
    }
    to {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}
@media (prefers-reduced-motion: reduce) {
    .ac-confirm-dialog {
        animation: none;
    }
}

/* ── Controles de filtro (chips + selects, altura unificada tipo Noticias) ─ */
:root {
    --ac-filter-h: 36px;
    --ac-filter-py: 7px;
    --ac-filter-px: 14px;
    --ac-filter-fs: 0.72rem;
    --ac-filter-select-pr: 28px;
    /* SVG inline (viewBox 24 salvo menú ⋮) */
    --ac-icon-xs: 12px;
    --ac-icon-sm: 14px;
    --ac-icon-md: 16px;
    --ac-icon-lg: 18px;
    --ac-icon-xl: 19px;
    --ac-icon-ellipsis-h: 3px;
}
/* Los 44px se disparaban SOLO por ancho, y eso dejaba un hueco: lo que hace
   falta un objetivo grande no es la pantalla estrecha, es el dedo. En una
   tablet táctil de 1366px el puntero es grueso pero el ancho supera 1080, así
   que los chips se quedaban en 36px — y el caso peor es Recetas, que solo
   EXISTE por encima de 1080px: las dos condiciones eran complementarias, así
   que en cualquier táctil donde se puede abrir Recetas sus filtros estaban por
   debajo del mínimo. Se añade `pointer: coarse` como segunda condición (coma
   = O), que no toca el escritorio con ratón. Encontrado el 2026-08-18
   auditando Recetas en un iPad Pro horizontal emulado. */
@media (max-width: 1080px), (pointer: coarse) {
    :root {
        --ac-filter-h: 44px;
        --ac-filter-py: 10px;
        --ac-filter-px: 16px;
        --ac-filter-fs: 0.75rem;
    }
}

.select-pill,
.news-brand-select {
    min-height: var(--ac-filter-h);
    padding: var(--ac-filter-py) var(--ac-filter-px);
    font-size: var(--ac-filter-fs);
    font-family: inherit;
    font-weight: 600;
    line-height: 1.2;
    box-sizing: border-box;
    border-radius: var(--radius-pill);
}

.select-pill,
.news-brand-select {
    padding-right: var(--ac-filter-select-pr);
    border: none;
    color: var(--text-main);
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--bg-surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2371717a' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}
.select-pill:focus,
.news-brand-select:focus {
    outline: none;
    box-shadow: 0 0 0 2px var(--accent-dim);
}

/* ── Buscador pill (Inventario, Recetas, Noticias) ─────────────────────── */
.ac-search-input {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    min-height: var(--ac-filter-h);
    padding: 8px 14px 8px 36px;
    border: none;
    border-radius: var(--radius-pill);
    background-color: var(--bg-surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 12px center;
    color: var(--text-main);
    font: inherit;
    font-size: 0.875rem;
    line-height: 1.2;
    outline: none;
    transition: box-shadow 0.15s var(--ease-out);
    -webkit-appearance: none;
    appearance: none;
}

.ac-search-input::placeholder {
    color: var(--text-faint);
}

.ac-search-input:focus {
    outline: none;
    box-shadow: 0 0 0 2px var(--accent-dim);
}

.ac-search-input::-webkit-search-cancel-button {
    cursor: pointer;
    opacity: 0.5;
}

/* Variante en formularios / panel (borde + esquinas suaves, no pill) */
.ac-search-input--flat {
    min-height: unset;
    padding: 7px 10px 7px 32px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background-color: var(--bg-body);
    font-size: 0.8rem;
    background-position: 10px center;
}

.ac-search-input--flat:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-dim);
}

/* ── Toast ─────────────────────────────────────────────────────────────── */
.ac-toast-container {
    position: fixed;
    bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}
@media (max-width: 1080px) {
    .ac-toast-container {
        bottom: calc(88px + env(safe-area-inset-bottom, 0px));
    }
}
.ac-toast {
    pointer-events: auto;
    padding: 12px 18px;
    border-radius: var(--radius-md);
    background: var(--bg-raised);
    border: 1px solid var(--border);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
    font-size: 0.88rem;
    color: var(--text-main);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.2s, transform 0.2s;
}
.ac-toast.visible {
    opacity: 1;
    transform: translateY(0);
}

/* Variante pill (recetas: mensaje + acción inline) */
.ac-toast--pill {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    background: rgba(var(--ac-overlay-surface-1), 0.96);
    border: 1px solid rgba(var(--ac-overlay-white), 0.12);
    border-radius: var(--radius-pill);
    box-shadow:
        0 4px 20px rgba(var(--ac-overlay-black), 0.55),
        0 1px 4px rgba(var(--ac-overlay-black), 0.35);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    max-width: 380px;
    white-space: nowrap;
    transform: translateY(6px) scale(0.97);
    transition: opacity 0.22s ease, transform 0.22s ease;
}
.ac-toast--pill.visible {
    transform: translateY(0) scale(1);
}
.ac-toast-msg {
    font-size: 0.75rem;
    font-weight: 600;
    color: rgba(var(--ac-overlay-white), 0.88);
    letter-spacing: 0.01em;
}
.ac-toast-sep {
    width: 1px;
    height: 14px;
    background: rgba(var(--ac-overlay-white), 0.18);
    flex-shrink: 0;
}

/* ── Contenedores de acciones (layout) ─────────────────────────────────── */
.state-msg-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin-top: 16px;
}
.state-msg-actions .btn {
    padding: 10px 18px;
}

/* ── Cabecera editor: acciones (papelera + cerrar) ─────────────────────── */
.ac-editor-header-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

/* ── Icono circular con tinte (papelera, confirmar, añadir) ────────────────
   Antes tres bloques casi idénticos (ac-icon-danger/success/accent-btn),
   copiados y pegados salvo tamaño y color. Ahora una base compartida
   (.ac-icon-btn) + tono (--danger|--success|--accent) + tamaño, solo
   --s|--m|--l (44×44 cabecera; 28×28 filas de formulario/etiquetas). */
.ac-icon-btn {
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: 0;
    margin: 0;
    border: none;
    border-radius: var(--radius-pill);
    cursor: pointer;
    font: inherit;
    line-height: 0;
    outline: none;
    box-shadow: none;
    -webkit-appearance: none;
    appearance: none;
    -webkit-tap-highlight-color: transparent;
    transition:
        background-color 0.15s var(--ease-out),
        transform 0.08s var(--ease-out);
}
.ac-icon-btn svg {
    width: var(--ac-icon-sm);
    height: var(--ac-icon-sm);
    pointer-events: none;
}
.ac-icon-btn:active {
    transform: scale(0.96);
}
.ac-icon-btn--s {
    width: 28px;
    height: 28px;
    min-width: 28px;
    min-height: 28px;
}
.ac-icon-btn--m {
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
}
.ac-icon-btn--l {
    width: 44px;
    height: 44px;
    min-width: 44px;
    min-height: 44px;
}
.ac-icon-btn--l svg { width: var(--ac-icon-md); height: var(--ac-icon-md); }

/* Papelera — círculo de tinte rojo siempre visible (pedido explícito del
   usuario: "la papelera también tiene que tener la sombrita roja
   siempre"), no solo al pasar el ratón — hover/active solo suben la
   intensidad. */
.ac-icon-btn--danger {
    background-color: rgba(var(--err-rgb), 0.12);
    color: var(--err-color);
}
@media (hover: hover) {
    .ac-icon-btn--danger:hover {
        background-color: rgba(var(--err-rgb), 0.18);
    }
}
.ac-icon-btn--danger:active {
    background-color: rgba(var(--err-rgb), 0.24);
}
/* Solo :focus-visible (no :focus): en Chromium un <button> ya distingue
   clic/toque (no marca :focus-visible) de navegación por teclado (sí la
   marca) — comprobado con Playwright. :focus sí se activa con cualquier
   método y fue la causa real de que el toque dejara el círculo rojo
   pintado tras cancelar la confirmación; con solo :focus-visible el
   teclado recupera un indicador visible sin reintroducir ese problema. */
.ac-icon-btn--danger:focus-visible {
    outline: 2px solid var(--err-color);
    outline-offset: 2px;
}

.ac-icon-btn--success {
    background-color: rgba(var(--ok-rgb), 0.12);
    color: var(--ok-color);
}
@media (hover: hover) {
    .ac-icon-btn--success:hover {
        background-color: rgba(var(--ok-rgb), 0.18);
    }
}
.ac-icon-btn--success:active {
    background-color: rgba(var(--ok-rgb), 0.24);
}
.ac-icon-btn--success:focus-visible {
    outline: 2px solid var(--ok-color);
    outline-offset: 2px;
}
.ac-icon-btn--success:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.ac-icon-btn--accent {
    background-color: rgba(var(--accent-rgb), 0.14);
    color: var(--accent);
}
@media (hover: hover) {
    .ac-icon-btn--accent:hover {
        background-color: rgba(var(--accent-rgb), 0.22);
    }
}
.ac-icon-btn--accent:active {
    background-color: rgba(var(--accent-rgb), 0.28);
}
.ac-icon-btn--accent:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.ac-icon-btn--primary {
    background-color: var(--accent-fill, var(--accent));
    color: var(--on-accent, #fff);
}
@media (hover: hover) {
    .ac-icon-btn--primary:hover { opacity: 0.88; }
}
.ac-icon-btn--primary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.ac-icon-btn--neutral {
    background-color: var(--bg-raised);
    color: var(--text-main);
}
@media (hover: hover) {
    .ac-icon-btn--neutral:hover { background-color: var(--bg-hover); }
}
.ac-icon-btn--neutral:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Transparente en reposo, se tiñe de rojo solo al interactuar — quitar/borrar etiqueta */
.ac-icon-btn--subtle {
    background: transparent;
    color: var(--text-faint);
}
@media (hover: hover) {
    .ac-icon-btn--subtle:hover {
        background: rgba(var(--err-rgb), 0.12);
        color: var(--err-color);
    }
}
.ac-icon-btn--subtle:active {
    background: rgba(var(--err-rgb), 0.18);
    color: var(--err-color);
}
.ac-icon-btn--subtle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.ac-icon-btn--subtle.ac-icon-btn--dim { opacity: 0.55; }
.ac-icon-btn--subtle.ac-icon-btn--dim:hover,
.ac-icon-btn--subtle.ac-icon-btn--dim:focus-visible { opacity: 1; }

.ac-icon-btn--frosted {
    background: rgba(var(--ac-overlay-surface-1), 0.72);
    color: rgba(var(--ac-overlay-white), 0.65);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
@media (hover: hover) {
    .ac-icon-btn--frosted:hover {
        background: rgba(var(--ac-overlay-surface-2), 0.85);
        color: #fff;
    }
}
/* Estado .active (toggle pressed/on) — pantalla completa, comparar, favorito,
   toolbar Lupa/Grid del styleguide. Antes vivía en el equivalente --frosted del
   extinto botón fantasma. */
.ac-icon-btn--frosted.active {
    background: var(--accent-fill, var(--accent));
    color: var(--on-accent, #fff);
}

/* ── Volver arriba ─────────────────────────────────────────────────────── */
/* Un solo botón en el DOM (index.html, fuera de las pestañas): el scroll es
   de `window` y no por panel (view-tabs.js guarda/restaura `window.scrollY`
   al cambiar de vista), así que sirve a las cinco pantallas sin lógica por
   pestaña — assets/js/scroll-top.js alterna `[inert]` según la posición.
   Bottom-LEFT a propósito: bottom-right lo ocupa `.editor-actions-bar` en
   modo edición, y los dos a la vez se solaparían en móvil.
   `inert` en vez de `hidden`: dos ventajas. Dejar el botón fuera del foco y
   del árbol de accesibilidad sin `display: none` es lo que permite el
   fundido — con `hidden` no hay nada que transicionar, salta en seco.
   Mismo patrón que el modal de login (NOTES.md, 2026-07-27).
   Va DESPUÉS de `.ac-icon-btn` en la cascada, no antes: `.ac-icon-btn` trae
   su propio `transition` (background-color + transform) y, a igual
   especificidad, gana quien se declara después — un `.ac-scroll-top-btn`
   más arriba en el archivo perdía su transición de opacity/transform
   entera, no solo la solapada, porque `transition` es un shorthand y no se
   mezcla entre reglas. */
.ac-scroll-top-btn {
    position: fixed;
    left: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-actions-bar);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.18s ease, transform 0.18s ease;
}
.ac-scroll-top-btn:not([inert]) {
    opacity: 1;
    transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
    .ac-scroll-top-btn {
        transition: none;
    }
}

/* Panel lateral: mismo reposo/hover/active que modal; anula CSS legacy de .icon-btn */
#editor-panel .ac-icon-btn--danger,
#editor-panel .ep-delete-btn {
    background-color: rgba(var(--err-rgb), 0.12) !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--err-color) !important;
}
#editor-panel .ac-icon-btn--danger:focus-visible,
#editor-panel .ep-delete-btn:focus-visible {
    outline: 2px solid var(--err-color) !important;
    outline-offset: 2px !important;
}
#editor-panel .ac-icon-btn--danger:active,
#editor-panel .ep-delete-btn:active {
    background-color: rgba(var(--err-rgb), 0.24) !important;
    box-shadow: none !important;
}
@media (hover: hover) {
    #editor-panel .ac-icon-btn--danger:hover,
    #editor-panel .ep-delete-btn:hover {
        background-color: rgba(var(--err-rgb), 0.18) !important;
        box-shadow: none !important;
    }
}

/* ── Tamaños SVG por contexto (sin width/height inline en JS/HTML) ─────── */
svg.ac-icon-svg-ellipsis {
    width: var(--ac-icon-xs);
    height: var(--ac-icon-ellipsis-h);
    flex-shrink: 0;
}
svg.ac-icon-svg-sm {
    width: var(--ac-icon-sm);
    height: var(--ac-icon-sm);
    flex-shrink: 0;
}
svg.ac-icon-svg-md {
    width: var(--ac-icon-md);
    height: var(--ac-icon-md);
    flex-shrink: 0;
}
svg.ac-icon-svg-lg {
    width: var(--ac-icon-lg);
    height: var(--ac-icon-lg);
    flex-shrink: 0;
}

/* ── Pastilla (ac-pill) — chip/etiqueta/indicador de estado. Sustituye a los
   antiguos chips de filtro y de etiqueta, más el indicador de estado de
   cámara (clases previas ya retiradas). Mantiene su propia paleta semántica
   (estado/filtro/marca), ya correcta — solo cambia el nombre del componente
   contenedor. ── */
.ac-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: none;
    border-radius: var(--radius-pill);
    font-family: inherit;
    font-weight: 600;
    white-space: nowrap;
    box-sizing: border-box;
}
.ac-pill::before {
    content: "";
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}
/* Los chips de filtro y etiqueta no llevan punto de estado */
.ac-pill--neutral::before,
.ac-pill--accent::before {
    display: none;
}
/* Pill con icono propio (p. ej. un check): el punto de estado sobraría al
   lado de un glifo que ya dice lo mismo. */
.ac-pill--icon::before {
    display: none;
}
.ac-pill svg {
    width: var(--ac-icon-xs);
    height: var(--ac-icon-xs);
    flex-shrink: 0;
}

/* Tamaños */
.ac-pill--xs { padding: 2px 8px 2px 6px; font-size: 0.62rem; }
.ac-pill--s  { padding: 4px 10px; font-size: 0.68rem; }
.ac-pill--m  { min-height: var(--ac-filter-h); padding: var(--ac-filter-py) var(--ac-filter-px); font-size: var(--ac-filter-fs); }
.ac-pill--l  { padding: 8px 16px; font-size: 0.85rem; }
.ac-pill--xl { padding: 10px 20px; font-size: 0.95rem; }

/* Colores de estado (cámara) */
.ac-pill--ok     { background: var(--ok-bg);     color: var(--ok-tx); }
.ac-pill--warn   { background: var(--warn-bg);   color: var(--warn-tx); }
.ac-pill--err    { background: var(--err-bg);    color: var(--err-tx); }
.ac-pill--pend   { background: var(--pend-bg);   color: var(--pend-tx); }
.ac-pill--repair { background: var(--repair-bg); color: var(--repair-tx); }
/* «Carrete: Sí» y el carrete «En la cámara». No es un estado, es un eje
   aparte — ver `--loaded-color` en tokens.css para por qué dejó de ser el
   amarillo de `warn`. */
.ac-pill--loaded { background: var(--loaded-bg); color: var(--loaded-tx); }
/* «Novedad» del catálogo de Cámaras: anunciada hace poco. No es un estado de
   tu colección —por eso no reutiliza `--ok`— ni un aviso —por eso no
   `--warn`—, es una fecha que se apaga sola pasados unos meses. */
.ac-pill--new    { background: var(--new-bg);    color: var(--new-tx); }
/* Chip «Foto / Vídeo / Foto y vídeo» del catálogo de Cámaras (2026-08-16,
   dos vueltas): tres colores, uno por lectura, en la misma intensidad tenue
   que el resto de estos chips de estado —no el relleno sólido de
   `.ac-pill--accent`, pensado para un chip de filtro ACTIVO y no para una
   descripción pasiva repetida en decenas de tarjetas—. `--ambas` reutiliza
   `--info` (=`--accent`, ya definida en tokens.css, sin usar hasta la
   primera vuelta de este chip). Además de color, las tres llevan icono
   propio (`pildoraFotoVideo()` en cameras-view.js, `.ac-pill--icon`): el
   usuario pidió, en la segunda vuelta, mejorar el aspecto entero y no solo
   sumarle un color a «Foto». */
.ac-pill--video  { background: var(--video-bg);  color: var(--video-tx); }
.ac-pill--foto   { background: var(--foto-bg);   color: var(--foto-tx); }
.ac-pill--ambas  { background: var(--info-bg);   color: var(--info-tx); }
/* «A la venta» del catálogo de Cámaras (2026-08-16): se compra nueva hoy,
   digital o analógica. Antes de esto el resto de chips informativos de esta
   familia (tipo, formato, precio, disponibilidad de segunda mano...) no lo
   diferenciaban de un vistazo — el usuario dijo que no le convencía «Se
   sigue fabricando» y pidió algo más evidente para todas las cámaras que se
   pueden comprar como nuevas, no solo para las analógicas que aún se
   fabrican. Ver `--buy-color` en tokens.css para el porqué del verde lima
   en vez del verde de `.ac-pill--ok` («Ya la tienes»). */
.ac-pill--buy    { background: var(--buy-bg);    color: var(--buy-tx); }

/* Colores de filtro y etiqueta */
.ac-pill--neutral {
    background: rgba(var(--ac-overlay-white), 0.07);
    color: var(--text-muted);
}
.ac-pill--accent {
    background: var(--accent-fill, var(--accent));
    color: #fff;
}
/* El recuento que llevan dentro los chips de filtro de Recetas, Cámaras y
   Películas («Réflex 55»). Estuvo en recipes.css hasta el 2026-08-22, de
   cuando solo lo usaba Recetas; es parte de `.ac-pill` y su sitio es este.
   Con el chip activo sube de opacidad: sobre el relleno de acento, un 0.55
   se lee mucho peor que sobre el gris. */
.ac-pill-count {
    margin-left: 3px;
    font-size: 0.70em;
    font-weight: 500;
    opacity: 0.55;
    letter-spacing: 0;
}
.ac-pill--accent .ac-pill-count {
    opacity: 0.80;
}

/* Chip de filtro que ahora mismo no puede dar nada (2026-08-22). Desde que
   los recuentos se calculan sobre lo YA filtrado y no sobre el catálogo
   entero, en Cámaras y en Películas aparecen chips a cero al cruzar filtros
   («Vídeo» con «Analógica» puesta). Se apagan en su sitio en vez de
   esconderse —una fila de filtros que cambia de forma mientras la usas es
   peor que un chip apagado— y llevan `disabled` en el JS. El selector repite
   `button` para ganarle en especificidad al `cursor: pointer` de la regla de
   abajo, que es `button.ac-pill--neutral`; el `:hover` se apaga allí mismo,
   porque un `disabled` no dispara eventos de ratón pero sí casa con `:hover`
   y se encendería igual. */
.ac-pill--empty {
    opacity: 0.4;
}
button.ac-pill--empty {
    cursor: default;
}

/* El cursor de mano y el brillo al pasar el ratón son solo para las pills
   que de verdad se pueden pulsar —filtros, etiquetas activables, pestañas
   de la comparativa—, que son siempre <button> o <a>. Las informativas
   (tipo, formato, precio... en una tarjeta; una etiqueta ya fijada en el
   cajón lateral) son <span>, y hasta el 2026-08-16 heredaban el mismo
   aspecto interactivo sin que pulsarlas hiciera nada — el usuario lo
   reportó en Cámaras («Compacta», «Sin espejo») pero el mismo `.ac-pill`
   se comparte en toda la app, así que el arreglo también. */
button.ac-pill--neutral,
a.ac-pill--neutral,
button.ac-pill--accent,
a.ac-pill--accent {
    cursor: pointer;
    touch-action: manipulation;
}
@media (hover: hover) {
    button.ac-pill--neutral:not(:disabled):hover,
    a.ac-pill--neutral:hover { background: rgba(var(--ac-overlay-white), 0.13); color: var(--text-main); }
}
button.ac-pill--neutral:focus-visible,
a.ac-pill--neutral:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Misma regla, otro color: «Ya la tienes» del catálogo de Cámaras pasó a ser
   un <button> el 2026-08-18 (lleva a TU ficha del inventario) y sin esto
   habría caído en el defecto contrario al de arriba — un control que sí hace
   algo pero se ve inerte, sin cursor ni respuesta al pasar por encima. El
   `.ac-pill--ok` informativo (el estado «Funcional» de Inventario, o esta
   misma pill cuando la cámara es una digital sin ficha que abrir) sigue
   siendo <span> y sigue sin heredar nada de esto. */
button.ac-pill--ok {
    cursor: pointer;
    touch-action: manipulation;
}
@media (hover: hover) {
    button.ac-pill--ok:hover { background: rgba(var(--ok-rgb), 0.24); }
}
button.ac-pill--ok:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
