* {
    box-sizing: border-box;
}

:root {
    /* White frosted glass: blanco translúcido sobre ciclorama navy.
       Alpha media para mantener legibilidad del texto sin perder el tinte azul detrás. */
    --panel-bg: rgba(255, 255, 255, 0.52);
    --panel-bg-strong: rgba(255, 255, 255, 0.60);
    /* Tono cálido EFECTIVO del panel (blanco 0.6 sobre el ciclorama cream).
       Se usa en superficies pequeñas/vacías (tarjeta de ayuda) que, por estar
       sobre zonas más frías del fondo, leerían más blancas con el token translúcido.
       Al hornear el cream con mayor opacidad, igualan el color del panel grande. */
    --panel-bg-warm: rgba(243, 238, 229, 0.82);
    --panel-border: rgba(255, 255, 255, 0.50);
    --panel-border-inner: rgba(255, 255, 255, 0.35);
    --inner-bg: rgba(255, 255, 255, 0.30);
    --inner-bg-hover: rgba(255, 255, 255, 0.45);
    --inner-border: rgba(255, 255, 255, 0.45);
    --text-primary: #212529;
    --text-secondary: rgba(0, 0, 0, 0.78);
    /* Subido de 0.60 → 0.68: sobre el panel translúcido apoyado en la zona más
       clara del ciclorama, 0.60 caía por debajo de WCAG AA 4.5:1 en labels
       secundarios/placeholders. 0.68 lo asegura sin ensuciar la jerarquía. */
    --text-tertiary: rgba(0, 0, 0, 0.68);
    --accent: #212529;
    --accent-soft: rgba(0, 0, 0, 0.08);
    /* ── Acento único (Color Consistency Lock) ─────────────────────────────
       Paleta monocroma: ESTADO/SELECCIÓN (pill activo, paso activo, vista
       activa en la toolbar) y ACCIÓN (CTA primario, botón sólido, opción
       seleccionada en dropdowns) comparten el MISMO navy. Un solo acento en
       toda la página — no introducir un segundo color de acento. */
    --accent-active: #212529;
    --accent-active-strong: #16181b;
    /* Sombra estratificada — más suave porque el panel claro no necesita
       contraste tan fuerte contra el ciclorama navy de abajo. */
    /* Highlight interno (1ª capa, inset) = refracción del borde superior del
       cristal esmerilado → da volumen físico al panel. El resto: sombra navy
       estratificada, suave porque el panel claro no necesita tanto contraste. */
    --shadow-panel:
        inset 0 1px 0 rgba(255, 255, 255, 0.55),
        0 1px 2px rgba(0, 0, 0, 0.06),
        0 6px 16px rgba(0, 0, 0, 0.10),
        0 22px 48px rgba(0, 0, 0, 0.14),
        0 40px 90px rgba(0, 0, 0, 0.18);
    --panel-blur: blur(18px) saturate(140%);
    --panel-radius: 24px;
    /* Tipografía de marca (cargada en index.html). Títulos → Montserrat semibold/
       bold; texto → Poppins regular. Fallback a fuentes de sistema si el CDN falla. */
    --font-title: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
    --font-body: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
}

body {
    margin: 0;
    overflow: hidden;
    /* DECISIÓN DE FUENTE (2026-07): texto en Poppins regular, títulos en Montserrat
       (ver regla .hero-title/… más abajo). Ambas se cargan vía <link> de Google
       Fonts en index.html; si el CDN falla, caen al stack de sistema. */
    font-family: var(--font-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    letter-spacing: -0.005em;
    /* Ciclorama estudio: navy profundo arriba → cream cálido al pie + foco radial bajo el producto */
    background:
        radial-gradient(ellipse 50% 28% at 50% 82%, rgba(255, 245, 225, 0.55) 0%, rgba(255, 245, 225, 0) 70%),
        linear-gradient(to bottom,
            #06101f 0%,
            #0a172b 8%,
            #102035 22%,
            #1c2f48 38%,
            #4a5567 52%,
            #8e8d83 66%,
            #c8bfa9 80%,
            #dcd2bb 100%);
    color: var(--text-primary);
}

/* TÍTULOS → Montserrat (semibold/bold). El texto general va en Poppins (body).
   Solo se cambia la familia: los pesos existentes de cada título (600/700) ya
   están en el rango negrita/seminegrita que pide la marca. Cubre títulos de
   cliente (hero, panel Settings, subpaneles, secciones) y de los paneles dev. */
.hero-title,
#config-panel .panel-header strong,
.subpanel-header strong,
.subpanel-title,
#config-panel h2,
.section-heading-label,
.section-heading-value,
.mesh-list-heading,
.section-title,
#material-editor-panel .panel-header strong,
#controls-panel .panel-header strong,
.shortcuts-card h2 {
    font-family: var(--font-title);
}

#brand-logo {
    position: fixed;
    top: 50px;
    left: 50px;
    height: 30px;
    width: auto;
    z-index: 50;
    pointer-events: none;
    user-select: none;
}

/* ============================================================
   Panel-hero (izquierda, desktop) — título + claim + ayuda + bullets
   ============================================================ */
#hero-panel {
    position: fixed;
    left: 50px;
    top: 19vh;
    width: 312px;       /* mantener — HERO_LEFT_RESERVE (main.js) asume este ancho */
    z-index: 8;          /* bajo los paneles dev (z-index 10) por si coinciden */
    display: flex;
    flex-direction: column;
    color: var(--text-primary);
    /* El texto no captura eventos → se puede arrastrar la cámara "a través" del
       hero. Solo la tarjeta de ayuda vuelve a ser interactiva. */
    pointer-events: none;
}
#hero-panel .hero-help { pointer-events: auto; }

/* Entrada escalonada (MOTION 4): cada elemento del hero sube y aparece con un
   pequeño retardo en cascada. `backwards` mantiene el estado inicial (oculto)
   antes de arrancar. Curva ease-out expresiva. */
.hero-title,
.hero-subtitle,
.hero-help,
.hero-features li {
    animation: pvRise 0.7s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}
.hero-title     { animation-delay: 0.06s; }
.hero-subtitle  { animation-delay: 0.15s; }
.hero-help      { animation-delay: 0.24s; }
.hero-features li:nth-child(1) { animation-delay: 0.33s; }
.hero-features li:nth-child(2) { animation-delay: 0.40s; }
.hero-features li:nth-child(3) { animation-delay: 0.47s; }

.hero-title {
    margin: 0;
    font-size: 46px;
    line-height: 1.0;
    font-weight: 600;
    letter-spacing: -1.6px;
    color: #212529;
}
.hero-subtitle {
    margin: 20px 0 0;
    font-size: 15.5px;
    line-height: 1.55;
    font-weight: 400;
    color: var(--text-secondary);
    max-width: 268px;
}

/* Tarjeta de ayuda — clicable, abre el overlay de atajos. */
.hero-help {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 36px;
    padding: 14px 16px;
    width: 100%;
    text-align: left;
    background: var(--panel-bg-warm);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    border: 1px solid var(--panel-border);
    border-radius: var(--panel-radius);
    box-shadow: var(--shadow-panel);
    cursor: pointer;
    transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.25s ease, background 0.15s ease;
}
.hero-help:hover {
    transform: translateY(-2px);
    background: var(--panel-bg-warm);
}
.hero-help-icon {
    display: flex;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.06);
    color: #212529;
}
.hero-help-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-width: 0;
}
.hero-help-text strong {
    font-size: 13px;
    font-weight: 600;
    color: #212529;
}
.hero-help-text span {
    font-size: 12px;
    color: #212529;
}
.hero-help-arrow {
    display: flex;
    flex-shrink: 0;
    color: #212529;
    transition: transform 0.15s ease;
}
.hero-help:hover .hero-help-arrow { transform: translateX(2px); }

/* Bullets de valor. */
.hero-features {
    list-style: none;
    margin: 42px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 28px;
}
.hero-features li {
    display: flex;
    align-items: center;
    gap: 13px;
}
.hf-icon {
    display: flex;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, 0.20);
    color: #212529;
}
.hf-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.hf-text strong {
    font-size: 13.5px;
    font-weight: 600;
    color: #212529;
}
.hf-text span {
    font-size: 12px;
    color: #212529;
}

