/* Marketplace nypau — "aviso mural": el anuncio pegado en el poste/almacén.
   Blanco y negro puros como base, con el color reservado para los acentos
   (cintas, tags, precio). Precio a mano, categoría como tag colgando,
   tarjetas con leve inclinación que se enderezan al pasar el mouse.

   Modo día/noche: por defecto sigue al sistema del visitante
   (prefers-color-scheme); el botón de la barra lo fuerza poniendo
   data-theme="light|dark" en <html> (static/tema.js, persistido en
   localStorage). El data-theme explícito siempre gana sobre el sistema. */
/* Tipografía elegible por cuenta (/mi-perfil/apariencia, tema.js pone
   data-fuente en <html>): clásica (default, la de siempre) o elegante
   (Playfair Display + Caveat, cargadas de Google Fonts en base.html). */
/* Cada juego define TRES roles: titulares (--f-display), precio a mano
   (--f-mano, distinto por juego) y cuerpo (--f-cuerpo: TODA la letra del
   sitio — barra, títulos de aviso, comuna, admin — cambia con el juego). */
:root {
    --f-display: Georgia, 'Times New Roman', serif;
    --f-mano: 'Comic Sans MS', 'Marker Felt', cursive;
    --f-cuerpo: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}
html[data-fuente="elegante"] {
    --f-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
    --f-mano: 'Caveat', 'Comic Sans MS', cursive;
    --f-cuerpo: Georgia, 'Times New Roman', serif;
}
html[data-fuente="maquina"] {
    --f-display: 'Special Elite', 'Courier New', monospace;
    --f-mano: 'Special Elite', 'Courier New', monospace;
    --f-cuerpo: 'Special Elite', 'Courier New', monospace;
}
html[data-fuente="redondeada"] {
    --f-display: 'Baloo 2', 'Trebuchet MS', sans-serif;
    --f-mano: 'Baloo 2', 'Trebuchet MS', sans-serif;
    --f-cuerpo: 'Baloo 2', 'Trebuchet MS', sans-serif;
}
/* Caveat tiene x-height menor que Comic Sans: los precios suben de tamaño
   cuando está activa. */
html[data-fuente="elegante"] .tarjeta .precio { font-size: 1.7rem; line-height: 1; }
html[data-fuente="elegante"] .pub-modal .precio-modal,
html[data-fuente="maquina"] .pub-modal .precio-modal,
html[data-fuente="redondeada"] .pub-modal .precio-modal { font-size: clamp(1.6rem, 5vw, 2rem); }
html[data-fuente="elegante"] .info-pub .precio-grande,
html[data-fuente="maquina"] .info-pub .precio-grande,
html[data-fuente="redondeada"] .info-pub .precio-grande { font-size: 2.7rem; line-height: 1; }
/* Ajustes por juego (ronda 13, feedback usuario):
   - redondeada: Baloo 2 trae caja de línea muy alta ("todo se sube" y queda
     aireado) — se compacta line-height y baja un pelo el tamaño base.
   - maquina: Special Elite aprieta los dígitos del precio — letter-spacing.
   - clasica (sin data-fuente): nombre de tienda, antigüedad y ubicación de
     la tarjeta un poco más grandes.
   - elegante: Georgia rinde chico y apretado — sube el tamaño raíz. */
/* SIN tocar el font-size raíz: escalar todo el sitio por tipografía se
   sintió como "se agranda/achica todo" (feedback ronda 14). Solo ajustes
   puntuales de line-height, espaciado y jerarquía. */
html[data-fuente="redondeada"] body { line-height: 1.3; }
html[data-fuente="redondeada"] .tarjeta .titulo,
html[data-fuente="redondeada"] .tarjeta .precio,
html[data-fuente="redondeada"] .tarjeta .meta,
html[data-fuente="redondeada"] .tarjeta .seller { line-height: 1.2; }
html[data-fuente="maquina"] .tarjeta .precio,
html[data-fuente="maquina"] .info-pub .precio-grande,
html[data-fuente="maquina"] .pub-modal .precio-modal { letter-spacing: 0.07em; }
.tarjeta .meta { font-size: 0.84rem; }
.tarjeta .seller { font-size: 0.82rem; }
/* Elegante se veía igual a clásica (misma letra de cuerpo en las tarjetas):
   los títulos de aviso pasan a la serif de titulares, en itálica. */
html[data-fuente="elegante"] .tarjeta .titulo {
    font-family: var(--f-display); font-style: italic; font-size: 1rem;
}
html[data-fuente="elegante"] .pub-modal h2,
html[data-fuente="elegante"] .info-pub h1 { letter-spacing: 0.01em; }
/* Special Elite y Baloo no tienen itálica real: mejor derechas. */
html[data-fuente="maquina"] .logo, html[data-fuente="maquina"] .hero-mural,
html[data-fuente="maquina"] h1.titulo-seccion, html[data-fuente="maquina"] .info-pub h1,
html[data-fuente="redondeada"] .logo, html[data-fuente="redondeada"] .hero-mural,
html[data-fuente="redondeada"] h1.titulo-seccion, html[data-fuente="redondeada"] .info-pub h1 { font-style: normal; }

