/* Paleta "Estudio3D Default" (Fase 8, BITACORA.md) — cromo/plata + azul vívido, anclada en el
   logo real (wwwroot/images/logo-estudio3d.png) y en "Cromo Premium" (tema id=15, la dirección
   que el usuario ya eligió desde mockups reales). Reemplaza la paleta cobre/pátina/latón de la
   Fase 7, rechazada explícitamente por no combinar con el logo. Los NOMBRES de variable se
   mantienen idénticos a los de siempre a propósito -- son el contrato que usa el sistema de
   temas estacionales completo (10 plantillas + "Cromo Premium" + el resolutor + el editor
   admin, Fases 5-6) para sobreescribir colores por tema. Solo cambiaron los valores. */
:root {
    --bg-0: #0e1013;
    --bg-1: #191c20;
    --bg-2: #212529;
    --surface: rgba(25, 28, 32, .6);
    --surface-2: rgba(33, 37, 41, .88);
    --line: rgba(46, 51, 57, .5);
    --line-strong: rgba(184, 191, 198, .45);
    --text-1: #f3f4f6;
    --text-2: #9aa2ab;
    --text-3: #7a828c;
    --cyan: #1d7ac7;
    --violet: #4b515a;
    --pink: #1b5c93;
    --blue: #2c8fe0;
    --green: #34d399;
    --amber: #fbbf24;
    --red: #f87171;
    --grad: linear-gradient(120deg, #1d7ac7, #4b515a 50%, #1b5c93);
    --grad-soft: linear-gradient(120deg, rgba(29, 122, 199, .16), rgba(75, 81, 90, .16) 50%, rgba(27, 92, 147, .16));
    /* Blanco o casi-negro según el peor contraste de Cyan/Violet/Pink -- lo recalcula
       Services/ColorTemaVisualUtilidades.TextoLegibleSobre en cada request (Fase 6). Nunca se
       declara acá en la práctica (_TemaActivoEstilos.cshtml siempre la inyecta primero), pero se
       documenta con el valor real de este tema para que site.css quede completo por sí solo. */
    --on-accent: #ffffff;
    --font-head: 'Big Shoulders Display', system-ui, sans-serif;
    --border-1: rgba(46, 51, 57, .5);
    --font-body: 'Work Sans', system-ui, sans-serif;
    --radius-card: 16px;
    --radius-control: 8px;
    /* Tokens de la Fase 7 -- consolidan ~30 valores de radio/sombra que antes se repetían
       sueltos por todo el archivo (ver BITACORA.md Fase 7 para el detalle de la auditoría). */
    --radius-sm: 6px;
    --shadow-elevated: 0 12px 32px rgba(0, 0, 0, .4);
    --shadow-glow: 0 0 20px rgba(29, 122, 199, .35);
}

html { font-size: 15px; min-height: 100%; }

body {
    min-height: 100vh;
    margin: 0;
    color: var(--text-1);
    font-family: var(--font-body);
    background:
        radial-gradient(1100px 520px at 85% -10%, color-mix(in srgb, var(--violet) 16%, transparent), transparent 60%),
        radial-gradient(900px 520px at -10% 20%, color-mix(in srgb, var(--cyan) 14%, transparent), transparent 55%),
        radial-gradient(800px 520px at 50% 115%, color-mix(in srgb, var(--pink) 10%, transparent), transparent 60%),
        var(--bg-1);
    overflow-x: hidden;
}

/* ---- fondo decorativo ---- */
.bg-grid, .bg-orb { position: fixed; inset: 0; pointer-events: none; z-index: -1; }
/* Los 3 orbes y las líneas de la grilla usan var(--cyan/--violet/--pink) -- no colores literales
   -- para que el halo ambiental SIEMPRE combine con el tema activo. Antes de la Fase 8 estaban
   hardcodeados en el cobre de la Fase 7, así que un cambio de tema (ej. a "Cromo Premium" o
   cualquier plantilla festiva) dejaba el halo de fondo desentonando con las tarjetas
   translúcidas de encima -- la causa real de "el tema se superpone a todo, no tiene lógica". */
.bg-grid {
    background-image:
        linear-gradient(color-mix(in srgb, var(--cyan) 5%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--cyan) 5%, transparent) 1px, transparent 1px);
    background-size: 44px 44px;
    -webkit-mask-image: radial-gradient(ellipse at 50% 0%, #000 30%, transparent 78%);
    mask-image: radial-gradient(ellipse at 50% 0%, #000 30%, transparent 78%);
}
.bg-orb {
    border-radius: 50%;
    filter: blur(90px);
    opacity: .38;
    animation: float 18s ease-in-out infinite;
}
.bg-orb-1 { width: 520px; height: 520px; top: -170px; right: -120px; background: var(--cyan); }
.bg-orb-2 { width: 480px; height: 480px; bottom: -170px; left: -130px; background: var(--violet); animation-delay: -6s; }
.bg-orb-3 { width: 380px; height: 380px; top: 42%; left: 55%; background: var(--pink); opacity: .18; animation-delay: -12s; }
@keyframes float {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50% { transform: translate(40px, -28px) scale(1.08); }
}

/* ---- decoración de temas estacionales (BITACORA.md Fase 5, rearquitecturada en Fase 9) ---- */
/* Hasta la Fase 8, estos elementos eran position:fixed sobre TODO el viewport, en TODAS las
   páginas (Admin incluido) -- el usuario lo calificó de invasivo/infantil y pidió explícitamente
   que la decoración "pertenezca a una sección concreta" (85-90% Estudio3D, 10-15% temática).
   Fase 9: ahora solo se invocan dentro de .hero-fallback (Views/Home/Index.cshtml,
   _TemaActivoDecoracionAncla.cshtml) -- ya no aparecen en Admin, Checkout, Carrito, Login ni en
   el resto de la tienda. position:absolute (antes fixed) las ancla a ese contenedor, que ya es
   position:relative;overflow:hidden, así que nunca se salen de su sección ni generan scroll.
   z-index:0 las deja detrás del contenido real del hero (.hero-print/h1/p/a, todos z-index:1) --
   nunca compiten visualmente con el título ni el botón. pointer-events:none se mantiene por si
   acaso, aunque ya no hay riesgo real de tapar controles al estar contenidas en un card
   decorativo sin inputs propios. */
.tema-decoracion { position: absolute; pointer-events: none; z-index: 0; }
.tema-decoracion--flotar { animation: temaFlotar 6s ease-in-out infinite; }
.tema-decoracion--caer { animation: temaCaer 9s linear infinite; }
.tema-decoracion--parpadear { animation: temaParpadear 2.4s ease-in-out infinite; }
.tema-decoracion--girar { animation: temaGirar 14s linear infinite; }
/* Variante "PatronRepetido" (Fase 6): mosaico de atmósfera (nieve, confeti) -- ahora cubre solo
   el hero, no la página. inset:-24px de sobra para que "flotar" (±16px) nunca deje un borde sin
   cubrir. "caer" anima background-position en vez de transform -- ver Fase 6 para el porqué. */
.tema-decoracion-patron { position: absolute; inset: -24px; pointer-events: none; z-index: 0; background-repeat: repeat; }
.tema-decoracion-patron.tema-decoracion--caer { animation: temaPatronCaer 14s linear infinite; }
@keyframes temaPatronCaer {
    from { background-position: 0 0; }
    to { background-position: 0 240px; }
}
/* Píldora de saludo (Fase 6) — centrada, debajo del navbar (min-height 64px) para no competir con
   los elementos decorativos de esquina (que usan top:16px) ni con la cinta de previsualización
   (fija abajo, ancho completo). Sin interacción propia -- mismo criterio pointer-events que el
   resto de la decoración. z-index bajado a 5 en la Fase 8 (mismo motivo que .tema-decoracion-
   patron): al quedar centrada cerca del nav, se dibujaba encima del menú "Cuenta" abierto. */
.tema-saludo {
    position: fixed; top: 78px; left: 50%; transform: translateX(-50%);
    z-index: 5; pointer-events: none;
    max-width: min(90vw, 360px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    padding: .45rem 1.1rem; border-radius: 999px;
    background: var(--grad); color: var(--on-accent, #fff);
    font-weight: 700; font-size: .85rem; text-align: center;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .35);
}
@keyframes temaFlotar {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-16px); }
}
@keyframes temaCaer {
    0% { transform: translateY(-10vh); }
    100% { transform: translateY(110vh); }
}
@keyframes temaParpadear {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}
@keyframes temaGirar {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* ---- banner informativo (texto corrido) ---- */
.banner-informativo {
    background: var(--grad);
    overflow: hidden;
    position: relative;
    height: 2.1rem;
    z-index: 1030;
}
/* Cada copia arranca en left:100% (recién fuera del borde derecho, sin importar su ancho ni el del
   viewport) y el transform la empuja "-100vw - 100%" — su propio ancho más el viewport completo —
   así siempre termina totalmente fuera por la izquierda. Con solo translateX(-50%) (versión anterior)
   un mensaje corto en una pantalla ancha dejaba las dos copias visibles a la vez, y parecía que el
   texto "empezaba a la mitad de la pantalla" en vez de entrar desde el borde. */
.banner-informativo__texto {
    position: absolute;
    top: 0;
    left: 100%;
    display: flex;
    align-items: center;
    height: 100%;
    padding: 0 3rem;
    /* Texto sobre var(--grad) directamente, igual que .btn-primary -- mismo mecanismo de
       contraste (Fase 6, --on-accent), antes hardcodeado en #fff a mano (Fase 8). */
    color: var(--on-accent, #fff);
    font-weight: 600;
    font-size: .82rem;
    letter-spacing: .02em;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .25);
    animation: desplazarBannerInformativo 16s linear infinite;
}
.banner-informativo__texto:nth-of-type(2) { animation-delay: 8s; }
@keyframes desplazarBannerInformativo {
    from { transform: translateX(0); }
    to { transform: translateX(calc(-100vw - 100%)); }
}
@media (prefers-reduced-motion: reduce) {
    .banner-informativo__texto {
        animation: none;
        position: static;
        padding: .5rem 1rem;
    }
    .banner-informativo__texto:nth-of-type(2) { display: none; }
    /* .bg-orb no tenía guard hasta ahora (hueco preexistente, corregido de paso acá porque ya se
       toca esta capa para lo nuevo — BITACORA.md Fase 5) y .tema-decoracion es la decoración de
       temas estacionales, nueva en esta misma sección. .tema-decoracion-patron es su variante de
       mosaico (Fase 6). */
    .bg-orb, .tema-decoracion, .tema-decoracion-patron { animation: none !important; }
    /* La pieza queda revelada de una (altura 0, no 100%) -- Fase 7. Sin esto, "sin movimiento"
       dejaría la máscara tapando la pieza entera, como si el hero estuviera roto. */
    .hero-print-mascara { animation: none !important; height: 0 !important; }
}

/* ---- barra de navegación ---- */
.navbar {
    background: color-mix(in srgb, var(--bg-0) 82%, transparent) !important;
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--cyan) 14%, transparent), var(--shadow-elevated) !important;
    min-height: 64px;
    position: sticky;
    top: 0;
    z-index: 1020;
}
.navbar-brand { font-family: var(--font-head); font-size: 1.32rem; font-weight: 700; letter-spacing: .4px; }
.brand-logo { display: flex; align-items: center; gap: .65rem; }
.brand-logo img {
    width: 42px; height: 42px; object-fit: contain;
    border-radius: var(--radius-sm); padding: 2px; background: #fff;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--cyan) 50%, transparent), var(--shadow-glow);
}
.brand-logo span {
    background: var(--grad);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}