/* Tablet / portátil estrecho (769-1100px): en vez de ocultar el hero entero
   —perdiendo marca y acceso a la ayuda— lo COMPACTAMOS: título reducido +
   tarjeta de ayuda, sin subtítulo ni bullets. La cámara NO reserva su ancho en
   este rango (HERO_LEFT_RESERVE solo aplica ≥1101px en main.js); el hero sigue
   siendo pointer-events:none salvo la tarjeta, así el modelo se arrastra "a
   través" del texto. */
@media (max-width: 1100px) {
    #hero-panel { top: 96px; width: 248px; }
    .hero-title { font-size: 30px; }
    .hero-subtitle { display: none; }
    .hero-features { display: none; }
    .hero-help { margin-top: 22px; }
}
/* Por debajo de 768px el flujo vive en el bottom-sheet inferior → hero fuera
   para no competir por el espacio. */
/* El hero se oculta en TABLET VERTICAL, no solo en telefono. El producto ocupa
   ~260px de ancho en pantalla (frameObjectToView usa una distancia fija), y el
   panel de Configuracion reserva 482px. Con el hero puesto la franja libre es
   `ancho - 482 - heroRight`, asi que por debajo de ~1150px el modelo no cabe y
   se monta sobre el hero o sobre el panel. Medido: fallaba de 901 a 1040 px
   (iPad Pro 12.9" vertical son 1024) y otra vez en 1101-1104.
   Entre el hero y el producto, gana el producto. */
@media (max-width: 1150px) {
    #hero-panel { display: none; }
}

#viewer-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    background: transparent;
    transition: all 0.3s ease;
}

/* ─── Toolbar inferior del visor ─────────────────────────────────────────── */
#viewer-toolbar {
    position: fixed;
    bottom: 28px;
    left: 50%;
    /* --viewer-shift lo fija main.js = (reservaIzq - reservaDer)/2, así la
       toolbar comparte EXACTAMENTE el eje de centrado del modelo. */
    transform: translateX(calc(-50% + var(--viewer-shift, 0px)));
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 12px;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    border: 1px solid rgba(21, 35, 58, 0.08);
    border-radius: 999px;
    box-shadow:
        0 8px 24px rgba(21, 35, 58, 0.12),
        0 2px 6px rgba(21, 35, 58, 0.08);
    z-index: 20;
    font-family: var(--font-body);
    /* Solo opacidad: NO tocar transform (lo usa el centrado --viewer-shift). */
    animation: pvFade 0.6s ease 0.45s backwards;
    transition: transform 0.3s ease;
}
.vt-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 8px 12px;
    border: none;
    background: transparent;
    color: #212529;
    font-family: inherit;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    cursor: pointer;
    border-radius: 8px;
    transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
    min-width: 60px;
}
.vt-btn:hover {
    background: rgba(21, 35, 58, 0.06);
}
.vt-btn:active {
    transform: scale(0.96);
}
/* Activo (p.ej. Rotar con auto-rotación ON): relleno navy + icono/texto blanco,
   claramente marcado contra el toolbar claro. (El color de texto por defecto ya
   es navy, así que un mero cambio de color no se vería — hace falta el relleno.) */
.vt-btn.active {
    background: var(--accent-active);
    color: #ffffff;
}
.vt-btn.active:hover {
    background: var(--accent-active-strong);
}
.vt-btn svg {
    flex-shrink: 0;
    opacity: 0.85;
}
.vt-btn.active svg {
    opacity: 1;
}

.vt-divider {
    width: 1px;
    height: 28px;
    background: rgba(21, 35, 58, 0.12);
    margin: 0 4px;
    flex-shrink: 0;
}

/* ─── Hint inicial "Arrastra para girar" ─────────────────────────────────── */
#viewer-hint {
    position: fixed;
    bottom: 100px;
    left: 50%;
    transform: translateX(calc(-50% + var(--viewer-shift, 0px))) translateY(10px);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    background: rgba(21, 35, 58, 0.85);
    color: #ffffff;
    border-radius: 999px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 500;
    opacity: 0;
    pointer-events: none;
    z-index: 19;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: opacity 0.4s ease, transform 0.4s ease;
}
#viewer-hint.visible {
    opacity: 1;
    transform: translateX(calc(-50% + var(--viewer-shift, 0px))) translateY(0);
}

/* El botón toggle SOLO existe para mobile — en desktop está oculto. */
.vt-toggle { display: none; }

/* Ayuda en el toolbar = SOLO mobile. En desktop la entrada a la guía es la
   tarjeta del hero, así que aquí se oculta para no duplicar el affordance. */
@media (min-width: 769px) {
    #vt-help { display: none; }
}

/* Logo más compacto y menos metido en mobile (30px/50px de inset domina en una
   pantalla de teléfono). Queda arriba-izquierda, por encima del toolbar (top 88). */
@media (max-width: 768px) {
    #brand-logo { top: 18px; left: 16px; height: 22px; }
}

/* En mobile, la toolbar queda vertical en el lateral izquierdo, anclada arriba
   (no centrada) para que NUNCA colisione con el panel de Configuración que
   sale desde la franja inferior. Sólo iconos, sin labels — ahorra espacio.
   Por defecto sólo se ve el botón toggle; el resto aparece al pulsarlo
   (clase `.expanded` en el toolbar). */
@media (max-width: 768px) {
    #viewer-toolbar {
        flex-direction: column;
        bottom: auto;
        top: 88px;
        left: 12px;
        transform: none;
        padding: 8px 6px;
        gap: 2px;
        border-radius: 28px;
    }
    /* Aparece el toggle. Los demás botones quedan colapsados por defecto. */
    .vt-toggle { display: flex; }
    .vt-toggle svg { transition: transform 0.2s ease; }
    #viewer-toolbar.expanded .vt-toggle svg { transform: rotate(90deg); }
    #viewer-toolbar:not(.expanded) > .vt-btn:not(.vt-toggle),
    #viewer-toolbar:not(.expanded) > .vt-divider {
        display: none;
    }
    /* WCAG AA: target táctil ≥44×44px. Con SVG 18×18 + padding 13px llegamos a 44px. */
    .vt-btn {
        min-width: 44px;
        min-height: 44px;
        padding: 13px 13px;
        gap: 0;
    }
    .vt-btn span {
        display: none;  /* sólo icono en mobile */
    }
    .vt-divider {
        width: 24px;
        height: 1px;
        margin: 4px 0;
    }
    /* La toolbar es fija en mobile — el estado abierto/colapsado del panel
       no la mueve. Sobrescribimos el desktop rule body.panel-open. */
    body.panel-open #viewer-toolbar {
        transform: none;
    }
    #viewer-hint {
        bottom: 24px;
        top: auto;
    }
    body.panel-open #viewer-hint,
    body.panel-open #viewer-hint.visible {
        transform: translateX(-50%);
    }
}

/* ============================================================
   Panel derecho (configuración / paleta)
   ============================================================ */
#config-panel {
    position: absolute;
    top: 84px;
    right: 22px;
    width: 460px;
    /* Reserva ~95px abajo para que el CTA flotante (#cta-share, ~50px alto +
       32px bottom + margen) NUNCA quede tapado al expandir el panel. */
    max-height: calc(100vh - 84px - 95px);
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    padding: 0;
    border-radius: var(--panel-radius);
    border: 1px solid var(--panel-border);
    box-shadow: var(--shadow-panel);
    z-index: 10;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    animation: slideIn 0.5s ease-out;
}

@keyframes slideIn {
    from { opacity: 0; transform: translateX(20px); }
    to   { opacity: 1; transform: translateX(0); }
}

/* Reveal premium: sube + aparece. Usado por la cascada del hero y el CTA. */
@keyframes pvRise {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}
/* Fade puro (sin transform) para elementos cuyo transform ya está en uso —
   p.ej. el toolbar, que se centra con translateX(calc(-50% + var(--viewer-shift))). */
@keyframes pvFade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* Entrada SOLO con transform (sin opacity) — para el modal de color, cuyo
   backdrop-filter se rompería si se animara la opacidad. */