:root, :root[data-theme="light"] {
    --bg: var(--dia-bg, #ffffff);
    --superficie: var(--dia-superficie, #fafafa);
    /* Tonos "de color" v3: bordes sólidos del color (--dia-borde), barra y
       pie teñidos (--dia-barra), y fondo pastel muy leve (--dia-bg) DETRÁS
       de las publicaciones — las superficies (tarjetas, paneles) quedan
       blancas/negras base. Los tonos neutros solo pintan el fondo. */
    --borde: var(--dia-borde, rgba(10,10,10,0.16));
    --barra: var(--dia-barra, var(--bg));
    /* Copias "-sitio" resueltas en el html: la zona de tienda remapea --bg y
       compañía, y usar var(--bg) dentro de esa zona (fondo default) crearía
       un ciclo (declaración inválida = botones sin texto). */
    --bg-sitio: var(--bg);
    --superficie-sitio: var(--superficie);
    --borde-sitio: var(--borde);
    --borde-hover: rgba(10,10,10,0.4);
    --texto: #0a0a0a;
    --texto-2: #444444;
    --rojo: #a8332b;
    --verde: #3c7a6e;
    /* El acento sigue al tono de color elegido (--dia-accent lo definen los
       tonos v3); sin tono de color queda el terracota clásico. */
    --accent: var(--dia-accent, #8a4a30);
    /* Pulgar de la barra de scroll: color sólido del tono; gris neutro si
       el tono no define color. */
    --scroll-thumb: var(--dia-borde, #c2c2c2);
    --tape1: #e8b400;
    --tape2: #c24b3c;
    --tape3: #3c7a6e;
    --sombra: rgba(0,0,0,0.14);
    /* Dorado de los separadores (bordes de la tienda del vendedor). */
    --dorado: #d4af37;
}
/* Mismo juego de variables oscuras dos veces: no hay forma en CSS puro de
   compartir el bloque entre la media query y el data-theme forzado. Si se
   toca un valor acá, tocarlo en los DOS bloques. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg: var(--noche-bg, #161616);
        --superficie: var(--noche-superficie, #222222);
        --borde: var(--noche-borde, rgba(250,250,250,0.16));
        --barra: var(--noche-barra, var(--bg));
        --borde-hover: rgba(250,250,250,0.4);
        --texto: #fafafa;
        --texto-2: #b5b5b5;
        --rojo: #e2685a;
        --verde: #5fb3a3;
        --accent: var(--noche-accent, #c9ab8f);
        --scroll-thumb: var(--noche-borde, #4a4a4a);
        --tape1: #f2c94c;
        --tape2: #e2685a;
        --tape3: #5fb3a3;
        --sombra: rgba(0,0,0,0.5);
        --dorado: #f0c437;
    }
}
:root[data-theme="dark"] {
    --bg: var(--noche-bg, #161616);
    --superficie: var(--noche-superficie, #222222);
    --borde: var(--noche-borde, rgba(250,250,250,0.16));
    --barra: var(--noche-barra, var(--bg));
    --borde-hover: rgba(250,250,250,0.4);
    --texto: #fafafa;
    --texto-2: #b5b5b5;
    --rojo: #e2685a;
    --verde: #5fb3a3;
    --accent: var(--noche-accent, #c9ab8f);
    --scroll-thumb: var(--noche-borde, #4a4a4a);
    --tape1: #f2c94c;
    --tape2: #e2685a;
    --tape3: #5fb3a3;
    --sombra: rgba(0,0,0,0.5);
    --dorado: #f0c437;
}
/* Tono del negro nocturno, elegible por el visitante (swatches en la barra,
   static/tema.js, localStorage). Solo redefine los tokens que consumen los
   bloques oscuros de arriba: en modo día no tiene efecto, y las tiendas con
   tema propio tampoco lo ven (pisan --bg/--superficie en perfil.html). */
:root[data-noche="puro"]  { --noche-bg: #000000; --noche-superficie: #0d0d0d; }
:root[data-noche="medio"] { --noche-bg: #0f0f0f; --noche-superficie: #1a1a1a; }
:root[data-noche="suave"] { --noche-bg: #161616; --noche-superficie: #222222; }
/* Tonos nocturnos DE COLOR (v3): bordes sólidos del matiz (--noche-borde),
   barra/pie teñidos (--noche-barra), fondo apenas matizado (--noche-bg).
   Las superficies (tarjetas/paneles) quedan en el negro base #222. */
:root[data-noche="azulado"] { --noche-borde: #5b82b8; --noche-barra: #16202e; --noche-bg: #10151c; --noche-accent: #7ea3d6; }
:root[data-noche="calido"]  { --noche-borde: #c99a55; --noche-barra: #221c12; --noche-bg: #171310; --noche-accent: #dcb679; }
:root[data-noche="morado"]  { --noche-borde: #9a76d0; --noche-barra: #201730; --noche-bg: #16101f; --noche-accent: #b596e2; }
:root[data-noche="vino"]    { --noche-borde: #c05a6e; --noche-barra: #2a151b; --noche-bg: #1c0f13; --noche-accent: #d67e8f; }
:root[data-noche="bosque"]  { --noche-borde: #4faa78; --noche-barra: #14231a; --noche-bg: #0f1a14; --noche-accent: #6fc496; }
:root[data-noche="oceano"]    { --noche-borde: #3f9bbf; --noche-barra: #12222b; --noche-bg: #0e181e; --noche-accent: #66b6d6; }
:root[data-noche="ambar"]     { --noche-borde: #d9a233; --noche-barra: #241d10; --noche-bg: #18130a; --noche-accent: #e8b955; }
:root[data-noche="esmeralda"] { --noche-borde: #2fae9b; --noche-barra: #10241f; --noche-bg: #0d1815; --noche-accent: #52c5b3; }
:root[data-noche="rosa"]      { --noche-borde: #d073a8; --noche-barra: #261523; --noche-bg: #180f16; --noche-accent: #de92bd; }
/* "Negro y dorado": el tono de lujo pedido — bordes, barra y acento en oro
   sobre negro cálido profundo. */
:root[data-noche="dorado"]    { --noche-borde: #d4af37; --noche-barra: #221c0a; --noche-bg: #141107; --noche-accent: #e6c14d; }
/* Segunda tanda nocturna (ronda 18): el panel ya tiene scroll, hay espacio. */
:root[data-noche="petroleo"] { --noche-borde: #3e8e9e; --noche-barra: #0f2226; --noche-bg: #0b171a; --noche-accent: #5fb3c4; }
:root[data-noche="indigo"]   { --noche-borde: #6272d9; --noche-barra: #171a33; --noche-bg: #101222; --noche-accent: #8a97e8; }
:root[data-noche="lima"]     { --noche-borde: #9ab53e; --noche-barra: #1e2410; --noche-bg: #14180a; --noche-accent: #b5cf62; }
:root[data-noche="cobre"]    { --noche-borde: #c47a4a; --noche-barra: #251811; --noche-bg: #180f0a; --noche-accent: #d69a6e; }
:root[data-noche="plata"]    { --noche-borde: #9aa3ad; --noche-barra: #1d2023; --noche-bg: #131517; --noche-accent: #c0c8d0; }
:root[data-noche="magenta"]  { --noche-borde: #c94fb8; --noche-barra: #261024; --noche-bg: #180a17; --noche-accent: #dc78ce; }
/* Tono del fondo de día (mismo mecanismo que el nocturno: tokens que solo
   consume el bloque claro; el modo noche y las tiendas con tema no los ven). */
:root[data-dia="blanco"] { --dia-bg: #ffffff; --dia-superficie: #fafafa; }
:root[data-dia="crema"]  { --dia-bg: #f7f2e7; --dia-superficie: #fdfaf3; }
:root[data-dia="gris"]   { --dia-bg: #ececec; --dia-superficie: #f6f6f6; }
:root[data-dia="sepia"]  { --dia-bg: #f3ead8; --dia-superficie: #f9f4e8; }
/* Tonos de día DE COLOR (v3): bordes sólidos del matiz (--dia-borde),
   barra/pie teñidos pastel (--dia-barra) y fondo pastel muy leve (--dia-bg).
   Las superficies (tarjetas/paneles) quedan blancas (#fafafa base). */
:root[data-dia="celeste"]  { --dia-borde: #5b8fc7; --dia-barra: #d8e6f4; --dia-bg: #f3f8fc; --dia-accent: #33628f; }
:root[data-dia="mango"]    { --dia-borde: #e8a33d; --dia-barra: #f9e3c0; --dia-bg: #fdf6ec; --dia-accent: #a3661a; }
:root[data-dia="amarillo"] { --dia-borde: #d9b616; --dia-barra: #f5ecba; --dia-bg: #fdf9e8; --dia-accent: #8a7410; }
:root[data-dia="lila"]     { --dia-borde: #8f6fc7; --dia-barra: #e6ddf4; --dia-bg: #f8f5fc; --dia-accent: #64489c; }
:root[data-dia="rosado"]   { --dia-borde: #d46d8c; --dia-barra: #f6dbe4; --dia-bg: #fdf3f6; --dia-accent: #a83e60; }
:root[data-dia="menta"]    { --dia-borde: #4aa87a; --dia-barra: #d7ecdf; --dia-bg: #f2faf5; --dia-accent: #2c7a54; }
:root[data-dia="cielo"]    { --dia-borde: #3d7ec9; --dia-barra: #d3e3f5; --dia-bg: #f1f7fd; --dia-accent: #2a5c99; }
:root[data-dia="coral"]    { --dia-borde: #e07856; --dia-barra: #f8ddd3; --dia-bg: #fdf4f0; --dia-accent: #ad4a2e; }
:root[data-dia="turquesa"] { --dia-borde: #2fa3a0; --dia-barra: #d2ebea; --dia-bg: #f0f9f9; --dia-accent: #1d7573; }
:root[data-dia="oliva"]    { --dia-borde: #8a9a3d; --dia-barra: #e5e9cd; --dia-bg: #f7f9ec; --dia-accent: #5f6b28; }
/* "Blanco y dorado": versión diurna del tono de lujo. */
:root[data-dia="dorado"]   { --dia-borde: #c9a227; --dia-barra: #f3e7bd; --dia-bg: #fcf8e9; --dia-accent: #8a6d1a; }
/* Segunda tanda diurna (ronda 18). */
:root[data-dia="lavanda"]   { --dia-borde: #7a6ecb; --dia-barra: #e2ddf6; --dia-bg: #f7f5fd; --dia-accent: #55489e; }
:root[data-dia="durazno"]   { --dia-borde: #e89a6b; --dia-barra: #f9e2d2; --dia-bg: #fdf5ef; --dia-accent: #a35c2f; }
:root[data-dia="arena"]     { --dia-borde: #c2a878; --dia-barra: #eee3cd; --dia-bg: #faf6ec; --dia-accent: #7d6437; }
:root[data-dia="salvia"]    { --dia-borde: #7d9c7f; --dia-barra: #dce8dd; --dia-bg: #f3f8f4; --dia-accent: #4a6b4c; }
:root[data-dia="hielo"]     { --dia-borde: #6fa7b8; --dia-barra: #dcebef; --dia-bg: #f2f9fb; --dia-accent: #3d6b7a; }
:root[data-dia="frambuesa"] { --dia-borde: #c74e79; --dia-barra: #f4d8e3; --dia-bg: #fcf1f5; --dia-accent: #96305a; }
* { margin: 0; padding: 0; box-sizing: border-box; }
/* ===== Barra de scroll a juego con el tema: riel del color del fondo y
   pulgar redondeado del color sólido del tono elegido (gris neutro en los
   temas blanco/negro base). Firefox usa la forma corta. ===== */
* { scrollbar-color: var(--scroll-thumb) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb {
    background: var(--scroll-thumb);
    border-radius: 999px;
    /* Borde del color del riel: hace ver el pulgar "flotando" y redondo. */
    border: 3px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: var(--texto-2); }
::-webkit-scrollbar-corner { background: var(--bg); }
/* El clip en <body> solo se propaga al viewport y el body queda "visible":
   los corazones (right: -8px) seguían ensanchando la página en móvil y la
   línea de la barra se veía corrida. El clip tiene que estar en <html>. */
html { overflow-x: clip; }
body {
    background: var(--bg);
    color: var(--texto);
    font-family: var(--f-cuerpo);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    /* Corazones/lápices sobresalen de las tarjetas (right: -8px): sin esto
       generan scroll lateral y la línea de la barra se ve "descentrada". */
    overflow-x: clip;
}
a { color: inherit; text-decoration: none; }
main { flex: 1; width: 100%; max-width: 1400px; margin: 0 auto; padding: 1.5rem 1rem 3rem; }

.topbar {
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
    /* Línea divisoria SIEMPRE dorada (pedido explícito) y barra teñida del
       tono elegido (--barra cae al fondo si el tono no define color). */
    padding: 0.9rem 1.5rem; border-bottom: 2px solid var(--dorado);
    position: sticky; top: 0; background: var(--barra, var(--bg)); z-index: 100;
}
/* En pantallas angostas la barra se apila centrada (con tantos links, el
   layout lado a lado quedaba torcido al envolver). */
@media (max-width: 860px) {
    .topbar { flex-direction: column; gap: 0.5rem; padding: 0.7rem 1rem; }
    .topbar nav { justify-content: center; gap: 0.7rem; }
}
.logo { font-family: var(--f-display); font-weight: 900; font-style: italic; font-size: 1.35rem; }
.logo span { color: var(--texto-2); font-weight: 400; font-style: normal; }
.topbar nav { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.topbar nav a { font-size: 0.9rem; color: var(--texto-2); }
.topbar nav a:hover { color: var(--texto); }
/* Botón de modo día/noche de la barra (manejado por static/tema.js). */
.toggle-tema {
    background: none; border: 1.5px solid var(--texto); color: var(--texto);
    border-radius: 999px; width: 34px; height: 34px; padding: 0; margin-top: 0;
    font-size: 1rem; line-height: 1; cursor: pointer; flex-shrink: 0;
}
.toggle-tema:hover { background: var(--texto); color: var(--bg); }
.btn-borde {
    border: 1.5px solid var(--texto); border-radius: 999px; padding: 0.4rem 0.9rem;
    color: var(--texto) !important; transition: background 0.2s, color 0.2s;
}
.btn-borde:hover { background: var(--texto); color: var(--bg) !important; }

footer { border-top: 2px solid var(--dorado); background: var(--barra, var(--bg)); padding: 1.25rem; text-align: center; color: var(--texto-2); font-size: 0.8rem; }
footer a { text-decoration: underline; text-underline-offset: 2px; }

/* Titular grande de la home: el rótulo del mural, igual que la maqueta. */
.hero-mural {
    font-family: var(--f-display); font-weight: 900; font-style: italic;
    font-size: clamp(2rem, 5vw, 3rem); line-height: 0.95; letter-spacing: -0.01em;
    text-transform: uppercase; text-wrap: balance; margin-top: 1.5rem;
}

/* Grilla de publicaciones: avisos "pegados" al mural, calcado de la maqueta
   aprobada -- SIN caja alrededor: la foto (cuadrada, redondeada, borde de
   tinta) y el texto flotan directo sobre el fondo, con sombra de papel,
   cinta arriba y leve inclinación que se endereza al pasar el mouse. */
.grilla { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 2.2rem 1.6rem; align-items: start; margin-top: 2rem; }
/* En teléfono: 2 columnas compactas (con minmax(220px) quedaba UNA columna
   de tarjetas gigantes y bajar por 60 avisos se hacía eterno). */
@media (max-width: 600px) {
    /* minmax(0,1fr): con 1fr a secas el contenido (fotos/cintas) impone su
       ancho mínimo y la segunda columna se salía de la pantalla. */
    .grilla { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.4rem 0.8rem; }
    .grilla .tarjeta .precio { font-size: 1.15rem; }
    .grilla .tarjeta h3 { font-size: 0.9rem; }
}
/* Sin rotación ni filter en la tarjeta: transform + drop-shadow rasterizan
   el texto (antialias gris = letras con halo, borrosas). La inclinación del
   mural queda solo en las cintas; la sombra de papel, en la foto. */
.tarjeta {
    position: relative; display: block; overflow: visible;
    transition: transform 0.2s cubic-bezier(.2,.8,.3,1);
}
.tarjeta:hover { transform: translateY(-4px); z-index: 2; }
.tarjeta:hover .foto, .tarjeta:hover .sin-foto { box-shadow: 0 10px 16px var(--sombra); }
/* Cinta de papel arriba de cada aviso, con los bordes más oscuros como la
   cinta real de la maqueta. */
.tarjeta .tape {
    position: absolute; top: -9px; left: 50%; height: 22px; width: 76px;
    transform: translateX(-50%) rotate(-3deg); opacity: 0.88; z-index: 2;
    background: var(--tape2); box-shadow: 0 1px 2px var(--sombra);
}
.tarjeta .tape::before, .tarjeta .tape::after {
    content: ""; position: absolute; top: 0; bottom: 0; width: 6px;
    background: inherit; filter: brightness(0.85);
}
.tarjeta .tape::before { left: -2px; }
.tarjeta .tape::after { right: -2px; }
.grilla .tarjeta:nth-child(2n) .tape { transform: translateX(-50%) rotate(3deg); }
.grilla .tarjeta:nth-child(3n+1) .tape { background: var(--tape1); }
.grilla .tarjeta:nth-child(3n+2) .tape { background: var(--tape2); }
.grilla .tarjeta:nth-child(3n+3) .tape { background: var(--tape3); }
/* Tag de categoría colgando sobre la foto, con "agujerito". */
.tarjeta .cat-tag {
    position: absolute; top: 8px; left: -10px; z-index: 2;
    background: var(--bg); border: 1.5px solid var(--texto); border-radius: 3px;
    padding: 0.15rem 0.5rem 0.15rem 0.9rem; font-size: 0.62rem; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--texto);
}
.tarjeta .cat-tag::before {
    content: ""; position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
    width: 5px; height: 5px; border-radius: 50%; background: var(--bg); border: 1.5px solid var(--texto);
}
.tarjeta .foto {
    width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block;
    border-radius: 10px; border: 1.5px solid var(--texto); margin-bottom: 0.6rem;
    background: var(--superficie);
    box-shadow: 0 2px 5px var(--sombra);
    transition: box-shadow 0.2s;
}
/* Corazón de favoritos (static/favoritos.js): estampilla en la esquina de
   la tarjeta; apagado = contorno, activo = rojo del tema. */
.fav-btn {
    position: absolute; top: 6px; right: -8px; z-index: 3;
    width: 30px; height: 30px; border-radius: 50%; padding: 0; margin-top: 0;
    background: var(--bg); border: 1.5px solid var(--texto);
    color: transparent; -webkit-text-stroke: 1.2px var(--texto-2);
    font-size: 0.95rem; line-height: 1; cursor: pointer;
    transform: rotate(6deg); transition: transform 0.15s, color 0.15s;
}
.fav-btn:hover { transform: rotate(0deg) scale(1.12); }
.fav-btn.activo { color: var(--rojo); -webkit-text-stroke: 0; border-color: var(--rojo); }
/* Variante junto al título del detalle: en línea, sin flotar. */
.fav-btn.fav-detalle {
    position: static; transform: none; vertical-align: middle;
    margin-left: 0.5rem; width: 34px; height: 34px; font-size: 1.05rem;
}
.fav-btn.fav-detalle:hover { transform: scale(1.12); }
/* Hueco sin foto. La versión anterior era un rectángulo rayado enorme con un
   emoji diminuto flotando al medio: en una tarjeta grande (vitrina, portada de
   revista) el vacío se comía la página y hacía ver rotos todos los diseños.
   Ahora se lee como una ficha de papel a propósito: trama más separada y
   suave, sello centrado y la leyenda que explica qué pasa. */
.tarjeta .sin-foto {
    width: 100%; aspect-ratio: 1/1;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.5rem;
    color: var(--texto-2); font-size: 1.5rem; border-radius: 10px;
    border: 1.5px dashed var(--borde);
    margin-bottom: 0.6rem;
    background: var(--superficie);
    background-image: repeating-linear-gradient(135deg, var(--borde) 0 1px, transparent 1px 16px);
    box-shadow: 0 2px 5px var(--sombra);
    transition: box-shadow 0.2s;
}
.tarjeta .sin-foto::after {
    content: "Sin foto";
    font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.1em;
    opacity: 0.75;
}
.tarjeta .titulo { color: var(--texto); font-weight: 700; font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tarjeta .precio {
    font-family: var(--f-mano); font-size: 1.4rem; font-weight: 700;
    color: var(--accent); display: inline-block; margin: 0.1rem 0;
}
.tarjeta .meta { color: var(--texto-2); font-size: 0.74rem; margin-top: 0.1rem; display: flex; justify-content: space-between; gap: 0.5rem; }
.tarjeta .meta .dist { font-family: 'Courier New', monospace; }
.tarjeta .seller { color: var(--texto-2); font-size: 0.72rem; opacity: 0.85; margin-top: 0.15rem; }

/* ===== Modal de vista rápida: el aviso "descolgado del mural" para leerlo
   de cerca, con el fondo difuminado -- calcado de la maqueta. Compacto:
   entra entero en pantalla; para leer más está el botón de página completa. */
.pub-backdrop {
    display: none; position: fixed; inset: 0; z-index: 9000;
    align-items: center; justify-content: center; padding: 1.5rem;
    background: rgba(20,16,10,0.5); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
/* Apertura de la vista rápida: el fondo se funde y la tarjeta sube un poco
   con un leve escalado, para que el aviso "aparezca" en vez de saltar. El
   guard global de prefers-reduced-motion neutraliza estas animaciones. */
.pub-backdrop.open { display: flex; animation: modal-fondo 0.18s ease-out; }
.pub-backdrop.open .pub-modal { animation: modal-entra 0.24s cubic-bezier(0.2, 0.8, 0.2, 1); }
@keyframes modal-fondo { from { opacity: 0; } }
@keyframes modal-entra { from { opacity: 0; transform: translateY(14px) scale(0.97); } }
.pub-modal {
    background: var(--bg); color: var(--texto); border: 1.5px solid var(--texto); border-radius: 14px;
    max-width: 680px; width: 100%; max-height: calc(100vh - 2.5rem); overflow-y: auto;
    padding: clamp(1.1rem, 3vw, 1.7rem) clamp(1.1rem, 3vw, 1.7rem) 0; position: relative;
    box-shadow: 0 24px 48px rgba(0,0,0,0.35);
}
.pub-modal .cerrar {
    position: absolute; top: 12px; right: 14px; border: 1.5px solid var(--texto); background: var(--bg);
    color: var(--texto); width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
    font-size: 0.95rem; line-height: 1; margin-top: 0; padding: 0;
}
.pub-modal .cat-tag {
    position: static; display: inline-block; background: var(--bg); border: 1.5px solid var(--texto);
    border-radius: 3px; padding: 0.15rem 0.5rem 0.15rem 0.9rem; font-size: 0.62rem;
    text-transform: uppercase; letter-spacing: 0.06em;
    margin-bottom: 0.6rem; position: relative;
}
.pub-modal .cat-tag::before {
    content: ""; position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
    width: 5px; height: 5px; border-radius: 50%; background: var(--bg); border: 1.5px solid var(--texto);
}
.pub-modal .galeria-mini {
    height: clamp(260px, 48vh, 460px); border-radius: 12px; border: 1.5px solid var(--texto);
    margin-bottom: 0.8rem; position: relative; overflow: hidden;
    display: flex; align-items: center; justify-content: center; background: var(--superficie);
}
/* contain (no cover): la foto entera se autoajusta a la vista rápida en vez
   de salir recortada (feedback ronda 14). */
.pub-modal .galeria-mini img { width: 100%; height: 100%; object-fit: contain; }
.pub-modal .galeria-mini .sin-foto-mini { font-size: 2.4rem; opacity: 0.4; }
.pub-modal .foto-nav {
    position: absolute; top: 50%; transform: translateY(-50%); width: 30px; height: 30px;
    border-radius: 50%; border: 1.5px solid var(--texto); background: var(--bg); color: var(--texto);
    cursor: pointer; font-size: 0.9rem; line-height: 1; opacity: 0.85; margin-top: 0; padding: 0;
}
.pub-modal .foto-nav:hover { background: var(--texto); color: var(--bg); }
.pub-modal .foto-nav.prev { left: 8px; }
.pub-modal .foto-nav.next { right: 8px; }
.pub-modal .foto-dots { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); display: flex; gap: 5px; }
.pub-modal .foto-dots span { width: 6px; height: 6px; border-radius: 50%; background: var(--texto); opacity: 0.3; }
.pub-modal .foto-dots span.activa { opacity: 0.9; }
.pub-modal h2 {
    font-family: var(--f-display); font-weight: 900; font-style: italic;
    font-size: clamp(1.1rem, 3.5vw, 1.4rem); margin: 0 0 0.2rem; text-wrap: balance;
}
.pub-modal .precio-modal {
    font-family: var(--f-mano); font-size: clamp(1.3rem, 4.5vw, 1.7rem);
    font-weight: 700; display: inline-block; margin: 0.1rem 0 0.4rem; color: var(--accent);
}
.pub-modal .meta-modal { font-size: 0.8rem; color: var(--texto-2); margin-bottom: 0.6rem; }
.pub-modal .vendedor-fila {
    display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 0;
    border-top: 1.5px solid var(--texto); border-bottom: 1.5px solid var(--texto);
    font-size: 0.92rem; margin-bottom: 0.7rem;
}
.pub-modal .vendedor-fila a { font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.pub-modal .vendedor-fila a:hover { color: var(--accent); }
.pub-modal .desc-modal {
    font-size: 0.9rem; line-height: 1.5; margin-bottom: 0.7rem; color: var(--texto-2); white-space: pre-wrap;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.pub-modal .ver-completa {
    display: block; cursor: pointer; font-size: 0.8rem; font-weight: 700; text-align: center;
    padding: 0.55rem; margin-bottom: 0.9rem; border: 1.5px dashed var(--texto); border-radius: 8px;
    color: var(--texto); background: none;
}
.pub-modal .ver-completa:hover { background: var(--texto); color: var(--bg); }
.pub-modal .contacto-label {
    font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--texto-2);
    margin-bottom: 0.5rem;
}
.pub-modal .contacto-tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-bottom: 1.2rem; }
.pub-modal .contacto-tabs a {
    flex: 1; min-width: 100px; text-align: center; padding: 0.6rem 0.5rem;
    border: 1.5px solid var(--texto); border-radius: 8px; font-size: 0.85rem; font-weight: 700;
    color: var(--texto); transition: background 0.15s, color 0.15s;
}
.pub-modal .contacto-tabs a:hover { background: var(--texto); color: var(--bg); }
.pub-modal .contacto-tabs a b { display: block; margin-top: 0.25rem; font-size: 0.78rem; font-weight: 400; opacity: 0.8; }

/* Recortes de papel cayendo de fondo (solo contorno, ambiental) -- el
   detalle que remata el mural en la maqueta. Poblado por /static/mural.js. */
.scraps-fall { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.scrap-fall {
    position: absolute; top: -5vh; opacity: 0.28; border-radius: 2px;
    border: 1.2px solid var(--texto); background: none;
    animation: scrapFall linear infinite;
}
@keyframes scrapFall {
    from { transform: translate(0, 0) rotate(0deg); }
    to { transform: translate(var(--drift, 40px), 110vh) rotate(var(--spin, 240deg)); }
}
@media (prefers-reduced-motion: reduce) { .scrap-fall { animation: none; display: none; } }
/* Recortes de papel de COLOR para la decoración de tienda (deco-recortes):
   notita visible con caída, deriva y giro (el contorno tenue del mural no se
   veía sobre el fondo del vendedor). */
.papel-cae {
    position: absolute; top: -8vh;
    background: center / contain no-repeat;
    animation: scrapFall linear infinite;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
}
@media (prefers-reduced-motion: reduce) { .papel-cae { animation: none; display: none; } }
/* Solo main y footer: la .topbar ya es sticky con z-index 100 (arriba) y
   meterla acá se lo pisaba, dejando el panel de tonos DEBAJO del buscador
   (imposible de clickear). */
main, footer { position: relative; z-index: 1; }

/* Formularios / paneles */
form.panel, .panel {
    background: var(--superficie); border: 1.5px solid var(--texto); border-radius: 12px;
    padding: 1.5rem; max-width: 560px; margin: 1.5rem auto; box-shadow: 0 3px 8px var(--sombra);
}
.panel h2 { font-family: var(--f-display); font-size: 1.05rem; margin: 1.5rem 0 0.6rem; }
.panel ul { padding-left: 1.2rem; margin-bottom: 0.6rem; }
.panel li { margin-bottom: 0.4rem; line-height: 1.5; color: var(--texto-2); }
.panel p { line-height: 1.6; color: var(--texto-2); margin-bottom: 0.6rem; }
.panel a { text-decoration: underline; text-underline-offset: 2px; }
/* Opciones de radio con texto al lado (flujo vender: elegir comprador).
   El input global es width:100%; acá se acota para que quede en línea. */
.opcion-radio {
    display: flex; align-items: center; gap: 0.6rem;
    font-size: 1rem; color: var(--texto);
    border: 1.5px solid var(--borde); border-radius: 8px;
    padding: 0.7rem 0.9rem; margin: 0.5rem 0; cursor: pointer;
}
.opcion-radio input[type="radio"] { width: auto; margin: 0; accent-color: var(--dorado); }
.opcion-radio:has(input:checked) { border-color: var(--dorado); }

/* Estrellas del formulario de reseña: radios ocultos + labels ★. El truco
   flex-direction: row-reverse hace que "checked ~ label" pinte las de la
   izquierda (DOM 5..1, visual 1..5). Cero JS (CSP). */
.estrellas-input { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 0.2rem; margin: 0.8rem 0; }
.estrellas-input input { position: absolute; opacity: 0; width: 0; }
.estrellas-input label { font-size: 2.2rem; color: var(--borde); cursor: pointer; line-height: 1; margin: 0; }
.estrellas-input label:hover,
.estrellas-input label:hover ~ label,
.estrellas-input input:checked ~ label { color: var(--dorado); }
.estrellas-input input:focus-visible + label { outline: 2px solid var(--dorado); border-radius: 4px; }

/* Reseñas de compra verificada (ronda 11): promedio en cabecera de tienda,
   tarjetas de reseña con autor visible y badges. */
.tienda-estrellas { display: inline-block; margin-top: 0.3rem; color: var(--dorado); font-weight: 700; text-decoration: none; }
.resenas { margin-top: 2.5rem; }
.resena-card {
    border: 1px solid var(--borde); background: var(--superficie);
    border-radius: 10px; padding: 1rem; margin-bottom: 1rem;
    max-width: 720px; text-align: left;
}
.resena-card header { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: baseline; margin-bottom: 0.4rem; }
.resena-card header a { font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.resena-estrellas { color: var(--dorado); letter-spacing: 2px; }
.badge-verificada { font-size: 0.75rem; border: 1px solid var(--dorado); color: var(--dorado); border-radius: 999px; padding: 0.1rem 0.55rem; white-space: nowrap; }
.badge-repetida { font-size: 0.75rem; border: 1px solid var(--borde); color: var(--texto-2); border-radius: 999px; padding: 0.1rem 0.55rem; white-space: nowrap; }
.resena-respuesta { border-left: 3px solid var(--dorado); margin: 0.6rem 0 0; padding: 0.3rem 0.8rem; color: var(--texto-2); }
.form-respuesta { display: flex; gap: 0.5rem; margin-top: 0.5rem; }
.form-respuesta input { flex: 1; }
.form-respuesta button, .form-reporte-resena button { margin-top: 0; padding: 0.4rem 0.8rem; font-size: 0.85rem; }
.form-reporte-resena { margin-top: 0.5rem; }
.tarjeta-estrellas { color: var(--dorado); font-weight: 700; }
/* Adjuntos del chat (ronda 12): imagen inline, tarjeta de documento y
   botón de adjuntar (input file oculto dentro del label). */
.burbuja-img {
    display: block; max-width: min(320px, 100%); max-height: 320px;
    border-radius: 10px; margin-bottom: 0.35rem; border: 1px solid var(--borde);
}
.burbuja-doc {
    display: flex; align-items: center; gap: 0.6rem;
    border: 1.5px solid var(--borde); border-radius: 10px;
    padding: 0.55rem 0.8rem; margin-bottom: 0.35rem;
    text-decoration: none; background: var(--bg); max-width: 320px;
}
.burbuja-doc .doc-icono { font-size: 1.6rem; }
.burbuja-doc .doc-info { display: flex; flex-direction: column; min-width: 0; }
.burbuja-doc .doc-info b {
    color: var(--texto); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.burbuja-doc .doc-info span { font-size: 0.75rem; color: var(--texto-2); }
.btn-adjuntar { position: relative; overflow: hidden; cursor: pointer; }
.btn-adjuntar input[type="file"] {
    position: absolute; inset: 0; opacity: 0; width: 100%; cursor: pointer;
}

/* Estadísticas del vendedor sobre la tabla de gestión (ronda 12). */
.estadisticas { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0.8rem 0 1rem; }
/* Gráfico de visitas por día (ronda 29): barras CSS, ancho fluido. */
.grafico-visitas {
    border: 1px solid var(--borde); background: var(--superficie);
    border-radius: 10px; padding: 0.7rem 0.9rem; margin: 0 0 1rem;
    max-width: 560px;
}
.barras-visitas {
    display: flex; align-items: flex-end; gap: 4px; height: 86px;
}
.col-visita {
    flex: 1; display: flex; flex-direction: column; align-items: center;
    justify-content: flex-end; height: 100%; min-width: 0;
}
.barra-visita {
    width: 100%; max-width: 26px; min-height: 2px; border-radius: 3px 3px 0 0;
    background: linear-gradient(to top, var(--accent, var(--dorado)),
                color-mix(in srgb, var(--accent, var(--dorado)) 55%, var(--bg)));
    transition: height 0.4s ease;
}
.dia-visita { font-size: 0.62rem; color: var(--texto-2); margin-top: 2px; }
/* Caja inline del punto de encuentro del chat (ronda 30, sin prompt()). */
.caja-lugar { display: flex; gap: 0.4rem; align-items: center; margin: 0.5rem 0; max-width: 640px; }
.caja-lugar input { flex: 1; margin-top: 0; }
.caja-lugar button { margin-top: 0; padding: 0.5rem 0.9rem; }
.stat {
    border: 1px solid var(--borde); background: var(--superficie); border-radius: 10px;
    padding: 0.5rem 0.9rem; text-align: center; min-width: 86px;
}
.stat b { display: block; font-size: 1.25rem; color: var(--texto); }
.stat span { font-size: 0.72rem; color: var(--texto-2); }

/* Insignias de confianza en la cabecera de la tienda (ronda 12). */
.insignias { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; margin-top: 0.5rem; }
.insignia {
    font-size: 0.78rem; font-weight: 700; border-radius: 999px;
    padding: 0.15rem 0.7rem; border: 1px solid var(--borde); color: var(--texto-2);
    background: var(--superficie);
}
.insignia-cinco-estrellas { border-color: var(--dorado); color: var(--dorado); }
.insignia-verificado { border-color: var(--verde, #2e7d32); color: var(--verde, #2e7d32); }

/* Sección "Otros también vieron" del detalle (ronda 12). */
.tambien-vieron { margin-top: 2.5rem; }
.tambien-vieron .titulo-seccion { margin-bottom: 0.8rem; }

/* Sección "Para ti" del home (recomendaciones por intereses). */
.para-ti { margin-bottom: 2.5rem; }
.para-ti .titulo-seccion { margin-bottom: 0.8rem; }
label { display: block; font-size: 0.85rem; color: var(--texto-2); margin: 0.9rem 0 0.3rem; }
input, textarea, select {
    width: 100%; background: var(--bg); border: 1.5px solid var(--borde); border-radius: 8px;
    color: var(--texto); padding: 0.6rem 0.75rem; font-family: inherit; font-size: 0.95rem;
}
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--texto); }
input[type="checkbox"] {
    width: auto; flex-shrink: 0; background: none; border: none; padding: 0;
    accent-color: var(--texto); cursor: pointer;
}
textarea { min-height: 120px; resize: vertical; }
button, .boton {
    background: var(--texto); color: var(--bg); border: 1.5px solid var(--texto); border-radius: 999px;
    padding: 0.65rem 1.3rem; font-family: inherit; font-weight: 600; font-size: 0.95rem;
    cursor: pointer; margin-top: 1.1rem;
    /* inline-flex centra el texto vertical (el "+ Publicar" quedaba alto). */
    display: inline-flex; align-items: center; justify-content: center;
    gap: 0.3rem; line-height: 1.15;
    transition: transform 0.15s ease, opacity 0.15s ease;
}
/* Hover "vivo": el botón salta un pelín y se asienta un poco elevado.
   Solo translateY (rotate/filter difuminan texto — lección ronda 9). */
@keyframes salto-boton {
    0% { transform: translateY(0); }
    45% { transform: translateY(-4px); }
    100% { transform: translateY(-2px); }
}
button:not(.fav-btn):not(.toggle-tema):not(.tono-opcion):not(.bgmode-btn):hover, .boton:hover {
    opacity: 0.85; animation: salto-boton 0.28s ease; transform: translateY(-2px);
}
button:not(.fav-btn):not(.toggle-tema):not(.tono-opcion):not(.bgmode-btn):active, .boton:active { animation: none; transform: translateY(0); }
button.secundario, .boton.secundario { background: none; color: var(--texto); border: 1.5px solid var(--texto); }
button.peligro { background: none; color: var(--rojo); border: 1.5px solid var(--rojo); }
.error-msg { background: none; border: 1.5px solid var(--rojo); color: var(--rojo); border-radius: 8px; padding: 0.7rem 1rem; margin-top: 1rem; font-size: 0.9rem; }
.ok-msg { background: none; border: 1.5px solid var(--verde); color: var(--verde); border-radius: 8px; padding: 0.7rem 1rem; margin-top: 1rem; font-size: 0.9rem; }

/* Buscador de la home */
.buscador { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.5rem; }
/* El :not(checkbox) importa: sin él la casilla "Con foto" hereda flex:1 y
   min-width:200px, se estira como si fuera un campo de texto y deja su
   etiqueta descolgada al otro lado del hueco. */
.buscador input:not([type="checkbox"]) { flex: 1; min-width: 200px; }
.buscador select { width: auto; }
.buscador button { margin-top: 0; }
.filtro-foto {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
    font-size: 0.9rem;
    cursor: pointer;
}
.filtro-foto input { margin: 0; }

/* Detalle de publicación: el aviso "ampliado", recto (sin inclinación) para
   que se lea claro -- la inclinación queda solo para la tarjeta chica. */
.detalle {
    display: grid; grid-template-columns: 1.1fr 1fr; gap: 1.25rem; margin-top: 1.5rem;
    background: var(--superficie); border: 1.5px solid var(--texto); border-radius: 12px; padding: 1.25rem;
    box-shadow: 0 4px 10px var(--sombra);
    /* Acotado y centrado: antes ocupaba todo el ancho con fotos gigantes y
       "Otros también vieron" quedaba fuera de vista (feedback ronda 14). */
    max-width: 1000px; margin-left: auto; margin-right: auto;
}
@media (max-width: 800px) { .detalle { grid-template-columns: 1fr; } }
.galeria img {
    width: 100%; border-radius: 10px; border: 1.5px solid var(--texto); margin-bottom: 0.75rem;
    max-height: 420px; object-fit: contain; background: var(--bg);
}
.info-pub h1 { font-family: var(--f-display); font-weight: 900; font-style: italic; font-size: 1.5rem; text-wrap: balance; }
.info-pub .precio-grande { font-family: var(--f-mano); font-size: 2.2rem; font-weight: 700; margin: 0.6rem 0; color: var(--accent); }
/* Mini historial de precio: el original tachado junto al vigente. */
.precio-anterior {
    text-decoration: line-through; opacity: 0.55; font-size: 0.6em;
    font-weight: 400; margin-right: 0.3em; color: var(--texto-2);
}
.chip { display: inline-block; border: 1.5px solid var(--texto); border-radius: 999px; padding: 0.2rem 0.75rem; font-size: 0.78rem; color: var(--texto); }
.chip.vendida { color: var(--rojo); border-color: var(--rojo); }
.chip.reservada { color: var(--accent); border-color: var(--accent); }

/* Explorar por categoría (home limpio): chips-enlace a las landings /?cat=X. */
.cat-nav { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.1rem 0 1.1rem; }
.cat-nav .chip { text-decoration: none; cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease; }
.cat-nav .chip:hover { background: var(--texto); color: var(--bg); border-color: var(--texto); }

/* Visto ✓/✓✓ en los mensajes propios del chat (ronda 17). */
.burbuja-meta .visto { margin-left: 0.3rem; opacity: 0.6; letter-spacing: -0.1em; }
.burbuja-meta .visto.leido { color: var(--verde); opacity: 1; }

/* Respuestas rápidas del chat: chips que llenan el cuadro con un toque.
   Mismo ancho máximo que el formulario: sin tope, la última fila de chips
   se estiraba más allá del cuadro y se veía corrida hacia un lado. */
.chips-rapidas { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.8rem 0 0.5rem; max-width: 640px; }
.chips-rapidas button {
    border: 1.5px solid var(--borde); background: var(--superficie); color: var(--texto-2);
    border-radius: 999px; padding: 0.3rem 0.75rem; font-size: 0.8rem;
    cursor: pointer; margin-top: 0; transition: border-color 0.15s, color 0.15s;
}
.chips-rapidas button:hover { border-color: var(--texto); color: var(--texto); }

/* Tiendas que sigo (/favoritos): fichas horizontales con avatar y conteo. */
.tiendas-seguidas { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.tienda-seguida {
    display: inline-flex; align-items: center; gap: 0.55rem;
    border: 1.5px solid var(--borde); border-radius: 999px;
    padding: 0.35rem 0.9rem 0.35rem 0.4rem; background: var(--superficie);
    transition: border-color 0.15s;
}
.tienda-seguida:hover { border-color: var(--texto); }
.tienda-seguida .avatar-mini {
    width: 30px; height: 30px; border-radius: 50%; object-fit: cover;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1.5px solid var(--borde); font-size: 0.9rem;
}
.tienda-seguida .tienda-nombre { font-weight: 700; font-size: 0.88rem; }
.tienda-seguida .tienda-avisos { color: var(--texto-2); font-size: 0.78rem; }

/* Aviso global del sitio (/admin/sitio): cinta bajo la barra en TODAS las
   páginas mientras el admin lo tenga puesto. */
.aviso-global {
    text-align: center; font-size: 0.85rem; font-weight: 600;
    padding: 0.45rem 1rem; background: var(--superficie);
    border-bottom: 1.5px dashed var(--dorado); position: relative; z-index: 5;
}
/* Cartel Reservada sobre la tarjeta de la tienda: etiqueta ladeada, como
   pegada a mano (a juego con el mural). */
.tarjeta .banda-reservada {
    position: absolute; top: 8px; left: -6px; z-index: 2;
    transform: rotate(-6deg);
    background: var(--accent); color: var(--bg);
    font-size: 0.62rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: 0.08em; padding: 0.22rem 0.6rem; border-radius: 3px;
    pointer-events: none; box-shadow: 0 2px 4px var(--sombra);
}
.descripcion { white-space: pre-wrap; color: var(--texto-2); margin-top: 1rem; line-height: 1.55; }
.contacto-botones { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1.25rem; }
.boton-wsp { background: var(--verde); border-color: var(--verde); color: var(--bg); }

/* Perfil público (tienda del vendedor) */
/* Acciones del dueño (publicar/editar/compartir): fila arriba a la derecha,
   a la altura del nombre — solo las ve el dueño. */
.acciones-dueno { display: flex; gap: 0.6rem; justify-content: flex-end; flex-wrap: wrap; margin-top: 1rem; }
.acciones-dueno + .cabecera-perfil { margin-top: 0.3rem; }
.cabecera-perfil { display: flex; align-items: center; gap: 1.25rem; margin-top: 1.5rem; flex-wrap: wrap; }
.avatar { width: 84px; height: 84px; border-radius: 50%; object-fit: cover; border: 1.5px solid var(--texto); background: var(--borde); }
.avatar-placeholder { width: 84px; height: 84px; border-radius: 50%; display:flex; align-items:center; justify-content:center; font-size: 2rem; background: var(--borde); border: 1.5px solid var(--texto); }
.bio { color: var(--texto-2); margin-top: 0.3rem; max-width: 640px; white-space: pre-wrap; }

/* Tablas admin / mis publicaciones */
table { width: 100%; border-collapse: collapse; margin-top: 1rem; font-size: 0.9rem; }
th, td { text-align: left; padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--borde); }
th { color: var(--texto-2); font-weight: 600; font-size: 0.8rem; }
td form { display: inline; }
td button { margin-top: 0; padding: 0.3rem 0.7rem; font-size: 0.8rem; }
.estado-pendiente { color: var(--tape2); }
.estado-aprobado { color: var(--verde); }
.estado-suspendido, .estado-eliminada { color: var(--rojo); }
.miniatura { width: 54px; height: 40px; object-fit: cover; border-radius: 6px; border: 1px solid var(--borde); }

h1.titulo-seccion { font-family: var(--f-display); font-weight: 900; font-style: italic; font-size: 1.7rem; margin-top: 1rem; text-wrap: balance; }
.subtitulo { color: var(--texto-2); font-size: 0.9rem; margin-top: 0.25rem; }
.fotos-edit { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.5rem; }
.fotos-edit .foto-item { position: relative; }
.fotos-edit img { width: 90px; height: 68px; object-fit: cover; border-radius: 8px; border: 1px solid var(--borde); }
.fotos-edit label { font-size: 0.7rem; margin: 0.2rem 0 0; text-align: center; }

/* ===== Personalización de tienda del vendedor: swatches circulares para
   elegir fondo/letra/cintas, usados en mi_perfil.html. Mismo lenguaje visual
   que el resto del sitio, sin nada de color libre (listas fijas). ===== */
.swatches { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 0.4rem; }
.swatch {
    width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
    border: 1.5px solid rgba(128,128,128,0.4); position: relative; padding: 0;
    display: flex; align-items: center; justify-content: center; font-family: var(--f-display); font-weight: 700;
}
.swatch.ink-swatch { background: #c9c5bb; font-size: 0.85rem; }
/* Tilde de selección: color puesto por JS según contraste contra el propio
   swatch (negro sobre claro, blanco sobre oscuro) -- nada de halo difuminado. */
.swatch.active::after {
    content: "✓"; position: absolute; inset: -4px; display: flex; align-items: center; justify-content: center;
    font-size: 0.75rem; font-weight: 900; width: 16px; height: 16px; margin: auto;
    background: var(--check-bg, #fff); color: var(--check-fg, #000); border-radius: 50%; border: 1.5px solid var(--bg);
}
/* Aviso (no bloqueo) de combo fondo/letra con poco contraste en el editor. */
.contrast-warning { margin-top: 0.6rem; font-size: 0.85rem; color: var(--rojo); font-weight: 700; }

/* Botones de decoración de fondo del editor (quieto/recortes/motas). */
.bgmodes { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.4rem; }
.bgmode-btn {
    font-family: inherit; font-size: 0.8rem; border: 1.5px solid var(--texto); background: var(--bg);
    color: var(--texto); padding: 0.4rem 0.8rem; border-radius: 999px; cursor: pointer; margin-top: 0;
}
.bgmode-btn.active { background: var(--texto); color: var(--bg); }

/* Decoraciones de fondo de la tienda del vendedor (puro CSS; con cualquiera
   que no sea "recortes", mural.js no genera recortes cayendo). */
body.deco-motas {
    background-image: radial-gradient(var(--borde) 1px, transparent 1px);
    background-size: 14px 14px;
}
body.deco-rayas {
    background-image: repeating-linear-gradient(45deg, var(--borde) 0 1px, transparent 1px 18px);
}
body.deco-cuadricula {
    background-image: linear-gradient(var(--borde) 1px, transparent 1px),
                      linear-gradient(90deg, var(--borde) 1px, transparent 1px);
    background-size: 24px 24px;
}
/* Confeti: SOLO papelitos cayendo (deco_animada.js) — el patrón de
   puntitos estáticos de fondo se quitó (ronda 25, se veía a lunares). */

/* Minis de decoración en el editor (/mi-perfil): muestra del patrón dentro
   del botón, para elegir viendo y no adivinando por el nombre. */
.bgmode-mini {
    width: 44px; height: 24px; border-radius: 5px; flex-shrink: 0;
    border: 1px solid var(--borde); background: var(--superficie);
    display: inline-block; position: relative; overflow: hidden;
}
.bgmode-mini.mini-motas { background-image: radial-gradient(var(--texto-2) 1px, transparent 1px); background-size: 7px 7px; }
.bgmode-mini.mini-rayas { background-image: repeating-linear-gradient(45deg, var(--texto-2) 0 1px, transparent 1px 8px); }
.bgmode-mini.mini-cuadricula {
    background-image: linear-gradient(var(--texto-2) 1px, transparent 1px),
                      linear-gradient(90deg, var(--texto-2) 1px, transparent 1px);
    background-size: 9px 9px;
}
.bgmode-mini.mini-confeti {
    /* Papelitos alargados en ángulos varios (ya no puntos). */
    background-image:
        linear-gradient(35deg, transparent 44%, #d9a233 44% 56%, transparent 56%),
        linear-gradient(-25deg, transparent 44%, #c24b3c 44% 56%, transparent 56%),
        linear-gradient(65deg, transparent 44%, #3c7a6e 44% 56%, transparent 56%);
    background-size: 12px 9px, 14px 10px, 11px 8px;
    background-position: 1px 2px, 18px 10px, 30px 4px;
    background-repeat: no-repeat;
}
.bgmode-mini.mini-globos {
    background-image:
        radial-gradient(ellipse 4px 5px at 30% 45%, #e05c5c 60%, transparent 61%),
        radial-gradient(ellipse 3.5px 4.5px at 65% 60%, #5b7fc7 60%, transparent 61%);
}
.bgmode-mini.mini-mariposas {
    background-image:
        radial-gradient(ellipse 3px 4px at 38% 50%, #e2a23b 60%, transparent 61%),
        radial-gradient(ellipse 3px 4px at 55% 50%, #c96f9d 60%, transparent 61%);
}
.bgmode-mini.mini-aurora {
    background-image: linear-gradient(100deg,
        rgba(94, 227, 160, 0.7) 10%, rgba(140, 120, 235, 0.6) 45%,
        rgba(80, 200, 235, 0.6) 80%);
}
.bgmode-mini.mini-gatito {
    background-image:
        radial-gradient(circle 4px at 68% 55%, #7d7d85 60%, transparent 61%),
        radial-gradient(circle 3px at 30% 62%, #c4566e 60%, transparent 61%);
}
/* Gatito con estambre (ronda 31): el gato vive pegado al borde inferior
   derecho, respira suave y da zarpazos; la cola se menea sola. */
.capa-gato { pointer-events: none; }
.gato-deco {
    position: absolute; right: 26px; bottom: 0;
    width: 118px; height: 108px;
    background: center bottom / contain no-repeat;
    transform-origin: 50% 100%;
    animation: respira-gato 3.6s ease-in-out infinite alternate;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.18));
}
@keyframes respira-gato {
    from { transform: scaleY(1); }
    to   { transform: scaleY(1.035); }
}
.gato-deco.golpea { animation: zarpazo 0.5s ease-out; }
@keyframes zarpazo {
    0%   { transform: rotate(0deg); }
    35%  { transform: rotate(-13deg) translateX(-9px); }
    100% { transform: rotate(0deg); }
}
.gato-cola {
    position: absolute; right: 122px; bottom: 2px;
    width: 66px; height: 38px;
    background: center / contain no-repeat;
    transform-origin: 100% 85%;
    animation: menear-cola 2.8s ease-in-out infinite alternate;
}
@keyframes menear-cola {
    from { transform: rotate(-4deg); }
    to   { transform: rotate(14deg); }
}
/* Recortes: dos papelitos inclinados (rotate solo en elementos sin texto). */
.bgmode-mini.mini-recortes::before, .bgmode-mini.mini-recortes::after {
    content: ""; position: absolute; width: 9px; height: 12px; border-radius: 1px;
    background: var(--texto-2); opacity: 0.7;
}
.bgmode-mini.mini-recortes::before { left: 9px; top: 3px; transform: rotate(-14deg); }
.bgmode-mini.mini-recortes::after { right: 8px; top: 8px; transform: rotate(22deg); background: #c9a227; }
.bgmode-btn { display: inline-flex; align-items: center; gap: 0.45rem; justify-content: flex-start; }

/* ===== Mensajería interna y notificaciones ===== */
/* Campanita y contadores en la barra: el badge usa --rojo para destacar
   sobre cualquier tema (los tokens ya cambian con el modo noche). */
.nav-campana { text-decoration: none; position: relative; }
.badge-num {
    display: inline-block; min-width: 1.1rem; padding: 0 0.25rem; margin-left: 0.15rem;
    background: var(--rojo); color: #fff; border-radius: 999px;
    font-size: 0.68rem; font-weight: 700; text-align: center; line-height: 1.4;
    vertical-align: top;
}

/* Bandeja de conversaciones */
.lista-conversaciones { list-style: none; padding: 0; margin: 1rem 0 0; max-width: 640px; }
.conversacion {
    display: block; padding: 0.8rem 1rem; margin-bottom: 0.6rem; text-decoration: none;
    background: var(--superficie); border: 1px solid var(--borde); border-radius: 10px;
    color: var(--texto);
}
.conversacion:hover { border-color: var(--texto-2); }
.conv-quien { font-weight: 700; }
.conv-pub { color: var(--texto-2); font-size: 0.85rem; }
.conv-ultimo { color: var(--texto-2); font-size: 0.9rem; margin-top: 0.2rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-fecha { color: var(--texto-2); font-size: 0.75rem; margin-top: 0.2rem; }
.conversacion.sin-leer .conv-quien::after {
    content: "●"; color: var(--rojo); margin-left: 0.35rem; font-size: 0.7rem;
}

/* Hilo de mensajes: burbujas, las mías a la derecha con acento. */
.hilo-cabecera { display: flex; align-items: baseline; gap: 0.8rem; flex-wrap: wrap; max-width: 640px; }
.hilo-cabecera .volver { color: var(--texto-2); text-decoration: none; }
.hilo-cabecera .volver:hover { text-decoration: underline; }
/* Mini-tarjeta de contexto del hilo: qué publicación se está conversando. */
.chat-contexto {
    display: flex; align-items: center; gap: 0.8rem; max-width: 640px;
    margin-top: 0.8rem; padding: 0.6rem 0.8rem; text-decoration: none;
    background: var(--superficie); border: 1px solid var(--borde);
    border-radius: 10px; color: var(--texto);
}
.chat-contexto:hover { border-color: var(--texto-2); }
.chat-contexto img {
    width: 56px; height: 56px; object-fit: cover; border-radius: 8px; flex-shrink: 0;
}
.chat-contexto-sinfoto {
    width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
    font-size: 1.5rem; background: var(--bg); border-radius: 8px; flex-shrink: 0;
}
.chat-contexto-datos { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.chat-contexto-datos b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-contexto-precio { font-weight: 700; color: var(--accent); }
.chat-aviso-edicion {
    max-width: 640px; margin-top: 0.5rem; padding: 0.5rem 0.8rem;
    font-size: 0.85rem; color: var(--rojo); border: 1px dashed var(--rojo);
    border-radius: 8px;
}
.hilo { display: flex; flex-direction: column; gap: 0.5rem; max-width: 640px; margin-top: 1rem; }
.burbuja {
    max-width: 80%; padding: 0.55rem 0.85rem; border-radius: 12px;
    background: var(--superficie); border: 1px solid var(--borde);
    align-self: flex-start;
}
.burbuja.mia { align-self: flex-end; border-color: var(--accent); }
.burbuja-cuerpo { overflow-wrap: anywhere; white-space: pre-wrap; }
.burbuja-meta { color: var(--texto-2); font-size: 0.7rem; margin-top: 0.25rem; }

.form-mensaje { max-width: 640px; margin-top: 1rem; }
.form-mensaje textarea { width: 100%; }
/* Fila de botones del chat: ALTURA FIJA para Enviar/Adjuntar/Ubicación.
   Los emojis (📎 📍) hacen la línea más alta que el texto solo y el label
   de adjuntar quedaba descuadrado — con height fija todos miden igual. */
.form-mensaje button, .form-mensaje .btn-adjuntar {
    margin-top: 0; display: inline-flex; align-items: center; gap: 0.3rem;
    padding: 0 1.1rem; height: 2.5rem; line-height: 1; vertical-align: middle;
}
/* Chat a dos columnas en escritorio: hilo a la izquierda, la publicación
   COMPLETA (fotos grandes) a la derecha — que se vea qué se está comprando. */
.chat-layout { display: flex; gap: 1.6rem; align-items: flex-start; }
.chat-principal { flex: 1 1 auto; min-width: 0; }
.chat-pub-panel {
    flex: 0 0 340px; position: sticky; top: 84px;
    background: var(--superficie); border: 1px solid var(--borde);
    border-radius: 12px; padding: 0.9rem;
    /* La publicación ENTERA (título + fotos + descripción) sin desbordar la
       pantalla: si la descripción es larga, el panel scrollea por dentro. */
    max-height: calc(100vh - 100px); overflow-y: auto;
}
.chat-pub-foto {
    width: 100%; aspect-ratio: 4 / 3; object-fit: contain;
    background: color-mix(in srgb, var(--texto) 4%, var(--bg));
    border-radius: 8px; display: block;
}
.chat-pub-minis { display: flex; gap: 0.4rem; margin-top: 0.4rem; }
.chat-pub-minis img {
    width: 64px; height: 64px; object-fit: cover; border-radius: 6px;
    border: 1px solid var(--borde);
}
.chat-pub-titulo { font-size: 1.05rem; margin: 0.7rem 0 0.2rem; }
.chat-pub-precio { font-family: var(--f-mano); font-size: 1.5rem; margin: 0 0 0.3rem; color: var(--accent, var(--texto)); }
.chat-pub-desc {
    font-size: 0.85rem; color: var(--texto-2); line-height: 1.5;
    margin: 0.3rem 0 0; white-space: pre-line; overflow-wrap: break-word;
}
/* Aviso de "editada después de conversar" desplegable: qué decía antes. */
.chat-ediciones summary { cursor: pointer; color: inherit; }
.chat-ediciones ul { margin: 0.4rem 0 0 1.1rem; padding: 0; line-height: 1.55; }
.chat-ediciones .antes { text-decoration: line-through; opacity: 0.75; }
.chat-ediciones blockquote {
    margin: 0.2rem 0 0.4rem; padding: 0.3rem 0.6rem; font-style: italic;
    border-left: 3px solid var(--borde); opacity: 0.85; white-space: pre-line;
}
.solo-movil { display: none; }
@media (max-width: 920px) {
    .chat-pub-panel { display: none; }
    .solo-movil { display: flex; }
}
/* Resultado del "Mensaje" del modal, en el mismo lugar del botón. */
.msg-enviado {
    border: 1.5px solid var(--verde, #2c7a4b); color: var(--verde, #2c7a4b);
    border-radius: 8px; padding: 0.55rem 0.9rem; font-size: 0.88rem;
}
.msg-enviado a { color: inherit; text-decoration: underline; }
.msg-error-envio {
    border: 1.5px solid #b3402a; color: #b3402a;
    border-radius: 8px; padding: 0.55rem 0.9rem; font-size: 0.88rem;
}
/* Chips de respuestas rápidas propias: bordecito de acento para
   distinguirlas de las de la casa. */
.chips-rapidas .chip-propia { border-color: var(--accent, var(--dorado)); }
/* Historial de cambios del aviso (transparencia). */
.historial-ediciones { margin: 0.4rem 0 0; font-size: 0.85rem; color: var(--texto-2); }
.historial-ediciones summary { cursor: pointer; }
.historial-ediciones ul { margin: 0.4rem 0 0 1.1rem; padding: 0; line-height: 1.6; }

/* Notificaciones */
.lista-notificaciones { list-style: none; padding: 0; margin: 1rem 0 0; max-width: 640px; }
.notificacion {
    /* display:block: las notificaciones con link son <a> (inline por
       defecto) y la caja se encogía al texto — se veían "cortadas". */
    display: block;
    padding: 0.7rem 1rem; margin-bottom: 0.5rem;
    background: var(--superficie); border: 1px solid var(--borde); border-radius: 10px;
}
.notificacion.sin-leer { border-left: 3px solid var(--accent); }
.notif-icono { margin-right: 0.4rem; }
.notif-texto { overflow-wrap: anywhere; }
.notif-fecha { display: block; color: var(--texto-2); font-size: 0.75rem; margin-top: 0.2rem; }
.notificacion a { color: var(--texto); }

/* ===== Fase 2: banner de verificación + apariencia por cuenta ===== */
.banner-verificacion {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    flex-wrap: wrap; padding: 0.8rem 1rem; margin-bottom: 1.2rem;
    background: var(--superficie); border: 1.5px solid var(--accent); border-radius: 10px;
}
.banner-verificacion form { margin: 0; }
.banner-verificacion button { margin-top: 0; }

.radios-apariencia { display: flex; flex-direction: column; gap: 0.45rem; margin-top: 0.4rem; }
.radios-apariencia label { display: flex; align-items: center; gap: 0.5rem; margin: 0; font-weight: 400; }
.radios-apariencia input[type="radio"] { width: auto; margin: 0; }

/* Vista previa en vivo de /mi-perfil/apariencia: formulario a la izquierda
   y un mini-mural de muestra al lado (queda pegado al hacer scroll) para ver
   cómo cambian las tarjetas. En angosto, la muestra pasa abajo. */
.apariencia-wrap { display: flex; gap: 2.5rem; align-items: flex-start; justify-content: flex-start; }
.apariencia-wrap form.panel { flex: 0 1 560px; min-width: 0; }
.apariencia-preview { flex: 1 1 auto; max-width: 640px; position: sticky; top: 90px; margin-top: 1.5rem; }
/* Mini-mural: varias tarjetas para que la muestra se parezca al inicio real. */
.preview-grilla {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 1.8rem 1.3rem; align-items: start; margin-top: 0;
}
/* La .preview-tarjeta del editor de tienda es inline de 150px; acá vive en
   una grilla y ocupa su celda completa. */
.preview-grilla .preview-tarjeta { display: block; width: auto; pointer-events: none; }
/* Grupos de tono día/noche: el que no corresponde al modo previsualizado se
   atenúa (sigue clickeable: elegirlo salta a ese modo, apariencia.js). */
.grupo-tono { margin-top: 0.4rem; }
.grupo-tono + .grupo-tono { margin-top: 0.9rem; }
/* Día y noche en dos columnas, separadas por la línea dorada del sitio;
   en pantallas angostas vuelven a apilarse (la línea pasa a horizontal). */
.tonos-dosc { display: grid; grid-template-columns: 1fr 1fr; column-gap: 1.2rem; }
/* Colores plegados: 6 a la vista y el resto tras "Más colores" (details). */
.mas-colores { margin-top: 0.4rem; }
.mas-colores summary { cursor: pointer; color: var(--texto-2); font-size: 0.85rem; padding: 0.25rem 0; }
.mas-colores[open] summary { margin-bottom: 0.3rem; }
/* Pegado a la barra: que modo+tonos+tipografía se alcancen sin bajar. */
.apariencia-wrap { margin-top: -0.4rem; }
.apariencia-wrap form.panel { padding-top: 1rem; }
.tonos-dosc .grupo-tono + .grupo-tono { margin-top: 0.4rem; }
.tonos-dosc .grupo-tono-noche { border-left: 2px solid var(--dorado); padding-left: 1.2rem; }
@media (max-width: 640px) {
    .tonos-dosc { grid-template-columns: 1fr; }
    .tonos-dosc .grupo-tono-noche {
        border-left: none; padding-left: 0;
        border-top: 2px solid var(--dorado); padding-top: 0.9rem; margin-top: 1rem;
    }
}
.grupo-tono .tonos-titulo { margin-bottom: 0.35rem; }
.grupo-tono { transition: opacity 0.2s; }
html[data-theme="light"] .grupo-tono-noche,
html[data-theme="dark"] .grupo-tono-dia { opacity: 0.45; }
@media (prefers-color-scheme: dark) {
    html:not([data-theme="light"]):not([data-theme="dark"]) .grupo-tono-dia { opacity: 0.45; }
}
@media (prefers-color-scheme: light) {
    html:not([data-theme="light"]):not([data-theme="dark"]) .grupo-tono-noche { opacity: 0.45; }
}
.radios-apariencia .tono-muestra { width: 40px; height: 24px; font-size: 0.75rem; }
.nota-label { color: var(--texto-2); font-size: 0.78rem; font-weight: 400; }
.preview-nota { color: var(--texto-2); font-size: 0.85rem; margin-bottom: 0.8rem; }
/* Rótulo con la fuente de titulares: sin él, cambiar la tipografía apenas
   se notaba en la muestra (el título de la tarjeta usa la fuente del texto). */
.preview-rotulo {
    font-family: var(--f-display); font-weight: 900; font-style: italic;
    font-size: 1.5rem; line-height: 0.95; text-transform: uppercase;
    margin-bottom: 1.2rem;
}
.preview-tarjeta { pointer-events: none; }
@media (max-width: 900px) {
    .apariencia-wrap { flex-direction: column; align-items: center; }
    .apariencia-preview { position: static; flex: none; width: min(300px, 90%); margin: 0 auto 1.5rem; }
}

/* ===== Compartir mi tienda (ronda 13): tarjeta + link + personalización ===== */
.compartir-wrap { display: flex; gap: 2rem; align-items: flex-start; margin-top: 1.5rem; flex-wrap: wrap; }
.compartir-panel { flex: 1 1 380px; max-width: 560px; }
.compartir-preview { flex: 1 1 320px; max-width: 420px; position: sticky; top: 90px; }
.tarjeta-preview { width: 100%; border: 1.5px solid var(--texto); border-radius: 12px; box-shadow: 0 4px 10px var(--sombra); }
.fila-link { display: flex; gap: 0.5rem; align-items: center; }
.fila-link input { flex: 1; min-width: 0; font-size: 0.88rem; }
.botones-compartir { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 1rem; }
@media (max-width: 760px) { .compartir-preview { position: static; max-width: 100%; } }

/* ===== Fase 3: filtros de precio y paginación del home ===== */
.filtro-precio { max-width: 110px; }
.paginacion {
    display: flex; align-items: center; justify-content: center; gap: 1.2rem;
    margin-top: 2.5rem;
}
.paginacion .boton { margin-top: 0; }

/* ===== Selector de tono del fondo (botón paleta + panel desplegable) ===== */
.selector-tono { display: inline-flex; }
/* Anclado a la .topbar (sticky = posicionado): cae justo en la línea
   divisoria. El borde derecho lo alinea tema.js con el botón 🎨.
   Fondo blanco FIJO (no sigue el modo): los tonos nocturnos (negros) no se
   distinguían sobre panel oscuro. */
.panel-tonos {
    position: absolute; top: 100%; right: 12px; z-index: 200;
    min-width: 180px; padding: 0.6rem; border-radius: 0 0 12px 12px;
    background: #faf5e6; color: #0a0a0a; border: 1.5px solid #0a0a0a; border-top: none;
    box-shadow: 0 8px 20px var(--sombra);
    display: flex; flex-direction: column; gap: 0.3rem;
    /* Con 14 tonos el panel se salía de la pantalla: se muestran ~6 y el
       resto con scroll propio (feedback ronda 14). */
    max-height: min(48vh, 330px); overflow-y: auto; overscroll-behavior: contain;
}
.panel-tonos .tonos-titulo { color: #444444; }
.panel-tonos .tono-opcion { color: #0a0a0a; }
.panel-tonos .tono-opcion:hover { border-color: rgba(10,10,10,0.4); }
.panel-tonos .tono-opcion.activo { border-color: #0a0a0a; }
.panel-tonos .tono-muestra { border-color: rgba(10,10,10,0.35); }
/* display:flex de arriba pisaba el atributo hidden (regla de autor gana a
   la de user-agent): el panel "cerrado" seguía visible. */
.panel-tonos[hidden] { display: none; }
.tonos-titulo { font-size: 0.75rem; color: var(--texto-2); margin: 0 0 0.2rem; text-transform: uppercase; letter-spacing: 0.04em; }
.tono-opcion {
    display: flex; align-items: center; gap: 0.55rem; margin-top: 0;
    background: none; border: 1.5px solid transparent; border-radius: 8px;
    padding: 0.4rem 0.5rem; font-family: inherit; font-size: 0.85rem;
    color: var(--texto); cursor: pointer; text-align: left;
    /* flex-start: el inline-flex centrado de los botones base desalineaba
       las muestras de color (cada nombre de largo distinto). */
    justify-content: flex-start; width: 100%;
}
.tono-opcion:hover { border-color: var(--borde-hover); }
.tono-opcion.activo { border-color: var(--texto); font-weight: 700; }
/* Muestra ancha con "Aa": distingue tonos casi iguales (negros de noche). */
.tono-muestra {
    width: 44px; height: 26px; border-radius: 6px; flex-shrink: 0;
    border: 1.5px solid var(--borde-hover);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.8rem; font-weight: 700; line-height: 1;
}

/* ===== Tienda del vendedor: seamless. El color del vendedor lo pinta
   perfil.html sobre el body (todo el fondo bajo la barra); la zona ya no
   dibuja recuadro propio — solo hereda color y remapea tokens. ===== */
/* Barra y pie quedan del sitio (blanco/negro según modo), como marcos que
   encierran el color del vendedor, separados por líneas doradas. El logo
   "Inicio" no hereda el texto del vendedor: siempre tinta del sitio. */
body.tienda-vendedor .topbar {
    color: var(--texto);
    border-bottom: 2px solid var(--dorado);
    /* Resplandor suave para que la línea se lea más dorada (metálica). */
    box-shadow: 0 1px 8px rgba(212, 175, 55, 0.4);
}
body.tienda-vendedor footer {
    background: var(--bg);
    border-top: 2px solid var(--dorado);
    box-shadow: 0 -1px 8px rgba(212, 175, 55, 0.4);
}
.zona-tienda { max-width: 1100px; margin: 0 auto; position: relative; }

/* ===== Recortes decorativos libres (ronda 17): capa absoluta sobre la
   tienda; x/y en % y rotación en la var --rot. Para visitantes es solo
   decoración (sin eventos); en modo ✨ Decorar se vuelve manipulable. ===== */
.widgets-libres { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.widget-libre {
    position: absolute; transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
    max-width: 230px; font-size: 0.82rem; line-height: 1.35;
    filter: drop-shadow(0 3px 6px var(--sombra));
}
.widget-nota {
    background: var(--superficie); border: 1.5px solid var(--texto);
    border-radius: 3px; padding: 0.55rem 0.7rem;
    font-family: var(--f-mano); font-size: 1.05rem;
}
/* Cinta adhesiva arriba de la notita, como las tarjetas del mural. */
.widget-nota::before {
    content: ""; position: absolute; top: -8px; left: 50%;
    transform: translateX(-50%) rotate(-3deg);
    width: 46px; height: 14px; background: var(--tape1); opacity: 0.85;
}
/* Texto editable inline en modo decorar: pista visual sutil de que se
   puede escribir ahí mismo (sin prompt nativo). */
.widget-libre.editable [contenteditable] {
    outline: 1px dashed color-mix(in srgb, var(--texto) 40%, transparent);
    outline-offset: 2px; cursor: text; min-width: 30px; display: inline-block;
}
.widget-libre.editable [contenteditable]:focus {
    outline: 1.5px solid var(--accent, var(--dorado));
}
/* Sello: estampa circular real — borde sólido + anillo interior
   discontinuo (outline) y texto centrado, como timbre de tinta. */
.widget-sello {
    border: 2px solid var(--accent); color: var(--accent);
    outline: 1.5px dashed var(--accent); outline-offset: -7px;
    border-radius: 50%; width: 96px; height: 96px; padding: 0.55rem;
    display: flex; align-items: center; justify-content: center;
    text-align: center; font-weight: 800; text-transform: uppercase;
    letter-spacing: 0.08em; font-size: 0.6rem; line-height: 1.3;
    background: var(--bg);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    overflow: hidden; word-break: break-word;
}
.widget-opiniones {
    background: var(--bg); border: 1.5px solid var(--dorado);
    border-radius: 10px; padding: 0.6rem 0.8rem; min-width: 170px;
}
.widget-opiniones .widget-titulo {
    font-family: var(--f-display); font-weight: 900; font-style: italic;
    font-size: 0.92rem; margin: 0 0 0.3rem;
}
.widget-opiniones .widget-cita { margin: 0.2rem 0 0; color: var(--texto-2); font-size: 0.78rem; }
.widget-opiniones .widget-cita-vacia { opacity: 0.6; font-style: italic; }

/* Modo ✨ Decorar (solo dueño): la capa NUNCA recibe eventos (con
   pointer-events auto bloqueaba toda la tienda: botones y publicaciones
   muertos). Solo cada recorte editable recibe los suyos. */
.widget-libre.editable {
    pointer-events: auto; cursor: grab; z-index: 40;
    outline: 2px dashed var(--accent); outline-offset: 4px; touch-action: none;
}
.widget-libre.editable:active { cursor: grabbing; }
.widget-controles {
    position: absolute; top: -34px; left: 50%; transform: translateX(-50%);
    display: flex; gap: 3px;
}
.widget-controles button {
    width: 26px; height: 26px; padding: 0; margin-top: 0; border-radius: 50%;
    border: 1.5px solid var(--texto); background: var(--bg); color: var(--texto);
    font-size: 0.8rem; line-height: 1; cursor: pointer;
}
.barra-decorar {
    position: sticky; top: 70px; z-index: 50;
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
    background: var(--superficie); border: 1.5px solid var(--dorado);
    border-radius: 10px; padding: 0.6rem 0.8rem; margin-bottom: 1rem;
    font-size: 0.85rem;
}
.barra-decorar .boton { margin-top: 0; padding: 0.35rem 0.7rem; font-size: 0.8rem; }
.zona-tienda.con-tema {
    color: var(--texto-tienda, var(--texto));
    margin-top: 1rem;
}
/* Dentro de la zona con tema, los tokens del sitio se remapean a los del
   vendedor para que tarjetas/chips/botones hereden sus colores. */
.zona-tienda.con-tema {
    --bg: var(--bg-tienda); --superficie: var(--superficie-tienda);
    --borde: var(--borde-tienda); --texto: var(--texto-tienda);
    --texto-2: var(--texto2-tienda); --accent: var(--accent-tienda);
    --tape1: var(--tape1-tienda); --tape2: var(--tape2-tienda); --tape3: var(--tape3-tienda);
}
.cabecera-perfil {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 0.4rem; max-width: 640px; margin: 1rem auto 0;
}
.cabecera-perfil .avatar, .cabecera-perfil .avatar-placeholder { margin: 0 auto; }
.cabecera-perfil .contactos-perfil {
    display: flex; gap: 0.6rem; margin-top: 0.6rem; flex-wrap: wrap; justify-content: center;
}
.titulo-publicaciones { text-align: center; font-size: 1.1rem; margin-top: 2rem; }

/* ===== Editor de perfil (/mi-perfil): opciones a la izquierda SIN caja
   (el "papel" es el fondo del sitio) y vista previa sticky a la derecha
   que acompaña el scroll. Botones de acción sólidos y a lo ancho. ===== */
.perfil-wrap { display: flex; gap: 3rem; align-items: flex-start; justify-content: center; }
.form-perfil { flex: 0 1 560px; min-width: 0; margin: 1.5rem 0; }
.form-perfil button[type="submit"] { width: 100%; }
.perfil-preview { flex: 0 0 260px; position: sticky; top: 90px; margin-top: 1.5rem; }
@media (max-width: 900px) {
    .perfil-wrap { flex-direction: column; align-items: center; }
    .perfil-preview { position: static; flex: none; width: min(280px, 90%); margin: 0 auto 1rem; order: -1; }
    .form-perfil { flex: none; width: 100%; max-width: 560px; }
}
.preview-cabecera { margin-bottom: 1rem; }
.preview-avatar {
    display: block; width: 56px; height: 56px; border-radius: 50%; object-fit: cover;
    border: 1.5px solid currentColor; margin: 0 auto;
}
.preview-avatar-vacio { display: flex; align-items: center; justify-content: center; font-size: 1.4rem; }
.preview-bio { font-size: 0.75rem; opacity: 0.75; margin-top: 0.2rem; }

/* ===== Vista previa en vivo del editor de tienda (mi_perfil.html) ===== */
.tienda-preview {
    margin-top: 0.5rem; padding: 1.2rem 1rem 0.8rem; border-radius: 12px;
    border: 1.5px solid var(--borde); text-align: center;
    transition: background 0.25s, color 0.25s;
}
.preview-tarjeta {
    position: relative; display: inline-block; width: 150px;
}
.preview-tape {
    position: absolute; top: -8px; left: 50%; height: 16px; width: 56px;
    transform: translateX(-50%) rotate(-3deg); opacity: 0.88;
    background: #c24b3c; transition: background 0.25s;
}
.preview-foto {
    height: 90px; border-radius: 10px; border: 1.5px solid currentColor;
    display: flex; align-items: center; justify-content: center; font-size: 1.8rem;
}
.preview-titulo { font-weight: 700; font-size: 0.85rem; margin-top: 0.4rem; }
.preview-precio { font-family: var(--f-mano); font-size: 1.25rem; font-weight: 700; }
.preview-nombre { font-family: var(--f-display); font-weight: 900; font-style: italic; margin-top: 0.6rem; }

/* Corazón dentro del modal de vista rápida: píldora con etiqueta, más
   grande que el de las tarjetas para que se entienda qué hace. */
.pub-modal .fav-modal {
    position: absolute; top: 12px; right: 52px; z-index: 3;
    width: auto; height: 34px; border-radius: 999px;
    padding: 0 0.8rem; transform: none;
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-size: 1.1rem;
}
.pub-modal .fav-modal::after {
    content: "Favorito"; font-size: 0.78rem; font-weight: 700;
    color: var(--texto-2); -webkit-text-stroke: 0;
}
.pub-modal .fav-modal.activo::after { color: var(--rojo); content: "Guardado"; }
.pub-modal .fav-modal:hover { transform: scale(1.06); }
/* Botón "¿Aún está disponible?" del modal: mismo look que los tabs de
   contacto (es un form para poder POSTear el mensaje predefinido). */
.pub-modal .contacto-tabs form { flex: 1; min-width: 100px; margin: 0; display: flex; }
.pub-modal .contacto-tabs form button {
    flex: 1; margin-top: 0; text-align: center; padding: 0.6rem 0.5rem;
    border: 1.5px solid var(--texto); border-radius: 8px; font-size: 0.85rem; font-weight: 700;
    color: var(--texto); background: var(--superficie); cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.pub-modal .contacto-tabs form button:hover { background: var(--texto); color: var(--bg); }
.pub-modal .contacto-tabs form button b { display: block; margin-top: 0.25rem; font-size: 0.78rem; font-weight: 400; opacity: 0.8; }

/* Lápiz de edición en las tarjetas de la propia tienda (solo el dueño). */
.editar-mini {
    position: absolute; top: 6px; right: -8px; z-index: 3;
    width: 30px; height: 30px; border-radius: 50%;
    background: var(--bg); border: 1.5px solid var(--texto);
    display: flex; align-items: center; justify-content: center;
    font-size: 0.85rem; cursor: pointer;
    transform: rotate(6deg); transition: transform 0.15s;
}
.editar-mini:hover { transform: rotate(0deg) scale(1.12); }

/* ===== Ronda 15: ofertas en el chat, búsquedas guardadas, vacaciones ===== */
/* Oferta de precio en burbuja: monto grande + estado o botones del dueño. */
.burbuja-oferta {
    display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap;
    border: 1.5px dashed var(--dorado); border-radius: 10px;
    padding: 0.45rem 0.7rem; margin-bottom: 0.3rem;
}
.burbuja-oferta .oferta-monto { font-family: var(--f-mano); font-size: 1.25rem; font-weight: 700; color: var(--accent); }
.oferta-acciones { display: flex; gap: 0.4rem; }
.oferta-acciones form { margin: 0; }
.btn-oferta { margin-top: 0; padding: 0.3rem 0.75rem; font-size: 0.8rem; }
.btn-oferta.ok { background: var(--verde); border-color: var(--verde); color: #fff; }
.btn-oferta.no { background: none; border-color: var(--rojo); color: var(--rojo); }
.chip-oferta { font-size: 0.78rem; color: var(--texto-2); border: 1.5px solid var(--borde); border-radius: 999px; padding: 0.15rem 0.6rem; }
.chip-oferta.aceptada { color: var(--verde); border-color: var(--verde); font-weight: 700; }
.chip-oferta.rechazada { color: var(--rojo); border-color: var(--rojo); }
.oferta-details { margin-top: 0.8rem; }
.oferta-details summary { cursor: pointer; color: var(--texto-2); font-size: 0.9rem; }
.form-oferta { display: flex; gap: 0.5rem; margin-top: 0.5rem; align-items: center; flex-wrap: wrap; }
.form-oferta input { max-width: 320px; }

/* Botón "avisarme" bajo el buscador + lista de búsquedas guardadas. */
.guardar-busqueda { display: flex; align-items: center; gap: 0.8rem; margin-top: 0.6rem; }
.lista-busquedas { list-style: none; padding: 0; margin: 1rem 0 0; }
.busqueda-item {
    display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
    border: 1px solid var(--borde); border-radius: 10px; background: var(--superficie);
    padding: 0.6rem 0.9rem; margin-bottom: 0.5rem;
}
.busqueda-item form { margin: 0; }
.busqueda-desc { text-decoration: none; }
.busqueda-desc:hover { text-decoration: underline; }

/* Cartel de tienda en vacaciones (tienda pública). */
.cartel-vacaciones {
    border: 1.5px solid var(--dorado); background: var(--superficie);
    border-radius: 10px; padding: 0.8rem 1rem; margin-top: 1.2rem;
    font-weight: 600;
}

/* ===== Feature E: widgets de tienda reordenables + anuncio destacado ===== */
.banner-tienda {
    border: 2px solid var(--dorado); border-radius: 12px;
    background: var(--superficie); padding: 0.9rem 1.2rem; margin-top: 1.5rem;
}
.banner-tienda .banner-texto { font-size: 1.05rem; font-weight: 700; margin: 0; }
/* Modo ordenar: la sección se marca y muestra su barra de flechas. */
.widget-tienda.ordenable {
    outline: 2px dashed var(--dorado); outline-offset: 6px;
    border-radius: 8px; margin-top: 1.8rem;
}
.orden-controles { display: flex; gap: 0.5rem; margin: 0.3rem 0 0.5rem; }
.orden-controles button {
    margin-top: 0; padding: 0.3rem 0.9rem; font-size: 0.8rem;
    background: var(--dorado); border-color: var(--dorado); color: #1a1a1a;
}

/* ===== Feature C: editor en vivo de la tienda (panel flotante) ===== */
.editor-vivo {
    position: fixed; top: 80px; right: 12px; z-index: 8000;
    width: min(320px, calc(100vw - 24px)); max-height: calc(100vh - 100px);
    overflow-y: auto; background: #faf5e6; color: #0a0a0a;
    border: 1.5px solid #0a0a0a; border-radius: 14px; padding: 0.9rem 1rem;
    box-shadow: 0 16px 36px rgba(0,0,0,0.35);
}
.editor-vivo .editor-titulo { font-weight: 700; margin: 0 0 0.5rem; }
/* X de cierre: sticky para que siga visible al scrollear el panel. */
.editor-vivo .editor-cerrar {
    position: sticky; top: -0.4rem; float: right; z-index: 2;
    margin: -0.2rem -0.3rem 0 0.5rem; padding: 0.1rem 0.45rem;
    background: #faf5e6; color: #0a0a0a; border: 1.5px solid #0a0a0a;
    border-radius: 50%; font-size: 0.9rem; line-height: 1.4; cursor: pointer;
}
.editor-vivo .editor-cerrar:hover { background: #0a0a0a; color: #faf5e6; }
.editor-vivo .tonos-titulo { color: #444444; margin-top: 0.6rem; }
.editor-swatches { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.editor-swatch {
    width: 30px; height: 30px; border-radius: 50%; padding: 0; margin-top: 0;
    border: 2px solid rgba(10,10,10,0.25); cursor: pointer;
}
.editor-swatch.activo { border-color: #0a0a0a; box-shadow: 0 0 0 2px #faf5e6, 0 0 0 4px #0a0a0a; }
.editor-vivo .bgmode-btn { background: #ffffff; color: #0a0a0a; border-color: rgba(10,10,10,0.4); font-size: 0.72rem; padding: 0.3rem 0.5rem; }
.editor-vivo .bgmode-btn.active { background: #0a0a0a; color: #ffffff; }
.editor-vivo input {
    background: #ffffff; color: #0a0a0a; border-color: rgba(10,10,10,0.35);
    font-size: 0.85rem; margin-top: 0.2rem;
}
.editor-acciones { display: flex; gap: 0.5rem; margin-top: 0.9rem; }
.editor-acciones button { margin-top: 0; padding: 0.45rem 1rem; font-size: 0.85rem; }
.editor-acciones .secundario { background: none; color: #0a0a0a; border-color: #0a0a0a; }

/* ---------- Ronda 19: forma de las tarjetas (body.forma-*) ----------
   La clase la pone base.html: la de la tienda si su dueño eligió una, o el
   default global de /admin/sitio. "clasica" no emite clase (look original). */
body.forma-suave .tarjeta .foto,
body.forma-suave .tarjeta .sin-foto { border-radius: 14px; }
body.forma-redondeada .tarjeta .foto,
body.forma-redondeada .tarjeta .sin-foto { border-radius: 26px; }
body.forma-redondeada .tarjeta .cat-tag { border-radius: 999px; padding-left: 1rem; }
/* Polaroid: marco blanco grueso con "mentón" abajo, foto casi sin radio.
   El marco es blanco de verdad (como la foto instantánea) en ambos modos. */
body.forma-polaroid .tarjeta .foto,
body.forma-polaroid .tarjeta .sin-foto {
    border-radius: 2px; border: 7px solid #ffffff; border-bottom-width: 24px;
    box-shadow: 0 3px 9px var(--sombra);
}
body.forma-polaroid .tarjeta .sin-foto { background-color: var(--superficie); }
/* Sello: borde punteado tipo estampilla. */
body.forma-sello .tarjeta .foto,
body.forma-sello .tarjeta .sin-foto {
    border-radius: 8px; border: 2px dashed var(--texto);
    outline: 4px solid var(--bg); outline-offset: -6px;
}

/* ---------- Ronda 19: color de bordes global (html[data-borde]) ----------
   Lo pone /admin/sitio; va DESPUÉS de los tonos para ganarles la cascada
   (misma especificidad, manda el orden). Cada clave define su par día/noche. */
:root[data-borde="dorado"] { --dia-borde: #d4af37; --noche-borde: #8a6d1a; }
:root[data-borde="plata"]  { --dia-borde: #9aa3ad; --noche-borde: #5a636d; }
:root[data-borde="negro"]  { --dia-borde: #1a1a1a; --noche-borde: #d8d8d8; }
:root[data-borde="rosa"]   { --dia-borde: #d1477f; --noche-borde: #a8477f; }
:root[data-borde="azul"]   { --dia-borde: #2f5d8a; --noche-borde: #4a7fb5; }
:root[data-borde="verde"]  { --dia-borde: #3c7a30; --noche-borde: #4faa78; }
:root[data-borde="morado"] { --dia-borde: #6b3fa0; --noche-borde: #9a76d0; }
.editor-vivo select {
    background: #ffffff; color: #0a0a0a; border: 2px solid rgba(10,10,10,0.35);
    border-radius: 6px; font-size: 0.85rem; margin-top: 0.2rem; padding: 0.35rem 0.5rem;
    width: 100%;
}

/* Minis de las decoraciones animadas en el editor (versión quieta). */
.bgmode-mini.mini-nubes {
    background-image:
        radial-gradient(ellipse 14px 5px at 30% 40%, var(--texto-2) 0 55%, transparent 80%),
        radial-gradient(ellipse 10px 4px at 72% 65%, var(--texto-2) 0 55%, transparent 80%);
}
.bgmode-mini.mini-luna {
    /* Luna + 3 estrellas puntuales (la grilla de puntitos anterior se
       confundía con el patrón de motas). */
    background-image:
        radial-gradient(circle 5px at 68% 40%, #d4af37 0 4.5px, transparent 5px),
        radial-gradient(circle 1px at 22% 28%, var(--texto-2) 0 1px, transparent 1.4px),
        radial-gradient(circle 1px at 36% 64%, var(--texto-2) 0 1px, transparent 1.4px),
        radial-gradient(circle 1px at 84% 72%, var(--texto-2) 0 1px, transparent 1.4px);
}
.bgmode-mini.mini-lluvia {
    background-image:
        radial-gradient(circle 4px at 74% 26%, #f2b53c 0 3.5px, transparent 4px),
        radial-gradient(ellipse 1px 5px at 50% 50%, var(--texto-2) 0 70%, transparent 100%);
    background-size: 100% 100%, 9px 12px;
}
.bgmode-mini.mini-lluvia_noche {
    background-image:
        radial-gradient(circle 4px at 74% 26%, #d4af37 0 3.5px, transparent 4px),
        radial-gradient(ellipse 1px 5px at 50% 50%, var(--texto-2) 0 70%, transparent 100%);
    background-size: 100% 100%, 9px 12px;
}
.bgmode-mini.mini-nieve {
    background-image:
        radial-gradient(var(--texto-2) 1.6px, transparent 2px),
        radial-gradient(var(--texto-2) 1px, transparent 1.4px);
    background-size: 14px 14px, 9px 9px;
    background-position: 0 0, 5px 6px;
}
.bgmode-mini.mini-estrellas {
    background-image:
        radial-gradient(#d4af37 1.2px, transparent 1.6px),
        radial-gradient(var(--texto-2) 0.8px, transparent 1.2px);
    background-size: 15px 15px, 9px 9px;
    background-position: 3px 4px, 0 0;
}

/* ---------- Ronda 20 ---------- */
.bgmode-mini.mini-hojas {
    background-image:
        radial-gradient(ellipse 3px 5px at 30% 35%, #c9762a 0 60%, transparent 90%),
        radial-gradient(ellipse 2.5px 4px at 70% 65%, #a8552a 0 60%, transparent 90%);
}
.bgmode-mini.mini-burbujas {
    background-image:
        radial-gradient(circle 4px at 32% 55%, transparent 0 2.4px, var(--texto-2) 2.8px 3.6px, transparent 4px),
        radial-gradient(circle 2.6px at 72% 35%, transparent 0 1.4px, var(--texto-2) 1.7px 2.3px, transparent 2.6px);
}

/* ---------- Ronda 21 ---------- */
.bgmode-mini.mini-petalos {
    background-image:
        radial-gradient(ellipse 3px 4px at 30% 40%, #f29ab5 0 60%, transparent 90%),
        radial-gradient(ellipse 2.5px 3.5px at 70% 65%, #f6b7c8 0 60%, transparent 90%);
}
.bgmode-mini.mini-luciernagas {
    background-image:
        radial-gradient(circle 2px at 30% 40%, #e3c34f 0 1.4px, transparent 2px),
        radial-gradient(circle 1.5px at 72% 62%, #e3c34f 0 1px, transparent 1.5px);
}

/* Diálogos propios (dialogo.js): caja abajo con el tema activo, en vez del
   alert() nativo "nypau.com dice...". El velo cubre todo pero es invisible:
   tocar fuera cierra (aceptar en avisos, cancelar en confirmaciones). */
.dialogo-velo {
    position: fixed; inset: 0; z-index: 300;
    display: flex; align-items: flex-end; justify-content: center;
    padding: 0 1rem 9vh; background: rgba(0, 0, 0, 0.12);
}
.dialogo-tienda {
    background: var(--superficie); color: var(--texto);
    border: 1px solid var(--borde); border-top: 3px solid var(--accent, var(--dorado));
    border-radius: 12px; max-width: 430px; width: 100%;
    padding: 1rem 1.2rem; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.25);
    animation: subir-dialogo 0.22s ease-out;
}
.dialogo-tienda p { margin: 0 0 0.8rem; font-size: 0.95rem; line-height: 1.45; }
.dialogo-botones { display: flex; gap: 0.6rem; justify-content: flex-end; }
.dialogo-botones .boton { margin-top: 0; padding: 0.45rem 1.1rem; font-size: 0.85rem; }
@keyframes subir-dialogo {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}
/* Barra de cambios sin guardar del editor en vivo: chica, abajo, sin velo
   (la página sigue usable); singleton en tienda_editor.js. */
.barra-cambios {
    position: fixed; bottom: 5vh; left: 50%; transform: translateX(-50%);
    z-index: 250; display: flex; align-items: center; gap: 0.7rem;
    background: var(--superficie); color: var(--texto);
    border: 1px solid var(--borde); border-left: 3px solid var(--accent, var(--dorado));
    border-radius: 10px; padding: 0.5rem 0.9rem; font-size: 0.85rem;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.25); white-space: nowrap;
    /* Keyframes propios: subir-dialogo pisaba el translateX(-50%) del
       centrado y la barra nacía corrida a la derecha y saltaba al centro. */
    animation: subir-barra 0.22s ease-out;
}
@keyframes subir-barra {
    from { opacity: 0; transform: translate(-50%, 16px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}
.barra-cambios .boton { margin-top: 0; padding: 0.35rem 0.8rem; font-size: 0.8rem; }

/* Buscador dentro de la tienda (ronda 20). */
.buscador-tienda {
    display: flex; gap: 0.5rem; align-items: center; justify-content: center;
    margin: 0.3rem auto 1.1rem; max-width: 480px;
}
.buscador-tienda input { flex: 1; margin-top: 0; }
.buscador-tienda button { margin-top: 0; padding: 0.45rem 1rem; font-size: 0.85rem; }
.buscador-tienda .limpiar-busqueda { text-decoration: underline; white-space: nowrap; }
.aviso-fijadas { text-align: center; color: var(--rojo); }

/* Chip de aviso fijado (ronda 20): estampilla junto a la cinta. */
.tarjeta .chip-fijada {
    position: absolute; top: -12px; right: 14px; z-index: 3;
    font-size: 1.05rem; transform: rotate(14deg);
    filter: drop-shadow(0 1px 1px var(--sombra));
}

/* Ajustes del modal (ronda 20, pedidos del usuario): precio más chico,
   "Ver completa" en la fila del vendedor (contacto sube), y botones de
   contacto con el color de acento del tono elegido (como el resto). */
.pub-modal .precio-modal { font-size: clamp(1.1rem, 3.5vw, 1.4rem); }
html[data-fuente="elegante"] .pub-modal .precio-modal,
html[data-fuente="maquina"] .pub-modal .precio-modal,
html[data-fuente="redondeada"] .pub-modal .precio-modal { font-size: clamp(1.3rem, 4vw, 1.65rem); }
.pub-modal .vendedor-fila .ver-completa {
    margin: 0 0 0 auto; padding: 0.35rem 0.7rem; font-size: 0.75rem;
    white-space: nowrap; flex-shrink: 0;
}
.pub-modal .contacto-tabs a,
.pub-modal .contacto-tabs form button {
    border-color: var(--accent); color: var(--accent);
}
.pub-modal .contacto-tabs a b,
.pub-modal .contacto-tabs form button b { font-size: 0.72rem; }
.pub-modal .contacto-tabs a:hover,
.pub-modal .contacto-tabs form button:hover { background: var(--accent); color: var(--bg); }
.pub-modal .vendedor-fila { flex-wrap: wrap; }

/* ---------- Decoraciones animadas v2 (partículas JS, ronda 20) ----------
   deco_animada.js genera elementos sueltos con posición/tamaño/ritmo
   aleatorios (misma técnica que los recortes cayendo de mural.js, que sí se
   ven bien) dentro de #scrapsFall. Los gradientes de fondo de la v1 no
   parecían clima de verdad. Colores opacos mezclados con el fondo para que
   las superposiciones no dejen costuras. */
/* Nubes v3: cúmulo de lóbulos circulares (hijos <b>) sobre una base
   alargada, suavizado con blur — la silueta de 3 círculos duros no parecía
   nube. El color se mezcla con el fondo para funcionar en día y noche. */
.nube-deco {
    position: absolute; left: -36vw;
    /* La nube completa es un SVG (nubeSvg, con blur y sombra internos). */
    background: center / contain no-repeat;
    animation: pasar-nube linear infinite;
}
@keyframes pasar-nube { to { transform: translateX(180vw); } }
/* Luna v3: disco dorado con borde definido (visible también sobre fondo
   claro — la v2 era crema sobre blanco), cráteres (hijos <b>) y halo. */
.luna-deco {
    position: absolute; border-radius: 50%;
    background: radial-gradient(circle at 32% 30%, #fff9e3, #f5e6a8 45%, #e3c76f 78%, #cfae52);
    border: 1px solid color-mix(in srgb, var(--texto) 35%, #cfae52);
    box-shadow: 0 0 0 10px rgba(240, 214, 128, 0.12),
                0 0 46px 18px rgba(240, 214, 128, 0.4);
    animation: flotar-luna ease-in-out infinite alternate;
}
.luna-deco b {
    position: absolute; border-radius: 50%;
    background: rgba(160, 132, 62, 0.3);
    box-shadow: inset 1px 1px 2px rgba(110, 88, 38, 0.4);
}
@keyframes flotar-luna { to { transform: translateY(9vh); } }
/* Lluvia v3: gotas finas inclinadas + salpicaduras a ras de suelo +
   charcos que se van formando (crecen una vez y quedan brillando). */
.gota-lluvia {
    position: absolute; top: -30px; width: 1.5px; border-radius: 999px;
    /* Agua azul-celeste con puntita brillante (más "gota", menos rayón). */
    background: linear-gradient(to bottom, transparent 10%,
                rgba(126, 178, 226, 0.65) 55%, #a9d0f0 92%, #e8f4ff);
    animation: caer-lluvia linear infinite;
}
@keyframes caer-lluvia {
    from { transform: translate(1.5vh, -6vh) rotate(7deg); }
    to   { transform: translate(-7vh, 106vh) rotate(7deg); }
}
.gota-lluvia.gota-noche {
    background: linear-gradient(to bottom, transparent 12%,
                color-mix(in srgb, #aac6e8 70%, var(--texto)));
}
.salpicadura {
    position: absolute; width: 16px; height: 6px; border-radius: 50%;
    border: 1.5px solid rgba(150, 196, 236, 0.75);
    border-top-color: transparent; opacity: 0;
    animation: salpicar ease-out infinite;
}
@keyframes salpicar {
    0%   { transform: scale(0.15); opacity: 0; }
    30%  { opacity: 0.55; }
    100% { transform: scale(1.3); opacity: 0; }
}
.charco {
    position: absolute;
    transform: scaleX(0);
    /* La mancha de agua es un SVG irregular (charcoSvg en deco_animada.js)
       con gradiente de cielo y brillos horizontales. */
    background: center / 100% 100% no-repeat;
}
/* Ondas dentro del charco: anillo que se expande y muere, en bucle. */
.charco::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 60%; height: 60%; border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.4);
    animation: onda-charco 2.6s ease-out infinite;
}
@keyframes onda-charco {
    from { transform: translate(-50%, -50%) scale(0.15); opacity: 0.7; }
    to   { transform: translate(-50%, -50%) scale(1.5); opacity: 0; }
}
.charco.charco-noche { /* el color viene del SVG (charcoSvg noche) */ }
@keyframes formar-charco { to { transform: scaleX(1); } }
@keyframes brillo-charco { from { opacity: 0.6; } to { opacity: 0.95; } }
/* Cielo de la lluvia: velo que aclara (sol) u oscurece (luna) pulsando
   lento — el "clima" respira sin tocar el contenido (queda detrás). */
.cielo-lluvia { position: absolute; inset: 0; animation: respira-cielo ease-in-out 14s infinite alternate; }
.cielo-lluvia.cielo-sol {
    background: linear-gradient(to bottom, rgba(255, 236, 170, 0.22), rgba(255, 244, 200, 0.05) 55%, transparent);
}
.cielo-lluvia.cielo-luna {
    background: linear-gradient(to bottom, rgba(16, 24, 52, 0.32), rgba(18, 26, 54, 0.12) 60%, rgba(10, 16, 38, 0.2));
}
@keyframes respira-cielo { from { opacity: 0.45; } to { opacity: 1; } }
/* Sol: disco cálido con halo grande en capas (todo lo que da luz, con halo). */
.sol-deco {
    position: absolute; border-radius: 50%;
    background: radial-gradient(circle at 38% 34%, #fff6c9, #ffd75e 55%, #f2b53c);
    border: 1px solid color-mix(in srgb, var(--texto) 22%, #f2b53c);
    box-shadow: 0 0 0 12px rgba(255, 215, 94, 0.14),
                0 0 34px 14px rgba(255, 215, 94, 0.45),
                0 0 90px 40px rgba(255, 215, 94, 0.18);
    animation: flotar-luna ease-in-out infinite alternate;
}
/* Cometa: cabeza brillante + cola con degradado, cruza lentísimo. */
.cometa {
    position: absolute; left: -30vw; width: 110px; height: 2px;
    border-radius: 999px;
    background: linear-gradient(to left, #fff8dc, rgba(255, 244, 200, 0.35) 45%, transparent);
    transform: rotate(6deg);
    animation: pasar-cometa linear infinite;
}
.cometa::before {
    content: ""; position: absolute; right: -3px; top: -2.5px;
    width: 7px; height: 7px; border-radius: 50%;
    background: #fff8dc;
    box-shadow: 0 0 10px 4px rgba(255, 244, 200, 0.75);
}
@keyframes pasar-cometa { to { transform: translateX(170vw) rotate(6deg); } }
/* Estrella fugaz: trazo que aparece, cruza rápido y muere; el resto del
   ciclo queda invisible (por eso se ve "de vez en cuando"). */
.fugaz {
    position: absolute; width: 90px; height: 1.5px; border-radius: 999px;
    background: linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0.3) 50%, transparent);
    box-shadow: 0 0 6px 1px rgba(255, 255, 255, 0.4);
    opacity: 0;
    transform: rotate(24deg);
    animation: caer-fugaz linear infinite;
}
@keyframes caer-fugaz {
    0%   { transform: translate(0, 0) rotate(24deg); opacity: 0; }
    2%   { opacity: 0.9; }
    9%   { transform: translate(34vw, 15vw) rotate(24deg); opacity: 0; }
    100% { transform: translate(34vw, 15vw) rotate(24deg); opacity: 0; }
}
/* Lago de las luciérnagas: mancha de agua SVG (charcoSvg tonos bosque)
   con halo suave que respira. */
.lago {
    position: absolute;
    background: center / 100% 100% no-repeat;
    filter: drop-shadow(0 0 14px rgba(159, 232, 216, 0.35));
    animation: brillo-charco 4.5s ease-in-out infinite alternate;
}
/* Nieve: copos con vaivén lateral (keyframes intermedios) y brillo suave. */
.copo-nieve {
    position: absolute; top: -14px; border-radius: 50%;
    background: radial-gradient(circle at 45% 40%,
                color-mix(in srgb, #ffffff 85%, var(--texto)),
                color-mix(in srgb, #dfe9f5 60%, var(--texto)) 65%, transparent);
    box-shadow: 0 0 6px 1px rgba(255, 255, 255, 0.4);
    animation: caer-nieve linear infinite;
}
@keyframes caer-nieve {
    from { transform: translate(0, -4vh); }
    25%  { transform: translate(2.2vw, 24vh); }
    50%  { transform: translate(-1.8vw, 50vh); }
    75%  { transform: translate(2vw, 76vh); }
    to   { transform: translate(-1.2vw, 106vh); }
}
/* Cristales de 6 brazos (SVG) en primer plano: giran mientras caen —
   caer-nieve mueve transform y girar-copo la propiedad rotate, sin pelear. */
.copo-nieve.copo-cristal {
    border-radius: 0; box-shadow: none;
    background: center / contain no-repeat;
    filter: drop-shadow(0 0 4px rgba(220, 236, 255, 0.6));
    animation: caer-nieve linear infinite, girar-copo linear infinite;
}
@keyframes girar-copo { from { rotate: 0deg; } to { rotate: 360deg; } }
/* Globos: suben bamboleándose (vaiven-globo mueve translate, la subida va
   en subir-globo con top) y revientan al tocarlos. */
.globo-deco {
    position: absolute; bottom: -140px;
    background: center / contain no-repeat;
    animation: subir-globo linear infinite, vaiven-globo ease-in-out infinite alternate;
    pointer-events: auto; cursor: pointer;
    filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.12));
}
@keyframes subir-globo { from { translate: 0 0; } to { translate: 0 -128vh; } }
@keyframes vaiven-globo { from { rotate: -6deg; } to { rotate: 6deg; } }
.globo-deco.pop { animation: reventar 0.3s ease-out forwards; }
/* Mariposas: vagan por waypoints (translate) mientras aletean (transform
   scaleX pulsante — propiedades separadas, sin conflicto). */
.mariposa-deco {
    position: absolute;
    background: center / contain no-repeat;
    animation: vagar-luci ease-in-out infinite, aletear ease-in-out infinite alternate;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.15));
}
@keyframes aletear {
    from { transform: scaleX(1) rotate(-4deg); }
    to   { transform: scaleX(0.45) rotate(6deg); }
}
/* Mariposa pasajera (escena hojas): cruza la pantalla una vez y se va. */
.mariposa-deco.mariposa-pasa {
    left: -8vw;
    animation-name: cruzar-pantalla, aletear;
    animation-timing-function: ease-in-out, ease-in-out;
    animation-iteration-count: 1, infinite;
    animation-direction: normal, alternate;
}
@keyframes cruzar-pantalla {
    0%   { translate: 0 0; }
    30%  { translate: 34vw -7vh; }
    60%  { translate: 68vw 5vh; }
    100% { translate: 120vw -4vh; }
}

/* Aurora austral: cortinas de luz difusas ondulando (skew + deriva). */
.aurora-banda {
    position: absolute; top: -6vh; height: 52vh; width: 34vw; left: 8vw;
    border-radius: 0 0 50% 50%;
    background: linear-gradient(to bottom, rgba(94, 227, 160, 0.5),
                rgba(94, 227, 190, 0.18) 55%, transparent);
    filter: blur(26px);
    animation: ondear-aurora ease-in-out infinite alternate;
}
.aurora-banda.aurora-2 {
    left: 36vw; width: 30vw; height: 60vh;
    background: linear-gradient(to bottom, rgba(140, 120, 235, 0.42),
                rgba(150, 120, 235, 0.14) 55%, transparent);
}
.aurora-banda.aurora-3 {
    left: 62vw; width: 28vw; height: 46vh;
    background: linear-gradient(to bottom, rgba(80, 200, 235, 0.4),
                rgba(80, 200, 235, 0.12) 55%, transparent);
}
@keyframes ondear-aurora {
    from { transform: skewX(-8deg) translateX(-4vw) scaleY(1); opacity: 0.65; }
    50%  { opacity: 1; }
    to   { transform: skewX(9deg) translateX(4vw) scaleY(1.14); opacity: 0.75; }
}
/* Estrellas: puntitos que titilan (algunas doradas, más grandes). */
.estrella-deco {
    position: absolute; border-radius: 50%;
    background: color-mix(in srgb, var(--texto) 55%, #e8ddb0);
    box-shadow: 0 0 5px 1px color-mix(in srgb, #e8ddb0 45%, transparent);
    animation: titilar ease-in-out infinite alternate;
}
.estrella-deco.dorada { background: var(--dorado, #d4af37); box-shadow: 0 0 8px 2px rgba(212, 175, 55, 0.65); }
@keyframes titilar {
    from { opacity: 0.15; transform: scale(0.8); }
    to   { opacity: 0.9;  transform: scale(1.15); }
}
/* Hojas de otoño y pétalos: forma REAL dibujada en SVG (data URI desde
   deco_animada.js, con nervaduras/brillo) — el cuadrado con border-radius
   no parecía hoja. */
.hoja-deco {
    position: absolute; top: -30px;
    background: center / contain no-repeat;
    animation: caer-hoja linear infinite;
}
@keyframes caer-hoja {
    from { transform: translate(0, -5vh) rotate(0deg); }
    25%  { transform: translate(4vw, 24vh) rotate(85deg); }
    50%  { transform: translate(-3vw, 50vh) rotate(170deg); }
    75%  { transform: translate(4vw, 76vh) rotate(255deg); }
    to   { transform: translate(-2vw, 106vh) rotate(340deg); }
}
/* Mundo del motor FisicaDeco (fisica.js, ronda 25): capa fija al borde
   inferior del viewport, por encima del contenido, con PERSPECTIVA (cada
   pieza es un plano 3D fino rotando en x/y/z). Las piezas se mueven SOLO
   por transform desde el rAF del motor — nada de transiciones de posición.
   Solo la opacidad transiciona, para el fade de despedida. */
.suelo-fisico {
    position: fixed; left: 0; right: 0; bottom: 0; height: 0;
    z-index: 60; pointer-events: none;
    perspective: 700px; perspective-origin: 50% 100%;
}
/* Variante WebGL (ronda 26): un solo canvas a pantalla completa; la
   perspectiva la proyecta el shader/CPU, no CSS. */
.suelo-fisico.lienzo-fisico {
    top: 0; height: 100%; width: 100%; display: block; perspective: none;
}
.suelo-fisico .pieza-suelo {
    position: absolute; left: 0; bottom: 4px;
    background: center / contain no-repeat;
    will-change: transform;
    transition: opacity 2.2s ease;
    pointer-events: auto; cursor: pointer;
}
.suelo-fisico .se-va { opacity: 0 !important; pointer-events: none; }
/* Burbujas: anillos con brillo interior subiendo desde abajo. */
.burbuja-deco {
    position: absolute; bottom: -40px; border-radius: 50%;
    border: 1.5px solid color-mix(in srgb, var(--texto) 35%, #7fb3d1);
    box-shadow: inset 2px -2px 4px rgba(255, 255, 255, 0.3);
    animation: subir-burbuja linear infinite;
    pointer-events: auto; cursor: pointer;
}
@keyframes subir-burbuja {
    from { transform: translate(0, 0); opacity: 0.65; }
    to   { transform: translate(3vw, -118vh); opacity: 0.15; }
}
/* Al tocarla revienta: deco_animada.js la congela donde está y el pop
   reemplaza la animación de subida. */
.burbuja-deco.pop { animation: reventar 0.32s ease-out forwards; }
@keyframes reventar {
    0%   { transform: scale(1); opacity: 0.7; }
    60%  { transform: scale(1.55); opacity: 0.4; }
    100% { transform: scale(1.95); opacity: 0; }
}
/* Confeti cayendo (ronda 24): cintitas SVG que bailan al caer mientras
   "titilan" girando sobre su eje (dos animaciones independientes). */
.confeti-deco {
    position: absolute; top: -26px;
    background: center / contain no-repeat;
    animation: caer-confeti linear infinite, girar-confeti ease-in-out infinite alternate;
}
@keyframes caer-confeti {
    from { translate: 0 -5vh; rotate: 0deg; }
    25%  { translate: 3.5vw 24vh; rotate: 160deg; }
    50%  { translate: -3vw 50vh; rotate: 300deg; }
    75%  { translate: 3.5vw 76vh; rotate: 480deg; }
    to   { translate: -2vw 106vh; rotate: 640deg; }
}
@keyframes girar-confeti {
    0%   { transform: scaleX(1); }
    50%  { transform: scaleX(0.15); }
    100% { transform: scaleX(1); }
}
/* Pétalos sakura: SVG con muesca, caen con vaivén suave. */
.petalo-deco {
    position: absolute; top: -26px;
    background: center / contain no-repeat;
    animation: caer-petalo linear infinite;
}
@keyframes caer-petalo {
    from { transform: translate(0, -4vh) rotate(0deg); }
    25%  { transform: translate(3vw, 24vh) rotate(60deg); }
    50%  { transform: translate(-2.5vw, 50vh) rotate(125deg); }
    75%  { transform: translate(3vw, 76vh) rotate(200deg); }
    to   { transform: translate(-1.5vw, 106vh) rotate(280deg); }
}
/* Luciérnagas: puntitos que vagan por waypoints propios (variables CSS por
   partícula) mientras el brillo pulsa — dos animaciones sin conflicto:
   vagar mueve `translate`, brillar toca opacidad/halo. */
.luciernaga-deco {
    position: absolute; border-radius: 50%;
    /* Núcleo caliente casi blanco que se apaga hacia el borde: bichito de
       luz, no un punto plano. */
    background: radial-gradient(circle at 45% 40%, #fffbe0 25%, #ffe97a 62%,
                rgba(255, 233, 122, 0.35));
    animation: vagar-luci ease-in-out infinite, brillo-luci ease-in-out infinite alternate;
}
@keyframes vagar-luci {
    0%   { translate: 0 0; }
    25%  { translate: var(--x1, 6vw) var(--y1, -6vh); }
    50%  { translate: var(--x2, -8vw) var(--y2, 5vh); }
    75%  { translate: var(--x3, 5vw) var(--y3, 8vh); }
    100% { translate: 0 0; }
}
@keyframes brillo-luci {
    from { opacity: 0.12; box-shadow: 0 0 3px 1px rgba(255, 233, 122, 0.2); }
    to   { opacity: 1; box-shadow: 0 0 16px 6px rgba(255, 233, 122, 0.8),
                                   0 0 38px 14px rgba(255, 233, 122, 0.3); }
}
/* Las grandes de primer plano: núcleo casi blanco y halo aún mayor. */
.luciernaga-deco.luci-grande {
    background: radial-gradient(circle, #fffbe0 30%, #ffe97a);
}
@keyframes brillo-luci-grande {
    from { opacity: 0.2; box-shadow: 0 0 6px 2px rgba(255, 233, 122, 0.3); }
    to   { opacity: 1; box-shadow: 0 0 22px 9px rgba(255, 240, 150, 0.85),
                                   0 0 52px 20px rgba(255, 233, 122, 0.35); }
}
.luciernaga-deco.luci-grande {
    animation-name: vagar-luci, brillo-luci-grande;
}

/* Con patrones estáticos de fondo (motas/rayas/cuadrícula/confeti), el
   encabezado de la tienda y los botones del dueño llevan placa con LEVE
   traslucidez: el patrón queda detrás y se insinúa, pero el texto se lee
   (la placa 100% sólida tapaba el patrón y quedaba fea). */
body:is(.deco-motas, .deco-rayas, .deco-cuadricula) .cabecera-perfil,
body:is(.deco-motas, .deco-rayas, .deco-cuadricula) .acciones-dueno {
    background: color-mix(in srgb, var(--bg) 86%, transparent);
    border-radius: 14px;
    box-shadow: 0 0 0 12px color-mix(in srgb, var(--bg) 86%, transparent);
}
/* Confeti: placa más translúcida todavía — que la fiesta se vea a través
   del nombre (86% tapaba demasiado). */
body.deco-confeti .cabecera-perfil,
body.deco-confeti .acciones-dueno {
    background: color-mix(in srgb, var(--bg) 72%, transparent);
    border-radius: 14px;
    box-shadow: 0 0 0 12px color-mix(in srgb, var(--bg) 72%, transparent);
}

/* =====================================================================
   DISEÑOS DE TIENDA (ronda 21) — body.diseno-<clave>, ver temas.DISENOS.
   A diferencia de deco-/forma-, que PINTAN, estos cambian la ESTRUCTURA:
   cómo se reparten los avisos. Cada uno es un registro distinto del mismo
   tablón de papel, no una identidad nueva: la cinta, el tag de categoría y
   la sombra de papel se conservan salvo donde estorban.
   'mural' es el layout original y no emite clase (no hay reglas acá).
   Solo aplican dentro de la tienda de un vendedor (body.tienda-vendedor).
   ===================================================================== */

/* --- REVISTA: el primer aviso es la portada -------------------------- */
/* El vendedor destaca UNA pieza (la fijada queda primera) y el resto sigue
   en grilla.
   La clave es `align-content: start` + una última fila 1fr: sin eso las
   filas se reparten el alto de la foto y el texto queda desparramado con
   huecos enormes entre título, precio y comuna. Acá el texto se agrupa
   arriba y la fila 1fr se come el sobrante. */
body.diseno-revista .grilla > .tarjeta:first-child {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    /* Filas 1fr arriba y abajo: centran verticalmente el bloque de texto. Con
       align-content:start el título quedaba pegado al borde superior y dejaba
       un hueco de aire enorme debajo de la comuna. */
    grid-template-rows: 1fr auto auto auto auto 1fr;
    column-gap: 1.8rem;
    height: 270px;
    margin-bottom: 1.4rem;
    border-bottom: 1.5px dashed var(--borde);
    padding-bottom: 1.4rem;
}
/* La foto ocupa el alto del bloque en vez de imponerlo. `min-height: 0` es
   imprescindible: sin él la imagen sigue aportando su alto natural a las
   filas automáticas y la portada se estira a 650px, dejando el precio
   descolgado al fondo. El alto fijo del contenedor es el que manda. */
body.diseno-revista .grilla > .tarjeta:first-child .foto,
body.diseno-revista .grilla > .tarjeta:first-child .sin-foto {
    grid-row: 1 / -1; grid-column: 1;
    aspect-ratio: auto; height: 100%; min-height: 0; object-fit: cover;
    margin-bottom: 0;
}
body.diseno-revista .grilla > .tarjeta:first-child .titulo {
    grid-column: 2; grid-row: 2;
    font-size: 1.6rem; white-space: normal; line-height: 1.2;
    align-self: end;
}
body.diseno-revista .grilla > .tarjeta:first-child .precio {
    grid-column: 2; grid-row: 3; font-size: 2.2rem; margin: 0.5rem 0 0;
    align-self: start;
}
body.diseno-revista .grilla > .tarjeta:first-child .meta {
    grid-column: 2; grid-row: 4; margin-top: 0.6rem; align-self: start;
    justify-content: flex-start; gap: 0.8rem;
}
body.diseno-revista .grilla > .tarjeta:first-child .seller {
    grid-column: 2; grid-row: 5; align-self: start; margin-top: 0.25rem;
}
/* Cinta ancha sobre la foto, no sobre el bloque entero: centrada en la
   tarjeta quedaba flotando en el aire entre foto y texto. */
body.diseno-revista .grilla > .tarjeta:first-child .tape {
    width: 132px; height: 26px; left: 25%;
    transform: translateX(-50%) rotate(-1deg);
}

/* --- LISTA: columna de clasificados ---------------------------------- */
/* Para tiendas con mucho stock donde importa comparar precios rápido.
   Ancho acotado: a lo ancho de la pantalla la fila dejaba ~900px de blanco
   muerto entre el texto y el precio. Cuatro columnas fijas — miniatura,
   texto, precio a la derecha, corazón — para que los precios queden
   alineados en una columna y se puedan comparar de un vistazo. */
body.diseno-lista .grilla {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    max-width: 780px;
    /* Centrada: la cabecera de la tienda va centrada y una lista pegada a la
       izquierda dejaba la página descompensada. */
    margin-inline: auto;
}
body.diseno-lista .tarjeta {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) auto 34px;
    grid-template-rows: auto auto;
    column-gap: 1rem;
    align-items: center;
    padding: 0.75rem 0.4rem;
    border-bottom: 1.5px dashed var(--borde);
}
body.diseno-lista .tarjeta .foto,
body.diseno-lista .tarjeta .sin-foto {
    grid-row: 1 / -1; grid-column: 1;
    aspect-ratio: 1 / 1; margin-bottom: 0; font-size: 1.2rem;
}
/* En una miniatura de 72px la leyenda no cabe y se encima al emoji. */
body.diseno-lista .tarjeta .sin-foto::after { display: none; }
body.diseno-lista .tarjeta .titulo { grid-column: 2; grid-row: 1; }
body.diseno-lista .tarjeta .meta { grid-column: 2; grid-row: 2; justify-content: flex-start; gap: 0.6rem; }
body.diseno-lista .tarjeta .precio {
    grid-column: 3; grid-row: 1 / -1;
    font-size: 1.3rem; margin: 0; text-align: right; white-space: nowrap;
}
/* En una fila densa la cinta, el tag de categoría y el vendedor son ruido:
   el tag además se cortaba contra el corazón. */
body.diseno-lista .tarjeta .tape,
body.diseno-lista .tarjeta .cat-tag,
body.diseno-lista .tarjeta .seller { display: none; }
/* El corazón deja de flotar y pasa a ser la cuarta columna: absoluto se
   montaba encima del precio. */
body.diseno-lista .tarjeta .fav-btn {
    position: static; transform: none;
    grid-column: 4; grid-row: 1 / -1; justify-self: center;
}
body.diseno-lista .tarjeta .fav-btn:hover { transform: scale(1.12); }
/* El salto vertical del hover descoloca la fila entera: se cambia por un
   realce del papel. */
body.diseno-lista .tarjeta:hover { transform: none; }
body.diseno-lista .tarjeta:hover .foto,
body.diseno-lista .tarjeta:hover .sin-foto { box-shadow: 0 4px 10px var(--sombra); }

/* --- VITRINA: catálogo de fotos grandes ------------------------------ */
/* Ropa, arte, objetos donde la foto vende. Columnas más anchas que el mural
   (300px contra 220px), NO un número fijo: con `repeat(2, 1fr)` las tarjetas
   llegaban a 620px de ancho en escritorio y cabía una y media por pantalla. */
body.diseno-vitrina .grilla {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 2.6rem 2rem;
}
/* 1/1 y no 4/5: en columnas de 380px la foto vertical daba 475px de alto y,
   sin foto cargada, eran nueve huecos gigantes uno tras otro. */
body.diseno-vitrina .tarjeta .foto,
body.diseno-vitrina .tarjeta .sin-foto { aspect-ratio: 1 / 1; }
body.diseno-vitrina .tarjeta .titulo {
    font-size: 1.05rem; white-space: normal; line-height: 1.3;
}
body.diseno-vitrina .tarjeta .precio { font-size: 1.7rem; }

/* --- ESCAPARATE: tablón desordenado ---------------------------------- */
/* Collage real por columnas CSS: cada aviso cae donde queda hueco y las
   fotos alternan proporción, así que el desnivel nace del contenido.
   La versión anterior empujaba con margin-top a la grilla pareja y el
   resultado no leía como collage sino como layout roto. */
/* Rejilla normal con `align-items: start` (ya viene de .grilla) y fotos de
   proporción alternada: las tarjetas quedan de alto distinto y el desnivel
   sale del contenido, sin empujar con márgenes.
   No se usa column-count: con 9 avisos el balanceo dejaba la cuarta columna
   entera vacía y las cintas se salían de las tarjetas del borde. */
body.diseno-escaparate .grilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 2.4rem 1.6rem;
}
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+1) .foto,
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+1) .sin-foto { aspect-ratio: 1 / 1; }
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+2) .foto,
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+2) .sin-foto { aspect-ratio: 3 / 4; }
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+3) .foto,
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+3) .sin-foto { aspect-ratio: 4 / 3; }
/* Cada cinta en un ángulo distinto refuerza el "pegado a mano". */
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+1) .tape { transform: translateX(-50%) rotate(-6deg); }
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+2) .tape { transform: translateX(-52%) rotate(5deg); }
body.diseno-escaparate .grilla > .tarjeta:nth-child(3n+3) .tape { transform: translateX(-48%) rotate(-2deg); }

/* --- Teléfono -------------------------------------------------------- */
@media (max-width: 600px) {
    /* La portada de revista no cabe en dos columnas: se apila y la foto
       recupera su proporción propia (con height:100% quedaba una franja). */
    body.diseno-revista .grilla > .tarjeta:first-child {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto;
        /* height y no min-height: el alto fijo de escritorio hay que soltarlo
           o la foto desborda su fila y se monta encima del título. */
        height: auto;
    }
    body.diseno-revista .grilla > .tarjeta:first-child .foto,
    body.diseno-revista .grilla > .tarjeta:first-child .sin-foto {
        grid-row: auto; grid-column: 1;
        aspect-ratio: 4 / 3; height: auto; margin-bottom: 0.6rem;
    }
    body.diseno-revista .grilla > .tarjeta:first-child .titulo,
    body.diseno-revista .grilla > .tarjeta:first-child .precio,
    body.diseno-revista .grilla > .tarjeta:first-child .meta,
    body.diseno-revista .grilla > .tarjeta:first-child .seller {
        grid-column: 1; grid-row: auto;
    }
    body.diseno-revista .grilla > .tarjeta:first-child .titulo { font-size: 1.2rem; }
    body.diseno-revista .grilla > .tarjeta:first-child .precio { font-size: 1.6rem; margin-top: 0.3rem; }
    body.diseno-revista .grilla > .tarjeta:first-child .tape { left: 50%; }
    body.diseno-lista .tarjeta {
        grid-template-columns: 60px minmax(0, 1fr) auto 30px;
        column-gap: 0.7rem;
    }
    body.diseno-lista .tarjeta .precio { font-size: 1.1rem; }
    /* minmax(0,1fr) y no 300px: en 390px de pantalla una columna de 300
       desbordaba. Vitrina en teléfono es una sola foto grande por fila. */
    body.diseno-vitrina .grilla {
        grid-template-columns: minmax(0, 1fr);
        gap: 1.8rem;
    }
}
/* Ayuda bajo los botones de diseño: explica en una línea qué hace el layout
   elegido (el nombre solo no alcanza). */
.editor-ayuda {
    margin: 0.35rem 0 0; font-size: 0.78rem; color: var(--texto-2); line-height: 1.35;
}
/* Dos columnas parejas: con flex y wrap los cinco botones quedaban en filas
   de 4 y 1, con el borde derecho dentado. */
.editor-disenos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.4rem;
}
.editor-disenos .bgmode-btn { text-align: left; width: 100%; }

/* Mini maquetas de los diseños. Cada una dibuja el reparto de los avisos con
   bloques repetidos por box-shadow, dentro de la caja de 44x24 de .bgmode-mini.
   El nombre solo ("Vitrina") no dice qué le va a pasar a la página. */
.editor-disenos .bgmode-mini::before,
.editor-disenos .bgmode-mini::after {
    content: ""; position: absolute; background: var(--texto-2); opacity: 0.75;
}
/* Mural: seis bloques iguales, 3 x 2. */
.bgmode-mini.mini-d-mural::before {
    left: 4px; top: 4px; width: 10px; height: 7px;
    box-shadow: 13px 0 var(--texto-2), 26px 0 var(--texto-2),
                0 9px var(--texto-2), 13px 9px var(--texto-2), 26px 9px var(--texto-2);
}
/* Revista: una portada ancha arriba y la grilla debajo. */
.bgmode-mini.mini-d-revista::before {
    left: 4px; top: 3px; width: 36px; height: 10px;
}
.bgmode-mini.mini-d-revista::after {
    left: 4px; top: 16px; width: 10px; height: 5px;
    box-shadow: 13px 0 var(--texto-2), 26px 0 var(--texto-2);
}
/* Lista: barras de ancho completo, una por aviso. */
.bgmode-mini.mini-d-lista::before {
    left: 4px; top: 4px; width: 36px; height: 4px;
    box-shadow: 0 6px var(--texto-2), 0 12px var(--texto-2);
}
/* Vitrina: dos bloques grandes. */
.bgmode-mini.mini-d-vitrina::before {
    left: 4px; top: 4px; width: 16px; height: 16px;
    box-shadow: 20px 0 var(--texto-2);
}
/* Escaparate: bloques a distinta altura, tipo collage. */
.bgmode-mini.mini-d-escaparate::before {
    left: 4px; top: 3px; width: 8px; height: 12px;
    box-shadow: 11px 4px var(--texto-2), 22px 1px var(--texto-2), 33px 6px var(--texto-2);
}
/* Interruptor de alertas por correo en /busquedas. */
.alertas-correo {
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.8rem; flex-wrap: wrap;
    margin: 0.6rem 0 1.1rem; padding: 0.6rem 0.8rem;
    border: 1.5px dashed var(--borde); border-radius: 10px;
    font-size: 0.84rem; color: var(--texto-2);
}

/* ── Accesibilidad: respeto por "reducir movimiento" ──────────────────────
   Usuarios con trastornos vestibulares (o que activaron la preferencia del
   sistema) no deben recibir la capa de clima/mascota/confeti ni rebotes.
   La capa ambiental es puramente estética: se oculta entera sin perder nada.
   El resto de la interfaz conserva sus cambios de estado, pero instantáneos. */
@media (prefers-reduced-motion: reduce) {
    #scrapsFall,
    .suelo-fisico { display: none !important; }

    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

/* Migas de pan (breadcrumb) de la ficha de publicación: navegación jerárquica
   Inicio › Categoría › Título. Discreta, se pliega en móvil sin romper. */
.breadcrumb {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
    margin: 0 0 1rem; font-size: 0.85rem; color: var(--texto-2);
}
.breadcrumb a { color: var(--texto-2); text-decoration: none; }
.breadcrumb a:hover { color: var(--texto); text-decoration: underline; }
.breadcrumb .sep { opacity: 0.55; }
.breadcrumb .actual {
    color: var(--texto); font-weight: 600;
    max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Bloqueo de scroll del fondo mientras la vista rápida está abierta. */
body.modal-abierto { overflow: hidden; }

/* Vista previa de fotos al crear/editar publicación (publicar_fotos.js). */
.previa-fotos:empty { display: none; }
.previa-aviso { font-size: 0.82rem; color: var(--texto-2); margin: 0.5rem 0 0; }
.previa-aviso.excede { color: #b3261e; font-weight: 600; }

/* Galería mejorada de la ficha (galeria_detalle.js): imagen principal grande +
   tira de miniaturas clicables. Sin JS, .galeria apila las fotos (fallback). */
.galeria-mejorada .galeria-principal {
    width: 100%; border-radius: 10px; border: 1.5px solid var(--texto);
    max-height: 460px; object-fit: contain; background: var(--bg); margin-bottom: 0.6rem;
}
.galeria-tira { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.galeria-miniatura {
    padding: 0; border: 1.5px solid var(--borde); border-radius: 8px; cursor: pointer;
    background: var(--bg); width: 64px; height: 52px; overflow: hidden; margin: 0;
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.galeria-miniatura img { width: 100%; height: 100%; object-fit: cover; display: block; }
.galeria-miniatura:hover { transform: translateY(-1px); }
.galeria-miniatura.activa { border-color: var(--accent); border-width: 2px; }
.galeria-miniatura:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Condición del artículo (Tanda 1): verde=nuevo, dorado=reacondicionado;
   'usado' queda neutro con el estilo base del chip. Mismo patrón que
   .chip.vendida/.reservada, con variables que ya se adaptan a claro/oscuro. */
.chip.condicion-nuevo { color: var(--verde); border-color: var(--verde); }
.chip.condicion-reacondicionado { color: var(--dorado); border-color: var(--dorado); }

/* Preguntas públicas del aviso (Tanda 4). */
.preguntas-seccion { margin-top: 2rem; }
.preguntar-form textarea, .responder-form textarea { width: 100%; }
.lista-preguntas { list-style: none; padding: 0; margin: 1rem 0 0; }
.pregunta-item { border-top: 1px solid var(--borde); padding: 0.8rem 0; }
.pregunta-texto, .respuesta-texto { margin: 0.15rem 0; }
.respuesta-texto { padding-left: 0.4rem; border-left: 2px solid var(--verde); }
.qa-marca { display: inline-block; min-width: 1.2em; font-weight: 700; color: var(--texto-2); }
.qa-marca.resp { color: var(--verde); }
.pregunta-meta { color: var(--texto-2); font-size: 0.8rem; }
.ocultar-pregunta { background: none; border: none; color: var(--texto-2);
    font-size: 0.78rem; text-decoration: underline; cursor: pointer; padding: 0.2rem 0; width: auto; }

/* Botón en envío (no_doble_envio.js): atenuado + cursor de espera. */
button:disabled { opacity: 0.62; cursor: progress; }

/* Micro "pop" del corazón al marcar favorito (favoritos.js añade .pop con
   reflow-restart). Solo al marcar; reduced-motion lo neutraliza (bloque global). */
@keyframes fav-pop {
    0% { transform: scale(1); }
    40% { transform: scale(1.42); }
    70% { transform: scale(0.9); }
    100% { transform: scale(1); }
}
.fav-btn.pop { animation: fav-pop 0.34s cubic-bezier(0.2, 0.8, 0.2, 1); }

/* Flechas ‹ › sobre la imagen principal de la galería (galeria_detalle.js).
   El visor es el contenedor relativo; reduced-motion no aplica (sin animación). */
.galeria-mejorada .galeria-visor { position: relative; margin-bottom: 0.6rem; }
.galeria-mejorada .galeria-visor .galeria-principal { margin-bottom: 0; display: block; }
.galeria-flecha {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 38px; height: 38px; border-radius: 50%;
    border: 1.5px solid var(--texto); background: var(--bg); color: var(--texto);
    font-size: 1.4rem; line-height: 1; cursor: pointer; opacity: 0.85;
    display: flex; align-items: center; justify-content: center; padding: 0;
}
.galeria-flecha:hover { background: var(--texto); color: var(--bg); opacity: 1; }
.galeria-flecha-prev { left: 8px; }
.galeria-flecha-next { right: 8px; }

/* Botón "volver arriba" (volver_arriba.js): aparece al bajar. */
.volver-arriba {
    position: fixed; right: 16px; bottom: 16px; z-index: 200;
    width: 44px; height: 44px; border-radius: 50%;
    border: 1.5px solid var(--texto); background: var(--bg); color: var(--texto);
    font-size: 1.3rem; cursor: pointer; opacity: 0; pointer-events: none;
    transform: translateY(8px); transition: opacity 0.2s, transform 0.2s;
    display: flex; align-items: center; justify-content: center; padding: 0;
}
.volver-arriba.visible { opacity: 0.9; pointer-events: auto; transform: translateY(0); }
.volver-arriba:hover { background: var(--texto); color: var(--bg); opacity: 1; }

/* Hint de precio formateado en el form de publicar (publicar_precio.js). */
.precio-hint { display: block; color: var(--texto-2); font-size: 0.82rem; margin-top: 0.2rem; min-height: 1em; }

/* Skip-link "Saltar al contenido" (a11y): oculto fuera de pantalla hasta foco. */
.skip-link {
    position: fixed; left: 8px; top: -60px; z-index: 300;
    background: var(--bg); color: var(--texto); border: 1.5px solid var(--texto);
    border-radius: 8px; padding: 0.5rem 0.9rem; text-decoration: none; transition: top 0.15s;
}
.skip-link:focus { top: 8px; }
main:focus { outline: none; }

/* Nudge para subir fotos en el form de publicar (problema: pocos avisos con foto). */
.foto-nudge {
    margin: 0.4rem 0 0; padding: 0.5rem 0.75rem; font-size: 0.85rem;
    color: var(--texto-2); border-left: 3px solid var(--dorado); border-radius: 4px;
}
