/* =============================================================
   Rakuxt — Identidad institucional v0 (Bloque 0)
   Capa A theming: identidad del PRODUCTO Rakuxt (fija, no switcheable)
   Las CSS vars del storefront por tenant viven en .rkxt-shell con
   override granular (ver DOC02 sección 4 + CLAUDE.md regla 11).
   ============================================================= */

:root {
    color-scheme: light;

    /* Paleta naranja institucional (alineada con sitio público IntegraIA) */
    --rkxt-primary: #EB5202;          /* naranja kosiuko */
    --rkxt-primary-hover: #D14802;
    --rkxt-primary-soft: #FFEEDE;     /* naranja muy claro de fondo */
    --rkxt-secondary: #F59E0B;        /* ámbar — acento cálido */
    --rkxt-accent: #F59E0B;           /* ámbar */

    --rkxt-bg: #FFFFFF;
    --rkxt-bg-alt: #FBF8F4;           /* crema sutil */
    --rkxt-surface: #FFFFFF;
    --rkxt-surface-2: #F5F1EB;        /* crema más marcada */
    --rkxt-border: #ECE9E4;
    --rkxt-border-soft: #F3F0EA;

    --rkxt-text: #0E0E11;
    --rkxt-text-muted: #5E5E68;
    --rkxt-text-dim: #8A8A95;
    --rkxt-fg-on-primary: #FFFFFF;

    /* Texto sobre superficies claras (cards del storefront). Los temas del storefront
       pueden pisar --rkxt-text (ej. blanco para fondo oscuro) sin tocar --rkxt-surface,
       que queda claro: las cards siguen necesitando texto oscuro. Este token NO lo pisa
       el tema, así el nombre del producto siempre contrasta sobre la card clara. */
    --rkxt-on-surface: #18181B;
    --rkxt-on-surface-muted: #6B7280;

    --rkxt-radius: 14px;
    --rkxt-radius-sm: 8px;
    --rkxt-radius-pill: 999px;

    --rkxt-font-display: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --rkxt-font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --rkxt-font-serif:   'DM Serif Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;

    --rkxt-shadow-sm: 0 1px 2px rgba(15, 15, 18, 0.04), 0 1px 1px rgba(15, 15, 18, 0.03);
    --rkxt-shadow-md: 0 6px 20px rgba(235, 82, 2, 0.10), 0 2px 6px rgba(15, 15, 18, 0.04);
    --rkxt-shadow-lg: 0 24px 60px rgba(15, 15, 18, 0.14), 0 4px 12px rgba(15, 15, 18, 0.06);

    --rkxt-grad-primary: linear-gradient(135deg, #EB5202 0%, #F59E0B 100%);

    /* Semáforo semántico (estados ok / atención / mal / neutro). Usado por los
       indicadores de objetivos (dashboard del vendedor) y reutilizable en cualquier
       chip/barra de estado. *-soft = fondo tenue del mismo tono para badges/tracks. */
    --rkxt-ok: #16a34a;
    --rkxt-ok-soft: #DCFCE7;
    --rkxt-warn: #D97706;
    --rkxt-warn-soft: #FEF3C7;
    --rkxt-bad: #DC2626;
    --rkxt-bad-soft: #FEE2E2;
    --rkxt-neutral: #94A3B8;
    --rkxt-neutral-soft: #F1F5F9;

    /* Alias para el % "restante" en negativo (distribución de metas). */
    --rkxt-danger: var(--rkxt-bad);
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
    background: var(--rkxt-bg);
    color: var(--rkxt-text);
    font-family: var(--rkxt-font-body);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
    font-family: var(--rkxt-font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: 0 0 0.5rem 0;
    color: var(--rkxt-text);
}

a {
    color: var(--rkxt-primary);
    text-decoration: none;
    transition: color 0.15s ease;
}

a:hover {
    color: var(--rkxt-primary-hover);
}

code, pre, .mono {
    font-family: 'JetBrains Mono', 'Cascadia Code', Consolas, monospace;
    font-size: 0.88em;
}

/* --- Blazor reconnect / error UI --- */
#blazor-error-ui {
    background: var(--rkxt-surface);
    border-top: 2px solid var(--rkxt-accent);
    color: var(--rkxt-text);
    display: none;
    left: 0;
    padding: 0.8rem 1.5rem;
    position: fixed;
    bottom: 0;
    width: 100%;
    z-index: 1000;
    box-shadow: var(--rkxt-shadow-lg);
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 1rem;
    top: 0.6rem;
    color: var(--rkxt-text-muted);
}

.blazor-error-boundary {
    background: #FEF2F2;
    border-left: 3px solid #DC2626;
    color: #7F1D1D;
    padding: 1rem 1.25rem;
    border-radius: var(--rkxt-radius-sm);
}

.blazor-error-boundary::after {
    content: "Ocurrió un error al renderizar este componente.";
}

/* --- Forms validation hints --- */
.valid.modified:not([type=checkbox]) { outline: 1px solid #10B981; }
.invalid { outline: 1px solid #DC2626; }
.validation-message { color: #F87171; font-size: 0.875rem; }

/* --- Account pages (Login / Register / AccessDenied) --- */
.rkxt-auth {
    min-height: calc(100vh - 140px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 24px;
    background:
        radial-gradient(900px 500px at 80% -100px, rgba(235, 82, 2, 0.06), transparent 60%),
        radial-gradient(700px 400px at -10% 110%, rgba(245, 158, 11, 0.06), transparent 60%),
        var(--rkxt-bg-alt);
}

.rkxt-auth-card {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 36px 32px;
    width: 100%;
    max-width: 420px;
    box-shadow: var(--rkxt-shadow-lg);
}

.rkxt-auth-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--rkxt-text);
    font-family: var(--rkxt-font-display);
    font-weight: 700;
    font-size: 1rem;
    margin-bottom: 24px;
}

.rkxt-auth-brand:hover { color: var(--rkxt-text); }

.rkxt-auth-title {
    font-size: 1.6rem;
    margin: 0 0 8px 0;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.rkxt-auth-lead {
    color: var(--rkxt-text-muted);
    font-size: 0.92rem;
    margin: 0 0 24px 0;
}

.rkxt-auth-error {
    background: rgba(220, 38, 38, 0.12);
    border: 1px solid rgba(220, 38, 38, 0.4);
    color: #FCA5A5;
    padding: 10px 14px;
    border-radius: var(--rkxt-radius-sm);
    font-size: 0.875rem;
    margin-bottom: 16px;
}

.rkxt-field {
    display: block;
    margin-bottom: 16px;
}

/* Campo con checkbox: casilla + etiqueta en línea. */
.rkxt-field-check {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}
.rkxt-field-check input[type=checkbox] {
    width: 16px;
    height: 16px;
    accent-color: var(--rkxt-primary);
    margin: 0;
}

/* Modificador de .rkxt-field-check para checkboxes con texto largo (título + ayuda debajo):
   alinea la casilla arriba en vez de centrada. Ver Materializar.razor. */
.rkxt-field-check.rkxt-field-check-block {
    align-items: flex-start;
    gap: 10px;
    cursor: pointer;
}
.rkxt-field-check-block input[type=checkbox] {
    margin-top: 3px;
    flex: 0 0 auto;
}
.rkxt-field-check-block strong {
    display: block;
    color: var(--rkxt-text);
    font-size: 0.92rem;
    font-weight: 600;
}
.rkxt-field-check-block .rkxt-field-hint { margin-top: 2px; }

.rkxt-field-label {
    display: block;
    color: var(--rkxt-text-muted);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-bottom: 6px;
}

.rkxt-field-hint {
    display: block;
    color: var(--rkxt-text-dim);
    font-size: 0.78rem;
    margin-top: 6px;
}

/* Marca "(opcional)" dentro de un label de campo: minúscula, peso normal, atenuada. */
.rkxt-field-opt {
    text-transform: none;
    font-weight: 400;
    color: var(--rkxt-text-dim);
}

.rkxt-field-error {
    display: block;
    color: #FCA5A5;
    font-size: 0.8rem;
    margin-top: 4px;
}

.rkxt-input {
    width: 100%;
    padding: 11px 14px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    color: var(--rkxt-on-surface);
    font-family: var(--rkxt-font-body);
    font-size: 0.95rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Textarea para pegar código (HTML/CSS del componente Código HTML): monospace, sin wrap. */
textarea.rkxt-bloque-code {
    font-family: 'JetBrains Mono', 'Consolas', 'Courier New', monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    white-space: pre;
    overflow: auto;
    tab-size: 2;
}

/* Fieldset del efecto hover en el editor de la Grilla de productos */
.rkxt-bloque-efecto {
    border: 1px solid var(--rkxt-border);
    border-radius: 10px;
    padding: 12px 14px 14px;
    margin: 4px 0 2px;
}
.rkxt-bloque-efecto > legend {
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0 6px;
    color: var(--rkxt-on-surface);
}

/* ===== Componente storefront: Grilla de productos (GrillaProductos) ===== */
.rkxt-sf-gp-titulo {
    margin: 0 0 18px;
    font-size: 1.4rem;
}
.rkxt-sf-gp-grid {
    display: grid;
    grid-template-columns: repeat(var(--rkxt-sf-grid-cols, 4), minmax(0, 1fr));
    column-gap: var(--gp-gap-x, 20px);
    row-gap: var(--gp-gap-y, 24px);
}
@media (max-width: 900px) { .rkxt-sf-gp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .rkxt-sf-gp-grid { grid-template-columns: 1fr; } }

.rkxt-sf-gp-card {
    display: block;
    text-decoration: none;
    color: inherit;
}
.rkxt-sf-gp-card:hover { text-decoration: none; color: inherit; }

.rkxt-sf-gp-imgwrap {
    display: block;
    position: relative;
    overflow: hidden;
    border-radius: 10px;
    background: var(--rkxt-bg-alt, #f3f3f3);
}
.rkxt-sf-gp-img {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 4;
    background-color: var(--rkxt-bg-alt, #f3f3f3);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    transition: background-size 0.25s ease;
    cursor: zoom-in;
}
.rkxt-sf-gp-info { display: block; padding: 10px 2px 2px; }
.rkxt-sf-gp-nombre { display: block; font-weight: 600; font-size: 0.95rem; line-height: 1.25; }
.rkxt-sf-gp-sku {
    display: block;
    margin-top: 2px;
    font-family: var(--rkxt-font-mono, 'JetBrains Mono', monospace);
    font-size: 0.75rem;
    color: var(--rkxt-text-muted);
}
.rkxt-sf-gp-precio { display: block; margin-top: 4px; }

/* Selector manual de productos del editor de la Grilla (buscador + miniatura) */
.rkxt-prodpick { max-height: 340px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.rkxt-prodpick-item { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 8px; cursor: pointer; }
.rkxt-prodpick-item:hover { background: var(--rkxt-bg-alt, #f3f3f3); }
.rkxt-prodpick-thumb { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 6px; background-color: var(--rkxt-bg-alt, #eee); background-size: cover; background-position: center; background-repeat: no-repeat; }
.rkxt-prodpick-txt { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.rkxt-prodpick-nombre { font-weight: 500; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rkxt-prodpick-sku { font-family: var(--rkxt-font-mono, monospace); font-size: 0.72rem; color: var(--rkxt-text-muted); }

/* Auto-armar jerarquía de categorías */
.rkxt-admin-page-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.rkxt-autojer-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.rkxt-autojer-card { border: 1px solid var(--rkxt-border); border-radius: 12px; padding: 14px; background: var(--rkxt-surface); opacity: 0.62; transition: opacity 0.15s ease, box-shadow 0.15s ease; }
.rkxt-autojer-card.is-on { opacity: 1; box-shadow: 0 2px 10px rgba(0,0,0,0.06); }
.rkxt-autojer-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rkxt-autojer-padre { font-weight: 700; font-size: 1.02rem; }
.rkxt-autojer-count { margin-left: auto; font-size: 0.8rem; color: var(--rkxt-text-muted); font-family: var(--rkxt-font-mono, monospace); }
.rkxt-autojer-sub { font-size: 0.8rem; color: var(--rkxt-text-muted); margin: 4px 0 10px; }
.rkxt-autojer-hijas { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.rkxt-autojer-hija { display: flex; align-items: center; gap: 8px; }
.rkxt-autojer-orig { font-size: 0.82rem; color: var(--rkxt-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 130px; }
.rkxt-autojer-arrow { color: var(--rkxt-text-muted); }
.rkxt-autojer-nuevo { flex: 1; min-width: 0; padding: 6px 10px; font-size: 0.88rem; }
.rkxt-badge-ok, .rkxt-badge-warn { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; padding: 2px 8px; border-radius: 999px; }
.rkxt-badge-ok { background: rgba(16,160,90,0.14); color: #0a7a43; }
.rkxt-badge-warn { background: rgba(235,140,0,0.16); color: #a65a00; }
.rkxt-btn-ia { background: linear-gradient(135deg, #7C3AED, #06B6D4); color: #fff; border: none; }
.rkxt-btn-ia:hover { filter: brightness(1.06); color: #fff; }
.rkxt-btn-ia:disabled { opacity: 0.5; cursor: not-allowed; }

/* Árbol editable de categorías (drag & drop) */
.rkxt-tree-root-zone { border: 2px dashed var(--rkxt-border); border-radius: 10px; padding: 12px; text-align: center; color: var(--rkxt-text-muted); margin-bottom: 14px; transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease; }
.rkxt-tree-root-zone.is-over { border-color: var(--rkxt-primary); background: rgba(235,82,2,0.06); color: var(--rkxt-primary); }
.rkxt-tree-ul { list-style: none; margin: 0; padding-left: 24px; }
.rkxt-tree-ul.rkxt-tree-root { padding-left: 0; }
.rkxt-tree-li { margin: 4px 0; position: relative; }
.rkxt-tree-node { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid var(--rkxt-border); border-radius: 8px; background: var(--rkxt-surface); cursor: grab; transition: border-color 0.12s ease, box-shadow 0.12s ease, opacity 0.12s ease, background 0.12s ease; }
.rkxt-tree-node:hover { border-color: var(--rkxt-primary); }
.rkxt-tree-node.is-dragging { opacity: 0.45; }
.rkxt-tree-node.is-over { border-color: var(--rkxt-primary); box-shadow: 0 0 0 2px var(--rkxt-primary); background: rgba(235,82,2,0.05); }
.rkxt-tree-node.is-match { border-color: var(--rkxt-primary); background: rgba(235,82,2,0.10); }
.rkxt-tree-search { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; max-width: 520px; }
.rkxt-tree-search input { flex: 1; }
.rkxt-tree-search-count { font-size: 0.82rem; color: var(--rkxt-text-muted); white-space: nowrap; }
.rkxt-tree-grip { color: var(--rkxt-text-muted); font-size: 0.9rem; }
.rkxt-tree-nombre { font-weight: 600; }
.rkxt-tree-cod { font-family: var(--rkxt-font-mono, monospace); font-size: 0.72rem; color: var(--rkxt-text-muted); }
.rkxt-tree-tag { font-size: 0.62rem; text-transform: uppercase; font-weight: 700; letter-spacing: 0.03em; padding: 1px 7px; border-radius: 999px; background: rgba(16,160,90,0.14); color: #0a7a43; }
.rkxt-tree-tag-off { background: rgba(120,120,120,0.16); color: #6a6a6a; }
.rkxt-tree-actions { margin-left: auto; display: flex; gap: 4px; }
.rkxt-tree-btn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: 1px solid var(--rkxt-border); border-radius: 6px; background: var(--rkxt-surface); color: var(--rkxt-on-surface); text-decoration: none; font-size: 0.85rem; cursor: pointer; }
.rkxt-tree-btn:hover { border-color: var(--rkxt-primary); color: var(--rkxt-primary); }

/* ===== Mega-menú del storefront (header clásico) ===== */
.rkxt-sf-megamenu { position: relative; z-index: 200; border-top: 1px solid var(--rkxt-border, rgba(0,0,0,0.08)); background: var(--rkxt-bg, #fff); }
.rkxt-mm-bar { display: flex; flex-wrap: wrap; gap: 2px; max-width: 1200px; margin: 0 auto; padding: 0 24px; list-style: none; }
.rkxt-mm-item { position: relative; }
.rkxt-mm-top { display: block; padding: 12px 14px; font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rkxt-text, inherit); text-decoration: none; white-space: nowrap; }
.rkxt-mm-item:hover > .rkxt-mm-top { color: var(--rkxt-primary, #EB5202); }
.rkxt-mm-panel { position: absolute; left: 0; top: 100%; z-index: 210; display: none; grid-template-columns: repeat(var(--mm-cols, 4), minmax(150px, 1fr)); gap: 16px 26px; min-width: 520px; max-width: 92vw; padding: 22px 26px; background: #fff; border: 1px solid rgba(0,0,0,0.08); border-radius: 0 0 12px 12px; box-shadow: 0 18px 44px rgba(0,0,0,0.16); }
.rkxt-mm-item:hover > .rkxt-mm-panel { display: grid; }
.rkxt-mm-col-head { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 0.9rem; color: var(--rkxt-text, #111); text-decoration: none; margin-bottom: 8px; }
.rkxt-mm-col-head:hover { color: var(--rkxt-primary, #EB5202); }
.rkxt-mm-thumb { width: 26px; height: 26px; border-radius: 5px; background-size: cover; background-position: center; flex: 0 0 auto; }
.rkxt-mm-sub { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.rkxt-mm-sub a { font-size: 0.85rem; color: var(--rkxt-text-muted, #666); text-decoration: none; }
.rkxt-mm-sub a:hover { color: var(--rkxt-primary, #EB5202); }
@media (max-width: 900px) { .rkxt-sf-megamenu { display: none; } }

/* Drawer anidado (header centrado) */
.rkxt-sf-drawer-group { margin: 2px 0; }
.rkxt-sf-drawer-group > summary { cursor: pointer; padding: 9px 0; font-weight: 600; list-style: revert; }
.rkxt-sf-drawer-sub { display: block; padding: 6px 0 6px 16px; font-size: 0.92rem; }
.rkxt-sf-drawer-all { color: var(--rkxt-primary, #EB5202); font-weight: 600; }

/* Menú de categorías DENTRO del nav (modos item_unico / categorias_nav) */
.rkxt-sf-header { position: relative; z-index: 300; }   /* el header (y sus paneles) por encima del contenido */
.rkxt-mm-navitem { position: relative; display: inline-flex; align-items: center; }
.rkxt-mm-navlink { cursor: pointer; white-space: nowrap; color: var(--rkxt-text, inherit); text-decoration: none; }
.rkxt-mm-navitem:hover > .rkxt-mm-navlink { color: var(--rkxt-primary, #EB5202); }
.rkxt-mm-navitem:hover > .rkxt-mm-panel { display: grid; }
/* El nav está a la derecha del header → el panel abre hacia la izquierda para no salirse. */
.rkxt-mm-navitem > .rkxt-mm-panel { left: auto; right: 0; }
.rkxt-mm-panel-full { left: auto; right: 0; min-width: min(900px, 90vw); }
@media (max-width: 900px) { .rkxt-mm-navitem > .rkxt-mm-panel { display: none !important; } }

.rkxt-input::placeholder {
    color: var(--rkxt-on-surface-muted);
    opacity: 0.7;
}

.rkxt-input:focus {
    outline: none;
    border-color: var(--rkxt-primary);
    box-shadow: 0 0 0 3px rgba(235, 82, 2, 0.18);
}

.rkxt-checkbox {
    display: flex;
    gap: 8px;
    align-items: center;
    color: var(--rkxt-text-muted);
    font-size: 0.875rem;
    margin: 8px 0 20px 0;
    cursor: pointer;
}

.rkxt-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 11px 18px;
    border-radius: var(--rkxt-radius-sm);
    font-family: var(--rkxt-font-display);
    font-weight: 600;
    font-size: 0.95rem;
    border: 1px solid transparent;
    cursor: pointer;
    transition: transform 0.1s ease, box-shadow 0.15s ease;
    text-decoration: none;
}

.rkxt-btn-primary {
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    box-shadow: 0 6px 18px rgba(235, 82, 2, 0.22);
}

.rkxt-btn-primary:hover { background: var(--rkxt-primary-hover); }

.rkxt-btn-primary:hover { transform: translateY(-1px); box-shadow: 0 8px 24px rgba(235, 82, 2, 0.28); }
.rkxt-btn-primary:active { transform: translateY(0); }

.rkxt-btn-block { width: 100%; }

.rkxt-auth-meta {
    margin-top: 22px;
    color: var(--rkxt-text-dim);
    font-size: 0.875rem;
    text-align: center;
}

.rkxt-auth-meta a {
    color: var(--rkxt-primary-hover);
    font-weight: 500;
}

/* --- Admin pages --- */
.rkxt-admin-page-header {
    /* STICKY: la cabecera del listado NO desaparece al scrollear la tabla larga. El contenedor
       que scrollea es .rkxt-admin-content (overflow-y:auto en AdminLayout.razor.css), así que
       position:sticky se ancla ahí. Fondo opaco + borde inferior para que las filas de la tabla
       no se transparenten por debajo al pasar. */
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--rkxt-bg);
    border-bottom: 1px solid var(--rkxt-border);
    /* COMPACTO: título + texto de ayuda apilados y pegados a la izquierda; la acción (+Nuevo…)
       arriba a la derecha, a la altura del título. Grid con placement explícito → robusto ante
       headers sin lead o sin botón (degrada bien en las ~80 pantallas que usan esta clase). */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    column-gap: 16px;
    row-gap: 2px;
    padding: 20px 0 11px;
    margin-bottom: 16px;
}

.rkxt-admin-page-header h1 {
    grid-column: 1;
    grid-row: 1;
    font-size: 1.6rem;
    margin: 0;
    letter-spacing: -0.02em;
}

/* Encabezado del "circuito" en la sección Variantes del producto: escala del artículo + puente a la
   curva. Explica por qué el dropdown de talle está acotado y cómo se relaciona con las curvas. */
.rkxt-escala-info {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 9px 14px;
    margin: 0 0 14px;
    font-size: 0.85rem;
}
.rkxt-escala-info-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; }
.rkxt-escala-info-label { color: var(--rkxt-text-muted); text-transform: uppercase; font-size: 0.68rem; letter-spacing: 0.05em; font-weight: 700; }
.rkxt-escala-info-talles { color: var(--rkxt-text-muted); letter-spacing: 0.02em; }
.rkxt-escala-info-warn { color: var(--rkxt-warn); }
.rkxt-escala-info-curva { white-space: nowrap; }

/* Único elemento de acción del header (un <a class="rkxt-btn"> suelto o el wrapper
   .rkxt-admin-page-actions): arriba a la derecha, alineado con el título. */
.rkxt-admin-page-header > :not(h1):not(.rkxt-admin-page-lead) {
    grid-column: 2;
    grid-row: 1 / span 2;
    justify-self: end;
    align-self: start;
}

/* Mobile: se apila (título → ayuda → acción) para no apretar en pantallas angostas. */
@media (max-width: 680px) {
    .rkxt-admin-page-header { grid-template-columns: 1fr; }
    .rkxt-admin-page-header > :not(h1):not(.rkxt-admin-page-lead) {
        grid-column: 1;
        grid-row: auto;
        justify-self: start;
        margin-top: 8px;
    }
}

/* Contador de items del listado, embebido en el título (respeta el filtro activo). */
.rkxt-admin-page-count {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--rkxt-text-muted);
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-radius: 999px;
    padding: 2px 10px;
    vertical-align: middle;
    margin-left: 8px;
    white-space: nowrap;
}

.rkxt-admin-page-lead {
    grid-column: 1;
    grid-row: 2;
    color: var(--rkxt-text-muted);
    font-size: 0.9rem;
    margin: 0;
}

.rkxt-admin-empty {
    color: var(--rkxt-text-dim);
    font-size: 0.9rem;
    padding: 24px;
    border: 1px dashed var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    text-align: center;
}

.rkxt-admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 12px;
}

.rkxt-admin-stat {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 14px 16px;
}

.rkxt-admin-stat-label {
    color: var(--rkxt-text-dim);
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 6px;
}

.rkxt-admin-stat-value {
    color: var(--rkxt-text);
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.rkxt-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    /* SIN overflow:hidden: convertía la tabla en contenedor de scroll y rompía el thead sticky
       (se anclaba a la tabla en vez de a .rkxt-admin-content). Con border-collapse el radius casi
       no se ve igual. */
    font-size: 0.9rem;
}

.rkxt-table th, .rkxt-table td {
    text-align: left;
    padding: 10px 14px;
    border-bottom: 1px solid var(--rkxt-border-soft);
}

.rkxt-table th {
    background: var(--rkxt-bg-alt);
    color: var(--rkxt-text-muted);
    font-weight: 600;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Títulos de columna sticky: quedan fijos JUSTO debajo del header + filterbar sticky al
   scrollear el listado. --rkxt-theadtop = alto del header (+ filterbar si existe), lo calcula
   el helper JS de AdminLayout. box-shadow como separador porque con border-collapse el
   border-bottom del th no acompaña al elemento sticky. */
.rkxt-table thead th {
    position: sticky;
    top: var(--rkxt-theadtop, 0px);
    z-index: 10;
    background: var(--rkxt-bg-alt);
    box-shadow: inset 0 -1px 0 var(--rkxt-border);
}

.rkxt-table tbody tr:last-child td { border-bottom: none; }
.rkxt-table tbody tr:hover { background: var(--rkxt-surface-2); }

/* ============ Cabeceras de tabla ORDENABLES (patrón reusable — ver Components/Shared/ThOrden.razor) ============
   Un <th> ordenable pasa a contener un <a class="rkxt-th-sort"> que hereda el look tipográfico del
   th (uppercase/muted/letter-spacing vía "inherit") y agrega: (1) hover con pista sutil "↕" +
   color naranja, (2) columna activa con flecha ▲/▼ siempre visible en color naranja. No cambia el
   alto de fila (mismo tamaño de fuente que el resto del thead) ni rompe el sticky (sigue siendo
   hijo directo del <th>, que es el elemento con position:sticky). */
.rkxt-th-sort {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: inherit;
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    text-decoration: none;
    cursor: pointer;
}
.rkxt-th-sort:hover { color: var(--rkxt-primary); text-decoration: none; }
.rkxt-th-sort-hint {
    opacity: 0;
    font-size: 0.7rem;
    transition: opacity .12s ease;
}
.rkxt-th-sort:hover .rkxt-th-sort-hint { opacity: .5; }
.rkxt-th-sort-active,
.rkxt-th-sort-active:hover { color: var(--rkxt-primary); }
.rkxt-th-sort-arrow {
    font-size: 0.6rem;
    color: var(--rkxt-primary);
}
.rkxt-th-sort:focus-visible {
    outline: 2px solid var(--rkxt-primary);
    outline-offset: 2px;
    border-radius: 2px;
}
.rkxt-th-sort:focus:not(:focus-visible) { outline: none; }

.rkxt-btn-inline { width: auto; padding: 8px 14px; font-size: 0.85rem; }

.rkxt-btn-ghost {
    background: var(--rkxt-surface-2);
    color: var(--rkxt-on-surface);
    border: 1px solid var(--rkxt-border);
    width: auto;
    padding: 11px 16px;
}

.rkxt-btn-ghost:hover {
    background: var(--rkxt-surface);
    border-color: var(--rkxt-primary);
    color: var(--rkxt-on-surface);
}

/* ============ OAuth buttons (Google / Microsoft / etc.) ============ */
.rkxt-auth-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 24px 0 16px;
    color: var(--rkxt-text-muted);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 1px;
}
.rkxt-auth-divider::before,
.rkxt-auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--rkxt-border);
}

.rkxt-oauth-stack {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.rkxt-btn-oauth {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    background: var(--rkxt-surface-2);
    color: var(--rkxt-text);
    border: 1px solid var(--rkxt-border);
    padding: 12px 16px;
    font-weight: 500;
    border-radius: var(--rkxt-radius-sm, 8px);
    cursor: pointer;
    font-family: inherit;
    font-size: 14px;
}
.rkxt-btn-oauth:hover:not(:disabled) {
    border-color: var(--rkxt-primary);
}
.rkxt-btn-oauth:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}
.rkxt-btn-oauth svg {
    flex-shrink: 0;
}
.rkxt-oauth-soon {
    margin-left: auto;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--rkxt-text-muted);
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    padding: 2px 8px;
    border-radius: 999px;
}

/* Estado busy (download / acción async) — pointer-events bloqueado + spinner inline */
.rkxt-btn.rkxt-is-busy,
a.rkxt-is-busy {
    pointer-events: none;
    opacity: 0.85;
    cursor: progress;
}

.rkxt-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: rkxt-spin 0.7s linear infinite;
    margin-right: 8px;
    vertical-align: -2px;
    opacity: 0.8;
}

.rkxt-busy-text {
    font-style: italic;
    opacity: 0.9;
}

@keyframes rkxt-spin {
    to { transform: rotate(360deg); }
}

/* ============================================================================
   Sistema responsive de anchos de formularios admin (refactor 2026-05-28)
   ----------------------------------------------------------------------------
   Antes: .rkxt-form-narrow tenía max-width:720px hardcoded → desperdiciaba la
   mitad del viewport en monitores grandes. Ahora es fluido con cap razonable
   y los field-grids escalan en breakpoints reales (3 col desktop, 2 col tablet,
   1 col mobile).

   Para forms con muchos campos: usar .rkxt-field-grid (3 col), .rkxt-field-grid-2
   (2 col forzado), o .rkxt-field-grid-4 (4 col desktop ancho).
   Para textareas / JSON dentro de un grid: agregar .rkxt-field-full al <label>
   para que ocupe la fila completa.
   ============================================================================ */
.rkxt-form-narrow {
    width: 100%;
    max-width: 1280px;        /* cap para 4K — evita líneas de texto demasiado largas */
}

.rkxt-form-wide {
    width: 100%;
    max-width: none;
    margin-top: 0;
}

.rkxt-form-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 20px;
    flex-wrap: wrap;
}

/* Modificadores de alineación — reemplazan style="justify-content:..." inline. */
.rkxt-form-actions-start { justify-content: flex-start; }
.rkxt-form-actions-split { justify-content: space-between; margin-bottom: 8px; }

.rkxt-field-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
}

.rkxt-field-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.rkxt-field-grid-4 {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
}

/* Tablet / laptop angosto: bajar a 2 columnas para evitar apretar. */
@media (max-width: 1023px) {
    .rkxt-field-grid,
    .rkxt-field-grid-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Mobile: 1 columna full-width. */
@media (max-width: 599px) {
    .rkxt-field-grid,
    .rkxt-field-grid-2,
    .rkxt-field-grid-4 {
        grid-template-columns: 1fr;
    }
}

/* Campo que ocupa toda la fila dentro de un grid (textareas largas, JSON, etc.). */
.rkxt-field-grid .rkxt-field-full,
.rkxt-field-grid-2 .rkxt-field-full,
.rkxt-field-grid-4 .rkxt-field-full {
    grid-column: 1 / -1;
}

/* --- Admin sidebar links (global porque NavLink renderiza <a> fuera del scope CSS isolation) --- */
.rkxt-admin-link {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    margin-bottom: 2px;
    border-radius: var(--rkxt-radius-sm);
    color: var(--rkxt-text-dim);
    font-size: 0.92rem;
    font-weight: 500;
    text-decoration: none;
    border-left: 2px solid transparent;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.rkxt-admin-link-icon {
    display: inline-flex;
    width: 18px;
    justify-content: center;
    font-size: 0.95rem;
    flex-shrink: 0;
}

.rkxt-admin-link:hover {
    background: var(--rkxt-surface);
    color: var(--rkxt-text);
}

.rkxt-admin-link.active {
    background: var(--rkxt-primary-soft);
    color: var(--rkxt-text);
    border-left-color: var(--rkxt-primary);
    font-weight: 600;
}

/* ============================================================================
   Grupos colapsables del sidebar admin — <details>/<summary> nativos.
   ============================================================================ */
.rkxt-admin-group {
    margin: 6px 0;
}

.rkxt-admin-group-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    cursor: pointer;
    color: var(--rkxt-text-dim);
    font-size: 0.74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-radius: var(--rkxt-radius-sm);
    list-style: none;
    user-select: none;
}

/* Suprime el marker default de <summary> */
.rkxt-admin-group-toggle::-webkit-details-marker { display: none; }
.rkxt-admin-group-toggle::marker { display: none; }

.rkxt-admin-group-toggle:hover {
    background: var(--rkxt-surface);
    color: var(--rkxt-text);
}

.rkxt-admin-group-label {
    flex: 1;
}

.rkxt-admin-group-chevron {
    font-size: 0.8rem;
    transition: transform 0.18s ease;
    color: var(--rkxt-text-dim);
}

.rkxt-admin-group[open] > .rkxt-admin-group-toggle .rkxt-admin-group-chevron {
    transform: rotate(180deg);
}

.rkxt-admin-group-items {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding-bottom: 4px;
    animation: rkxtAdminGroupExpand 0.18s ease;
}

@keyframes rkxtAdminGroupExpand {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.rkxt-admin-link-disabled,
.rkxt-admin-link-disabled:hover {
    background: transparent;
    color: var(--rkxt-text-dim);
    cursor: not-allowed;
    opacity: 0.5;
    border-left-color: transparent;
}

.rkxt-admin-section-label {
    display: block;
    margin: 14px 0 4px;
    padding: 0 12px;
    color: var(--rkxt-text-dim);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.7;
}

.rkxt-admin-link.rkxt-admin-link-sub {
    padding-left: 24px;
    font-size: 0.88rem;
}

/* ----------------------------------------------------------------------------
   Sub-grupo anidado (2º nivel) — ej. Integraciones / Diseño dentro de Configuración.
   Reusa <details>/.rkxt-admin-group* del 1er nivel con indentación extra y un
   toggle más chico para leerse como sub-sección.
   ---------------------------------------------------------------------------- */
.rkxt-admin-subgroup {
    margin: 2px 0 2px 8px;
    border-left: 1px solid var(--rkxt-border-soft);
}

.rkxt-admin-subgroup > .rkxt-admin-group-toggle {
    padding-left: 18px;
    font-size: 0.68rem;
    letter-spacing: 0.05em;
}

.rkxt-admin-subgroup > .rkxt-admin-group-toggle .rkxt-admin-link-icon {
    font-size: 0.85rem;
}

/* Los items del sub-grupo se indentan un escalón más que los sub-links de 1er nivel. */
.rkxt-admin-subgroup .rkxt-admin-link.rkxt-admin-link-sub {
    padding-left: 34px;
    font-size: 0.85rem;
}

.rkxt-admin-section-title {
    margin: 32px 0 8px;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--rkxt-text);
    border-bottom: 1px solid var(--rkxt-border);
    padding-bottom: 6px;
}

.rkxt-admin-section-lead {
    margin: 0 0 16px;
    color: var(--rkxt-text-muted);
    font-size: 0.92rem;
}

/* Utilidades chicas de spacing — usar en vez de style="margin-top:..." inline. */
.rkxt-mt-sm { margin-top: .4rem; }

/* Oculta visualmente pero mantiene accesible para lectores de pantalla (H1 semántico sin
   ocupar espacio visual — ej. cabecera compacta del catálogo, título ya cubierto por breadcrumb). */
.rkxt-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Lista compacta dentro de un .rkxt-flash/<details> (avisos, mensajes de resultado bulk). */
.rkxt-list-compact { margin: .4rem 0 0 1rem; }

.rkxt-text-muted {
    color: var(--rkxt-text-muted);
    font-size: 0.85em;
}

.rkxt-auth-success {
    margin: 12px 0;
    padding: 10px 14px;
    border-radius: var(--rkxt-radius-sm);
    background: rgba(46, 204, 113, 0.15);
    color: #2ecc71;
    font-weight: 500;
}

.rkxt-field-inline {
    flex-direction: column;
    min-width: 220px;
}

/* ===== Stock — pantalla de consulta + ajuste de inventario ===== */
.rkxt-stock-table td {
    vertical-align: middle;
}

.rkxt-stock-thumb {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: var(--rkxt-radius-sm);
    border: 1px solid var(--rkxt-border);
    background: var(--rkxt-surface-2);
    display: block;
}

.rkxt-stock-thumb-empty {
    display: inline-block;
}

/* Swatch de color reusable (alineado con el chip del editor de Atributos). */
.rkxt-color-chip {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 4px;
    border: 1px solid var(--rkxt-border);
    vertical-align: middle;
    margin-right: 6px;
}

.rkxt-stock-adjust {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
}

.rkxt-stock-step {
    padding: 6px 10px;
    font-size: 1rem;
    line-height: 1;
    min-width: 34px;
}

.rkxt-stock-qty {
    width: 72px;
    text-align: right;
}

.rkxt-stock-motivo {
    flex: 1;
    min-width: 90px;
    font-size: 0.85rem;
}

.rkxt-stock-save {
    padding: 6px 14px;
    white-space: nowrap;
}

.rkxt-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 18px;
    flex-wrap: wrap;
}

.rkxt-pager-info {
    color: var(--rkxt-text-muted);
    font-size: 0.85rem;
}

.rkxt-pager-nav {
    display: flex;
    gap: 8px;
}

.rkxt-filterbar {
    display: flex;
    gap: 12px;
    align-items: flex-end;
    flex-wrap: wrap;
    /* Sticky: la barra de filtros es parte de la cabecera → queda fija justo debajo del header
       sticky mientras se scrollea el listado. --rkxt-adminhdr-h la calcula el helper JS de
       AdminLayout (alto real del header, que varía con el largo del lead). Fondo opaco + borde
       para que las filas de la tabla no se transparenten por debajo. */
    position: sticky;
    top: var(--rkxt-adminhdr-h, 68px);
    z-index: 20;
    background: var(--rkxt-bg);
    padding: 10px 0 12px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--rkxt-border);
}

/* Barra de acciones/toggle que queda sticky JUSTO debajo del filterbar (ej. vista Lista/Pivote de
   Stock). El helper JS de AdminLayout calcula --rkxt-stickytoolbar-top = alto header + filterbar. */
.rkxt-sticky-toolbar {
    position: sticky;
    top: var(--rkxt-stickytoolbar-top, 120px);
    z-index: 15;
    background: var(--rkxt-bg);
    padding: 8px 0 10px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--rkxt-border);
}

.rkxt-btn-danger {
    background: #b91c1c;
    color: #fff;
    border: none;
}

.rkxt-btn-danger:hover:not(:disabled) {
    background: #991b1b;
}

.rkxt-btn-danger:disabled {
    background: #4a1f1f;
    color: #a1a1aa;
    cursor: not-allowed;
    opacity: 0.6;
}

.rkxt-tr-add {
    background: rgba(235, 82, 2, 0.05);
}

.rkxt-tr-add input {
    font-size: 0.9rem;
}

.rkxt-flash {
    margin: 0 0 16px 0;
    padding: 12px 16px;
    border-radius: var(--rkxt-radius-sm);
    font-weight: 500;
    border-left: 4px solid;
}

.rkxt-flash-ok {
    background: rgba(46, 204, 113, 0.12);
    color: #2ecc71;
    border-left-color: #2ecc71;
}

.rkxt-flash-error {
    background: rgba(220, 38, 38, 0.12);
    color: #ef4444;
    border-left-color: #dc2626;
}

.rkxt-flash-section {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    opacity: 0.75;
    margin-right: 6px;
}

.rkxt-import-tabs {
    display: flex;
    gap: 4px;
    margin: 20px 0 0 0;
    border-bottom: 2px solid var(--rkxt-border);
}

.rkxt-import-tab {
    padding: 10px 18px;
    color: var(--rkxt-text-muted);
    text-decoration: none;
    font-weight: 500;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: color 0.12s, border-color 0.12s;
}

/* Fase 4 navegación: tabla de override por tienda×categoría */
.rkxt-table-wrap {
    overflow-x: auto;
    margin-bottom: 16px;
}

.rkxt-nav-table .rkxt-nav-col { width: 120px; }
.rkxt-nav-table .rkxt-nav-col-orden { width: 90px; }
.rkxt-nav-table .rkxt-nav-col-nombre { width: 220px; }
.rkxt-nav-table td { vertical-align: middle; }
.rkxt-nav-cat-nombre { font-weight: 500; }
.rkxt-nav-table .rkxt-input-sm { width: 100%; }

/* Los tabs también se usan como <button> (paneles que cambian sin navegar). */
button.rkxt-import-tab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    font: inherit;
}

.rkxt-import-tab:hover {
    color: var(--rkxt-text);
}

.rkxt-import-tab.rkxt-import-tab-active {
    color: var(--rkxt-primary);
    border-bottom-color: var(--rkxt-primary);
    font-weight: 600;
}

.rkxt-import-card {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-top: none;
    padding: 24px;
    border-radius: 0 0 var(--rkxt-radius) var(--rkxt-radius);
    margin-bottom: 24px;
}

/* Sub-panel "Cómo se arma la plantilla" dentro de un .rkxt-import-card — agrupa checkboxes
   de configuración con jerarquía propia (título + lead). Ver Materializar.razor (objetivos). */
.rkxt-plantilla-opciones {
    margin-top: 20px;
    padding: 16px 18px;
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
}
.rkxt-plantilla-opciones-title {
    margin: 0 0 4px;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--rkxt-text);
}
.rkxt-plantilla-opciones-lead {
    margin: 0 0 14px;
    color: var(--rkxt-text-muted);
    font-size: 0.85rem;
}
.rkxt-plantilla-opciones .rkxt-field-check-block { margin-bottom: 14px; }
.rkxt-plantilla-opciones .rkxt-field-check-block:last-child { margin-bottom: 0; }
/* Callout indentado a la altura del texto del checkbox (16px casilla + 10px gap). */
.rkxt-plantilla-opciones .rkxt-callout { margin: 6px 0 14px 26px; }

/* Mini-callout genérico para destacar una decisión dependiente de un switch (ej. método
   de curva cuando Modo estricto está activo). Reusable fuera de .rkxt-plantilla-opciones. */
.rkxt-callout {
    padding: 12px 14px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
}
.rkxt-callout .rkxt-field { margin-bottom: 0; }
.rkxt-callout-primary {
    border-color: color-mix(in srgb, var(--rkxt-primary) 30%, var(--rkxt-border));
    border-left: 3px solid var(--rkxt-primary);
    background: var(--rkxt-primary-soft);
}

.rkxt-import-step {
    margin: 20px 0;
    padding: 16px;
    background: var(--rkxt-bg);
    border-radius: var(--rkxt-radius-sm);
}

.rkxt-import-step h3 {
    margin: 0 0 8px 0;
    font-size: 1rem;
    color: var(--rkxt-text);
}

.rkxt-import-row-ok {
    background: rgba(46, 204, 113, 0.06);
}

.rkxt-import-row-omit {
    background: rgba(245, 158, 11, 0.06);
    opacity: 0.8;
}

.rkxt-import-row-error {
    background: rgba(220, 38, 38, 0.08);
}

/* =============================================================
   Storefront (Capa B — theming switcheable por tenant)
   El wrapper .rkxt-shell recibe CSS vars inline desde StorefrontLayout
   con los valores del Tema asignado a la Tienda. Esto deja la identidad
   del producto (Capa A) intacta para admin.
   ============================================================= */

.rkxt-shell {
    --rkxt-sf-radius: 12px;
    background: var(--rkxt-bg);
    color: var(--rkxt-text);
    min-height: 100vh;
    font-family: var(--rkxt-font-body);
    /* Guard anti scroll horizontal: los breakouts full-bleed (.rkxt-sf-pagina / secciones
       ancho-completo) usan width:100vw, que en presencia de scrollbar vertical es levemente
       más ancho que el viewport visible → asomaría 1px de scroll horizontal. `clip` lo recorta
       sin crear contenedor de scroll (no rompe position:sticky como haría overflow:hidden) y no
       altera el cálculo del breakout (se aplica en un ancestro, no en el elemento que rompe). */
    overflow-x: clip;
}

/* Barra promocional (franja superior, chrome). Fondo/color vienen inline (config de tienda).
   Mensajes rotan con rkxt-promobar.js; solo el .is-active se ve. */
.rkxt-sf-promobar {
    text-align: center;
    padding: 9px 16px;
    font-size: .78rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-weight: 600;
    line-height: 1.2;
}
.rkxt-sf-promobar-msg { display: none; }
.rkxt-sf-promobar-msg.is-active { display: inline-block; }

/* Tamaño del texto de la promobar (componente del motor: prop "tamano"). */
.rkxt-sf-promobar.rkxt-pb-sm { font-size: .70rem; }
.rkxt-sf-promobar.rkxt-pb-normal { font-size: .78rem; }
.rkxt-sf-promobar.rkxt-pb-lg { font-size: .92rem; }
/* Espaciado entre letras (prop "tracking"). */
.rkxt-sf-promobar.rkxt-pb-tk-amplio { letter-spacing: .12em; }
.rkxt-sf-promobar.rkxt-pb-tk-extra  { letter-spacing: .22em; }

/* Efecto deslizante (clon de kosiuko.com): un mensaje ENTRA desde la izquierda al centro, se queda
   quieto (JS: data-pausa) y SALE hacia la derecha; loop con el siguiente. rkxt-promobar.js alterna las
   clases is-center/is-exit. Los mensajes se apilan en la MISMA celda de grid (altura natural, sin
   position:absolute) y lo que sale de cuadro se recorta con overflow:hidden. */
.rkxt-sf-promobar--deslizar { display: grid; overflow: hidden; }
.rkxt-sf-promobar--deslizar .rkxt-sf-promobar-msg {
    grid-area: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: translateX(-120%);
    opacity: 0;
    transition: transform .65s cubic-bezier(.22, .61, .36, 1), opacity .4s ease;
    will-change: transform, opacity;
}
.rkxt-sf-promobar--deslizar .rkxt-sf-promobar-msg.is-reset  { transform: translateX(-120%); opacity: 0; transition: none; }
.rkxt-sf-promobar--deslizar .rkxt-sf-promobar-msg.is-center { transform: translateX(0);     opacity: 1; }
.rkxt-sf-promobar--deslizar .rkxt-sf-promobar-msg.is-exit   { transform: translateX(120%);  opacity: 0; }
/* Sentido invertido (der → izq): entra desde la derecha y sale por la izquierda. Mismo JS (is-reset/
   is-center/is-exit); solo se invierten los ejes de entrada/salida. */
.rkxt-sf-promobar--deslizar.is-invertido .rkxt-sf-promobar-msg          { transform: translateX(120%); }
.rkxt-sf-promobar--deslizar.is-invertido .rkxt-sf-promobar-msg.is-reset { transform: translateX(120%); transition: none; }
.rkxt-sf-promobar--deslizar.is-invertido .rkxt-sf-promobar-msg.is-center{ transform: translateX(0); }
.rkxt-sf-promobar--deslizar.is-invertido .rkxt-sf-promobar-msg.is-exit  { transform: translateX(-120%); }

/* Efecto marquesina: una sola fila que se desplaza en loop continuo (sin JS). El track lleva
   los mensajes duplicados ×2 y se traslada -50% → al terminar la 1ª copia, la 2ª está calzada. */
.rkxt-sf-promobar--marquesina { overflow: hidden; white-space: nowrap; padding-left: 0; padding-right: 0; }
.rkxt-sf-promobar--marquesina .rkxt-sf-promobar-track {
    display: inline-flex;
    will-change: transform;
    animation: rkxt-pb-marquee linear infinite;
}
.rkxt-sf-promobar--marquesina .rkxt-sf-promobar-item { padding: 0 2.5em; flex: 0 0 auto; }
@keyframes rkxt-pb-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
    .rkxt-sf-promobar--marquesina .rkxt-sf-promobar-track { animation: none; }
}

/* Celular: mensaje rotativo más compacto (menos tracking) para que no se corte ni apriete
   en 390px. El texto ya envuelve (no hay nowrap); acá solo aflojamos densidad. */
@media (max-width: 520px) {
    .rkxt-sf-promobar {
        padding: 8px 14px;
        font-size: .72rem;
        letter-spacing: .04em;
    }
}

.rkxt-sf-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--rkxt-hpad, 18px) 32px;
    border-bottom: 1px solid var(--rkxt-border);
    background: var(--rkxt-surface);
}

/* Header sticky (prop del componente Encabezado): sigue al scroll pegado arriba. El shell usa
   overflow-x:clip (no overflow:hidden) así que el sticky funciona. La promobar queda arriba y se
   va con el scroll; el header se ancla en top:0 (estilo kosiuko). */
.rkxt-sf-header--sticky { position: sticky; top: 0; }
/* Header transparente sobre el hero: arranca glassy y se vuelve sólido al scrollear (rkxt-header.js
   le agrega .is-solid). Sin overlap del hero en v1 (eso queda para "abrir piezas"). */
.rkxt-sf-header--transp { background: color-mix(in srgb, var(--rkxt-surface) 18%, transparent); backdrop-filter: blur(6px); border-bottom-color: transparent; transition: background .25s ease, border-color .25s ease; }
.rkxt-sf-header--transp.is-solid { background: var(--rkxt-surface); border-bottom-color: var(--rkxt-border); backdrop-filter: none; }

.rkxt-sf-brand {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--rkxt-text);
    font-weight: 700;
    font-size: 1.15rem;
}

/* El "logo" del header clásico escala con header.logo_altura (--rkxt-hlogo). Los factores
   están calibrados para que el default (52px) se vea ~igual que antes (mark 36px, nombre 18px). */
.rkxt-sf-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: calc(var(--rkxt-hlogo, 52px) * 0.69);
    height: calc(var(--rkxt-hlogo, 52px) * 0.69);
    border-radius: 8px;
    background: var(--rkxt-grad-primary);
    color: var(--rkxt-fg-on-primary);
    font-weight: 800;
    font-size: calc(var(--rkxt-hlogo, 52px) * 0.28);
    flex-shrink: 0;
}

/* Nombre de la tienda como logo-texto (cuando no hay imagen de logo cargada). */
.rkxt-sf-brand-name {
    font-size: calc(var(--rkxt-hlogo, 52px) * 0.35);
    line-height: 1;
}

/* Logo real de la tienda (sLogoUrl) en el header. */
.rkxt-sf-brand-logo {
    height: var(--rkxt-hlogo, 52px);
    width: auto;
    max-width: 280px;
    object-fit: contain;
    display: block;
}

.rkxt-sf-nav {
    display: flex;
    gap: 24px;
}

.rkxt-sf-nav a {
    color: var(--rkxt-text-muted);
    text-decoration: none;
    font-weight: 500;
}

.rkxt-sf-nav a:hover {
    color: var(--rkxt-primary);
}

/* Botón "vaciar carrito" del header (config carrito.mostrar_limpiar_header). */
.rkxt-sf-nav-cart-clear {
    display: inline-flex;
    margin: 0;
}
.rkxt-sf-nav-cart-clear button {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    color: var(--rkxt-text-muted);
    padding: 0 2px;
}
.rkxt-sf-nav-cart-clear button:hover {
    color: var(--rkxt-primary);
}

/* ============================================================
   RESPONSIVE del HEADER CLÁSICO (.rkxt-sf-header).
   El patrón desktop (brand + search 380px + nav en una fila) NO entra en
   celular/tablet. Estrategia mobile-first dentro de @media (desktop-first
   para consistencia con el resto del archivo):
     · ≤900 (tablet): la fila pasa a wrap; brand + nav arriba (space-between),
       search baja a una 2ª fila full-width (flex-basis:100%). El search ya no
       empuja el layout porque ocupa su propia línea.
     · ≤520 (celular): nav más compacta (gap chico), brand más chico,
       search sigue full-width abajo. Nada desborda el viewport.
   El header centrado tiene su propio bloque responsive (más abajo, 640).
   ============================================================ */
@media (max-width: 900px) {
    /* :not(.rkxt-sf-header-centro) → no tocar el header centrado, que es display:grid y
       tiene su propio bloque responsive (640). Acá solo el clásico (flex). */
    .rkxt-sf-header:not(.rkxt-sf-header-centro) {
        flex-wrap: wrap;
        padding: 14px 16px;
        row-gap: 12px;
    }
    /* search ocupa una fila propia, full-width — no empuja brand/nav */
    .rkxt-sf-search {
        order: 3;
        flex: 1 1 100%;
        margin: 0;
    }
    /* brand + nav comparten la 1ª fila */
    .rkxt-sf-brand { order: 1; }
    .rkxt-sf-nav   { order: 2; gap: 16px; }
}
@media (max-width: 520px) {
    .rkxt-sf-header:not(.rkxt-sf-header-centro) {
        padding: 12px 16px;
    }
    .rkxt-sf-brand {
        font-size: 1rem;
        gap: 8px;
        min-width: 0;            /* permite truncar el nombre largo sin desbordar */
    }
    .rkxt-sf-brand-name {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 1.05rem;       /* en celular cap el logo-texto, sin importar logo_altura */
    }
    .rkxt-sf-brand-mark {
        width: 34px;
        height: 34px;
        font-size: 0.85rem;
    }
    .rkxt-sf-brand-logo {
        height: 38px;
        max-width: 150px;
    }
    .rkxt-sf-nav {
        gap: 14px;
        font-size: 0.95rem;
    }
}

/* ============================================================
   HEADER MODO "CENTRADO" (estilo kosiuko.com) — opt-in por config.
   Grid de 3 columnas: hamburguesa izq · logo/nombre centrado · íconos der.
   El header clásico (.rkxt-sf-header flex) queda intacto.
   ============================================================ */
.rkxt-sf-header-centro {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 16px;
    /* border-bottom + padding heredados de .rkxt-sf-header */
}

/* Col 1 — botón hamburguesa (abre el drawer) */
.rkxt-sf-hamb {
    justify-self: start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: var(--rkxt-radius-sm, 8px);
    background: none;
    color: inherit;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}
.rkxt-sf-hamb:hover {
    background: var(--rkxt-surface-2);
    color: var(--rkxt-primary);
}
.rkxt-sf-hamb svg {
    width: 24px;
    height: 24px;
    display: block;
}

/* Col 2 — brand centrado (logo o nombre grande tipo kosiuko) */
.rkxt-sf-brand-centro {
    justify-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    color: var(--rkxt-text);
    max-width: 100%;
}
.rkxt-sf-brand-centro .rkxt-sf-brand-logo {
    /* Altura configurable (config header.logo_altura → var inline). El logo crece hasta ese
       alto y a lo ancho hasta el límite del header centrado (logo ancho tipo "KOSIUKO"). */
    height: var(--rkxt-hlogo, 52px);
    max-width: min(92%, 820px);
    width: auto;
    object-fit: contain;
}
/* Padding vertical del header centrado configurable (config header.padding_vertical → var). */
.rkxt-sf-header-centro {
    padding-top: var(--rkxt-hpad, 18px);
    padding-bottom: var(--rkxt-hpad, 18px);
}
.rkxt-sf-brand-name-centro {
    font-family: var(--rkxt-font-serif, var(--rkxt-font-display));
    font-size: 1.9rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--rkxt-text);
    white-space: nowrap;
    /* compensa el letter-spacing para que quede ópticamente centrado */
    padding-left: 0.18em;
}

/* ===== Altura del header centrado (config header.altura) =====
   El render emite rkxt-sf-header-alto-{compacto|normal|grande} junto a rkxt-sf-header-centro.
   Cada altura ajusta el padding vertical de la barra + el tamaño del logo/nombre de marca.
   `normal` = el default actual (padding 18px del .rkxt-sf-header + logo 52px / nombre 1.9rem),
   se declara explícito por claridad y para ganarle a la cascada si hace falta. */

/* COMPACTO — barra baja, deja más aire para el hero. Logo/nombre más chicos. */
.rkxt-sf-header-alto-compacto {
    padding-top: 10px;
    padding-bottom: 10px;
}
.rkxt-sf-header-alto-compacto .rkxt-sf-brand-logo {
    height: 38px;
}
.rkxt-sf-header-alto-compacto .rkxt-sf-brand-name-centro {
    font-size: 1.45rem;
    letter-spacing: 0.14em;
    padding-left: 0.14em;
}

/* NORMAL — default actual (explícito). */
.rkxt-sf-header-alto-normal {
    padding-top: 18px;
    padding-bottom: 18px;
}
.rkxt-sf-header-alto-normal .rkxt-sf-brand-logo {
    height: 52px;
}
.rkxt-sf-header-alto-normal .rkxt-sf-brand-name-centro {
    font-size: 1.9rem;
}

/* GRANDE — barra amplia con mucho aire vertical, logo/nombre destacados (estilo kosiuko:
   "KOSIUKO" grande y respirado arriba del hero). */
.rkxt-sf-header-alto-grande {
    padding-top: 34px;
    padding-bottom: 34px;
}
.rkxt-sf-header-alto-grande .rkxt-sf-brand-logo {
    height: 90px;
    max-width: 620px;   /* logo ancho tipo "KOSIUKO": deja que crezca a lo ancho */
    width: auto;
}
.rkxt-sf-header-alto-grande .rkxt-sf-brand-name-centro {
    font-size: 2.6rem;
    letter-spacing: 0.26em;
    padding-left: 0.26em;
}

/* Col 3 — íconos a la derecha (lupa, user, wishlist, carrito) */
.rkxt-sf-header-icons {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.rkxt-sf-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--rkxt-radius-sm, 8px);
    color: inherit;
    text-decoration: none;
    font-size: 1.05rem;
    line-height: 1;
    transition: background-color .15s ease, color .15s ease;
}
.rkxt-sf-icon:hover {
    background: var(--rkxt-surface-2);
    color: var(--rkxt-primary);
}
.rkxt-sf-icon svg {
    width: 22px;
    height: 22px;
    display: block;
}

/* Cuenta con saludo — header CENTRADO. El ícono de "Mi cuenta" (estado logueado) se ensancha para
   mostrar el primer nombre del cliente al lado del ícono; lo escribe rkxt-sesion.js client-side. */
.rkxt-sf-icon-cuenta {
    width: auto;
    gap: 6px;
    padding: 0 10px;
    font-size: 0.9rem;
    font-weight: 600;
    max-width: 170px;
}
.rkxt-sf-cuenta-nombre {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Saludo "Hola, {nombre}" — header CLÁSICO (link del nav, hereda el estilo de .rkxt-sf-nav a). */
.rkxt-sf-cuenta-link { font-weight: 600; }
/* El [hidden] del estado inactivo debe ganarle al display de los íconos/nav (sino se ven los DOS
   estados: la silueta con nombre Y la de "Ingresar"). .rkxt-sf-icon usa inline-flex y pisa [hidden]. */
[data-rkxt-sesion-auth][hidden],
[data-rkxt-sesion-anon][hidden] { display: none !important; }

/* Badge contador posicionado arriba-derecha del ícono (override del flujo
   inline que usa .rkxt-sf-badge en el header clásico). */
.rkxt-sf-icon .rkxt-sf-badge {
    position: absolute;
    top: 2px;
    right: 2px;
    margin: 0;
    min-width: 16px;
    height: 16px;
    border-radius: 8px;
    font-size: 0.62rem;
    border: 2px solid var(--rkxt-surface);
    box-sizing: content-box;
    pointer-events: none;
}

/* ============================================================
   DRAWER lateral izquierdo (menú del header centrado / mobile).
   Oculto por defecto; el JS le agrega .is-open.
   ============================================================ */
.rkxt-sf-drawer {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1100;
    background: rgba(0, 0, 0, 0.45);
}
.rkxt-sf-drawer.is-open {
    display: block;
}
.rkxt-sf-drawer-panel {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 300px;
    max-width: 85vw;
    background: var(--rkxt-surface);
    border-right: 1px solid var(--rkxt-border);
    box-shadow: 4px 0 24px rgba(0, 0, 0, 0.18);
    padding: 18px 0;
    overflow-y: auto;
    /* slide-in desde la izquierda */
    transform: translateX(-100%);
    transition: transform .25s ease;
}
.rkxt-sf-drawer.is-open .rkxt-sf-drawer-panel {
    transform: translateX(0);
}
.rkxt-sf-drawer-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin: 0 12px 8px;
    padding: 0;
    border: none;
    border-radius: var(--rkxt-radius-sm, 8px);
    background: none;
    color: var(--rkxt-text-muted);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}
.rkxt-sf-drawer-close:hover {
    background: var(--rkxt-surface-2);
    color: var(--rkxt-primary);
}
.rkxt-sf-drawer-nav {
    display: flex;
    flex-direction: column;
}
.rkxt-sf-drawer-nav a {
    display: block;
    padding: 14px 24px;
    color: var(--rkxt-text);
    text-decoration: none;
    font-size: 1rem;
    font-weight: 500;
    border-bottom: 1px solid var(--rkxt-border);
    transition: background-color .15s ease, color .15s ease;
}
.rkxt-sf-drawer-nav a:hover {
    background: var(--rkxt-surface-2);
    color: var(--rkxt-primary);
}

/* ---- Mega-menú compuesto (menu.modo=="compuesto") ----
   Panel ANCHO armado con el motor de secciones (Chrome:Menu). Reusa .rkxt-sf-drawer (velo + is-open +
   rkxt-drawer.js), pero el panel es ancho, full-height y desliza a velocidad configurable
   (--rkxt-mega-vel, seteada inline por StorefrontLayout desde menu.compuesto_velocidad). */
.rkxt-sf-drawer--mega .rkxt-sf-mega-panel {
    /* Full-width real (estilo kosiuko): el panel ocupa TODO el ancho de la ventana, sea cual sea el
       tamaño. Altura = contenido (dropdown desde arriba), no full-height. Sin scroll horizontal. */
    width: 100%;
    max-width: 100%;
    bottom: auto;
    max-height: 100vh;
    padding: 0;
    overflow-x: hidden;
    overflow-y: auto;
    transition: transform var(--rkxt-mega-vel, 350ms) cubic-bezier(.22, .61, .36, 1);
}
/* Dentro del panel las secciones fluyen simples: sin cap 1200, sin full-bleed (calc con viewport),
   sin márgenes negativos → nunca desbordan ni generan scroll horizontal. Las columnas se reparten. */
.rkxt-sf-mega-body .rkxt-sf-sec,
.rkxt-sf-mega-body .rkxt-sf-sec-ancho-contenido,
.rkxt-sf-mega-body .rkxt-sf-sec-ancho-completo {
    width: auto;
    max-width: none;
    margin-inline: 0;
    padding-inline: 0;
}
.rkxt-sf-mega-body .rkxt-sf-sec-cols {
    max-width: none;
    margin-inline: 0;
}
/* Sentido der→izq: el panel entra desde la derecha. La regla .is-open lo lleva a translateX(0). */
.rkxt-sf-drawer--mega-der .rkxt-sf-mega-panel {
    left: auto;
    right: 0;
    border-right: none;
    border-left: 1px solid var(--rkxt-border);
    box-shadow: -4px 0 24px rgba(0, 0, 0, 0.18);
    transform: translateX(100%);
}
.rkxt-sf-drawer--mega .rkxt-sf-drawer-close {
    position: absolute;
    top: 14px;
    right: 16px;
    margin: 0;
    z-index: 2;
}
.rkxt-sf-mega-body {
    padding: 40px 44px 48px;
}
.rkxt-sf-mega-empty {
    padding: 20px 4px;
    color: var(--rkxt-text-muted);
    max-width: 460px;
}
.rkxt-sf-mega-empty-sub {
    font-size: 0.9rem;
    margin-top: 8px;
    line-height: 1.5;
}
/* Mega-menú: las columnas estiran a la altura de la fila (= columna más alta) para que una imagen con
   "Rellenar alto" ocupe TODO el alto del panel, pegada a los bordes (look kosiuko de la foto promo). */
.rkxt-sf-mega-body .rkxt-sf-sec-cols { align-items: stretch; }

/* Imagen que rellena el alto de su columna (.rkxt-sf-sec-col es flex-column → la foto crece con flex:1). */
.rkxt-sf-img.is-rellenar {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
}
.rkxt-sf-img.is-rellenar .rkxt-sf-img-marco {
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
    display: block;
}
.rkxt-sf-img.is-rellenar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Columna de categorías (componente ColumnaCategorias) dentro del mega-menú. */
.rkxt-sf-mmcol { min-width: 150px; }
.rkxt-sf-mmcol-head {
    display: block;
    font-weight: 700;
    font-size: 0.82rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--rkxt-text);
    text-decoration: none;
    margin-bottom: 14px;
}
.rkxt-sf-mmcol-head:hover { color: var(--rkxt-primary); }
.rkxt-sf-mmcol-links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.rkxt-sf-mmcol-links a {
    color: var(--rkxt-text-muted);
    text-decoration: none;
    font-size: 0.95rem;
    transition: color .15s ease;
}
.rkxt-sf-mmcol-links a:hover { color: var(--rkxt-primary); }
.rkxt-sf-mmcol-verall { font-weight: 600; color: var(--rkxt-text); }
.rkxt-sf-mmcol-sub > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--rkxt-text-muted);
    font-size: 0.95rem;
}
.rkxt-sf-mmcol-sub > summary::-webkit-details-marker { display: none; }
.rkxt-sf-mmcol-sub[open] > summary { color: var(--rkxt-text); font-weight: 600; }
.rkxt-sf-mmcol-caret { font-size: 0.7rem; transition: transform .2s ease; }
.rkxt-sf-mmcol-sub[open] .rkxt-sf-mmcol-caret { transform: rotate(180deg); }
.rkxt-sf-mmcol-sub ul {
    list-style: none;
    margin: 6px 0 4px;
    padding: 0 0 0 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.rkxt-sf-mmcol-sub ul a { font-size: 0.9rem; color: var(--rkxt-text-muted); text-decoration: none; }
.rkxt-sf-mmcol-sub ul a:hover { color: var(--rkxt-primary); }

/* Link destacado en MenuLinks (ej. JOIN THE SALE). El color inline lo pinta; acá solo el peso. */
.rkxt-sf-ml-destacado { font-weight: 700; }

/* Submenú desplegable ▾ de un link de MenuLinks (ej. JOIN THE SALE → sub-items curados). */
.rkxt-sf-ml-sub > summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.rkxt-sf-ml-sub > summary::-webkit-details-marker { display: none; }
.rkxt-sf-ml-sub[open] .rkxt-sf-mmcol-caret { transform: rotate(180deg); }
.rkxt-sf-ml-sub ul {
    list-style: none;
    margin: 8px 0 4px;
    padding: 0 0 0 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.rkxt-sf-ml-sub ul a {
    color: var(--rkxt-text-muted);
    text-decoration: none;
    font-size: 0.92rem;
}
.rkxt-sf-ml-sub ul a:hover { color: var(--rkxt-primary); }

/* Trigger del mega-menú en el header clásico (el centrado usa la hamburguesa). */
.rkxt-sf-nav-megatrigger {
    background: none;
    border: none;
    cursor: pointer;
    font: inherit;
    color: inherit;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
}
.rkxt-sf-nav-megatrigger:hover { color: var(--rkxt-primary); }
.rkxt-sf-nav-megacaret { font-size: 0.7rem; }

@media (max-width: 720px) {
    .rkxt-sf-mega-body { padding: 28px 20px 36px; }
    .rkxt-sf-drawer--mega .rkxt-sf-mega-panel { width: 97vw; }
}

/* Responsive — header centrado en mobile: logo y controles más compactos */
@media (max-width: 640px) {
    .rkxt-sf-header-centro {
        padding: 12px 16px;
        gap: 8px;
    }
    .rkxt-sf-brand-centro .rkxt-sf-brand-logo {
        height: 38px;
        max-width: 180px;
    }
    .rkxt-sf-brand-name-centro {
        font-size: 1.3rem;
        letter-spacing: 0.12em;
        padding-left: 0.12em;
    }
    .rkxt-sf-hamb,
    .rkxt-sf-icon {
        width: 36px;
        height: 36px;
    }
    .rkxt-sf-header-icons {
        gap: 2px;
    }
    /* En mobile las 3 alturas se aplanan a un tamaño cómodo (sin headers gigantes que coman
       toda la pantalla). Igualamos/superamos la especificidad de las reglas -alto-* de arriba. */
    .rkxt-sf-header-alto-compacto,
    .rkxt-sf-header-alto-normal,
    .rkxt-sf-header-alto-grande {
        padding-top: 12px;
        padding-bottom: 12px;
    }
    .rkxt-sf-header-alto-compacto .rkxt-sf-brand-logo,
    .rkxt-sf-header-alto-normal .rkxt-sf-brand-logo,
    .rkxt-sf-header-alto-grande .rkxt-sf-brand-logo {
        height: 40px;
        max-width: 200px;
    }
    .rkxt-sf-header-alto-compacto .rkxt-sf-brand-name-centro,
    .rkxt-sf-header-alto-normal .rkxt-sf-brand-name-centro,
    .rkxt-sf-header-alto-grande .rkxt-sf-brand-name-centro {
        font-size: 1.4rem;
        letter-spacing: 0.12em;
        padding-left: 0.12em;
    }
}

.rkxt-sf-main {
    max-width: 1200px;
    margin: 0 auto;
    /* El padding-TOP es configurable por tienda (grupo "Espaciado", default 0 = hero pegado al
       header, look kosiuko). El aire lateral e inferior los necesita el contenido boxed
       (catálogo/categoría/producto). El lateral baja con clamp en celular (16px) → desktop (32px)
       para que el contenido no quede ahogado en 390px sin tocar el desktop. Las secciones
       full-bleed (.rkxt-sf-pagina, hijo directo de este main) heredan este top → con 0 arrancan
       justo bajo el header; su margin:calc(50%-50vw) ignora el padding lateral (full-bleed real). */
    padding: var(--rkxt-sf-espacio-superior, 0) clamp(16px, 4vw, 32px) clamp(24px, 4vw, 32px);
}

/* Ancho completo (config catalogo.ancho_completo) — sin cap de 1200px. */
.rkxt-sf-main.rkxt-sf-main--full {
    max-width: none;
}

/* === Ancho completo GLOBAL (grupo "Diseño") — flag en el wrapper raíz .rkxt-shell ===
   Cuando está activo, NINGÚN elemento de NINGUNA página queda capeado a 1200px: el main, las
   secciones del motor (las "contenido" re-centradas y los moldes atómicos re-capeados), el
   catálogo, la barra del mega-menú y el footer-motor pasan a ocupar todo el ancho. Las secciones
   "contenido" conservan un gutter lateral fluido para que el texto no quede pegado al borde;
   las "completo" (hero/imágenes/banners) ya van edge-to-edge por su propio modelo full-bleed. */
.rkxt-shell--full .rkxt-sf-main { max-width: none; }
.rkxt-shell--full .rkxt-sf-sec-ancho-contenido { max-width: none; }
.rkxt-shell--full .rkxt-mm-bar { max-width: none; }
.rkxt-shell--full .rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-texto,
.rkxt-shell--full .rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-cbtn-wrap,
.rkxt-shell--full .rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-section,
.rkxt-shell--full .rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-newsletter,
.rkxt-shell--full .rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-nlform { max-width: none; }

.rkxt-sf-footer {
    display: flex;
    flex-wrap: wrap;            /* en celular las dos líneas envuelven en vez de desbordar */
    gap: 6px 16px;
    justify-content: space-between;
    align-items: center;
    padding: 18px clamp(16px, 4vw, 32px);
    border-top: 1px solid var(--rkxt-border);
    color: var(--rkxt-text-muted);
    font-size: 0.85rem;
}

.rkxt-sf-footer a {
    color: var(--rkxt-primary);
}

.rkxt-sf-footer-meta {
    opacity: 0.6;
}

/* Celular: footer mínimo apila copyright + meta centrados (en vez de space-between apretado). */
@media (max-width: 520px) {
    .rkxt-sf-footer {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 8px;
    }
}

.rkxt-sf-empty {
    text-align: center;
    padding: 80px 24px;
}

.rkxt-sf-empty h1 {
    margin-bottom: 12px;
}

.rkxt-sf-empty p {
    color: var(--rkxt-text-muted);
    margin-bottom: 24px;
}

/* ============================================================================
   Ajuste de imagen para componentes de DISEÑO (heroes, banners, fondos de sección).
   Patrón canónico de 2 capas para que el ajuste (brillo/contraste/saturación) afecte
   SOLO la foto y el velo de oscurecimiento sea independiente del filter:
     ::before = la FOTO (background-image + filter)  → recibe --img-filtro
     ::after  = el VELO negro (opacity)              → recibe --img-oscuro, NO el filter
   El contenido va por encima con position:relative + z-index. Las vars (--img-foto,
   --img-filtro, --img-oscuro, --img-pos-y) las inyecta cada molde inline (regla 11).
   NO aplica al catálogo PIM (fotos de producto) — solo a componentes de diseño.
   ============================================================================ */
.rkxt-sf-img-ajustable {
    position: relative;
    overflow: hidden;
}
.rkxt-sf-img-ajustable::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: var(--img-foto);
    background-size: cover;
    background-position: var(--img-pos-x, 50%) var(--img-pos-y, 50%);
    /* Zoom opcional (--img-escala, default 1 = sin cambio). Amplía la foto cover y, con
       overflow:hidden del contenedor, habilita reposición vertical/horizontal aunque la
       imagen encaje exacto en el contenedor (foto apaisada en hero ancho). */
    transform: scale(var(--img-escala, 1));
    filter: var(--img-filtro, none);
    z-index: 0;
}
.rkxt-sf-img-ajustable::after {
    content: "";
    position: absolute;
    inset: 0;
    background: #000;
    opacity: var(--img-oscuro, 0);
    pointer-events: none;
    z-index: 1;
}
/* El contenido de cada molde sube por encima de las dos capas. */
.rkxt-sf-img-ajustable > * { position: relative; z-index: 2; }

.rkxt-sf-hero {
    padding: 80px 32px;
    border-radius: var(--rkxt-sf-radius);
    color: var(--rkxt-fg-on-primary);
    margin-bottom: 48px;
    display: flex;
    min-height: 320px;
}
/* Hero sin foto: degradado de marca (default histórico). */
.rkxt-sf-hero-grad { background: var(--rkxt-grad-primary); }

.rkxt-sf-hero-content {
    position: relative;   /* por encima de foto + velo cuando el hero es .rkxt-sf-img-ajustable */
    z-index: 2;
    max-width: 640px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.rkxt-sf-hero-align-izquierda { justify-content: flex-start; text-align: left; }
.rkxt-sf-hero-align-izquierda .rkxt-sf-hero-content { margin-right: auto; }

.rkxt-sf-hero-align-centro { justify-content: center; text-align: center; }
.rkxt-sf-hero-align-centro .rkxt-sf-hero-content { margin: 0 auto; align-items: center; }

.rkxt-sf-hero-align-derecha { justify-content: flex-end; text-align: right; }
.rkxt-sf-hero-align-derecha .rkxt-sf-hero-content { margin-left: auto; align-items: flex-end; }

.rkxt-sf-hero h1 {
    color: #fff;
    font-size: 3rem;
    margin: 0;
    line-height: 1.1;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.rkxt-sf-hero-lead {
    font-size: 1.2rem;
    color: rgba(255, 255, 255, 0.95);
    margin: 0;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}

@media (max-width: 768px) {
    .rkxt-sf-hero { padding: 56px 24px; min-height: 240px; }
    .rkxt-sf-hero h1 { font-size: 2rem; }
    .rkxt-sf-hero-lead { font-size: 1rem; }
}
/* Tanda 2 — celular: padding más chico, heading legible sin desbordar, CTA con área táctil. */
@media (max-width: 520px) {
    .rkxt-sf-hero { padding: 40px 20px; min-height: 200px; }
    .rkxt-sf-hero h1 { font-size: 1.65rem; }
    .rkxt-sf-hero .rkxt-btn { min-height: 44px; }
}

.rkxt-sf-section {
    margin-bottom: 48px;
}

.rkxt-sf-section-head h1,
.rkxt-sf-section h2 {
    margin-bottom: 8px;
}

.rkxt-sf-section-lead {
    color: var(--rkxt-text-muted);
    margin-bottom: 24px;
}

.rkxt-sf-grid {
    display: grid;
    grid-template-columns: repeat(var(--rkxt-sf-grid-cols, 4), minmax(0, 1fr));
    gap: var(--pd-gap-y, 20px) var(--pd-gap-x, 20px);
}

@media (max-width: 900px) {
    .rkxt-sf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Tanda 2 (responsive componentes): en celular el grid de productos se queda en 2 columnas
   (tarjetas legibles, patrón estándar de e-commerce) en vez de colapsar a 1 y desperdiciar
   ancho. Gap más chico para que entren las dos columnas en 390px sin apretar. Solo 1 columna
   en pantallas muy angostas (<360px). */
@media (max-width: 520px) {
    .rkxt-sf-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--pd-gap-y, 12px) var(--pd-gap-x, 12px);
    }
    .rkxt-sf-card-info { padding: 12px; }
    .rkxt-sf-card-info h3 { font-size: 0.92rem; }
    .rkxt-sf-card-precio { font-size: 1rem; }
}
@media (max-width: 359px) {
    .rkxt-sf-grid { grid-template-columns: 1fr; }
}

/* ===== Secciones del CMS (layout de página: "diseñar la hoja") ===== */
/* Gap vertical entre franjas apiladas — configurable por tienda (default 0 = look kosiuko, sin
   separación). La var la inyecta .rkxt-sf-main inline (regla 11). */
.rkxt-sf-sec {
    margin-bottom: var(--rkxt-sf-espacio-secciones, 0);
}
.rkxt-sf-sec-cols {
    display: grid;
    gap: var(--rkxt-sf-col-gap, 24px);
    align-items: start;
}
.rkxt-sf-sec-full .rkxt-sf-sec-cols  { grid-template-columns: 1fr; }
.rkxt-sf-sec-2col .rkxt-sf-sec-cols  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rkxt-sf-sec-3col .rkxt-sf-sec-cols  { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rkxt-sf-sec-4col .rkxt-sf-sec-cols  { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.rkxt-sf-sec-5col .rkxt-sf-sec-cols  { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.rkxt-sf-sec-centro .rkxt-sf-sec-cols { grid-template-columns: minmax(0, 680px); justify-content: center; }

/* Sección con fondo (color o imagen): padding interno + radius para que el contenido no
   quede pegado al borde. El color/imagen van por style inline (valores del tenant, regla 11). */
.rkxt-sf-sec-fondo {
    position: relative;
    padding: clamp(1.5rem, 4vw, 3rem) clamp(1rem, 4vw, 3rem);
    border-radius: var(--rkxt-sf-radius, var(--rkxt-radius));
    background-size: cover;
    background-position: center;
    overflow: hidden;   /* recorta foto + velo al radius de la franja */
}

/* Fondo IMAGEN → patrón de 2 capas configurable (reemplaza el velo hardcodeado 0.32):
   ::before = la FOTO (background-image + filter brillo/contraste/saturación) — recibe --img-filtro.
   ::after  = el VELO de legibilidad (opacidad propia) — recibe --img-oscuro, NO el filter.
   El render solo agrega la clase rkxt-sf-sec-fondo-img cuando el fondo es imagen (nunca en
   fondo de color sólido: ahí el tenant ya eligió el color y un velo lo ensuciaría). Las vars
   --img-* las inyecta EstiloFondo() inline (regla 11). El contenido va por encima vía z-index. */
.rkxt-sf-sec-fondo-img::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-image: var(--img-foto);
    background-size: cover;
    background-position: center;
    filter: var(--img-filtro, none);
    pointer-events: none;
    z-index: 0;
}
.rkxt-sf-sec-fondo-img::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: #000;
    opacity: var(--img-oscuro, 0);
    pointer-events: none;
    z-index: 1;
}
.rkxt-sf-sec-fondo-img > .rkxt-sf-sec-cols {
    position: relative;
    z-index: 2;
}

/* Cada columna apila verticalmente sus componentes. El gap entre componentes es configurable
   por tienda (default 16px). La var la inyecta .rkxt-sf-main inline (regla 11). */
.rkxt-sf-sec-col {
    display: flex;
    flex-direction: column;
    gap: var(--rkxt-sf-espacio-componentes, 16px);
    min-width: 0;
}

/* Colapso responsive de columnas (reusa breakpoints del storefront: 900 / 520).
   Step-down gradual para que 4-5 columnas (típico de footer) no salten directo a 2 y queden
   apretadas: a 900 las densas (4col/5col) bajan a 3 y la 3col baja a 2; a 520 todo a 1.
   Resultado: 5→3→1, 4→3→1, 3→2→1, 2→1. Alineado con el preview del editor (.cols-4/.cols-5). */
@media (max-width: 900px) {
    .rkxt-sf-sec-3col .rkxt-sf-sec-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .rkxt-sf-sec-4col .rkxt-sf-sec-cols,
    .rkxt-sf-sec-5col .rkxt-sf-sec-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Escalón intermedio (tablet portrait / phablet): las densas (3/4/5col) bajan a 2 ANTES de
   colapsar a 1 en celular. Suaviza el salto 3→1 en el rango ~521-680 (antes era abrupto:
   a 521px todavía 3 columnas apretadas, a 520px de golpe 1). Resultado final: 5→3→2→1, 4→3→2→1,
   3→2→2→1, 2→2→1. El footer de 5 columnas (kosiuko) queda prolijo en cada escalón. */
@media (max-width: 680px) {
    .rkxt-sf-sec-3col .rkxt-sf-sec-cols,
    .rkxt-sf-sec-4col .rkxt-sf-sec-cols,
    .rkxt-sf-sec-5col .rkxt-sf-sec-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 520px) {
    .rkxt-sf-sec-2col .rkxt-sf-sec-cols,
    .rkxt-sf-sec-3col .rkxt-sf-sec-cols,
    .rkxt-sf-sec-4col .rkxt-sf-sec-cols,
    .rkxt-sf-sec-5col .rkxt-sf-sec-cols { grid-template-columns: 1fr; }
}

/* ===== Ancho de sección + Paño (fondo de página) — modelo full-bleed UNIFICADO =====

   ROOT CAUSE del bug "ancho-completo queda boxed a 1200":
   El truco full-bleed `width:100vw; margin-left:calc(50% - 50vw)` SOLO es confiable cuando se
   aplica a un hijo DIRECTO del contenedor centrado (.rkxt-sf-main, max-width:1200 + padding:32).
   En el árbol real la sección NO es hijo directo del main: cuelga de .rkxt-sf-pagina (el wrapper
   que RenderizarPagina SIEMPRE emite alrededor de las secciones, tenga o no color de paño). Ese
   wrapper es `width:auto` → su content-box mide 1136px (1200 − 64 de padding del main), así que
   el `50%` de la sección resuelve contra 1136, no contra el centrado real del viewport. El truco
   queda "tuneado" a un ancho intermedio frágil y, con scrollbar/redondeo/anidamiento, NO rompe el
   cap → la sección se ve a ~1200 con márgenes.

   FIX (robusto, una sola breakout, nivel predecible):
   Hacemos que .rkxt-sf-pagina (SIEMPRE presente, con o sin fondo) sea el breakout full-bleed —
   como hijo DIRECTO de .rkxt-sf-main, el calc(50%-50vw) sí resuelve exacto (mismo cálculo que el
   patrón canónico). DENTRO del paño full-bleed:
     · "contenido" se re-centra a 1200 con padding lateral fluido (idéntico a antes visualmente).
     · "completo"  va width:100% del paño = todo el viewport (edge-to-edge real).
   Así el comportamiento es el MISMO exista o no color de paño (el color solo agrega bg + padding
   vertical). Las páginas catálogo/categoría/producto también pasan por este wrapper → quedan con
   sus secciones "contenido" centradas a 1200, igual que hoy. */

/* El paño SIEMPRE rompe el cap del main y ocupa el viewport entero (transparente por defecto).
   Es hijo directo de .rkxt-sf-main → el calc resuelve contra el contenedor centrado real. */
.rkxt-sf-pagina {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    background-color: transparent;
}

/* Con color de fondo: mismo breakout + bg + aire vertical para que respire arriba/abajo.
   El color sólido viaja por style inline (valor del tenant, regla 11). */
.rkxt-sf-pagina-fondo {
    padding-block: clamp(1.5rem, 4vw, 3rem);
}

/* ===== Footer-motor (chrome al pie, sistema de secciones — DOC08) =====

   El <footer class="rkxt-sf-pagina rkxt-sf-footer-motor"> que emite RenderizarPagina con
   Chrome="footer" es HERMANO del <main> y HIJO DIRECTO de .rkxt-shell (NO vive dentro de
   .rkxt-sf-main). Hereda de .rkxt-sf-pagina TODO el modelo full-bleed (width:100vw +
   margin:calc(50%-50vw)): como hijo directo de .rkxt-shell (= ancho del viewport, sin cap),
   el calc resuelve exacto igual que en el body. Por eso una sección "ancho-completo" adentro
   del footer va edge-to-edge real y una "contenido" se re-centra a 1200 con su propio padding
   lateral fluido (.rkxt-sf-sec-ancho-contenido) — sin re-implementar nada acá.

   CRÍTICO (no romper el breakout): NO agregar padding/margin LATERAL a esta clase. El padding
   lateral sobre un elemento width:100vw lo desborda (scroll horizontal, recortado igual por el
   overflow-x:clip del shell) y descalibra el re-centrado interno. Solo tocamos el eje vertical
   (padding-block) y la tipografía, que no afectan el cálculo full-bleed. El aire lateral del
   contenido ya lo ponen las secciones internas (contenido = padding fluido; completo = 0). */
.rkxt-sf-footer-motor {
    /* Aire vertical de footer e-commerce. Proporción tomada de .rkxt-sf-footer-rich (3rem arriba
       / 1.5rem abajo): el pie respira generoso arriba y cierra más ajustado abajo. Las secciones
       internas CON fondo ya traen su propio padding (.rkxt-sf-sec-fondo); este padding-block es
       el aire base para footers de secciones SIN fondo (texto/links sueltos sobre el paño). */
    padding-block: clamp(2rem, 4vw, 3rem) clamp(1.25rem, 3vw, 1.5rem);

    /* Separador sutil arriba: marca el footer como chrome al pie sin imponer un color de línea
       fijo. Derivado de currentColor (= color de texto efectivo del footer, sea claro u oscuro
       según el tema/sección) → legible en footer claro Y oscuro, mismo patrón que
       .rkxt-sf-footer-logos / -legal. Si una sección con fondo propio arranca pegada arriba,
       igual queda prolijo: la línea cae por detrás del padding. */
    border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);

    /* Footers suelen ir un punto más chicos que el body (~.9rem). Heredable por las secciones
       internas (texto/links) salvo que un componente fije su propio tamaño. */
    font-size: .9rem;

    /* Fallback de color SEGURO para el footer-motor: el color de texto real lo define cada
       sección (PaginaSeccion.ColorTexto → style="color:..." inline en cada <section>, que gana
       por especificidad). Pero si una sección NO define color, hereda de acá. Usamos el token
       semántico --rkxt-text (lo pisa el tema del storefront cuando el fondo es oscuro), NUNCA un
       #fff/#000 fijo: así el texto del footer contrasta con el fondo del tema. Esto resuelve el
       bug de "texto del footer invisible" sin tapar el color por-sección. */
    color: var(--rkxt-text);
}

/* Ancho contenido = el paño ya es full-bleed, así que acá REPONEMOS el cap de 1200 centrado
   con padding lateral fluido (es el comportamiento "normal"/default de las páginas). */
.rkxt-sf-sec-ancho-contenido {
    max-width: 1200px;
    margin-inline: auto;
    padding-inline: clamp(1rem, 4vw, 32px);
}

/* Ancho completo = edge-to-edge REAL. La sección llena el ancho del paño (= viewport completo)
   y AHORA el contenido interno también va al 100% (sin cap 1200) para que un Hero/Imagen/banner
   pueda tocar los dos bordes como en kosiuko.com. El cap de 1200 ya NO vive acá: se reaplica
   SELECTIVAMENTE a los moldes que NO deben pegarse al borde (texto/botón sueltos), abajo. */
.rkxt-sf-sec-ancho-completo {
    width: 100%;
    margin-inline: 0;
}
.rkxt-sf-sec-ancho-completo > .rkxt-sf-sec-cols {
    max-width: none;
    margin-inline: 0;
    padding-inline: 0;
    gap: 0;
}

/* En una sección completo, los moldes "atómicos" (texto suelto, botón suelto) NO deben quedar
   pegados al borde del viewport → se auto-acotan a 1200 centrados con padding lateral fluido.
   Los moldes "full-bleed-capable" (Hero/Imagen/banners) quedan al 100% (ver abajo) y van de
   borde a borde. El selector llega hasta el molde (.rkxt-sf-sec-col > X) con especificidad 0,3,0
   para ganarle siempre al CSS scoped del componente (0,2,0), sin depender del orden de carga. */
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-texto,
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-cbtn-wrap,
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-section,
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-newsletter,
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-nlform {
    max-width: 1200px;
    margin-inline: auto;
    padding-inline: clamp(1rem, 4vw, 32px);
    box-sizing: border-box;
    width: 100%;
}

/* Moldes full-bleed-capable dentro de sección completo: ocupan TODO el ancho real (borde a
   borde) y pierden el border-radius + margin horizontal que traen de su CSS scoped (kosiuko no
   tiene esquinas redondeadas ni márgenes laterales en el hero). El margin vertical del Hero/Imagen
   se conserva acotado para que no se peguen verticalmente al resto del flujo. Especificidad 0,3,0
   le gana al scoped 0,2,0 sin importar el orden de carga. El texto interno del HeroCarousel
   (.rkxt-sf-hc-content max-width:640) se sigue auto-centrando solo — no lo tocamos. */
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-hc,
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-hero {
    width: 100%;
    border-radius: 0;
    margin: 0;
}
/* BannerPromocional full-bleed: además del radius/margin pierde el borde lateral (sino dibuja
   una línea pegada al borde del viewport) y sigue ocultando el overflow del grid imagen/texto. */
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-promo {
    width: 100%;
    border-radius: 0;
    border: none;
    margin: 0;
}
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-img {
    width: 100%;
    margin: 0;
}
/* La Imagen full-bleed estira su <img> a todo el ancho y suelta el cap de alto (520px) para que
   un banner panorámico cubra de borde a borde. is-rounded pierde el radius contra los bordes. */
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-img img {
    width: 100%;
    max-width: none;
    max-height: none;
}
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-img.is-rounded img {
    border-radius: 0;
}
.rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > .rkxt-sf-img a {
    width: 100%;
}

/* Sección completo CON fondo (color o imagen): el fondo cubre de borde a borde, así que un
   border-radius se vería raro recortando esquinas contra los bordes del viewport → lo quitamos.
   El padding vertical lo conserva (rkxt-sf-sec-fondo) para separar el contenido del borde
   superior/inferior; el lateral lo da el padding-inline del molde atómico de arriba.
   Para fondo IMAGEN el overlay ::before usa inset:0 → cubre todo el ancho igual (hero kosiuko). */
.rkxt-sf-sec-ancho-completo.rkxt-sf-sec-fondo {
    border-radius: 0;
    padding-left: 0;
    padding-right: 0;
}

/* Visibilidad por dispositivo (divisor mobile/desktop = 768px). */
@media (max-width: 768px) {
    .rkxt-sf-hide-mobile { display: none !important; }
}
@media (min-width: 769px) {
    .rkxt-sf-hide-desktop { display: none !important; }
}

/* ===== Popups (secciones en modo overlay) =====
   El render emite el popup OCULTO; rkxt-popup.js le agrega .is-open según el disparador
   (delay / scroll / salida / inmediato). Sin .is-open NO ocupa espacio ni se ve. Con .is-open
   se vuelve un modal centrado sobre un velo oscuro a pantalla completa. El velo (rgba oscuro) y
   el z-index son valores técnicos, no tokenizables. */
.rkxt-sf-popup {
    display: none;
}

.rkxt-sf-popup.is-open {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 1200;
    align-items: center;
    justify-content: center;
    padding: clamp(1rem, 4vw, 2.5rem);
    background: rgba(15, 15, 18, 0.62);
    overflow-y: auto;
    animation: rkxt-pop-velo 0.22s ease both;
}

/* La caja = tarjeta del modal. Reusa .rkxt-sf-sec-fondo para el fondo color/imagen del tenant
   (el "JOIN US" negro de kosiuko viaja inline). Acá fijamos surface/radius/sombra por si NO
   trae fondo, y el ancho según tamaño. La animación de entrada (fade + scale) va en la caja. */
.rkxt-sf-popup-caja {
    position: relative;
    width: 90vw;
    background: var(--rkxt-surface);
    color: var(--rkxt-on-surface);
    border-radius: var(--rkxt-sf-radius, var(--rkxt-radius));
    box-shadow: var(--rkxt-shadow-lg);
    padding: clamp(1.75rem, 4vw, 2.75rem);
    animation: rkxt-pop-caja 0.26s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}

/* Cuando la caja TRAE fondo (.rkxt-sf-sec-fondo) ya aporta su padding/radius/background; acá
   solo nos aseguramos de que la sombra del modal se mantenga (el fondo de sección no la trae). */
.rkxt-sf-popup-caja.rkxt-sf-sec-fondo {
    box-shadow: var(--rkxt-shadow-lg);
}

/* Tamaños = max-width (el width:90vw lo hace responsive en pantallas chicas). */
.rkxt-sf-popup-chico   .rkxt-sf-popup-caja { max-width: 380px; }
.rkxt-sf-popup-mediano .rkxt-sf-popup-caja { max-width: 560px; }
.rkxt-sf-popup-grande  .rkxt-sf-popup-caja { max-width: 760px; }

/* Botón ✕ arriba a la derecha, sobre la caja. Hereda el color del texto de la caja (sobre
   fondo oscuro queda claro) y se realza al hover. position absolute → no afecta el layout. */
.rkxt-sf-popup-close {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--rkxt-radius-pill);
    background: transparent;
    color: inherit;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.7;
    transition: background 0.12s, opacity 0.12s;
}

.rkxt-sf-popup-close:hover {
    opacity: 1;
    background: rgba(127, 127, 127, 0.18);
}

/* El cuerpo reusa la grilla de columnas del CMS (.rkxt-sf-sec-cols) pero sin el gap enorme
   de las secciones de página: dentro del modal el espacio es más contenido. z-index:1 para
   quedar por encima del overlay ::before cuando el fondo es imagen. */
.rkxt-sf-popup-cuerpo {
    position: relative;
    z-index: 1;
    gap: 18px;
}

@keyframes rkxt-pop-velo {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes rkxt-pop-caja {
    from { opacity: 0; transform: translateY(14px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ===== FormularioNewsletter =====
   Pensado para vivir dentro de un popup de fondo oscuro: título y texto HEREDAN el color de
   la caja (que el tenant fija inline via .rkxt-sf-sec-fondo → color claro sobre oscuro). NO
   forzamos colores oscuros en título/texto. El input email sí lleva su propio fondo claro
   (.rkxt-input ya es surface) para que sea legible contra cualquier fondo. */
.rkxt-sf-nlform {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    text-align: center;
    color: inherit;
}

.rkxt-sf-nlform-tit {
    margin: 0;
    font-family: var(--rkxt-font-serif, var(--rkxt-font-display));
    font-size: clamp(1.25rem, 3vw, 1.6rem);
    line-height: 1.2;
    color: inherit;
}

.rkxt-sf-nlform-txt {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.5;
    opacity: 0.88;
    color: inherit;
    max-width: 46ch;
}

/* Fila input + botón. En mobile apila (botón full width). */
.rkxt-sf-nlform-row {
    display: flex;
    gap: 10px;
    width: 100%;
    max-width: 460px;
    margin-top: 4px;
}

.rkxt-sf-nlform-input {
    flex: 1 1 auto;
    min-width: 0;
}

.rkxt-sf-nlform-row .rkxt-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Mensaje de éxito destacado: pill suave en tono primary, legible sobre fondo claro u oscuro
   (el primary-soft es traslúcido del naranja). */
.rkxt-sf-nlform-ok {
    margin: 0;
    padding: 12px 18px;
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-primary-soft);
    color: var(--rkxt-primary);
    font-weight: 600;
    font-size: 0.98rem;
}

@media (max-width: 520px) {
    .rkxt-sf-nlform-row {
        flex-direction: column;
    }
    .rkxt-sf-nlform-row .rkxt-btn {
        width: 100%;
    }
}

/* Card de producto del storefront. El HOVER es parametrizable por TEMA (DOC09 H5): los
   defaults reproducen la identidad Rakuxt (lift + borde primary + sombra); un tema editorial
   tipo kosiuko lo apaga y usa solo zoom sutil de la imagen seteando en VariablesCssJson:
     --rkxt-card-hover-lift: 0px; --rkxt-card-hover-border: var(--rkxt-border);
     --rkxt-card-hover-shadow: none; --rkxt-card-img-zoom: 1.04;
   Así la sombra del color primary NO se filtra en temas ajenos a la marca Rakuxt. */
.rkxt-sf-card {
    display: block;
    background: var(--rkxt-surface);
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--rkxt-border);
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}

.rkxt-sf-card:hover {
    transform: translateY(calc(-1 * var(--rkxt-card-hover-lift, 2px)));
    border-color: var(--rkxt-card-hover-border, var(--rkxt-primary));
    box-shadow: var(--rkxt-card-hover-shadow, var(--rkxt-shadow-md));
}

.rkxt-sf-card .rkxt-sf-card-img {
    transition: transform 0.35s ease;
}

.rkxt-sf-card:hover .rkxt-sf-card-img {
    transform: scale(var(--rkxt-card-img-zoom, 1));
}

/* Links dentro de bloques de contenido del motor (Texto / Html): heredan el color del
   contexto en vez de caer al azul default del user-agent (DOC09 H8). */
.rkxt-sf-texto a,
.rkxt-sf-html a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.rkxt-sf-card-img {
    width: 100%;
    aspect-ratio: 4 / 5;
    background-color: var(--rkxt-bg-alt);
    /* Encuadre configurable (F3.7.39): var inyectada en .rkxt-shell, override per-producto inline. */
    background-size: var(--rkxt-fit-bg, contain);
    background-position: center;
    background-repeat: no-repeat;
}

.rkxt-sf-card-info {
    padding: 16px;
}

.rkxt-sf-card-info h3 {
    font-size: 1rem;
    margin-bottom: 6px;
    color: var(--rkxt-on-surface);
}

.rkxt-sf-card-precio {
    color: var(--rkxt-primary);
    font-weight: 700;
    font-size: 1.05rem;
    margin: 0;
}

.rkxt-sf-card-meta {
    margin-top: 6px;
    font-size: 0.82rem;
    color: var(--rkxt-on-surface-muted);
}

/* Chip de categoría en la card (config catalogo.mostrar_categorias_chip). */
.rkxt-sf-card-cat {
    display: inline-block;
    margin-top: 6px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--rkxt-on-surface-muted);
    background: color-mix(in srgb, var(--rkxt-on-surface) 8%, transparent);
    padding: 2px 9px;
    border-radius: 999px;
}

/* Chip de categoría en la ficha (link, config ficha.mostrar_categoria). */
.rkxt-sf-pdp-cat {
    text-decoration: none;
    margin: 2px 0 14px;
    font-size: 0.78rem;
    color: var(--rkxt-text);
    background: color-mix(in srgb, var(--rkxt-text) 8%, transparent);
}
.rkxt-sf-pdp-cat:hover {
    background: color-mix(in srgb, var(--rkxt-primary) 18%, transparent);
}

/* Precio con oferta (tachado + destacado) */
.rkxt-sf-card-precio-lista {
    color: var(--rkxt-text-muted);
    text-decoration: line-through;
    font-weight: 400;
    margin-right: 8px;
    font-size: 0.92em;
}

.rkxt-sf-card-precio-oferta {
    color: #dc2626;
    font-weight: 700;
}

/* PrecioTag — render unificado de precio (con/sin oferta) en cards y ficha (T1+T2).
   Hereda tamaño/color del contenedor (.rkxt-sf-card-precio o .rkxt-sf-pdp-precio).
   Cuando hay oferta, el precio efectivo va en rojo + lista tachado + badge de % off.
   Muted via color-mix sobre --rkxt-text para que rinda en cualquier tema. */
.rkxt-sf-precio {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}

.rkxt-sf-precio-now {
    color: inherit;
    font-weight: inherit;
}

.rkxt-sf-precio.has-oferta .rkxt-sf-precio-now {
    color: #dc2626;
}

.rkxt-sf-precio-lista {
    color: currentColor;
    opacity: 0.5;
    text-decoration: line-through;
    font-weight: 400;
    font-size: 0.78em;
}

.rkxt-sf-precio-off {
    font-size: 0.66em;
    font-weight: 700;
    color: #fff;
    background: #dc2626;
    padding: 2px 7px;
    border-radius: 999px;
    line-height: 1.4;
    white-space: nowrap;
}

/* ============ CategoriaGrid ============ */
.rkxt-sf-cats {
    --rkxt-sf-cats-cols: 3;
}

.rkxt-sf-cats-grid {
    display: grid;
    grid-template-columns: repeat(var(--rkxt-sf-cats-cols), minmax(0, 1fr));
    gap: 18px;
}

@media (max-width: 900px) {
    .rkxt-sf-cats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 520px) {
    .rkxt-sf-cats-grid { grid-template-columns: 1fr; }
}

.rkxt-sf-cat-card {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
    border: 1px solid var(--rkxt-border);
    background: var(--rkxt-surface);
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}

.rkxt-sf-cat-card:hover {
    transform: translateY(-2px);
    border-color: var(--rkxt-primary);
    box-shadow: var(--rkxt-shadow-md);
}

.rkxt-sf-cat-card-img {
    aspect-ratio: 16 / 10;
    background-color: var(--rkxt-bg-alt);
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: center;
    justify-content: center;
}

.rkxt-sf-cat-card-placeholder {
    font-size: 2rem;
    font-weight: 700;
    color: var(--rkxt-primary);
    font-family: var(--rkxt-font-display);
    letter-spacing: 0.05em;
}

.rkxt-sf-cat-card-name {
    padding: 14px 18px;
    font-weight: 600;
    color: var(--rkxt-on-surface);
}

/* ============ BannerPromocional ============ */
.rkxt-sf-promo {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
    border: 1px solid var(--rkxt-border);
    margin-bottom: 48px;
    background: var(--rkxt-surface);
}

.rkxt-sf-promo-derecha .rkxt-sf-promo-img { order: 2; }
.rkxt-sf-promo-derecha .rkxt-sf-promo-text { order: 1; }

.rkxt-sf-promo-img {
    /* La foto va en ::before (.rkxt-sf-img-ajustable, filterable) + velo en ::after. Este color
       queda de placeholder detrás por si no hay imagen. min-height da cuerpo a la celda. */
    background-color: var(--rkxt-bg-alt);
    min-height: 280px;
}

.rkxt-sf-promo-text {
    padding: 40px 36px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 14px;
}

.rkxt-sf-promo-text h2 {
    margin: 0;
    font-size: 1.8rem;
    line-height: 1.2;
}

.rkxt-sf-promo-text p {
    margin: 0;
    color: var(--rkxt-text-muted);
    font-size: 1rem;
}

.rkxt-sf-promo-text a { align-self: flex-start; }

@media (max-width: 768px) {
    .rkxt-sf-promo { grid-template-columns: 1fr; }
    .rkxt-sf-promo-derecha .rkxt-sf-promo-img,
    .rkxt-sf-promo-derecha .rkxt-sf-promo-text { order: initial; }
    .rkxt-sf-promo-text { padding: 28px 24px; }
}

/* ============ Newsletter ============ */
.rkxt-sf-newsletter {
    background: var(--rkxt-bg-alt);
    border-radius: var(--rkxt-sf-radius);
    padding: 48px 32px;
    margin-bottom: 48px;
    text-align: center;
}

.rkxt-sf-newsletter-inner {
    max-width: 540px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
    align-items: center;
}

.rkxt-sf-newsletter h2 { margin: 0; font-size: 1.6rem; color: var(--rkxt-on-surface); }
.rkxt-sf-newsletter p { margin: 0; color: var(--rkxt-on-surface-muted); }

.rkxt-sf-newsletter-form {
    display: flex;
    gap: 8px;
    width: 100%;
    max-width: 420px;
    margin-top: 8px;
}

.rkxt-sf-newsletter-form input[type="email"] { flex: 1; }

@media (max-width: 520px) {
    .rkxt-sf-newsletter-form { flex-direction: column; }
}

/* ============ Carrusel horizontal (alternativa al grid en ProductosDestacados) ============ */
.rkxt-sf-carousel {
    display: flex;
    gap: 16px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: 12px;
    scrollbar-width: thin;
}

.rkxt-sf-carousel > .rkxt-sf-card {
    flex: 0 0 240px;
    scroll-snap-align: start;
}

/* Leyenda opcional bajo el precio de la ficha (ficha.leyenda_precio — ej. exhibición
   "precio sin impuestos nacionales", DOC09 F5). */
.rkxt-sf-pdp-leyenda-precio {
    font-size: 0.78rem;
    color: var(--rkxt-text-muted);
    margin: -8px 0 12px;
}

/* "También te puede interesar" al pie de la ficha (DOC09 F4). Reusa las cards del catálogo. */
.rkxt-sf-pdp-relacionados {
    margin-top: 44px;
}

.rkxt-sf-pdp-relacionados h2 {
    font-family: var(--rkxt-font-display);
    margin: 0 0 16px;
}

/* PDP — ficha de producto */
.rkxt-sf-pdp {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 48px;
}

@media (max-width: 800px) {
    .rkxt-sf-pdp { grid-template-columns: 1fr; }
}

.rkxt-sf-pdp-gallery {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.rkxt-sf-pdp-main {
    aspect-ratio: 4 / 5;
    background-color: var(--rkxt-bg-alt);
    background-position: center;
    background-repeat: no-repeat;
    border-radius: var(--rkxt-sf-radius);
}

/* T4: zoom tipo lupa — el cursor sugiere acercar; el JS hace el inner-zoom en hover. */
.rkxt-sf-pdp-main[data-rkxt-zoom] {
    cursor: zoom-in;
    transition: background-size 0.08s ease-out;
}

.rkxt-sf-pdp-thumbs {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}

.rkxt-sf-pdp-thumb {
    aspect-ratio: 1;
    background-color: var(--rkxt-bg-alt);
    background-position: center;
    background-repeat: no-repeat;
    border-radius: 6px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: border-color 0.12s ease;
}

.rkxt-sf-pdp-thumb:hover {
    border-color: color-mix(in srgb, var(--rkxt-primary) 50%, transparent);
}

.rkxt-sf-pdp-thumb.is-active {
    border-color: var(--rkxt-primary);
}

/* Stage de la galería: contiene la foto principal (con zoom) y el video, se alternan. */
.rkxt-sf-pdp-stage {
    position: relative;
}

.rkxt-sf-pdp-main-video {
    width: 100%;
    aspect-ratio: 4 / 5;
    background: #000;
    border-radius: var(--rkxt-sf-radius);
    object-fit: contain;
    display: block;
}

/* Miniatura de video: cuadrado oscuro con ícono play. */
.rkxt-sf-pdp-thumb-video {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #111;
    color: #fff;
}

.rkxt-sf-pdp-thumb-play {
    font-size: 1.1rem;
    line-height: 1;
    opacity: 0.9;
}

/* Layout galería "izquierda": miniaturas en columna vertical a la izquierda de la
   principal, tan alta como ella (scroll si sobran). Configurable por tienda. */
.rkxt-sf-pdp-gallery--izquierda {
    flex-direction: row-reverse;
    align-items: stretch;
    gap: 12px;
}

.rkxt-sf-pdp-gallery--izquierda .rkxt-sf-pdp-stage {
    flex: 1 1 auto;
    min-width: 0;
}

.rkxt-sf-pdp-gallery--izquierda .rkxt-sf-pdp-thumbs {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    flex: 0 0 78px;
    width: 78px;
    gap: 8px;
    overflow-y: auto;
}

.rkxt-sf-pdp-gallery--izquierda .rkxt-sf-pdp-thumb {
    width: 78px;
    flex: 0 0 auto;
}

/* En mobile la columna izquierda no entra: volvemos a fila debajo. */
@media (max-width: 720px) {
    .rkxt-sf-pdp-gallery--izquierda {
        flex-direction: column;
        align-items: stretch;
    }
    .rkxt-sf-pdp-gallery--izquierda .rkxt-sf-pdp-thumbs {
        flex-direction: row;
        width: auto;
        flex: 0 0 auto;
        overflow-x: auto;
        overflow-y: visible;
    }
}

.rkxt-sf-pdp-info h1 {
    font-size: 1.8rem;
    margin-bottom: 4px;
}

.rkxt-sf-pdp-sku {
    color: var(--rkxt-text-muted);
    margin-bottom: 16px;
}

.rkxt-sf-pdp-precio {
    color: var(--rkxt-primary);
    font-size: 2rem;
    font-weight: 800;
    margin-bottom: 24px;
}

.rkxt-sf-pdp-desc {
    margin-bottom: 24px;
    color: var(--rkxt-text-muted);
    line-height: 1.6;
}

.rkxt-sf-pdp-variantes h2 {
    font-size: 1rem;
    margin: 24px 0 8px 0;
}

.rkxt-sf-pdp-tabla-variantes {
    width: 100%;
    border-collapse: collapse;
    background: var(--rkxt-surface);
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
    margin-bottom: 24px;
}

.rkxt-sf-pdp-tabla-variantes th,
.rkxt-sf-pdp-tabla-variantes td {
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid var(--rkxt-border);
    font-size: 0.92rem;
    color: var(--rkxt-on-surface);
}

.rkxt-sf-pdp-tabla-variantes th {
    font-weight: 600;
    color: var(--rkxt-on-surface-muted);
    background: var(--rkxt-surface-2);
}

/* Ficha en modo TABLA (mayorista): la tabla de variantes gana una columna de cantidad por talle
   para cargar la curva completa. Reusa .rkxt-sf-qo-input (input + feedback de clamp del catálogo). */
.rkxt-sf-pdp-cant {
    width: 1%;
    white-space: nowrap;
}
.rkxt-sf-pdp-cant .rkxt-sf-qo-input {
    width: 88px;
    text-align: right;
}
.rkxt-sf-pdp-row-sinstock {
    opacity: 0.6;
}
.rkxt-sf-pdp-row-sinstock td {
    color: var(--rkxt-on-surface-muted);
}

/* Especificaciones técnicas (specs heredadas del artículo maestro, clave/valor).
   Theme-agnóstico: usa el par bg/text del tema (siempre contrastan) en vez de los
   tokens --rkxt-surface*, que algunos temas del storefront no overridean (quedarían
   claros con texto claro = invisible). Fondos/bordes sutiles via color-mix sobre el
   texto del tema, así rinde igual en temas claros u oscuros. */
.rkxt-sf-pdp-specs {
    margin: 24px 0;
}

.rkxt-sf-pdp-specs h2 {
    font-size: 1rem;
    margin: 0 0 8px 0;
    color: var(--rkxt-text);
}

.rkxt-sf-pdp-tabla-specs {
    width: 100%;
    border-collapse: collapse;
    color: var(--rkxt-text);
    border: 1px solid color-mix(in srgb, var(--rkxt-text) 18%, transparent);
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
}

.rkxt-sf-pdp-tabla-specs th,
.rkxt-sf-pdp-tabla-specs td {
    padding: 9px 12px;
    text-align: left;
    border-bottom: 1px solid color-mix(in srgb, var(--rkxt-text) 12%, transparent);
    font-size: 0.92rem;
    vertical-align: top;
    color: var(--rkxt-text);
}

.rkxt-sf-pdp-tabla-specs tr:last-child th,
.rkxt-sf-pdp-tabla-specs tr:last-child td {
    border-bottom: none;
}

.rkxt-sf-pdp-tabla-specs th {
    font-weight: 600;
    width: 40%;
    white-space: nowrap;
    background: color-mix(in srgb, var(--rkxt-text) 7%, transparent);
}

.rkxt-sf-pdp-cta {
    margin-top: 16px;
}

.rkxt-sf-pdp-combo {
    margin: 24px 0;
    padding: 20px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-primary);
    border-radius: var(--rkxt-sf-radius);
}

.rkxt-sf-pdp-combo h2 {
    margin-top: 0;
    font-size: 1rem;
    color: var(--rkxt-primary);
}

.rkxt-sf-pdp-combo-lista {
    list-style: none;
    padding-left: 0;
    margin: 12px 0;
}

.rkxt-sf-pdp-combo-lista li {
    padding: 8px 0;
    border-bottom: 1px solid var(--rkxt-border);
}

.rkxt-sf-pdp-combo-lista li:last-child {
    border-bottom: none;
}

.rkxt-sf-pdp-ahorro {
    background: rgba(34, 197, 94, 0.12);
    padding: 10px 14px;
    border-radius: 8px;
    margin: 12px 0;
}

.rkxt-sf-pdp-stock-combo {
    color: var(--rkxt-text-muted);
    font-size: 0.92rem;
    margin: 8px 0 0 0;
}

/* Tanda 2 — PDP en celular: la galería ya pasa a 1 columna a 800px (full-width). Acá:
   · La tabla de variantes/talles puede tener N columnas (1 por atributo) y desbordar en 390px:
     le damos scroll horizontal interno SOLO a esa tabla (no a la página) para que nunca empuje
     el ancho del viewport. La de specs (2 columnas clave/valor) entra siempre, no la tocamos.
   · El CTA "Agregar al carrito" full-width y con buena área táctil. */
@media (max-width: 640px) {
    .rkxt-sf-pdp { gap: 28px; }
    .rkxt-sf-pdp-info h1 { font-size: 1.5rem; }
    .rkxt-sf-pdp-precio { font-size: 1.7rem; margin-bottom: 18px; }
    .rkxt-sf-pdp-tabla-variantes {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
    }
    .rkxt-sf-pdp-cta .rkxt-btn { width: 100%; min-height: 48px; }
    .rkxt-sf-pdp-thumbs { grid-template-columns: repeat(5, 1fr); }
}

/* Breadcrumbs */
.rkxt-sf-breadcrumbs {
    color: var(--rkxt-text-muted);
    font-size: 0.88rem;
    margin-bottom: 20px;
}

.rkxt-sf-breadcrumbs a {
    color: var(--rkxt-text-muted);
}

/* Botón "Volver a donde estaba" (ficha de producto). En el carrito se ubica en .rkxt-form-actions. */
.rkxt-sf-volver {
    margin: -4px 0 18px;
}

.rkxt-sf-breadcrumbs a:hover {
    color: var(--rkxt-primary);
}

.rkxt-sf-breadcrumbs strong {
    color: var(--rkxt-text);
}

/* Conteo de resultados en la línea del breadcrumb ("Inicio › Catálogo · 654 productos") —
   reemplaza al <p class="rkxt-sf-section-lead"> grande de abajo del H1 (cabecera compacta). */
.rkxt-sf-breadcrumbs-count {
    margin-left: 2px;
}

/* Search en header */
.rkxt-sf-search {
    display: flex;
    align-items: center;
    flex: 0 1 380px;
    gap: 4px;
    margin: 0 24px;
}

.rkxt-sf-search-input {
    flex: 1;
    background: var(--rkxt-bg);
    border: 1px solid var(--rkxt-border);
}

.rkxt-sf-search-btn {
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    border: none;
    border-radius: var(--rkxt-radius-sm);
    padding: 8px 14px;
    cursor: pointer;
    font-size: 1rem;
}

.rkxt-sf-search-btn:hover {
    background: var(--rkxt-primary-hover);
}

/* GeoBanner */
.rkxt-sf-geobanner {
    background: #1e293b;             /* slate-800 — fondo oscuro neutro, no compite con el theme del tenant */
    color: #f1f5f9;                  /* slate-100 — alto contraste WCAG AAA sobre slate-800 */
    padding: 10px clamp(16px, 4vw, 32px);   /* lateral fluido: no ahoga el texto en celular */
    font-size: 0.9rem;
    display: flex;
    gap: 12px;
    justify-content: space-between;
    align-items: center;
    border-bottom: none;
    font-weight: 500;
}

@media (max-width: 520px) {
    .rkxt-sf-geobanner { font-size: 0.82rem; }
}

.rkxt-sf-geobanner strong {
    color: #fcd34d;                  /* amber-300 — destaca el nombre del país sobre fondo dark */
    font-weight: 600;
}

.rkxt-sf-geobanner-close {
    background: transparent;
    border: none;
    color: #cbd5e1;                  /* slate-300 — botón close visible pero no dominante */
    cursor: pointer;
    font-size: 1.3rem;
    line-height: 1;
    padding: 0 4px;
}

.rkxt-sf-geobanner-close:hover {
    color: #ffffff;
}

/* Catálogo con sidebar de filtros */
.rkxt-sf-catalog {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 32px;
}

@media (max-width: 800px) {
    .rkxt-sf-catalog { grid-template-columns: 1fr; }
    /* Tanda 2: en celular/tablet el sidebar de filtros se apila ARRIBA del grid. Para que no
       empuje todo el catálogo fuera de pantalla: no sticky, cap de alto con scroll interno, y
       las opciones de cada bloque reflowean en fila (chips) en vez de una columna larga. Así
       el bloque de filtros ocupa poco alto y el grid queda visible enseguida. */
    .rkxt-sf-sidebar {
        position: static;
        top: auto;
        max-height: 42vh;
        overflow-y: auto;
        margin-bottom: 20px;
    }
    .rkxt-sf-filter-block { padding-bottom: 12px; margin-bottom: 12px; }
    .rkxt-sf-filter-opt {
        display: inline-flex;
        padding: 8px 0;
        margin-right: 16px;          /* separa las opciones cuando van en fila */
        min-height: 40px;            /* área táctil cómoda */
    }
}

.rkxt-sf-sidebar {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-sf-radius);
    padding: 18px;
    height: fit-content;
    position: sticky;
    /* Misma config que el panel del asesor: pegado a la altura del PRIMER registro (debajo del header
       de tienda + encabezado de columnas sticky, medido en --rkxt-sf-panel-top) + alto acotado con
       scroll interno si la lista de filtros es larga → no se esconde detrás de la cabecera al scrollear. */
    top: calc(var(--rkxt-sf-panel-top, 20px) + 4px);
    max-height: calc(100vh - var(--rkxt-sf-panel-top, 20px) - 24px);
    overflow-y: auto;
}

/* ===== Asesor de pedidos IA en el catálogo: 3ª columna (derecha) + colapso mutuo con los filtros ===== */
/* Con chat (solo mayorista): filtros abiertos (240px) · productos (1fr) · chat colapsado a rail (46px). */
.rkxt-sf-catalog--conchat { grid-template-columns: 240px 1fr 46px; }
/* Chat abierto: filtros a rail (46px) · productos (1fr) · panel del chat. */
.rkxt-sf-catalog--conchat.is-chat { grid-template-columns: 46px 1fr min(400px, 34vw); }

/* Rail (lateral colapsado): barrita clickeable con etiqueta vertical. */
.rkxt-sf-lateral-rail {
    display: none;
    align-items: center; justify-content: center;
    /* Alto FIJO (no 100%): un sticky tan alto como su contenedor no se pega. Es una barrita/tab que
       queda fija a la altura del primer registro (top abajo) mientras scrolleás la lista. */
    width: 46px; height: 260px;
    background: var(--rkxt-surface-2, #f4f4f5);
    border: 1px solid var(--rkxt-border); border-radius: var(--rkxt-sf-radius);
    cursor: pointer; padding: 12px 0; color: var(--rkxt-text);
    /* Sticky a la altura del PRIMER registro de la tabla = debajo del header de tienda + del encabezado
       de columnas sticky (--rkxt-sf-panel-top lo mide rkxt-catalogo-agente.js). Sino el header/thead lo tapan. */
    position: sticky; top: calc(var(--rkxt-sf-panel-top, 20px) + 4px);
    transition: background .15s ease;
}
.rkxt-sf-lateral-rail:hover { background: color-mix(in srgb, var(--rkxt-primary) 12%, var(--rkxt-surface-2, #f4f4f5)); }
.rkxt-sf-lateral-rail-txt { writing-mode: vertical-rl; transform: rotate(180deg); font-weight: 600; font-size: .9rem; white-space: nowrap; letter-spacing: .02em; }
/* El rail del asesor usa EXACTAMENTE el mismo estilo que el de filtros (neutro) — sin variante de color. */

/* Chat abierto → los filtros se contraen al rail. La sidebar deja de ser sticky/fit-content y pasa a
   columna estática y estirada (como la del asesor) para que el rail interno pueda pegarse (un rail dentro
   de un contenedor sticky/corto no se pega a la altura del primer registro). */
.rkxt-sf-catalog--conchat.is-chat .rkxt-sf-sidebar { background: none; border: none; padding: 0; position: static; top: auto; height: auto; align-self: stretch; max-height: none; overflow: visible; }
.rkxt-sf-catalog--conchat.is-chat .rkxt-sf-sidebar > form { display: none; }
.rkxt-sf-catalog--conchat.is-chat .rkxt-sf-sidebar > .rkxt-sf-lateral-rail { display: flex; }

/* El chat: por defecto colapsado (rail visible, panel oculto). */
.rkxt-sf-chat { position: relative; }
.rkxt-sf-chat > .rkxt-sf-lateral-rail { display: flex; }
.rkxt-sf-chat-panel { display: none; }
.rkxt-sf-catalog--conchat.is-chat .rkxt-sf-chat > .rkxt-sf-lateral-rail { display: none; }
.rkxt-sf-catalog--conchat.is-chat .rkxt-sf-chat-panel {
    display: flex; flex-direction: column;
    /* Arranca a la altura del primer registro (debajo del header + encabezado de columnas sticky). */
    position: sticky; top: calc(var(--rkxt-sf-panel-top, 20px) + 4px);
    height: calc(100vh - var(--rkxt-sf-panel-top, 20px) - 24px); max-height: calc(100vh - var(--rkxt-sf-panel-top, 20px) - 24px);
    background: var(--rkxt-surface); border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-sf-radius); overflow: hidden;
}
.rkxt-sf-chat-head {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 12px 14px; border-bottom: 1px solid var(--rkxt-border);
    background: var(--rkxt-primary); color: var(--rkxt-fg-on-primary, #fff);
}
.rkxt-sf-chat-title { font-weight: 700; }
.rkxt-sf-chat-collapse { background: none; border: none; color: inherit; font-size: 1.05rem; cursor: pointer; line-height: 1; padding: 2px 7px; border-radius: 6px; }
.rkxt-sf-chat-collapse:hover { background: rgba(255,255,255,.22); }
.rkxt-sf-chat-msgs { flex: 1 1 auto; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.rkxt-sf-chat-bubble { max-width: 88%; padding: 9px 12px; border-radius: 12px; font-size: .92rem; line-height: 1.42; white-space: pre-wrap; word-wrap: break-word; }
.rkxt-sf-chat-bubble--user { align-self: flex-end; background: var(--rkxt-primary); color: var(--rkxt-fg-on-primary, #fff); border-bottom-right-radius: 4px; }
.rkxt-sf-chat-bubble--bot { align-self: flex-start; background: var(--rkxt-surface-2, #f4f4f5); color: var(--rkxt-text); border: 1px solid var(--rkxt-border); border-bottom-left-radius: 4px; }
.rkxt-sf-chat-verped-link { display: inline-block; margin-top: 4px; font-weight: 600; color: var(--rkxt-primary); }
.rkxt-sf-chat-empty { color: var(--rkxt-text-muted); font-size: .9rem; }
.rkxt-sf-chat-empty ul { margin: 6px 0 0; padding-left: 18px; }
.rkxt-sf-chat-empty li { margin: 3px 0; }
.rkxt-sf-chat-status { padding: 6px 14px; font-size: .85rem; color: var(--rkxt-text-muted); font-style: italic; }
.rkxt-sf-chat-form { display: flex; gap: 8px; padding: 10px; border-top: 1px solid var(--rkxt-border); background: var(--rkxt-surface); }
.rkxt-sf-chat-input { flex: 1 1 auto; resize: none; border: 1px solid var(--rkxt-border); border-radius: 10px; padding: 8px 10px; font: inherit; font-size: .92rem; background: var(--rkxt-bg, #fff); color: var(--rkxt-text); }
.rkxt-sf-chat-input:focus { outline: none; border-color: var(--rkxt-primary); }
.rkxt-sf-chat-send { flex: 0 0 auto; width: 42px; border: none; border-radius: 10px; background: var(--rkxt-primary); color: var(--rkxt-fg-on-primary, #fff); font-size: 1.05rem; cursor: pointer; }
.rkxt-sf-chat-send:disabled { opacity: .5; cursor: default; }

/* Mobile: 1 columna apilada; rails como botones full-width, panel como bloque alto. */
@media (max-width: 800px) {
    .rkxt-sf-catalog--conchat, .rkxt-sf-catalog--conchat.is-chat { grid-template-columns: 1fr; }
    .rkxt-sf-lateral-rail { width: 100%; min-height: 0; height: auto; position: static; padding: 10px; }
    .rkxt-sf-lateral-rail-txt { writing-mode: horizontal-tb; transform: none; }
    .rkxt-sf-catalog--conchat.is-chat .rkxt-sf-chat-panel { position: static; height: 72vh; max-height: 72vh; }
}

.rkxt-sf-filter-block {
    border: none;
    border-bottom: 1px solid var(--rkxt-border);
    padding: 0 0 16px 0;
    margin: 0 0 16px 0;
}

.rkxt-sf-filter-block:last-of-type {
    border-bottom: none;
}

.rkxt-sf-filter-block legend {
    font-weight: 700;
    font-size: 0.92rem;
    margin-bottom: 10px;
    color: var(--rkxt-on-surface);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.rkxt-sf-filter-opt {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    cursor: pointer;
    font-size: 0.92rem;
    color: var(--rkxt-on-surface);
}

.rkxt-sf-filter-opt:hover {
    color: var(--rkxt-primary);
}

.rkxt-sf-filter-opt input[type=checkbox] {
    accent-color: var(--rkxt-primary);
}

.rkxt-sf-filter-clear {
    display: inline-block;
    margin-top: 12px;
    color: var(--rkxt-primary);
    font-size: 0.85rem;
    text-decoration: underline;
}

/* --- Fase 2 navegación: árbol de filtros de categoría (multinivel) --- */
.rkxt-sf-filtree {
    list-style: none;
    margin: 0;
    padding: 0;
}

.rkxt-sf-filtree--root {
    /* el primer nivel no se indenta; los anidados sí, vía .rkxt-sf-filtree-branch */
}

.rkxt-sf-filtree .rkxt-sf-filtree {
    /* niveles anidados: línea-guía + sangría */
    margin-left: 9px;
    padding-left: 11px;
    border-left: 1px solid var(--rkxt-border);
}

.rkxt-sf-filtree-opt {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 0;
    cursor: pointer;
    font-size: 0.9rem;
    color: var(--rkxt-on-surface);
    flex: 1;
    min-width: 0;
}

.rkxt-sf-filtree-opt:hover {
    color: var(--rkxt-primary);
}

.rkxt-sf-filtree-opt input[type=checkbox] {
    accent-color: var(--rkxt-primary);
    flex-shrink: 0;
}

.rkxt-sf-filtree-nombre {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Rama con hijos: el <summary> lleva el checkbox (label) + el chevron de abrir/cerrar */
.rkxt-sf-filtree-summary {
    display: flex;
    align-items: center;
    gap: 6px;
    list-style: none;
    cursor: pointer;
}

.rkxt-sf-filtree-summary::-webkit-details-marker { display: none; }
.rkxt-sf-filtree-summary::marker { content: ""; }

.rkxt-sf-filtree-chevron {
    flex-shrink: 0;
    color: var(--rkxt-text-muted);
    font-size: 0.7rem;
    transition: transform 0.15s ease;
    padding: 0 2px;
}

.rkxt-sf-filtree-branch[open] > .rkxt-sf-filtree-summary > .rkxt-sf-filtree-chevron {
    transform: rotate(90deg);
}

/* --- Fase 2 navegación: filtro de rango de precio (slider de dos puntas) --- */
.rkxt-sf-pricefilter {
    padding-top: 2px;
}

.rkxt-sf-price-vals {
    display: flex;
    justify-content: space-between;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--rkxt-on-surface);
    margin-bottom: 10px;
}

.rkxt-sf-price-slider {
    position: relative;
    height: 26px;
}

/* Riel de fondo */
.rkxt-sf-price-rail {
    position: absolute;
    left: 0;
    right: 0;
    top: 11px;
    height: 4px;
    border-radius: 2px;
    background: var(--rkxt-border);
}

/* Tramo activo (entre las dos puntas), pintado por JS con left/right en % */
.rkxt-sf-price-track {
    position: absolute;
    top: 11px;
    height: 4px;
    border-radius: 2px;
    background: var(--rkxt-primary);
}

/* Los dos range superpuestos: sin fondo, solo el thumb es clickeable */
.rkxt-sf-price-slider input[type=range] {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    width: 100%;
    margin: 0;
    height: 26px;
    background: none;
    pointer-events: none;
    -webkit-appearance: none;
    appearance: none;
}

.rkxt-sf-price-slider input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    pointer-events: auto;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    border: 3px solid var(--rkxt-primary);
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.rkxt-sf-price-slider input[type=range]::-moz-range-thumb {
    pointer-events: auto;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    border: 3px solid var(--rkxt-primary);
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.rkxt-sf-price-slider input[type=range]::-moz-range-track { background: none; }

.rkxt-sf-price-hint {
    display: block;
    margin-top: 8px;
    font-size: 0.78rem;
    color: var(--rkxt-text-muted);
}

/* Fila superior del catálogo mayorista/B2C: buscador de carga rápida (izq., solo mayorista) +
   "Ordenar por" (der.), FUERA de .rkxt-sf-catalog-main y ARRIBA de .rkxt-sf-catalog. Full width
   para que sidebar | tabla | asesor arranquen los 3 a la misma altura (el tope de la tabla). */
.rkxt-sf-catalog-topbar {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.rkxt-sf-catalog-topbar .rkxt-sf-qo-search {
    flex: 1 1 320px;
    max-width: 460px;
    margin-bottom: 0;
}
.rkxt-sf-catalog-topbar .rkxt-sf-catalog-toolbar {
    margin-bottom: 0;
    margin-left: auto;
}
@media (max-width: 800px) {
    /* Mismo quiebre que .rkxt-sf-catalog (sidebar se apila arriba): la fila superior también
       apila para no apretar buscador + ordenar en una sola línea angosta. */
    .rkxt-sf-catalog-topbar { flex-direction: column; align-items: stretch; }
    .rkxt-sf-catalog-topbar .rkxt-sf-qo-search { max-width: none; }
    .rkxt-sf-catalog-topbar .rkxt-sf-catalog-toolbar { margin-left: 0; }
    .rkxt-sf-catalog-topbar .rkxt-sf-catalog-toolbar .rkxt-sf-toolbar-form { width: 100%; }
    .rkxt-sf-catalog-topbar .rkxt-sf-toolbar-form select.rkxt-input { flex: 1; }
}

.rkxt-sf-catalog-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 20px;
}

.rkxt-sf-toolbar-form label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--rkxt-text-muted);
    font-size: 0.92rem;
}

.rkxt-sf-toolbar-form select.rkxt-input {
    min-width: 180px;
}

/* Botones flotantes sobre cards (wishlist + compare) */
.rkxt-sf-card-img {
    position: relative;
}

/* Medio principal = video (mp4): se reproduce el primer frame como portada del listado. */
.rkxt-sf-card-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: var(--rkxt-fit, cover);
    display: block;
    background: #000;
}
.rkxt-sf-card-play {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 0.95rem;
    padding-left: 3px;
    pointer-events: none;
    z-index: 2;
}

.rkxt-sf-card-actions {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    gap: 6px;
    z-index: 2;
}

.rkxt-sf-card-action {
    background: rgba(255, 255, 255, 0.92);
    color: var(--rkxt-text);
    border: 1px solid var(--rkxt-border);
    border-radius: 50%;
    width: 32px;
    height: 32px;
    cursor: pointer;
    font-size: 0.92rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s, transform 0.15s;
    box-shadow: 0 2px 6px rgba(15, 15, 18, 0.10);
}

.rkxt-sf-card-action:hover {
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    transform: scale(1.1);
}

.rkxt-sf-card-action.is-active {
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
}

/* Botones data-rkxt-wishlist/compare en ficha cuando son rkxt-btn-ghost */
.rkxt-btn[data-rkxt-wishlist].is-active,
.rkxt-btn[data-rkxt-compare].is-active {
    background: var(--rkxt-primary-soft);
    color: var(--rkxt-primary);
    border-color: var(--rkxt-primary);
}

/* Badges contadores en header */
.rkxt-sf-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    padding: 0 5px;
    height: 18px;
    border-radius: 9px;
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    font-size: 0.7rem;
    font-weight: 700;
    margin-left: 2px;
    vertical-align: top;
}

.rkxt-sf-badge:empty {
    display: none;
}

/* Tabla comparador */
.rkxt-sf-compare-tabla {
    width: 100%;
    border-collapse: collapse;
    background: var(--rkxt-surface);
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
}

.rkxt-sf-compare-tabla th,
.rkxt-sf-compare-tabla td {
    padding: 14px;
    border-bottom: 1px solid var(--rkxt-border);
    border-right: 1px solid var(--rkxt-border);
    text-align: center;
    vertical-align: top;
}

.rkxt-sf-compare-tabla th:first-child {
    text-align: left;
    background: var(--rkxt-surface-2);
    font-weight: 600;
}

.rkxt-sf-compare-tabla th a {
    color: var(--rkxt-text);
    font-weight: 700;
}

.rkxt-sf-compare-img {
    width: 100%;
    aspect-ratio: 4/5;
    background-color: var(--rkxt-bg-alt);
    background-size: var(--rkxt-fit-bg, cover);
    background-position: center;
    background-repeat: no-repeat;
    border-radius: 6px;
}

/* Tanda 2 — comparador en celular: el comparador es por naturaleza lado-a-lado (hasta 3
   productos + columna de etiquetas). En vez de romper la tabla, el contenedor scrollea en
   horizontal y cada columna tiene un ancho mínimo usable. La página NO desborda: el scroll
   queda contenido en el comparador. (El contenedor #rkxt-compare-cont lo rellena el JS.) */
@media (max-width: 720px) {
    #rkxt-compare-cont {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    #rkxt-compare-cont .rkxt-sf-compare-tabla {
        min-width: 520px;
    }
    .rkxt-sf-compare-tabla th,
    .rkxt-sf-compare-tabla td { padding: 10px; }
}

/* Pedido badges */
.rkxt-pedido-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Badge "mensajes del cliente sin leer" por fila en la grilla de pedidos → link al detalle. */
.rkxt-pedido-badge-msg {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--rkxt-primary);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.4;
    text-decoration: none;
    white-space: nowrap;
    vertical-align: middle;
}
.rkxt-pedido-badge-msg:hover { filter: brightness(0.92); }

.rkxt-estado-pendiente { background: #FFF3D6; color: #B45309; }
.rkxt-estado-pagado { background: #FFEEDE; color: #B85420; }
.rkxt-estado-preparando { background: #F3E8FF; color: #7C3AED; }
.rkxt-estado-enviado { background: #DBEAFE; color: #1D4ED8; }
.rkxt-estado-entregado { background: #DCFCE7; color: #15803D; }
.rkxt-estado-cancelado { background: #FEE2E2; color: #B91C1C; }
/* F9_M024 — estados B2B + entregas parciales. */
.rkxt-estado-enrevision { background: #EDE9FE; color: #6D28D9; }
.rkxt-estado-aprobado { background: #D1FAE5; color: #047857; }
.rkxt-estado-devuelto { background: #FFE4E6; color: #BE123C; }
.rkxt-estado-entregaparcial { background: #FFE8CC; color: #C2570C; }
/* F20 — el cliente re-editó su pedido (inbox del vendedor, distinto de "Pendiente" recién creado). */
.rkxt-estado-modificado { background: #FDE68A; color: #92400E; }
.rkxt-estado-desechado { background: #E5E7EB; color: #6B7280; }

.rkxt-pedido-bloque {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 14px 16px;
    margin-bottom: 14px;
}

/* Carrito */
.rkxt-sf-cart-tabla {
    width: 100%;
    border-collapse: collapse;
    background: var(--rkxt-surface);
    border-radius: var(--rkxt-sf-radius);
    overflow: hidden;
    margin-bottom: 24px;
}

.rkxt-sf-cart-tabla th,
.rkxt-sf-cart-tabla td {
    padding: 14px;
    border-bottom: 1px solid var(--rkxt-border);
    vertical-align: middle;
}

.rkxt-sf-cart-tabla thead th {
    background: var(--rkxt-surface-2);
    text-align: left;
    font-weight: 600;
}

.rkxt-sf-cart-img {
    width: 80px;
    height: 80px;
    background-color: var(--rkxt-bg-alt);
    background-size: var(--rkxt-fit-bg, cover);
    background-position: center;
    background-repeat: no-repeat;
    border-radius: 6px;
}

.rkxt-sf-cart-qty {
    display: flex;
    gap: 6px;
    align-items: center;
}

.rkxt-sf-cart-qty input { width: 70px; }

/* Tanda 2: en celular la tabla del carrito NO debe hacer scroll horizontal. Reflow a cards:
   table/tr/td pasan a block, se oculta el thead y cada <tr> queda como una tarjeta apilada con
   la imagen + datos + acciones. Sin tocar el markup (CSS puro). El <tfoot> del total también
   se apila a la derecha. Mejora de polish recomendada: agregar data-label a cada <td> para
   rotular Precio/Cantidad/Subtotal (requiere markup — anotado en el resumen). */
@media (max-width: 640px) {
    .rkxt-sf-cart-tabla,
    .rkxt-sf-cart-tabla tbody,
    .rkxt-sf-cart-tabla tfoot,
    .rkxt-sf-cart-tabla tr,
    .rkxt-sf-cart-tabla td {
        display: block;
        width: 100%;
    }
    .rkxt-sf-cart-tabla { border: none; background: none; overflow: visible; }
    .rkxt-sf-cart-tabla thead { display: none; }
    .rkxt-sf-cart-tabla tbody tr {
        position: relative;
        background: var(--rkxt-surface);
        border: 1px solid var(--rkxt-border);
        border-radius: var(--rkxt-sf-radius);
        padding: 14px 14px 14px 104px;     /* deja lugar a la izquierda para la miniatura */
        margin-bottom: 14px;
        min-height: 104px;
    }
    .rkxt-sf-cart-tabla tbody td {
        border: none;
        padding: 4px 0;
    }
    /* La miniatura se ancla a la izquierda de la card */
    .rkxt-sf-cart-tabla tbody td:first-child {
        position: absolute;
        top: 14px;
        left: 14px;
        width: 76px;
        padding: 0;
    }
    .rkxt-sf-cart-img { width: 76px; height: 76px; }
    /* Cantidad + acciones: a lo ancho, tappables */
    .rkxt-sf-cart-qty { flex-wrap: wrap; }
    .rkxt-sf-cart-qty input { width: 84px; }
    .rkxt-sf-cart-tabla tbody td .rkxt-btn-inline { width: 100%; margin-top: 4px; }
    /* Total (tfoot): la celda con colspan se alinea a la izquierda apilada */
    .rkxt-sf-cart-tabla tfoot tr {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        padding: 8px 4px;
        border-top: 2px solid var(--rkxt-border);
    }
    .rkxt-sf-cart-tabla tfoot td { width: auto; padding: 0; text-align: left !important; }
    .rkxt-sf-cart-tabla tfoot td:empty { display: none; }

    /* Acciones del carrito (Seguir comprando / Vaciar / Finalizar): a lo ancho, apiladas, con
       Finalizar primero. El div anidado (estilo inline en el markup) también full-width. */
    .rkxt-sf-section > .rkxt-form-actions {
        flex-direction: column;
        gap: 10px;
    }
    .rkxt-sf-section > .rkxt-form-actions > a,
    .rkxt-sf-section > .rkxt-form-actions > div { width: 100%; }
    .rkxt-sf-section > .rkxt-form-actions > div {
        flex-direction: column;
        align-items: stretch !important;
    }
    .rkxt-sf-section > .rkxt-form-actions .rkxt-btn,
    .rkxt-sf-section > .rkxt-form-actions form,
    .rkxt-sf-section > .rkxt-form-actions form .rkxt-btn { width: 100%; min-height: 46px; }
}

/* ============================================================================
   REGLA GENERAL Rakuxt — sticky de barra de filtros + thead en tablas del STOREFRONT
   ("toda tabla que el usuario llena o consulta"). Equivalente storefront del patrón ya
   establecido en el admin (.rkxt-filterbar + .rkxt-table thead th, ver AdminLayout.razor
   y sus vars --rkxt-adminhdr-h/--rkxt-theadtop). Acá:
     .rkxt-sf-sticky-filtros   → agregar a la <form>/barra de filtros que va JUSTO ARRIBA de
                                 la tabla. Se pega debajo del header de tienda (si es sticky).
     .rkxt-sf-sticky-thead     → agregar al <thead> de la tabla. Se pega debajo del header
                                 de tienda + de la barra de filtros.
   Ambas clases se SUMAN (no reemplazan) a las clases propias de cada pantalla, ej.:
     <form class="rkxt-sf-stock-filtros rkxt-sf-sticky-filtros" ...>
     <thead class="rkxt-sf-sticky-thead"><tr>...
   Los offsets (--rkxt-sf-sticky-top = alto header, --rkxt-sf-theadtop = header + filtros) se
   miden en runtime por rkxt-catalogo-agente.js (alto variable: header configurable por tenant,
   filtros que wrapean en mobile/tablet) — mismo mecanismo que ya usaba el catálogo mayorista,
   generalizado. Requiere layout "apilado" (filtros arriba de la tabla, no en rail lateral) y
   NINGÚN ancestro con overflow-x:auto en desktop (gotcha del catálogo — .rkxt-shell usa
   overflow-x:clip, no rompe sticky; ver comentario en .rkxt-sf-qo-scroll más abajo). En mobile,
   las tablas basadas en .rkxt-sf-cart-tabla colapsan a cards y ocultan el thead (media query
   640px más arriba) — ahí el sticky del thead deja de aplicar solo, no hace falta guard extra;
   la barra de filtros sigue sticky (no molesta, no hay thead debajo tapándose). */
.rkxt-sf-sticky-filtros {
    position: sticky;
    top: var(--rkxt-sf-sticky-top, 0px);
    z-index: 6;
    background: var(--rkxt-bg);
}
.rkxt-sf-sticky-thead th {
    position: sticky;
    top: var(--rkxt-sf-theadtop, 0px);
    z-index: 5;
}

/* Carga rápida (quick order) — modo mayorista del catálogo: grilla con cantidad por fila.
   Reusa el look de la tabla del carrito (surface + bordes + header surface-2). */
.rkxt-sf-qo-form { margin-bottom: 24px; }

.rkxt-sf-qo-scroll {
    /* DESKTOP: overflow visible → este div NO es scroll container, así el thead sticky se ancla al
       VIEWPORT (la página) y el encabezado de columnas queda fijo al scrollear. OJO: NO usar
       overflow-x:auto acá — en CSS, auto en un eje fuerza el otro a auto aunque se declare visible,
       y eso volvería a anclar el sticky contra este div (que se scrollea con la página). El
       overflow-x:clip del .rkxt-shell ya evita el scroll horizontal del body en desktop. */
    overflow: visible;
    border-radius: var(--rkxt-sf-radius);
    border: 1px solid var(--rkxt-border);
    background: var(--rkxt-surface);
}
/* MOBILE: la tabla (min-width 640px) no entra → scroll horizontal propio del wrapper. Ahí el sticky
   del thead deja de anclar al viewport (queda anclado a este contenedor), trade-off aceptado en mobile. */
@media (max-width: 800px) {
    .rkxt-sf-qo-scroll { overflow-x: auto; }
}

.rkxt-sf-qo-tabla {
    width: 100%;
    border-collapse: collapse;
    min-width: 640px;
}

.rkxt-sf-qo-tabla th,
.rkxt-sf-qo-tabla td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--rkxt-border);
    vertical-align: middle;
    text-align: left;
}

.rkxt-sf-qo-tabla thead th {
    background: var(--rkxt-surface-2);
    font-weight: 600;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--rkxt-text-muted);
    /* Encabezado de columnas siempre visible al scrollear la lista (cientos de productos).
       Offset = altura del header de tienda si es sticky (--rkxt-sf-sticky-top, lo mide rkxt-catalogo-agente.js;
       0 si el header no es sticky). Sin esto, con header sticky el thead queda TAPADO por el header. */
    position: sticky;
    top: var(--rkxt-sf-sticky-top, 0px);
    z-index: 5;
}

.rkxt-sf-qo-tabla tbody tr:last-child td { border-bottom: none; }
.rkxt-sf-qo-tabla tbody tr:hover { background: var(--rkxt-bg-alt); }

.rkxt-sf-qo-th-img { width: 64px; }
.rkxt-sf-qo-th-precio { width: 140px; }
.rkxt-sf-qo-th-stock { width: 110px; }
.rkxt-sf-qo-th-cant { width: 120px; }

.rkxt-sf-qo-img {
    display: block;
    width: 56px;
    height: 56px;
    background-color: var(--rkxt-bg-alt);
    /* Encuadre configurable (F3.7.39): hereda tienda ?? empresa vía var del shell. */
    background-size: var(--rkxt-fit-bg, cover);
    background-position: center;
    background-repeat: no-repeat;
    border-radius: 6px;
}

.rkxt-sf-qo-cell-nombre { line-height: 1.3; }

.rkxt-sf-qo-img-link {
    display: block;
    cursor: pointer;
    border-radius: 8px;
    transition: box-shadow .12s ease, transform .12s ease;
}
.rkxt-sf-qo-img-link:hover {
    box-shadow: 0 0 0 2px var(--rkxt-primary);
    transform: translateY(-1px);
}

.rkxt-sf-qo-nombre {
    display: block;
    font-weight: 600;
    color: var(--rkxt-text);
    cursor: pointer;
}
.rkxt-sf-qo-nombre:hover { color: var(--rkxt-primary); text-decoration: underline; }

.rkxt-sf-qo-vermas {
    display: inline-block;
    margin-top: 2px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--rkxt-primary);
}
.rkxt-sf-qo-vermas:hover { text-decoration: underline; }

.rkxt-sf-qo-sku {
    display: block;
    font-family: var(--rkxt-font-mono, 'JetBrains Mono', monospace);
    font-size: 0.78rem;
    color: var(--rkxt-text-muted);
    margin-top: 2px;
}

.rkxt-sf-qo-stock-ok { color: var(--rkxt-text); font-size: 0.9rem; }
.rkxt-sf-qo-stock-na { color: var(--rkxt-text-muted); }

.rkxt-sf-qo-chip-off {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--rkxt-text-muted);
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
}

.rkxt-sf-qo-row--off { opacity: 0.62; }
/* Item 5 — fila/producto que modificó el VENDEDOR (el cliente la ve resaltada al re-editar). */
.rkxt-sf-qo-row--modv > td { background: #FEF6DC; }
.rkxt-sf-qo-row--modv:hover > td { background: #FDECBE; }
.rkxt-qo-badge-modv {
    display: inline-block; margin-left: .4rem; font-size: .68rem; font-weight: 700;
    color: #92400E; background: #FDE68A; padding: .06rem .42rem; border-radius: 6px;
    vertical-align: middle; letter-spacing: .01em;
}
.rkxt-sf-cart-filter-on--modv { color: #92400E; }

.rkxt-sf-qo-input { width: 90px; text-align: right; }
.rkxt-sf-qo-input:disabled { cursor: not-allowed; opacity: 0.5; }

.rkxt-sf-qo-bar {
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 14px;
    padding: 14px 16px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-sf-radius);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06);
}

.rkxt-sf-qo-bar-hint { color: var(--rkxt-text-muted); font-size: 0.9rem; }
.rkxt-sf-qo-bar .rkxt-btn { min-height: 44px; }

@media (max-width: 640px) {
    .rkxt-sf-qo-bar { flex-direction: column; align-items: stretch; }
    .rkxt-sf-qo-bar .rkxt-btn { width: 100%; }
    .rkxt-sf-qo-bar-hint { text-align: center; }
}

/* --- Acordeón de curva de talles (carga rápida B2B) --- */

/* Tag "N talles" junto al SKU para distinguir productos con curva. */
.rkxt-sf-qo-curva-tag {
    display: inline-block;
    margin-top: 2px;
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--rkxt-primary);
    background: var(--rkxt-primary-soft);
}

/* Botón-celda que reemplaza al input para productos con curva: muestra el TOTAL + chevron. */
.rkxt-sf-qo-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: 90px;
    justify-content: space-between;
    padding: 7px 10px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    color: var(--rkxt-text);
    font: inherit;
    cursor: pointer;
    transition: border-color .12s ease, background .12s ease;
}
.rkxt-sf-qo-toggle:hover:not(:disabled) { border-color: var(--rkxt-primary); }
.rkxt-sf-qo-toggle:disabled { cursor: not-allowed; opacity: 0.5; }
.rkxt-sf-qo-toggle[aria-expanded="true"] {
    border-color: var(--rkxt-primary);
    background: var(--rkxt-primary-soft);
}

.rkxt-sf-qo-total {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--rkxt-text-muted);
}
.rkxt-sf-qo-total--has { color: var(--rkxt-primary); }

.rkxt-sf-qo-chevron {
    flex: 0 0 auto;
    font-size: 0.7rem;
    color: var(--rkxt-text-muted);
}
.rkxt-sf-qo-toggle[aria-expanded="true"] .rkxt-sf-qo-chevron { color: var(--rkxt-primary); }

/* Sub-fila detail-row con la curva. */
.rkxt-sf-qo-detail > td {
    padding: 0;
    background: var(--rkxt-bg-alt);
}
.rkxt-sf-qo-curva {
    padding: 14px 16px;
    border-top: 2px solid var(--rkxt-primary-soft);
}

.rkxt-sf-qo-curva-loading {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--rkxt-text-muted);
    font-size: 0.9rem;
    padding: 6px 0;
}
.rkxt-sf-qo-spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--rkxt-border);
    border-top-color: var(--rkxt-primary);
    border-radius: 50%;
    animation: rkxt-qo-spin 0.7s linear infinite;
}
@keyframes rkxt-qo-spin { to { transform: rotate(360deg); } }

.rkxt-sf-qo-curva-error {
    color: var(--rkxt-text-muted);
    font-size: 0.9rem;
    padding: 4px 0;
}

/* Cabecera de la curva: reparto rápido + totales en vivo. */
.rkxt-sf-qo-curva-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 12px;
}
.rkxt-sf-qo-reparto {
    display: flex;
    align-items: center;
    gap: 8px;
}
.rkxt-sf-qo-reparto-lbl {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--rkxt-text-muted);
}
.rkxt-sf-qo-reparto-input { width: 86px; text-align: right; }
.rkxt-sf-qo-reparto-btn { min-height: 38px; padding: 6px 14px; }

.rkxt-sf-qo-curva-totales {
    display: flex;
    align-items: center;
    gap: 16px;
    font-size: 0.9rem;
}
.rkxt-sf-qo-curva-units {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--rkxt-primary);
}
.rkxt-sf-qo-curva-sub { color: var(--rkxt-text-muted); }
.rkxt-sf-qo-curva-sub strong {
    color: var(--rkxt-text);
    font-variant-numeric: tabular-nums;
}

/* Grilla de inputs por talle. */
.rkxt-sf-qo-curva-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
    gap: 10px;
}
.rkxt-sf-qo-curva-cell--off { opacity: 0.55; }
/* Item 5 — talle que modificó el vendedor (el cliente lo ve resaltado en la curva). */
.rkxt-sf-qo-curva-cell--modv {
    background: var(--rkxt-warn-soft, #FEF3C7);
    border-radius: var(--rkxt-radius-sm, 8px);
    box-shadow: inset 3px 0 0 var(--rkxt-warn, #D97706);
    padding: 6px 8px;
    margin: -2px 0;
}
.rkxt-sf-qo-curva-talle--modv { color: var(--rkxt-warn, #D97706); }

.rkxt-sf-qo-curva-talle {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--rkxt-text);
}
.rkxt-sf-qo-curva-input { width: 100%; text-align: right; }
.rkxt-sf-qo-curva-input:disabled { cursor: not-allowed; opacity: 0.6; }
.rkxt-sf-qo-curva-stock {
    font-size: 0.72rem;
    font-weight: 400;
    color: var(--rkxt-text-muted);
}
/* Stock del LOCAL DEL CLIENTE por talle (distinto del disponible del vendedor). En rojo cuando
   está agotado o por debajo del mínimo declarado: ahí es donde hay que reponer. */
.rkxt-sf-qo-curva-mio {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--rkxt-text-muted);
    opacity: 0.9;
}
.rkxt-sf-qo-curva-mio--bajo { color: #c2410c; }

@media (max-width: 640px) {
    .rkxt-sf-qo-curva-head { flex-direction: column; align-items: stretch; }
    .rkxt-sf-qo-curva-totales { justify-content: space-between; }
}

/* WhatsApp flotante */
.rkxt-sf-whatsapp {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 56px;
    height: 56px;
    background: #25D366;
    color: #FFFFFF;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 8px 24px rgba(37, 211, 102, 0.4);
    transition: transform 0.15s;
    z-index: 100;
}

.rkxt-sf-whatsapp:hover {
    transform: scale(1.08);
    color: #FFFFFF;
}

.rkxt-sf-pdp-cta .rkxt-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* =============================================================
   AuthLayout — fondo inmersivo + card flotante (Login / Registro)
   Patrón estilo Tiendanube: foto full-screen + tarjeta a la izquierda.
   Mantiene identidad dark Rakuxt con card translúcida sobre la foto.
   ============================================================= */

.rkxt-auth-fullscreen {
    position: relative;
    min-height: 100vh;
    width: 100%;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.rkxt-auth-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    z-index: 0;
    transform: scale(1.02);
}

.rkxt-auth-overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    /* light overlay: cohesión cálida + leve oscurecido en bordes para legibilidad de topbar/footer */
    background:
        linear-gradient(120deg,
            rgba(255, 255, 255, 0.62) 0%,
            rgba(255, 255, 255, 0.38) 42%,
            rgba(255, 255, 255, 0.10) 62%,
            rgba(255, 255, 255, 0.00) 100%),
        linear-gradient(180deg,
            rgba(15, 15, 18, 0.18) 0%,
            rgba(15, 15, 18, 0.00) 18%,
            rgba(15, 15, 18, 0.00) 82%,
            rgba(15, 15, 18, 0.25) 100%);
}

.rkxt-auth-topbar {
    position: relative;
    z-index: 3;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 22px 40px;
}

.rkxt-auth-topbrand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--rkxt-text);
    font-family: var(--rkxt-font-display);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    text-decoration: none;
    text-shadow: 0 1px 6px rgba(255, 255, 255, 0.6);
}

.rkxt-auth-topbrand .rkxt-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: var(--rkxt-primary);
    color: #FFFFFF;
    font-weight: 800;
    font-size: 0.95rem;
    box-shadow: 0 4px 14px rgba(235, 82, 2, 0.32);
}

.rkxt-auth-topbrand:hover { color: var(--rkxt-text); }

.rkxt-auth-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    border-radius: var(--rkxt-radius-pill);
    background: rgba(255, 255, 255, 0.88);
    color: var(--rkxt-text);
    font-size: 0.85rem;
    text-decoration: none;
    border: 1px solid var(--rkxt-border);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 2px 8px rgba(15, 15, 18, 0.08);
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.rkxt-auth-pill:hover {
    background: #FFFFFF;
    border-color: var(--rkxt-primary);
    color: var(--rkxt-primary);
}

.rkxt-auth-pill strong {
    color: var(--rkxt-primary);
    font-weight: 700;
}

.rkxt-auth-panel {
    position: relative;
    z-index: 2;
    flex: 1;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    padding: 24px 40px 40px 80px;
}

.rkxt-auth-panel-card {
    width: 100%;
    max-width: 460px;
    background: rgba(255, 255, 255, 0.96);
    border: 1px solid var(--rkxt-border);
    border-radius: 18px;
    padding: 36px 36px 28px 36px;
    box-shadow:
        0 24px 60px rgba(15, 15, 18, 0.22),
        0 4px 12px rgba(15, 15, 18, 0.08);
    backdrop-filter: blur(8px) saturate(120%);
    -webkit-backdrop-filter: blur(8px) saturate(120%);
    color: var(--rkxt-text);
}

/* Cuando el form interno tiene grid de 3 columnas no entra cómodo en la card de 460 */
.rkxt-auth-panel-card .rkxt-field-grid {
    grid-template-columns: 1fr 1fr;
}

@media (max-width: 720px) {
    .rkxt-auth-panel-card .rkxt-field-grid {
        grid-template-columns: 1fr;
    }
}

.rkxt-auth-panel-card h1 {
    font-size: 1.55rem;
    margin: 0 0 6px 0;
    color: var(--rkxt-text);
    letter-spacing: -0.02em;
}

.rkxt-auth-panel-card h2.rkxt-admin-section-title {
    margin-top: 18px;
    margin-bottom: 6px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--rkxt-text-muted);
    border-bottom: 1px solid var(--rkxt-border);
    padding-bottom: 4px;
    font-weight: 700;
}

.rkxt-auth-panel-card .rkxt-auth-lead {
    color: var(--rkxt-text-muted);
    margin: 0 0 18px 0;
    font-size: 0.92rem;
}

.rkxt-auth-panel-card .rkxt-auth-brand {
    display: none; /* el brand ya vive en el topbar del layout */
}

.rkxt-auth-panel-card .rkxt-input {
    background: var(--rkxt-bg-alt);
    border-color: var(--rkxt-border);
}

.rkxt-auth-panel-card .rkxt-input:focus {
    border-color: var(--rkxt-primary);
    background: #FFFFFF;
}

.rkxt-auth-panel-card .rkxt-btn-primary {
    width: 100%;
    padding: 13px 18px;
    font-size: 1rem;
}

.rkxt-auth-panel-card .rkxt-form-actions {
    flex-direction: column-reverse;
    gap: 10px;
    margin-top: 22px;
}

.rkxt-auth-panel-card .rkxt-form-actions .rkxt-btn {
    width: 100%;
}

.rkxt-auth-panel-card .rkxt-auth-meta {
    margin-top: 18px;
    border-top: 1px solid var(--rkxt-border);
    padding-top: 16px;
}

.rkxt-auth-foot {
    position: relative;
    z-index: 3;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding: 14px 40px 18px 40px;
    color: var(--rkxt-text-muted);
    font-size: 0.78rem;
    text-shadow: 0 1px 4px rgba(255, 255, 255, 0.55);
}

.rkxt-auth-foot a {
    color: var(--rkxt-text);
    text-decoration: none;
}

.rkxt-auth-foot a:hover {
    color: var(--rkxt-primary);
}

.rkxt-auth-foot-sep {
    opacity: 0.4;
}

@media (max-width: 900px) {
    .rkxt-auth-panel {
        padding: 12px 20px 24px 20px;
        justify-content: center;
    }
    .rkxt-auth-topbar {
        padding: 16px 20px;
    }
    .rkxt-auth-foot {
        padding: 12px 20px 16px 20px;
        justify-content: center;
        text-align: center;
    }
    .rkxt-auth-pill {
        font-size: 0.78rem;
        padding: 6px 12px;
    }
}

@media (max-width: 520px) {
    .rkxt-auth-panel-card {
        padding: 26px 22px 22px 22px;
        border-radius: 14px;
    }
    .rkxt-auth-panel-card h1 {
        font-size: 1.35rem;
    }
}

/* Landing pública en home `/` (cuando el AuthLayout sirve la home) */
.rkxt-home-features {
    list-style: none;
    padding: 0;
    margin: 18px 0 22px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.rkxt-home-features li {
    color: var(--rkxt-text-muted);
    font-size: 0.92rem;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    line-height: 1.5;
}

.rkxt-home-bullet {
    color: var(--rkxt-accent);
    font-weight: 800;
    font-size: 1rem;
    flex-shrink: 0;
    margin-top: 1px;
}

.rkxt-home-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 8px;
}

.rkxt-home-actions .rkxt-btn {
    width: 100%;
    padding: 13px 18px;
    font-size: 1rem;
}

/* =============================================================
   LandingLayout — paleta light + naranja institucional
   Identidad alineada con sitio público IntegraIA (mockup en /).
   Variables locales encapsuladas en .rkxt-landing — no afecta
   admin, storefront ni auth (mantienen Capa A dark vigente).
   ============================================================= */

.rkxt-landing {
    --land-bg: #FFFFFF;
    --land-bg-soft: #FAF8F5;
    --land-bg-strip: #FBF8F4;
    --land-text: #0E0E11;
    --land-text-muted: #5E5E68;
    --land-text-dim: #8A8A95;
    --land-border: #ECE9E4;
    --land-border-strong: #DAD6CF;

    --land-orange: #EB5202;
    --land-orange-hover: #D14802;
    --land-orange-soft: #FFEEDE;
    --land-orange-ink: #92340A;

    --land-green: #16A34A;
    --land-green-soft: #DCFCE7;
    --land-amber-soft: #FFF3D6;
    --land-amber-ink: #B45309;

    --land-radius: 12px;
    --land-radius-sm: 8px;
    --land-radius-pill: 999px;

    --land-shadow-sm: 0 1px 2px rgba(15, 15, 18, 0.04), 0 1px 1px rgba(15, 15, 18, 0.03);
    --land-shadow-md: 0 12px 32px rgba(15, 15, 18, 0.07), 0 2px 6px rgba(15, 15, 18, 0.04);
    --land-shadow-mock: 0 24px 60px rgba(235, 82, 2, 0.10), 0 4px 12px rgba(15, 15, 18, 0.05);

    --land-font-display: 'DM Serif Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
    --land-font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

    background: var(--land-bg);
    color: var(--land-text);
    font-family: var(--land-font-body);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* --- top suite bar --- */
.rkxt-landing-suitebar {
    background: var(--land-bg-strip);
    border-bottom: 1px solid var(--land-border);
    font-size: 0.82rem;
    color: var(--land-text-muted);
}

.rkxt-landing-suitebar-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 9px 32px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.rkxt-landing-suite-back,
.rkxt-landing-suite-nav a {
    color: var(--land-text-muted);
    text-decoration: none;
    transition: color 0.12s;
}

.rkxt-landing-suite-back:hover,
.rkxt-landing-suite-nav a:hover {
    color: var(--land-orange);
}

.rkxt-landing-suite-mark {
    color: var(--land-text);
    font-weight: 600;
    margin-left: 4px;
}

.rkxt-landing-suite-nav {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.rkxt-landing-suite-sep {
    opacity: 0.45;
}

/* --- header --- */
.rkxt-landing-header {
    background: var(--land-bg);
    border-bottom: 1px solid var(--land-border);
}

.rkxt-landing-header-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 18px 32px;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 32px;
}

.rkxt-landing-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: var(--land-text);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: -0.01em;
}

.rkxt-landing-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: var(--land-orange);
    color: #FFFFFF;
    box-shadow: 0 6px 14px rgba(235, 82, 2, 0.25);
}

.rkxt-landing-brand-name {
    font-family: var(--land-font-body);
    font-weight: 700;
}

.rkxt-landing-nav {
    display: inline-flex;
    justify-content: center;
    gap: 28px;
}

.rkxt-landing-nav a {
    color: var(--land-text-muted);
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 500;
    transition: color 0.12s;
    padding: 6px 2px;
    border-bottom: 2px solid transparent;
}

.rkxt-landing-nav a:hover {
    color: var(--land-text);
}

.rkxt-landing-nav a.is-active {
    color: var(--land-orange);
    border-bottom-color: var(--land-orange);
}

.rkxt-landing-header-cta {
    display: inline-flex;
    gap: 10px;
}

/* --- botones (paleta light naranja) --- */
.rkxt-landing-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 18px;
    border-radius: var(--land-radius-sm);
    font-family: var(--land-font-body);
    font-weight: 600;
    font-size: 0.92rem;
    border: 1.5px solid transparent;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.12s, border-color 0.12s, color 0.12s, transform 0.08s, box-shadow 0.15s;
}

.rkxt-landing-btn-primary {
    background: var(--land-orange);
    color: #FFFFFF;
    box-shadow: 0 6px 18px rgba(235, 82, 2, 0.20);
}

.rkxt-landing-btn-primary:hover {
    background: var(--land-orange-hover);
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 10px 22px rgba(235, 82, 2, 0.28);
}

.rkxt-landing-btn-outline {
    background: var(--land-bg);
    color: var(--land-orange);
    border-color: var(--land-orange);
}

.rkxt-landing-btn-outline:hover {
    background: var(--land-orange-soft);
    color: var(--land-orange-hover);
}

.rkxt-landing-btn-ghost {
    background: transparent;
    color: var(--land-text);
    border-color: transparent;
    padding-left: 6px;
    padding-right: 6px;
}

.rkxt-landing-btn-ghost:hover {
    color: var(--land-orange);
}

.rkxt-landing-btn-lg {
    padding: 13px 22px;
    font-size: 1rem;
}

/* --- main / hero --- */
.rkxt-landing-main {
    flex: 1;
}

.rkxt-landing-hero {
    background: var(--land-bg);
}

.rkxt-landing-hero-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 72px 32px 88px 32px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 64px;
    align-items: center;
}

@media (max-width: 980px) {
    .rkxt-landing-hero-inner {
        grid-template-columns: 1fr;
        padding: 48px 24px 60px 24px;
        gap: 48px;
    }
    .rkxt-landing-header-inner {
        grid-template-columns: auto auto;
    }
    .rkxt-landing-nav { display: none; }
    .rkxt-landing-header-cta .rkxt-landing-btn-outline { display: none; }
}

.rkxt-landing-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px;
    border-radius: var(--land-radius-pill);
    background: var(--land-orange-soft);
    color: var(--land-orange-ink);
    font-size: 0.84rem;
    font-weight: 500;
    margin-bottom: 22px;
}

.rkxt-landing-chip-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--land-orange);
}

.rkxt-landing-h1 {
    font-family: var(--land-font-display);
    font-weight: 400;
    font-size: clamp(2.5rem, 5.5vw, 4rem);
    line-height: 1.04;
    letter-spacing: -0.015em;
    color: var(--land-text);
    margin: 0 0 24px 0;
}

.rkxt-landing-h1-accent {
    color: var(--land-orange);
}

.rkxt-landing-lead {
    color: var(--land-text-muted);
    font-size: 1.05rem;
    line-height: 1.6;
    margin: 0 0 32px 0;
    max-width: 520px;
}

.rkxt-landing-cta-row {
    display: inline-flex;
    gap: 14px;
    align-items: center;
    margin-bottom: 28px;
    flex-wrap: wrap;
}

.rkxt-landing-trust {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--land-text-muted);
    font-size: 0.88rem;
    margin: 0;
}

.rkxt-landing-trust-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--land-orange-soft);
    color: var(--land-orange);
    font-size: 0.75rem;
    font-weight: 700;
}

.rkxt-landing-trust-dot {
    opacity: 0.5;
}

.rkxt-landing-trust strong {
    color: var(--land-text);
    font-weight: 600;
}

/* --- mock window admin --- */
.rkxt-landing-hero-mock {
    display: flex;
    justify-content: center;
}

.rkxt-landing-mock-window {
    background: var(--land-bg);
    border: 1px solid var(--land-border);
    border-radius: var(--land-radius);
    overflow: hidden;
    width: 100%;
    max-width: 560px;
    box-shadow: var(--land-shadow-mock);
}

.rkxt-landing-mock-chrome {
    background: var(--land-bg-soft);
    border-bottom: 1px solid var(--land-border);
    padding: 11px 14px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.rkxt-landing-mock-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
}

.rkxt-landing-mock-dot-red { background: #FF5F57; }
.rkxt-landing-mock-dot-amber { background: #FEBC2E; }
.rkxt-landing-mock-dot-green { background: #28C840; }

.rkxt-landing-mock-url {
    margin-left: 18px;
    color: var(--land-text-dim);
    font-size: 0.82rem;
    font-family: 'JetBrains Mono', Consolas, monospace;
}

.rkxt-landing-mock-body {
    padding: 22px;
}

.rkxt-landing-mock-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 18px;
}

.rkxt-landing-mock-title {
    font-weight: 600;
    color: var(--land-text);
    font-size: 0.95rem;
}

.rkxt-landing-mock-badge {
    color: var(--land-orange);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
}

.rkxt-landing-mock-kpis {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 18px;
}

.rkxt-landing-mock-kpi {
    background: var(--land-bg-soft);
    border-radius: var(--land-radius-sm);
    padding: 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.rkxt-landing-mock-kpi-label {
    color: var(--land-text-dim);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.rkxt-landing-mock-kpi-value {
    color: var(--land-text);
    font-weight: 700;
    font-size: 1.1rem;
    letter-spacing: -0.01em;
}

.rkxt-landing-mock-kpi-trend {
    color: var(--land-text-dim);
    font-size: 0.72rem;
}

.rkxt-landing-mock-kpi-trend.rkxt-up {
    color: var(--land-green);
}

.rkxt-landing-mock-events {
    border-top: 1px solid var(--land-border);
    padding-top: 14px;
}

.rkxt-landing-mock-events-title {
    display: block;
    color: var(--land-text-dim);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 8px;
}

.rkxt-landing-mock-event {
    display: grid;
    grid-template-columns: 24px 1fr auto auto;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    font-size: 0.86rem;
    color: var(--land-text);
    border-bottom: 1px solid var(--land-border);
}

.rkxt-landing-mock-event:last-child {
    border-bottom: none;
}

.rkxt-landing-mock-event-icon {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.65rem;
    font-weight: 700;
    color: #FFFFFF;
}

.rkxt-landing-mock-event-orange { background: var(--land-orange); }
.rkxt-landing-mock-event-green { background: var(--land-green); }

.rkxt-landing-mock-event-text {
    color: var(--land-text);
}

.rkxt-landing-mock-event-meta {
    color: var(--land-text-dim);
    font-size: 0.78rem;
}

.rkxt-landing-mock-tag {
    padding: 3px 8px;
    border-radius: var(--land-radius-sm);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.04em;
}

.rkxt-landing-mock-tag-ok {
    background: var(--land-green-soft);
    color: var(--land-green);
}

.rkxt-landing-mock-tag-warn {
    background: var(--land-amber-soft);
    color: var(--land-amber-ink);
}

/* --- footer --- */
.rkxt-landing-footer {
    background: var(--land-bg-strip);
    border-top: 1px solid var(--land-border);
    color: var(--land-text-muted);
    font-size: 0.82rem;
}

.rkxt-landing-footer-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 16px 32px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.rkxt-landing-footer a {
    color: var(--land-text-muted);
    text-decoration: none;
    transition: color 0.12s;
}

.rkxt-landing-footer a:hover {
    color: var(--land-orange);
}

.rkxt-landing-footer-sep {
    opacity: 0.4;
}

/* ==== Image upload preview (admin tiendas) ==== */
.rkxt-image-preview {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: repeating-conic-gradient(#f1f3f5 0% 25%, #fff 0% 50%) 0 0 / 16px 16px;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: 6px;
    margin: 6px 0;
    max-width: 100%;
}

.rkxt-image-preview img {
    display: block;
    max-width: 100%;
    object-fit: contain;
}

.rkxt-image-preview-logo img {
    height: 60px;
    max-width: 280px;
}

.rkxt-image-preview-favicon img {
    height: 48px;
    width: 48px;
}

.rkxt-image-preview-cat img {
    max-height: 140px;
    max-width: 280px;
    object-fit: cover;
    border-radius: var(--rkxt-radius-sm);
}

/* Preview de N imágenes en input[multiple] */
.rkxt-image-preview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 8px;
    margin-bottom: 8px;
}

.rkxt-image-preview-grid:empty { display: none; }

.rkxt-image-preview-grid-item {
    position: relative;
    aspect-ratio: 1;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    overflow: hidden;
    background: var(--rkxt-bg-alt);
}

.rkxt-image-preview-grid-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rkxt-image-preview-grid-item.is-principal {
    border-color: var(--rkxt-primary);
    box-shadow: 0 0 0 1px var(--rkxt-primary);
}

.rkxt-image-preview-badge {
    position: absolute;
    top: 4px;
    left: 4px;
    background: var(--rkxt-primary);
    color: #fff;
    font-size: 0.65rem;
    padding: 2px 6px;
    border-radius: 3px;
    text-transform: uppercase;
    font-weight: 600;
    letter-spacing: 0.04em;
}

/* ============ Diseñar páginas — UI admin ============ */
.rkxt-diseno-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--rkxt-border);
    margin: 24px 0;
}

.rkxt-diseno-tab {
    background: transparent;
    border: none;
    border-bottom: 3px solid transparent;
    padding: 10px 18px;
    font-weight: 600;
    color: var(--rkxt-text-dim);
    cursor: pointer;
    margin-bottom: -1px;
}

.rkxt-diseno-tab:hover { color: var(--rkxt-text); }

.rkxt-diseno-tab.is-active {
    color: var(--rkxt-primary);
    border-bottom-color: var(--rkxt-primary);
}

.rkxt-diseno-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
}

/* ---- Gestor de páginas con URL propia (tab "Páginas" del editor de diseño) ---- */
.rkxt-diseno-paglist {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.rkxt-diseno-pagrow {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    background: var(--rkxt-surface, #fff);
    border: 1px solid var(--rkxt-border, #e5e7eb);
    border-radius: var(--rkxt-radius, 10px);
}
.rkxt-diseno-pagrow.is-disabled { opacity: .6; }
.rkxt-diseno-pagrow-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}
.rkxt-diseno-pagrow-info code { font-size: .8rem; }
.rkxt-diseno-pagrow-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

/* Breadcrumb al diseñar una página custom (volver al gestor + título). */
.rkxt-diseno-pagbread {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--rkxt-border, #e5e7eb);
}
.rkxt-diseno-pagbread-tit {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
    flex: 1 1 auto;
}

/* Storefront: página custom no encontrada / sin publicar. */
.rkxt-sf-pagina-404 {
    max-width: 640px;
    margin: 80px auto;
    padding: 0 20px;
    text-align: center;
}
.rkxt-sf-pagina-404 h1 { margin: 0 0 12px; }
.rkxt-sf-pagina-404 p { margin: 0 0 24px; color: var(--rkxt-text-muted, #6b7280); }
.rkxt-sf-pagina-vacia { min-height: 40vh; }

/* Control inline compacto del paño (fondo de la página) en la toolbar del editor.
   Etiqueta + swatch de color alineados horizontalmente, font chica, en línea con el resto
   de la toolbar. El .rkxt-color-swatch ya es global (no se redefine acá). */
.rkxt-diseno-pano {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    color: var(--rkxt-text-muted);
    cursor: pointer;
}
.rkxt-diseno-pano > span {
    white-space: nowrap;
}

.rkxt-diseno-stack {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Tarjeta de un componente dentro de un slot. Es el row flex en sí mismo
   (icono + títulos + acciones como hijos directos), pensada para vivir en
   columnas angostas: por eso permite wrap de las acciones y trunca títulos. */
.rkxt-diseno-block {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    box-shadow: var(--rkxt-shadow-sm);
}

/* Bloque cuyo editor lateral está ABIERTO (feedback de "qué estoy editando"), sea que se abrió por el
   botón "Editar" o por el clic sobre el componente en el preview. */
.rkxt-diseno-block.is-editing {
    background: var(--rkxt-primary-soft);
    border-left: 3px solid var(--rkxt-primary);
}

.rkxt-diseno-block.is-disabled {
    opacity: 0.55;
    background: var(--rkxt-bg-alt);
    box-shadow: none;
}

.rkxt-diseno-block-icon {
    font-size: 1.3rem;
    width: 28px;
    text-align: center;
    flex-shrink: 0;
}

.rkxt-diseno-block-titles {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.rkxt-diseno-block-titles strong {
    font-size: 0.9rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rkxt-diseno-block-titles small {
    font-size: 0.8rem;
    color: var(--rkxt-text-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rkxt-diseno-block-actions {
    display: flex;
    gap: 3px;
    flex-wrap: wrap;
    flex-shrink: 0;
    justify-content: flex-end;
}

/* Selector de tipo de bloque en el modal "Agregar" */
.rkxt-diseno-tipos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 12px;
}

.rkxt-diseno-tipo-card {
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 16px;
    text-align: center;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: center;
    transition: border-color 0.12s, transform 0.12s;
}

.rkxt-diseno-tipo-card:hover {
    border-color: var(--rkxt-primary);
    transform: translateY(-1px);
}

.rkxt-diseno-tipo-icon { font-size: 1.8rem; }
.rkxt-diseno-tipo-card strong { font-size: 0.95rem; color: var(--rkxt-text); }
.rkxt-diseno-tipo-card small {
    font-size: 0.78rem;
    color: var(--rkxt-text-dim);
    line-height: 1.3;
}

/* ---- Editor de secciones con layout (la "hoja" del CMS en el admin) ---- */

/* Contenedor vertical de todas las secciones de la página. */
.rkxt-diseno-secs {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Tarjeta de una sección: agrupa su header de control + la grilla de slots. */
.rkxt-diseno-sec {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 16px;
    box-shadow: var(--rkxt-shadow-sm);
}

/* Flash de la tarjeta de sección al clickear su bloque en el preview (clic-en-preview → editar). */
.rkxt-diseno-sec--flash {
    outline: 2px solid var(--rkxt-primary);
    outline-offset: 2px;
    transition: outline-color .2s;
}

.rkxt-diseno-sec.is-disabled {
    opacity: 0.55;
    background: var(--rkxt-bg-alt);
    box-shadow: none;
}

/* Header de la sección: badge de layout + selects inline + acciones a la derecha. */
.rkxt-diseno-sec-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

/* Etiqueta del layout (pill suave en tono primary). */
.rkxt-diseno-sec-badge {
    display: inline-flex;
    align-items: center;
    background: var(--rkxt-primary-soft);
    color: var(--rkxt-primary);
    border: 1px solid var(--rkxt-primary-soft);
    border-radius: var(--rkxt-radius-pill);
    padding: 3px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

/* Grupo de botones a la derecha del header. */
.rkxt-diseno-sec-actions {
    margin-left: auto;
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

/* Variante chica del input para los selects inline del header. */
.rkxt-input-xs {
    width: auto;
    padding: 5px 8px;
    font-size: 0.8rem;
    border-radius: 6px;
}

/* ---- Barra "Fondo" de la sección (debajo del head, secundaria al control de layout) ---- */
/* Fila horizontal compacta: tipo de fondo + swatch/uploader + color de texto. Separada
   del head con un borde sutil para que se lea como una sub-barra y no compita con él. */
.rkxt-diseno-sec-fondo {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 0.82rem;
    margin: -4px 0 14px;
    padding-top: 10px;
    border-top: 1px dashed var(--rkxt-border);
}

/* Mini-labels "Fondo" / "Texto": muted, peso 600, chicos. */
.rkxt-diseno-sec-fondo-lbl {
    color: var(--rkxt-text-muted);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.01em;
}

/* Miniatura de la imagen de fondo subida. */
.rkxt-diseno-fondo-thumb {
    width: 40px;
    height: 28px;
    object-fit: cover;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface-2);
    flex: 0 0 auto;
}

/* ---- Color picker global ----
   Movido desde Components/Admin/Compass/PropsEditor.razor.css (estaba scoped y NO aplicaba
   fuera de ese componente — p.ej. los <input type=color> de la barra Fondo del editor de
   diseño). Ahora global para que cualquier admin lo reuse. */
.rkxt-color-row {
    display: flex;
    align-items: center;
    gap: .5rem;
}
.rkxt-color-swatch {
    width: 44px;
    height: 38px;
    padding: 2px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    cursor: pointer;
}
.rkxt-color-hex {
    max-width: 140px;
}
.rkxt-color-hint {
    font-size: 0.78rem;
    color: var(--rkxt-text-muted);
}
/* Chip de vista previa del color elegido (feedback de legibilidad inmediato en el control "color"). */
.rkxt-color-demo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex: 0 0 auto;
    border-radius: var(--rkxt-radius-sm);
    border: 1px solid var(--rkxt-border);
    font: 600 11px/1 var(--rkxt-font-body);
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.45);
}
/* Badge "obligatorio" del PropsEditor (reemplaza el asterisco pegado, más legible). */
.rkxt-badge-req {
    display: inline-block;
    margin-left: .4rem;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--rkxt-bad-soft);
    color: var(--rkxt-bad);
    font: 600 .68rem/1.5 var(--rkxt-font-body);
    text-transform: lowercase;
    vertical-align: middle;
}
/* Subtítulo de una fila de repeater (primer texto no vacío del ítem, ej. título del slide). */
.rkxt-repeater-item-sub {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .8rem;
    color: var(--rkxt-text-muted);
}

/* Slider de ajuste numérico (brillo/contraste/saturación/oscurecimiento). GLOBAL porque lo
   reusan el control "ajusteImagen" del PropsEditor y la barra Fondo del editor de diseño
   (mismo motivo que .rkxt-color-row: el CSS isolation no cruza componentes). */
.rkxt-field-range {
    display: flex;
    flex-direction: column;
    gap: .15rem;
}
.rkxt-field-range .rkxt-field-label {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    font-size: .86rem;
    color: var(--rkxt-text);
}
.rkxt-field-range .rkxt-field-label em {
    font-style: normal;
    color: var(--rkxt-text-muted);
    font-variant-numeric: tabular-nums;
    font-size: .82rem;
}
.rkxt-range {
    width: 100%;
    accent-color: var(--rkxt-primary);
    height: 1.3rem;
    cursor: pointer;
}

/* Grupo compacto de sliders de ajuste en la barra Fondo del editor de diseño. */
.rkxt-diseno-fondo-ajustes {
    display: grid;
    grid-template-columns: repeat(2, minmax(120px, 1fr));
    gap: .4rem .8rem;
    flex-basis: 100%;
    margin-top: .4rem;
    padding-top: .5rem;
    border-top: 1px dashed var(--rkxt-border);
}
.rkxt-field-range-xs .rkxt-field-label { font-size: .8rem; }

/* Grilla de columnas DENTRO del editor (representación de la disposición). */
.rkxt-diseno-sec-cols {
    display: grid;
    gap: 12px;
    align-items: start;
}
.rkxt-diseno-sec-cols.cols-1 { grid-template-columns: 1fr; }
.rkxt-diseno-sec-cols.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rkxt-diseno-sec-cols.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rkxt-diseno-sec-cols.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.rkxt-diseno-sec-cols.cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }

@media (max-width: 900px) {
    .rkxt-diseno-sec-cols.cols-4,
    .rkxt-diseno-sec-cols.cols-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 520px) {
    .rkxt-diseno-sec-cols.cols-2,
    .rkxt-diseno-sec-cols.cols-3,
    .rkxt-diseno-sec-cols.cols-4,
    .rkxt-diseno-sec-cols.cols-5 { grid-template-columns: 1fr; }
}

/* Estructura (panel izquierdo): las columnas se muestran COMO COLUMNAS (lado a lado), cada una con su
   etiqueta "Columna N". En secciones angostas (3-5 col) el bloque de componente pasa a layout VERTICAL
   (título arriba, acciones abajo en 2 renglones) para que nada se encime y "Editar" siempre se vea. El
   PREVIEW de la derecha muestra la disposición horizontal real. */
.rkxt-diseno-colgroup {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.rkxt-diseno-col-lbl {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    color: var(--rkxt-text-dim);
    margin: 2px 0 5px 2px;
}

/* Fila superior del bloque (grip + ícono + título). En 1-2 columnas convive en línea con las acciones;
   en 3-5 columnas el bloque se apila (esta fila arriba, acciones abajo). */
.rkxt-diseno-block-main {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
}
.rkxt-diseno-sec-cols.cols-3 .rkxt-diseno-block,
.rkxt-diseno-sec-cols.cols-4 .rkxt-diseno-block,
.rkxt-diseno-sec-cols.cols-5 .rkxt-diseno-block {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
}
.rkxt-diseno-sec-cols.cols-3 .rkxt-diseno-block-main,
.rkxt-diseno-sec-cols.cols-4 .rkxt-diseno-block-main,
.rkxt-diseno-sec-cols.cols-5 .rkxt-diseno-block-main {
    flex: 0 0 auto;
}
/* Acciones en 2 renglones (↑ ↓ ⧉ arriba · Editar × abajo) cuando el bloque está apilado. */
.rkxt-diseno-sec-cols.cols-3 .rkxt-diseno-block-actions,
.rkxt-diseno-sec-cols.cols-4 .rkxt-diseno-block-actions,
.rkxt-diseno-sec-cols.cols-5 .rkxt-diseno-block-actions {
    justify-content: flex-start;
    gap: 4px;
    border-top: 1px solid var(--rkxt-border);
    padding-top: 6px;
}

/* Una columna/slot: zona soltable que apila sus componentes + el botón add. */
.rkxt-diseno-slot {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
    min-height: 96px;
    padding: 10px;
    background: var(--rkxt-bg-alt);
    border: 1px dashed var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
}

/* Botón "+ componente" tenue al pie del slot (dashed, full width). */
.rkxt-diseno-slot-add {
    margin-top: auto;
    width: 100%;
    background: transparent;
    border: 1px dashed var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    color: var(--rkxt-text-dim);
    padding: 8px 10px;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.12s, color 0.12s, background 0.12s;
}

.rkxt-diseno-slot-add:hover {
    border-color: var(--rkxt-primary);
    color: var(--rkxt-primary);
    background: var(--rkxt-primary-soft);
}

/* ---- Editor de popups (secciones en modo overlay) ----
   Bloque separado del de secciones de página de arriba: lo despegamos con margen + un borde
   superior y un título para que se lea como una zona distinta ("flotantes", no parte de la hoja). */
.rkxt-diseno-popups {
    margin-top: 32px;
    padding-top: 20px;
    border-top: 1px solid var(--rkxt-border);
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.rkxt-diseno-popups::before {
    content: "Popups (flotantes)";
    font-family: var(--rkxt-font-display);
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--rkxt-on-surface);
    letter-spacing: 0.01em;
}

/* Cada tarjeta de popup se diferencia de una sección normal con un acento secundario (ámbar)
   en el borde izquierdo — pista visual de que NO es una sección de la hoja sino un overlay. */
.rkxt-diseno-popup-edit {
    border-left: 3px solid var(--rkxt-secondary);
}

/* El badge del popup adopta el tono ámbar para reforzar la diferencia con el badge de layout
   de las secciones normales (que es primary/naranja). */
.rkxt-diseno-popup-edit .rkxt-diseno-sec-badge {
    background: color-mix(in srgb, var(--rkxt-secondary) 14%, transparent);
    color: color-mix(in srgb, var(--rkxt-secondary) 72%, var(--rkxt-on-surface));
    border-color: color-mix(in srgb, var(--rkxt-secondary) 28%, transparent);
}

/* El head del popup tiene muchos selects de comportamiento (disparador / valor / frecuencia /
   tamaño): que envuelvan prolijo en pantallas chicas. Hereda flex-wrap del .rkxt-diseno-sec-head;
   acá aseguramos que las acciones (Ocultar/Eliminar) no se peguen a los selects al envolver. */
.rkxt-diseno-popup-edit .rkxt-diseno-sec-head {
    row-gap: 10px;
}

/* ---- Split builder: estructura (izq) + preview en vivo (der) ---- */
/* El preview es un iframe del storefront REAL. Queda sticky dentro del scroll del
   .rkxt-admin-content mientras la estructura (que suele ser más larga) scrollea. */
.rkxt-diseno-split {
    display: grid;
    grid-template-columns: minmax(430px, 46%) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

.rkxt-diseno-estructura { min-width: 0; }

.rkxt-diseno-preview {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    height: calc(100vh - 170px);
    min-height: 420px;
}

.rkxt-diseno-preview-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.rkxt-diseno-preview-tit {
    font-family: var(--rkxt-font-display);
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--rkxt-on-surface);
    margin-right: auto;
}

.rkxt-diseno-preview-dev {
    display: flex;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    overflow: hidden;
}

.rkxt-diseno-preview-dev button {
    background: var(--rkxt-bg-alt);
    border: 0;
    padding: 4px 12px;
    font-size: 0.95rem;
    cursor: pointer;
    line-height: 1.4;
}

.rkxt-diseno-preview-dev button.is-active {
    background: color-mix(in srgb, var(--rkxt-primary) 14%, transparent);
}

.rkxt-diseno-preview-marco {
    flex: 1;
    min-height: 0;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: #fff;
    overflow: hidden;
    display: flex;
    justify-content: center;
}

.rkxt-diseno-preview-marco iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
    background: #fff;
}

/* Vista móvil: el marco angosta el iframe a 390px (el storefront responde al viewport del iframe). */
.rkxt-diseno-preview.is-mobile .rkxt-diseno-preview-marco {
    background: color-mix(in srgb, var(--rkxt-border) 30%, transparent);
}

.rkxt-diseno-preview.is-mobile .rkxt-diseno-preview-marco iframe {
    width: 390px;
    max-width: 100%;
    box-shadow: 0 0 0 1px var(--rkxt-border);
}

/* Pantallas angostas: estructura arriba, preview abajo con alto fijo (deja de ser sticky). */
@media (max-width: 1180px) {
    .rkxt-diseno-split { grid-template-columns: 1fr; }
    .rkxt-diseno-preview { position: static; height: 520px; }
}

/* Bloque Html en modo JS: iframe sandbox de ancho completo, alto auto vía postMessage. */
.rkxt-sf-html-frame {
    width: 100%;
    border: 0;
    display: block;
    min-height: 120px;
}

/* ---- Editor de pines (control pinsImagen del PropsEditor) ---- */
.rkxt-pins-editor { display: flex; flex-direction: column; gap: 8px; }

.rkxt-pins-marco {
    position: relative;
    line-height: 0;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    overflow: hidden;
}

.rkxt-pins-marco img {
    width: 100%;
    display: block;
    cursor: crosshair;
}

.rkxt-pins-dot {
    position: absolute;
    transform: translate(-50%, -50%);
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #EB5202;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    display: grid;
    place-items: center;
    box-shadow: 0 0 0 2px #fff, 0 2px 6px rgba(0, 0, 0, 0.3);
    pointer-events: none;
    line-height: 1;
}

.rkxt-pins-fila {
    display: flex;
    align-items: center;
    gap: 6px;
}

.rkxt-pins-fila select { flex: 1; min-width: 0; }
.rkxt-pins-fila input[type="text"] { width: 120px; }
.rkxt-pins-coord { width: 4.6rem; }

/* ---- Shop The Look (lookbook con pines, estilo kosiuko.com) ---- */
.rkxt-sf-lookbook h2 {
    font-family: var(--rkxt-font-display);
    margin: 0 0 14px;
}

.rkxt-sf-lookbook-marco {
    position: relative;
    overflow: hidden;
    line-height: 0;
}

.rkxt-sf-lookbook-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rkxt-sf-lookbook-velo {
    position: absolute;
    inset: 0;
    background: #000;
    pointer-events: none;
}

.rkxt-sf-lookbook-pin {
    position: absolute;
    transform: translate(-50%, -50%);
    width: 30px;
    height: 30px;
    border: 0;
    background: transparent;
    cursor: pointer;
    display: grid;
    place-items: center;
    z-index: 2;
}

.rkxt-sf-lookbook-pin-punto {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.35);
    transition: transform 0.18s ease;
    animation: rkxt-lb-pulso 2.4s ease-in-out infinite;
}

.rkxt-sf-lookbook-pin:hover .rkxt-sf-lookbook-pin-punto,
.rkxt-sf-lookbook-pin.is-active .rkxt-sf-lookbook-pin-punto {
    transform: scale(1.35);
    animation: none;
}

@keyframes rkxt-lb-pulso {
    0%, 100% { box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.35); }
    50% { box-shadow: 0 0 0 9px rgba(255, 255, 255, 0.18), 0 2px 8px rgba(0, 0, 0, 0.35); }
}

.rkxt-sf-lookbook-card {
    position: absolute;
    transform: translate(-50%, 16px);
    width: 216px;
    max-width: 78vw;
    background: #fff;
    color: #111;
    border-radius: 8px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
    display: flex;
    gap: 10px;
    padding: 8px;
    line-height: 1.3;
    text-decoration: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease, transform 0.18s ease;
    z-index: 3;
}

.rkxt-sf-lookbook-card.is-open {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 10px);
}

/* Pin en la franja baja de la imagen: la card abre hacia ARRIBA para no cortarse. */
.rkxt-sf-lookbook-card.is-arriba { transform: translate(-50%, calc(-100% - 16px)); }
.rkxt-sf-lookbook-card.is-arriba.is-open { transform: translate(-50%, calc(-100% - 10px)); }

.rkxt-sf-lookbook-card-img {
    width: 58px;
    height: 74px;
    flex-shrink: 0;
    border-radius: 6px;
    background-color: #f4f2ee;
    background-size: var(--rkxt-fit-bg, cover);
    background-position: center;
}

.rkxt-sf-lookbook-card-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    justify-content: center;
    min-width: 0;
}

.rkxt-sf-lookbook-card-info strong {
    font-size: 0.82rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rkxt-sf-lookbook-card-precio { font-size: 0.85rem; }

/* ---- Biblioteca de medios (modal reuso de blobs) ---- */
.rkxt-media-modal { max-width: 820px; width: min(92vw, 820px); }

.rkxt-media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 10px;
    max-height: min(56vh, 540px);
    overflow-y: auto;
    padding: 2px;
}

.rkxt-media-item {
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 0 0 6px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 5px;
    overflow: hidden;
    transition: border-color 0.12s, transform 0.12s;
}

.rkxt-media-item:hover { border-color: var(--rkxt-primary); transform: translateY(-1px); }

.rkxt-media-item img,
.rkxt-media-item video {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    background: #fff;
}

.rkxt-media-item small {
    font-size: 0.7rem;
    color: var(--rkxt-text-muted);
    padding: 0 8px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- Panel lateral de propiedades (editor de diseño, reemplaza al modal) ---- */
.rkxt-props-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(460px, 92vw);
    background: var(--rkxt-surface, var(--rkxt-bg));
    border-left: 1px solid var(--rkxt-border);
    box-shadow: -12px 0 32px rgba(0, 0, 0, 0.14);
    z-index: 900;   /* debajo de los modales (backdrop 1000), arriba del contenido admin */
    display: flex;
    flex-direction: column;
}

.rkxt-props-panel-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--rkxt-border);
}

.rkxt-props-panel-head strong {
    font-family: var(--rkxt-font-display);
    font-size: 1rem;
}

.rkxt-props-panel-head small { margin-right: auto; }

.rkxt-props-panel-body {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
}

/* Acordeones de grupos de props (PropDefinition.Group). */
.rkxt-props-group {
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    margin: 10px 0;
    padding: 0 12px 4px;
}

.rkxt-props-group > summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 0.88rem;
    padding: 9px 0;
    color: var(--rkxt-text);
    user-select: none;
}

/* ---- Drag & drop del editor de diseño (grip + estados) ---- */
.rkxt-diseno-grip {
    cursor: grab;
    color: var(--rkxt-text-muted);
    font-size: 0.95rem;
    line-height: 1;
    padding: 2px 4px;
    border-radius: 4px;
    user-select: none;
    flex-shrink: 0;
}

.rkxt-diseno-grip:hover {
    color: var(--rkxt-text);
    background: color-mix(in srgb, var(--rkxt-border) 45%, transparent);
}

.rkxt-diseno-grip:active { cursor: grabbing; }

.rkxt-diseno-sec.is-dragging,
.rkxt-diseno-block.is-dragging,
.rkxt-repeater-item.is-dragging { opacity: 0.45; }

.rkxt-diseno-sec.is-over,
.rkxt-diseno-block.is-over,
.rkxt-repeater-item.is-over {
    outline: 2px dashed var(--rkxt-primary);
    outline-offset: -2px;
}

.rkxt-diseno-slot.is-over {
    outline: 2px dashed var(--rkxt-primary);
    outline-offset: -2px;
    background: color-mix(in srgb, var(--rkxt-primary) 6%, transparent);
}

/* Mini-sketch en las filas de componentes colocados (reemplaza el emoji genérico). */
.rkxt-diseno-block-sketch svg {
    width: 46px;
    height: auto;
    display: block;
    background: #fff;
    border: 1px solid var(--rkxt-border);
    border-radius: 4px;
}

/* ---- Galería de componentes (modal "agregar componente" tipo Wix) ---- */
.rkxt-galc-modal { max-width: 860px; width: min(92vw, 860px); }

.rkxt-galc-toolbar {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 14px;
}

.rkxt-galc-buscar { max-width: 340px; }

.rkxt-galc-cats {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.rkxt-galc-cat {
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: 999px;
    padding: 3px 12px;
    font-size: 0.82rem;
    color: var(--rkxt-text-muted);
    cursor: pointer;
    transition: border-color 0.12s, color 0.12s, background 0.12s;
}

.rkxt-galc-cat:hover { color: var(--rkxt-text); border-color: var(--rkxt-primary); }

.rkxt-galc-cat.is-active {
    background: color-mix(in srgb, var(--rkxt-primary) 12%, transparent);
    border-color: var(--rkxt-primary);
    color: color-mix(in srgb, var(--rkxt-primary) 80%, var(--rkxt-text));
    font-weight: 600;
}

.rkxt-galc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 12px;
    max-height: min(56vh, 560px);
    overflow-y: auto;
    padding: 2px;
}

.rkxt-galc-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-bg-alt);
    overflow: hidden;
    transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
}

.rkxt-galc-card:hover {
    border-color: var(--rkxt-primary);
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}

.rkxt-galc-card-main {
    background: none;
    border: 0;
    padding: 0 0 8px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-align: center;
    font: inherit;
    color: inherit;
}

.rkxt-galc-thumb {
    display: block;
    aspect-ratio: 100 / 64;
    background: #fff;
    border-bottom: 1px solid var(--rkxt-border);
}

.rkxt-galc-thumb svg,
.rkxt-galc-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rkxt-galc-card-main strong {
    font-size: 0.9rem;
    color: var(--rkxt-text);
    padding: 0 10px;
}

.rkxt-galc-card-main small {
    font-size: 0.74rem;
    line-height: 1.35;
    color: var(--rkxt-text-muted);
    padding: 0 10px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rkxt-galc-card-foot {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 6px 10px 9px;
    font-size: 0.78rem;
    margin-top: auto;
}

.rkxt-galc-lbl-ok { color: var(--rkxt-ok, #1a7f37); font-weight: 600; }

.rkxt-galc-lbl-inst {
    color: color-mix(in srgb, var(--rkxt-primary) 85%, var(--rkxt-text));
    font-weight: 600;
}

/* Los no instalados se distinguen con un velo suave hasta el hover (invita a "estrenarlos"). */
.rkxt-galc-card.is-noinstalado .rkxt-galc-thumb { opacity: 0.75; }
.rkxt-galc-card.is-noinstalado:hover .rkxt-galc-thumb { opacity: 1; }

/* ---- Selector de layout en el modal "Agregar sección" ---- */
.rkxt-diseno-layouts {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
}

.rkxt-diseno-layout-card {
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 16px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: center;
    transition: border-color 0.12s, transform 0.12s;
}

.rkxt-diseno-layout-card:hover {
    border-color: var(--rkxt-primary);
    transform: translateY(-1px);
}

.rkxt-diseno-layout-card strong { font-size: 0.9rem; color: var(--rkxt-text); }

/* Mini-preview del layout: 1-3 <i> que ilustran las columnas. */
.rkxt-diseno-layout-mini {
    display: flex;
    gap: 5px;
    width: 100%;
    height: 38px;
    justify-content: center;
    align-items: stretch;
}

.rkxt-diseno-layout-mini i {
    display: block;
    flex: 1;
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-radius: 4px;
}

/* "Centrado": una caja angosta centrada. */
.rkxt-diseno-layout-mini i.c {
    flex: 0 0 52%;
}

/* Editor de props */
.rkxt-bloque-editor {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.rkxt-checkbox-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 6px;
    max-height: 260px;
    overflow-y: auto;
    padding: 8px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-bg-alt);
}

.rkxt-checkbox-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 3px;
    cursor: pointer;
    font-size: 0.88rem;
}

.rkxt-checkbox-item:hover { background: var(--rkxt-surface); }

.rkxt-file-input {
    padding: 6px 8px;
    font-size: 13px;
}

/* ============ Dashboard widgets configurables (Bloque 8) ============ */

.rkxt-dash-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 16px;
    flex-wrap: wrap;
}

.rkxt-dash-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.rkxt-dash-period {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    color: var(--rkxt-text-dim);
}

.rkxt-dash-period select {
    padding: 6px 10px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    color: var(--rkxt-text);
    font-size: 0.85rem;
}

.rkxt-dash-loading {
    padding: 60px 24px;
    text-align: center;
    color: var(--rkxt-text-dim);
}

/* Grid responsive: 4 columnas en desktop, ajustable. Cada card declara su ancho con .rkxt-w-w{1,2,3}. */
.rkxt-dash-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin-top: 16px;
}

@media (max-width: 1100px) {
    .rkxt-dash-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .rkxt-w-w3 { grid-column: span 2 !important; }
}

@media (max-width: 600px) {
    .rkxt-dash-grid { grid-template-columns: 1fr; }
    .rkxt-w-w1, .rkxt-w-w2, .rkxt-w-w3 { grid-column: span 1 !important; }
}

.rkxt-w-w1 { grid-column: span 1; }
.rkxt-w-w2 { grid-column: span 2; }
.rkxt-w-w3 { grid-column: span 3; }
.rkxt-w-h1 { min-height: 140px; }
.rkxt-w-h2 { min-height: 280px; }

/* ===================== Panel comercial mayorista (/admin, Inicio.razor) ===================== */
/* KPIs con drill-down 360: cada card es un <a> que navega al sector (estilo DigitalOne). */
.rkxt-kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin-top: 18px;
}
@media (max-width: 1100px) { .rkxt-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .rkxt-kpi-grid { grid-template-columns: 1fr; } }

.rkxt-kpi-card {
    display: block;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-left: 4px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 16px 18px 18px;
    text-decoration: none;
    color: inherit;
    transition: box-shadow 130ms ease, transform 130ms ease, border-color 130ms ease;
}
.rkxt-kpi-card:hover {
    box-shadow: 0 8px 22px rgba(0,0,0,0.10);
    transform: translateY(-2px);
    border-left-color: var(--rkxt-primary, #EB5202);
}
.rkxt-kpi-accent { border-left-color: var(--rkxt-primary, #EB5202); }
.rkxt-kpi-oportunidad { border-left-color: #2e9e6b; }
.rkxt-kpi-oportunidad:hover { border-left-color: #2e9e6b; }

.rkxt-kpi-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    min-height: 26px;
    margin-bottom: 6px;
}
.rkxt-kpi-ico { font-size: 1.15rem; }
.rkxt-kpi-badge {
    font-size: 0.7rem;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
}
.rkxt-kpi-badge-warn { background: #fdecec; color: #c0392b; }
.rkxt-kpi-badge-op   { background: #e7f6ee; color: #1e7d51; }

.rkxt-kpi-valor {
    font-size: 2.1rem;
    font-weight: 800;
    line-height: 1.05;
    color: var(--rkxt-text);
    font-variant-numeric: tabular-nums;
}
.rkxt-kpi-unidad { font-size: 1rem; font-weight: 600; color: var(--rkxt-text-dim); }
.rkxt-kpi-label { font-size: 0.92rem; font-weight: 600; margin-top: 4px; color: var(--rkxt-text); }
.rkxt-kpi-sub   { font-size: 0.78rem; color: var(--rkxt-text-dim); margin-top: 2px; }

/* Rankings: dos paneles con canvas Chart.js (estilo GHApp). */
.rkxt-dash-charts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-top: 18px;
}
@media (max-width: 900px) { .rkxt-dash-charts { grid-template-columns: 1fr; } }

.rkxt-dash-chart-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 8px;
}
.rkxt-dash-chart-wrap { position: relative; height: 320px; }

/* ===== Detalle del pedido — cabecera sticky compacta + listas a 2 columnas ===== */
/* Sticky: rompe el padding del .rkxt-admin-content (28px 36px) con márgenes negativos
   para cubrir todo el ancho y no dejar hueco arriba al scrollear. */
.rkxt-ped-sticky {
    position: sticky;
    /* el .rkxt-admin-content tiene padding-top:28px; con top:-28 + padding-top:28 el header queda
       AL RAS del borde superior del scroll (sin gap por el que se asome el contenido). */
    top: -28px;
    z-index: 30;
    background: var(--rkxt-bg);
    margin: -28px -36px 14px;
    padding: 28px 36px 10px;
    border-bottom: 1px solid var(--rkxt-border);
}
.rkxt-ped-hdr-top { display: flex; align-items: flex-start; gap: 18px; }
.rkxt-ped-hdr-id { display: flex; flex-direction: column; flex: 0 0 auto; }
.rkxt-ped-hdr-num { font-size: 1.15rem; font-weight: 700; line-height: 1.2; }
.rkxt-ped-hdr-tipo { font-size: .7rem; color: var(--rkxt-text-dim); text-transform: uppercase; letter-spacing: .4px; }
.rkxt-ped-hdr-cli { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.rkxt-ped-hdr-cli-nombre { font-size: 1.15rem; font-weight: 700; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rkxt-ped-hdr-cli-cod { font-size: .74rem; color: var(--rkxt-text-dim); align-self: flex-end; margin-top: 1px; }
.rkxt-ped-hdr-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; font-size: .76rem; color: var(--rkxt-text-dim); white-space: nowrap; flex: 0 0 auto; }
.rkxt-ped-sticky .rkxt-dash-toolbar { margin: 8px 0 0; }
.rkxt-ped-sticky .rkxt-flash { margin: 8px 0 0; }

/* Listas "más pedido" / "no pidió" — 2 columnas con alto fijo (~10 renglones) + scroll. */
.rkxt-dash-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 10px; }
@media (max-width: 700px) { .rkxt-dash-2col { grid-template-columns: 1fr; } }
.rkxt-dash-scrolllist { max-height: 280px; overflow-y: auto; margin: 4px 0 0; padding-right: 6px; }

.rkxt-dash-card {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    position: relative;
    transition: box-shadow 120ms ease, transform 120ms ease;
}

.rkxt-dash-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
}

.rkxt-dash-card-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 8px;
    margin-bottom: 12px;
}

.rkxt-dash-card-titles h3 {
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--rkxt-text-dim);
    margin: 0 0 2px 0;
}

.rkxt-dash-card-meta {
    font-size: 0.7rem;
    color: var(--rkxt-text-dim);
    text-transform: lowercase;
}

.rkxt-dash-card-period {
    background: transparent;
    border: 1px solid transparent;
    color: var(--rkxt-text-dim);
    border-radius: 4px;
    width: 26px; height: 26px;
    line-height: 0;
    font-size: 1.1rem;
    cursor: pointer;
}

.rkxt-dash-card-period:hover {
    background: var(--rkxt-bg-alt);
    border-color: var(--rkxt-border);
}

.rkxt-dash-card-period-menu {
    position: absolute;
    top: 38px;
    right: 14px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    box-shadow: 0 8px 24px rgba(0,0,0,0.08);
    display: flex;
    flex-direction: column;
    z-index: 5;
    min-width: 160px;
    overflow: hidden;
}

.rkxt-dash-card-period-opt {
    background: transparent;
    border: none;
    padding: 8px 12px;
    text-align: left;
    font-size: 0.85rem;
    color: var(--rkxt-text);
    cursor: pointer;
}

.rkxt-dash-card-period-opt:hover { background: var(--rkxt-bg-alt); }
.rkxt-dash-card-period-opt.is-active { background: var(--rkxt-primary); color: #fff; }

.rkxt-dash-card-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 60px;
}

.rkxt-dash-card-foot {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
}

.rkxt-dash-card-action {
    color: var(--rkxt-primary);
    font-size: 0.85rem;
    text-decoration: none;
    font-weight: 600;
}

.rkxt-dash-card-action:hover { text-decoration: underline; }

.rkxt-dash-card-error {
    color: #b91c1c;
    font-size: 0.85rem;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.rkxt-dash-cifra {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.rkxt-dash-cifra-valor {
    font-size: 1.9rem;
    font-weight: 700;
    color: var(--rkxt-text);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.rkxt-dash-cifra-sub {
    font-size: 0.82rem;
    color: var(--rkxt-text-dim);
}

.rkxt-dash-cambio {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    font-weight: 600;
    margin-top: 4px;
}

.rkxt-dash-cambio.is-up { color: #16a34a; }
.rkxt-dash-cambio.is-down { color: #dc2626; }
.rkxt-dash-cambio-lbl { color: var(--rkxt-text-dim); font-weight: 400; }

.rkxt-dash-spark {
    width: 100%;
    height: 60px;
    margin-top: 10px;
    display: block;
}

.rkxt-dash-funnel {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.rkxt-dash-funnel-etapa {
    width: 100%;
}

.rkxt-dash-funnel-bar {
    background: var(--rkxt-primary);
    color: #fff;
    padding: 8px 12px;
    border-radius: var(--rkxt-radius-sm);
    display: flex;
    justify-content: space-between;
    align-items: center;
    min-width: 80px;
    transition: width 240ms ease;
    font-size: 0.85rem;
}

.rkxt-dash-funnel-bar:nth-child(odd) { opacity: 0.92; }
.rkxt-dash-funnel-lbl { font-weight: 600; }
.rkxt-dash-funnel-val { font-variant-numeric: tabular-nums; }

.rkxt-dash-top {
    list-style: none;
    padding: 0;
    margin: 0;
    counter-reset: rkxt-top;
}

.rkxt-dash-top li {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0;
    border-bottom: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
    counter-increment: rkxt-top;
    gap: 12px;
}

.rkxt-dash-top li:last-child { border-bottom: none; }

.rkxt-dash-top li::before {
    content: counter(rkxt-top);
    color: var(--rkxt-text-dim);
    font-size: 0.75rem;
    font-weight: 700;
    min-width: 18px;
}

.rkxt-dash-top-lbl {
    flex: 1;
    color: var(--rkxt-text);
    font-size: 0.88rem;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

a.rkxt-dash-top-lbl:hover { color: var(--rkxt-primary); text-decoration: underline; }

.rkxt-dash-top-val {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--rkxt-text);
}

.rkxt-dash-empty {
    color: var(--rkxt-text-dim);
    font-size: 0.85rem;
    text-align: center;
    padding: 20px 12px;
}

.rkxt-dash-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.rkxt-dash-table th, .rkxt-dash-table td {
    padding: 6px 8px;
    text-align: left;
    border-bottom: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
}

.rkxt-dash-table th {
    color: var(--rkxt-text-dim);
    font-weight: 600;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.rkxt-dash-table tbody tr:hover { background: var(--rkxt-bg-alt); }
.rkxt-dash-table a { color: var(--rkxt-primary); text-decoration: none; }

/* ============ Skeleton shimmer ============ */
.rkxt-skeleton {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0;
}

.rkxt-skeleton-bar {
    background: linear-gradient(90deg,
        var(--rkxt-bg-alt) 0%,
        var(--rkxt-border-soft, var(--rkxt-border)) 50%,
        var(--rkxt-bg-alt) 100%);
    background-size: 200% 100%;
    animation: rkxt-shimmer 1.4s infinite ease-in-out;
    border-radius: 4px;
    height: 14px;
}

.rkxt-skeleton-bar-l { width: 60%; height: 28px; }
.rkxt-skeleton-bar-s { width: 90%; height: 12px; }

@keyframes rkxt-shimmer {
    0% { background-position: 200% 50%; }
    100% { background-position: -200% 50%; }
}

/* ============ Empty state genérico ============ */
.rkxt-empty-state {
    background: var(--rkxt-surface);
    border: 1px dashed var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 40px 24px;
    text-align: center;
    max-width: 560px;
    margin: 32px auto;
}

.rkxt-empty-state h2 {
    font-size: 1.2rem;
    margin: 0 0 8px 0;
}

.rkxt-empty-state p {
    color: var(--rkxt-text-dim);
    margin: 0 0 16px 0;
}

/* ============ Modal personalizar dashboard ============ */
.rkxt-modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex; align-items: center; justify-content: center;
    z-index: 1000;
    padding: 24px;
    overflow-y: auto;
}

.rkxt-modal {
    background: var(--rkxt-surface);
    border-radius: var(--rkxt-radius);
    border: 1px solid var(--rkxt-border);
    width: 100%;
    max-width: 720px;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 48px);
}

.rkxt-modal-lg { max-width: 900px; }

.rkxt-modal-head {
    padding: 18px 22px;
    border-bottom: 1px solid var(--rkxt-border);
    display: flex; justify-content: space-between; align-items: center;
}

.rkxt-modal-head h2 { margin: 0; font-size: 1.05rem; }

.rkxt-modal-close {
    background: transparent;
    border: none;
    font-size: 1.6rem;
    cursor: pointer;
    color: var(--rkxt-text-dim);
    line-height: 1;
}

.rkxt-modal-body {
    padding: 18px 22px;
    overflow-y: auto;
    flex: 1;
}

.rkxt-modal-foot {
    padding: 14px 22px;
    border-top: 1px solid var(--rkxt-border);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    align-items: center;
}

.rkxt-personalizar-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.rkxt-personalizar-toolbar input[type=search] {
    padding: 6px 10px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    min-width: 220px;
}

.rkxt-personalizar-cat {
    margin-bottom: 22px;
}

.rkxt-personalizar-cat h3 {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--rkxt-text-dim);
    margin: 0 0 10px 0;
    border-bottom: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
    padding-bottom: 6px;
}

.rkxt-personalizar-lista {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.rkxt-personalizar-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
}

.rkxt-personalizar-item.is-on {
    border-color: var(--rkxt-primary);
    background: rgba(235, 82, 2, 0.04);
}

.rkxt-personalizar-check {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex: 1;
    cursor: pointer;
}

.rkxt-personalizar-check input { margin-top: 4px; }
.rkxt-personalizar-check strong { display: block; font-size: 0.92rem; }
.rkxt-personalizar-check small { display: block; font-size: 0.78rem; color: var(--rkxt-text-dim); }

.rkxt-personalizar-acciones {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-wrap: wrap;
}

.rkxt-personalizar-acciones select {
    padding: 4px 6px;
    font-size: 0.78rem;
    border: 1px solid var(--rkxt-border);
    border-radius: 4px;
}

.rkxt-defaults-toolbar {
    display: flex; align-items: center; gap: 16px; margin: 16px 0;
}

.rkxt-defaults-toolbar select {
    padding: 6px 10px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    font-size: 0.9rem;
}

.rkxt-defaults-foot {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--rkxt-border);
    display: flex;
    justify-content: flex-end;
}

.rkxt-btn-xs {
    padding: 2px 6px;
    font-size: 0.75rem;
    border-radius: 3px;
}

.rkxt-text-dim { color: var(--rkxt-text-dim); font-size: 0.78rem; }

/* ============ WhatsApp split (pais + región + número) ============ */
.rkxt-field-wa {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 16px;
}

.rkxt-wa-row {
    display: grid;
    grid-template-columns: minmax(180px, 1.6fr) 90px 1fr;
    gap: 8px;
}

@media (max-width: 560px) {
    .rkxt-wa-row { grid-template-columns: 1fr; }
}

.rkxt-wa-pais, .rkxt-wa-region, .rkxt-wa-numero {
    min-width: 0;
}

.rkxt-wa-region, .rkxt-wa-numero {
    font-variant-numeric: tabular-nums;
}

/* ============ Editor de imágenes (galería con upload) ============ */
.rkxt-imgeditor {
    margin-top: 28px;
    padding-top: 20px;
    border-top: 1px solid var(--rkxt-border);
}

.rkxt-imgeditor-head h3 {
    margin: 0 0 4px 0;
    font-size: 1.05rem;
}

.rkxt-imgeditor-controls {
    display: flex;
    gap: 12px;
    align-items: center;
    margin: 14px 0;
    flex-wrap: wrap;
}

.rkxt-imgeditor-upload {
    position: relative;
    display: inline-block;
}

.rkxt-imgeditor-upload input[type=file] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.rkxt-imgeditor-url {
    display: flex;
    gap: 8px;
    flex: 1;
    min-width: 280px;
    align-items: center;
}

.rkxt-imgeditor-url input {
    flex: 1;
}

.rkxt-imgeditor-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 14px;
    margin-top: 16px;
}

.rkxt-imgeditor-item {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.rkxt-imgeditor-item.is-principal {
    border-color: var(--rkxt-primary);
    box-shadow: 0 0 0 1px var(--rkxt-primary);
}

.rkxt-imgeditor-thumb {
    position: relative;
    aspect-ratio: 1 / 1;
    background: var(--rkxt-bg-alt);
    border-radius: 4px;
    overflow: hidden;
}

.rkxt-imgeditor-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rkxt-imgeditor-badge {
    position: absolute;
    top: 6px; left: 6px;
    background: var(--rkxt-primary);
    color: #fff;
    font-size: 0.7rem;
    padding: 2px 6px;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

.rkxt-input-sm {
    font-size: 0.82rem;
    padding: 4px 8px;
}

.rkxt-imgeditor-actions {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

.rkxt-imgeditor-actions button { flex: 0 0 auto; }

.rkxt-imgeditor-foot {
    margin-top: 14px;
}

.rkxt-flash-warning {
    background: #fef3c7;
    border: 1px solid #fde68a;
    color: #92400e;
    padding: 10px 14px;
    border-radius: var(--rkxt-radius-sm);
}

.rkxt-flash-success {
    background: #d1fae5;
    border: 1px solid #6ee7b7;
    color: #065f46;
    padding: 10px 14px;
    border-radius: var(--rkxt-radius-sm);
}

/* Banner informativo neutro/azul — mismo padding/radio que -success/-warning/-error.
   Tono celeste sobrio (no compite con el naranja de marca), legible sobre fondo light. */
.rkxt-flash-info {
    background: #e0f2fe;
    border: 1px solid #7dd3fc;
    color: #075985;
    padding: 10px 14px;
    border-radius: var(--rkxt-radius-sm);
}

/* ============ Badges genericos para listas (estado, tipo, etc.) ============ */
.rkxt-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 12px;
    background: var(--rkxt-bg-alt);
    color: var(--rkxt-text);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border: 1px solid var(--rkxt-border);
}

.rkxt-badge-success {
    background: #d1fae5;
    color: #065f46;
    border-color: #6ee7b7;
}

.rkxt-badge-warning {
    background: #fef3c7;
    color: #92400e;
    border-color: #fde68a;
}

.rkxt-badge-error {
    background: #fee2e2;
    color: #991b1b;
    border-color: #fecaca;
}

.rkxt-badge-info {
    background: var(--rkxt-primary-soft);
    color: var(--rkxt-primary);
    border-color: color-mix(in srgb, var(--rkxt-primary) 35%, transparent);
}

/* Barra de filtros (search + checks) sobre listados admin. */
.rkxt-admin-filtros {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: flex-end;
    margin: 0 0 1rem;
}
/* Los .rkxt-field dentro de la barra de filtros no necesitan su margin-bottom default
   (todos comparten la misma fila, alineados por align-items:flex-end del contenedor). */
.rkxt-admin-filtros .rkxt-field { margin: 0; }

.rkxt-table-actions {
    text-align: right;
    white-space: nowrap;
}

/* Columna angosta de checkbox de selección en tablas con bulk-select. */
.rkxt-table-check-col { width: 36px; }

/* ============ Selector de fuente de imágenes en el importador ============ */
.rkxt-import-imgsrc {
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 16px 20px;
    margin: 16px 0;
    background: var(--rkxt-surface);
}

.rkxt-import-imgsrc legend {
    padding: 0 8px;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--rkxt-text-dim);
}

.rkxt-import-imgopt {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 0;
    cursor: pointer;
}

.rkxt-import-imgopt input[type="radio"] {
    margin-top: 4px;
    flex-shrink: 0;
}

.rkxt-import-imgopt > span {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
}

.rkxt-import-imgopt small {
    font-size: 0.82rem;
    color: var(--rkxt-text-dim);
}

.rkxt-import-imgopt-detail {
    margin-left: 26px;
    padding: 12px 14px;
    background: var(--rkxt-bg-alt);
    border-radius: var(--rkxt-radius-sm);
    margin-bottom: 8px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

@media (max-width: 600px) {
    .rkxt-import-imgopt-detail { grid-template-columns: 1fr; }
}

/* ============ Card "Acceso a la tienda" en Edit de Tienda ============ */
.rkxt-tienda-acceso {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-left: 4px solid var(--rkxt-primary);
    border-radius: var(--rkxt-radius);
    margin: 0 0 28px 0;
    overflow: hidden;
}

.rkxt-tienda-acceso-head {
    padding: 14px 20px;
    border-bottom: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
}

.rkxt-tienda-acceso-head h2 {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: var(--rkxt-text);
}

.rkxt-tienda-acceso-body {
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.rkxt-tienda-acceso-url .rkxt-field-label,
.rkxt-tienda-acceso-dominio .rkxt-field-label {
    display: block;
    margin-bottom: 8px;
}

.rkxt-url-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.rkxt-url-input {
    flex: 1 1 280px;
    padding: 8px 12px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-bg-alt);
    font-family: monospace;
    font-size: 0.88rem;
    color: var(--rkxt-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rkxt-btn-sm {
    padding: 6px 12px;
    font-size: 0.82rem;
    border-radius: var(--rkxt-radius-sm);
}

.rkxt-tienda-dominio-estado {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    border-radius: var(--rkxt-radius-sm);
    gap: 12px;
    flex-wrap: wrap;
}

.rkxt-tienda-dominio-estado code {
    font-family: monospace;
    color: var(--rkxt-primary);
}

.rkxt-tienda-dominio-vacio {
    background: var(--rkxt-bg-alt);
    border: 1px dashed var(--rkxt-border);
    color: var(--rkxt-text-dim);
}

.rkxt-tienda-dominio-pendiente {
    background: #fef3c7;
    border: 1px solid #fde68a;
    color: #92400e;
}

.rkxt-tienda-dominio-activo {
    background: #d1fae5;
    border: 1px solid #6ee7b7;
    color: #065f46;
}

/* Link "Ir a tienda" en sidebar admin */
.rkxt-admin-link-gotostore {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
}

/* ============ Stepper horizontal (wizard de dominio) ============ */
.rkxt-stepper {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 24px 0 32px 0;
    counter-reset: rkxt-step;
    gap: 8px;
}

.rkxt-stepper li {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 12px;
    border-bottom: 3px solid var(--rkxt-border);
    color: var(--rkxt-text-dim);
    text-align: center;
}

.rkxt-stepper li.is-done {
    border-bottom-color: var(--rkxt-primary);
    color: var(--rkxt-text);
}

.rkxt-stepper li.is-current {
    border-bottom-color: var(--rkxt-primary);
    color: var(--rkxt-primary);
    font-weight: 600;
}

.rkxt-stepper-num {
    width: 32px;
    height: 32px;
    line-height: 32px;
    border-radius: 50%;
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    margin-bottom: 6px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.rkxt-stepper li.is-done .rkxt-stepper-num,
.rkxt-stepper li.is-current .rkxt-stepper-num {
    background: var(--rkxt-primary);
    border-color: var(--rkxt-primary);
    color: #fff;
}

.rkxt-stepper-label {
    font-size: 0.85rem;
}

@media (max-width: 600px) {
    .rkxt-stepper-label { display: none; }
}

/* Panel de cada paso */
.rkxt-step-panel {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 24px 28px;
    margin-bottom: 24px;
}

.rkxt-step-panel h2 {
    margin: 0 0 10px 0;
    font-size: 1.1rem;
}

.rkxt-step-panel h3 { font-size: 0.95rem; margin: 24px 0 10px 0; }

.rkxt-dns-record-title {
    color: var(--rkxt-primary);
    margin-top: 24px;
}

.rkxt-dns-table {
    width: 100%;
    max-width: 700px;
    border-collapse: collapse;
    margin: 8px 0 16px 0;
    border: 1px solid var(--rkxt-border);
}

.rkxt-dns-table th, .rkxt-dns-table td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
    text-align: left;
    vertical-align: top;
}

.rkxt-dns-table th {
    background: var(--rkxt-bg-alt);
    width: 160px;
    font-weight: 600;
    color: var(--rkxt-text-dim);
    font-size: 0.85rem;
}

.rkxt-dns-table code {
    font-family: monospace;
    color: var(--rkxt-text);
    background: var(--rkxt-bg-alt);
    padding: 2px 6px;
    border-radius: 3px;
}

.rkxt-dns-warning {
    background: #fef3c7;
    border: 1px solid #fde68a;
    color: #92400e;
    padding: 12px 14px;
    border-radius: var(--rkxt-radius-sm);
    margin: 16px 0;
}

.rkxt-dns-check {
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 14px 18px;
    margin-top: 14px;
}

.rkxt-dns-check-row {
    padding: 4px 0;
    font-size: 0.92rem;
}

.rkxt-dns-check-row.ok { color: #065f46; }
.rkxt-dns-check-row.fail { color: #991b1b; }

/* ============ ArticuloPicker (typeahead Interactive) ============ */
.rkxt-picker {
    position: relative;
    width: 100%;
}

.rkxt-picker-input { width: 100%; }

.rkxt-picker-chip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--rkxt-primary);
    border-radius: var(--rkxt-radius-sm);
    background: rgba(235, 82, 2, 0.04);
}

.rkxt-picker-chip-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.rkxt-picker-chip-text strong {
    font-family: monospace;
    font-size: 0.85rem;
    color: var(--rkxt-primary);
}

.rkxt-picker-chip-text span {
    font-size: 0.88rem;
    color: var(--rkxt-text);
}

.rkxt-picker-clear {
    background: transparent;
    border: none;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    color: var(--rkxt-text-dim);
    padding: 0 4px;
}

.rkxt-picker-clear:hover { color: var(--rkxt-primary); }

.rkxt-picker-list {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
    max-height: 320px;
    overflow-y: auto;
    z-index: 20;
}

.rkxt-picker-item {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--rkxt-border-soft, var(--rkxt-border));
    padding: 8px 12px;
    cursor: pointer;
    color: var(--rkxt-text);
    font-size: 0.88rem;
}

.rkxt-picker-item:last-child { border-bottom: none; }
.rkxt-picker-item:hover { background: var(--rkxt-bg-alt); }

.rkxt-picker-item strong {
    display: inline-block;
    font-family: monospace;
    color: var(--rkxt-primary);
    margin-right: 8px;
}

.rkxt-picker-item span {
    color: var(--rkxt-text);
}

.rkxt-picker-item small {
    display: inline-block;
    margin-left: 8px;
    color: var(--rkxt-text-dim);
    font-size: 0.76rem;
}

.rkxt-picker-empty {
    color: var(--rkxt-text-dim);
    cursor: default;
    font-style: italic;
}

.rkxt-picker-empty:hover { background: transparent; }

/* ==========================================================================
   Quick-create inline (botón "+ Nueva" en label + <dialog>)
   Patrón reutilizable: agregar entidades catálogo sin perder el form padre.
   ========================================================================== */
.rkxt-field-action {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 8px;
    padding: 2px 10px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--rkxt-primary, #EB5202);
    background: var(--rkxt-primary-soft, #FFEEDE);
    border: 1px solid transparent;
    border-radius: 999px;
    cursor: pointer;
    line-height: 1.6;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.rkxt-field-action:hover,
.rkxt-field-action:focus-visible {
    background: var(--rkxt-primary, #EB5202);
    color: #fff;
    outline: none;
}

.rkxt-dialog {
    width: min(440px, calc(100vw - 32px));
    padding: 0;
    border: 1px solid var(--rkxt-border, #e2e8f0);
    border-radius: 14px;
    background: var(--rkxt-surface, #fff);
    color: var(--rkxt-text, #1e293b);
    box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
}
.rkxt-dialog::backdrop {
    background: rgba(15, 23, 42, 0.42);
    backdrop-filter: blur(2px);
}
.rkxt-dialog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--rkxt-border, #e2e8f0);
}
.rkxt-dialog-head h3 {
    margin: 0;
    font-size: 1.05rem;
    color: var(--rkxt-text, #1e293b);
}
.rkxt-dialog-close {
    background: transparent;
    border: none;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--rkxt-text-muted, #64748b);
    cursor: pointer;
    padding: 0 6px;
    border-radius: 6px;
}
.rkxt-dialog-close:hover { color: var(--rkxt-text, #1e293b); background: rgba(15, 23, 42, 0.06); }
.rkxt-dialog-body { padding: 18px 20px; display: flex; flex-direction: column; gap: 14px; }
.rkxt-dialog-body .rkxt-field { margin: 0; }
.rkxt-dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 14px 20px;
    border-top: 1px solid var(--rkxt-border, #e2e8f0);
    background: var(--rkxt-bg-soft, #fafafa);
    border-radius: 0 0 14px 14px;
}

/* ===== C5 — Envío sin cargo (badge storefront) + zonas admin ===== */
.rkxt-sf-badge-envio {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 8px;
    border-radius: 12px;
    background: #d1fae5;
    color: #065f46;
    border: 1px solid #6ee7b7;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.rkxt-sf-pdp-envio { margin: 4px 0 0; }
/* Inputs mini para días estimados (mín-máx) y celda sin wrap en la tabla de zonas */
.rkxt-cell-nowrap { white-space: nowrap; }
.rkxt-input-mini { width: 48px; display: inline-block; padding-left: 4px; padding-right: 4px; }

/* ===== C5 — Checkout: selección de envío + total ===== */
.rkxt-checkout-envios { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 8px; }
.rkxt-radio-card {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px 12px; border: 1px solid var(--rkxt-border); border-radius: 10px;
    cursor: pointer; background: var(--rkxt-surface, #fff); transition: border-color .15s, box-shadow .15s;
}
.rkxt-radio-card:hover { border-color: var(--rkxt-primary); }
.rkxt-radio-card:has(input:checked) { border-color: var(--rkxt-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rkxt-primary) 25%, transparent); }
.rkxt-radio-card input { margin-top: 3px; }
.rkxt-radio-card-body { display: flex; flex-direction: column; gap: 2px; }
.rkxt-radio-card-body strong { color: var(--rkxt-on-surface); }
.rkxt-radio-card-body small { color: var(--rkxt-on-surface-muted); }
.rkxt-checkout-total-box {
    display: flex; flex-wrap: wrap; gap: 18px; align-items: baseline;
    margin: 14px 0; padding: 12px 14px; border-radius: 10px;
    background: var(--rkxt-bg-alt); border: 1px solid var(--rkxt-border); font-size: 0.95rem;
}
.rkxt-checkout-total-box strong { color: var(--rkxt-on-surface); }

/* Tanda 2 — checkout en celular: el resumen (subtotal/envío/ajuste/total) se apila en filas
   label↔valor en vez de envolver inline desprolijo. Las acciones (volver / confirmar) full-width
   apiladas, con el botón confirmar arriba para que sea lo primero al alcance del pulgar. */
@media (max-width: 520px) {
    .rkxt-checkout-total-box {
        flex-direction: column;
        gap: 8px;
    }
    .rkxt-checkout-total-box span {
        display: flex;
        justify-content: space-between;
        width: 100%;
    }
    #rkxt-checkout-form .rkxt-form-actions { flex-direction: column-reverse; }
    #rkxt-checkout-form .rkxt-form-actions .rkxt-btn { width: 100%; min-height: 46px; }
}

/* ===== C5 — Selector de ámbito (empresa/tienda) en pantallas de negocio ===== */
.rkxt-ambito-bar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px;
    margin: 4px 0 18px; padding: 12px 14px; border-radius: 10px;
    background: var(--rkxt-bg-alt); border: 1px solid var(--rkxt-border);
}
.rkxt-ambito-form { margin: 0; }
.rkxt-ambito-hint { margin: 0; flex: 1 1 260px; font-size: 0.82rem; color: var(--rkxt-on-surface-muted); align-self: center; }
.rkxt-row-section {
    background: var(--rkxt-bg-alt); font-size: 0.78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.04em; color: var(--rkxt-on-surface-muted);
}

/* ===== T6c — Reconciliación de imágenes huérfanas ===== */
.rkxt-recon-bulkbar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    position: sticky; top: 0; z-index: 5; margin: 8px 0 14px;
    padding: 12px 14px; border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-bg-alt); border: 1px solid var(--rkxt-border);
}
.rkxt-recon-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.rkxt-recon-card {
    display: flex; flex-direction: column; gap: 8px;
    background: var(--rkxt-surface, #fff); border: 1px solid var(--rkxt-border);
    border-left: 3px solid var(--rkxt-border); border-radius: var(--rkxt-radius); padding: 12px;
}
.rkxt-recon-card--alta  { border-left-color: #6ee7b7; }
.rkxt-recon-card--media { border-left-color: #fde68a; }
.rkxt-recon-card--baja  { border-left-color: #fecaca; }
.rkxt-recon-thumb {
    aspect-ratio: 1 / 1; background: var(--rkxt-bg-alt); border-radius: var(--rkxt-radius-sm);
    overflow: hidden; display: flex; align-items: center; justify-content: center;
}
.rkxt-recon-thumb img { width: 100%; height: 100%; object-fit: contain; }
.rkxt-recon-meta { display: flex; flex-direction: column; gap: 4px; }
.rkxt-recon-file { font-size: 0.72rem; color: var(--rkxt-on-surface-muted); word-break: break-all; }
.rkxt-recon-actions { display: flex; gap: 6px; margin-top: 4px; }

/* ============================================================
   FIX DE LEGIBILIDAD DE BOTONES (consistente plataforma)
   Regla 28: botones de fondo de color usados como <a> heredaban
   `a:hover { color: primary-hover }` -> texto naranja sobre naranja
   = invisible ("Finalizar compra", "Buscar"). Re-afirmamos el color
   en todos los estados con especificidad doble-clase (gana al a:hover
   global sin depender del orden de cascada). Vale <button> y <a>.
   ============================================================ */
.rkxt-btn.rkxt-btn-primary,
.rkxt-btn.rkxt-btn-primary:link,
.rkxt-btn.rkxt-btn-primary:visited,
.rkxt-btn.rkxt-btn-primary:hover,
.rkxt-btn.rkxt-btn-primary:focus,
.rkxt-btn.rkxt-btn-primary:active {
    color: var(--rkxt-fg-on-primary);
    text-decoration: none;
}
.rkxt-sf-search-btn,
.rkxt-sf-search-btn:link,
.rkxt-sf-search-btn:visited,
.rkxt-sf-search-btn:hover,
.rkxt-sf-search-btn:focus,
.rkxt-sf-search-btn:active {
    color: var(--rkxt-fg-on-primary);
    text-decoration: none;
}
.rkxt-btn.rkxt-btn-danger,
.rkxt-btn.rkxt-btn-danger:hover,
.rkxt-btn.rkxt-btn-danger:focus,
.rkxt-btn.rkxt-btn-danger:active {
    color: #fff;
    text-decoration: none;
}
a.rkxt-btn:hover,
a.rkxt-btn:focus,
a.rkxt-btn:active { text-decoration: none; }

.rkxt-btn:focus-visible,
.rkxt-sf-search-btn:focus-visible {
    outline: 2px solid var(--rkxt-primary);
    outline-offset: 2px;
}
.rkxt-btn:focus:not(:focus-visible),
.rkxt-sf-search-btn:focus:not(:focus-visible) { outline: none; }

/* ============================================================
   FocusOnNavigate — sin "marco" en el título de cada página.
   Blazor (<FocusOnNavigate Selector="h1">) pone tabindex="-1" en el
   primer <h1> y le hace .focus() tras cada navegación, por accesibilidad
   (lleva al usuario de lector de pantalla al heading de la página nueva).
   El navegador dibujaba su outline default alrededor del título -> el
   "recuadro" que se ve en la home y en TODOS los formularios.
   Estos headings tienen tabindex="-1": NO son alcanzables con Tab
   (están fuera del orden de tabulación), así que sacarles el outline NO
   afecta la navegación por teclado. El foco programático sigue ocurriendo
   (accesibilidad intacta), solo que ahora es invisible.
   Los controles interactivos reales (inputs/select/textarea/botones/links)
   conservan su focus ring vía :focus-visible más arriba.
   ============================================================ */
h1[tabindex="-1"]:focus,
h2[tabindex="-1"]:focus,
h3[tabindex="-1"]:focus,
[tabindex="-1"].rkxt-landing-h1:focus,
[tabindex="-1"].rkxt-admin-page-header h1:focus {
    outline: none;
    box-shadow: none;
}

/* ============================================================
   Asignar imágenes por arrastre  (/admin/catalog/imagenes/asignar)
   Split 50/50: artículos (drop targets) | explorador de media (draggable).
   Hermano de Reconciliar — reúsa estética de miniaturas. Todo con tokens --rkxt-*.
   ============================================================ */
.rkxt-imgassign-a11y-hint {
    font-size: 0.8rem;
    color: var(--rkxt-on-surface-muted);
    margin: 0 0 12px;
    display: flex; align-items: center; gap: 6px;
}

.rkxt-imgassign-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    align-items: start;
}
.rkxt-imgassign-panel {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    display: flex; flex-direction: column;
    max-height: calc(100vh - 230px);
    min-height: 420px;
    overflow: hidden;
}
.rkxt-imgassign-panel-head {
    display: flex; align-items: center; gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--rkxt-border);
    background: var(--rkxt-bg-alt);
    flex-wrap: wrap;
}
.rkxt-imgassign-panel-title { font-weight: 700; font-size: 0.92rem; color: var(--rkxt-text); margin: 0; }
.rkxt-imgassign-panel-head .rkxt-input { flex: 1 1 160px; min-width: 0; padding: 8px 12px; font-size: 0.9rem; }
.rkxt-imgassign-scroll { overflow-y: auto; padding: 16px; flex: 1; }

.rkxt-imgassign-breadcrumb {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
    padding: 8px 16px; font-size: 0.82rem;
    color: var(--rkxt-on-surface-muted);
    border-bottom: 1px solid var(--rkxt-border-soft);
    background: var(--rkxt-surface);
}
.rkxt-imgassign-breadcrumb button {
    background: none; border: none; cursor: pointer;
    color: var(--rkxt-primary); font: inherit; padding: 2px 4px; border-radius: 4px;
}
.rkxt-imgassign-breadcrumb button:hover { background: var(--rkxt-primary-soft); }
.rkxt-imgassign-breadcrumb-sep { color: var(--rkxt-text-dim); }
.rkxt-imgassign-breadcrumb-current { color: var(--rkxt-text); font-weight: 600; }

/* Panel izquierdo — cards de artículo (drop targets) */
.rkxt-imgassign-articulos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px;
}
.rkxt-imgassign-art {
    display: flex; flex-direction: column; gap: 8px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 10px;
    transition: border-color .12s ease, box-shadow .12s ease, background .12s ease;
}
.rkxt-imgassign-art--vacio {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--rkxt-primary) 30%, var(--rkxt-border));
}
.rkxt-imgassign-art.is-dragover {
    border-color: var(--rkxt-primary); border-style: solid;
    background: var(--rkxt-primary-soft);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--rkxt-primary) 22%, transparent);
}
.rkxt-imgassign-art-thumb {
    aspect-ratio: 1 / 1; background: var(--rkxt-bg-alt);
    border-radius: var(--rkxt-radius-sm); overflow: hidden;
    display: flex; align-items: center; justify-content: center; position: relative;
}
.rkxt-imgassign-art-thumb img,
.rkxt-imgassign-art-thumb video { width: 100%; height: 100%; object-fit: contain; }
.rkxt-imgassign-art-thumb-ph { font-size: 1.6rem; color: var(--rkxt-text-dim); }
.rkxt-imgassign-art-name {
    font-size: 0.85rem; font-weight: 600; color: var(--rkxt-on-surface); line-height: 1.3;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rkxt-imgassign-art-code { font-family: 'JetBrains Mono', Consolas, monospace; font-size: 0.72rem; color: var(--rkxt-on-surface-muted); }
.rkxt-imgassign-art-foot { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-top: auto; }
.rkxt-imgassign-art-foot .rkxt-badge-zero { background: var(--rkxt-bg-alt); color: var(--rkxt-text-dim); border-color: var(--rkxt-border); }

/* Panel derecho — grid de media */
.rkxt-imgassign-media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 10px;
}
.rkxt-imgassign-folder {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
    aspect-ratio: 1 / 1; background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border); border-radius: var(--rkxt-radius-sm);
    cursor: pointer; padding: 8px;
    transition: border-color .12s ease, background .12s ease;
}
.rkxt-imgassign-folder:hover { border-color: var(--rkxt-primary); background: var(--rkxt-primary-soft); }
.rkxt-imgassign-folder-icon { font-size: 1.8rem; line-height: 1; }
.rkxt-imgassign-folder-name { font-size: 0.72rem; color: var(--rkxt-on-surface-muted); text-align: center; word-break: break-word; line-height: 1.2; max-width: 100%; }

.rkxt-imgassign-media {
    position: relative; aspect-ratio: 1 / 1; background: var(--rkxt-bg-alt);
    border: 2px solid var(--rkxt-border); border-radius: var(--rkxt-radius-sm);
    overflow: hidden; cursor: grab;
    transition: border-color .12s ease, box-shadow .12s ease, opacity .12s ease;
}
.rkxt-imgassign-media:active { cursor: grabbing; }
.rkxt-imgassign-media img, .rkxt-imgassign-media video { width: 100%; height: 100%; object-fit: contain; display: block; pointer-events: none; }
.rkxt-imgassign-media:hover { border-color: color-mix(in srgb, var(--rkxt-primary) 50%, transparent); }
.rkxt-imgassign-media.is-selected { border-color: var(--rkxt-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rkxt-primary) 28%, transparent); }
.rkxt-imgassign-media.is-assigned { opacity: 0.55; }
.rkxt-imgassign-media.is-assigned::after {
    content: "✓"; position: absolute; top: 4px; right: 4px;
    width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
    background: #065f46; color: #fff; border-radius: 50%; font-size: 0.72rem; font-weight: 700;
}
.rkxt-imgassign-media-type {
    position: absolute; bottom: 4px; left: 4px;
    background: rgba(15,15,18,0.72); color: #fff; font-size: 0.66rem;
    padding: 1px 6px; border-radius: var(--rkxt-radius-pill); line-height: 1.5;
}

/* Barra de progreso bulk (sticky) */
.rkxt-imgassign-progress {
    position: sticky; top: 0; z-index: 6;
    margin: 0 0 16px; padding: 12px 16px;
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-bg-alt); border: 1px solid var(--rkxt-border);
    display: flex; flex-direction: column; gap: 8px;
}
.rkxt-imgassign-progress-head { display: flex; align-items: center; gap: 10px; font-size: 0.88rem; font-weight: 600; color: var(--rkxt-text); }
.rkxt-imgassign-progress-bar { height: 6px; border-radius: var(--rkxt-radius-pill); background: var(--rkxt-surface-2); overflow: hidden; }
.rkxt-imgassign-progress-fill { height: 100%; width: 0; background: var(--rkxt-grad-primary); transition: width .2s ease; }
.rkxt-imgassign-progress-items { display: flex; flex-wrap: wrap; gap: 6px; }
.rkxt-imgassign-progress-chip {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 0.74rem; padding: 2px 9px; border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-surface); border: 1px solid var(--rkxt-border); color: var(--rkxt-on-surface-muted);
    max-width: 180px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.rkxt-imgassign-progress-chip.is-ok { color: #065f46; border-color: #6ee7b7; background: #d1fae5; }
.rkxt-imgassign-progress-chip.is-err { color: #991b1b; border-color: #fecaca; background: #fee2e2; }

/* El atributo HTML `hidden` debe ganar sobre los `display:flex/grid` de arriba
   (una regla de autor con display pisa el [hidden] del user-agent). Sin esto, la
   barra de progreso / grid / fallback aparecen visibles al cargar la página. */
.rkxt-imgassign-progress[hidden],
.rkxt-imgassign-media-grid[hidden],
.rkxt-imgassign-breadcrumb[hidden],
.rkxt-imgassign-fallback[hidden] { display: none; }

@media (max-width: 1100px) {
    .rkxt-imgassign-split { grid-template-columns: 1fr; }
    .rkxt-imgassign-panel { max-height: none; }
    .rkxt-imgassign-panel--media { order: -1; }
}

/* ============ Admin: gestión de redes sociales por tienda (/admin/org/tiendas/{id}/redes) ============ */
.rkxt-redes-lista {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    margin-bottom: 1rem;
}
.rkxt-red-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 1rem;
    padding: .7rem .85rem;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
}
.rkxt-red-row.is-off { opacity: .55; }
.rkxt-red-chip {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-weight: 700;
    flex: 0 0 auto;
    overflow: hidden;
}
.rkxt-red-chip img { width: 100%; height: 100%; object-fit: cover; }
.rkxt-red-campos {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    min-width: 0;
}
.rkxt-red-nombre { font-size: .9rem; }
.rkxt-red-logo {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .8rem;
    flex: 0 0 auto;
}
.rkxt-red-logo input[type=file] { max-width: 150px; font-size: .78rem; }
.rkxt-red-acciones { display: flex; gap: .3rem; flex: 0 0 auto; }
.rkxt-redes-agregar {
    display: flex;
    gap: .5rem;
    align-items: center;
    padding-top: 1rem;
    border-top: 1px dashed var(--rkxt-border);
}
.rkxt-redes-agregar select { max-width: 260px; }

@media (max-width: 720px) {
    .rkxt-red-row { grid-template-columns: auto 1fr; }
    .rkxt-red-logo, .rkxt-red-acciones { grid-column: 1 / -1; }
}

/* ============ Footer "completo" del storefront (estilo Kosiuko) ============ */
.rkxt-sf-footer-rich {
    padding: 3rem clamp(1rem, 4vw, 3rem) 1.5rem;
    font-size: .9rem;
}
.rkxt-sf-footer-top {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 2rem;
    max-width: 1280px;
    margin: 0 auto;
}
.rkxt-sf-footer-col h4 {
    margin: 0 0 1rem;
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}
.rkxt-sf-footer-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .55rem; }
.rkxt-sf-footer-col a { color: inherit; text-decoration: none; opacity: .82; transition: opacity .12s ease; }
.rkxt-sf-footer-col a:hover { opacity: 1; text-decoration: underline; }
.rkxt-sf-footer-redes-iconos { display: flex; flex-wrap: wrap; gap: .9rem; align-items: center; }
.rkxt-sf-footer-red {
    width: 34px; height: 34px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    color: inherit; overflow: hidden; opacity: .85;
    /* Borde sutil con el color de marca de la red (variable inline --red-color);
       cae a currentColor cuando la plataforma no define color. */
    border: 1px solid color-mix(in srgb, var(--red-color, currentColor) 55%, transparent);
    transition: opacity .12s ease, transform .12s ease, border-color .12s ease, background .12s ease;
}
.rkxt-sf-footer-red:hover {
    opacity: 1; transform: translateY(-2px);
    border-color: var(--red-color, currentColor);
    background: color-mix(in srgb, var(--red-color, currentColor) 14%, transparent);
}
.rkxt-sf-footer-red img { width: 100%; height: 100%; object-fit: cover; }
.rkxt-sf-footer-red-txt { font-weight: 700; }
.rkxt-sf-footer-app-tit { margin-top: 1.5rem !important; }
.rkxt-sf-footer-app { display: flex; flex-wrap: wrap; gap: .6rem; }
.rkxt-sf-footer-app-badge {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .45rem .85rem;
    color: inherit; text-decoration: none;
    /* Pill outline derivado de currentColor → legible en footer claro y oscuro. */
    border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    border-radius: 10px;
    transition: border-color .12s ease, background .12s ease;
}
.rkxt-sf-footer-app-badge:hover {
    border-color: color-mix(in srgb, currentColor 70%, transparent);
    background: color-mix(in srgb, currentColor 8%, transparent);
    text-decoration: none;
}
.rkxt-sf-footer-app-ico { font-size: 1rem; line-height: 1; opacity: .9; }
.rkxt-sf-footer-app-txt { display: flex; flex-direction: column; line-height: 1.15; font-weight: 600; font-size: .9rem; }
.rkxt-sf-footer-app-txt small { font-size: .62rem; font-weight: 500; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }
.rkxt-sf-footer-logos {
    display: flex; flex-wrap: wrap; gap: 2rem; align-items: center; justify-content: center;
    max-width: 1280px; margin: 2.5rem auto 0; padding-top: 1.5rem;
    /* Separador derivado de currentColor → funciona en footer oscuro Y claro
       (antes rgba blanco fijo, invisible si el tenant pone color_fondo claro). */
    border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
}
.rkxt-sf-footer-logos img { max-height: 38px; width: auto; opacity: .9; filter: grayscale(1); transition: filter .15s ease, opacity .15s ease; }
.rkxt-sf-footer-logos a:hover img, .rkxt-sf-footer-logos img:hover { filter: grayscale(0); opacity: 1; }
.rkxt-sf-footer-legal {
    display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; justify-content: space-between;
    max-width: 1280px; margin: 1.5rem auto 0; padding-top: 1.25rem;
    border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
    font-size: .8rem; opacity: .75;
}
.rkxt-sf-footer-powered a { color: inherit; }

/* ============ Componentes del MOTOR de secciones (footer-motor + body) ============
   Extraídos del look validado de .rkxt-sf-footer-rich. Pensados sobre todo para el footer
   armado con el motor (.rkxt-sf-footer-motor), pero usables en CUALQUIER columna de CUALQUIER
   sección — por eso TODO hereda color (color:inherit) y deriva bordes/separadores de
   currentColor: se ven bien tanto sobre fondo OSCURO (footer con color_fondo del tema) como
   CLARO (body, fondo blanco). NUNCA color absoluto: el color efectivo lo fija la sección/footer
   contenedor (resuelve el bug de "color por sección"). */

/* --- Título común (mismo tratamiento que .rkxt-sf-footer-col h4) compartido por los 3 moldes --- */
.rkxt-sf-ml-tit,
.rkxt-sf-redes-tit,
.rkxt-sf-appbadges-tit {
    margin: 0 0 1rem;
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: inherit;
}

/* --- 1. MenuLinks: columna título + lista de links --- */
.rkxt-sf-ml { color: inherit; }
.rkxt-sf-ml-list {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-direction: column; gap: .55rem;
}
.rkxt-sf-ml-list a {
    color: inherit; text-decoration: none; opacity: .82;
    transition: opacity .12s ease;
}
.rkxt-sf-ml-list a:hover { opacity: 1; text-decoration: underline; }

/* --- 2. Redes: título + íconos sociales (reusa el look de .rkxt-sf-footer-red) --- */
.rkxt-sf-redes { color: inherit; }
.rkxt-sf-redes-iconos { display: flex; flex-wrap: wrap; gap: .9rem; align-items: center; }
.rkxt-sf-red {
    /* Diámetro default = mediano (-md). Sobreescrito por los modificadores de tamaño. */
    width: 34px; height: 34px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    color: inherit; text-decoration: none; overflow: hidden; opacity: .85;
    /* Borde con el color de marca de la red (--red-color inline); cae a currentColor cuando
       la plataforma no define color → visible sobre footer oscuro Y body claro. */
    border: 1px solid color-mix(in srgb, var(--red-color, currentColor) 55%, transparent);
    transition: opacity .12s ease, transform .12s ease, border-color .12s ease, background .12s ease;
}
.rkxt-sf-red:hover {
    opacity: 1; transform: translateY(-2px);
    border-color: var(--red-color, currentColor);
    background: color-mix(in srgb, var(--red-color, currentColor) 14%, transparent);
}
.rkxt-sf-red img { width: 100%; height: 100%; object-fit: cover; }
/* Glifo de marca inline (SVG single-path en currentColor): centrado con padding dentro del
   círculo (a diferencia del <img> que va a borde). ~52% del diámetro = aire prolijo. */
.rkxt-sf-red-svg { width: 52%; height: 52%; display: block; }
.rkxt-sf-red:hover .rkxt-sf-red-svg { color: var(--red-color, currentColor); }
.rkxt-sf-red-txt { font-weight: 700; line-height: 1; }

/* Modificadores de tamaño (diámetro del ícono) */
.rkxt-sf-redes-sm .rkxt-sf-red { width: 28px; height: 28px; font-size: .85rem; }
.rkxt-sf-redes-md .rkxt-sf-red { width: 34px; height: 34px; font-size: 1rem; }
.rkxt-sf-redes-lg .rkxt-sf-red { width: 44px; height: 44px; font-size: 1.2rem; }

/* Modificadores de forma (border-radius) */
.rkxt-sf-redes-f-circulo .rkxt-sf-red { border-radius: 50%; }
.rkxt-sf-redes-f-cuadrado .rkxt-sf-red { border-radius: 8px; }

/* --- 3. AppBadges: título + botones App Store / Google Play (look de .rkxt-sf-footer-app-badge) --- */
.rkxt-sf-appbadges { color: inherit; }
.rkxt-sf-appbadges-row { display: flex; flex-wrap: wrap; gap: .6rem; }
.rkxt-sf-appbadge {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .45rem .85rem;
    color: inherit; text-decoration: none;
    /* Pill outline derivado de currentColor → legible en footer claro y oscuro. */
    border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    border-radius: 10px;
    transition: border-color .12s ease, background .12s ease;
}
.rkxt-sf-appbadge:hover {
    border-color: color-mix(in srgb, currentColor 70%, transparent);
    background: color-mix(in srgb, currentColor 8%, transparent);
    text-decoration: none;
}
.rkxt-sf-appbadge-ico { font-size: 1rem; line-height: 1; opacity: .9; }
.rkxt-sf-appbadge-txt { display: flex; flex-direction: column; line-height: 1.15; font-weight: 600; font-size: .9rem; }
.rkxt-sf-appbadge-txt small { font-size: .62rem; font-weight: 500; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }

/* --- Modificadores de alineación compartidos por Redes + AppBadges (default = izquierda) --- */
.rkxt-sf-redes.is-centro,
.rkxt-sf-appbadges.is-centro { text-align: center; }
.rkxt-sf-redes.is-centro .rkxt-sf-redes-iconos,
.rkxt-sf-appbadges.is-centro .rkxt-sf-appbadges-row { justify-content: center; }
.rkxt-sf-redes.is-derecha,
.rkxt-sf-appbadges.is-derecha { text-align: right; }
.rkxt-sf-redes.is-derecha .rkxt-sf-redes-iconos,
.rkxt-sf-appbadges.is-derecha .rkxt-sf-appbadges-row { justify-content: flex-end; }

/* ============ Admin: configuración del footer (/admin/org/tiendas/{id}/footer) ============ */
.rkxt-admin-card-title { margin: 0 0 1rem; font-size: 1.05rem; }
.rkxt-footer-col-edit {
    border: 1px solid var(--rkxt-border); border-left: 3px solid var(--rkxt-primary);
    border-radius: var(--rkxt-radius-sm); background: var(--rkxt-surface);
    padding: .85rem 1rem; margin-bottom: .85rem;
}
.rkxt-footer-col-head { display: flex; gap: 1rem; align-items: center; justify-content: space-between; margin-bottom: .75rem; }
.rkxt-footer-col-head > input { max-width: 280px; }
.rkxt-footer-links { display: flex; flex-direction: column; gap: .45rem; padding-left: .5rem; }
.rkxt-footer-link-row { display: flex; gap: .4rem; align-items: center; }
.rkxt-footer-link-row > input[type=text]:nth-of-type(1) { flex: 0 0 30%; }
.rkxt-footer-link-row > input[type=text]:nth-of-type(2) { flex: 1 1 auto; min-width: 0; }
.rkxt-footer-link-blank { display: inline-flex; align-items: center; gap: .2rem; font-size: .85rem; white-space: nowrap; }
.rkxt-footer-logos-grid { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem; }
.rkxt-footer-logo-item {
    display: flex; flex-direction: column; gap: .4rem; align-items: center;
    border: 1px solid var(--rkxt-border); border-radius: var(--rkxt-radius-sm);
    padding: .6rem; background: var(--rkxt-surface); width: 170px;
}
.rkxt-footer-logo-item img { max-height: 48px; max-width: 100%; object-fit: contain; }
.rkxt-footer-logo-add { display: flex; align-items: center; gap: .5rem; font-size: .85rem; padding-top: .5rem; border-top: 1px dashed var(--rkxt-border); }

/* ============ Admin: catálogo global de plataformas de redes (/admin/config/redes-sociales) ============ */
.rkxt-plat-campos { display: flex; flex-direction: column; gap: .4rem; min-width: 0; }
.rkxt-plat-fila1, .rkxt-plat-fila2 { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.rkxt-plat-fila1 > input[type=text] { flex: 0 1 180px; }
.rkxt-plat-fila2 > input { flex: 1 1 200px; min-width: 0; }
.rkxt-plat-codigo { font-size: .78rem; background: var(--rkxt-surface-2); padding: 2px 7px; border-radius: 4px; color: var(--rkxt-text); }
.rkxt-plat-badge { font-size: .68rem; text-transform: uppercase; color: var(--rkxt-text-muted); letter-spacing: .04em; }

/* Botón "+ agregar" de repeaters inline (links del footer, etc.). Mismo look que el
   del editor de props de Compass, pero global — el de PropsEditor está scoped y no
   alcanza a Footer.razor (CSS isolation no cruza componentes). */
.rkxt-repeater-add {
    align-self: flex-start;
    border: 1px dashed var(--rkxt-border);
    background: transparent;
    color: var(--rkxt-text-dim);
    border-radius: var(--rkxt-radius-sm);
    padding: .45rem 1rem;
    cursor: pointer;
    font-size: .85rem;
    transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.rkxt-repeater-add:hover {
    border-color: var(--rkxt-primary);
    color: var(--rkxt-primary);
    background: var(--rkxt-primary-soft);
}

/* ===== Cuentas de cliente del storefront (/t/{slug}/cuenta/*) ===== */
/* Caja angosta centrada para login/registro/olvidé/reset/home — formularios cortos
   que no necesitan el ancho completo del catálogo. */
.rkxt-sf-cuenta-narrow {
    max-width: 560px;
    margin-left: auto;
    margin-right: auto;
}
/* "Mis pedidos": tabla con 5 columnas (Número, Fecha, Estado, Total, Acciones) → contenedor más
   ancho que el de los forms de cuenta, para que el número no se parta y el estado quede prolijo. */
.rkxt-sf-cuenta-pedidos {
    max-width: 940px;
    margin-left: auto;
    margin-right: auto;
}
.rkxt-sf-cuenta-pedidos .rkxt-sf-cart-tabla code { white-space: nowrap; }       /* RKXT-2026-000002 en 1 línea */
.rkxt-sf-cuenta-pedidos .rkxt-sf-cart-tabla td:nth-child(2) { white-space: nowrap; }  /* Fecha en 1 línea */
.rkxt-sf-cuenta-pedidos .rkxt-sf-cart-tabla td:nth-child(3) [class*="rkxt-estado-"] {  /* label de estado en 1 línea */
    display: inline-block;
    white-space: nowrap;
    font-weight: 600;
}
.rkxt-sf-pedido-motivo {                                                        /* motivo de la devolución, prolijo */
    display: block;
    margin-top: 4px;
    max-width: 280px;
    line-height: 1.35;
}
.rkxt-sf-pedido-nota-bloqueo {                                                  /* por qué el cliente no puede editar el pedido */
    display: inline-block;
    max-width: 260px;
    text-align: left;
    line-height: 1.35;
    white-space: normal;
}
/* CTA "hacer un nuevo pedido" — header de Mis pedidos con acción a la derecha */
.rkxt-sf-cuenta-pedidos-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.rkxt-sf-nuevo-pedido-cta { white-space: nowrap; }
/* Banner GLOBAL "estás modificando el pedido X" (StorefrontLayout) — barra ámbar bajo el header,
   visible en toda la tienda mientras el cliente está en modo edición (salvo el catálogo, que ya
   muestra su banner propio). Usa el semáforo --rkxt-warn (estado, no color de marca). */
.rkxt-sf-edicion-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px 20px;
    flex-wrap: wrap;
    padding: 10px 20px;
    background: var(--rkxt-warn-soft, #FEF3C7);
    border-bottom: 1px solid color-mix(in srgb, var(--rkxt-warn, #D97706) 45%, transparent);
    color: var(--rkxt-text, #1a1a1a);
    font-size: 0.92rem;
    line-height: 1.35;
}
.rkxt-sf-edicion-banner-msg strong { font-weight: 700; }
.rkxt-sf-edicion-banner-acciones {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
/* Filtro "mostrar solo los productos del carrito/pedido" en el catálogo */
.rkxt-sf-cart-filter {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0 0 16px;
    padding: 10px 14px;
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-sf-radius, 10px);
}
.rkxt-sf-cart-filter-on { font-weight: 600; }
/* ============================================================================
   Item 2 — dashboard del pedido para el cliente (storefront, CuentaPedidoDashboard.razor).
   Identidad PROPIA del storefront: NO reusa .rkxt-kpi-row/.rkxt-dash-* del admin (esas
   siguen sirviendo a Admin/Sales/Pedidos/Detalle.razor y ZonaPeligrosa.razor — no tocar).
   Cards con --rkxt-surface/--rkxt-radius del TEMA del tenant (kosiuko-wholesale = navy).
   El callout "modificado" usa el semáforo real --rkxt-warn(-soft) (estado, no color de marca).
   ============================================================================ */
.rkxt-sf-section-subtitle { font-size: 1.05rem; font-weight: 700; margin: 6px 0 2px; }

/* ============================================================
   Mi stock del cliente (/t/{slug}/cuenta/stock) — F22_M037.
   Grilla manual por SKU + importador Excel total/parcial.
   ============================================================ */
.rkxt-sf-cuenta-stock { max-width: 1040px; }
.rkxt-sf-stock-import { padding: 4px 0 0; }
.rkxt-sf-stock-step { margin: 18px 0; }
.rkxt-sf-stock-step h3 { margin: 0 0 6px; font-size: 1rem; }
.rkxt-sf-stock-hint { margin: 8px 0 0; font-size: .86rem; color: var(--rkxt-text-muted); }
/* Selector de modo total/parcial: dos "cards" con radio. */
.rkxt-sf-stock-modo { display: grid; gap: 10px; margin: 6px 0 14px; }
.rkxt-sf-stock-modo-opt {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 12px 14px; border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm); cursor: pointer; font-size: .92rem; line-height: 1.4;
}
.rkxt-sf-stock-modo-opt:has(input:checked) { border-color: var(--rkxt-primary); background: var(--rkxt-surface-2); }
.rkxt-sf-stock-modo-opt:has(input:disabled) { opacity: .55; cursor: not-allowed; }
.rkxt-sf-stock-modo-opt input { margin-top: 3px; }
/* Advertencia TOTAL (semáforo de riesgo, NO color de marca — mismo criterio que .rkxt-sf-dash-modv). */
.rkxt-sf-stock-advertencia {
    margin: 12px 0; padding: 14px 16px;
    background: var(--rkxt-warn-soft);
    border: 1px solid color-mix(in srgb, var(--rkxt-warn) 35%, transparent);
    border-left: 4px solid var(--rkxt-warn);
    border-radius: var(--rkxt-radius-sm); font-size: .9rem;
}
.rkxt-sf-stock-advertencia strong { display: block; margin-bottom: 4px; }
.rkxt-sf-stock-advertencia p { margin: 0; }
.rkxt-sf-stock-aviso {
    margin: 10px 0; padding: 10px 14px; font-size: .88rem;
    background: var(--rkxt-warn-soft);
    border-left: 3px solid var(--rkxt-warn); border-radius: var(--rkxt-radius-sm);
}
.rkxt-sf-stock-resumen { margin: 8px 0 14px; padding-left: 20px; font-size: .92rem; line-height: 1.7; }
.rkxt-sf-stock-resumen-alerta { color: var(--rkxt-warn); font-weight: 600; }
/* Filtros de la grilla manual. Lleva también .rkxt-sf-sticky-filtros (patrón genérico, ver arriba
   de la sección "Carga rápida") para quedar pegada arriba junto con el thead al scrollear la
   lista — puede ser larga. */
.rkxt-sf-stock-filtros { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0 14px; align-items: center; }
.rkxt-sf-stock-buscar { flex: 1 1 220px; min-width: 180px; }
.rkxt-sf-stock-filtros select { flex: 0 1 200px; }
/* Grilla: columnas numéricas a la derecha + form inline por fila. */
.rkxt-sf-stock-tabla td { vertical-align: middle; }
/* FIX regresión sticky thead — .rkxt-sf-cart-tabla trae overflow:hidden (para redondear las
   esquinas de la card). Con un <th> position:sticky adentro, ese overflow:hidden convierte a la
   TABLA MISMA en el contenedor de scroll del sticky (en vez del viewport/página) → el thead se
   ancla contra su propia caja, que nunca "scrollea" internamente, y el título de columna queda
   vacío/invisible en reposo y al scrollear. Mismo bug y mismo fix YA aplicado en el admin
   (.rkxt-table, ver comentario ahí: "SIN overflow:hidden ... rompía el thead sticky"). Acotado
   SOLO a esta tabla — .rkxt-sf-cart-tabla sigue con overflow:hidden en /cart y /cuenta/pedidos
   (sin sticky ahí, no les afecta). Costo cosmético menor: las esquinas superiores de la card ya
   no quedan perfectamente recortadas al radius (mismo trade-off aceptado en el admin). */
.rkxt-sf-stock-tabla { overflow: visible; }
.rkxt-sf-stock-fila-form { display: flex; gap: 8px; align-items: center; justify-content: flex-end; margin: 0; }
/* Fila "bajo mínimo" (cantidad < mínimo con mínimo>0): borde-izq de aviso para que el cliente
   vea de un vistazo qué tiene que reponer. */
.rkxt-sf-stock-bajo > td:first-child { box-shadow: inset 3px 0 0 var(--rkxt-warn); }
/* Feedback del guardado por fila (rkxt-stock.js, sin recargar). */
.rkxt-sf-stock-fila-msg { font-size: .82rem; font-weight: 600; color: #16a34a; white-space: nowrap; }
.rkxt-sf-stock-fila-msg.is-error { color: var(--rkxt-danger, #dc2626); }
.rkxt-sf-stock-fila-ok > td { transition: background-color .2s ease; background-color: color-mix(in srgb, #16a34a 14%, transparent); }
.rkxt-sf-stock-pag { display: flex; gap: 12px; align-items: center; justify-content: center; margin: 16px 0; }

/* ADMIN — "Stock del local del cliente" en la ficha del cliente (/admin/crm/clientes/{id}). Readonly. */
.rkxt-cs-section { margin: 22px 0 28px; }
.rkxt-cs-title { margin: 0 0 4px; font-size: 1.1rem; }
.rkxt-cs-kpis { display: flex; flex-wrap: wrap; gap: 10px 22px; margin: 10px 0 14px; }
.rkxt-cs-kpi { font-size: .95rem; }
.rkxt-cs-kpi strong { font-size: 1.05rem; }
.rkxt-cs-kpi--alerta strong { color: var(--rkxt-warn); }
.rkxt-cs-tabla { width: 100%; max-width: 720px; }
.rkxt-cs-badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .72rem; font-weight: 700; }
.rkxt-cs-badge-danger { background: color-mix(in srgb, var(--rkxt-danger, #dc2626) 15%, transparent); color: var(--rkxt-danger, #dc2626); }
.rkxt-cs-badge-warn { background: var(--rkxt-warn-soft, #FEF3C7); color: color-mix(in srgb, var(--rkxt-warn) 70%, #000); }

/* Paginador de secciones por-ítem del detalle de pedido (depósitos/entregas en pedidos grandes). */
.rkxt-sec-pager { display: flex; gap: 12px; align-items: center; margin: 14px 0; }

/* --- Callout "tu vendedor ajustó N renglones" (item 5). --- */
.rkxt-sf-dash-modv {
    margin: 0 0 22px;
    padding: 16px 18px;
    background: var(--rkxt-warn-soft);
    border: 1px solid color-mix(in srgb, var(--rkxt-warn) 35%, transparent);
    border-left: 4px solid var(--rkxt-warn);
    border-radius: var(--rkxt-radius-sm);
}
.rkxt-sf-dash-modv-head { margin: 0; font-size: .98rem; color: var(--rkxt-text); }
.rkxt-sf-dash-modv-icon { margin-right: 6px; }
.rkxt-sf-dash-modv-list { margin: 10px 0 6px; padding-left: 20px; font-size: .9rem; line-height: 1.6; color: var(--rkxt-text); }
.rkxt-sf-dash-modv-list li { margin: 2px 0; }
.rkxt-sf-dash-modv-link { display: inline-block; margin-top: 4px; font-weight: 600; }

/* --- KPIs a lo ancho: 4 tiles con icono en chip naranja-soft, apilan 2/1 col en mobile. --- */
.rkxt-sf-dash-kpis {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
    margin: 6px 0 26px;
}
@media (max-width: 720px) { .rkxt-sf-dash-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px) { .rkxt-sf-dash-kpis { grid-template-columns: 1fr; } }
.rkxt-sf-dash-kpi {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 18px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    box-shadow: var(--rkxt-shadow-sm);
}
.rkxt-sf-dash-kpi-icon {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-primary-soft);
}
.rkxt-sf-dash-kpi-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rkxt-sf-dash-kpi-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--rkxt-text-muted); }
.rkxt-sf-dash-kpi-val { font-size: 1.4rem; font-weight: 700; color: var(--rkxt-text); line-height: 1.15; }

/* --- Composición del pedido: card + 3 columnas de barras + "lo que más pediste". --- */
.rkxt-sf-dash-composicion {
    margin: 0 0 26px;
    padding: 22px 24px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
}
.rkxt-sf-dash-cols {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px;
    margin-top: 10px;
}
@media (max-width: 900px) { .rkxt-sf-dash-cols { grid-template-columns: 1fr; gap: 26px; } }
.rkxt-sf-dash-col { min-width: 0; }
.rkxt-sf-dash-col-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    font-size: .95rem;
    font-weight: 700;
    color: var(--rkxt-text);
}
.rkxt-sf-dash-col-dot { width: 10px; height: 10px; border-radius: 999px; flex: 0 0 auto; }
.rkxt-sf-dash-col-dot--marca { background: var(--rkxt-primary); }
.rkxt-sf-dash-col-dot--talle { background: var(--rkxt-accent, #FFD166); }
.rkxt-sf-dash-col-dot--tipologia { background: var(--rkxt-secondary, #9aa); }

.rkxt-sf-dash-bar-row {
    display: grid;
    grid-template-columns: minmax(56px, 1fr) minmax(0, 2fr) auto;
    align-items: center;
    gap: 10px;
    margin-top: 9px;
}
.rkxt-sf-dash-bar-row:first-of-type { margin-top: 0; }
.rkxt-sf-dash-bar-label {
    font-size: .85rem;
    color: var(--rkxt-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rkxt-sf-dash-bar-track {
    position: relative;
    height: 9px;
    border-radius: 999px;
    background: var(--rkxt-surface-2);
    overflow: hidden;
}
.rkxt-sf-dash-bar-fill {
    position: absolute;
    inset: 0 auto 0 0;
    height: 100%;
    border-radius: 999px;
    transition: width .3s ease;
}
.rkxt-sf-dash-bar-val {
    font-size: .8rem;
    font-variant-numeric: tabular-nums;
    color: var(--rkxt-text);
    white-space: nowrap;
}

.rkxt-sf-dash-top { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--rkxt-border); }
.rkxt-sf-dash-top-title { margin: 0 0 8px; font-size: .95rem; font-weight: 700; color: var(--rkxt-text); }
.rkxt-sf-dash-top-list {
    list-style: none;
    margin: 0;
    padding: 0 6px 0 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: .9rem;
    max-height: 280px;
    overflow-y: auto;
}
.rkxt-sf-cuenta-form {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 24px;
}
.rkxt-sf-cuenta-alt {
    text-align: center;
    margin-top: 20px;
    color: var(--rkxt-text-muted);
}
.rkxt-sf-cuenta-mayorista {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: center;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 24px;
}
.rkxt-sf-cuenta-badge {
    display: inline-block;
    margin-left: 10px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    vertical-align: middle;
}
.rkxt-sf-cuenta-section {
    margin-top: 32px;
    padding-top: 24px;
    border-top: 1px solid var(--rkxt-border);
}
.rkxt-sf-cuenta-section h2 {
    margin-bottom: 8px;
}

/* Cards de navegación de "Mi cuenta" (Mis pedidos / Mis direcciones). */
.rkxt-sf-cuenta-cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-top: 8px;
}
@media (max-width: 520px) {
    .rkxt-sf-cuenta-cards { grid-template-columns: 1fr; }
}
.rkxt-sf-cuenta-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 20px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    text-decoration: none;
    color: var(--rkxt-on-surface);
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.rkxt-sf-cuenta-card:hover {
    border-color: var(--rkxt-primary);
    transform: translateY(-2px);
}
.rkxt-sf-cuenta-card-icon { font-size: 1.6rem; }
.rkxt-sf-cuenta-card-title { font-weight: 700; }
.rkxt-sf-cuenta-card-desc {
    color: var(--rkxt-text-muted);
    font-size: 0.85rem;
}

/* Lista de direcciones guardadas. */
.rkxt-sf-cuenta-dir-list {
    display: grid;
    gap: 14px;
}
.rkxt-sf-cuenta-dir {
    padding: 16px 18px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
}
.rkxt-sf-cuenta-dir-head {
    display: flex;
    align-items: center;
    margin-bottom: 6px;
}
.rkxt-sf-cuenta-dir p { margin: 0 0 12px; }

/* Log / bitácora de auditoría */
.rkxt-log-detalle-btn { padding: 4px 10px; font-size: 0.78rem; }
.rkxt-log-detalle-row > td {
    background: var(--rkxt-bg-alt);
    padding: 0;
}
.rkxt-log-pre {
    margin: 0;
    padding: 12px 16px;
    font-family: var(--rkxt-font-mono, ui-monospace, 'JetBrains Mono', monospace);
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--rkxt-text);
    white-space: pre-wrap;
    word-break: break-word;
    overflow-x: auto;
}

/* ============================================================================
   Dashboard del vendedor — revisión de pedido mayorista contra objetivo.
   (Pedidos/Detalle.razor). Workspace de dos espacios:
     · A = Artículos  (form de ajuste del pedido)
     · B = Indicadores (KPIs + tarjetas con semáforo + barras real-vs-meta)
     · C = Asistente IA (placeholder, junto a Indicadores en la columna lateral)
   En desktop: A a la izquierda fluida, B+C en una columna lateral sticky.
   En mobile (<1100px): se apilan A → B → C.
   Colores del semáforo = vars :root (--rkxt-ok/warn/bad/neutral), inyectadas
   inline desde el helper EstadoColor de C#. Las posiciones (width fill, left meta)
   sí van inline porque son dinámicas por dato.
   ============================================================================ */
.rkxt-dash-workspace {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(340px, 420px);
    gap: 28px;
    align-items: start;
    margin-top: 8px;
}
@media (max-width: 1100px) {
    .rkxt-dash-workspace {
        grid-template-columns: 1fr;
        gap: 4px;
    }
}

.rkxt-dash-space { min-width: 0; }

/* La columna lateral (Indicadores + IA) sigue al scroll mientras se revisan los ítems. */
.rkxt-dash-space-side {
    display: flex;
    flex-direction: column;
    gap: 20px;
    position: sticky;
    top: 16px;
}
@media (max-width: 1100px) {
    .rkxt-dash-space-side { position: static; }
}

/* La 1ª section de cada espacio ya trae el margin-top del .rkxt-admin-section-title;
   lo anulamos para que el título quede alineado con el tope del espacio vecino. */
.rkxt-dash-space > .rkxt-admin-section-title:first-child,
.rkxt-dash-panel > .rkxt-admin-section-title:first-child {
    margin-top: 0;
}

/* Panel contenedor de Indicadores (tarjeta envolvente para separarlo de Artículos). */
.rkxt-dash-panel {
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 18px 20px;
}

/* Fila de cantidad del "+ Agregar al pedido" (antes width inline). */
.rkxt-dash-add-cant { max-width: 110px; }

/* ---- KPIs (piezas / monto) ---- */
.rkxt-dash-kpis {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin: 4px 0 18px;
}
.rkxt-dash-kpi {
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 12px 14px;
}
.rkxt-dash-kpi-label {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--rkxt-text-dim);
}
.rkxt-dash-kpi-val {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--rkxt-text);
}

/* ---- Tarjetas de indicador ---- */
.rkxt-dash-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.rkxt-dash-card {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    padding: 13px 15px;
}
.rkxt-dash-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    font-size: 0.95rem;
}
.rkxt-dash-dot {
    width: 10px;
    height: 10px;
    border-radius: 999px;
    flex: 0 0 auto;
    background: var(--rkxt-neutral);   /* fallback; el tono real llega inline */
}
.rkxt-dash-escalar {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    font-size: 0.9rem;
    margin-bottom: 8px;
}

/* ---- Barras real-vs-meta (track + fill + marcador de meta) ---- */
.rkxt-dash-bar-track {
    position: relative;
    height: 8px;
    border-radius: 999px;
    background: var(--rkxt-surface-2);
    overflow: hidden;
}
.rkxt-dash-bar-fill {
    position: absolute;
    inset: 0 auto 0 0;
    height: 100%;
    border-radius: 999px;
    background: var(--rkxt-neutral);   /* el tono real llega inline (width + background) */
    transition: width 0.3s ease;
}
/* Marcador vertical de la meta sobre la barra. `left` llega inline (posición dinámica).
   `overflow:hidden` del track lo recortaría → se renderiza fuera del track con su propio
   contenedor de fila; por eso vive como hijo del track pero con z-index y sin clip propio. */
.rkxt-dash-bar-meta {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: var(--rkxt-text);
    opacity: 0.55;
    border-radius: 2px;
    pointer-events: none;
}
.rkxt-dash-bar-row {
    display: grid;
    grid-template-columns: minmax(60px, 1fr) minmax(0, 2fr) auto;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}
.rkxt-dash-bar-row:first-of-type { margin-top: 0; }
.rkxt-dash-bar-label {
    font-size: 0.85rem;
    color: var(--rkxt-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* La barra-track dentro de una fila no necesita clip extra; el meta marker se ve completo. */
.rkxt-dash-bar-row .rkxt-dash-bar-track { overflow: visible; }
.rkxt-dash-bar-row .rkxt-dash-bar-fill { overflow: hidden; }
.rkxt-dash-bar-val {
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--rkxt-text);
    white-space: nowrap;
}

/* ---- Bloques informativos (más pedido / por tipología / no pidió) ---- */
.rkxt-dash-info {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 18px;
}
.rkxt-dash-info-block {
    border-top: 1px solid var(--rkxt-border);
    padding-top: 12px;
}
.rkxt-dash-info-title {
    margin: 0 0 6px;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--rkxt-text-dim);
}
.rkxt-dash-info-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.88rem;
}

/* ---- Espacio C — Asistente IA (placeholder no funcional) ---- */
.rkxt-dash-ia {
    border: 1px dashed color-mix(in srgb, var(--rkxt-primary) 30%, var(--rkxt-border));
    border-radius: var(--rkxt-radius);
    padding: 16px 18px;
    background:
        radial-gradient(420px 200px at 90% -40px, rgba(124, 58, 237, 0.06), transparent 70%),
        var(--rkxt-surface);
}
.rkxt-dash-ia-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}
.rkxt-dash-ia-icon { font-size: 1.05rem; line-height: 1; }
.rkxt-dash-ia-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
}
.rkxt-dash-ia-soon {
    margin-left: auto;
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--rkxt-text-dim);
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    padding: 2px 8px;
    border-radius: 999px;
}
.rkxt-dash-ia-lead {
    margin: 0 0 10px;
    font-size: 0.85rem;
    color: var(--rkxt-text-muted);
}
.rkxt-dash-ia-input {
    resize: vertical;
    margin-bottom: 10px;
    opacity: 0.7;
    cursor: not-allowed;
}
.rkxt-dash-ia-btn {
    width: 100%;
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
}

/* ===== Dashboard del pedido (rediseño full-width: KPIs + secciones + cliente + IA) ===== */
.rkxt-dash-toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 4px 0 18px; }
/* Bloque de confirmación de acciones de pedido (Anular / Desechar / Duplicar / Eliminar). */
.rkxt-confirm-box {
    margin: 0 0 20px;
    padding: 16px 18px;
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-left: 4px solid var(--rkxt-warn);
    border-radius: var(--rkxt-radius-sm, 8px);
}
.rkxt-confirm-box-danger {
    background: var(--rkxt-bad-soft);
    border-left-color: var(--rkxt-bad);
}
.rkxt-confirm-box-ok {
    background: var(--rkxt-ok-soft);
    border-left-color: var(--rkxt-ok);
}
.rkxt-confirm-title { display: block; margin: 0 0 4px; font-size: 1.02rem; }
.rkxt-confirm-lead { margin: 0 0 12px; color: var(--rkxt-text-muted); }
/* Lista de impacto dentro de una caja de confirmación ("N clientes / N artículos / N pedidos"). */
.rkxt-confirm-list { margin: 4px 0 12px; padding-left: 20px; }
.rkxt-confirm-list li { margin: 2px 0; }
/* Utilitario: celda de acciones en una sola línea (Editar + Eliminar). */
.rkxt-nowrap { white-space: nowrap; }
/* Zona Peligrosa — bloque con acento de peligro + filas de radio. */
.rkxt-danger-block { border-left: 4px solid var(--rkxt-bad); }
.rkxt-radio-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 6px 0;
    cursor: pointer;
}
.rkxt-radio-row input { margin: 0; }
/* F9_M024 — oculta los forms de confirmación (siempre en el árbol para que el handler exista en el POST) hasta abrirse. */
.rkxt-hidden { display: none !important; }
.rkxt-dash-block {
    margin: 0 0 26px;
    padding: 18px 20px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-sf-radius, 12px);
}
.rkxt-dash-cliente { border-left: 4px solid var(--rkxt-primary); }
.rkxt-text-accent { color: var(--rkxt-primary); }

/* Tiles de KPI a lo ancho */
.rkxt-kpi-row { display: flex; flex-wrap: wrap; gap: 12px; }
.rkxt-kpi {
    flex: 1 1 130px;
    min-width: 120px;
    display: flex; flex-direction: column; gap: 4px;
    padding: 12px 14px;
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-radius: 10px;
}
.rkxt-kpi-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--rkxt-text-muted); }
.rkxt-kpi-val { font-size: 1.5rem; font-weight: 700; line-height: 1.1; }

/* Columnas de distribución (marca / talle / categoría / cliente) */
.rkxt-dash-dist-cols { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 18px; margin-top: 8px; }
@media (max-width: 900px) { .rkxt-dash-dist-cols { grid-template-columns: 1fr; } }
.rkxt-dash-dist { min-width: 0; }

/* Panel del Asistente IA — full width, cómodo */
.rkxt-ia-full { }
.rkxt-ia-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.rkxt-ia-icon { font-size: 1.2rem; line-height: 1; }
.rkxt-ia-box { display: flex; flex-direction: column; gap: 10px; }
.rkxt-ia-respuesta {
    background: var(--rkxt-surface-2);
    border: 1px solid var(--rkxt-border);
    border-radius: 10px;
    padding: 14px 16px;
    white-space: pre-wrap;
    line-height: 1.5;
    min-height: 48px;
}
.rkxt-ia-input-row { display: flex; gap: 10px; align-items: flex-start; }
.rkxt-ia-input { flex: 1; resize: vertical; }
.rkxt-ia-mic {
    flex: 0 0 auto;
    width: 48px; height: 48px;
    border-radius: 50%;
    border: 1px solid var(--rkxt-border);
    background: var(--rkxt-surface-2);
    font-size: 1.25rem; cursor: pointer;
    transition: background .15s, transform .15s;
}
.rkxt-ia-mic:hover { background: var(--rkxt-bg-alt); }
.rkxt-ia-mic--on { background: var(--rkxt-bad, #dc2626); color: #fff; animation: rkxt-ia-pulse 1s infinite; }
@keyframes rkxt-ia-pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
.rkxt-ia-actions { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.rkxt-ia-voz-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: .9rem; color: var(--rkxt-text-muted); cursor: pointer; }
.rkxt-ia-send { min-width: 130px; }

/* ===== Editar pedido = catálogo en el Admin (Fase 2, rediseño 2026-07-23) =====
   Antes: 3 bandas full-width apiladas (KPIs → filtros → carga por curva) empujaban la tabla
   fuera del viewport. Ahora: UNA sola cabecera sticky de 2 columnas —
     izquierda (.rkxt-ed-cab-kpis, angosta)  = indicadores + donut de marcas
     derecha  (.rkxt-ed-cab-main, ancha)     = filtros (fila + "Más filtros") + carga (curva/cantidad)
   El wrapper .rkxt-ed-cabecera SUMA la clase .rkxt-filterbar → hereda sticky (top: var(--rkxt-
   adminhdr-h), z-index:20, fondo opaco) del patrón genérico del admin, y el JS de AdminLayout.razor
   (que mide ".rkxt-admin-content .rkxt-filterbar" con ResizeObserver) mide el bloque COMPLETO
   automáticamente — no hace falta tocar el JS. thead sticky queda pegado justo debajo (--rkxt-
   theadtop = alto header + alto de este bloque). La clase .rkxt-filterbar va en el WRAPPER, no en
   el <form method=get> interno (que ahora es solo .rkxt-ed-filtros, sin sticky propio). */
.rkxt-ed-cabecera.rkxt-filterbar {
    display: grid;
    grid-template-columns: minmax(200px, 240px) minmax(0, 1fr);
    align-items: stretch;
    gap: 18px;
    padding: 12px 0 14px;
}
.rkxt-ed-cab-kpis {
    display: flex; flex-direction: column; gap: 10px;
    padding-right: 16px; border-right: 1px solid var(--rkxt-border-soft);
    min-width: 0;
}
.rkxt-ed-cab-main { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.rkxt-ed-cab-section-label {
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--rkxt-text-dim); margin: 0;
}
@media (max-width: 1100px) {
    .rkxt-ed-cabecera.rkxt-filterbar { grid-template-columns: 1fr; }
    .rkxt-ed-cab-kpis {
        flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: 14px 26px;
        padding-right: 0; padding-bottom: 10px;
        border-right: none; border-bottom: 1px solid var(--rkxt-border-soft);
    }
    .rkxt-ed-cab-kpis .rkxt-ed-kpi { min-width: 150px; }
    .rkxt-ed-cab-kpis .rkxt-ed-pie { flex: 1 1 220px; }
}

/* Indicadores achicados (menos renglones, menos alto): la barra vs-objetivo pasa de 8px a 4px,
   valores en una sola línea con la etiqueta, donut de 92px a 60px. Todas estas reglas son propias
   de esta pantalla (prefijo rkxt-ed-*, sin otros consumidores) salvo rkxt-kpi-label/val que SÍ se
   reusan en otras pantallas (Dashboard, Detalle, Analytics) — por eso el tamaño de fuente se pisa
   scopeado a .rkxt-ed-cab-kpis, nunca en la regla base. */
.rkxt-ed-kpi { display: flex; flex-direction: column; gap: 2px; }
.rkxt-ed-cab-kpis .rkxt-kpi-label { font-size: .68rem; }
.rkxt-ed-cab-kpis .rkxt-kpi-val { font-size: 1.15rem; font-weight: 700; }
.rkxt-ed-vs { font-size: .74rem; }
.rkxt-ed-cab-kpis .rkxt-dash-bar-track { height: 4px; border-radius: 4px; background: var(--rkxt-bg-alt); overflow: hidden; margin-top: 4px; }
.rkxt-ed-cab-kpis .rkxt-dash-bar-fill { height: 100%; }
.rkxt-ed-pie { display: flex; flex-direction: column; gap: 2px; }
.rkxt-ed-pie-row { display: flex; align-items: center; gap: 10px; margin-top: 2px; }
.rkxt-ed-cab-kpis .rkxt-ed-donut { width: 60px; height: 60px; transform: rotate(-90deg); flex: 0 0 auto; }
.rkxt-ed-cab-kpis .rkxt-ed-pie-leg { font-size: .72rem; gap: 2px; }
.rkxt-ed-pie-leg { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.rkxt-ed-pie-leg li { display: flex; align-items: center; gap: 6px; }
.rkxt-ed-pie-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* Catálogo de 2.888 SKUs detrás → los filtros crecieron de 3 a 7 campos. Para no saturar la fila
   principal, .rkxt-ed-filtros pasa a columna: fila 1 = lo de siempre (modo/buscar/marca/cat, ahora
   con la 3ra opción "Con cantidad"), fila 2 = <details> "Más filtros" con Talle/Color/Precio/Stock
   (ver bloque de abajo). El <form method=get> YA NO carga la clase .rkxt-filterbar — el sticky +
   fondo + borde ahora vive en el wrapper .rkxt-ed-cabecera (ver arriba), este form es un simple
   hijo de .rkxt-ed-cab-main. */
.rkxt-ed-filtros { display: flex; flex-direction: column; gap: 10px; }
.rkxt-ed-filtros-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.rkxt-ed-modo { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.rkxt-ed-q { max-width: 280px; }

/* --- "Más filtros": panel colapsable con Talle / Color / Precio / Stock. --- */
.rkxt-ed-masfiltros {
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-bg-alt);
}
.rkxt-ed-masfiltros-toggle {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 14px; cursor: pointer; list-style: none;
    font-size: .85rem; font-weight: 700; color: var(--rkxt-text-muted); user-select: none;
}
.rkxt-ed-masfiltros-toggle::-webkit-details-marker { display: none; }
.rkxt-ed-masfiltros-toggle::marker { display: none; }
.rkxt-ed-masfiltros-toggle:hover { color: var(--rkxt-text); }
.rkxt-ed-masfiltros-chevron { transition: transform .18s ease; color: var(--rkxt-text-dim); }
.rkxt-ed-masfiltros[open] > .rkxt-ed-masfiltros-toggle .rkxt-ed-masfiltros-chevron { transform: rotate(180deg); }
/* Badge con la cantidad de filtros avanzados activos (Talle+Color+Precio+Stock), para que el
   vendedor sepa que hay algo tildado sin tener que abrir el panel. Ocultar con display:none
   desde el .razor cuando el contador es 0. */
.rkxt-ed-masfiltros-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-primary); color: var(--rkxt-fg-on-primary);
    font-size: .68rem; font-weight: 700;
}
.rkxt-ed-masfiltros-panel {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 16px;
    padding: 4px 14px 14px;
}
.rkxt-ed-masfiltros-group { min-width: 0; }
.rkxt-ed-masfiltros-label {
    display: block; margin: 0 0 6px; font-size: .72rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em; color: var(--rkxt-text-dim);
}
.rkxt-ed-masfiltros-actions {
    grid-column: 1 / -1; display: flex; justify-content: flex-end; align-items: center; gap: 10px;
    padding-top: 10px; margin-top: 2px; border-top: 1px solid var(--rkxt-border-soft);
}

/* Grupo de chips (checkboxes disfrazados de pill) — Talle agrupado por escala, Color con swatch.
   Reusa .rkxt-color-chip como base del punto de color donde aplica. */
.rkxt-ed-chipgroup {
    display: flex; flex-direction: column; gap: 8px;
    max-height: 190px; overflow-y: auto; padding-right: 4px;
}
.rkxt-ed-chipgroup-scale {
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--rkxt-text-dim); margin: 4px 0 -2px;
}
.rkxt-ed-chipgroup-scale:first-child { margin-top: 0; }
.rkxt-ed-chiprow { display: flex; flex-wrap: wrap; gap: 6px; }
.rkxt-ed-chip {
    position: relative;
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px; border: 1px solid var(--rkxt-border); border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-surface); font-size: .82rem; color: var(--rkxt-text);
    cursor: pointer; user-select: none; transition: border-color .15s, background .15s, color .15s;
}
.rkxt-ed-chip:hover { border-color: var(--rkxt-primary); }
.rkxt-ed-chip:has(input:checked) {
    border-color: var(--rkxt-primary); background: var(--rkxt-primary-soft); color: var(--rkxt-primary); font-weight: 600;
}
.rkxt-ed-chip:has(input:focus-visible) { outline: 2px solid var(--rkxt-primary); outline-offset: 2px; }
.rkxt-ed-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.rkxt-ed-chip-swatch {
    width: 13px; height: 13px; border-radius: 4px; border: 1px solid var(--rkxt-border);
    flex: 0 0 auto;
}

/* Rango de precio (min–max) — dos inputs numéricos cortos. */
.rkxt-ed-rangoprecio { display: flex; align-items: center; gap: 8px; }
.rkxt-ed-rangoprecio input { width: 100px; }
.rkxt-ed-rangoprecio span { color: var(--rkxt-text-dim); font-size: .8rem; }

/* Filtro de stock: reusa .rkxt-input (select) — sin clase propia, ver skeleton. */
.rkxt-ed-tabla td { vertical-align: middle; }
.rkxt-ed-prod td { border-top: 2px solid var(--rkxt-border); background: var(--rkxt-surface-2); }
.rkxt-ed-prodvar td { background: var(--rkxt-surface-2); }   /* sub-filas de variante: mismo fondo, sin separador */
.rkxt-ed-tabla .rkxt-ed-prodcell { vertical-align: top; }
.rkxt-ed-prod .rkxt-badge { margin-left: 0; }
.rkxt-ed-cant { max-width: 110px; }
/* Item 5 — renglón que modificó el CLIENTE (el vendedor lo ve resaltado). Pisa el fondo surface-2. */
.rkxt-ed-row--modc td { background: #FEF6DC !important; }
.rkxt-ed-badge-modc {
    display: inline-block; margin-left: .4rem; font-size: .68rem; font-weight: 700;
    color: #92400E; background: #FDE68A; padding: .06rem .42rem; border-radius: 6px;
    vertical-align: middle; letter-spacing: .01em;
}
.rkxt-ed-precio { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 600; }
/* Bloque producto: miniatura (aprovecha el rowspan) + datos */
.rkxt-ed-prodinfo { display: flex; gap: 12px; align-items: flex-start; padding: 4px 0; }
.rkxt-ed-thumb {
    flex: 0 0 auto; width: 64px; height: 84px; border-radius: 8px;
    background-color: var(--rkxt-bg-alt); background-size: cover; background-position: center; background-repeat: no-repeat;
    border: 1px solid var(--rkxt-border);
    display: flex; align-items: center; justify-content: center; font-size: 1.4rem; color: var(--rkxt-text-muted);
}
.rkxt-ed-proddata { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rkxt-ed-proddata code { font-size: .8rem; }
.rkxt-ed-proddata .rkxt-badge { align-self: flex-start; }
.rkxt-ed-paginador { display: flex; align-items: center; gap: 14px; margin: 14px 0; }
.rkxt-ed-aplicar { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.rkxt-ed-restaurar { margin-top: 14px; }

/* --- Banner "generación masiva" (pedido = plantilla para N clientes). Mismo patrón visual que
   Admin/Crm/Objetivos/Agente.razor (.rkxt-callout.rkxt-callout-primary), con estructura propia
   en vez de layout inline: acá el botón va en un <EditForm method="post"> (esta pantalla es SSR,
   sin @rendermode InteractiveServer como Agente.razor — no hay @onclick de verdad, es un submit). */
.rkxt-ed-masivo-banner {
    display: flex; justify-content: space-between; align-items: center;
    gap: 14px; flex-wrap: wrap; margin-bottom: 16px;
}
.rkxt-ed-masivo-banner strong { color: var(--rkxt-text); }
.rkxt-ed-masivo-banner-lead { display: block; margin-top: 2px; font-size: .82rem; }

/* --- Carga por curva: panel con las DOS formas de cargar el pedido, una al lado de la otra, para
   que el vendedor entienda de un vistazo que son alternativas (no pasos secuenciales). Izquierda
   = acción potente (llena todo el rango filtrado de una sola vez); derecha = recordatorio de que
   la tabla de abajo sigue siendo edición manual por SKU. El submit de "Aplicar" ya recibe feedback
   del loader global del admin (rkxt-admin-navloader.js, barra de progreso arriba en todo submit
   dentro de .rkxt-admin) — sumale confirm() porque sobreescribe muchos renglones de una, mismo
   criterio que "↺ Restaurar pedido original" en este mismo archivo. */
.rkxt-ed-curva-panel {
    display: flex; align-items: stretch; gap: 18px;
    margin: 4px 0 18px; padding: 16px 18px;
    background: var(--rkxt-surface); border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius); box-shadow: var(--rkxt-shadow-sm);
}
@media (max-width: 760px) { .rkxt-ed-curva-panel { flex-direction: column; } }
.rkxt-ed-curva-mode { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; justify-content: center; }
.rkxt-ed-curva-mode-head { display: flex; align-items: flex-start; gap: 10px; }
.rkxt-ed-curva-icon {
    flex: 0 0 auto; width: 34px; height: 34px; border-radius: var(--rkxt-radius-sm);
    display: flex; align-items: center; justify-content: center; font-size: 1.05rem;
    background: var(--rkxt-primary-soft);
}
.rkxt-ed-curva-mode-head strong { display: block; font-size: .95rem; }
.rkxt-ed-curva-mode-head .rkxt-text-muted { font-size: .8rem; }
.rkxt-ed-curva-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin-top: 2px; }
.rkxt-ed-curva-form input[type=number] { width: 90px; }
.rkxt-ed-curva-form .rkxt-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; transform: none; }
.rkxt-ed-curva-hint { margin: 2px 0 0; font-size: .78rem; color: var(--rkxt-text-muted); }
/* Separador "o" entre los dos modos — línea vertical en desktop, horizontal en mobile. */
.rkxt-ed-curva-divider {
    flex: 0 0 auto; position: relative; width: 1px; background: var(--rkxt-border-soft);
}
.rkxt-ed-curva-divider span {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    background: var(--rkxt-surface); padding: 4px 0;
    font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--rkxt-text-dim);
}
@media (max-width: 760px) {
    .rkxt-ed-curva-divider { width: auto; height: 1px; margin: 2px 0; }
    .rkxt-ed-curva-divider span { padding: 0 8px; }
}

/* --- Panel de curva DENTRO de .rkxt-ed-cab-main (rediseño 2026-07-23): ya no es una banda
   full-width propia, vive apilado debajo del form de filtros en la columna derecha de la cabecera
   sticky. Fondo crema (mismo tono que .rkxt-ed-masfiltros) para que ambos sub-paneles de la
   columna derecha (filtros avanzados + carga) lean como un mismo grupo visual, y padding/gap
   reducidos para bajar el alto total del bloque sticky. El lado "Carga por cantidad" no tiene
   controles (solo texto explicativo) → se le da menos ancho para no desperdiciar espacio. */
.rkxt-ed-cab-main .rkxt-ed-curva-panel {
    margin: 0; padding: 12px 14px; gap: 14px;
    background: var(--rkxt-bg-alt); border: 1px solid var(--rkxt-border); box-shadow: none;
    border-radius: var(--rkxt-radius-sm);
}
.rkxt-ed-cab-main .rkxt-ed-curva-mode { gap: 6px; }
.rkxt-ed-cab-main .rkxt-ed-curva-mode--manual { flex: 0 1 190px; }
.rkxt-ed-cab-main .rkxt-ed-curva-icon { width: 28px; height: 28px; font-size: .95rem; }
.rkxt-ed-cab-main .rkxt-ed-curva-mode-head strong { font-size: .85rem; }
.rkxt-ed-cab-main .rkxt-ed-curva-mode-head .rkxt-text-muted { font-size: .74rem; }
.rkxt-ed-cab-main .rkxt-ed-curva-form { gap: 8px; margin-top: 0; }
.rkxt-ed-cab-main .rkxt-ed-curva-form input[type=number] { width: 76px; }
.rkxt-ed-cab-main .rkxt-ed-curva-hint { font-size: .7rem; margin-top: 2px; }

/* ---- Editar objetivo: bloques de indicador + fila "agregar indicador" ---- */
.rkxt-ind-bloque { margin-bottom: 16px; }
.rkxt-ind-bloque-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
}
.rkxt-ind-add {
    display: flex;
    gap: 8px;
    align-items: flex-end;
    margin-top: 8px;
}
.rkxt-ind-add-field { margin: 0; flex: 1; }

/* Carga rápida mayorista — buscador + feedback de límite de stock (F11.x) */
.rkxt-sf-qo-search {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 12px;
    flex-wrap: wrap;
}
.rkxt-sf-qo-search-input {
    flex: 1 1 280px;
    max-width: 460px;
}
.rkxt-sf-qo-search-clear {
    color: var(--rkxt-text-muted);
    font-size: 0.85rem;
    text-decoration: underline;
}
.rkxt-sf-qo-search-clear:hover { color: var(--rkxt-primary); }
.rkxt-sf-qo-input--clamped {
    border-color: var(--rkxt-warn) !important;
    box-shadow: 0 0 0 2px var(--rkxt-warn-soft);
    transition: border-color .2s, box-shadow .2s;
}

/* Paginación del catálogo storefront */
.rkxt-sf-pag {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin: 28px 0 8px;
    flex-wrap: wrap;
}
.rkxt-sf-pag-info { color: var(--rkxt-text-muted); font-size: 0.95rem; }
.rkxt-sf-pag-off { opacity: .45; pointer-events: none; }

/* Barra de progreso al confirmar el pedido mayorista (overlay) */
.rkxt-qo-overlay {
    position: fixed; inset: 0; z-index: 9999;
    background: rgba(0,0,0,.45);
    display: flex; align-items: center; justify-content: center;
}
/* El display:flex de arriba le gana al display:none implícito del atributo hidden → re-afirmarlo. */
.rkxt-qo-overlay[hidden] { display: none; }
.rkxt-qo-overlay-box {
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    padding: 26px 30px; max-width: 340px; text-align: center;
    box-shadow: 0 18px 50px rgba(0,0,0,.25);
}
.rkxt-qo-overlay-bar {
    height: 6px; border-radius: 999px;
    background: var(--rkxt-bg-alt); overflow: hidden; position: relative;
}
.rkxt-qo-overlay-bar span {
    position: absolute; top: 0; height: 100%; width: 40%; border-radius: 999px;
    background: var(--rkxt-primary); animation: rkxt-qo-bar 1.1s ease-in-out infinite;
}
@keyframes rkxt-qo-bar { 0% { left: -42%; } 100% { left: 100%; } }
.rkxt-qo-overlay-text { margin: 14px 0 0; color: var(--rkxt-text); font-size: 0.95rem; }

/* Acordeón Cliente+entrega en el detalle de pedido (gana espacio para el vendedor) */
.rkxt-pedido-acc {
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    margin-bottom: 16px;
    background: var(--rkxt-surface);
}
.rkxt-pedido-acc-summary {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; padding: 12px 16px; cursor: pointer; list-style: none;
}
.rkxt-pedido-acc-summary::-webkit-details-marker { display: none; }
.rkxt-pedido-acc-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rkxt-pedido-acc-label {
    color: var(--rkxt-text-muted); font-size: .8rem;
    text-transform: uppercase; letter-spacing: .04em;
}
.rkxt-pedido-acc-cliente { color: var(--rkxt-text); font-size: 1.05rem; }
.rkxt-pedido-acc-chevron { color: var(--rkxt-text-muted); transition: transform .2s; }
.rkxt-pedido-acc[open] .rkxt-pedido-acc-chevron { transform: rotate(180deg); }
.rkxt-pedido-acc-body { padding: 0 16px 12px; }
.rkxt-pedido-acc-body .rkxt-admin-section-title:first-child { margin-top: 4px; }

/* Toast flotante de confirmación al guardar (rkxt-form-scroll.js): aparece donde esté el scroll,
   así el usuario ve "Guardado" sin que la página tenga que saltar al top. */
.rkxt-toast {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 9999;
    max-width: 360px;
    padding: 12px 18px;
    border-radius: var(--rkxt-radius, 12px);
    box-shadow: 0 8px 28px rgba(0, 0, 0, .20);
    font-weight: 600;
    line-height: 1.35;
    color: #fff;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity .25s ease, transform .25s ease;
}
.rkxt-toast.rkxt-toast-show { opacity: 1; transform: translateY(0); }
.rkxt-toast-ok { background: var(--rkxt-ok, #16a34a); }
@media (max-width: 560px) {
    .rkxt-toast { left: 16px; right: 16px; max-width: none; }
}

/* =============================================================
   Mensajería directa vendedor ↔ cliente por pedido
   Reutilizable en Admin (Detalle de pedido) y Storefront (Mis mensajes).
   Burbujas: vendedor SIEMPRE a la izquierda (neutra), cliente SIEMPRE a la
   derecha (acento naranja tenue) — el lado no depende de quién mira.
   ============================================================= */

.rkxt-msg-thread {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 420px;
    overflow-y: auto;
    padding: 16px;
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    scroll-behavior: smooth;
}

.rkxt-msg-thread-empty {
    margin: auto;
    text-align: center;
    color: var(--rkxt-text-muted);
    font-size: 0.92rem;
    line-height: 1.5;
    padding: 28px 12px;
}

.rkxt-msg-bubble {
    max-width: 78%;
    padding: 10px 14px 8px;
    border-radius: var(--rkxt-radius);
    border: 1px solid var(--rkxt-border);
    background: var(--rkxt-surface);
    box-shadow: var(--rkxt-shadow-sm);
    position: relative;
}

.rkxt-msg-bubble--vendedor {
    align-self: flex-start;
    border-bottom-left-radius: 4px;
}

.rkxt-msg-bubble--cliente {
    align-self: flex-end;
    background: var(--rkxt-primary-soft);
    border-color: color-mix(in srgb, var(--rkxt-primary) 25%, var(--rkxt-border));
    border-bottom-right-radius: 4px;
}

.rkxt-msg-autor {
    display: block;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--rkxt-text-dim);
    margin-bottom: 3px;
}

.rkxt-msg-bubble--cliente .rkxt-msg-autor { color: var(--rkxt-primary-hover); }

.rkxt-msg-cuerpo {
    margin: 0;
    color: var(--rkxt-text);
    font-size: 0.93rem;
    line-height: 1.42;
    white-space: pre-wrap;
    word-break: break-word;
}

.rkxt-msg-hora {
    display: block;
    margin-top: 4px;
    font-size: 0.7rem;
    color: var(--rkxt-text-dim);
    text-align: right;
}

.rkxt-msg-bubble--vendedor .rkxt-msg-hora { text-align: left; }

.rkxt-msg-nuevo-tag {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    vertical-align: middle;
}

/* Marca sutil de "no leído": halo + punto naranja, visible sin hover */
.rkxt-msg-nuevo {
    box-shadow: 0 0 0 2px rgba(235, 82, 2, 0.18), var(--rkxt-shadow-sm);
}
.rkxt-msg-nuevo::after {
    content: "";
    position: absolute;
    top: 10px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--rkxt-primary);
}
.rkxt-msg-bubble--vendedor.rkxt-msg-nuevo::after { left: -4px; }
.rkxt-msg-bubble--cliente.rkxt-msg-nuevo::after { right: -4px; }

/* Caja de envío (form plano + textarea + botón) */
.rkxt-msg-form {
    display: flex;
    gap: 10px;
    align-items: flex-end;
    margin-top: 14px;
}
.rkxt-msg-form textarea.rkxt-input {
    resize: vertical;
    min-height: 64px;
}
.rkxt-msg-form .rkxt-btn { flex-shrink: 0; }

/* Cabecera de la página de hilo (número + estado a la izq, link proforma a la der) */
.rkxt-msg-hilo-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}
.rkxt-msg-hilo-head h1 { margin: 0 0 4px; display: inline-flex; align-items: center; gap: 10px; }

/* Buzón "Mis mensajes": 1 fila por conversación/pedido */
.rkxt-msg-convlist {
    display: grid;
    gap: 12px;
}
.rkxt-msg-conv-row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "main meta" "preview preview";
    gap: 4px 12px;
    padding: 16px 18px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    text-decoration: none;
    color: var(--rkxt-on-surface);
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.rkxt-msg-conv-row:hover {
    border-color: var(--rkxt-primary);
    transform: translateY(-1px);
}
.rkxt-msg-conv-main {
    grid-area: main;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.rkxt-msg-conv-main code { font-weight: 700; }
.rkxt-msg-conv-preview {
    grid-area: preview;
    margin: 2px 0 0;
    color: var(--rkxt-text-muted);
    font-size: 0.88rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rkxt-msg-conv-meta {
    grid-area: meta;
    display: flex;
    align-items: center;
    gap: 8px;
    justify-self: end;
}
.rkxt-msg-conv-fecha {
    font-size: 0.78rem;
    color: var(--rkxt-text-dim);
    white-space: nowrap;
}
.rkxt-msg-conv-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    font-size: 0.72rem;
    font-weight: 700;
    white-space: nowrap;
}

/* Card "Mis mensajes" en Mi cuenta con badge de no-leídos superpuesto */
.rkxt-sf-cuenta-card-msg { position: relative; }
.rkxt-sf-cuenta-card-msg-badge {
    position: absolute;
    top: 12px;
    right: 12px;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
    font-size: 0.68rem;
    font-weight: 800;
    border-radius: var(--rkxt-radius-pill);
    box-shadow: 0 2px 6px rgba(235, 82, 2, 0.35);
}

/* Mobile-first: 360px mínimo */
@media (max-width: 480px) {
    .rkxt-msg-thread { max-height: 340px; padding: 12px; }
    .rkxt-msg-bubble { max-width: 88%; }
    .rkxt-msg-form { flex-direction: column; align-items: stretch; }
    .rkxt-msg-conv-row { grid-template-columns: 1fr; grid-template-areas: "main" "preview" "meta"; }
    .rkxt-msg-conv-meta { justify-self: start; }
    .rkxt-msg-hilo-head { flex-direction: column; align-items: flex-start; }
}

/* =============================================================
   Loader de navegación del admin — barra de progreso fina fija arriba
   (estilo YouTube/GitHub). Creada dinámicamente por rkxt-admin-navloader.js
   y agregada a document.body: NO tiene markup propio en ningún .razor.
   Se muestra al clickear cualquier link `/admin/*` o al submitear un form
   del admin (enhanced navigation SSR no dispara el spinner nativo del
   navegador, así que sin esto la pantalla parece congelada mientras carga
   el detalle de pedidos u otras pantallas con queries pesadas).
   ============================================================= */
.rkxt-admin-navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 100000; /* por encima del header/thead sticky del admin */
    pointer-events: none;
    overflow: hidden;
    background: transparent;
    opacity: 0;
    transition: opacity 0.15s ease;
}
.rkxt-admin-navbar.is-active { opacity: 1; }
.rkxt-admin-navbar span {
    position: absolute;
    top: 0;
    left: -40%;
    height: 100%;
    width: 35%;
    border-radius: 0 999px 999px 0;
    background: var(--rkxt-grad-primary, var(--rkxt-primary));
    box-shadow: 0 0 8px 1px rgba(235, 82, 2, 0.55);
}
.rkxt-admin-navbar.is-active span {
    animation: rkxt-admin-navbar-sweep 1.05s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes rkxt-admin-navbar-sweep {
    0% { left: -40%; width: 35%; }
    55% { left: 40%; width: 45%; }
    100% { left: 100%; width: 35%; }
}
@media (prefers-reduced-motion: reduce) {
    .rkxt-admin-navbar span { animation: none; left: 0; width: 100%; opacity: 0.65; }
}

/* =============================================================
   Pedidos masivos — multi-selección de clientes + job bulk que
   sobrevive navegación (Clientes → "Generar pedidos").
   3 piezas:
     1. .rkxt-bulk-selectbar   — barra sticky que aparece con ≥1 marcado
                                  en cualquier listado con checkbox de selección
                                  (hoy: /admin/crm/clientes). Reusa el mismo
                                  slot sticky que .rkxt-sticky-toolbar (el JS
                                  de AdminLayout ya mide su altura con
                                  ResizeObserver — con hidden="" el alto pasa
                                  a 0 y el thead de la tabla se re-acomoda solo,
                                  sin tocar el script).
     2. .rkxt-bulkjob-steps    — lista colapsable "detalle por cliente" en la
                                  pantalla de progreso de un job bulk. Se usa
                                  DEBAJO de <RkxtBulkProgress> (que ya cubre
                                  título/fase/ítem actual/contadores/barra —
                                  ver Components/Shared/RkxtBulkProgress.razor).
     3. .rkxt-bulkjob-pill     — indicador flotante persistente (isla
                                  InteractiveServer montada en AdminLayout,
                                  mismo patrón previsto para el futuro FAB de
                                  Raku — CLAUDE.md ETAPA 2). Bottom-LEFT a
                                  propósito: se reserva bottom-right para Raku.
   ============================================================= */

/* 1. Barra de selección bulk. Compone con .rkxt-sticky-toolbar en el mismo
   elemento (<div class="rkxt-sticky-toolbar rkxt-bulk-selectbar" hidden="@(_sel.Count==0)">)
   para heredar el position:sticky + la medición automática por ResizeObserver;
   acá solo se pisan look (fondo/borde primary) y espaciado. Declarada DESPUÉS
   de .rkxt-sticky-toolbar en el archivo → gana por orden de cascada sin !important. */
.rkxt-bulk-selectbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    background: var(--rkxt-primary-soft);
    border: 1px solid color-mix(in srgb, var(--rkxt-primary) 30%, var(--rkxt-border));
    border-radius: var(--rkxt-radius-sm);
    padding: 10px 16px;
    margin-bottom: 14px;
}
.rkxt-bulk-selectbar[hidden] { display: none; }

.rkxt-bulk-selectbar-count {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--rkxt-text);
}
.rkxt-bulk-selectbar-count strong {
    color: var(--rkxt-primary);
    font-size: 1.05rem;
    margin-right: 4px;
}

.rkxt-bulk-selectbar-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

@media (max-width: 680px) {
    .rkxt-bulk-selectbar { justify-content: flex-start; }
    .rkxt-bulk-selectbar-actions { width: 100%; }
    .rkxt-bulk-selectbar-actions .rkxt-btn { flex: 1 1 auto; }
}

/* 2. Detalle por cliente del job bulk (debajo de RkxtBulkProgress). */
.rkxt-bulkjob-steps {
    margin-top: 14px;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    overflow: hidden;
}
.rkxt-bulkjob-steps summary {
    padding: 10px 14px;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--rkxt-text);
    background: var(--rkxt-bg-alt);
    list-style: none;
}
.rkxt-bulkjob-steps summary::-webkit-details-marker { display: none; }
.rkxt-bulkjob-steps summary::before { content: '▸  '; color: var(--rkxt-text-muted); }
.rkxt-bulkjob-steps[open] summary::before { content: '▾  '; }

.rkxt-bulkjob-steplist {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 320px;
    overflow-y: auto;
}
.rkxt-bulkjob-step {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 7px 14px;
    font-size: 0.85rem;
    border-top: 1px solid var(--rkxt-border-soft);
}
.rkxt-bulkjob-step:first-child { border-top: none; }
.rkxt-bulkjob-step-icon { flex: 0 0 16px; font-weight: 700; }
.rkxt-bulkjob-step-ok .rkxt-bulkjob-step-icon { color: var(--rkxt-ok); }
.rkxt-bulkjob-step-error .rkxt-bulkjob-step-icon { color: var(--rkxt-bad); }
.rkxt-bulkjob-step-pendiente .rkxt-bulkjob-step-icon,
.rkxt-bulkjob-step-procesando .rkxt-bulkjob-step-icon { color: var(--rkxt-text-dim); }
.rkxt-bulkjob-step-cliente { color: var(--rkxt-text); font-weight: 500; }
.rkxt-bulkjob-step-msg { color: var(--rkxt-bad); font-size: 0.8rem; }
.rkxt-bulkjob-step-error { background: var(--rkxt-bad-soft); }

/* Lista de chips con los clientes elegidos (pantalla de configuración del job,
   antes de arrancar). Reusa .rkxt-badge para cada chip — esto solo da el wrap. */
.rkxt-bulkjob-chiplist {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 8px 0 18px;
}

/* 3. Indicador flotante persistente del job bulk. */
.rkxt-bulkjob-pill {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 9997;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 320px;
    padding: 10px 12px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius);
    box-shadow: var(--rkxt-shadow-lg);
    text-decoration: none;
    color: var(--rkxt-text);
    transition: transform .15s ease, box-shadow .15s ease;
}
.rkxt-bulkjob-pill:hover {
    transform: translateY(-2px);
    box-shadow: 0 28px 64px rgba(15,15,18,.18), 0 4px 14px rgba(15,15,18,.08);
    color: var(--rkxt-text);
    text-decoration: none;
}

.rkxt-bulkjob-pill-spinner {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 3px solid var(--rkxt-primary-soft);
    border-top-color: var(--rkxt-primary);
    animation: rkxt-bulkjob-spin 0.8s linear infinite;
}
@keyframes rkxt-bulkjob-spin { to { transform: rotate(360deg); } }

.rkxt-bulkjob-pill-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.rkxt-bulkjob-pill-text strong {
    font-size: 0.85rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rkxt-bulkjob-pill-text small {
    font-size: 0.72rem;
    color: var(--rkxt-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rkxt-bulkjob-pill-pct {
    flex: 0 0 auto;
    font-size: 0.95rem;
    font-weight: 800;
    color: var(--rkxt-primary);
}

/* Terminado: check verde en vez de spinner, acento --rkxt-ok. */
.rkxt-bulkjob-pill-done {
    border-color: color-mix(in srgb, var(--rkxt-ok) 35%, var(--rkxt-border));
    background: var(--rkxt-ok-soft);
}
.rkxt-bulkjob-pill-done .rkxt-bulkjob-pill-spinner {
    animation: none;
    border: none;
    background: var(--rkxt-ok);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    font-weight: 800;
}
.rkxt-bulkjob-pill-done .rkxt-bulkjob-pill-pct { color: var(--rkxt-ok); }

.rkxt-bulkjob-pill-close {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--rkxt-text-dim);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.rkxt-bulkjob-pill-close:hover { background: var(--rkxt-surface-2); color: var(--rkxt-text); }

@media (max-width: 560px) {
    .rkxt-bulkjob-pill { left: 16px; right: 16px; max-width: none; bottom: 16px; }
}

/* Fila de tabla seleccionada en la multi-selección de clientes (generación masiva). */
.rkxt-table tbody tr.rkxt-row-selected { background: var(--rkxt-primary-soft, #FFEEDE); }

/* ── Editor de pedido: compactar la cabecera sticky ──────────────────────────
   Los <select> heredan .rkxt-input (width:100%) y dentro de un flex-wrap se llevan un RENGLÓN ENTERO
   cada uno (marca, categoría, método) — eso inflaba la cabecera a ~543px (60% del viewport) y dejaba
   poco alto para la tabla, que es donde se carga. Acotándolos vuelven a la misma línea. */
.rkxt-ed-filtros-row > select.rkxt-input { width: auto; min-width: 150px; max-width: 230px; }
.rkxt-ed-curva-form select.rkxt-input { width: auto; min-width: 170px; max-width: 240px; }

/* ── Detalle del pedido: filas compactas + separador blanco fino ─────────────
   Las celdas heredaban padding 10px (mucha separación) y el separador --rkxt-border-soft se PIERDE
   sobre el fondo crema (--rkxt-surface-2) de las filas. Con el blanco recorta limpio y queda más
   delicado, y cada renglón (incluidas las sub-filas de talle) se distingue sin engordar la tabla. */
.rkxt-ed-tabla td { padding: 5px 14px; border-bottom: 1px solid var(--rkxt-surface, #fff); }
.rkxt-ed-tabla th { padding: 7px 14px; }
.rkxt-ed-tabla .rkxt-input { padding-top: 5px; padding-bottom: 5px; }
.rkxt-ed-prodinfo { padding: 2px 0; }
.rkxt-ed-thumb { width: 52px; height: 68px; }