@keyframes pvRiseModal {
    from { transform: translateY(16px); }
    to   { transform: translateY(0); }
}

#config-panel .panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 22px 24px 14px;
    margin: 0;
}
#config-panel .panel-header strong {
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.4px;
}
#config-panel.collapsed { padding-bottom: 0; }
#config-panel.collapsed .panel-header { padding-bottom: 18px; }
#config-panel.collapsed .scrollable-content {
    max-height: 0 !important;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
}
#config-panel.collapsed .panel-toggle svg { transform: rotate(-90deg); }

.scrollable-content {
    overflow-y: auto;
    overflow-x: hidden;
    flex: 1;
    transition: opacity 0.2s ease, max-height 0.35s ease;
}

/* ============================================================
   Scrollbars unificadas (todos los paneles)
   ============================================================ */
.scrollable-content,
#controls-panel .panel-content,
#material-editor-panel .panel-content {
    scrollbar-width: thin;
    scrollbar-color: rgba(21, 35, 58, 0.20) transparent;
}
.scrollable-content::-webkit-scrollbar,
#controls-panel .panel-content::-webkit-scrollbar,
#material-editor-panel .panel-content::-webkit-scrollbar { width: 6px; }
.scrollable-content::-webkit-scrollbar-track,
#controls-panel .panel-content::-webkit-scrollbar-track,
#material-editor-panel .panel-content::-webkit-scrollbar-track { background: transparent; }
.scrollable-content::-webkit-scrollbar-thumb,
#controls-panel .panel-content::-webkit-scrollbar-thumb,
#material-editor-panel .panel-content::-webkit-scrollbar-thumb {
    background: rgba(21, 35, 58, 0.20);
    border-radius: 10px;
}
.scrollable-content::-webkit-scrollbar-thumb:hover,
#controls-panel .panel-content::-webkit-scrollbar-thumb:hover,
#material-editor-panel .panel-content::-webkit-scrollbar-thumb:hover { background: rgba(21, 35, 58, 0.32); }

#config-panel section {
    margin: 0;
    padding: 20px 24px;
    border-bottom: 1px solid var(--panel-border-inner);
}
#config-panel section:last-child { border-bottom: none; }

/* ─── Subpaneles dentro de Configuración ─────────────────────────────────
   Cada subpanel (Modelo, Color y acabado, ...) tiene su propio header
   colapsable. El separador inferior aparece entre subpaneles. */
#config-panel .subpanel {
    border-bottom: 1px solid var(--panel-border-inner);
}
#config-panel .subpanel:last-child { border-bottom: none; }

.subpanel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 24px 12px;
    cursor: pointer;
    user-select: none;
    background: transparent;
    transition: background 0.15s ease;
}
.subpanel-header:hover { background: rgba(21, 35, 58, 0.04); }
.subpanel-header strong {
    font-size: 13px;
    font-weight: 700;
    color: #212529;
    letter-spacing: 0.2px;
}

.subpanel-toggle {
    background: none;
    border: none;
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: #212529;
    opacity: 0.55;
    transition: transform 0.22s ease, opacity 0.15s ease;
    padding: 0;
}
.subpanel-header:hover .subpanel-toggle { opacity: 0.9; }

.subpanel-content {
    padding: 0 0 8px 0;
    max-height: 2000px;
    overflow: hidden;
    transition: max-height 0.25s ease, padding 0.25s ease;
}

#config-panel .subpanel.collapsed .subpanel-content {
    max-height: 0;
    padding: 0;
}
#config-panel .subpanel.collapsed .subpanel-toggle svg {
    transform: rotate(-90deg);
}

/* ─── Lista de piezas del modelo (dentro de Color y acabado) ───────────────
   Cada fila: esferita 3D (mismo render que la paleta, 30% más grande) +
   nombre del color (grande) + nombre del mesh (secundario). */
.mesh-list-section {
    margin-bottom: 14px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--panel-border-inner);
}
.mesh-list-heading {
    margin: 0 0 10px 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #212529;
    opacity: 0.7;
}
/* Sin scroll propio: que el .scrollable-content del panel sea el ÚNICO
   contenedor con scroll. Antes #mesh-list tenía max-height:360px + overflow
   auto → al abrir el grid de colores quedaba un "scroll dentro de scroll"
   apretado. Ahora la lista + la paleta fluyen y scrollea el panel entero. */
#mesh-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.mesh-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 10px;
    border: 1px solid transparent;
    border-radius: 10px;
    background: transparent;
    color: #212529;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.mesh-row:hover {
    background: rgba(21, 35, 58, 0.06);
}
.mesh-row.active {
    background: rgba(21, 35, 58, 0.10);
    border-color: rgba(21, 35, 58, 0.22);
}
/* Swatch 68px = 52px (paleta) × 1.3. Mismo look 3D que .color-button. */
.mesh-row .mesh-swatch {
    width: 68px;
    height: 68px;
    border-radius: 50%;
    border: 1px solid rgba(21, 35, 58, 0.12);
    flex-shrink: 0;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    box-shadow:
        0 2px 6px rgba(21, 35, 58, 0.16),
        inset 0 1px 0 rgba(255, 255, 255, 0.30),
        inset 0 -2px 4px rgba(0, 0, 0, 0.12);
}
.mesh-labels {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    overflow: hidden;
}
.mesh-piece-name {
    font-size: 13px;
    font-weight: 700;
    color: #212529;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mesh-color-name {
    font-size: 11px;
    font-weight: 500;
    color: #212529;
    opacity: 0.65;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Modelo en una sola línea: label + dropdown inline. */
.model-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 24px;
    border-bottom: 1px solid var(--panel-border-inner);
}
.model-row-label {
    font-size: 13px;
    font-weight: 700;
    color: #212529;
    letter-spacing: 0.2px;
    flex-shrink: 0;
}
#models-list,
#tipo-list {
    flex: 1;
    min-width: 0;
}
.models-select {
    width: 100%;
    box-sizing: border-box;
}
.models-select option {
    font-weight: normal;
    padding: 4px 8px;
}
.models-empty {
    font-size: 12px;
    color: var(--text-tertiary);
    font-style: italic;
}

/* ─── Encabezado de grupo del panel (p.ej. "Diseña tu cubierta") ─────────── */
.config-group-label {
    padding: 18px 24px 4px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.6px;
    color: var(--text-tertiary);
}

/* ----- Filas de configuración (Tipo / Modelo / Acabado / Material / …) ----- */
/* Estructura uniforme: columna izquierda (nº de paso + label) + control. */
.config-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 24px;
    border-bottom: 1px solid var(--panel-border-inner);
}
/* Columna izquierda de ancho fijo: mantiene alineados todos los controles
   tengan o no número de paso. */
.config-row-head {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 104px;
    flex-shrink: 0;
}
#config-panel .config-row-label {
    font-size: 13px;
    font-weight: 700;
    color: #212529;
    letter-spacing: 0.2px;
    margin: 0;
}
/* Insignia numerada del paso. Color = navy (acento único de estado). */
.step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--accent-active);
    color: #ffffff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.config-row > .pill-toggle,
.config-row > select,
.config-row > #tipo-list,
.config-row > #models-list {
    flex: 1;
    min-width: 0;
}

/* Header de subpanel con número de paso (Color = paso 4). */
.subpanel-title {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
}

/* Helper bajo el header de Color: indica que las piezas son clicables.
   Vive dentro de <section> (padding 24px ya aplicado) → sin padding propio. */
.color-helper {
    margin: 0 0 10px;
    padding: 0;
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--text-tertiary);
}