.nav-link { color: var(--text-2) !important; font-weight: 500; position: relative; }
.nav-link:hover { color: var(--text-1) !important; text-shadow: 0 0 14px color-mix(in srgb, var(--cyan) 50%, transparent); }
.navbar-nav .nav-link::after {
    content: "";
    position: absolute;
    left: .75rem; right: .75rem; bottom: .1rem;
    height: 2px; border-radius: 2px;
    background: var(--grad);
    transform: scaleX(0);
    transition: transform .25s ease;
    transform-origin: left;
}
.navbar-nav .nav-link:hover::after { transform: scaleX(1); }
.navbar-text { color: var(--text-2) !important; }
/* "Ver tienda" + nombre de usuario + "Cerrar sesión" del panel Admin — en fila en escritorio
   (como ya se veía), en columna dentro del menú hamburguesa en pantallas angostas. Sin esto
   quedaban amontonados en una fila apretada al desplegar el menú en el celular, dando la
   impresión de que no estaba ahí (reportado por el usuario). */
.navbar-cuenta { display: flex; align-items: center; gap: .75rem; }
@media (max-width: 991.98px) {
    .navbar-cuenta { flex-direction: column; align-items: stretch; gap: .6rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
    .navbar-cuenta .navbar-text { text-align: center; }
}

.main-nav { align-items: center; }
/* .nav-search y .form-control:focus (más abajo, "formularios") comparten el mismo anillo de
   foco (.2rem, alpha .18) -- antes eran dos recetas ligeramente distintas escritas por separado
   (Fase 7, BITACORA.md). */
.nav-search {
    display: flex; align-items: center; gap: .5rem;
    background: color-mix(in srgb, var(--bg-0) 65%, transparent);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: .45rem .9rem;
    margin: .5rem 1rem;
    color: var(--text-3);
    flex: 0 1 260px;
    transition: border-color .18s ease, box-shadow .18s ease;
}
.nav-search:focus-within { border-color: var(--cyan); box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--cyan) 18%, transparent); }
.nav-search svg { flex: 0 0 auto; opacity: .8; }
.nav-search input {
    background: transparent; border: 0; outline: none; color: var(--text-1);
    font-size: .9rem; width: 100%;
}
.nav-search input::placeholder { color: var(--text-3); }
.nav-actions { align-items: center; gap: .35rem; }
.nav-icon-link {
    display: flex; align-items: center; justify-content: center;
    width: 42px; height: 42px; border-radius: var(--radius-control);
    color: var(--text-2); text-decoration: none;
    border: 1px solid transparent;
    transition: all .18s ease;
}
.nav-icon-link:hover { color: var(--text-1); border-color: var(--line-strong); background: color-mix(in srgb, var(--cyan) 10%, transparent); box-shadow: var(--shadow-glow); }
.nav-icon-link.dropdown-toggle::after { display: none; }
.nav-badge {
    position: absolute; top: 2px; right: 2px;
    min-width: 18px; height: 18px; padding: 0 4px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 999px;
    background: linear-gradient(120deg, var(--pink), var(--cyan));
    color: var(--on-accent, #fff); font-size: .68rem; font-weight: 700;
    box-shadow: 0 0 10px color-mix(in srgb, var(--pink) 50%, transparent);
}
.dropdown-menu {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 12px;
    box-shadow: var(--shadow-elevated);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    padding: .5rem;
}
.dropdown-item { color: var(--text-1); border-radius: var(--radius-control); padding: .5rem .75rem; font-weight: 500; }
.dropdown-item:hover, .dropdown-item:focus { background: color-mix(in srgb, var(--cyan) 14%, transparent); color: var(--text-1); }
.dropdown-item-text { padding: .5rem .75rem; }
.dropdown-divider { border-color: var(--line); }
.dropdown-item.text-danger:hover { background: color-mix(in srgb, var(--red) 14%, transparent); color: var(--red) !important; }
/* Bootstrap trae el dropdown-header pensado para fondo claro (gris casi invisible acá) —
   subtítulo de sub-grupo dentro de un desplegable con varias secciones (ej. "Ventas": separa
   Cotizaciones de Ventas de mesón). */
.dropdown-header { color: var(--text-2); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; padding: .5rem .75rem .25rem; }

/* ---- acordeón de categorías (menú) ---- */
.btn-toggle-categoria {
    background: transparent; border: 0; color: var(--text-3);
    width: 32px; height: 32px; flex: 0 0 32px;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--radius-control); cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.btn-toggle-categoria:hover { background: color-mix(in srgb, var(--cyan) 14%, transparent); color: var(--text-1); }
.btn-toggle-categoria svg { transition: transform .2s ease; }
.btn-toggle-categoria[aria-expanded="true"] svg { transform: rotate(180deg); }
.dropdown-subcategorias { list-style: none; margin: 0; padding: 0; display: none; }
.dropdown-subcategorias.mostrar { display: block; }

/* ---- sidebar del panel Admin (Fase 9, BITACORA.md, Bloque 9C) ---- */
/* Reemplaza la barra superior con menú hamburguesa -- pedido explícito del usuario
   ("idealmente dejar ese menu a un costado"). Nombres de clase propios (.admin-*), nunca
   .navbar/.container/main.container, que el sitio público sigue usando desde este mismo
   site.css -- ver Areas/Admin/Views/Shared/_Layout.cshtml para el porqué de este cuidado
   (ambos layouts comparten un solo archivo CSS). offcanvas-lg de Bootstrap: sidebar fijo desde
   lg (992px), cajón deslizable debajo -- un solo marcado HTML para los dos casos. */
.admin-shell { display: flex; min-height: 100vh; }
.admin-sidebar {
    --bs-offcanvas-width: 260px;
    width: 260px;
    background: var(--surface-2);
    border-right: 1px solid var(--line);
    flex-shrink: 0;
}
.admin-sidebar .offcanvas-body { display: flex; flex-direction: column; padding: 0; }
.admin-sidebar .offcanvas-header { border-bottom: 1px solid var(--line); padding: 1rem 1.1rem; }
.admin-sidebar-brand {
    display: flex; align-items: center; gap: .65rem;
    padding: 1.1rem 1.25rem; text-decoration: none;
    font-family: var(--font-head); font-weight: 700; font-size: 1.15rem;
    color: var(--text-1); border-bottom: 1px solid var(--line);
}
.admin-sidebar-brand img { width: 36px; height: 36px; object-fit: contain; border-radius: var(--radius-sm); padding: 2px; background: #fff; }
.admin-sidebar-nav { list-style: none; margin: 0; padding: .75rem; flex: 1 1 auto; overflow-y: auto; }
.admin-sidebar-nav > li { margin-bottom: .2rem; }
.admin-sidebar-link {
    display: block; padding: .6rem .85rem; border-radius: var(--radius-control);
    color: var(--text-2); text-decoration: none; font-weight: 500; font-size: .92rem;
    transition: background .15s ease, color .15s ease;
}
.admin-sidebar-link:hover { background: color-mix(in srgb, var(--cyan) 10%, transparent); color: var(--text-1); }
.admin-sidebar-link.activo { background: var(--grad); color: var(--on-accent, #fff); font-weight: 600; }
.admin-sidebar-grupo {
    display: flex; align-items: center; justify-content: space-between; width: 100%;
    padding: .6rem .85rem; border-radius: var(--radius-control); border: 0; background: transparent;
    color: var(--text-2); font-weight: 500; font-size: .92rem; cursor: pointer; text-align: left;
    transition: background .15s ease, color .15s ease;
}
.admin-sidebar-grupo:hover { background: color-mix(in srgb, var(--cyan) 10%, transparent); color: var(--text-1); }
.admin-sidebar-grupo.activo { color: var(--cyan); font-weight: 600; }
.admin-sidebar-grupo svg { width: 14px; height: 14px; transition: transform .2s ease; flex-shrink: 0; }
.admin-sidebar-grupo[aria-expanded="true"] svg { transform: rotate(180deg); }
.admin-sidebar-subnav { list-style: none; margin: .15rem 0 .3rem; padding: 0 0 0 .9rem; border-left: 1px solid var(--line); }
.admin-sidebar-subnav .admin-sidebar-link { font-size: .87rem; padding: .5rem .75rem; }
.admin-sidebar-subnav-titulo { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); padding: .5rem .75rem .2rem; font-weight: 700; }
.admin-sidebar-divider { border: 0; border-top: 1px solid var(--line); margin: .4rem .75rem; }
.admin-sidebar-cuenta {
    padding: 1rem 1.25rem; border-top: 1px solid var(--line);
    display: flex; flex-direction: column; gap: .6rem;
}
.admin-sidebar-cuenta .navbar-text { font-size: .82rem; }
.admin-topbar {
    position: sticky; top: 0; z-index: 1020;
    display: flex; align-items: center; gap: .75rem; padding: .75rem 1rem;
    background: color-mix(in srgb, var(--bg-0) 92%, transparent);
    border-bottom: 1px solid var(--line);
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
.admin-content { flex: 1 1 auto; min-width: 0; }
@media (min-width: 992px) {
    .admin-sidebar { position: sticky; top: 0; height: 100vh; }
}

/* Miniatura de tema (Admin/TemasVisuales/Index) como botón de previsualizar, no solo imagen
   decorativa -- a pedido del usuario ("en la miniatura idealmente debería poder pre-visualizar
   el tema"). El botón de texto "Previsualizar" ya existía más abajo en la tarjeta; esto agrega
   un segundo punto de entrada más visible, con el mismo POST. */
.tema-miniatura-btn {
    display: block; width: 100%; aspect-ratio: 16/9; position: relative;
    background: rgba(255, 255, 255, .04); border: none; padding: 0; cursor: pointer;
}
.tema-miniatura-overlay {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--bg-0) 55%, transparent);
    color: #fff; font-weight: 600; font-size: .9rem; letter-spacing: .02em;
    opacity: 0; transition: opacity .15s ease;
}
.tema-miniatura-btn:hover .tema-miniatura-overlay,
.tema-miniatura-btn:focus-visible .tema-miniatura-overlay { opacity: 1; }

/* ---- pin del mapa de contacto (logo de la tienda) ---- */
.pin-logo-tienda {
    background: #fff;
    border-radius: 50%;
    padding: 4px;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--blue) 60%, transparent), 0 4px 14px rgba(0, 0, 0, .5);
}