/* ─── Resumen del diseño (subpanel de cierre) ───────────────────────────── */
#config-summary {
    display: flex;
    flex-direction: column;
    padding: 4px 24px 0;
}
.summary-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px solid var(--panel-border-inner);
    font-size: 12.5px;
}
.summary-row:last-child { border-bottom: none; }
.summary-key {
    color: var(--text-tertiary);
    font-weight: 500;
    flex-shrink: 0;
}
.summary-val {
    color: var(--text-primary);
    font-weight: 600;
    text-align: right;
    letter-spacing: -0.1px;
}
/* Bloque de piezas/colores dentro del resumen. */
.summary-pieces {
    padding: 6px 0 2px;
    border-bottom: 1px solid var(--panel-border-inner);
}
.summary-piece {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    font-size: 12px;
}
.summary-piece-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex-shrink: 0;
    border: 1px solid rgba(21, 35, 58, 0.18);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.summary-piece-name { color: var(--text-secondary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.summary-piece-color { color: var(--text-primary); font-weight: 600; }
.summary-note {
    margin: 12px 24px 4px;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--text-tertiary);
}
.summary-note strong { color: var(--text-secondary); font-weight: 600; }

/* Pill toggle segmentado (Brillo/Mate, C-Clamp/Fast-Clamp, Magnets/Screws). */
.pill-toggle {
    display: inline-flex;
    background: rgba(21, 35, 58, 0.06);
    border-radius: 999px;
    padding: 3px;
    gap: 0;
    width: 100%;
}
.pill-toggle button {
    flex: 1;
    border: none;
    background: transparent;
    color: #212529;
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.3px;
    padding: 7px 12px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.pill-toggle button:hover:not(.active) {
    background: rgba(21, 35, 58, 0.04);
}
.pill-toggle button.active {
    background: var(--accent-active);
    color: #ffffff;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.12),
        0 2px 6px rgba(21, 35, 58, 0.22);
}

/* Lista de piezas con grid de colores inline (al seleccionar). */
.mesh-item {
    display: flex;
    flex-direction: column;
}
.mesh-item + .mesh-item {
    margin-top: 6px;
}
.mesh-row .mesh-chevron {
    margin-left: auto;
    color: rgba(21, 35, 58, 0.45);
    transition: transform 0.2s ease;
}
.mesh-item.active .mesh-row .mesh-chevron {
    transform: rotate(180deg);
    color: rgba(21, 35, 58, 0.80);
}
/* Grid de colores que aparece debajo de la pieza activa. */
.mesh-color-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    padding: 12px 4px 14px;
    margin: 4px 6px 8px;
    border-top: 1px solid var(--panel-border-inner);
    animation: meshGridIn 0.25s ease-out;
}
@keyframes meshGridIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.mesh-color-empty {
    grid-column: 1 / -1;
    font-size: 12px;
    color: var(--text-tertiary);
    font-style: italic;
    text-align: center;
    padding: 8px;
}

#config-panel h2 {
    margin: 0 0 14px 0;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.8px;
    color: var(--text-tertiary);
}

/* Heading "Color: Baby Blue" — label tracking uppercase + valor en caso natural */
.section-heading {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}
.section-heading-label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.8px;
    color: var(--text-tertiary);
}
.section-heading-label::after { content: ":"; margin-left: 1px; opacity: 0.6; }
.section-heading-value {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.2px;
    text-transform: none;
    color: var(--text-primary);
    line-height: 1.1;
}

#config-panel label {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    letter-spacing: -0.005em;
}

/* Selects elegantes con chevron SVG inline (sin flecha nativa del browser) */
#config-panel select,
#controls-panel select,
#material-editor-panel select {
    width: 100%;
    padding: 11px 38px 11px 16px;
    background-color: var(--inner-bg);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'><path d='M1.5 1.5L6 6L10.5 1.5' stroke='%23000000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 11px;
    border: 1px solid var(--inner-border);
    border-radius: 14px;
    color: var(--text-primary);
    font-size: 13px;
    font-family: inherit;
    font-weight: 500;
    letter-spacing: -0.005em;
    cursor: pointer;
    transition: background-color 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
    outline: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}
#config-panel select:hover,
#controls-panel select:hover,
#material-editor-panel select:hover { background-color: var(--inner-bg-hover); }
#config-panel select:focus,
#controls-panel select:focus,
#material-editor-panel select:focus {
    border-color: rgba(21, 35, 58, 0.22);
    box-shadow: 0 0 0 4px rgba(21, 35, 58, 0.06);
}
#config-panel select option,
#controls-panel select option,
#material-editor-panel select option { background: #ffffff; color: var(--text-primary); }

/* ============================================================
   Desplegable custom (Tipo / Modelo) — reemplaza al <select> nativo
   para tematizar también la lista de opciones (el menú nativo lo dibuja
   el SO y no acepta CSS). Construido en ui.js → createCustomSelect().
   ============================================================ */
.pv-select { position: relative; width: 100%; }

.pv-select-trigger {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 16px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 14px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: -0.005em;
    line-height: 1.2;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}
.pv-select-trigger:hover { background: var(--inner-bg-hover); }
.pv-select.open .pv-select-trigger,
.pv-select-trigger:focus-visible {
    outline: none;
    border-color: rgba(21, 35, 58, 0.22);
    box-shadow: 0 0 0 4px rgba(21, 35, 58, 0.06);
}
.pv-select-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pv-select-chevron {
    display: flex;
    flex-shrink: 0;
    color: var(--text-secondary);
    transition: transform 0.22s ease;
}
.pv-select.open .pv-select-chevron { transform: rotate(180deg); }

.pv-select-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 40;
    display: none;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    max-height: 280px;
    overflow-y: auto;
    background: rgba(255, 255, 255, 0.94);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    border: 1px solid var(--panel-border);
    border-radius: 14px;
    box-shadow:
        0 8px 28px rgba(21, 35, 58, 0.18),
        0 2px 8px rgba(21, 35, 58, 0.10);
    animation: pvSelectIn 0.16s ease-out;
}
.pv-select.open .pv-select-menu { display: flex; }
@keyframes pvSelectIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.pv-select-option {
    width: 100%;
    padding: 10px 12px;
    border: none;
    background: transparent;
    border-radius: 10px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: -0.005em;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.14s ease, color 0.14s ease;
}
.pv-select-option:hover { background: rgba(21, 35, 58, 0.06); }
.pv-select-option.selected {
    background: #212529;
    color: #ffffff;
    font-weight: 600;
}
.pv-select-option.selected:hover { background: #16181b; }

@media (max-width: 768px) {
    /* WCAG AA: target táctil ≥44px de alto. */
    .pv-select-trigger { padding: 13px 16px; }
    .pv-select-option { padding: 13px 14px; }
}

/* ============================================================
   Selector en modo VENTANA (solo móvil)
   El menú desplegable se recortaba contra #config-panel, que en ≤480px es una
   franja inferior con `max-height: 50vh` y `overflow: hidden`. En móvil, ui.js
   MUEVE el .pv-select-menu a <body> dentro de este overlay, así que aquí hay
   que deshacer su posicionamiento absoluto y su caja (borde, sombra, fondo),
   porque de eso se encarga ya la tarjeta.
   Mismo lenguaje visual que #color-modal: scrim con blur, tarjeta de cristal,
   entrada solo con transform.
   ============================================================ */
.pv-select-sheet {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(6, 16, 31, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    z-index: 1500;
}
.pv-select-sheet-card {
    width: 100%;
    max-width: 440px;
    max-height: 82vh;
    display: flex;
    flex-direction: column;
    padding: 22px 24px;
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    border: 1px solid var(--panel-border);
    border-radius: var(--panel-radius);
    box-shadow: var(--shadow-panel);
    /* Sin opacity: animarla desactivaría el backdrop-filter durante el fade. */
    animation: pvRiseModal 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
.pv-select-sheet-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}
.pv-select-sheet-eyebrow {
    display: block;
    margin-bottom: 3px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.6px;
    color: var(--text-tertiary);
}
.pv-select-sheet-name {
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
    color: var(--text-primary);
}
.pv-select-sheet-close {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--inner-border);
    border-radius: 50%;
    background: var(--inner-bg);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.pv-select-sheet-close:hover {
    background: var(--inner-bg-hover);
    color: var(--text-primary);
    border-color: rgba(21, 35, 58, 0.20);
}
/* El menú, ya dentro de la tarjeta: pierde la caja flotante y pasa a ser la
   lista desplazable del diálogo. `display: flex` porque aquí no está el
   `.pv-select.open` que lo mostraba. */
.pv-select-sheet .pv-select-menu {
    position: static;
    display: flex;
    max-height: none;
    padding: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    animation: none;
    gap: 4px;
    overflow-y: auto;
    scrollbar-gutter: stable;
}
.pv-select-sheet .pv-select-option {
    padding: 15px 16px;
    font-size: 14px;
}

/* Indicador de pieza seleccionada */
#selected-mesh-indicator {
    padding: 11px 14px;
    margin-bottom: 10px;
    border-radius: 14px;
    background: var(--inner-bg);
    border: 1px dashed var(--inner-border);
    font-size: 12px;
    color: var(--text-tertiary);
    transition: all 0.3s ease;
    cursor: default;
}
#selected-mesh-indicator.active {
    background: rgba(21, 35, 58, 0.06);
    border: 1px solid rgba(21, 35, 58, 0.20);
    color: var(--text-primary);
}
#selected-mesh-indicator strong {
    display: block;
    margin-bottom: 2px;
    font-weight: 600;
    color: var(--text-secondary);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 1.2px;
}

/* Grilla de colores: 4 columnas con swatches grandes (Fitts). El nombre del
   color elegido vive en el heading "COLOR: <nombre>"; cada swatch usa el
   atributo `title` como tooltip nativo al pasar el ratón. */
#color-selector-container {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    justify-items: center;
    padding: 6px 0 2px;
}

.color-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    cursor: pointer;
    transition: transform 0.2s ease;
    animation: fadeIn 0.3s ease-out backwards;
}
.color-item:hover { transform: translateY(-2px); }

.color-button {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: 1px solid rgba(21, 35, 58, 0.12);
    transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.22s ease, border-color 0.22s ease;
    margin-bottom: 0;
    cursor: grab;
    position: relative;
    box-shadow:
        0 2px 6px rgba(21, 35, 58, 0.16),
        inset 0 1px 0 rgba(255, 255, 255, 0.30),
        inset 0 -2px 4px rgba(0, 0, 0, 0.12);
}
.color-button:hover {
    transform: scale(1.08);
    border-color: rgba(21, 35, 58, 0.28);
    box-shadow:
        0 4px 12px rgba(21, 35, 58, 0.22),
        inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.color-button:active { cursor: grabbing; }

/* Estado seleccionado: doble anillo "color del swatch → blanco → color del swatch".
   El interior se consigue con un borde blanco sólido; el exterior con box-shadow
   que referencia --swatch-color (inyectado por JS para cada botón). */
.color-button.selected {
    border-color: #ffffff;
    border-width: 3px;
    box-shadow:
        0 0 0 3px var(--swatch-color, #212529),
        0 6px 18px rgba(21, 35, 58, 0.30);
    transform: scale(1.08);
}
.color-button.dragging { opacity: 0.4; cursor: grabbing; }

/* Color de TEST (codigo que empieza por digito). Solo visible en modo dev
   -- loadConfig los filtra en produccion -- pero se marca para que no haya duda
   de que no forma parte del catalogo. Ver isTestColorCode() en materials.js. */
.color-item.is-test .color-button { border: 2px dashed #b4541a; }
.color-test-badge {
    display: block;
    margin-top: 4px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: #b4541a;
    text-align: center;
}

/* Aviso bajo la parrilla del selector: nombra los colores que NO se pintan en
   esta pieza (ver RESTRICTED_COLOR_CODES en materials.js). Los swatches se
   ocultan, asi que esta nota es lo unico que le dice al usuario que el color
   existe en el catalogo pero no aplica aqui. */
.color-modal-note {
    margin: 14px 0 0;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--text-secondary);
    opacity: 0.8;
    text-align: left;
}

/* El nombre del color va en el heading dinámico — el span queda accesible (sr-only). */
.color-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ============================================================
   Panel izquierdo (Scene Controls)
   ============================================================ */
/* Contenedor de los paneles del lado izquierdo (Scene Controls + Modelo) */
#left-panels {
    position: absolute;
    left: 22px;
    top: 100px; /* alineado con #config-panel; queda holgura bajo el logo (top 22 + height 39 + margen 39) */
    width: 280px;
    max-height: calc(100vh - 120px);
    display: flex;
    flex-direction: column;
    gap: 12px;
    z-index: 10;
    pointer-events: none;
}
#left-panels > * { pointer-events: auto; }

#controls-panel {
    width: 100%;
    padding: 22px;
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 13px;
    border-radius: var(--panel-radius);
    border: 1px solid var(--panel-border);
    box-shadow: var(--shadow-panel);
    animation: slideInLeft 0.5s ease-out;
    display: flex;
    flex-direction: column;
    flex: 0 1 auto;
    min-height: 0;
    overflow: hidden;
}

/* Panel "Editor de materiales" (modo dev) — mismo look que controls/models */
#material-editor-panel {
    width: 100%;
    padding: 22px;
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 13px;
    border-radius: var(--panel-radius);
    border: 1px solid var(--panel-border);
    box-shadow: var(--shadow-panel);
    animation: slideInLeft 0.55s ease-out;
    display: flex;
    flex-direction: column;
    flex: 0 1 auto;
    min-height: 0;
    overflow: hidden;
}
#material-editor-panel .panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}
#material-editor-panel .panel-header strong {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}
#material-editor-panel .panel-content {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    transition: opacity 0.2s ease, max-height 0.35s ease;
    direction: rtl;
    margin-left: -20px;
    padding-left: 14px;
}
#material-editor-panel .panel-content > * { direction: ltr; }
#material-editor-panel.collapsed { padding-bottom: 14px; }
#material-editor-panel.collapsed .panel-header { margin-bottom: 0; }
#material-editor-panel.collapsed .panel-content {
    max-height: 0 !important;
    opacity: 0;
    margin-top: 0;
    pointer-events: none;
    overflow: hidden;
}
#material-editor-panel.collapsed .panel-toggle svg { transform: rotate(-90deg); }

#material-editor-panel input[type="text"] {
    width: 100%;
    padding: 7px 12px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 999px;
    color: var(--text-primary);
    font-size: 12px;
    font-family: inherit;
    outline: none;
    margin-bottom: 6px;
}
#material-editor-panel input[type="text"]::placeholder { color: var(--text-tertiary); }
#material-editor-panel input[type="text"]:focus {
    background: rgba(21, 35, 58, 0.05);
    border-color: rgba(21, 35, 58, 0.22);
    box-shadow: 0 0 0 4px rgba(21, 35, 58, 0.06);
}

.editor-load-btn {
    width: 100%;
    margin-bottom: 14px;
}

.editor-flakes-section,
.editor-advanced-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--panel-border-inner);
}
.editor-flakes-section .section-title,
.editor-advanced-section .section-title {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 10px;
    display: block;
    color: var(--text-primary);
}

.editor-save-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--panel-border-inner);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.editor-save-buttons {
    display: flex;
    gap: 6px;
}
.editor-save-buttons .panel-btn { flex: 1; }

.editor-restore-btn {
    width: 100%;
    margin-top: 6px;
    opacity: 0.85;
    font-size: 11px;
}
.editor-restore-btn:hover { opacity: 1; }

.custom-colors-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--panel-border-inner);
}
.custom-colors-section .section-title {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 8px;
    display: block;
    color: var(--text-primary);
}

#custom-colors-list {
    display: flex;
    flex-direction: column;
    gap: 5px;
    max-height: 160px;
    overflow-y: auto;
}
.cc-empty {
    font-size: 11px;
    color: var(--text-tertiary);
    padding: 6px 4px;
    font-style: italic;
}
.custom-color-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 12px;
    cursor: pointer;
    transition: background-color 0.18s ease, border-color 0.18s ease;
}
.custom-color-row:hover {
    background: var(--inner-bg-hover);
    border-color: rgba(21, 35, 58, 0.20);
}
.cc-swatch {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1px solid rgba(21, 35, 58, 0.18);
    box-shadow: 0 1px 3px rgba(21, 35, 58, 0.16), inset 0 1px 0 rgba(255,255,255,0.35);
    flex-shrink: 0;
}
.cc-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.cc-name {
    font-size: 12px;
    color: var(--text-primary);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cc-code {
    font-size: 10px;
    color: var(--text-tertiary);
    font-family: ui-monospace, monospace;
}
.cc-del {
    padding: 3px 8px;
    background: transparent;
    border: 1px solid var(--inner-border);
    border-radius: 999px;
    color: var(--text-tertiary);
    font-size: 11px;
    cursor: pointer;
    transition: all 0.2s ease;
}
.cc-del:hover {
    background: rgba(180, 40, 40, 0.10);
    color: #b03030;
    border-color: rgba(180, 40, 40, 0.32);
}

@keyframes slideInLeft {
    from { opacity: 0; transform: translateX(-20px); }
    to   { opacity: 1; transform: translateX(0); }
}

#controls-panel strong {
    font-size: 14px;
    font-weight: 600;
    display: block;
    color: var(--text-primary);
}