/* ---- contenido ---- */
main.container { padding-top: 2.4rem !important; padding-bottom: 4rem !important; position: relative; }

h1, .h1 {
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: -.6px;
    background: var(--grad);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    margin-bottom: .25rem;
}
h3 { font-family: var(--font-head); font-weight: 600; letter-spacing: -.3px; color: var(--text-1); }
.page-heading { display: flex; align-items: end; justify-content: space-between; gap: 1rem; margin-bottom: 1.5rem; }
.page-heading p, .form-shell > p { color: var(--text-2); margin: 0; }
.back-link { color: var(--cyan); text-decoration: none; display: inline-block; margin-bottom: .6rem; font-weight: 600; }
.back-link:hover { color: color-mix(in srgb, var(--cyan) 60%, white); text-shadow: 0 0 12px color-mix(in srgb, var(--cyan) 60%, transparent); }
.text-muted { color: var(--text-3) !important; }
.text-danger { color: var(--red) !important; }
.detalle-info { color: var(--text-1); font-size: 1.02rem; }
.detalle-info b { color: var(--cyan); font-weight: 650; }

/* ---- tarjetas ---- */
.card {
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    color: var(--text-1);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: var(--shadow-elevated), inset 0 1px 0 rgba(255, 255, 255, .04);
    transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
a.card:hover {
    transform: translateY(-3px);
    border-color: var(--line-strong);
    box-shadow: 0 16px 44px rgba(0, 0, 0, .45), var(--shadow-glow), inset 0 1px 0 rgba(255, 255, 255, .05);
}
.card:hover {
    border-color: var(--line-strong);
    box-shadow: 0 14px 40px rgba(0, 0, 0, .4), var(--shadow-glow);
}
a.card { color: var(--text-1); }
.card.border-info { border-color: color-mix(in srgb, var(--cyan) 50%, transparent) !important; }

/* ---- tarjeta de producto (catálogo) ---- */
.tarjeta-producto-media {
    display: block;
    position: relative;
    aspect-ratio: 1;
    overflow: hidden;
    background: rgba(255, 255, 255, .04);
    border-radius: var(--radius-card) var(--radius-card) 0 0;
}
.tarjeta-producto-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.tarjeta-producto:hover .tarjeta-producto-media img { transform: scale(1.07); }
.tarjeta-producto-overlay {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    /* Tintado con --bg-0 en vez de negro puro (Fase 8) -- coherente con el resto de la paleta
       en vez de un overlay genérico sin relación con el tema. */
    background: color-mix(in srgb, var(--bg-0) 78%, transparent);
    opacity: 0;
    transition: opacity .25s ease;
}
.tarjeta-producto:hover .tarjeta-producto-overlay { opacity: 1; }
.table-card { overflow: hidden; }
.table-card thead th {
    background: color-mix(in srgb, var(--cyan) 10%, transparent);
    color: var(--cyan);
    font-size: .76rem;
    letter-spacing: .09em;
    text-transform: uppercase;
    border: 0;
    padding: 1rem;
    border-bottom: 1px solid var(--line);
}

/* ---- botones ---- */
.btn { font-weight: 600; border-radius: var(--radius-control); transition: all .18s ease; }
.btn-primary {
    background: var(--grad);
    border: 0;
    padding: .6rem 1.1rem;
    /* Bootstrap pone color:#fff por defecto en .btn-primary -- se sobrescribe acá porque un tema
       puede tener un degradado claro (dorado, amarillo) donde el blanco no se lee. --on-accent lo
       calcula el propio tema (Fase 6, BITACORA.md) según el peor contraste de sus 3 acentos. */
    color: var(--on-accent, #fff);
    box-shadow: var(--shadow-glow);
}
.btn-primary:hover, .btn-primary:focus {
    background: var(--grad);
    color: var(--on-accent, #fff);
    filter: brightness(1.12);
    transform: translateY(-1px);
    box-shadow: 0 10px 30px color-mix(in srgb, var(--cyan) 50%, transparent);
}
.btn-outline-primary { color: var(--cyan); border-color: color-mix(in srgb, var(--cyan) 50%, transparent); }
.btn-outline-primary:hover { color: var(--on-accent, #fff); background: var(--cyan); border-color: var(--cyan); box-shadow: var(--shadow-glow); }
.btn-outline-secondary { color: var(--text-2); border-color: var(--line-strong); }
.btn-outline-secondary:hover { color: #fff; background: color-mix(in srgb, var(--cyan) 16%, transparent); border-color: var(--cyan); }
.btn-outline-success { color: var(--green); border-color: color-mix(in srgb, var(--green) 50%, transparent); }
.btn-outline-success:hover { color: var(--on-accent, #fff); background: var(--green); border-color: var(--green); box-shadow: 0 0 20px color-mix(in srgb, var(--green) 40%, transparent); }
.btn-outline-danger { color: var(--red); border-color: color-mix(in srgb, var(--red) 50%, transparent); }
.btn-outline-danger:hover { color: var(--on-accent, #fff); background: var(--red); border-color: var(--red); box-shadow: 0 0 20px color-mix(in srgb, var(--red) 40%, transparent); }
.btn-outline-info { color: var(--cyan); border-color: color-mix(in srgb, var(--cyan) 50%, transparent); }
.btn-outline-info:hover { color: var(--on-accent, #fff); background: var(--cyan); border-color: var(--cyan); }
.file-btn { display: inline-flex; align-items: center; border-style: dashed !important; }
.file-btn svg { width: 18px; height: 18px; margin-right: .5rem; }
.file-btn:hover svg { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--cyan) 60%, transparent)); }
.btn-outline-light { color: var(--text-1); border-color: color-mix(in srgb, var(--text-1) 35%, transparent); }
.btn-outline-light:hover { color: var(--bg-0); background: var(--text-1); border-color: var(--text-1); }
.btn-light { color: var(--text-1); background: color-mix(in srgb, var(--text-2) 14%, transparent); border-color: transparent; }
.btn-light:hover { background: color-mix(in srgb, var(--text-2) 24%, transparent); color: var(--text-1); }
.btn-success { background: linear-gradient(120deg, color-mix(in srgb, var(--green) 75%, black), var(--green)); border: 0; box-shadow: 0 6px 20px color-mix(in srgb, var(--green) 30%, transparent); }
.btn-success:hover { filter: brightness(1.1); }
.btn-secondary { background: color-mix(in srgb, var(--text-2) 18%, transparent); border: 0; color: var(--text-1); }
.btn-secondary:hover { background: color-mix(in srgb, var(--text-2) 30%, transparent); }
.btn-link { color: var(--cyan); }
.btn:active { transform: translateY(0); }

/* ---- insignias ---- */
.badge { padding: .5em .75em; border-radius: var(--radius-control); font-weight: 600; letter-spacing: .02em; }
.text-bg-primary { background: linear-gradient(120deg, var(--cyan), var(--violet)) !important; }
.text-bg-success { background: color-mix(in srgb, var(--green) 18%, transparent) !important; color: var(--green) !important; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--green) 40%, transparent); }
.text-bg-danger { background: color-mix(in srgb, var(--red) 16%, transparent) !important; color: var(--red) !important; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 40%, transparent); }
.text-bg-secondary { background: color-mix(in srgb, var(--text-2) 14%, transparent) !important; color: var(--text-2) !important; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-2) 30%, transparent); }
.text-bg-warning { background: linear-gradient(120deg, color-mix(in srgb, var(--amber) 75%, black), var(--amber)) !important; color: var(--on-accent, #1a1204) !important; }
.text-bg-light { background: color-mix(in srgb, var(--text-1) 12%, transparent) !important; color: var(--text-1) !important; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-1) 25%, transparent); }
.text-bg-info { background: color-mix(in srgb, var(--cyan) 18%, transparent) !important; color: var(--cyan) !important; }

/* ---- tablas ---- */
.table { --bs-table-color: var(--text-1); --bs-table-bg: transparent; color: var(--text-1); }
.table td { padding: 1rem; vertical-align: middle; border-color: var(--line); }
.table th { color: var(--text-1); border-color: var(--line); }
.table tbody tr { transition: background .15s ease; }
.table tbody tr:hover { background: color-mix(in srgb, var(--cyan) 6%, transparent); }
.table-primary { --bs-table-bg: color-mix(in srgb, var(--cyan) 16%, transparent) !important; --bs-table-color: var(--text-1) !important; }
.table-success { --bs-table-bg: color-mix(in srgb, var(--green) 16%, transparent) !important; --bs-table-color: var(--text-1) !important; }
.table-light { --bs-table-bg: color-mix(in srgb, var(--text-2) 8%, transparent) !important; --bs-table-color: var(--text-3) !important; }

/* ---- formularios ---- */
.form-shell { max-width: 820px; margin: auto; }
.form-card { padding: 1.75rem; margin-top: 1.25rem; background: var(--surface-2); }
/* Zona de arrastrar-y-soltar del formulario de cotización -- vivía como <style> inline en
   Views/Cotizar/Index.cshtml (@section Head), migrada acá en la Fase 7 (BITACORA.md) para que
   comparta el lenguaje visual del resto del sitio en vez de un color de acento fijo aparte. */
.dropzone-archivos { padding: 1.5rem; text-align: center; cursor: pointer; border-style: dashed; border-width: 2px; transition: border-color .18s ease, background .18s ease; }
.dropzone-archivos.dragover { border-color: var(--cyan); background: color-mix(in srgb, var(--cyan) 8%, transparent); }
.archivo-adjunto-item { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: .4rem .7rem; border-radius: var(--radius-control); background: var(--surface-2); font-size: .875rem; }
.form-card label, form label { font-weight: 650; margin-bottom: .35rem; color: var(--text-2); }
/* Mismo anillo de foco que .nav-search (Fase 7, BITACORA.md). */
.form-control, .form-select {
    background: color-mix(in srgb, var(--bg-0) 65%, transparent);
    border: 1px solid var(--line-strong);
    color: var(--text-1);
    min-height: 44px;
    border-radius: var(--radius-control);
}
.form-control::placeholder { color: var(--text-3); }
.form-control:focus, .form-select:focus {
    background: color-mix(in srgb, var(--bg-0) 80%, transparent);
    color: var(--text-1);
    border-color: var(--cyan);
    box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--cyan) 18%, transparent);
}
.form-select option { background: var(--bg-1); color: var(--text-1); }
.form-actions {
    border-top: 1px solid var(--line);
    margin-top: 1.75rem;
    padding-top: 1.25rem;
    display: flex;
    justify-content: end;
    gap: .75rem;
}
.form-check-input:checked { background-color: var(--violet); border-color: var(--violet); }

/* ---- paginación ---- */
.pagination .page-link {
    background: color-mix(in srgb, var(--bg-0) 60%, transparent);
    border-color: var(--line);
    color: var(--text-2);
}
.pagination .page-link:hover { color: var(--cyan); background: color-mix(in srgb, var(--cyan) 10%, transparent); }
.pagination .page-item.active .page-link {
    background: var(--grad);
    border-color: transparent;
    color: var(--on-accent, #fff);
    font-weight: 700;
    box-shadow: var(--shadow-glow);
}

/* ---- modales ---- */
.modal-content {
    background: var(--surface-2);
    color: var(--text-1);
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    box-shadow: 0 18px 50px rgba(0, 0, 0, .5);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}
.modal-header, .modal-footer { border-color: var(--line); }
.modal-title { font-family: var(--font-head); font-weight: 600; color: var(--text-1); }
.modal-backdrop.show { opacity: .65; }

/* ---- alertas ---- */
.alert { border-radius: 12px; border: 1px solid var(--line); background: var(--surface-2); }
.alert-info { border-color: color-mix(in srgb, var(--cyan) 40%, transparent); background: color-mix(in srgb, var(--cyan) 14%, var(--bg-0)); color: var(--cyan); }
.alert-success { border-color: color-mix(in srgb, var(--green) 40%, transparent); background: color-mix(in srgb, var(--green) 14%, var(--bg-0)); color: var(--green); }
.alert-warning { border-color: color-mix(in srgb, var(--amber) 40%, transparent); background: color-mix(in srgb, var(--amber) 14%, var(--bg-0)); color: var(--amber); }
.alert-danger { border-color: color-mix(in srgb, var(--red) 40%, transparent); background: color-mix(in srgb, var(--red) 14%, var(--bg-0)); color: var(--red); }
.btn-close { filter: invert(1); }

/* ---- tarjetas de estadísticas (panel) ---- */
/* .card (Bootstrap) trae flex-direction: column porque está pensada para apilar
   card-header/card-body/card-footer — acá no se usa ningún .card-body, así que .stat-card
   hereda esa columna sin quererlo, y el ícono queda arriba centrado (ancho fijo) mientras el
   bloque de texto de abajo, sin padding ni text-align propios, se queda pegado a la
   izquierda de su propio ancho (más angosto que "Total vendido este mes") y pegado al borde
   de la card — se ve como si los valores salieran "corridos" y el ícono sin aire arriba
   (reportado por el usuario, con captura real). */
.stat-card { display: flex; gap: 1rem; align-items: center; padding: 1.5rem; text-align: center; }
.stat-card .stat-icon {
    width: 56px; height: 56px; border-radius: var(--radius-control); flex: 0 0 56px;
    display: flex; align-items: center; justify-content: center;
}
.stat-card .stat-icon svg { width: 28px; height: 28px; }
/* Los nombres de clase (stat-cyan/violet/pink) quedan de la paleta anterior a propósito -- mismo
   trade-off ya documentado para --cyan/--violet/--pink en :root (Fase 7, BITACORA.md):
   renombrarlas tocaría las vistas Razor que las usan, no solo site.css. */
/* Los 3 acentos de la Fase 8 (cyan/violet/pink = azul medio/cromo oscuro/azul oscuro) son todos
   bastante oscuros -- funcionan como paradas de degradado, pero leídos solos como color de
   ícono/texto sobre una tarjeta oscura quedan con poco contraste. Se aclaran acá con color-mix en
   vez de hardcodear un tono aparte para cada uno (ese era justo el bug: .stat-violet era el único
   de los 3 sin var(), un tono elegido a mano que por casualidad se leía bien con la paleta vieja). */
.stat-cyan { background: linear-gradient(135deg, color-mix(in srgb, var(--cyan) 22%, transparent), color-mix(in srgb, var(--cyan) 6%, transparent)); color: color-mix(in srgb, var(--cyan) 60%, white); box-shadow: 0 0 24px color-mix(in srgb, var(--cyan) 25%, transparent); }
.stat-violet { background: linear-gradient(135deg, color-mix(in srgb, var(--violet) 26%, transparent), color-mix(in srgb, var(--violet) 6%, transparent)); color: color-mix(in srgb, var(--violet) 60%, white); box-shadow: 0 0 24px color-mix(in srgb, var(--violet) 30%, transparent); }
.stat-pink { background: linear-gradient(135deg, color-mix(in srgb, var(--pink) 24%, transparent), color-mix(in srgb, var(--pink) 6%, transparent)); color: color-mix(in srgb, var(--pink) 60%, white); box-shadow: 0 0 24px color-mix(in srgb, var(--pink) 28%, transparent); }
.stat-card h2 { font-family: var(--font-head); font-weight: 700; margin: 0; color: var(--text-1); }
.stat-card small { color: var(--text-2); }

/* ---- tarjetas de mantenedores ---- */
.mant-card { display: flex; align-items: center; gap: 1.1rem; min-height: 110px; }
.mant-card .mant-icon {
    width: 54px; height: 54px; border-radius: var(--radius-control); flex: 0 0 54px;
    display: flex; align-items: center; justify-content: center;
    color: color-mix(in srgb, var(--cyan) 60%, white);
    background: var(--grad-soft);
    box-shadow: 0 0 22px color-mix(in srgb, var(--cyan) 20%, transparent);
}
.mant-card .mant-icon svg { width: 26px; height: 26px; }
.mant-card b { font-size: 1.05rem; }
.mant-card .display-6 { font-family: var(--font-head); font-weight: 700; color: var(--text-1); }

/* ---- inicio de sesión ---- */
.login-wrap { display: flex; align-items: center; justify-content: center; min-height: calc(100vh - 190px); }
.login-card { max-width: 440px; width: 100%; position: relative; padding: 2.2rem 2rem; }
.login-card::before {
    content: "";
    position: absolute; inset: -1px;
    border-radius: calc(var(--radius-card) + 1px);
    padding: 1px;
    background: var(--grad);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}
.login-logo {
    width: 74px; height: 74px; border-radius: var(--radius-card); margin: 0 auto 1rem;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-soft);
    box-shadow: 0 0 34px color-mix(in srgb, var(--cyan) 40%, transparent);
}
.login-logo svg { width: 40px; height: 40px; color: color-mix(in srgb, var(--cyan) 60%, white); }
.login-card h2 { font-family: var(--font-head); font-weight: 700; text-align: center; color: var(--text-1); }
.login-card .login-sub { text-align: center; color: var(--text-3); margin-bottom: 1.4rem; font-size: .92rem; }

/* ---- carrusel de banners (inicio) ---- */
.banner-carousel {
    border-radius: 20px;
    overflow: hidden;
    margin-bottom: 1.75rem;
    border: 1px solid var(--line);
    box-shadow: 0 14px 44px rgba(0, 0, 0, .4);
}
.banner-slide {
    height: 400px;
    background-size: cover;
    background-position: center;
    background-color: var(--bg-2);
    display: flex;
    align-items: center;
}
.banner-overlay {
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, color-mix(in srgb, var(--bg-0) 88%, transparent) 0%, color-mix(in srgb, var(--bg-0) 55%, transparent) 45%, color-mix(in srgb, var(--bg-0) 15%, transparent) 75%, transparent 100%);
    display: flex;
    align-items: center;
}
.banner-content { max-width: 560px; padding: 0 3rem; }
.banner-content h1 {
    font-family: var(--font-head);
    font-size: 2.2rem;
    font-weight: 700;
    letter-spacing: -.6px;
    background: none;
    -webkit-background-clip: initial;
    background-clip: initial;
    -webkit-text-fill-color: #fff;
    color: #fff;
    margin-bottom: .6rem;
    text-shadow: 0 4px 24px rgba(0, 0, 0, .5);
}
.banner-content p { color: var(--text-1); font-size: 1.05rem; margin-bottom: 1.2rem; text-shadow: 0 2px 10px rgba(0, 0, 0, .5); }
.carousel-indicators { margin-bottom: .75rem; }
.carousel-indicators [data-bs-target] { background-color: rgba(255, 255, 255, .4); width: 9px; height: 9px; border-radius: 50%; opacity: 1; }
.carousel-indicators .active { background: var(--grad); }
.carousel-control-prev, .carousel-control-next { width: 6%; opacity: 0; transition: opacity .2s ease; }
.banner-carousel:hover .carousel-control-prev, .banner-carousel:hover .carousel-control-next { opacity: .85; }

/* ---- hero de respaldo (sin banners configurados): capas de impresión animadas ---- */
/* Brillo ambiental (Fase 6) con --grad-soft, que ya se deriva por tema -- cero datos nuevos.
   --grad-soft ya ES un linear-gradient(...); no se puede anidar dentro de radial-gradient(...)
   como si fuera un color plano (sería CSS inválido), así que se aplica directo. */
.hero-fallback {
    position: relative; padding: 3.5rem 2rem; text-align: center; overflow: hidden;
    background: var(--grad-soft);
}
/* La pieza "se imprime" una sola vez al cargar la página -- el "momento orquestado" que pide el
   skill frontend-design, en vez de un efecto que se repite sin parar. .hero-print-objeto (Fase 8:
   ahora un <svg> real, no un <div> con clip-path -- evoca el cabezal/riel y el filamento del
   propio logo, no un hexágono abstracto) define la silueta final SIEMPRE a tamaño completo;
   .hero-print-mascara la cubre por completo al empezar y se encoge desde arriba, así que su
   borde inferior -- con la línea del "nozzle" pegada -- descubre la pieza de abajo hacia arriba,
   como una impresora FDM real. */
.hero-print { position: relative; width: clamp(90px, 12vw, 130px); aspect-ratio: 1; margin: 0 auto 1.4rem; }
.hero-print-objeto {
    position: absolute; inset: 0;
    display: block;
    box-shadow: var(--shadow-glow);
}
.hero-print-mascara {
    position: absolute; left: -4px; right: -4px; top: 0; height: 100%;
    /* Fase 9E (BITACORA.md): era var(--bg-1) plano -- .hero-fallback en realidad pinta
       var(--grad-soft) (Bloque 724), así que la máscara nunca calzaba del todo. Invisible en
       temas oscuros (--bg-1 y --grad-soft leen parecido sobre una base oscura), pero en
       Primavera (el primer tema claro de esta fase) se notaba como una caja sólida de más. */
    background: var(--grad-soft);
    animation: heroImprimir 2.2s .3s cubic-bezier(.4, 0, .2, 1) both;
}
.hero-print-mascara::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
    background: var(--grad); box-shadow: var(--shadow-glow);
}
@keyframes heroImprimir {
    from { height: 100%; }
    to { height: 0%; }
}
.hero-fallback h1, .hero-fallback p, .hero-fallback a { position: relative; z-index: 1; }