#controls-panel .panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
}
#controls-panel .panel-header strong { margin: 0; }

.panel-toggle {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 50%;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
    padding: 0;
}
.panel-toggle:hover {
    background: var(--inner-bg-hover);
    color: var(--text-primary);
    border-color: rgba(21, 35, 58, 0.20);
}
.panel-toggle svg {
    transition: transform 0.25s ease;
}

/* Contenido plegable + scroll cuando hay overflow (scrollbar a la izquierda) */
#controls-panel .panel-content {
    opacity: 1;
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    transition: opacity 0.2s ease, max-height 0.35s ease;
    /* direction: rtl mueve el scrollbar al lado izquierdo. Se compensa abajo en hijos. */
    direction: rtl;
    /* Extiende el contenido más allá del padding del panel para que el scrollbar pegue al borde. */
    margin-left: -20px;
    padding-left: 14px;
}
/* Los hijos vuelven a ltr para que texto y layout no se inviertan. */
#controls-panel .panel-content > * {
    direction: ltr;
}

#controls-panel.collapsed { padding-bottom: 14px; }
#controls-panel.collapsed .panel-header { margin-bottom: 0; }
#controls-panel.collapsed .panel-content {
    max-height: 0 !important;
    opacity: 0;
    margin-top: 0;
    pointer-events: none;
    overflow: hidden;
}
#controls-panel.collapsed .panel-toggle svg {
    transform: rotate(-90deg);
}

/* Sliders unificados: aplica a todos los paneles (Scene Controls + Editor) */
#left-panels input[type="range"],
#config-panel input[type="range"] {
    width: 100%;
    height: 4px;
    border-radius: 2px;
    background: rgba(21, 35, 58, 0.12);
    outline: none;
    margin: 8px 0 16px;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}
#left-panels input[type="range"]::-webkit-slider-thumb,
#config-panel input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #212529;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(21, 35, 58, 0.30);
    transition: transform 0.15s ease;
}
#left-panels input[type="range"]::-webkit-slider-thumb:hover,
#config-panel input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.15); }
#left-panels input[type="range"]::-moz-range-thumb,
#config-panel input[type="range"]::-moz-range-thumb {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #212529;
    cursor: pointer;
    border: none;
    box-shadow: 0 2px 6px rgba(21, 35, 58, 0.30);
}

#controls-panel label {
    display: inline-block;
    margin-left: 8px;
    cursor: pointer;
    user-select: none;
    color: var(--text-secondary);
}

#controls-panel input[type="checkbox"] {
    cursor: pointer;
    width: 15px;
    height: 15px;
    accent-color: var(--accent);
}

.control-row { margin-bottom: 12px; }

.control-label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
    color: var(--text-secondary);
    font-size: 12px;
}
.control-value {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   Botones
   ============================================================ */
.panel-btn {
    flex: 1;
    padding: 10px 16px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 999px;
    color: var(--text-primary);
    font-size: 12px;
    font-family: inherit;
    font-weight: 500;
    letter-spacing: -0.005em;
    cursor: pointer;
    transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
    white-space: nowrap;
}
.panel-btn:hover:not(:disabled) {
    background: var(--inner-bg-hover);
    border-color: rgba(21, 35, 58, 0.20);
}
.panel-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* Primario sólido: navy con texto blanco sobre white glass */
.panel-btn-primary {
    background: #212529;
    color: #ffffff;
    border-color: #212529;
    font-weight: 600;
    box-shadow: 0 2px 6px rgba(21, 35, 58, 0.18);
}
.panel-btn-primary:hover:not(:disabled) {
    background: #16181b;
    border-color: #16181b;
    color: #ffffff;
}

/* ============================================================
   Sección de luces (3-point lighting)
   ============================================================ */
.lights-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--panel-border-inner);
}
.lights-section .section-title {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 12px;
    display: block;
    color: var(--text-primary);
}

/* ─── Secciones de los paneles dev: todas visibles, bien marcadas ─────────
   Cada grupo (Luces, Temperatura, Softbox, Fondo, Presets en Scene Controls;
   Metal & partículas, Avanzado, Mis colores en el Editor) lleva su título como
   una "banda" de cabecera: fondo tintado + barra navy a la izquierda +
   mayúsculas tracking. Así se distinguen de un vistazo entre sí y del cuerpo,
   sin colapsar nada. */
#controls-panel .lights-section,
#controls-panel .bg-section,
#controls-panel .presets-section,
#material-editor-panel .editor-flakes-section,
#material-editor-panel .editor-advanced-section,
#material-editor-panel .custom-colors-section {
    margin-top: 18px;
    padding-top: 0;
    border-top: none;
}
#controls-panel .section-title,
#material-editor-panel .section-title {
    display: flex;
    align-items: center;
    margin: 0 0 14px;
    padding: 8px 12px;
    background: rgba(21, 35, 58, 0.07);
    border-left: 3px solid #212529;
    border-radius: 8px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.1px;
    text-transform: uppercase;
    color: #212529;
}

/* ============================================================
   Sección de fondo (color pickers + foco)
   ============================================================ */
.bg-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--panel-border-inner);
}
.bg-section .section-title {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 12px;
    display: block;
    color: var(--text-primary);
}
.color-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    font-size: 12px;
    color: var(--text-secondary);
}
.color-row input[type="color"] {
    -webkit-appearance: none;
    appearance: none;
    width: 36px;
    height: 24px;
    border: 1px solid var(--inner-border);
    border-radius: 6px;
    background: transparent;
    cursor: pointer;
    padding: 0;
}
.color-row input[type="color"]::-webkit-color-swatch-wrapper {
    padding: 0;
    border-radius: 5px;
}
.color-row input[type="color"]::-webkit-color-swatch {
    border: none;
    border-radius: 5px;
}
.color-row input[type="color"]::-moz-color-swatch {
    border: none;
    border-radius: 5px;
}

/* ============================================================
   Buscador / filtro de colores
   ============================================================ */
#color-toolbar {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 14px;
}
#color-toolbar #color-search {
    width: 100%;
    padding: 11px 16px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 14px;
    color: var(--text-primary);
    font-size: 13px;
    letter-spacing: -0.005em;
    outline: none;
    transition: background-color 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}
#color-toolbar #color-search::placeholder { color: var(--text-tertiary); }
#color-toolbar #color-search:focus {
    background: rgba(21, 35, 58, 0.05);
    border-color: rgba(21, 35, 58, 0.22);
    box-shadow: 0 0 0 4px rgba(21, 35, 58, 0.06);
}
#color-toolbar #color-search::placeholder { color: var(--text-tertiary); }

#finish-filter {
    display: flex;
    gap: 2px;
    background: rgba(21, 35, 58, 0.06);
    padding: 4px;
    border-radius: 999px;
    border: 1px solid var(--inner-border);
    box-shadow: inset 0 1px 2px rgba(21, 35, 58, 0.10);
}
#finish-filter button {
    flex: 1;
    padding: 8px 12px;
    background: transparent;
    border: none;
    border-radius: 999px;
    color: var(--text-tertiary);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
#finish-filter button:hover { color: var(--text-secondary); }
#finish-filter button.active {
    background: #ffffff;
    color: #212529;
    box-shadow:
        0 1px 2px rgba(0, 0, 0, 0.12),
        0 4px 12px rgba(0, 0, 0, 0.18),
        inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

/* ============================================================
   Presets
   ============================================================ */
.presets-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--panel-border-inner);
}
.presets-section .section-title {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 10px;
    display: block;
    color: var(--text-primary);
}
#controls-panel #preset-name {
    display: block;
    width: 100%;
    padding: 8px 14px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 999px;
    color: var(--text-primary);
    font-size: 12px;
    outline: none;
    margin-bottom: 6px;
    font-family: inherit;
    transition: all 0.2s ease;
}
#controls-panel #preset-name::placeholder { color: var(--text-tertiary); }
#controls-panel #preset-name:focus {
    background: rgba(21, 35, 58, 0.05);
    border-color: rgba(21, 35, 58, 0.22);
    box-shadow: 0 0 0 4px rgba(21, 35, 58, 0.06);
}

.presets-section #btn-save-preset {
    width: 100%;
    flex: none;
}

#preset-list {
    margin-top: 8px;
    max-height: 140px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.preset-row { display: flex; gap: 4px; }
.preset-row .preset-load {
    flex: 1;
    padding: 6px 12px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 999px;
    color: var(--text-primary);
    font-size: 12px;
    cursor: pointer;
    text-align: left;
    transition: all 0.2s ease;
}
.preset-row .preset-load:hover { background: var(--inner-bg-hover); border-color: rgba(21, 35, 58, 0.20); }
.preset-row .preset-del {
    padding: 6px 10px;
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 999px;
    color: var(--text-tertiary);
    font-size: 11px;
    cursor: pointer;
    transition: all 0.2s ease;
}
.preset-row .preset-del:hover { background: rgba(180, 40, 40, 0.10); color: #b03030; border-color: rgba(180, 40, 40, 0.32); }

/* ============================================================
   Tooltip de pieza al hacer hover
   ============================================================ */
#mesh-tooltip {
    position: fixed;
    pointer-events: none;
    padding: 5px 12px;
    background: rgba(20, 20, 20, 0.85);
    color: #fff;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.3px;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    opacity: 0;
    transition: opacity 0.15s ease;
    z-index: 100;
    backdrop-filter: blur(4px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

/* ============================================================
   Loading overlay
   ============================================================ */
#loading-overlay {
    position: fixed;
    inset: 0;
    background: rgba(245, 247, 250, 0.78);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2000;
    transition: opacity 0.35s ease;
}
#loading-overlay.fade-out { opacity: 0; }
.loading-card {
    text-align: center;
    color: var(--text-primary);
    min-width: 280px;
}
.loading-spinner {
    width: 44px;
    height: 44px;
    border: 3px solid rgba(21, 35, 58, 0.10);
    border-top-color: var(--accent);
    border-radius: 50%;
    margin: 0 auto 16px;
    animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Etiqueta de progreso oculta: no mostramos al cliente el nombre del asset que
   se está cargando (ej. "Environment: Peppermint Powerplant 2k"). El spinner y
   la barra siguen visibles. */
.loading-text { display: none; font-size: 13px; margin-bottom: 12px; color: var(--text-secondary); }
.loading-bar {
    width: 100%;
    height: 3px;
    background: rgba(21, 35, 58, 0.10);
    border-radius: 2px;
    overflow: hidden;
}
.loading-bar-fill {
    width: 0%;
    height: 100%;
    background: var(--accent);
    transition: width 0.2s ease;
}

/* ============================================================
   Overlay de atajos
   ============================================================ */
#shortcuts-overlay {
    position: fixed;
    inset: 0;
    background: rgba(6, 16, 31, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1500;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}
#shortcuts-overlay.visible { opacity: 1; pointer-events: auto; }
.shortcuts-card {
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    border: 1px solid var(--panel-border);
    border-radius: var(--panel-radius);
    padding: 28px 32px;
    color: var(--text-primary);
    max-width: 480px;
    box-shadow: var(--shadow-panel);
}
.shortcuts-card h2 {
    margin: 0 0 18px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}
.shortcuts-card table { width: 100%; border-collapse: collapse; }
.shortcuts-card td { padding: 7px 8px; font-size: 12.5px; color: var(--text-secondary); }
/* Columna izquierda = el gesto/acción; un punto más marcada que la descripción. */
.shortcuts-card td:first-child { white-space: nowrap; font-weight: 600; color: var(--text-primary); }
/* Subtítulo de la sección de atajos (solo dev). */
.shortcuts-card .shortcuts-subtitle {
    margin: 22px 0 10px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-tertiary);
}
.shortcuts-card kbd {
    background: var(--inner-bg);
    border: 1px solid var(--inner-border);
    border-radius: 5px;
    padding: 2px 7px;
    font-size: 10px;
    font-family: ui-monospace, monospace;
    color: var(--text-primary);
}
.shortcuts-card p {
    margin: 12px 0 0;
    font-size: 10px;
    color: var(--text-tertiary);
    text-align: center;
}

/* ============================================================
   Modal de selección de color (ventana centrada, patrón del overlay de ayuda)
   ============================================================ */
#color-modal {
    position: fixed;
    inset: 0;
    background: rgba(6, 16, 31, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    z-index: 1500;
    /* Mostrar/ocultar con visibility, NO con opacity: animar la opacidad del
       overlay (o de la tarjeta) desactiva el backdrop-filter del card mientras
       dura el fade → se veía el panel a través del cristal los primeros frames.
       Con visibility el blur está activo desde el primer frame. */
    visibility: hidden;
    pointer-events: none;
}
#color-modal.visible { visibility: visible; pointer-events: auto; }
.color-modal-card {
    width: 100%;
    max-width: 440px;
    max-height: 82vh;
    display: flex;
    flex-direction: column;
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    border: 1px solid var(--panel-border);
    border-radius: var(--panel-radius);
    box-shadow: var(--shadow-panel);
    padding: 22px 24px;
    /* Entrada SOLO con transform (sin opacity) para no romper el backdrop-filter. */
    animation: pvRiseModal 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
.color-modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 18px;
}
.color-modal-eyebrow {
    display: block;
    margin-bottom: 3px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.6px;
    color: var(--text-tertiary);
}
.color-modal-piece {
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
    color: var(--text-primary);
}
.color-modal-close {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--inner-border);
    border-radius: 50%;
    background: var(--inner-bg);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.color-modal-close:hover {
    background: var(--inner-bg-hover);
    color: var(--text-primary);
    border-color: rgba(21, 35, 58, 0.20);
}
.color-modal-grid {
    display: grid;
    /* Columnas FIJAS (no auto-fill): el nº de columnas no depende del ancho, así
       no salta cuando aparece la barra de scroll. + scrollbar-gutter reserva el
       hueco de la barra desde el inicio → cero reflow / blink al abrir. */
    grid-template-columns: repeat(5, 1fr);
    gap: 16px 12px;
    overflow-y: auto;
    scrollbar-gutter: stable;
    padding: 4px 2px 2px;
    justify-items: center;
}
/* Sin animación de entrada escalonada por swatch DENTRO del modal: el `fadeIn`
   con translateY(8px) hacía el contenido transitoriamente más alto durante el
   stagger → el scrollbar aparecía y luego desaparecía. El modal ya entra entero
   con `pvRise`, así que los swatches aparecen ya asentados (sin parpadeo). */
.color-modal-grid .color-item { animation: none; }
@media (max-width: 480px) {
    .color-modal-card { padding: 18px; max-height: 86vh; }
    .color-modal-grid { grid-template-columns: repeat(5, 1fr); gap: 14px 10px; }
}

/* Desktop: la ventana de color NO va centrada tapando el modelo. Se ancla
   arriba-derecha, EXACTAMENTE sobre el panel de Configuración (mismo ancho 460,
   top 84, right 22, y reserva inferior ~100px como el panel), y sin scrim para
   que el diseño 3D siga visible mientras se elige color. Clic en el modelo
   (overlay transparente) o ✕/Esc cierran. */
@media (min-width: 769px) {
    #color-modal {
        justify-content: flex-end;
        align-items: flex-start;
        padding: 84px 22px 0;
        background: transparent;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    .color-modal-card {
        width: 460px;
        max-width: 460px;
        max-height: calc(100vh - 84px - 100px);
    }
    /* En el panel ancho (460) caben 6 columnas cómodas. */
    .color-modal-grid { grid-template-columns: repeat(6, 1fr); }
}

/* ============================================================
   Touch drag ghost
   ============================================================ */
#touch-ghost {
    position: fixed;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 2px solid #fff;
    pointer-events: none;
    z-index: 9999;
    opacity: 0.85;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

/* ============================================================
   Notificaciones (toasts)
   ============================================================ */
#toast-container {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    z-index: 1000;
    pointer-events: none;
    /* Sin tope de ancho la burbuja crecía hacia los DOS lados desde el centro y
       en móvil se salía por ambos bordes a la vez: "Screws require C-Clamp —
       clamping switched from Fast-Clamp" son 61 caracteres, unos 500px a 13px
       de fuente, sobre un viewport de 390. Los avisos de cliente más largos
       llegan a 74. `width: max-content` mantiene la burbuja ajustada al texto
       cuando es corto; el `max-width` la obliga a partir en varias líneas.
       El tope de 600px está elegido para que los mensajes ACTUALES seguan
       cabiendo en UNA línea en escritorio, o sea que ahí no cambia nada; quien
       fuerza el salto es el 92vw, que solo muerde en pantallas estrechas. */
    width: max-content;
    max-width: min(92vw, 600px);
}
.toast {
    padding: 10px 22px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 500;
    color: #fff;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.25);
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.3s ease, transform 0.3s ease;
    pointer-events: none;
    /* Antes `nowrap`, que impedía cualquier salto de línea — de ahí el recorte. */
    white-space: normal;
    text-align: center;
    line-height: 1.35;
    /* Sobreescribe el `border-radius: 999px` de arriba con un radio FIJO. Con
       una sola línea el resultado es idéntico (la burbuja mide ~36px de alto,
       así que 999px ya se recortaba a ~18); la diferencia es que al partir en
       dos o tres líneas el radio deja de crecer con la altura y la burbuja no
       se deforma. */
    border-radius: 18px;
}
.toast.visible { opacity: 1; transform: translateY(0); }
.toast-info    { background: rgba(40, 40, 40, 0.92); }
.toast-success { background: rgba(40, 110, 70, 0.92); }
.toast-warning { background: rgba(150, 100, 20, 0.92); }
.toast-error   { background: rgba(150, 40, 40, 0.92); }