@media (max-width: 576px) {
    .banner-slide { height: 280px; }
    .banner-content { padding: 0 1.5rem; }
    .banner-content h1 { font-size: 1.5rem; }
}

/* ---- pie de página ---- */
.site-footer {
    border-top: 1px solid var(--line);
    padding: 1.4rem 0;
    margin-top: 2rem;
    color: var(--text-3);
    font-size: .9rem;
    text-align: center;
}
.site-footer b { background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }

/* ---- scrollbar ---- */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--bg-1); }
::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--cyan) 28%, transparent); border-radius: var(--radius-control); border: 2px solid var(--bg-1); }
::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--cyan) 50%, transparent); }

@media (max-width: 576px) {
    main.container { padding-top: 1.3rem !important; }
    .page-heading { align-items: start; flex-direction: column; }
    .page-heading .btn { width: 100%; }
    .form-card { padding: 1.15rem; }
    .table { font-size: .88rem; }
    .login-card { padding: 1.5rem 1.1rem; }
}

/* ---- diseñador 3D ---- */
.disenador3d-grid {
    display: grid;
    grid-template-columns: minmax(280px, 360px) 1fr;
    gap: 1.25rem;
    align-items: start;
}
.disenador3d-panel {
    padding: 1.5rem;
    max-height: calc(100vh - 140px);
    overflow-y: auto;
}
.disenador3d-panel h3 { font-size: .95rem; margin: 0 0 .1rem; }
.disenador3d-panel .text-muted { margin-bottom: 1rem; }
.disenador3d-campo { margin-bottom: 1rem; }
.disenador3d-campo label {
    display: flex;
    justify-content: space-between;
    font-weight: 650;
    margin-bottom: .35rem;
    color: var(--text-2);
    font-size: .85rem;
}
.disenador3d-campo label .valor-campo { color: var(--cyan); font-variant-numeric: tabular-nums; }
.disenador3d-campo input[type="range"] {
    width: 100%;
    accent-color: var(--cyan);
    height: 26px;
}
.disenador3d-campo .form-control, .disenador3d-campo .form-select { min-height: 40px; }
.disenador3d-campo.form-check { display: flex; align-items: center; gap: .5rem; margin-bottom: .75rem; }
.disenador3d-campo.form-check label { margin: 0; }
.disenador3d-visor-shell {
    border: 1px solid var(--line);
    border-radius: 16px;
    overflow: hidden;
    background: var(--bg-1);
    position: relative;
}
.disenador3d-visor {
    width: 100%;
    height: min(62vh, 620px);
    min-height: 380px;
}
.disenador3d-visor canvas { display: block; }
.disenador3d-hint {
    position: absolute;
    bottom: .6rem;
    left: 50%;
    transform: translateX(-50%);
    font-size: .72rem;
    color: var(--text-3);
    background: color-mix(in srgb, var(--bg-0) 55%, transparent);
    padding: .25rem .7rem;
    border-radius: 999px;
    pointer-events: none;
}
.disenador3d-modo-vista {
    position: absolute;
    top: .6rem;
    right: .6rem;
    display: flex;
    gap: .3rem;
    background: color-mix(in srgb, var(--bg-0) 55%, transparent);
    padding: .3rem;
    border-radius: 999px;
}
.disenador3d-modo-vista button {
    background: transparent;
    border: 0;
    color: var(--text-2);
    border-radius: 999px;
    padding: .3rem .8rem;
    font-size: .78rem;
    font-weight: 600;
}
.disenador3d-modo-vista button.activo { background: var(--grad); color: var(--on-accent, #fff); }
.disenador3d-cargando {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    background: color-mix(in srgb, var(--bg-0) 60%, transparent);
    backdrop-filter: blur(1px);
    color: var(--text-1);
    font-size: .85rem;
    font-weight: 600;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s ease;
    z-index: 6;
}
.disenador3d-cargando.activo { opacity: 1; }
.disenador3d-spinner {
    width: 20px;
    height: 20px;
    border: 3px solid rgba(255, 255, 255, .25);
    border-top-color: var(--cyan);
    border-radius: 50%;
    animation: disenador3d-girar .7s linear infinite;
}
@keyframes disenador3d-girar { to { transform: rotate(360deg); } }
.disenador3d-exportar {
    display: flex;
    gap: .6rem;
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
}
.disenador3d-tabs { display: flex; gap: .4rem; margin-bottom: 1.1rem; flex-wrap: wrap; }
.disenador3d-tabs button {
    background: color-mix(in srgb, var(--text-3) 10%, transparent);
    border: 1px solid var(--line);
    color: var(--text-2);
    border-radius: 999px;
    padding: .35rem .9rem;
    font-size: .82rem;
    font-weight: 600;
}
.disenador3d-tabs button.activo { background: var(--grad); color: var(--on-accent, #fff); border-color: transparent; }
.tarjetas-generadores { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1.1rem; }
.tarjeta-generador {
    padding: 1.4rem;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    text-decoration: none;
}
.tarjeta-generador .icono-generador { font-size: 1.8rem; }
.tarjeta-generador h3 { margin: 0; font-size: 1.05rem; }
.tarjeta-generador p { color: var(--text-2); font-size: .86rem; margin: 0; }

@media (max-width: 900px) {
    .disenador3d-grid { grid-template-columns: 1fr; }
    .disenador3d-panel { max-height: none; }
}

/* Convertidor a SVG / Quitar fondo: vista previa de imagen en vez del visor 3D — mismo shell
   (.disenador3d-visor-shell) que ya usan los otros generadores, para que el overlay de carga
   (.disenador3d-cargando, position:absolute) tenga el mismo contenedor position:relative. */
.disenador3d-preview-imagen {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    padding: 1.25rem;
    min-height: 380px;
    align-items: center;
    justify-content: center;
}
.disenador3d-preview-mitad { flex: 1 1 260px; max-width: 100%; text-align: center; }
.disenador3d-preview-mitad .disenador3d-preview-etiqueta {
    font-size: .78rem;
    font-weight: 650;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-bottom: .5rem;
}
.disenador3d-preview-mitad img,
.disenador3d-preview-mitad svg {
    max-width: 100%;
    max-height: min(50vh, 480px);
    display: block;
    margin: 0 auto;
    cursor: crosshair;
}
/* El SVG que devuelve ImageTracer no trae su propio fondo (transparente) — sin esto, un trazado
   de tonos oscuros (como una foto con fondo negro) se pierde contra el tema oscuro del sitio y
   parece "todo negro" aunque el trazado en sí esté bien (confirmado leyendo el SVG generado:
   cientos de paths con colores reales, el problema era solo de contraste en la vista previa). */
.disenador3d-preview-mitad svg {
    background: #fff;
    border-radius: 8px;
}
.disenador3d-preview-transparencia {
    background-image:
        linear-gradient(45deg, #444 25%, transparent 25%),
        linear-gradient(-45deg, #444 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #444 75%),
        linear-gradient(-45deg, transparent 75%, #444 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    background-color: #222;
    border-radius: 8px;
}

/* Limpiador de SVG: una miniatura por cada <path> del archivo subido, clic para incluir/excluir
   del resultado final — ver limpiador-svg.js. */
.limpiador-grilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: .6rem;
    padding: 1.1rem;
    max-height: 340px;
    overflow-y: auto;
}
.limpiador-miniatura {
    border: 2px solid var(--line);
    border-radius: 10px;
    background: #fff;
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: .4rem;
    cursor: pointer;
    position: relative;
    transition: border-color .12s ease, opacity .12s ease;
}
.limpiador-miniatura:hover { border-color: var(--cyan); }
.limpiador-miniatura svg { max-width: 100%; max-height: 100%; }
.limpiador-miniatura.excluido { opacity: .3; }
.limpiador-miniatura.excluido::after {
    content: "✕";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--red);
    font-size: 1.7rem;
    font-weight: 700;
}
.limpiador-miniatura .limpiador-indice {
    position: absolute;
    bottom: 1px;
    right: 4px;
    font-size: .62rem;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

/* ---- correos ---- */
/* Bootstrap pinta .list-group-item y .nav-tabs .nav-link.active en blanco por defecto — nunca
   se habían usado en el sitio (confirmado: cero usos previos de .list-group con theming propio,
   cero usos de .nav-tabs), así que quedaban sin oscurecer y contrastaban fuerte contra el resto
   del panel. Se restyean acá, de forma global, para que cualquier uso futuro también herede el
   tema oscuro en vez de repetir el mismo problema. */
.list-group-item {
    background: transparent;
    color: var(--text-1);
    border-color: var(--line);
}
.list-group-item-action:hover, .list-group-item-action:focus {
    background: color-mix(in srgb, var(--cyan) 7%, transparent);
    color: var(--text-1);
}
.list-group-item .text-muted { color: var(--text-3) !important; }

.nav-tabs { border-bottom-color: var(--line); }
.nav-tabs .nav-link { color: var(--text-2); border-color: transparent; }
.nav-tabs .nav-link:hover { color: var(--text-1); border-color: transparent; }
.nav-tabs .nav-link.active {
    color: var(--text-1);
    background: var(--surface-2);
    border-color: var(--line) var(--line) var(--surface-2);
}

.correo-item.no-leido { font-weight: 600; }
.correo-item.no-leido .correo-preview { color: var(--text-1); }
.correo-preview {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.correo-cuerpo { max-width: 100%; overflow-x: auto; }
.correo-cuerpo img { max-width: 100%; height: auto; }