/* ============================================================
   Fade in animation para color items
   ============================================================ */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
.color-item:nth-child(1) { animation-delay: 0.05s; }
.color-item:nth-child(2) { animation-delay: 0.1s; }
.color-item:nth-child(3) { animation-delay: 0.15s; }
.color-item:nth-child(4) { animation-delay: 0.2s; }
.color-item:nth-child(5) { animation-delay: 0.25s; }
.color-item:nth-child(6) { animation-delay: 0.3s; }
.color-item:nth-child(7) { animation-delay: 0.35s; }
.color-item:nth-child(8) { animation-delay: 0.4s; }
.color-item:nth-child(n+9) { animation-delay: 0.45s; }

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 768px) {
    #config-panel { width: 290px; right: 10px; top: 10px; max-height: calc(100vh - 20px); }
    #controls-panel { width: 240px; left: 10px; top: 10px; }
    #color-selector-container { grid-template-columns: repeat(3, 1fr); }
    /* Reestructuración del panel: las filas pegan más al borde y baja el ancho
       de la columna izquierda para dejar más sitio al control. */
    .config-row { padding: 12px 16px; }
    .config-row-head { width: 92px; }
    .config-row-label { font-size: 12px; }
    /* Encabezados de grupo, helper y resumen comparten el padding horizontal
       de las filas (16px) para no quedar descuadrados respecto a los controles. */
    .config-group-label { padding: 14px 16px 4px; }
    #config-summary { padding: 4px 16px 0; }
    .summary-note { margin: 12px 16px 4px; }
    .mesh-color-grid { grid-template-columns: repeat(3, 1fr); gap: 8px; }
    /* WCAG AA: target táctil ≥44×44. En desktop 28×28 va bien con mouse. */
    .panel-toggle { width: 44px; height: 44px; }
}

@media (max-width: 480px) {
    #config-panel {
        width: calc(100% - 20px);
        right: 10px;
        left: 10px;
        top: auto;
        bottom: 10px;
        max-height: 50vh;
    }
    #controls-panel { display: none; }
    #color-selector-container { grid-template-columns: repeat(4, 1fr); gap: 8px; }
    .color-button { width: 40px; height: 40px; }
    /* Las filas en mobile bajan a vertical para que label + control no se aprieten. */
    .config-row { flex-direction: column; align-items: stretch; gap: 8px; padding: 10px 14px; }
    .config-row-head { width: auto; }
    .config-group-label { padding: 12px 14px 2px; }
    #config-summary { padding: 4px 14px 0; }
    .summary-note { margin: 10px 14px 4px; }
    .pill-toggle button { padding: 8px 10px; font-size: 11px; }
    /* 4 columnas en el grid inline (ya cómodo a 40px de swatch). */
    .mesh-color-grid { grid-template-columns: repeat(4, 1fr); gap: 8px; }
    /* Swatch de pieza también más pequeño para ahorrar verticalidad. */
    .mesh-row .mesh-swatch { width: 52px; height: 52px; }
}

/* ============================================================
   Toggle de paneles dev (abajo-izquierda)
   ============================================================ */
#dev-panels-toggle {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 20;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    border: 1px solid var(--panel-border);
    border-radius: 999px;
    background: var(--panel-bg-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    color: var(--text-primary);
    font: 600 12px/1 var(--font-body);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    box-shadow: var(--shadow-panel);
    transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
#dev-panels-toggle:hover {
    transform: translateY(-1px);
    background: #212529;
    color: #ffffff;
    border-color: #212529;
}
#dev-panels-toggle:active { transform: translateY(0); }
#dev-panels-toggle svg { display: block; }
#dev-panels-toggle .dev-toggle-label { display: inline-block; }
#dev-panels-toggle.is-off { color: var(--text-tertiary); opacity: 0.85; }

body.dev-panels-hidden #controls-panel,
body.dev-panels-hidden #material-editor-panel { display: none; }

/* ============================================================
   CTA primario — "Compartir con mi protésico"
   ============================================================ */
#cta-share {
    position: fixed;
    bottom: 32px;
    right: 32px;
    z-index: 30;
    display: inline-flex;
    align-items: center;
    gap: 11px;
    padding: 16px 26px;
    border: none;
    border-radius: 999px;
    background: #212529;
    color: #ffffff;
    font-family: var(--font-body);
    font-size: 14.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    /* Highlight superior interno + sombra navy estratificada = botón con cuerpo. */
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.14),
        0 10px 28px rgba(21, 35, 58, 0.34),
        0 2px 6px rgba(21, 35, 58, 0.22);
    /* Entra el último, tras la cascada del hero (MOTION 4). */
    animation: pvRise 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.5s backwards;
    transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.25s ease, background 0.2s ease;
}
#cta-share:hover {
    transform: translateY(-2px);
    background: #343a40;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.16),
        0 16px 40px rgba(21, 35, 58, 0.40),
        0 4px 10px rgba(21, 35, 58, 0.26);
}
#cta-share:active { transform: translateY(0); }
#cta-share svg { display: block; opacity: 0.95; transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1); }
#cta-share:hover svg { transform: translateX(3px); }

/* Desktop: el CTA queda anclado bottom-right siempre. Para evitar solapamiento
   con el panel expandido, el panel reserva ~110px abajo en su max-height
   (regla #config-panel en este mismo fichero). */

/* Mobile (≤768): el panel cubre la parte inferior. Subimos el CTA al lado
   derecho-superior (debajo del logo, a la altura de la toolbar vertical) y
   ocultamos el label para que sea compacto. */
@media (max-width: 768px) {
    #cta-share {
        bottom: auto;
        top: 88px;
        right: 12px;
        padding: 11px 13.2px;
        font-size: 13.2px;
    }
    #cta-share .cta-label { display: none; }
    body.panel-open #cta-share { right: 12px; }
}

/* ============================================================
   Reduced motion — OBLIGATORIO con MOTION_INTENSITY > 3.
   Colapsa todas las animaciones de entrada (cascada del hero, CTA, toolbar,
   reveals de color) y transiciones a instantáneo para usuarios que piden menos
   movimiento. El estado final es siempre el visible (los reveals usan
   `backwards`, así que sin animación el elemento ya está en su sitio).
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}
